Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2017
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.00 KB | None | 0 0
  1. /************************************************************************************
  2. * Copyright (C) 2017 Openbravo S.L.U.
  3. * Licensed under the Openbravo Commercial License version 1.0
  4. * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html
  5. * or in the legal folder of this module distribution.
  6. ************************************************************************************/
  7.  
  8. package org.openbravo.certification.france.aggregation;
  9.  
  10. import java.math.BigDecimal;
  11. import java.sql.SQLException;
  12. import java.util.Calendar;
  13. import java.util.Date;
  14. import java.util.List;
  15.  
  16. import org.apache.commons.collections.CollectionUtils;
  17. import org.apache.commons.lang.time.DateUtils;
  18. import org.hibernate.Query;
  19. import org.hibernate.ScrollMode;
  20. import org.hibernate.ScrollableResults;
  21. import org.hibernate.Session;
  22. import org.hibernate.criterion.Restrictions;
  23. import org.openbravo.base.exception.OBException;
  24. import org.openbravo.base.provider.OBProvider;
  25. import org.openbravo.base.session.SessionFactoryController;
  26. import org.openbravo.base.structure.BaseOBObject;
  27. import org.openbravo.certification.france.TicketAgg;
  28. import org.openbravo.certification.france.TicketAggDay;
  29. import org.openbravo.certification.france.hashing.Hashing;
  30. import org.openbravo.dal.core.OBContext;
  31. import org.openbravo.dal.service.OBCriteria;
  32. import org.openbravo.dal.service.OBDal;
  33. import org.openbravo.erpCommon.utility.OBMessageUtils;
  34. import org.openbravo.retail.posterminal.OBPOSApplications;
  35. import org.slf4j.Logger;
  36. import org.slf4j.LoggerFactory;
  37.  
  38. /**
  39. *
  40. * Generic class for aggregation process. Each aggregation implementation should extend it.
  41. *
  42. */
  43. public abstract class AggregationDao {
  44.  
  45. protected static final Logger log = LoggerFactory.getLogger(AggregationDao.class);
  46.  
  47. public static final int INITYEAR = 2018;
  48. protected Date initDate;
  49. protected Date periodStart;
  50. protected Date periodEnd;
  51. protected Date periodNext;
  52. private Class<BaseOBObject> aggregationEntity;
  53. private String frequency;
  54.  
  55. protected void initAggregation() {
  56. aggregationEntity = getAggregationEntity();
  57. frequency = getFrequency();
  58. Calendar calendar = Calendar.getInstance();
  59. calendar.set(Calendar.YEAR, INITYEAR);
  60. initDate = DateUtils.truncate(calendar.getTime(), Calendar.YEAR);
  61.  
  62. doChecks();
  63. }
  64.  
  65. protected abstract <T extends BaseOBObject> Class<T> getAggregationEntity();
  66.  
  67. protected abstract String getFrequency();
  68.  
  69. private void doChecks() {
  70. checkPeriodAfterInitDate();
  71. // TODO: uncomment when finishing testing
  72. // checkPeriodBeforeCurrentPeriod();
  73. }
  74.  
  75. private void checkPeriodAfterInitDate() {
  76. if (periodStart.compareTo(initDate) < 0) {
  77. throw new OBException("@OBCFR_PeriodBeforeInitDate@");
  78. }
  79. }
  80.  
  81. @SuppressWarnings("unused")
  82. private void checkPeriodBeforeCurrentPeriod() {
  83. Calendar calendar = Calendar.getInstance();
  84. calendar.setTime(new Date());
  85. Date currentPeriod = DateUtils.truncate(calendar.getTime(), Calendar.DATE);
  86.  
  87. if (periodEnd.compareTo(currentPeriod) >= 0) {
  88. throw new OBException("@OBCFR_PeriodAfterCurrentDate@");
  89. }
  90. }
  91.  
  92. /**
  93. * Run aggregation process for every terminal and every needed period till selected date
  94. *
  95. * @param terminals
  96. * List of terminal IDs for which aggregation process will be run. If empty, it will be
  97. * run for every active terminal within current client.
  98. * @return Number of aggregation records created.
  99. * @throws SQLException
  100. */
  101. public int runAggregation(List<String> terminals) throws SQLException {
  102. long t0 = System.currentTimeMillis();
  103.  
  104. int i = runSubPeriodAggregation(terminals);
  105. Session session = SessionFactoryController.getInstance().getSessionFactory().openSession();
  106. ScrollableResults scroll = getTerminals(session, terminals);
  107. try {
  108. while (scroll.next()) {
  109. long t1 = System.currentTimeMillis();
  110.  
  111. OBPOSApplications terminal = (OBPOSApplications) scroll.get(0);
  112. checkLastDayPeriodAggregated(terminal);
  113.  
  114. Date selectedPeriod = periodStart;
  115. Date firstPeriod = getFirstPeriodWithoutAggregation(terminal);
  116.  
  117. for (Date period = firstPeriod; period
  118. .compareTo(selectedPeriod) <= 0; period = periodNext) {
  119. long t2 = System.currentTimeMillis();
  120.  
  121. initPeriod(period);
  122. aggregatePeriod(terminal);
  123.  
  124. OBDal.getInstance().getConnection(false).commit();
  125. OBDal.getInstance().getSession().clear();
  126. i++;
  127.  
  128. log.debug("Aggregation for period {} took: {} ms.", period,
  129. System.currentTimeMillis() - t2);
  130. }
  131. log.debug("Aggregation for terminal {} took: {} ms.", terminal.getName(),
  132. System.currentTimeMillis() - t1);
  133. }
  134. log.debug("Aggregation took: {} ms.", System.currentTimeMillis() - t0);
  135. } finally {
  136. scroll.close();
  137. if (session.isOpen()) {
  138. session.close();
  139. }
  140. }
  141.  
  142. return i;
  143. }
  144.  
  145. private ScrollableResults getTerminals(Session session, List<String> terminals) {
  146. StringBuilder select = new StringBuilder();
  147. select.append(" select t");
  148. select.append(" from " + OBPOSApplications.ENTITY_NAME + " as t");
  149. select.append(" where t." + OBPOSApplications.PROPERTY_ACTIVE + " = true");
  150. select.append(" and t." + OBPOSApplications.PROPERTY_CLIENT + ".id = :clientId");
  151. if (!CollectionUtils.isEmpty(terminals)) {
  152. select.append(" and t." + OBPOSApplications.PROPERTY_ID + " not in = :terminals");
  153. }
  154.  
  155. Query qry = session.createQuery(select.toString());
  156. qry.setParameter("clientId", OBContext.getOBContext().getCurrentClient().getId());
  157. if (!CollectionUtils.isEmpty(terminals)) {
  158. qry.setParameter("terminals", terminals);
  159. }
  160.  
  161. return qry.scroll(ScrollMode.FORWARD_ONLY);
  162. }
  163.  
  164. protected void checkLastDayPeriodAggregated(OBPOSApplications terminal) {
  165. OBCriteria<TicketAgg> criteria = OBDal.getInstance().createCriteria(TicketAgg.class);
  166. criteria.add(Restrictions.eq(TicketAgg.PROPERTY_POSTERMINAL, terminal));
  167. criteria.add(Restrictions.eq(TicketAgg.PROPERTY_AGGREGATIONFREQUENCY,
  168. AggregationDayDao.FREQUENCY_DAILY));
  169. criteria.add(Restrictions.eq(TicketAgg.PROPERTY_AGGREGATIONDATE, periodEnd));
  170. criteria.setFilterOnReadableOrganization(false);
  171. criteria.setMaxResults(1);
  172.  
  173. if (criteria.uniqueResult() == null) {
  174. throw new OBException(String.format(
  175. OBMessageUtils.messageBD("OBCFR_LastDayPeriodNotAggregated"), terminal.getName()));
  176. }
  177. }
  178.  
  179. protected int runSubPeriodAggregation(List<String> terminals) throws SQLException {
  180. return 0;
  181. }
  182.  
  183. protected Date getFirstPeriodWithoutAggregation(OBPOSApplications terminal) {
  184.  
  185. // Get last aggregation record prior or equals selected period
  186. StringBuilder select = new StringBuilder();
  187. select.append(" select max(ta." + TicketAgg.PROPERTY_STARTINGDATE + ")");
  188. select.append(" from " + TicketAgg.ENTITY_NAME + " as ta");
  189. select.append(" where ta." + TicketAgg.PROPERTY_POSTERMINAL + ".id = :terminalId");
  190. select.append(" and ta." + TicketAgg.PROPERTY_AGGREGATIONFREQUENCY + " = :frequency");
  191. select.append(" and ta." + TicketAgg.PROPERTY_STARTINGDATE + " <= :date");
  192.  
  193. Query qry = OBDal.getInstance().getSession().createQuery(select.toString());
  194. qry.setParameter("terminalId", terminal.getId());
  195. qry.setParameter("frequency", frequency);
  196. qry.setParameter("date", periodStart);
  197. qry.setMaxResults(1);
  198.  
  199. // If there isn't any aggregation record, we start aggregating from initDate
  200. Date date = (Date) qry.uniqueResult();
  201. if (date == null) {
  202. return initDate;
  203. }
  204.  
  205. // If there is an aggregation record, we start aggregating from its next period
  206. return getPeriodNext(date);
  207. }
  208.  
  209. protected void initPeriod(Date period) {
  210. periodNext = getPeriodNext(period);
  211. periodStart = getPeriodStart(period);
  212. periodEnd = getPeriodEnd(period);
  213. }
  214.  
  215. private void aggregatePeriod(OBPOSApplications terminal) {
  216.  
  217. TicketAgg aggregation = createTicketAgg(terminal);
  218.  
  219. for (Object[] amounts : getSubPeriodAggregation(terminal)) {
  220. BigDecimal taxRate = (BigDecimal) amounts[0];
  221. BigDecimal taxBase = (BigDecimal) amounts[1];
  222. BigDecimal taxAmount = (BigDecimal) amounts[2];
  223. BigDecimal taxTotal = taxBase.add(taxAmount);
  224. BigDecimal taxCumTotal = getAggregationCumTotal(terminal, taxRate, taxTotal);
  225.  
  226. createTicketAggLine(aggregationEntity, aggregation, taxRate, taxBase, taxAmount, taxTotal,
  227. taxCumTotal);
  228. }
  229. }
  230.  
  231. @SuppressWarnings("unchecked")
  232. protected List<Object[]> getSubPeriodAggregation(OBPOSApplications terminal) {
  233. StringBuilder select = new StringBuilder();
  234. select.append(" select tad." + TicketAggDay.PROPERTY_TAXRATE);
  235. select.append(" , sum(tad." + TicketAggDay.PROPERTY_TAXBASE + ")");
  236. select.append(" , sum(tad." + TicketAggDay.PROPERTY_TAXAMOUNT + ")");
  237. select.append(" from " + TicketAggDay.ENTITY_NAME + " as tad");
  238. select.append(" where tad." + TicketAggDay.PROPERTY_POSTERMINAL + ".id = :terminalId");
  239. select.append(" and tad." + TicketAggDay.PROPERTY_STARTINGDATE + " >= :startingDay");
  240. select.append(" and tad." + TicketAggDay.PROPERTY_STARTINGDATE + " <= :endingDay");
  241. select.append(" group by tad." + TicketAggDay.PROPERTY_TAXRATE);
  242.  
  243. Query qry = OBDal.getInstance().getSession().createQuery(select.toString());
  244. qry.setParameter("terminalId", terminal.getId());
  245. qry.setParameter("startingDay", periodStart);
  246. qry.setParameter("endingDay", periodEnd);
  247.  
  248. return qry.list();
  249. }
  250.  
  251. protected BigDecimal getAggregationCumTotal(OBPOSApplications terminal, BigDecimal taxRate,
  252. BigDecimal taxTotal) {
  253. StringBuilder select = new StringBuilder();
  254. select.append(" select tad." + TicketAggDay.PROPERTY_CUMULATIVETOTALAGGREGATION);
  255. select.append(" from " + TicketAggDay.ENTITY_NAME + " as tad");
  256. select.append(" where tad." + TicketAggDay.PROPERTY_POSTERMINAL + ".id = :terminalId");
  257. select.append(" and tad." + TicketAggDay.PROPERTY_STARTINGDATE + " <= :day");
  258. select.append(" and tad." + TicketAggDay.PROPERTY_TAXRATE + " = :taxRate");
  259. select.append(" order by tad." + TicketAggDay.PROPERTY_STARTINGDATE + " desc");
  260.  
  261. Query qry = OBDal.getInstance().getSession().createQuery(select.toString());
  262. qry.setParameter("terminalId", terminal.getId());
  263. qry.setParameter("day", periodEnd);
  264. qry.setParameter("taxRate", taxRate);
  265. qry.setMaxResults(1);
  266.  
  267. BigDecimal previousCumTotal = (BigDecimal) qry.uniqueResult();
  268. return previousCumTotal != null ? previousCumTotal : BigDecimal.ZERO;
  269. }
  270.  
  271. private TicketAgg createTicketAgg(OBPOSApplications terminal) {
  272. TicketAgg aggregation = OBProvider.getInstance().get(TicketAgg.class);
  273. aggregation.setClient(terminal.getClient());
  274. aggregation.setOrganization(terminal.getOrganization());
  275. aggregation.setPOSTerminal(terminal);
  276. aggregation.setPOSTerminalName(terminal.getName());
  277. aggregation.setStartingDate(periodStart);
  278. aggregation.setEndingDate(periodEnd);
  279. aggregation = setAggregationPeriod(aggregation);
  280.  
  281. aggregation = (TicketAgg) Hashing.hashEntity(aggregation);
  282.  
  283. OBDal.getInstance().save(aggregation);
  284. return aggregation;
  285. }
  286.  
  287. protected abstract TicketAgg setAggregationPeriod(TicketAgg aggregation);
  288.  
  289. @SuppressWarnings("unchecked")
  290. private <T extends BaseOBObject> T createTicketAggLine(Class<T> clz, TicketAgg aggregation,
  291. BigDecimal taxRate, BigDecimal taxBase, BigDecimal taxAmount, BigDecimal taxTotal,
  292. BigDecimal taxCumTotal) {
  293.  
  294. T aggregationLine = OBProvider.getInstance().get(clz);
  295. aggregationLine.set(TicketAggDay.PROPERTY_CLIENT, aggregation.getClient());
  296. aggregationLine.set(TicketAggDay.PROPERTY_ORGANIZATION, aggregation.getOrganization());
  297. aggregationLine.set(TicketAggDay.PROPERTY_TICKETAGGREGATION, aggregation);
  298. aggregationLine.set(TicketAggDay.PROPERTY_POSTERMINAL, aggregation.getPOSTerminal());
  299. aggregationLine.set(TicketAggDay.PROPERTY_POSTERMINALNAME,
  300. aggregation.getPOSTerminal().getName());
  301. aggregationLine.set(TicketAggDay.PROPERTY_STARTINGDATE, aggregation.getStartingDate());
  302. aggregationLine.set(TicketAggDay.PROPERTY_ENDINGDATE, aggregation.getEndingDate());
  303. aggregationLine.set(TicketAggDay.PROPERTY_TAXRATE, taxRate);
  304. aggregationLine.set(TicketAggDay.PROPERTY_TAXBASE, taxBase);
  305. aggregationLine.set(TicketAggDay.PROPERTY_TAXAMOUNT, taxAmount);
  306. aggregationLine.set(TicketAggDay.PROPERTY_TOTALAGGREGATION, taxTotal);
  307. aggregationLine.set(TicketAggDay.PROPERTY_CUMULATIVETOTALAGGREGATION, taxCumTotal);
  308.  
  309. aggregationLine = (T) Hashing.hashEntity(aggregationLine);
  310.  
  311. OBDal.getInstance().save(aggregationLine);
  312. return aggregationLine;
  313. }
  314.  
  315. protected abstract Date getPeriodStart(Date period);
  316.  
  317. protected abstract Date getPeriodEnd(Date period);
  318.  
  319. protected abstract Date getPeriodNext(Date period);
  320.  
  321. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement