View Javadoc

1   /*
2    * Copyright 2007 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.module.purap.service.impl;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.commons.lang.builder.EqualsBuilder;
20  import org.apache.commons.lang.builder.HashCodeBuilder;
21  import org.kuali.ole.module.purap.PurapConstants;
22  import org.kuali.ole.module.purap.batch.service.PurapRunDateService;
23  import org.kuali.ole.module.purap.businessobject.CreditMemoItem;
24  import org.kuali.ole.module.purap.businessobject.PaymentRequestItem;
25  import org.kuali.ole.module.purap.document.AccountsPayableDocument;
26  import org.kuali.ole.module.purap.document.PaymentRequestDocument;
27  import org.kuali.ole.module.purap.document.VendorCreditMemoDocument;
28  import org.kuali.ole.module.purap.document.service.CreditMemoService;
29  import org.kuali.ole.module.purap.document.service.PaymentRequestService;
30  import org.kuali.ole.module.purap.document.service.PurapService;
31  import org.kuali.ole.module.purap.service.PdpExtractService;
32  import org.kuali.ole.module.purap.util.VendorGroupingHelper;
33  import org.kuali.ole.pdp.PdpConstants;
34  import org.kuali.ole.pdp.PdpParameterConstants;
35  import org.kuali.ole.pdp.businessobject.*;
36  import org.kuali.ole.pdp.service.*;
37  import org.kuali.ole.sys.OLEConstants;
38  import org.kuali.ole.sys.OLEParameterKeyConstants;
39  import org.kuali.ole.sys.businessobject.SourceAccountingLine;
40  import org.kuali.ole.sys.context.SpringContext;
41  import org.kuali.ole.sys.service.BankService;
42  import org.kuali.ole.sys.service.impl.OleParameterConstants;
43  import org.kuali.ole.sys.util.KfsDateUtils;
44  import org.kuali.ole.vnd.VendorConstants;
45  import org.kuali.rice.core.api.datetime.DateTimeService;
46  import org.kuali.rice.core.api.util.type.KualiDecimal;
47  import org.kuali.rice.core.api.util.type.KualiInteger;
48  import org.kuali.rice.coreservice.api.parameter.Parameter;
49  import org.kuali.rice.coreservice.api.parameter.Parameter.Builder;
50  import org.kuali.rice.coreservice.api.parameter.ParameterType;
51  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
52  import org.kuali.rice.kew.api.exception.WorkflowException;
53  import org.kuali.rice.kim.api.identity.Person;
54  import org.kuali.rice.kim.api.identity.PersonService;
55  import org.kuali.rice.kns.service.DataDictionaryService;
56  import org.kuali.rice.krad.document.Document;
57  import org.kuali.rice.krad.service.BusinessObjectService;
58  import org.kuali.rice.krad.service.DocumentService;
59  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
60  import org.springframework.transaction.annotation.Transactional;
61  
62  import java.sql.Timestamp;
63  import java.util.*;
64  
65  /**
66   * Implementation of PdpExtractService
67   */
68  @Transactional
69  public class PdpExtractServiceImpl implements PdpExtractService {
70      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PdpExtractServiceImpl.class);
71  
72      private PaymentRequestService paymentRequestService;
73      private BusinessObjectService businessObjectService;
74      private PaymentFileService paymentFileService;
75      private ParameterService parameterService;
76      private CustomerProfileService customerProfileService;
77      private DateTimeService dateTimeService;
78      private PersonService personService;
79      private PaymentGroupService paymentGroupService;
80      private PaymentDetailService paymentDetailService;
81      private CreditMemoService creditMemoService;
82      private DocumentService documentService;
83      private PurapRunDateService purapRunDateService;
84      private PdpEmailService paymentFileEmailService;
85      private BankService bankService;
86      private DataDictionaryService dataDictionaryService;
87      private PurapAccountingServiceImpl purapAccountingService;
88      private List<String> lockedDocuments;
89  
90      /**
91       * @see org.kuali.ole.module.purap.service.PdpExtractService#extractImmediatePaymentsOnly()
92       */
93      @Override
94      public void extractImmediatePaymentsOnly() {
95          LOG.debug("extractImmediatePaymentsOnly() started");
96          Date processRunDate = dateTimeService.getCurrentDate();
97          lockUnlockDocuments(true);
98          try {
99              extractPayments(true, processRunDate);
100         } finally {
101             lockUnlockDocuments(false);
102         }
103     }
104 
105     /**
106      * @see org.kuali.ole.module.purap.service.PdpExtractService#extractPayments(Date)
107      */
108     @Override
109     public void extractPayments(Date runDate) {
110         LOG.debug("extractPayments() started");
111 
112         extractPayments(false, runDate);
113     }
114 
115     /**
116      * Extracts payments from the database
117      *
118      * @param immediateOnly  whether to pick up immediate payments only
119      * @param processRunDate time/date to use to put on the {@link Batch} that's created; and when immediateOnly is false, is also
120      *                       used as the maximum allowed PREQ pay date when searching PREQ documents eligible to have payments extracted
121      */
122     protected void extractPayments(boolean immediateOnly, Date processRunDate) {
123         LOG.debug("extractPayments() started");
124 
125         Person uuser = getPersonService().getPersonByPrincipalName(OLEConstants.SYSTEM_USER);
126         if (uuser == null) {
127             LOG.error("extractPayments() Unable to find user " + OLEConstants.SYSTEM_USER);
128             throw new IllegalArgumentException("Unable to find user " + OLEConstants.SYSTEM_USER);
129         }
130 
131         List<String> campusesToProcess = getChartCodes(immediateOnly, processRunDate);
132         for (String campus : campusesToProcess) {
133             extractPaymentsForCampus(campus, uuser, processRunDate, immediateOnly);
134         }
135     }
136 
137     /**
138      * Handle a single campus
139      *
140      * @param campusCode
141      * @param puser
142      * @param processRunDate
143      */
144     protected void extractPaymentsForCampus(String campusCode, Person puser, Date processRunDate, boolean immediateOnly) {
145         if (LOG.isDebugEnabled()) {
146             LOG.debug("extractPaymentsForCampus() started for campus: " + campusCode);
147         }
148 
149         Batch batch = createBatch(campusCode, puser, processRunDate);
150 
151         Integer count = 0;
152         KualiDecimal totalAmount = KualiDecimal.ZERO;
153 
154         // Do all the special ones
155         Totals totals = extractSpecialPaymentsForChart(campusCode, puser, processRunDate, batch, immediateOnly);
156         count = count + totals.count;
157         totalAmount = totalAmount.add(totals.totalAmount);
158 
159         if (!immediateOnly) {
160             // Do all the regular ones (including credit memos)
161             totals = extractRegularPaymentsForChart(campusCode, puser, processRunDate, batch);
162             count = count + totals.count;
163             totalAmount = totalAmount.add(totals.totalAmount);
164         }
165 
166         batch.setPaymentCount(new KualiInteger(count));
167         batch.setPaymentTotalAmount(totalAmount);
168 
169         businessObjectService.save(batch);
170         paymentFileEmailService.sendLoadEmail(batch);
171     }
172 
173     /**
174      * Get all the payments that could be combined with credit memos
175      *
176      * @param campusCode
177      * @param puser
178      * @param processRunDate
179      * @param batch
180      * @return Totals
181      */
182     protected Totals extractRegularPaymentsForChart(String campusCode, Person puser, Date processRunDate, Batch batch) {
183         LOG.debug("START - extractRegularPaymentsForChart()");
184 
185         Totals totals = new Totals();
186 
187         java.sql.Date onOrBeforePaymentRequestPayDate = KfsDateUtils.convertToSqlDate(purapRunDateService.calculateRunDate(processRunDate));
188 
189         List<String> preqsWithOutstandingCreditMemos = new ArrayList<String>();
190 
191         Set<VendorGroupingHelper> vendors = creditMemoService.getVendorsOnCreditMemosToExtract(campusCode);
192         for (VendorGroupingHelper vendor : vendors) {
193             if (LOG.isDebugEnabled()) {
194                 LOG.debug("Processing Vendor: " + vendor);
195             }
196 
197             Map<String, List<PaymentRequestDocument>> bankCodePaymentRequests = new HashMap<String, List<PaymentRequestDocument>>();
198             Map<String, List<VendorCreditMemoDocument>> bankCodeCreditMemos = new HashMap<String, List<VendorCreditMemoDocument>>();
199 
200             // Get all the matching credit memos
201             Collection<VendorCreditMemoDocument> vendorMemos = creditMemoService.getCreditMemosToExtractByVendor(campusCode, vendor);
202             for (VendorCreditMemoDocument cmd : vendorMemos) {
203                 List<VendorCreditMemoDocument> bankMemos = new ArrayList<VendorCreditMemoDocument>();
204                 if (bankCodeCreditMemos.containsKey(cmd.getBankCode())) {
205                     bankMemos = bankCodeCreditMemos.get(cmd.getBankCode());
206                 }
207 
208                 bankMemos.add(cmd);
209                 bankCodeCreditMemos.put(cmd.getBankCode(), bankMemos);
210             }
211 
212             // get all matching payment requests
213             Collection<PaymentRequestDocument> vendorPreqs = paymentRequestService.getPaymentRequestsToExtractByVendor(campusCode, vendor, onOrBeforePaymentRequestPayDate);
214             for (PaymentRequestDocument prd : vendorPreqs) {
215                 List<PaymentRequestDocument> bankPreqs = new ArrayList<PaymentRequestDocument>();
216                 if (bankCodePaymentRequests.containsKey(prd.getBankCode())) {
217                     bankPreqs = bankCodePaymentRequests.get(prd.getBankCode());
218                 }
219 
220                 bankPreqs.add(prd);
221                 bankCodePaymentRequests.put(prd.getBankCode(), bankPreqs);
222             }
223 
224             // if bank functionality enabled, create bundles by bank, else just by vendor
225             if (bankService.isBankSpecificationEnabled()) {
226                 for (String bankCode : bankCodePaymentRequests.keySet()) {
227                     // if we have credit memos with bank code, process together, else let the preq go and will get picked up below
228                     // and processed as a single payment group
229                     if (bankCodeCreditMemos.containsKey(bankCode)) {
230                         processPaymentBundle(bankCodePaymentRequests.get(bankCode), bankCodeCreditMemos.get(bankCode), totals, preqsWithOutstandingCreditMemos, puser, processRunDate, batch);
231                     }
232                 }
233             } else {
234                 if (vendorMemos.isEmpty()) {
235                     processPaymentBundle((List<PaymentRequestDocument>) vendorPreqs, (List<VendorCreditMemoDocument>) vendorMemos, totals, preqsWithOutstandingCreditMemos, puser, processRunDate, batch);
236                 }
237             }
238         }
239 
240         LOG.debug("processing PREQs without CMs");
241 
242         Iterator<PaymentRequestDocument> paymentRequests = paymentRequestService.getPaymentRequestToExtractByChart(campusCode, onOrBeforePaymentRequestPayDate).iterator();
243         while (paymentRequests.hasNext()) {
244             PaymentRequestDocument prd = paymentRequests.next();
245             // if in the list created above, don't create the payment group
246             if (!preqsWithOutstandingCreditMemos.contains(prd.getDocumentNumber())) {
247                 PaymentGroup paymentGroup = processSinglePaymentRequestDocument(prd, batch, puser, processRunDate);
248 
249                 totals.count = totals.count + paymentGroup.getPaymentDetails().size();
250                 totals.totalAmount = totals.totalAmount.add(paymentGroup.getNetPaymentAmount());
251             }
252         }
253 
254 
255         LOG.debug("END - extractRegularPaymentsForChart()");
256         return totals;
257     }
258 
259     /**
260      * Processes the list of payment requests and credit memos as a payment group pending
261      *
262      * @param paymentRequests
263      * @param creditMemos
264      * @param totals
265      * @param preqsWithOutstandingCreditMemos
266      *
267      * @param puser
268      * @param processRunDate
269      * @param batch
270      */
271     protected void processPaymentBundle(List<PaymentRequestDocument> paymentRequests, List<VendorCreditMemoDocument> creditMemos, Totals totals, List<String> preqsWithOutstandingCreditMemos, Person puser, Date processRunDate, Batch batch) {
272         KualiDecimal paymentRequestAmount = KualiDecimal.ZERO;
273         for (PaymentRequestDocument paymentRequestDocument : paymentRequests) {
274             paymentRequestAmount = paymentRequestAmount.add(paymentRequestDocument.getGrandTotal());
275         }
276 
277         KualiDecimal creditMemoAmount = KualiDecimal.ZERO;
278         for (VendorCreditMemoDocument creditMemoDocument : creditMemos) {
279             creditMemoAmount = creditMemoAmount.add(creditMemoDocument.getCreditMemoAmount());
280         }
281 
282         // if payment amount greater than credit, create bundle
283         boolean bundleCreated = false;
284         if (paymentRequestAmount.compareTo(creditMemoAmount) >= 0) {
285             PaymentGroup paymentGroup = buildPaymentGroup(paymentRequests, creditMemos, batch);
286 
287             if (validatePaymentGroup(paymentGroup)) {
288                 this.businessObjectService.save(paymentGroup);
289                 if (LOG.isDebugEnabled()) {
290                     LOG.debug("Created PaymentGroup: " + paymentGroup.getId());
291                 }
292 
293                 totals.count++;
294                 totals.totalAmount = totals.totalAmount.add(paymentGroup.getNetPaymentAmount());
295 
296                 // mark the CMs and PREQs as processed
297                 for (VendorCreditMemoDocument cm : creditMemos) {
298                     updateCreditMemo(cm, puser, processRunDate);
299                 }
300 
301                 for (PaymentRequestDocument pr : paymentRequests) {
302                     updatePaymentRequest(pr, puser, processRunDate);
303                 }
304 
305                 bundleCreated = true;
306             }
307         }
308 
309         if (!bundleCreated) {
310             // add payment request doc numbers to list so they don't get picked up later
311             for (PaymentRequestDocument doc : paymentRequests) {
312                 preqsWithOutstandingCreditMemos.add(doc.getDocumentNumber());
313             }
314         }
315     }
316 
317     /**
318      * Handle a single payment request with no credit memos
319      *
320      * @param paymentRequestDocument
321      * @param batch
322      * @param puser
323      * @param processRunDate
324      * @return PaymentGroup
325      */
326     protected PaymentGroup processSinglePaymentRequestDocument(PaymentRequestDocument paymentRequestDocument, Batch batch, Person puser, Date processRunDate) {
327         List<PaymentRequestDocument> prds = new ArrayList<PaymentRequestDocument>();
328         List<VendorCreditMemoDocument> cmds = new ArrayList<VendorCreditMemoDocument>();
329         prds.add(paymentRequestDocument);
330 
331         PaymentGroup paymentGroup = buildPaymentGroup(prds, cmds, batch);
332         if (validatePaymentGroup(paymentGroup)) {
333             this.businessObjectService.save(paymentGroup);
334             updatePaymentRequest(paymentRequestDocument, puser, processRunDate);
335         }
336 
337         return paymentGroup;
338     }
339 
340     /**
341      * Get all the special payments for a campus and process them
342      *
343      * @param campusCode
344      * @param puser
345      * @param processRunDate
346      * @param batch
347      * @return Totals
348      */
349     protected Totals extractSpecialPaymentsForChart(String campusCode, Person puser, Date processRunDate, Batch batch, boolean immediatesOnly) {
350         Totals totals = new Totals();
351 
352         Iterator<PaymentRequestDocument> paymentRequests = null;
353         if (immediatesOnly) {
354             paymentRequests = paymentRequestService.getImmediatePaymentRequestsToExtract(campusCode).iterator();
355         } else {
356             java.sql.Date onOrBeforePaymentRequestPayDate = KfsDateUtils.convertToSqlDate(purapRunDateService.calculateRunDate(processRunDate));
357             paymentRequests = paymentRequestService.getPaymentRequestsToExtractSpecialPayments(campusCode, onOrBeforePaymentRequestPayDate).iterator();
358         }
359 
360         while (paymentRequests.hasNext()) {
361             PaymentRequestDocument prd = paymentRequests.next();
362             PaymentGroup pg = processSinglePaymentRequestDocument(prd, batch, puser, processRunDate);
363 
364             totals.count = totals.count + pg.getPaymentDetails().size();
365             totals.totalAmount = totals.totalAmount.add(pg.getNetPaymentAmount());
366         }
367 
368         return totals;
369     }
370 
371 
372     /**
373      * Mark a credit memo as extracted
374      *
375      * @param creditMemoDocument
376      * @param puser
377      * @param processRunDate
378      */
379     protected void updateCreditMemo(VendorCreditMemoDocument creditMemoDocument, Person puser, Date processRunDate) {
380         try {
381             VendorCreditMemoDocument doc = (VendorCreditMemoDocument) documentService.getByDocumentHeaderId(creditMemoDocument.getDocumentNumber());
382             doc.setExtractedTimestamp(new Timestamp(processRunDate.getTime()));
383             SpringContext.getBean(PurapService.class).saveDocumentNoValidation(doc);
384         } catch (WorkflowException e) {
385             throw new IllegalArgumentException("Unable to retrieve credit memo: " + creditMemoDocument.getDocumentNumber());
386         }
387     }
388 
389     /**
390      * Mark a payment request as extracted
391      *
392      * @param prd
393      * @param puser
394      * @param processRunDate
395      */
396     protected void updatePaymentRequest(PaymentRequestDocument paymentRequestDocument, Person puser, Date processRunDate) {
397         try {
398             PaymentRequestDocument doc = (PaymentRequestDocument) documentService.getByDocumentHeaderId(paymentRequestDocument.getDocumentNumber());
399             doc.setExtractedTimestamp(new Timestamp(processRunDate.getTime()));
400             SpringContext.getBean(PurapService.class).saveDocumentNoValidation(doc);
401         } catch (WorkflowException e) {
402             throw new IllegalArgumentException("Unable to retrieve payment request: " + paymentRequestDocument.getDocumentNumber());
403         }
404     }
405 
406     /**
407      * Create the PDP payment group from a list of payment requests & credit memos
408      *
409      * @param paymentRequests
410      * @param creditMemos
411      * @param batch
412      * @return PaymentGroup
413      */
414     protected PaymentGroup buildPaymentGroup(List<PaymentRequestDocument> paymentRequests, List<VendorCreditMemoDocument> creditMemos, Batch batch) {
415         // There should always be at least one Payment Request Document in the list.
416         PaymentGroup paymentGroup = null;
417         if (creditMemos.size() > 0) {
418             VendorCreditMemoDocument firstCmd = creditMemos.get(0);
419             paymentGroup = populatePaymentGroup(firstCmd, batch);
420         } else {
421             PaymentRequestDocument firstPrd = paymentRequests.get(0);
422             paymentGroup = populatePaymentGroup(firstPrd, batch);
423         }
424 
425         for (PaymentRequestDocument pr : paymentRequests) {
426             PaymentDetail pd = populatePaymentDetail(pr, batch);
427             paymentGroup.addPaymentDetails(pd);
428         }
429         for (VendorCreditMemoDocument cm : creditMemos) {
430             PaymentDetail pd = populatePaymentDetail(cm, batch);
431             paymentGroup.addPaymentDetails(pd);
432         }
433 
434         return paymentGroup;
435     }
436 
437     /**
438      * Checks payment group note lines does not exceed the maximum allowed
439      *
440      * @param paymentGroup group to validate
441      * @return true if group is valid, false otherwise
442      */
443     protected boolean validatePaymentGroup(PaymentGroup paymentGroup) {
444         // Check to see if the payment group has too many note lines to be printed on a check
445         List<PaymentDetail> payDetails = paymentGroup.getPaymentDetails();
446 
447         int noteLines = 0;
448         for (PaymentDetail paymentDetail : payDetails) {
449             noteLines++; // Add one for each payment detail; summary of each detail is included on check and counts as a line
450             noteLines += paymentDetail.getNotes().size(); // get all the possible notes for a given detail
451         }
452 
453         int maxNoteLines = getMaxNoteLines();
454         if (noteLines > maxNoteLines) {
455             // compile list of all doc numbers that make up payment group
456             List<String> preqDocIds = new ArrayList<String>();
457             List<String> cmDocIds = new ArrayList<String>();
458 
459             List<PaymentDetail> pds = paymentGroup.getPaymentDetails();
460             for (PaymentDetail payDetail : pds) {
461                 if (OLEConstants.FinancialDocumentTypeCodes.VENDOR_CREDIT_MEMO.equals(payDetail.getFinancialDocumentTypeCode())) {
462                     cmDocIds.add(payDetail.getCustPaymentDocNbr());
463                 } else {
464                     preqDocIds.add(payDetail.getCustPaymentDocNbr());
465                 }
466             }
467 
468             // send warning email and prevent group from being processed by returning false
469             paymentFileEmailService.sendExceedsMaxNotesWarningEmail(cmDocIds, preqDocIds, noteLines, maxNoteLines);
470 
471             return false;
472         }
473 
474         return true;
475     }
476 
477     /**
478      * @return configured maximum number of note lines allowed
479      */
480     protected int getMaxNoteLines() {
481         String maxLines = parameterService.getParameterValueAsString(OleParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.MAX_NOTE_LINES);
482         if (StringUtils.isBlank(maxLines)) {
483             throw new RuntimeException("System parameter for max note lines is blank");
484         }
485 
486         return Integer.parseInt(maxLines);
487     }
488 
489     /**
490      * Create a PDP payment detail record from a Credit Memo document
491      *
492      * @param creditMemoDocument Credit Memo to use for payment detail
493      * @param batch              current PDP batch object
494      * @return populated PaymentDetail line
495      */
496     protected PaymentDetail populatePaymentDetail(VendorCreditMemoDocument creditMemoDocument, Batch batch) {
497         PaymentDetail paymentDetail = new PaymentDetail();
498 
499         String invoiceNumber = creditMemoDocument.getCreditMemoNumber();
500         if (invoiceNumber.length() > 25) {
501             invoiceNumber = invoiceNumber.substring(0, 25);
502         }
503         paymentDetail.setInvoiceNbr(invoiceNumber);
504         paymentDetail.setCustPaymentDocNbr(creditMemoDocument.getDocumentNumber());
505 
506         if (creditMemoDocument.getPurchaseOrderIdentifier() != null) {
507             paymentDetail.setPurchaseOrderNbr(creditMemoDocument.getPurchaseOrderIdentifier().toString());
508         }
509 
510         if (creditMemoDocument.getPurchaseOrderDocument() != null) {
511             if (creditMemoDocument.getPurchaseOrderDocument().getRequisitionIdentifier() != null) {
512                 paymentDetail.setRequisitionNbr(creditMemoDocument.getPurchaseOrderDocument().getRequisitionIdentifier().toString());
513             }
514 
515             if (creditMemoDocument.getDocumentHeader().getOrganizationDocumentNumber() != null) {
516                 paymentDetail.setOrganizationDocNbr(creditMemoDocument.getDocumentHeader().getOrganizationDocumentNumber());
517             }
518         }
519 
520         paymentDetail.setCustomerInstitutionNumber(StringUtils.defaultString(creditMemoDocument.getVendorCustomerNumber()));
521 
522         final String creditMemoDocType = getDataDictionaryService().getDocumentTypeNameByClass(creditMemoDocument.getClass());
523         paymentDetail.setFinancialDocumentTypeCode(creditMemoDocType);
524         paymentDetail.setFinancialSystemOriginCode(OLEConstants.ORIGIN_CODE_KUALI);
525 
526         paymentDetail.setInvoiceDate(creditMemoDocument.getCreditMemoDate());
527         paymentDetail.setOrigInvoiceAmount(creditMemoDocument.getCreditMemoAmount().negated());
528         paymentDetail.setNetPaymentAmount(creditMemoDocument.getFinancialSystemDocumentHeader().getFinancialDocumentTotalAmount().negated());
529 
530         KualiDecimal shippingAmount = KualiDecimal.ZERO;
531         KualiDecimal discountAmount = KualiDecimal.ZERO;
532         KualiDecimal creditAmount = KualiDecimal.ZERO;
533         KualiDecimal debitAmount = KualiDecimal.ZERO;
534 
535         for (Iterator iter = creditMemoDocument.getItems().iterator(); iter.hasNext(); ) {
536             CreditMemoItem item = (CreditMemoItem) iter.next();
537 
538             KualiDecimal itemAmount = KualiDecimal.ZERO;
539             if (item.getExtendedPrice() != null) {
540                 itemAmount = item.getExtendedPrice();
541             }
542             if (PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE.equals(item.getItemTypeCode())) {
543                 discountAmount = discountAmount.subtract(itemAmount);
544             } else if (PurapConstants.ItemTypeCodes.ITEM_TYPE_SHIP_AND_HAND_CODE.equals(item.getItemTypeCode())) {
545                 shippingAmount = shippingAmount.subtract(itemAmount);
546             } else if (PurapConstants.ItemTypeCodes.ITEM_TYPE_FREIGHT_CODE.equals(item.getItemTypeCode())) {
547                 shippingAmount = shippingAmount.add(itemAmount);
548             } else if (PurapConstants.ItemTypeCodes.ITEM_TYPE_MIN_ORDER_CODE.equals(item.getItemTypeCode())) {
549                 debitAmount = debitAmount.subtract(itemAmount);
550             } else if (PurapConstants.ItemTypeCodes.ITEM_TYPE_MISC_CODE.equals(item.getItemTypeCode())) {
551                 if (itemAmount.isNegative()) {
552                     creditAmount = creditAmount.subtract(itemAmount);
553                 } else {
554                     debitAmount = debitAmount.subtract(itemAmount);
555                 }
556             }
557         }
558 
559         paymentDetail.setInvTotDiscountAmount(discountAmount);
560         paymentDetail.setInvTotShipAmount(shippingAmount);
561         paymentDetail.setInvTotOtherCreditAmount(creditAmount);
562         paymentDetail.setInvTotOtherDebitAmount(debitAmount);
563 
564         paymentDetail.setPrimaryCancelledPayment(Boolean.FALSE);
565 
566         addAccounts(creditMemoDocument, paymentDetail, creditMemoDocType);
567         addNotes(creditMemoDocument, paymentDetail);
568 
569         return paymentDetail;
570     }
571 
572     /**
573      * Create a PDP Payment Detail record from a Payment Request document
574      *
575      * @param paymentRequestDocument Payment Request to use for Payment Detail
576      * @param batch                  current PDP batch object
577      * @return populated PaymentDetail line
578      */
579     protected PaymentDetail populatePaymentDetail(PaymentRequestDocument paymentRequestDocument, Batch batch) {
580         PaymentDetail paymentDetail = new PaymentDetail();
581 
582         paymentDetail.setCustPaymentDocNbr(paymentRequestDocument.getDocumentNumber());
583 
584         String invoiceNumber = paymentRequestDocument.getInvoiceNumber();
585         if (invoiceNumber.length() > 25) {
586             invoiceNumber = invoiceNumber.substring(0, 25);
587         }
588         paymentDetail.setInvoiceNbr(invoiceNumber);
589 
590         if (paymentRequestDocument.getPurchaseOrderIdentifier() != null) {
591             paymentDetail.setPurchaseOrderNbr(paymentRequestDocument.getPurchaseOrderIdentifier().toString());
592         }
593 
594         if (paymentRequestDocument.getPurchaseOrderDocument().getRequisitionIdentifier() != null) {
595             paymentDetail.setRequisitionNbr(paymentRequestDocument.getPurchaseOrderDocument().getRequisitionIdentifier().toString());
596         }
597 
598         if (paymentRequestDocument.getDocumentHeader().getOrganizationDocumentNumber() != null) {
599             paymentDetail.setOrganizationDocNbr(paymentRequestDocument.getDocumentHeader().getOrganizationDocumentNumber());
600         }
601 
602         paymentDetail.setCustomerInstitutionNumber(StringUtils.defaultString(paymentRequestDocument.getVendorCustomerNumber()));
603 
604         final String paymentRequestDocType = getDataDictionaryService().getDocumentTypeNameByClass(paymentRequestDocument.getClass());
605         paymentDetail.setFinancialDocumentTypeCode(paymentRequestDocType);
606         paymentDetail.setFinancialSystemOriginCode(OLEConstants.ORIGIN_CODE_KUALI);
607 
608         paymentDetail.setInvoiceDate(paymentRequestDocument.getInvoiceDate());
609         paymentDetail.setOrigInvoiceAmount(paymentRequestDocument.getVendorInvoiceAmount());
610         if (paymentRequestDocument.isUseTaxIndicator()) {
611             paymentDetail.setNetPaymentAmount(paymentRequestDocument.getGrandPreTaxTotal()); // including discounts
612         } else {
613             paymentDetail.setNetPaymentAmount(paymentRequestDocument.getGrandTotal()); // including discounts
614         }
615 
616         KualiDecimal shippingAmount = KualiDecimal.ZERO;
617         KualiDecimal discountAmount = KualiDecimal.ZERO;
618         KualiDecimal creditAmount = KualiDecimal.ZERO;
619         KualiDecimal debitAmount = KualiDecimal.ZERO;
620 
621         for (Iterator iter = paymentRequestDocument.getItems().iterator(); iter.hasNext(); ) {
622             PaymentRequestItem item = (PaymentRequestItem) iter.next();
623 
624             KualiDecimal itemAmount = KualiDecimal.ZERO;
625             if (item.getTotalRemitAmount() != null) {
626                 itemAmount = item.getTotalRemitAmount();
627             }
628             if (PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE.equals(item.getItemTypeCode())) {
629                 discountAmount = discountAmount.add(itemAmount);
630             } else if (PurapConstants.ItemTypeCodes.ITEM_TYPE_SHIP_AND_HAND_CODE.equals(item.getItemTypeCode())) {
631                 shippingAmount = shippingAmount.add(itemAmount);
632             } else if (PurapConstants.ItemTypeCodes.ITEM_TYPE_FREIGHT_CODE.equals(item.getItemTypeCode())) {
633                 shippingAmount = shippingAmount.add(itemAmount);
634             } else if (PurapConstants.ItemTypeCodes.ITEM_TYPE_MIN_ORDER_CODE.equals(item.getItemTypeCode())) {
635                 debitAmount = debitAmount.add(itemAmount);
636             } else if (PurapConstants.ItemTypeCodes.ITEM_TYPE_MISC_CODE.equals(item.getItemTypeCode())) {
637                 if (itemAmount.isNegative()) {
638                     creditAmount = creditAmount.add(itemAmount);
639                 } else {
640                     debitAmount = debitAmount.add(itemAmount);
641                 }
642             }
643         }
644 
645         paymentDetail.setInvTotDiscountAmount(discountAmount);
646         paymentDetail.setInvTotShipAmount(shippingAmount);
647         paymentDetail.setInvTotOtherCreditAmount(creditAmount);
648         paymentDetail.setInvTotOtherDebitAmount(debitAmount);
649 
650         paymentDetail.setPrimaryCancelledPayment(Boolean.FALSE);
651 
652         addAccounts(paymentRequestDocument, paymentDetail, paymentRequestDocType);
653         addNotes(paymentRequestDocument, paymentDetail);
654 
655         return paymentDetail;
656     }
657 
658     /**
659      * Add accounts to a PDP Payment Detail
660      *
661      * @param accountsPayableDocument
662      * @param paymentDetail
663      * @param documentType
664      */
665     protected void addAccounts(AccountsPayableDocument accountsPayableDocument, PaymentDetail paymentDetail, String documentType) {
666         String creditMemoDocType = getDataDictionaryService().getDocumentTypeNameByClass(VendorCreditMemoDocument.class);
667         List<SourceAccountingLine> sourceAccountingLines = purapAccountingService.generateSourceAccountsForVendorRemit(accountsPayableDocument);
668         for (SourceAccountingLine sourceAccountingLine : sourceAccountingLines) {
669             KualiDecimal lineAmount = sourceAccountingLine.getAmount();
670             PaymentAccountDetail paymentAccountDetail = new PaymentAccountDetail();
671             paymentAccountDetail.setAccountNbr(sourceAccountingLine.getAccountNumber());
672 
673             if (creditMemoDocType.equals(documentType)) {
674                 lineAmount = lineAmount.negated();
675             }
676 
677             paymentAccountDetail.setAccountNetAmount(sourceAccountingLine.getAmount());
678             paymentAccountDetail.setFinChartCode(sourceAccountingLine.getChartOfAccountsCode());
679             paymentAccountDetail.setFinObjectCode(sourceAccountingLine.getFinancialObjectCode());
680 
681             paymentAccountDetail.setFinSubObjectCode(StringUtils.defaultIfEmpty(sourceAccountingLine.getFinancialSubObjectCode(), OLEConstants.getDashFinancialSubObjectCode()));
682             paymentAccountDetail.setOrgReferenceId(sourceAccountingLine.getOrganizationReferenceId());
683             paymentAccountDetail.setProjectCode(StringUtils.defaultIfEmpty(sourceAccountingLine.getProjectCode(), OLEConstants.getDashProjectCode()));
684             paymentAccountDetail.setSubAccountNbr(StringUtils.defaultIfEmpty(sourceAccountingLine.getSubAccountNumber(), OLEConstants.getDashSubAccountNumber()));
685             paymentDetail.addAccountDetail(paymentAccountDetail);
686         }
687     }
688 
689     /**
690      * Add Notes to a PDP Payment Detail
691      *
692      * @param accountsPayableDocument
693      * @param paymentDetail
694      */
695     protected void addNotes(AccountsPayableDocument accountsPayableDocument, PaymentDetail paymentDetail) {
696         int count = 1;
697 
698         if (accountsPayableDocument instanceof PaymentRequestDocument) {
699             PaymentRequestDocument prd = (PaymentRequestDocument) accountsPayableDocument;
700 
701             if (prd.getSpecialHandlingInstructionLine1Text() != null) {
702                 PaymentNoteText pnt = new PaymentNoteText();
703                 pnt.setCustomerNoteLineNbr(new KualiInteger(count++));
704                 pnt.setCustomerNoteText(prd.getSpecialHandlingInstructionLine1Text());
705                 paymentDetail.addNote(pnt);
706             }
707 
708             if (prd.getSpecialHandlingInstructionLine2Text() != null) {
709                 PaymentNoteText pnt = new PaymentNoteText();
710                 pnt.setCustomerNoteLineNbr(new KualiInteger(count++));
711                 pnt.setCustomerNoteText(prd.getSpecialHandlingInstructionLine2Text());
712                 paymentDetail.addNote(pnt);
713             }
714 
715             if (prd.getSpecialHandlingInstructionLine3Text() != null) {
716                 PaymentNoteText pnt = new PaymentNoteText();
717                 pnt.setCustomerNoteLineNbr(new KualiInteger(count++));
718                 pnt.setCustomerNoteText(prd.getSpecialHandlingInstructionLine3Text());
719                 paymentDetail.addNote(pnt);
720             }
721         }
722 
723         if (accountsPayableDocument.getNoteLine1Text() != null) {
724             PaymentNoteText pnt = new PaymentNoteText();
725             pnt.setCustomerNoteLineNbr(new KualiInteger(count++));
726             pnt.setCustomerNoteText(accountsPayableDocument.getNoteLine1Text());
727             paymentDetail.addNote(pnt);
728         }
729 
730         if (accountsPayableDocument.getNoteLine2Text() != null) {
731             PaymentNoteText pnt = new PaymentNoteText();
732             pnt.setCustomerNoteLineNbr(new KualiInteger(count++));
733             pnt.setCustomerNoteText(accountsPayableDocument.getNoteLine2Text());
734             paymentDetail.addNote(pnt);
735         }
736 
737         if (accountsPayableDocument.getNoteLine3Text() != null) {
738             PaymentNoteText pnt = new PaymentNoteText();
739             pnt.setCustomerNoteLineNbr(new KualiInteger(count++));
740             pnt.setCustomerNoteText(accountsPayableDocument.getNoteLine3Text());
741             paymentDetail.addNote(pnt);
742         }
743 
744         PaymentNoteText pnt = new PaymentNoteText();
745         pnt.setCustomerNoteLineNbr(new KualiInteger(count++));
746         pnt.setCustomerNoteText("Sales Tax: " + accountsPayableDocument.getTotalRemitTax());
747     }
748 
749     /**
750      * Populate the PDP Payment Group from fields on a payment request
751      *
752      * @param paymentRequestDocument
753      * @param batch
754      * @return PaymentGroup
755      */
756     protected PaymentGroup populatePaymentGroup(PaymentRequestDocument paymentRequestDocument, Batch batch) {
757         if (LOG.isDebugEnabled()) {
758             LOG.debug("populatePaymentGroup() payment request documentNumber: " + paymentRequestDocument.getDocumentNumber());
759         }
760 
761         PaymentGroup paymentGroup = new PaymentGroup();
762 
763         paymentGroup.setBatchId(batch.getId());
764         paymentGroup.setPaymentStatusCode(OLEConstants.PdpConstants.PAYMENT_OPEN_STATUS_CODE);
765         paymentGroup.setBankCode(paymentRequestDocument.getBankCode());
766 
767         String postalCode = paymentRequestDocument.getVendorPostalCode();
768         if (OLEConstants.COUNTRY_CODE_UNITED_STATES.equals(paymentRequestDocument.getVendorCountry())) {
769             // Add a dash in the zip code if necessary
770             if (postalCode.length() > 5) {
771                 postalCode = postalCode.substring(0, 5) + "-" + postalCode.substring(5);
772             }
773         }
774 
775         paymentGroup.setPayeeName(paymentRequestDocument.getVendorName());
776         paymentGroup.setPayeeId(paymentRequestDocument.getVendorHeaderGeneratedIdentifier() + "-" + paymentRequestDocument.getVendorDetailAssignedIdentifier());
777         paymentGroup.setPayeeIdTypeCd(PdpConstants.PayeeIdTypeCodes.VENDOR_ID);
778 
779         if (paymentRequestDocument.getVendorDetail().getVendorHeader().getVendorOwnershipCategoryCode() != null) {
780             paymentGroup.setPayeeOwnerCd(paymentRequestDocument.getVendorDetail().getVendorHeader().getVendorOwnershipCategoryCode());
781         }
782 
783 //        if (paymentRequestDocument.getVendorCustomerNumber() != null) {
784 //            paymentGroup.setCustomerInstitutionNumber(paymentRequestDocument.getVendorCustomerNumber());
785 //        }
786 
787         paymentGroup.setLine1Address(paymentRequestDocument.getVendorLine1Address());
788         paymentGroup.setLine2Address(paymentRequestDocument.getVendorLine2Address());
789         paymentGroup.setLine3Address("");
790         paymentGroup.setLine4Address("");
791 
792         paymentGroup.setCity(paymentRequestDocument.getVendorCityName());
793         paymentGroup.setState(paymentRequestDocument.getVendorStateCode());
794         paymentGroup.setZipCd(postalCode);
795         paymentGroup.setCountry(paymentRequestDocument.getVendorCountryCode());
796         paymentGroup.setCampusAddress(Boolean.FALSE);
797 
798         if (paymentRequestDocument.getPaymentRequestPayDate() != null) {
799             paymentGroup.setPaymentDate(paymentRequestDocument.getPaymentRequestPayDate());
800         }
801 
802         paymentGroup.setPymtAttachment(paymentRequestDocument.getPaymentAttachmentIndicator());
803         paymentGroup.setProcessImmediate(paymentRequestDocument.getImmediatePaymentIndicator());
804         paymentGroup.setPymtSpecialHandling(StringUtils.isNotBlank(paymentRequestDocument.getSpecialHandlingInstructionLine1Text()) || StringUtils.isNotBlank(paymentRequestDocument.getSpecialHandlingInstructionLine2Text()) || StringUtils.isNotBlank(paymentRequestDocument.getSpecialHandlingInstructionLine3Text()));
805         paymentGroup.setTaxablePayment(Boolean.FALSE);
806         paymentGroup.setNraPayment(VendorConstants.OwnerTypes.NR.equals(paymentRequestDocument.getVendorDetail().getVendorHeader().getVendorOwnershipCode()));
807         paymentGroup.setCombineGroups(Boolean.TRUE);
808 
809         return paymentGroup;
810     }
811 
812     /**
813      * Populates a PaymentGroup record from a Credit Memo document
814      *
815      * @param creditMemoDocument
816      * @param batch
817      * @return PaymentGroup
818      */
819     protected PaymentGroup populatePaymentGroup(VendorCreditMemoDocument creditMemoDocument, Batch batch) {
820         if (LOG.isDebugEnabled()) {
821             LOG.debug("populatePaymentGroup() credit memo documentNumber: " + creditMemoDocument.getDocumentNumber());
822         }
823 
824         PaymentGroup paymentGroup = new PaymentGroup();
825         paymentGroup.setBatchId(batch.getId());
826         paymentGroup.setPaymentStatusCode(OLEConstants.PdpConstants.PAYMENT_OPEN_STATUS_CODE);
827         paymentGroup.setBankCode(creditMemoDocument.getBankCode());
828 
829         String postalCode = creditMemoDocument.getVendorPostalCode();
830         if (OLEConstants.COUNTRY_CODE_UNITED_STATES.equals(creditMemoDocument.getVendorCountry())) {
831             // Add a dash in the zip code if necessary
832             if (postalCode.length() > 5) {
833                 postalCode = postalCode.substring(0, 5) + "-" + postalCode.substring(5);
834             }
835         }
836 
837         paymentGroup.setPayeeName(creditMemoDocument.getVendorName());
838         paymentGroup.setPayeeId(creditMemoDocument.getVendorHeaderGeneratedIdentifier() + "-" + creditMemoDocument.getVendorDetailAssignedIdentifier());
839         paymentGroup.setPayeeIdTypeCd(PdpConstants.PayeeIdTypeCodes.VENDOR_ID);
840 
841         if (creditMemoDocument.getVendorDetail().getVendorHeader().getVendorOwnershipCategoryCode() != null) {
842             paymentGroup.setPayeeOwnerCd(creditMemoDocument.getVendorDetail().getVendorHeader().getVendorOwnershipCategoryCode());
843         }
844 
845 //        if (creditMemoDocument.getVendorCustomerNumber() != null) {
846 //            paymentGroup.setCustomerInstitutionNumber(creditMemoDocument.getVendorCustomerNumber());
847 //        }
848 
849         paymentGroup.setLine1Address(creditMemoDocument.getVendorLine1Address());
850         paymentGroup.setLine2Address(creditMemoDocument.getVendorLine2Address());
851         paymentGroup.setLine3Address("");
852         paymentGroup.setLine4Address("");
853 
854         paymentGroup.setCity(creditMemoDocument.getVendorCityName());
855         paymentGroup.setState(creditMemoDocument.getVendorStateCode());
856         paymentGroup.setZipCd(postalCode);
857         paymentGroup.setCountry(creditMemoDocument.getVendorCountryCode());
858         paymentGroup.setCampusAddress(Boolean.FALSE);
859 
860         if (creditMemoDocument.getCreditMemoDate() != null) {
861             paymentGroup.setPaymentDate(creditMemoDocument.getCreditMemoDate());
862         }
863 
864         paymentGroup.setPymtAttachment(Boolean.FALSE);
865         paymentGroup.setProcessImmediate(Boolean.FALSE);
866         paymentGroup.setPymtSpecialHandling(Boolean.FALSE);
867         paymentGroup.setTaxablePayment(Boolean.FALSE);
868         paymentGroup.setNraPayment(VendorConstants.OwnerTypes.NR.equals(creditMemoDocument.getVendorDetail().getVendorHeader().getVendorOwnershipCode()));
869         paymentGroup.setCombineGroups(Boolean.TRUE);
870 
871         return paymentGroup;
872     }
873 
874     /**
875      * Create a new PDP batch
876      *
877      * @param campusCode
878      * @param puser
879      * @param processRunDate
880      * @return Batch
881      */
882     protected Batch createBatch(String campusCode, Person puser, Date processRunDate) {
883         String orgCode = parameterService.getParameterValueAsString(OleParameterConstants.PURCHASING_BATCH.class, OLEParameterKeyConstants.PurapPdpParameterConstants.PURAP_PDP_ORG_CODE);
884         String subUnitCode = parameterService.getParameterValueAsString(OleParameterConstants.PURCHASING_BATCH.class, OLEParameterKeyConstants.PurapPdpParameterConstants.PURAP_PDP_SUB_UNIT_CODE);
885         CustomerProfile customer = customerProfileService.get(campusCode, orgCode, subUnitCode);
886         if (customer == null) {
887             throw new IllegalArgumentException("Unable to find customer profile for " + campusCode + "/" + orgCode + "/" + subUnitCode);
888         }
889 
890         // Create the group for this campus
891         Batch batch = new Batch();
892         batch.setCustomerProfile(customer);
893         batch.setCustomerFileCreateTimestamp(new Timestamp(processRunDate.getTime()));
894         batch.setFileProcessTimestamp(new Timestamp(processRunDate.getTime()));
895         batch.setPaymentFileName(PurapConstants.PDP_PURAP_EXTRACT_FILE_NAME);
896         batch.setSubmiterUserId(puser.getPrincipalId());
897 
898         // Set these for now, we will update them later
899         batch.setPaymentCount(KualiInteger.ZERO);
900         batch.setPaymentTotalAmount(KualiDecimal.ZERO);
901 
902         businessObjectService.save(batch);
903 
904         return batch;
905     }
906 
907     /**
908      * Find all the campuses that have payments to process
909      *
910      * @return List<String>
911      */
912 
913     protected List<String> getChartCodes(boolean immediatesOnly, Date processRunDate) {
914         List<String> output = new ArrayList<String>();
915 
916         Iterator<PaymentRequestDocument> paymentRequests = null;
917         if (immediatesOnly) {
918             paymentRequests = paymentRequestService.getImmediatePaymentRequestsToExtract(null).iterator();
919         } else {
920             java.sql.Date onOrBeforePaymentRequestPayDate = KfsDateUtils.convertToSqlDate(purapRunDateService.calculateRunDate(processRunDate));
921             paymentRequests = paymentRequestService.getPaymentRequestsToExtract(onOrBeforePaymentRequestPayDate).iterator();
922         }
923 
924         while (paymentRequests.hasNext()) {
925             PaymentRequestDocument prd = paymentRequests.next();
926             if (!output.contains(prd.getProcessingCampusCode())) {
927                 output.add(prd.getProcessingCampusCode());
928             }
929         }
930 
931         return output;
932     }
933 
934 
935     /**
936      * Holds total count and amount for extract
937      */
938     protected class Totals {
939         public Integer count = 0;
940         public KualiDecimal totalAmount = KualiDecimal.ZERO;
941     }
942 
943     /**
944      * Holds temporary accounting information for combining into payment accounting details
945      */
946     protected class AccountingInfo {
947         private String chart;
948         private String account;
949         private String subAccount;
950         private String objectCode;
951         private String subObjectCode;
952         private String orgReferenceId;
953         private String projectCode;
954 
955         public AccountingInfo(String c, String a, String s, String o, String so, String or, String pc) {
956             setChart(c);
957             setAccount(a);
958             setSubAccount(s);
959             setObjectCode(o);
960             setSubObjectCode(so);
961             setOrgReferenceId(or);
962             setProjectCode(pc);
963         }
964 
965         public void setAccount(String account) {
966             this.account = account;
967         }
968 
969         public void setChart(String chart) {
970             this.chart = chart;
971         }
972 
973         public void setObjectCode(String objectCode) {
974             this.objectCode = objectCode;
975         }
976 
977         public void setOrgReferenceId(String orgReferenceId) {
978             this.orgReferenceId = orgReferenceId;
979         }
980 
981         public void setProjectCode(String projectCode) {
982             if (projectCode == null) {
983                 this.projectCode = OLEConstants.getDashProjectCode();
984             } else {
985                 this.projectCode = projectCode;
986             }
987         }
988 
989         public void setSubAccount(String subAccount) {
990             if (subAccount == null) {
991                 this.subAccount = OLEConstants.getDashSubAccountNumber();
992             } else {
993                 this.subAccount = subAccount;
994             }
995         }
996 
997         public void setSubObjectCode(String subObjectCode) {
998             if (subObjectCode == null) {
999                 this.subObjectCode = OLEConstants.getDashFinancialSubObjectCode();
1000             } else {
1001                 this.subObjectCode = subObjectCode;
1002             }
1003         }
1004 
1005         protected String key() {
1006             return chart + "~" + account + "~" + subAccount + "~" + objectCode + "~" + subObjectCode + "~" + orgReferenceId + "~" + projectCode;
1007         }
1008 
1009         @Override
1010         public int hashCode() {
1011             return new HashCodeBuilder(3, 5).append(key()).toHashCode();
1012         }
1013 
1014         @Override
1015         public boolean equals(Object obj) {
1016             if (!(obj instanceof AccountingInfo)) {
1017                 return false;
1018             }
1019             AccountingInfo thisobj = (AccountingInfo) obj;
1020             return new EqualsBuilder().append(key(), thisobj.key()).isEquals();
1021         }
1022     }
1023 
1024     private void lockUnlockDocuments(boolean locked) {
1025         for (String documentType : lockedDocuments) {
1026             Class<? extends Document> documentClass = dataDictionaryService.getDocumentClassByTypeName(documentType);
1027             if (parameterService.parameterExists(documentClass, OLEConstants.DOCUMENT_LOCKOUT_PARM_NM)) {
1028                 Parameter existingParam = parameterService.getParameter(documentClass, OLEConstants.DOCUMENT_LOCKOUT_PARM_NM);
1029                 Parameter.Builder updatedParam = Builder.create(existingParam);
1030                 updatedParam.setValue(locked ? "Y" : "N");
1031                 parameterService.updateParameter(updatedParam.build());
1032             } else {
1033                 String namespace = KRADServiceLocatorWeb.getKualiModuleService().getNamespaceCode(documentClass);
1034                 String detailType = KRADServiceLocatorWeb.getKualiModuleService().getComponentCode(documentClass);
1035                 Parameter.Builder newParam = Builder.create(OLEConstants.APPLICATION_NAMESPACE_CODE, namespace, detailType, OLEConstants.DOCUMENT_LOCKOUT_PARM_NM, ParameterType.Builder.create(OleParameterConstants.PARAMETER_CONFIG_TYPE_CODE));
1036                 newParam.setValue("Y");
1037                 newParam.setDescription(OLEConstants.DOCUMENT_LOCKOUT_PARM_DESC);
1038                 parameterService.createParameter(newParam.build());
1039             }
1040         }
1041     }
1042 
1043     /**
1044      * Sets the paymentRequestService attribute value.
1045      *
1046      * @param paymentRequestService The paymentRequestService to set.
1047      */
1048     public void setPaymentRequestService(PaymentRequestService paymentRequestService) {
1049         this.paymentRequestService = paymentRequestService;
1050     }
1051 
1052     /**
1053      * Sets the businessObjectService attribute value.
1054      *
1055      * @param businessObjectService The businessObjectService to set.
1056      */
1057     public void setBusinessObjectService(BusinessObjectService businessObjectService) {
1058         this.businessObjectService = businessObjectService;
1059     }
1060 
1061     /**
1062      * Sets the paymentFileService attribute value.
1063      *
1064      * @param paymentFileService The paymentFileService to set.
1065      */
1066     public void setPaymentFileService(PaymentFileService paymentFileService) {
1067         this.paymentFileService = paymentFileService;
1068     }
1069 
1070     /**
1071      * Sets the parameterService attribute value.
1072      *
1073      * @param parameterService The parameterService to set.
1074      */
1075     public void setParameterService(ParameterService parameterService) {
1076         this.parameterService = parameterService;
1077     }
1078 
1079     /**
1080      * Sets the customerProfileService attribute value.
1081      *
1082      * @param customerProfileService The customerProfileService to set.
1083      */
1084     public void setCustomerProfileService(CustomerProfileService customerProfileService) {
1085         this.customerProfileService = customerProfileService;
1086     }
1087 
1088     /**
1089      * Sets the dateTimeService attribute value.
1090      *
1091      * @param dateTimeService The dateTimeService to set.
1092      */
1093     public void setDateTimeService(DateTimeService dateTimeService) {
1094         this.dateTimeService = dateTimeService;
1095     }
1096 
1097     /**
1098      * Sets the paymentGroupService attribute value.
1099      *
1100      * @param paymentGroupService The paymentGroupService to set.
1101      */
1102     public void setPaymentGroupService(PaymentGroupService paymentGroupService) {
1103         this.paymentGroupService = paymentGroupService;
1104     }
1105 
1106     /**
1107      * Sets the paymentDetailService attribute value.
1108      *
1109      * @param paymentDetailService The paymentDetailService to set.
1110      */
1111     public void setPaymentDetailService(PaymentDetailService paymentDetailService) {
1112         this.paymentDetailService = paymentDetailService;
1113     }
1114 
1115     /**
1116      * Sets the creditMemoService attribute value.
1117      *
1118      * @param creditMemoService The creditMemoService to set.
1119      */
1120     public void setCreditMemoService(CreditMemoService creditMemoService) {
1121         this.creditMemoService = creditMemoService;
1122     }
1123 
1124     /**
1125      * Sets the documentService attribute value.
1126      *
1127      * @param documentService The documentService to set.
1128      */
1129     public void setDocumentService(DocumentService documentService) {
1130         this.documentService = documentService;
1131     }
1132 
1133     /**
1134      * Sets the purapRunDateService attribute value.
1135      *
1136      * @param purapRunDateService The purapRunDateService to set.
1137      */
1138     public void setPurapRunDateService(PurapRunDateService purapRunDateService) {
1139         this.purapRunDateService = purapRunDateService;
1140     }
1141 
1142     /**
1143      * Sets the paymentFileEmailService attribute value.
1144      *
1145      * @param paymentFileEmailService The paymentFileEmailService to set.
1146      */
1147     public void setPaymentFileEmailService(PdpEmailService paymentFileEmailService) {
1148         this.paymentFileEmailService = paymentFileEmailService;
1149     }
1150 
1151     /**
1152      * Sets the bankService attribute value.
1153      *
1154      * @param bankService The bankService to set.
1155      */
1156     public void setBankService(BankService bankService) {
1157         this.bankService = bankService;
1158     }
1159 
1160     /**
1161      * Gets the dataDictionaryService attribute.
1162      *
1163      * @return Returns the dataDictionaryService.
1164      */
1165     public DataDictionaryService getDataDictionaryService() {
1166         return dataDictionaryService;
1167     }
1168 
1169     /**
1170      * Sets the dataDictionaryService attribute value.
1171      *
1172      * @param dataDictionaryService The dataDictionaryService to set.
1173      */
1174     public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
1175         this.dataDictionaryService = dataDictionaryService;
1176     }
1177 
1178     public void setPurapAccountingService(PurapAccountingServiceImpl purapAccountingService) {
1179         this.purapAccountingService = purapAccountingService;
1180     }
1181 
1182     /**
1183      * @return Returns the personService.
1184      */
1185     protected PersonService getPersonService() {
1186         if (personService == null) {
1187             personService = SpringContext.getBean(PersonService.class);
1188         }
1189         return personService;
1190     }
1191 
1192     public void setLockedDocuments(List<String> lockedDocuments) {
1193         this.lockedDocuments = lockedDocuments;
1194     }
1195 
1196 
1197 }