Package org.bigk.invoices.services

Source Code of org.bigk.invoices.services.InvoicesServiceImpl

package org.bigk.invoices.services;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.bigk.invoices.exceptions.ServiceException;
import org.bigk.invoices.model.Invoice;
import org.bigk.invoices.model.InvoiceFilter;
import org.bigk.invoices.model.InvoicePosition;
import org.bigk.invoices.model.InvoicePositionSummary;
import org.bigk.invoices.model.InvoicePurchaser;
import org.bigk.invoices.model.Invoice_;
import org.bigk.invoices.model.PaymentKind;
import org.bigk.invoices.model.Purchaser;
import org.bigk.invoices.model.PurchaserRole;
import org.bigk.invoices.model.Tax;
import org.bigk.invoices.services.taxesconfig.TaxConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pl.bigk.utils.lexengines.LexEngine;
import pl.bigk.utils.lexengines.LexEnginePL;


@Service("invoicesService")
@Transactional
public class InvoicesServiceImpl implements InvoicesService {

  private static final Logger logger = LoggerFactory.getLogger(InvoicesServiceImpl.class);

  private static final String ALL_INVOICES_QUERY =
      "SELECT i FROM Invoice i ORDER BY p.year ASC, p.number ASC";

  @PersistenceContext
  protected EntityManager em;

  @Autowired
  protected PaymentKindsService paymentKindsService;
 
  @Autowired
  protected TaxesService taxesService;
 
  @Autowired
  protected PurchasersRolesService purchasersRolesService;
 
  @Autowired
  protected HRInvoiceNumberService hrInvoiceNumberService;
 
  @Autowired
  protected RecalcTotalOfIPSService recalcTotalOfIPSService;
 
  @Autowired
  private TaxesConfigService taxesConfigService;
 
  @Resource(name="invoiceTemplate")
  protected Invoice invoiceTemplate;

  @Override
  public List<Invoice> listAllItems() throws ServiceException {
    logger.debug("listAllItems() - start");

    TypedQuery<Invoice> query = em.createQuery(ALL_INVOICES_QUERY, Invoice.class);
    List<Invoice> list = query.getResultList();

    if (list != null) {
      for (Invoice invoice : list) {
        recalculateInvoice(invoice);
        hrInvoiceNumberService.updateHRInvoiceNumber(invoice);
      }
    }

    logger.debug("listAllItems() - end - read [{}] element(s)", CollectionUtils.size(list));
    return list;
  }

  @Override
  public List<Invoice> listItems4Page(InvoiceFilter filter) throws ServiceException {
    List<Invoice> list = readListForFilter(filter);
    updateFilterStats(filter);
   
    if (list != null) {
      for (Invoice invoice : list) {
        recalculateInvoice(invoice);
        hrInvoiceNumberService.updateHRInvoiceNumber(invoice);
      }
    }
   
    return list;
  }
 
  private List<Invoice> readListForFilter(InvoiceFilter filter) {
    logger.debug("listItems4Page(filter=[{}]) - start", filter);
   
    CriteriaBuilder critBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Invoice> critQuery = critBuilder.createQuery(Invoice.class);
   
    // select-clause
    Root<Invoice> root = critQuery.from(Invoice.class);
    critQuery.select(root);
   
        // where-clause
        Predicate wherePredicate = whereClauseForFilter(critBuilder, critQuery, root, filter);
        if (wherePredicate != null) {
            critQuery.where(wherePredicate);
        }
       
        // order-by-clause
    critQuery.orderBy(Arrays.asList(
        critBuilder.desc(root.get(Invoice_.year)),
        critBuilder.desc(root.get(Invoice_.number))));
       
    TypedQuery<Invoice> query = em.createQuery(critQuery);
   
    query.setFirstResult(filter.calculateFirstResultIndex());
    query.setMaxResults(filter.getPaginatedPageSize());
   
    List<Invoice> list = query.getResultList();
    logger.debug("listItems4Page() - end - read [{}] element(s)", CollectionUtils.size(list));
    return list;
  }
 
