Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /************************************************************************************
- * Copyright (C) 2017 Openbravo S.L.U.
- * Licensed under the Openbravo Commercial License version 1.0
- * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html
- * or in the legal folder of this module distribution.
- ************************************************************************************/
- package org.openbravo.certification.france.aggregation;
- import java.math.BigDecimal;
- import java.sql.SQLException;
- import java.util.Calendar;
- import java.util.Date;
- import java.util.List;
- import org.apache.commons.collections.CollectionUtils;
- import org.apache.commons.lang.time.DateUtils;
- import org.hibernate.Query;
- import org.hibernate.ScrollMode;
- import org.hibernate.ScrollableResults;
- import org.hibernate.Session;
- import org.hibernate.criterion.Restrictions;
- import org.openbravo.base.exception.OBException;
- import org.openbravo.base.provider.OBProvider;
- import org.openbravo.base.session.SessionFactoryController;
- import org.openbravo.base.structure.BaseOBObject;
- import org.openbravo.certification.france.TicketAgg;
- import org.openbravo.certification.france.TicketAggDay;
- import org.openbravo.certification.france.hashing.Hashing;
- import org.openbravo.dal.core.OBContext;
- import org.openbravo.dal.service.OBCriteria;
- import org.openbravo.dal.service.OBDal;
- import org.openbravo.erpCommon.utility.OBMessageUtils;
- import org.openbravo.retail.posterminal.OBPOSApplications;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- /**
- *
- * Generic class for aggregation process. Each aggregation implementation should extend it.
- *
- */
- public abstract class AggregationDao {
- protected static final Logger log = LoggerFactory.getLogger(AggregationDao.class);
- public static final int INITYEAR = 2018;
- protected Date initDate;
- protected Date periodStart;
- protected Date periodEnd;
- protected Date periodNext;
- private Class<BaseOBObject> aggregationEntity;
- private String frequency;
- protected void initAggregation() {
- aggregationEntity = getAggregationEntity();
- frequency = getFrequency();
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.YEAR, INITYEAR);
- initDate = DateUtils.truncate(calendar.getTime(), Calendar.YEAR);
- doChecks();
- }
- protected abstract <T extends BaseOBObject> Class<T> getAggregationEntity();
- protected abstract String getFrequency();
- private void doChecks() {
- checkPeriodAfterInitDate();
- // TODO: uncomment when finishing testing
- // checkPeriodBeforeCurrentPeriod();
- }
- private void checkPeriodAfterInitDate() {
- if (periodStart.compareTo(initDate) < 0) {
- throw new OBException("@OBCFR_PeriodBeforeInitDate@");
- }
- }
- @SuppressWarnings("unused")
- private void checkPeriodBeforeCurrentPeriod() {
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(new Date());
- Date currentPeriod = DateUtils.truncate(calendar.getTime(), Calendar.DATE);
- if (periodEnd.compareTo(currentPeriod) >= 0) {
- throw new OBException("@OBCFR_PeriodAfterCurrentDate@");
- }
- }
- /**
- * Run aggregation process for every terminal and every needed period till selected date
- *
- * @param terminals
- * List of terminal IDs for which aggregation process will be run. If empty, it will be
- * run for every active terminal within current client.
- * @return Number of aggregation records created.
- * @throws SQLException
- */
- public int runAggregation(List<String> terminals) throws SQLException {
- long t0 = System.currentTimeMillis();
- int i = runSubPeriodAggregation(terminals);
- Session session = SessionFactoryController.getInstance().getSessionFactory().openSession();
- ScrollableResults scroll = getTerminals(session, terminals);
- try {
- while (scroll.next()) {
- long t1 = System.currentTimeMillis();
- OBPOSApplications terminal = (OBPOSApplications) scroll.get(0);
- checkLastDayPeriodAggregated(terminal);
- Date selectedPeriod = periodStart;
- Date firstPeriod = getFirstPeriodWithoutAggregation(terminal);
- for (Date period = firstPeriod; period
- .compareTo(selectedPeriod) <= 0; period = periodNext) {
- long t2 = System.currentTimeMillis();
- initPeriod(period);
- aggregatePeriod(terminal);
- OBDal.getInstance().getConnection(false).commit();
- OBDal.getInstance().getSession().clear();
- i++;
- log.debug("Aggregation for period {} took: {} ms.", period,
- System.currentTimeMillis() - t2);
- }
- log.debug("Aggregation for terminal {} took: {} ms.", terminal.getName(),
- System.currentTimeMillis() - t1);
- }
- log.debug("Aggregation took: {} ms.", System.currentTimeMillis() - t0);
- } finally {
- scroll.close();
- if (session.isOpen()) {
- session.close();
- }
- }
- return i;
- }
- private ScrollableResults getTerminals(Session session, List<String> terminals) {
- StringBuilder select = new StringBuilder();
- select.append(" select t");
- select.append(" from " + OBPOSApplications.ENTITY_NAME + " as t");
- select.append(" where t." + OBPOSApplications.PROPERTY_ACTIVE + " = true");
- select.append(" and t." + OBPOSApplications.PROPERTY_CLIENT + ".id = :clientId");
- if (!CollectionUtils.isEmpty(terminals)) {
- select.append(" and t." + OBPOSApplications.PROPERTY_ID + " not in = :terminals");
- }
- Query qry = session.createQuery(select.toString());
- qry.setParameter("clientId", OBContext.getOBContext().getCurrentClient().getId());
- if (!CollectionUtils.isEmpty(terminals)) {
- qry.setParameter("terminals", terminals);
- }
- return qry.scroll(ScrollMode.FORWARD_ONLY);
- }
- protected void checkLastDayPeriodAggregated(OBPOSApplications terminal) {
- OBCriteria<TicketAgg> criteria = OBDal.getInstance().createCriteria(TicketAgg.class);
- criteria.add(Restrictions.eq(TicketAgg.PROPERTY_POSTERMINAL, terminal));
- criteria.add(Restrictions.eq(TicketAgg.PROPERTY_AGGREGATIONFREQUENCY,
- AggregationDayDao.FREQUENCY_DAILY));
- criteria.add(Restrictions.eq(TicketAgg.PROPERTY_AGGREGATIONDATE, periodEnd));
- criteria.setFilterOnReadableOrganization(false);
- criteria.setMaxResults(1);
- if (criteria.uniqueResult() == null) {
- throw new OBException(String.format(
- OBMessageUtils.messageBD("OBCFR_LastDayPeriodNotAggregated"), terminal.getName()));
- }
- }
- protected int runSubPeriodAggregation(List<String> terminals) throws SQLException {
- return 0;
- }
- protected Date getFirstPeriodWithoutAggregation(OBPOSApplications terminal) {
- // Get last aggregation record prior or equals selected period
- StringBuilder select = new StringBuilder();
- select.append(" select max(ta." + TicketAgg.PROPERTY_STARTINGDATE + ")");
- select.append(" from " + TicketAgg.ENTITY_NAME + " as ta");
- select.append(" where ta." + TicketAgg.PROPERTY_POSTERMINAL + ".id = :terminalId");
- select.append(" and ta." + TicketAgg.PROPERTY_AGGREGATIONFREQUENCY + " = :frequency");
- select.append(" and ta." + TicketAgg.PROPERTY_STARTINGDATE + " <= :date");
- Query qry = OBDal.getInstance().getSession().createQuery(select.toString());
- qry.setParameter("terminalId", terminal.getId());
- qry.setParameter("frequency", frequency);
- qry.setParameter("date", periodStart);
- qry.setMaxResults(1);
- // If there isn't any aggregation record, we start aggregating from initDate
- Date date = (Date) qry.uniqueResult();
- if (date == null) {
- return initDate;
- }
- // If there is an aggregation record, we start aggregating from its next period
- return getPeriodNext(date);
- }
- protected void initPeriod(Date period) {
- periodNext = getPeriodNext(period);
- periodStart = getPeriodStart(period);
- periodEnd = getPeriodEnd(period);
- }
- private void aggregatePeriod(OBPOSApplications terminal) {
- TicketAgg aggregation = createTicketAgg(terminal);
- for (Object[] amounts : getSubPeriodAggregation(terminal)) {
- BigDecimal taxRate = (BigDecimal) amounts[0];
- BigDecimal taxBase = (BigDecimal) amounts[1];
- BigDecimal taxAmount = (BigDecimal) amounts[2];
- BigDecimal taxTotal = taxBase.add(taxAmount);
- BigDecimal taxCumTotal = getAggregationCumTotal(terminal, taxRate, taxTotal);
- createTicketAggLine(aggregationEntity, aggregation, taxRate, taxBase, taxAmount, taxTotal,
- taxCumTotal);
- }
- }
- @SuppressWarnings("unchecked")
- protected List<Object[]> getSubPeriodAggregation(OBPOSApplications terminal) {
- StringBuilder select = new StringBuilder();
- select.append(" select tad." + TicketAggDay.PROPERTY_TAXRATE);
- select.append(" , sum(tad." + TicketAggDay.PROPERTY_TAXBASE + ")");
- select.append(" , sum(tad." + TicketAggDay.PROPERTY_TAXAMOUNT + ")");
- select.append(" from " + TicketAggDay.ENTITY_NAME + " as tad");
- select.append(" where tad." + TicketAggDay.PROPERTY_POSTERMINAL + ".id = :terminalId");
- select.append(" and tad." + TicketAggDay.PROPERTY_STARTINGDATE + " >= :startingDay");
- select.append(" and tad." + TicketAggDay.PROPERTY_STARTINGDATE + " <= :endingDay");
- select.append(" group by tad." + TicketAggDay.PROPERTY_TAXRATE);
- Query qry = OBDal.getInstance().getSession().createQuery(select.toString());
- qry.setParameter("terminalId", terminal.getId());
- qry.setParameter("startingDay", periodStart);
- qry.setParameter("endingDay", periodEnd);
- return qry.list();
- }
- protected BigDecimal getAggregationCumTotal(OBPOSApplications terminal, BigDecimal taxRate,
- BigDecimal taxTotal) {
- StringBuilder select = new StringBuilder();
- select.append(" select tad." + TicketAggDay.PROPERTY_CUMULATIVETOTALAGGREGATION);
- select.append(" from " + TicketAggDay.ENTITY_NAME + " as tad");
- select.append(" where tad." + TicketAggDay.PROPERTY_POSTERMINAL + ".id = :terminalId");
- select.append(" and tad." + TicketAggDay.PROPERTY_STARTINGDATE + " <= :day");
- select.append(" and tad." + TicketAggDay.PROPERTY_TAXRATE + " = :taxRate");
- select.append(" order by tad." + TicketAggDay.PROPERTY_STARTINGDATE + " desc");
- Query qry = OBDal.getInstance().getSession().createQuery(select.toString());
- qry.setParameter("terminalId", terminal.getId());
- qry.setParameter("day", periodEnd);
- qry.setParameter("taxRate", taxRate);
- qry.setMaxResults(1);
- BigDecimal previousCumTotal = (BigDecimal) qry.uniqueResult();
- return previousCumTotal != null ? previousCumTotal : BigDecimal.ZERO;
- }
- private TicketAgg createTicketAgg(OBPOSApplications terminal) {
- TicketAgg aggregation = OBProvider.getInstance().get(TicketAgg.class);
- aggregation.setClient(terminal.getClient());
- aggregation.setOrganization(terminal.getOrganization());
- aggregation.setPOSTerminal(terminal);
- aggregation.setPOSTerminalName(terminal.getName());
- aggregation.setStartingDate(periodStart);
- aggregation.setEndingDate(periodEnd);
- aggregation = setAggregationPeriod(aggregation);
- aggregation = (TicketAgg) Hashing.hashEntity(aggregation);
- OBDal.getInstance().save(aggregation);
- return aggregation;
- }
- protected abstract TicketAgg setAggregationPeriod(TicketAgg aggregation);
- @SuppressWarnings("unchecked")
- private <T extends BaseOBObject> T createTicketAggLine(Class<T> clz, TicketAgg aggregation,
- BigDecimal taxRate, BigDecimal taxBase, BigDecimal taxAmount, BigDecimal taxTotal,
- BigDecimal taxCumTotal) {
- T aggregationLine = OBProvider.getInstance().get(clz);
- aggregationLine.set(TicketAggDay.PROPERTY_CLIENT, aggregation.getClient());
- aggregationLine.set(TicketAggDay.PROPERTY_ORGANIZATION, aggregation.getOrganization());
- aggregationLine.set(TicketAggDay.PROPERTY_TICKETAGGREGATION, aggregation);
- aggregationLine.set(TicketAggDay.PROPERTY_POSTERMINAL, aggregation.getPOSTerminal());
- aggregationLine.set(TicketAggDay.PROPERTY_POSTERMINALNAME,
- aggregation.getPOSTerminal().getName());
- aggregationLine.set(TicketAggDay.PROPERTY_STARTINGDATE, aggregation.getStartingDate());
- aggregationLine.set(TicketAggDay.PROPERTY_ENDINGDATE, aggregation.getEndingDate());
- aggregationLine.set(TicketAggDay.PROPERTY_TAXRATE, taxRate);
- aggregationLine.set(TicketAggDay.PROPERTY_TAXBASE, taxBase);
- aggregationLine.set(TicketAggDay.PROPERTY_TAXAMOUNT, taxAmount);
- aggregationLine.set(TicketAggDay.PROPERTY_TOTALAGGREGATION, taxTotal);
- aggregationLine.set(TicketAggDay.PROPERTY_CUMULATIVETOTALAGGREGATION, taxCumTotal);
- aggregationLine = (T) Hashing.hashEntity(aggregationLine);
- OBDal.getInstance().save(aggregationLine);
- return aggregationLine;
- }
- protected abstract Date getPeriodStart(Date period);
- protected abstract Date getPeriodEnd(Date period);
- protected abstract Date getPeriodNext(Date period);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement