001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.pdp.dataaccess.impl;
017    
018    import java.sql.Timestamp;
019    import java.util.ArrayList;
020    import java.util.Calendar;
021    import java.util.Collection;
022    import java.util.Collections;
023    import java.util.Date;
024    import java.util.HashMap;
025    import java.util.Iterator;
026    import java.util.List;
027    import java.util.Map;
028    
029    import org.apache.commons.lang.builder.EqualsBuilder;
030    import org.apache.commons.lang.builder.HashCodeBuilder;
031    import org.apache.ojb.broker.query.Criteria;
032    import org.apache.ojb.broker.query.QueryByCriteria;
033    import org.apache.ojb.broker.query.QueryFactory;
034    import org.kuali.kfs.pdp.PdpConstants;
035    import org.kuali.kfs.pdp.PdpPropertyConstants;
036    import org.kuali.kfs.pdp.businessobject.DailyReport;
037    import org.kuali.kfs.pdp.businessobject.DisbursementNumberRange;
038    import org.kuali.kfs.pdp.businessobject.PaymentDetail;
039    import org.kuali.kfs.pdp.businessobject.PaymentGroup;
040    import org.kuali.kfs.pdp.businessobject.options.DailyReportComparator;
041    import org.kuali.kfs.pdp.dataaccess.PaymentDetailDao;
042    import org.kuali.kfs.sys.KFSParameterKeyConstants;
043    import org.kuali.kfs.sys.KFSPropertyConstants;
044    import org.kuali.kfs.sys.service.impl.KfsParameterConstants;
045    import org.kuali.rice.kns.dao.impl.PlatformAwareDaoBaseOjb;
046    import org.kuali.rice.kns.service.DateTimeService;
047    import org.kuali.rice.kns.service.ParameterService;
048    import org.kuali.rice.kns.util.KualiDecimal;
049    import org.kuali.rice.kns.util.KualiInteger;
050    
051    public class PaymentDetailDaoOjb extends PlatformAwareDaoBaseOjb implements PaymentDetailDao {
052        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PaymentDetailDaoOjb.class);
053    
054        private DateTimeService dateTimeService;
055        private ParameterService parameterService;
056    
057        public PaymentDetailDaoOjb() {
058            super();
059        }
060    
061    
062        /**
063         * @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getAchPaymentsWithUnsentEmail()
064         */
065        public Iterator getAchPaymentsWithUnsentEmail() {
066            LOG.debug("getAchPaymentsWithUnsentEmail() started");
067    
068            Criteria crit = new Criteria();
069            crit.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_STATUS_CODE, PdpConstants.PaymentStatusCodes.EXTRACTED);
070            crit.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_DISBURSEMENT_TYPE_CODE, PdpConstants.DisbursementTypeCodes.ACH);
071            crit.addIsNull(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.ADVICE_EMAIL_SENT_DATE);
072       
073            return getPersistenceBrokerTemplate().getIteratorByQuery(new QueryByCriteria(PaymentDetail.class,crit));
074        }
075    
076        /**
077         * @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getDailyReportData()
078         */
079        public List<DailyReport> getDailyReportData() {
080            LOG.debug("getDailyReportData() started");
081    
082            if (LOG.isDebugEnabled()) {
083                LOG.debug("getDailyReportData() " + dateTimeService.getCurrentSqlDate());
084            }
085    
086            Criteria criteria = new Criteria();
087            criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.PaymentGroup.PAYMENT_GROUP_PAYMENT_STATUS_CODE, PdpConstants.PaymentStatusCodes.OPEN);
088    
089            // (Payment date <= usePaydate OR immediate = TRUE)
090            Criteria criteria1 = new Criteria();
091            criteria1.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.PaymentGroup.PROCESS_IMMEDIATE, Boolean.TRUE);
092    
093            Criteria criteria2 = new Criteria();
094            criteria2.addLessOrEqualThan(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.PaymentGroup.PAYMENT_DATE, dateTimeService.getCurrentSqlDate());
095            criteria1.addOrCriteria(criteria2);
096    
097            criteria.addAndCriteria(criteria1);
098    
099            QueryByCriteria q = QueryFactory.newQuery(PaymentDetail.class, criteria);
100    
101            q.addOrderByDescending(PdpPropertyConstants.PaymentDetail.PAYMENT_PROCESS_IMEDIATE);
102            q.addOrderByDescending(PdpPropertyConstants.PaymentDetail.PAYMENT_SPECIAL_HANDLING);
103            q.addOrderByDescending(PdpPropertyConstants.PaymentDetail.PAYMENT_ATTACHMENT);
104            q.addOrderByAscending(PdpPropertyConstants.PaymentDetail.PAYMENT_CHART_CODE);
105            q.addOrderByAscending(PdpPropertyConstants.PaymentDetail.PAYMENT_UNIT_CODE);
106            q.addOrderByAscending(PdpPropertyConstants.PaymentDetail.PAYMENT_SUBUNIT_CODE);
107            q.addOrderByAscending(PdpPropertyConstants.PaymentDetail.PAYMENT_GROUP + "." + PdpPropertyConstants.PaymentGroup.PAYMENT_GROUP_ID);
108    
109            Map<Key, Numbers> summary = new HashMap<Key, Numbers>();
110            KualiInteger lastGroupId = null;
111            Iterator i = getPersistenceBrokerTemplate().getIteratorByQuery(q);
112            while (i.hasNext()) {
113                PaymentDetail d = (PaymentDetail) i.next();
114                Key rsk = new Key(d);
115                Numbers n = summary.get(rsk);
116                if (n == null) {
117                    n = new Numbers();
118                    n.amount = d.getNetPaymentAmount();
119                    n.payments = 1;
120                    n.payees = 1;
121                    summary.put(rsk, n);
122                    lastGroupId = d.getPaymentGroup().getId();
123                }
124                else {
125                    n.payments++;
126                    n.amount = n.amount.add(d.getNetPaymentAmount());
127                    if (lastGroupId.intValue() != d.getPaymentGroup().getId().intValue()) {
128                        n.payees++;
129                        lastGroupId = d.getPaymentGroup().getId();
130                    }
131                }
132            }
133            // Now take the data and put it in our result list
134            List<DailyReport> data = new ArrayList<DailyReport>();
135            for (Iterator iter = summary.keySet().iterator(); iter.hasNext();) {
136                Key e = (Key)iter.next();
137                Numbers n = summary.get(e);
138                DailyReport r = new DailyReport(e.customerShortName, n.amount, n.payments, n.payees, e.paymentGroup);
139                data.add(r);
140            }
141            Collections.sort(data, new DailyReportComparator());
142            
143            return data;
144        }
145    
146        class Key {
147            public Boolean pymtAttachment;
148            public Boolean pymtSpecialHandling;
149            public Boolean processImmediate;
150            public String customerShortName;
151            public PaymentGroup paymentGroup;
152    
153            public Key(PaymentDetail d) {
154                this(d.getPaymentGroup().getPymtAttachment(),d.getPaymentGroup().getPymtSpecialHandling(),
155                        d.getPaymentGroup().getProcessImmediate(), d.getPaymentGroup().getBatch().getCustomerProfile().getCustomerShortName(), d.getPaymentGroup());
156            }
157    
158            public Key(Boolean att,Boolean spec,Boolean immed, String c, PaymentGroup paymentGroup) {
159                pymtAttachment = att;
160                pymtSpecialHandling = spec;
161                processImmediate = immed;
162                customerShortName = c;
163                this.paymentGroup = paymentGroup;
164            }
165    
166            @Override
167            public int hashCode() {
168                return new HashCodeBuilder(3, 5).append(pymtAttachment)
169                .append(pymtSpecialHandling)
170                .append(processImmediate)
171                .append(customerShortName).toHashCode();
172            }
173            
174            @Override
175            public boolean equals(Object obj) {
176                if (!(obj instanceof Key)) {
177                    return false;
178                }
179                Key thisobj = (Key) obj;
180                return new EqualsBuilder().append(pymtAttachment, thisobj.pymtAttachment)
181                .append(pymtSpecialHandling, thisobj.pymtSpecialHandling)
182                .append(processImmediate, thisobj.processImmediate)
183                .append(customerShortName, thisobj.customerShortName).isEquals();
184            }
185    
186            @Override
187            public String toString() {
188                return pymtAttachment + " " + pymtSpecialHandling + " " + processImmediate + " " + customerShortName;
189            }
190        }
191    
192        class Numbers {
193            public KualiDecimal amount = KualiDecimal.ZERO;
194            public int payments = 0;
195            public int payees = 0;
196        }
197    
198        /**
199         * @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getDetailForEpic(java.lang.String, java.lang.String)
200         */
201        public PaymentDetail getDetailForEpic(String custPaymentDocNbr, String fdocTypeCode) {
202            LOG.debug("getDetailForEpic(custPaymentDocNbr, fdocTypeCode) started");
203            List data = new ArrayList();
204    
205            Criteria criteria = new Criteria();
206            criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_CUSTOMER_DOC_NUMBER, custPaymentDocNbr);
207            criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_DISBURSEMENT_FINANCIAL_DOCUMENT_TYPE_CODE, fdocTypeCode);
208    
209            String orgCode = parameterService.getParameterValue(KfsParameterConstants.PURCHASING_BATCH.class, KFSParameterKeyConstants.PurapPdpParameterConstants.PURAP_PDP_ORG_CODE);
210            String subUnitCode = parameterService.getParameterValue(KfsParameterConstants.PURCHASING_BATCH.class, KFSParameterKeyConstants.PurapPdpParameterConstants.PURAP_PDP_SUB_UNIT_CODE);
211    
212            criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_UNIT_CODE, orgCode);
213            criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_SUBUNIT_CODE, subUnitCode);
214    
215            List paymentDetails = (List) getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(PaymentDetail.class, criteria));
216            PaymentDetail cp = null;
217            for (Iterator iter = paymentDetails.iterator(); iter.hasNext();) {
218                PaymentDetail pd = (PaymentDetail) iter.next();
219                if (cp == null) {
220                    cp = pd;
221                }
222                else {
223                    if ((pd.getPaymentGroup().getBatch().getCustomerFileCreateTimestamp().compareTo(cp.getPaymentGroup().getBatch().getCustomerFileCreateTimestamp())) > 0) {
224                        cp = pd;
225                    }
226                }
227            }
228    
229            return cp;
230        }
231    
232        /**
233         * @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getDisbursementNumberRanges(java.lang.String)
234         */
235        public List<DisbursementNumberRange> getDisbursementNumberRanges(String campus) {
236            LOG.debug("getDisbursementNumberRanges() started");
237    
238            Date now = new Date();
239            Timestamp nowTs = new Timestamp(now.getTime());
240    
241            Criteria criteria = new Criteria();
242            criteria.addLessOrEqualThan(PdpPropertyConstants.DISBURSEMENT_NUMBER_RANGE_START_DATE, nowTs);
243            criteria.addEqualTo(PdpPropertyConstants.PHYS_CAMPUS_PROC_CODE, campus);
244            criteria.addEqualTo(KFSPropertyConstants.ACTIVE, true);
245    
246            QueryByCriteria qbc = new QueryByCriteria(DisbursementNumberRange.class, criteria);
247            qbc.addOrderBy(KFSPropertyConstants.BANK_CODE, true);
248    
249            return (List<DisbursementNumberRange>) getPersistenceBrokerTemplate().getCollectionByQuery(qbc);
250        }
251    
252        /**
253         * @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getUnprocessedCancelledDetails(java.lang.String, java.lang.String)
254         */
255        public Iterator getUnprocessedCancelledDetails(String organization, List<String> subUnits) {
256            LOG.debug("getUnprocessedCancelledDetails() started");
257    
258            Collection codes = new ArrayList();
259            codes.add(PdpConstants.PaymentStatusCodes.CANCEL_DISBURSEMENT);
260            codes.add(PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT);
261    
262            Criteria criteria = new Criteria();
263            criteria.addIn(PdpPropertyConstants.PaymentDetail.PAYMENT_SUBUNIT_CODE, subUnits);
264            criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_UNIT_CODE, organization);
265            criteria.addIn(PdpPropertyConstants.PaymentDetail.PAYMENT_STATUS_CODE, codes);
266            criteria.addIsNull(PdpPropertyConstants.PaymentDetail.PAYMENT_EPIC_PAYMENT_CANCELLED_DATE);
267    
268            return getPersistenceBrokerTemplate().getIteratorByQuery(new QueryByCriteria(PaymentDetail.class, criteria));
269        }
270    
271        /**
272         * @see org.kuali.kfs.pdp.dataaccess.PaymentDetailDao#getUnprocessedPaidDetails(java.lang.String, java.lang.String)
273         */
274        public Iterator getUnprocessedPaidDetails(String organization, List<String> subUnits) {
275            LOG.debug("getUnprocessedPaidDetails() started");
276    
277            Criteria criteria = new Criteria();
278            criteria.addIn(PdpPropertyConstants.PaymentDetail.PAYMENT_SUBUNIT_CODE, subUnits);
279            criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_UNIT_CODE, organization);
280            criteria.addEqualTo(PdpPropertyConstants.PaymentDetail.PAYMENT_STATUS_CODE, PdpConstants.PaymentStatusCodes.EXTRACTED);
281            criteria.addIsNull(PdpPropertyConstants.PaymentDetail.PAYMENT_EPIC_PAYMENT_PAID_EXTRACTED_DATE);
282    
283            return getPersistenceBrokerTemplate().getIteratorByQuery(new QueryByCriteria(PaymentDetail.class, criteria));
284        }
285    
286        public void setDateTimeService(DateTimeService dts) {
287            dateTimeService = dts;
288        }
289    
290        public void setParameterService(ParameterService ps) {
291            parameterService = ps;
292        }
293    }
294