  private void updateFilterStats(InvoiceFilter filter) {
    logger.debug("countItems4Page(filter=[{}]) - start", filter);
   
    CriteriaBuilder critBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Number> critQuery = critBuilder.createQuery(Number.class);
   
    // select-clause
    Root<Invoice> root = critQuery.from(Invoice.class);
    critQuery.select(critBuilder.count(root));
   
        // where-clause
        Predicate wherePredicate = whereClauseForFilter(critBuilder, critQuery, root, filter);
        if (wherePredicate != null) {
            critQuery.where(wherePredicate);
        }
   
    Number count = em.createQuery(critQuery).getSingleResult();
    filter.setCalculatedTotalRecordsAndPages(count.intValue());
   
    logger.debug("countItems4Page() - items counted: [{}]", count);
  }
 
  private Predicate whereClauseForFilter(CriteriaBuilder critBuilder,
      CriteriaQuery<?> critQuery, Root<Invoice> root,
      InvoiceFilter filter) {
   
    if (filter == null) {
      return null;
    }
   
    List<Predicate> where = new ArrayList<Predicate>();
   
    if (filter.getId() != null) {
      where.add(critBuilder.equal(root.get(Invoice_.id), filter.getId()));
    }
   
    if (StringUtils.isNotEmpty(filter.getYear())) {
      where.add(critBuilder.equal(root.get(Invoice_.year), filter.getYear()));
    }
   
    if (filter.getNumber() != null) {
      where.add(critBuilder.equal(root.get(Invoice_.number), filter.getNumber()));
    }
   
    if (StringUtils.isNotEmpty(filter.getPurchaserName())) {
      where.add(critBuilder.like(
          root.<Purchaser>get("invoicePurchasers").<String>get("name"), "%" + filter.getPurchaserName() + "%"));
    }

        if (where.size() > 0) {
            return critBuilder.and(where.toArray(new Predicate[0]));
        } else {
            return null;
        }
  }

  @Override
  public Invoice getInvoice(Long id) throws ServiceException {
    logger.debug("getInvoice(id=[{}]) - start", + id);

    Invoice invoice = em.find(Invoice.class, id);
    recalculateInvoice(invoice);
    hrInvoiceNumberService.updateHRInvoiceNumber(invoice);

    logger.debug("getInvoice(Long) - end - return value=[{}]", invoice);
    return invoice;
  }

  public Invoice prepareNewInvoice() throws ServiceException {
    logger.debug("prepareNewInvoice() - start");
   
    Invoice invoice = null;
    if (this.invoiceTemplate != null) {
      try {
        invoice = invoiceTemplate.clone();
      } catch (CloneNotSupportedException e) {
        logger.warn("prepareNewInvoice()", e);
      }
    }
   
    if (invoice == null) {
      invoice = new Invoice();
    }
   
    invoice.setInvoicePositions(new ArrayList<InvoicePosition>());
    invoice.setInvoicePurchasers(new ArrayList<InvoicePurchaser>());
   
    Calendar nowDay = Calendar.getInstance();
    nowDay.set(Calendar.HOUR, 0);
    nowDay.set(Calendar.MINUTE, 0);
    nowDay.set(Calendar.SECOND, 0);
    nowDay.set(Calendar.MILLISECOND, 0);
   
    Long curYear = new Long(nowDay.get(Calendar.YEAR));
    invoice.setYear(curYear.toString());
   
    int maxInvoiceNumber = this.getMaxInvoiceNumber(curYear.toString());
    maxInvoiceNumber++;
   
    Long number = new Long(maxInvoiceNumber);
    invoice.setNumber(number);
    invoice.setDocumentDate(nowDay.getTime());
    invoice.setSoldDate(nowDay.getTime());
   
    PaymentKind pk = null;
    if (invoice.getPaymentKindId() != null) {
      pk = paymentKindsService.getPaymentKind(invoice.getPaymentKindId());
    }
   
    Date paymentDate = null;
    if (pk != null) {
      invoice.setPaymentKind(pk);
      paymentDate = paymentKindsService.calculatePaymentDate(nowDay.getTime(), pk.getId());
      invoice.setPaymentDate(paymentDate);
    }
   
    recalculateInvoice(invoice);
    hrInvoiceNumberService.updateHRInvoiceNumber(invoice);
   
    if (logger.isDebugEnabled()) {
      logger.debug("prepareNewInvoice() - end - return value=" + invoice);
    }
    return invoice;
  }

