/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.pdp.dataaccess.impl;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.QueryByCriteria;
import org.apache.ojb.broker.query.QueryFactory;
import org.kuali.kfs.pdp.PdpConstants;
import org.kuali.kfs.pdp.PdpPropertyConstants;
import org.kuali.kfs.pdp.businessobject.DailyReport;
import org.kuali.kfs.pdp.businessobject.DisbursementNumberRange;
import org.kuali.kfs.pdp.businessobject.ExtractionUnit;
import org.kuali.kfs.pdp.businessobject.PaymentDetail;
import org.kuali.kfs.pdp.businessobject.PaymentGroup;
import org.kuali.kfs.pdp.businessobject.options.DailyReportComparator;
import org.kuali.kfs.pdp.dataaccess.PaymentDetailDao;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.core.api.util.type.KualiInteger;
import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
public class PaymentDetailDaoOjb extends PlatformAwareDaoBaseOjb implements PaymentDetailDao {
private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PaymentDetailDaoOjb.class);
public PaymentDetailDaoOjb() {
super();
}
/**
* @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getAchPaymentsWithUnsentEmail()
*/
@Override
public Iterator getAchPaymentsWithUnsentEmail() {
LOG.debug("getAchPaymentsWithUnsentEmail() started");
Criteria crit = new Criteria();
crit.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_STATUS_CODE, PdpConstants.PaymentStatusCodes.EXTRACTED);
crit.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_DISBURSEMENT_TYPE_CODE, PdpConstants.DisbursementTypeCodes.ACH);
crit.addIsNull(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.ADVICE_EMAIL_SENT_DATE);
return getPersistenceBrokerTemplate().getIteratorByQuery(new QueryByCriteria(PaymentDetail.class, crit));
}
/**
* @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getDailyReportData(java.sql.Date)
*/
@Override
public List<DailyReport> getDailyReportData(Date currentSqlDate) {
LOG.debug("getDailyReportData() started");
if (LOG.isDebugEnabled()) {
LOG.debug("getDailyReportData() " + currentSqlDate);
}
Criteria criteria = new Criteria();
criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.PaymentGroup.PAYMENT_GROUP_PAYMENT_STATUS_CODE, PdpConstants.PaymentStatusCodes.OPEN);
// (Payment date <= usePaydate OR immediate = TRUE)
Criteria criteria1 = new Criteria();
criteria1.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.PaymentGroup.PROCESS_IMMEDIATE, Boolean.TRUE);
Criteria criteria2 = new Criteria();
criteria2.addLessOrEqualThan(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.PaymentGroup.PAYMENT_DATE, currentSqlDate);
criteria1.addOrCriteria(criteria2);
criteria.addAndCriteria(criteria1);
QueryByCriteria q = QueryFactory.newQuery(PaymentDetail.class, criteria);
q.addOrderByDescending(PdpPropertyConstants.PaymentDetail.PAYMENT_PROCESS_IMEDIATE);
q.addOrderByDescending(PdpPropertyConstants.PaymentDetail.PAYMENT_SPECIAL_HANDLING);
q.addOrderByDescending(PdpPropertyConstants.PaymentDetail.PAYMENT_ATTACHMENT);
q.addOrderByAscending(PdpPropertyConstants.PaymentDetail.PAYMENT_CHART_CODE);
q.addOrderByAscending(PdpPropertyConstants.PaymentDetail.PAYMENT_UNIT_CODE);
q.addOrderByAscending(PdpPropertyConstants.PaymentDetail.PAYMENT_SUBUNIT_CODE);
q.addOrderByAscending(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.PaymentGroup.PAYMENT_GROUP_ID);
Map<Key, Numbers> summary = new HashMap<Key, Numbers>();
KualiInteger lastGroupId = null;
Iterator i = getPersistenceBrokerTemplate().getIteratorByQuery(q);
while (i.hasNext()) {
PaymentDetail d = (PaymentDetail) i.next();
Key rsk = new Key(d);
Numbers n = summary.get(rsk);
if (n == null) {
n = new Numbers();
n.amount = d.getNetPaymentAmount();
n.payments = 1;
n.payees = 1;
summary.put(rsk, n);
lastGroupId = d.getPaymentGroup().getId();
}
else {
n.payments++;
n.amount = n.amount.add(d.getNetPaymentAmount());
if (lastGroupId.intValue() != d.getPaymentGroup().getId().intValue()) {
n.payees++;
lastGroupId = d.getPaymentGroup().getId();
}
}
}
// Now take the data and put it in our result list
List<DailyReport> data = new ArrayList<DailyReport>();
for (Iterator iter = summary.keySet().iterator(); iter.hasNext();) {
Key e = (Key) iter.next();
Numbers n = summary.get(e);
DailyReport r = new DailyReport(e.customerShortName, n.amount, n.payments, n.payees, e.paymentGroup);
data.add(r);
}
Collections.sort(data, new DailyReportComparator());
return data;
}
class Key {
public Boolean pymtAttachment;
public Boolean pymtSpecialHandling;
public Boolean processImmediate;
public String customerShortName;
public PaymentGroup paymentGroup;
public Key(PaymentDetail d) {
this(d.getPaymentGroup().getPymtAttachment(), d.getPaymentGroup().getPymtSpecialHandling(), d.getPaymentGroup().getProcessImmediate(), d.getPaymentGroup().getBatch().getCustomerProfile().getCustomerShortName(), d.getPaymentGroup());
}
public Key(Boolean att, Boolean spec, Boolean immed, String c, PaymentGroup paymentGroup) {
pymtAttachment = att;
pymtSpecialHandling = spec;
processImmediate = immed;
customerShortName = c;
this.paymentGroup = paymentGroup;
}
@Override
public int hashCode() {
return new HashCodeBuilder(3, 5).append(pymtAttachment).append(pymtSpecialHandling).append(processImmediate).append(customerShortName).toHashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Key)) {
return false;
}
Key thisobj = (Key) obj;
return new EqualsBuilder().append(pymtAttachment, thisobj.pymtAttachment).append(pymtSpecialHandling, thisobj.pymtSpecialHandling).append(processImmediate, thisobj.processImmediate).append(customerShortName, thisobj.customerShortName).isEquals();
}
@Override
public String toString() {
return pymtAttachment + " " + pymtSpecialHandling + " " + processImmediate + " " + customerShortName;
}
}
class Numbers {
public KualiDecimal amount = KualiDecimal.ZERO;
public int payments = 0;
public int payees = 0;
}
/**
* @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getDetailForEpic(String, String, String, String)
*/
@Override
public PaymentDetail getDetailForEpic(String custPaymentDocNbr, String fdocTypeCode, String orgCode, String subUnitCode) {
LOG.debug("getDetailForEpic(custPaymentDocNbr, fdocTypeCode) started");
List data = new ArrayList();
Criteria criteria = new Criteria();
criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_CUSTOMER_DOC_NUMBER, custPaymentDocNbr);
criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_DISBURSEMENT_FINANCIAL_DOCUMENT_TYPE_CODE, fdocTypeCode);
criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_UNIT_CODE, orgCode);
criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_SUBUNIT_CODE, subUnitCode);
List paymentDetails = (List) getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(PaymentDetail.class, criteria));
PaymentDetail cp = null;
for (Iterator iter = paymentDetails.iterator(); iter.hasNext();) {
PaymentDetail pd = (PaymentDetail) iter.next();
if (cp == null) {
cp = pd;
}
else {
if ((pd.getPaymentGroup().getBatch().getCustomerFileCreateTimestamp().compareTo(cp.getPaymentGroup().getBatch().getCustomerFileCreateTimestamp())) > 0) {
cp = pd;
}
}
}
return cp;
}
/**
* @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getDisbursementNumberRanges(java.lang.String)
*/
@Override
public List<DisbursementNumberRange> getDisbursementNumberRanges(String campus) {
LOG.debug("getDisbursementNumberRanges() started");
java.util.Date now = new java.util.Date();
Timestamp nowTs = new Timestamp(now.getTime());
Criteria criteria = new Criteria();
criteria.addLessOrEqualThan(PdpPropertyConstants.DISBURSEMENT_NUMBER_RANGE_START_DATE, nowTs);
criteria.addEqualTo(PdpPropertyConstants.PHYS_CAMPUS_PROC_CODE, campus);
criteria.addEqualTo(KFSPropertyConstants.ACTIVE, true);
QueryByCriteria qbc = new QueryByCriteria(DisbursementNumberRange.class, criteria);
qbc.addOrderBy(KFSPropertyConstants.BANK_CODE, true);
return (List<DisbursementNumberRange>) getPersistenceBrokerTemplate().getCollectionByQuery(qbc);
}
/**
* @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getUnprocessedCancelledDetails(java.util.List)
*/
@Override
public Iterator getUnprocessedCancelledDetails(List<ExtractionUnit> extractionUnits) {
LOG.debug("getUnprocessedCancelledDetails() started");
Collection codes = new ArrayList();
codes.add(PdpConstants.PaymentStatusCodes.CANCEL_DISBURSEMENT);
codes.add(PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT);
Criteria subUnitsCriteria = buildExtractionUnitsCriteria(extractionUnits);
Criteria criteria = new Criteria();
criteria.addIn(PdpPropertyConstants.PaymentDetail.PAYMENT_STATUS_CODE, codes);
criteria.addIsNull(PdpPropertyConstants.PaymentDetail.PAYMENT_EPIC_PAYMENT_CANCELLED_DATE);
criteria.addAndCriteria(subUnitsCriteria);
return getPersistenceBrokerTemplate().getIteratorByQuery(new QueryByCriteria(PaymentDetail.class, criteria));
}
/**
* @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getUnprocessedPaidDetails(java.lang.String, java.lang.String)
*/
@Override
public Iterator getUnprocessedPaidDetails(List<ExtractionUnit> extractionUnits) {
LOG.debug("getUnprocessedPaidDetails() started");
Criteria subUnitsCriteria = buildExtractionUnitsCriteria(extractionUnits);
Criteria criteria = new Criteria();
criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_STATUS_CODE, PdpConstants.PaymentStatusCodes.EXTRACTED);
criteria.addIsNull(PdpPropertyConstants.PaymentDetail.PAYMENT_EPIC_PAYMENT_PAID_EXTRACTED_DATE);
criteria.addAndCriteria(subUnitsCriteria);
return getPersistenceBrokerTemplate().getIteratorByQuery(new QueryByCriteria(PaymentDetail.class, criteria));
}
/**
* Builds an "or" criteria from the List of extractionUnits
* @param extractionUnits the extractionUnits to build an or Criteria for
* @return an or Criteria to throw into a query
*/
protected Criteria buildExtractionUnitsCriteria(List<ExtractionUnit> extractionUnits) {
Criteria subUnitsCriteria = new Criteria();
for (ExtractionUnit extractionUnit : extractionUnits) {
Criteria subUnitCriteria = new Criteria();
subUnitCriteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_UNIT_CODE, extractionUnit.getUnit());
subUnitCriteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_SUBUNIT_CODE, extractionUnit.getSubUnit());
subUnitsCriteria.addOrCriteria(subUnitCriteria);
}
return subUnitsCriteria;
}
}