package org.bigk.invoices.services;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bigk.invoices.Globals;
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.PaymentKind;
import org.bigk.invoices.model.Tax;
import org.bigk.invoices.utils.HibernateUtils;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import pl.bzwbk.zriab.utils.lexengines.LexEngine;
import pl.bzwbk.zriab.utils.lexengines.LexEnginePL;
public class InvoicesServiceImpl implements InvoicesService {
/**
* Logger for this class
*/
private static final Log logger =
LogFactory.getLog(InvoicesServiceImpl.class);
protected PaymentKindsService paymentKindsService;
protected TaxesService taxesService;
protected HRInvoiceNumberService hrInvoiceNumberService;
protected Invoice invoiceTemplate;
public InvoicesServiceImpl() {
}
@SuppressWarnings("unchecked")
public List<Invoice> listAllItems() throws ServiceException {
if (logger.isDebugEnabled()) {
logger.debug("listAllItems() - start");
}
List<Invoice> list = null;
Session session = null;
try {
session = HibernateUtils.getCurrentSession();
Criteria crit = session.createCriteria(Invoice.class);
crit.addOrder(Order.desc("year"));
crit.addOrder(Order.desc("number"));
list = crit.list();
if (list != null) {
for (Invoice invoice : list) {
recalculateInvoice(invoice);
hrInvoiceNumberService.updateHRInvoiceNumber(invoice);
}
}
} catch (HibernateException ex) {
logger.error("listAllItems()", ex);
throw new ServiceException(ex);
}
if (logger.isDebugEnabled()) {
logger.debug("listAllItems() - end - return value=" + CollectionUtils.size(list));
}
return list;
}
@SuppressWarnings("unchecked")
public List<Invoice> listItems4Page(InvoiceFilter filter) throws ServiceException {
if (logger.isDebugEnabled()) {
logger.debug("listItems4Page(InvoiceFilter filter=" + filter + ") - start");
}
List<Invoice> list = null;
Session session = null;
try {
session = HibernateUtils.getCurrentSession();
Criteria crit = session.createCriteria(Invoice.class);
crit.addOrder(Order.desc("year"));
crit.addOrder(Order.desc("number"));
if (filter != null) {
if (filter.getId() != null)
crit.add(Restrictions.idEq(filter.getId()));
if (StringUtils.isNotEmpty(filter.getYear()))
crit.add(Restrictions.eq("year", filter.getYear()));
if (filter.getNumber() != null)
crit.add(Restrictions.eq("number", filter.getNumber()));
if (StringUtils.isNotEmpty(filter.getPurchaserName()))
crit.add(Restrictions.like("purchaserName", filter.getPurchaserName(), MatchMode.ANYWHERE));
}
HibernateUtils.updateStats(crit, filter);
int firstResult = (filter.getCurrentPage().intValue() - 1)
* filter.getPaginatedPageSize().intValue();
int maxResults = filter.getPaginatedPageSize().intValue();
crit.setFirstResult(firstResult);
crit.setMaxResults(maxResults);
list = crit.list();
if (list != null) {
for (Invoice invoice : list) {
recalculateInvoice(invoice);
hrInvoiceNumberService.updateHRInvoiceNumber(invoice);
}
}
} catch (HibernateException ex) {
logger.error("listItems4Page(InvoiceFilter)", ex);
throw new ServiceException(ex);
}
if (logger.isDebugEnabled()) {
logger.debug("listItems4Page(InvoiceFilter) - end - return value=" + CollectionUtils.size(list));
}
return list;
}
public Invoice getInvoice(Long id) throws ServiceException {
if (logger.isDebugEnabled()) {
logger.debug("getInvoice(Long id=" + id + ") - start");
}
Invoice object = null;
Session session = null;
try {
session = HibernateUtils.getCurrentSession();
object = (Invoice) session.get(Invoice.class, id);
recalculateInvoice(object);
hrInvoiceNumberService.updateHRInvoiceNumber(object);
} catch (HibernateException ex) {
logger.error("getInvoice(Long)", ex);
throw new ServiceException(ex);
}
if (logger.isDebugEnabled()) {
logger.debug("getInvoice(Long) - end - return value=" + object);
}
return object;
}
public Invoice prepareNewInvoice() throws ServiceException {
if (logger.isDebugEnabled()) {
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();
}
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 {
if (logger.isDebugEnabled()) {
logger.debug("getMaxInvoiceNumber(String year=" + year + ") - start");
}
Session session = null;
int maxNumber = 0;
try {
session = HibernateUtils.getCurrentSession();
Criteria crit = session.createCriteria(Invoice.class);
crit.add(Restrictions.eq("year", year));
crit.setProjection(Projections.max("number"));
Long maxNumberLong = (Long) crit.uniqueResult();
if (maxNumberLong != null)
maxNumber = maxNumberLong.intValue();
crit.setProjection(null);
crit.setResultTransformer(Criteria.ROOT_ENTITY);
} catch (HibernateException ex) {
logger.error("getMaxInvoiceNumber(Long)", ex);
throw new ServiceException(ex);
}
if (logger.isDebugEnabled()) {
logger.debug("getMaxInvoiceNumber(String) - end - return value=" + maxNumber);
}
return maxNumber;
}
public void saveInvoice(Invoice invoice) throws ServiceException {
if (logger.isDebugEnabled()) {
logger.debug("saveInvoice(Invoice invoice=" + invoice + ") - start");
}
List<InvoicePosition> positions = invoice.getInvoicePositions();
if (positions != null) {
for (InvoicePosition ip : positions) {
ip.setInvoice(invoice);
}
}
Session session = null;
try {
session = HibernateUtils.getCurrentSession();
session.save(invoice);
} catch (HibernateException ex) {
logger.error("saveInvoice(Invoice)", ex);
throw new ServiceException(ex);
}
if (logger.isDebugEnabled()) {
logger.debug("saveInvoice(Invoice) - end");
}
}
@Override
public void updateInvoice(Invoice invoice) throws ServiceException {
}
@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");
}
}
protected void recalculateInvoice(Invoice invoice) {
if (logger.isDebugEnabled()) {
logger.debug("recalculateInvoice(Invoice invoice=" + invoice + ") - start");
}
if (invoice == null)
return;
// create List with keys of summaries
List<Double> calculatedSummariesKeys = new ArrayList<Double>(4);
calculatedSummariesKeys.add(Globals.DOUBLE_022);
calculatedSummariesKeys.add(Globals.DOUBLE_007);
calculatedSummariesKeys.add(Globals.DOUBLE_003);
calculatedSummariesKeys.add(Globals.DOUBLE_0);
invoice.setCalculatedSummariesKeys(calculatedSummariesKeys);
// create Map with summaries
Map<Double, InvoicePositionSummary> calculatedSummaries =
new HashMap<Double, InvoicePositionSummary>(5);
calculatedSummaries.put(Globals.DOUBLE_022,
new InvoicePositionSummary(Globals.DOUBLE_022));
calculatedSummaries.put(Globals.DOUBLE_007,
new InvoicePositionSummary(Globals.DOUBLE_007));
calculatedSummaries.put(Globals.DOUBLE_003,
new InvoicePositionSummary(Globals.DOUBLE_003));
calculatedSummaries.put(Globals.DOUBLE_0,
new InvoicePositionSummary(Globals.DOUBLE_0));
// position with 'total' aggregates
InvoicePositionSummary ip1 = new InvoicePositionSummary(Globals.DOUBLE_1);
calculatedSummaries.put(Globals.DOUBLE_1, 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);
}
}
// 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 {
if (logger.isDebugEnabled()) {
logger.debug("deleteInvoice(Invoice invoice=" + invoice + ") - start");
}
Session session = null;
try {
session = HibernateUtils.getCurrentSession();
session.delete(invoice);
} catch (HibernateException ex) {
logger.error("deleteInvoice(Invoice)", ex);
throw new ServiceException(ex);
}
if (logger.isDebugEnabled()) {
logger.debug("deleteInvoice(Invoice) - end");
}
}
public PaymentKindsService getPaymentKindsService() {
return paymentKindsService;
}
public void setPaymentKindsService(PaymentKindsService paymentKindsService) {
this.paymentKindsService = paymentKindsService;
}
public TaxesService getTaxesService() {
return taxesService;
}
public void setTaxesService(TaxesService taxesService) {
this.taxesService = taxesService;
}
public HRInvoiceNumberService getHrInvoiceNumberService() {
return hrInvoiceNumberService;
}
public void setHrInvoiceNumberService(
HRInvoiceNumberService hrInvoiceNumberService) {
this.hrInvoiceNumberService = hrInvoiceNumberService;
}
public Invoice getInvoiceTemplate() {
return invoiceTemplate;
}
public void setInvoiceTemplate(Invoice invoiceTemplate) {
this.invoiceTemplate = invoiceTemplate;
}
}