  protected int getMaxInvoiceNumber(String year) throws ServiceException {
    logger.debug("getMaxInvoiceNumber(year=[{}]) - start", year);

    CriteriaBuilder critBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Invoice> critQuery = critBuilder.createQuery(Invoice.class);

    // select-clause
    Root<Invoice> root = critQuery.from(Invoice.class);
    critQuery.select(root)
        .where(critBuilder.equal(root.get(Invoice_.year), year))
        .orderBy(critBuilder.desc(root.get(Invoice_.number)));
   
    TypedQuery<Invoice> query = em.createQuery(critQuery).setMaxResults(1);
   
    Invoice invoice = null;
    try {
      invoice = query.getSingleResult();
    } catch (NoResultException ex) {
      logger.info("getMaxInvoiceNumber() - no result found - no invoices in this year?");
    }
   
    int maxNumber = 0;
    if (invoice != null) {
      maxNumber = invoice.getNumber().intValue();
    }
   
    logger.debug("getMaxInvoiceNumber() - end - return value=[{}]", maxNumber);
    return maxNumber;
  }

  public void saveInvoice(Invoice invoice) throws ServiceException {
    logger.debug("saveInvoice(Invoice invoice=[{}]) - start", invoice);

    List<InvoicePosition> positions = invoice.getInvoicePositions();
    if (positions != null) {
      for (InvoicePosition ip : positions) {
        ip.setInvoice(invoice);
      }
    }

    List<InvoicePurchaser> purchasers = invoice.getInvoicePurchasers();
    if (purchasers != null) {
      for (InvoicePurchaser ip : purchasers) {
        ip.setInvoice(invoice);
      }
    }

    em.merge(invoice);
   
    logger.debug("saveInvoice(Invoice) - end");
  }

  @Override
  public void updateInvoice(Invoice invoice) throws ServiceException {
    throw new UnsupportedOperationException("Ups... This method must be implemented!");
  }
 
  @Override
  public void addInvoicePosition(Invoice invoice, InvoicePosition invoicePosition)
      throws ServiceException {
    if (logger.isDebugEnabled()) {
      logger.debug("addInvoicePosition(Invoice invoice=" + invoice
          + ", InvoicePosition invoicePosition=" + invoicePosition
          + ") - start");
    }

    // read and set Tax object
    if (invoicePosition.getTaxId() != null) {
      Tax tax = taxesService.getTax(invoicePosition.getTaxId());
      invoicePosition.setTax(tax);
    }
   
    // set parent of this position
    invoicePosition.setInvoice(invoice);
   
    // add positions to parent's list
    List<InvoicePosition> invoicePositions = invoice.getInvoicePositions();
    if (invoicePositions == null) {
      invoicePositions = new ArrayList<InvoicePosition>();
      invoice.setInvoicePositions(invoicePositions);
    }
    invoicePositions.add(invoicePosition);

    this.recalculateInvoice(invoice);
    hrInvoiceNumberService.updateHRInvoiceNumber(invoice);
   
    if (logger.isDebugEnabled()) {
      logger.debug("addInvoicePosition(Invoice, InvoicePosition) - end");
    }
  }
 
  public void updateInvoicePosition(Invoice invoice,
      InvoicePosition invoicePosition, Long idx)
    throws ServiceException {
    if (logger.isDebugEnabled()) {
      logger.debug("updateInvoicePosition(Invoice invoice=" + invoice
          + ", InvoicePosition invoicePosition=" + invoicePosition
          + ", Long idx=" + idx + ") - start");
    }
   
    // read and set Tax object
    if (invoicePosition.getTaxId() != null) {
      Tax tax = taxesService.getTax(invoicePosition.getTaxId());
      invoicePosition.setTax(tax);
    }
   
    // set parent of this position
    invoicePosition.setInvoice(invoice);
   
    // add positions to parent's list
    List<InvoicePosition> invoicePositions = invoice.getInvoicePositions();
    if (invoicePositions == null) {
      invoicePositions = new ArrayList<InvoicePosition>();
      invoice.setInvoicePositions(invoicePositions);
    }
    invoicePositions.set(idx.intValue(), invoicePosition);

    this.recalculateInvoice(invoice);
    hrInvoiceNumberService.updateHRInvoiceNumber(invoice);

    if (logger.isDebugEnabled()) {
      logger.debug("updateInvoicePosition(Invoice, InvoicePosition, Long) - end");
    }
  }
 
  @Override
  public InvoicePosition getInvoicePosition(Invoice i, Long idx)
      throws ServiceException {
   
    InvoicePosition ip = null;
   
    if (i != null
        && i.getInvoicePositions() != null
        && i.getInvoicePositions().size() > idx) {
      ip = i.getInvoicePositions().get(idx.intValue());
    }
   
    return ip;
  }
 
  @Override
  public void addInvoicePurchaser(Invoice invoice, InvoicePurchaser invoicePurchaser)
      throws ServiceException {
    if (logger.isDebugEnabled()) {
      logger.debug("addInvoicePurchaser(Invoice invoice=" + invoice
          + ", InvoicePurchaser invoicePurchaser=" + invoicePurchaser
          + ") - start");
    }

    // read and set PurchaserRole object
    if (invoicePurchaser.getPurchaserRoleId() != null) {
      PurchaserRole role = purchasersRolesService.getPurchaserRole(invoicePurchaser.getPurchaserRoleId());
      invoicePurchaser.setPurchaserRole(role);
    }
   
    // set parent of this purchaser
    invoicePurchaser.setInvoice(invoice);
   
    // add purchaser to parent's list
    List<InvoicePurchaser> invoicePurchasers = invoice.getInvoicePurchasers();
    if (invoicePurchasers == null) {
      invoicePurchasers = new ArrayList<InvoicePurchaser>();
      invoice.setInvoicePurchasers(invoicePurchasers);
    }
    invoicePurchasers.add(invoicePurchaser);

    if (logger.isDebugEnabled()) {
      logger.debug("addInvoicePurchaser(Invoice, InvoicePurchaser) - end");
    }
  }
 
  public void updateInvoicePurchaser(Invoice invoice,
      InvoicePurchaser invoicePurchaser, Long idx)
    throws ServiceException {
   
    if (logger.isDebugEnabled()) {
      logger.debug("updateInvoicePurchaser(Invoice invoice=" + invoice
          + ", InvoicePurchaser invoicePurchaser=" + invoicePurchaser
          + ", Long idx=" + idx + ") - start");
    }
   
    // read and set PurchaserRole object
    if (invoicePurchaser.getPurchaserRoleId() != null) {
      PurchaserRole role = purchasersRolesService.getPurchaserRole(invoicePurchaser.getPurchaserRoleId());
      invoicePurchaser.setPurchaserRole(role);
    }
   
    // set parent of this purchaser
    invoicePurchaser.setInvoice(invoice);
   
    // set purchaser at parent's list
    List<InvoicePurchaser> invoicePurchasers = invoice.getInvoicePurchasers();
    if (invoicePurchasers == null) {
      invoicePurchasers = new ArrayList<InvoicePurchaser>();
      invoice.setInvoicePurchasers(invoicePurchasers);
    }
    invoicePurchasers.set(idx.intValue(), invoicePurchaser);

    if (logger.isDebugEnabled()) {
      logger.debug("updateInvoicePurchaser(Invoice, InvoicePurchaser, Long) - end");
    }
  }
 
  @Override
  public InvoicePurchaser getInvoicePurchaser(Invoice i, Long idx)
      throws ServiceException {
   
    InvoicePurchaser ip = null;
   
    if (i != null
        && i.getInvoicePurchasers() != null
        && i.getInvoicePurchasers().size() > idx) {
      ip = i.getInvoicePurchasers().get(idx.intValue());
    }
   
    return ip;
  }
 
  protected void recalculateInvoice(Invoice invoice) {
    if (logger.isDebugEnabled()) {
      logger.debug("recalculateInvoice(Invoice invoice=" + invoice + ") - start");
    }

    if (invoice == null)
      return;

    // create Map with summaries
    Map<Double, InvoicePositionSummary> calculatedSummaries =
      new HashMap<Double, InvoicePositionSummary>(5);

    // create List with keys of summaries
    List<Double> calculatedSummariesKeys = new ArrayList<Double>(4);
   
    TaxConfig tc = taxesConfigService.getTaxConfigByDate(invoice.getSoldDate());
    if (tc != null) {
      List<Double> availTaxes = tc.getAvailTaxes();
      for (Double at : availTaxes) {
        calculatedSummariesKeys.add(at);
        calculatedSummaries.put(at, new InvoicePositionSummary(at));
      }
    }
    calculatedSummariesKeys.add(NumberUtils.DOUBLE_ZERO);
    invoice.setCalculatedSummariesKeys(calculatedSummariesKeys);
   
    calculatedSummaries.put(NumberUtils.DOUBLE_ZERO,
        new InvoicePositionSummary(NumberUtils.DOUBLE_ZERO));
   
    // position with 'total' aggregates
    InvoicePositionSummary ip1 = new InvoicePositionSummary(NumberUtils.DOUBLE_ONE);
    calculatedSummaries.put(NumberUtils.DOUBLE_ONE, ip1);
   
    invoice.setCalculatedSummaries(calculatedSummaries);

   
    if (invoice.getInvoicePositions() != null) {
      for (InvoicePosition pos : invoice.getInvoicePositions()) {
        if (logger.isDebugEnabled()) {
          logger.debug("recalculateInvoice(Invoice) - iterate through invoicePositions - pos=" + pos);
        }
       
        Double percentTax = pos.getTax().getValue();
        if (logger.isDebugEnabled()) {
          logger.debug("recalculateInvoice(Invoice) - iterate through invoicePositions - percentTax=" + percentTax);
        }

        InvoicePositionSummary posFromMap =
          (InvoicePositionSummary) calculatedSummaries.get(percentTax);
        if (logger.isDebugEnabled()) {
          logger.debug("recalculateInvoice(Invoice) - iterate through invoicePositions - before add - posFromMap=" + posFromMap);
          logger.debug("recalculateInvoice(Invoice) - iterate through invoicePositions - before add  - ip1=" + ip1);
        }
       
        if (posFromMap != null) {
          posFromMap.addValueNetto(pos.getValueNetto());
          posFromMap.addSum(pos.getSum());
          posFromMap.addTotal(pos.getTotal());
        }
       
        ip1.addValueNetto(pos.getValueNetto());
        ip1.addSum(pos.getSum());
        ip1.addTotal(pos.getTotal());
       
        if (logger.isDebugEnabled()) {
          logger.debug("recalculateInvoice(Invoice) - iterate through invoicePositions - after add - posFromMap=" + posFromMap);
          logger.debug("recalculateInvoice(Invoice) - iterate through invoicePositions - after add  - ip1=" + ip1);
        }
      }
     
      // recalculate InvoicePositionSummary when dedicated service is set
      if (recalcTotalOfIPSService != null) {
        recalcTotalOfIPSService.recalculateTotal(ip1);
      }
     
      // get text for ip1::total
      BigDecimal total = ip1.getTotal();
      LexEngine le = new LexEnginePL();
     
      long integerPart = total.longValue();
      long digitsPart = total.multiply(new BigDecimal(100d)).remainder(new BigDecimal(100d)).longValue();
     
      invoice.setHrTotalIntegerPart(le.getTextForNumber(integerPart));
      invoice.setHrTotalDigitsPart(le.getTextForNumber(digitsPart));
     
      if (logger.isDebugEnabled()) {
        logger.debug("recalculateInvoice(Invoice) - set - hrTotalIntegerPart=" + invoice.getHrTotalIntegerPart());
        logger.debug("recalculateInvoice(Invoice) - set - hrTotalDigitsPart=" + invoice.getHrTotalDigitsPart());
      }
    }

    if (logger.isDebugEnabled()) {
      logger.debug("recalculateInvoice(Invoice) - end");
    }
  }
 
  public void deleteInvoice(Invoice invoice) throws ServiceException {
    logger.debug("deleteInvoice(invoice=[{}]) - start", invoice);

    em.remove(em.merge(invoice));

    logger.debug("deleteInvoice() - end");
  }
}
TOP

Related Classes of org.bigk.invoices.services.InvoicesServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.