1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.ole.module.purap.document.service.impl;
17  
18  import org.kuali.ole.coa.businessobject.Account;
19  import org.kuali.ole.coa.service.AccountService;
20  import org.kuali.ole.gl.batch.ScrubberStep;
21  import org.kuali.ole.module.purap.PurapConstants;
22  import org.kuali.ole.module.purap.PurapConstants.PaymentRequestStatuses;
23  import org.kuali.ole.module.purap.PurapKeyConstants;
24  import org.kuali.ole.module.purap.PurapParameterConstants;
25  import org.kuali.ole.module.purap.businessobject.*;
26  import org.kuali.ole.module.purap.document.*;
27  import org.kuali.ole.module.purap.document.service.AccountsPayableDocumentSpecificService;
28  import org.kuali.ole.module.purap.document.service.AccountsPayableService;
29  import org.kuali.ole.module.purap.document.service.PurapService;
30  import org.kuali.ole.module.purap.document.service.PurchaseOrderService;
31  import org.kuali.ole.module.purap.service.PurapAccountingService;
32  import org.kuali.ole.module.purap.service.PurapGeneralLedgerService;
33  import org.kuali.ole.module.purap.util.ExpiredOrClosedAccount;
34  import org.kuali.ole.module.purap.util.ExpiredOrClosedAccountEntry;
35  import org.kuali.ole.select.document.service.OleSelectDocumentService;
36  import org.kuali.ole.sys.OLEConstants;
37  import org.kuali.ole.sys.businessobject.SourceAccountingLine;
38  import org.kuali.ole.sys.context.SpringContext;
39  import org.kuali.ole.sys.service.impl.OleParameterConstants;
40  import org.kuali.rice.core.api.datetime.DateTimeService;
41  import org.kuali.rice.core.api.util.type.KualiDecimal;
42  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
43  import org.kuali.rice.kew.api.KewApiServiceLocator;
44  import org.kuali.rice.kew.api.WorkflowDocument;
45  import org.kuali.rice.kew.api.action.DocumentActionParameters;
46  import org.kuali.rice.kim.api.identity.Person;
47  import org.kuali.rice.kim.api.identity.PersonService;
48  import org.kuali.rice.kns.util.KNSGlobalVariables;
49  import org.kuali.rice.krad.UserSession;
50  import org.kuali.rice.krad.bo.Note;
51  import org.kuali.rice.krad.service.BusinessObjectService;
52  import org.kuali.rice.krad.service.DocumentService;
53  import org.kuali.rice.krad.service.NoteService;
54  import org.kuali.rice.krad.util.GlobalVariables;
55  import org.kuali.rice.krad.util.ObjectUtils;
56  import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
57  import org.springframework.transaction.annotation.Transactional;
58  
59  import java.util.*;
60  
61  
62  @Transactional
63  public class AccountsPayableServiceImpl implements AccountsPayableService {
64  
65      protected PurapAccountingService purapAccountingService;
66      protected PurapGeneralLedgerService purapGeneralLedgerService;
67      protected DocumentService documentService;
68      protected PurapService purapService;
69      protected ParameterService parameterService;
70      protected DateTimeService dateTimeService;
71      protected PurchaseOrderService purchaseOrderService;
72      protected AccountService accountService;
73      private OleSelectDocumentService oleSelectDocumentService;
74  
75      public void setParameterService(ParameterService parameterService) {
76          this.parameterService = parameterService;
77      }
78  
79      public void setPurapService(PurapService purapService) {
80          this.purapService = purapService;
81      }
82  
83      public void setPurapAccountingService(PurapAccountingService purapAccountingService) {
84          this.purapAccountingService = purapAccountingService;
85      }
86  
87      public void setPurapGeneralLedgerService(PurapGeneralLedgerService purapGeneralLedgerService) {
88          this.purapGeneralLedgerService = purapGeneralLedgerService;
89      }
90  
91      public void setDocumentService(DocumentService documentService) {
92          this.documentService = documentService;
93      }
94  
95      public void setDateTimeService(DateTimeService dateTimeService) {
96          this.dateTimeService = dateTimeService;
97      }
98  
99      public void setPurchaseOrderService(PurchaseOrderService purchaseOrderService) {
100         this.purchaseOrderService = purchaseOrderService;
101     }
102 
103     public void setAccountService(AccountService accountService) {
104         this.accountService = accountService;
105     }
106 
107     
108 
109 
110     @Override
111     public HashMap<String, ExpiredOrClosedAccountEntry> getExpiredOrClosedAccountList(AccountsPayableDocument document) {
112 
113         
114         HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccounts = expiredOrClosedAccountsList(document);
115 
116         return expiredOrClosedAccounts;
117     }
118 
119     
120 
121 
122 
123     @Override
124     public void generateExpiredOrClosedAccountNote(AccountsPayableDocument document, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
125 
126         
127         if (ObjectUtils.isNotNull(expiredOrClosedAccountList) && !expiredOrClosedAccountList.isEmpty()) {
128             addContinuationAccountsNote(document, expiredOrClosedAccountList);
129         }
130 
131     }
132 
133     
134 
135 
136     @Override
137     public void generateExpiredOrClosedAccountWarning(AccountsPayableDocument document) {
138 
139         
140         Person user = GlobalVariables.getUserSession().getPerson();
141 
142         
143         String showContinuationAccountWaringFO = parameterService.getParameterValueAsString(OleParameterConstants.PURCHASING_DOCUMENT.class, PurapConstants.PURAP_AP_SHOW_CONTINUATION_ACCOUNT_WARNING_FISCAL_OFFICERS);
144 
145         
146         String showContinuationAccountWaringAP = parameterService.getParameterValueAsString(OleParameterConstants.PURCHASING_DOCUMENT.class, PurapConstants.PURAP_AP_SHOW_CONTINUATION_ACCOUNT_WARNING_AP_USERS);
147 
148         
149         
150         
151         
152         if (isFiscalUser(document, user) && "Y".equals(showContinuationAccountWaringFO) && (document.isContinuationAccountIndicator())) {
153             KNSGlobalVariables.getMessageList().add(PurapKeyConstants.MESSAGE_CLOSED_OR_EXPIRED_ACCOUNTS_REPLACED);
154         }
155 
156         
157         
158         
159         if (isAPUser(document, user) && "Y".equals(showContinuationAccountWaringAP) && (document.isContinuationAccountIndicator())) {
160             KNSGlobalVariables.getMessageList().add(PurapKeyConstants.MESSAGE_CLOSED_OR_EXPIRED_ACCOUNTS_REPLACED);
161         }
162 
163     }
164 
165     
166 
167 
168 
169     @Override
170     public void processExpiredOrClosedAccount(PurApAccountingLineBase acctLineBase, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
171 
172         ExpiredOrClosedAccountEntry accountEntry = null;
173         String acctKey = acctLineBase.getChartOfAccountsCode() + "-" + acctLineBase.getAccountNumber();
174 
175         if (expiredOrClosedAccountList.containsKey(acctKey)) {
176 
177             accountEntry = expiredOrClosedAccountList.get(acctKey);
178 
179             if (accountEntry.getOriginalAccount().isContinuationAccountMissing() == false) {
180                 acctLineBase.setChartOfAccountsCode(accountEntry.getReplacementAccount().getChartOfAccountsCode());
181                 acctLineBase.setAccountNumber(accountEntry.getReplacementAccount().getAccountNumber());
182                 acctLineBase.refreshReferenceObject("chart");
183                 acctLineBase.refreshReferenceObject("account");
184             }
185         }
186     }
187 
188     
189 
190 
191 
192 
193 
194 
195     protected void addContinuationAccountsNote(AccountsPayableDocument document, HashMap<String, ExpiredOrClosedAccountEntry> accounts) {
196         String noteText;
197         StringBuffer sb = new StringBuffer("");
198         ExpiredOrClosedAccountEntry accountEntry = null;
199         ExpiredOrClosedAccount originalAccount = null;
200         ExpiredOrClosedAccount replacementAccount = null;
201 
202         
203         Set entries = accounts.entrySet();
204         Iterator it = entries.iterator();
205 
206         
207         while (it.hasNext()) {
208             Map.Entry entry = (Map.Entry) it.next();
209             accountEntry = (ExpiredOrClosedAccountEntry) entry.getValue();
210             originalAccount = accountEntry.getOriginalAccount();
211             replacementAccount = accountEntry.getReplacementAccount();
212 
213             
214             if (originalAccount.isContinuationAccountMissing() == false) {
215                 sb.append(" Account " + originalAccount.getAccountString() + " was replaced with account " + replacementAccount.getAccountString() + " ; ");
216             }
217 
218         }
219 
220         
221         if (sb.toString().length() > 0) {
222             try {
223                 Note resetNote = documentService.createNoteFromDocument(document, sb.toString());
224                 document.addNote(resetNote);
225             } catch (Exception e) {
226                 throw new RuntimeException(PurapConstants.REQ_UNABLE_TO_CREATE_NOTE + " " + e);
227             }
228         }
229     }
230 
231     
232 
233 
234 
235 
236 
237 
238 
239     protected Account getReplaceAccountForClosedAccount(Account account, AccountsPayableDocument document) {
240         if (account == null) {
241             return null; 
242         }
243         Account continueAccount = accountService.getByPrimaryId(account.getContinuationFinChrtOfAcctCd(), account.getContinuationAccountNumber());
244         return continueAccount;
245     }
246 
247     
248 
249 
250 
251 
252 
253 
254 
255     protected Account getReplaceAccountForExpiredAccount(Account account, AccountsPayableDocument document) {
256         if (account == null) {
257             return null; 
258         }
259         Account continueAccount = accountService.getByPrimaryId(account.getContinuationFinChrtOfAcctCd(), account.getContinuationAccountNumber());
260         return continueAccount;
261     }
262 
263     
264 
265 
266 
267 
268 
269 
270 
271 
272     protected HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountsList(AccountsPayableDocument document) {
273         
274         PurchaseOrderDocument po = document.getPurchaseOrderDocument();
275         if (po == null && document instanceof VendorCreditMemoDocument) {
276             PaymentRequestDocument preq = ((VendorCreditMemoDocument) document).getPaymentRequestDocument();
277             if (preq == null) {
278                 return null; 
279             }
280             po = ((VendorCreditMemoDocument) document).getPaymentRequestDocument().getPurchaseOrderDocument();
281         }
282         if (po == null) {
283             return null; 
284         }
285 
286         
287         List<SourceAccountingLine> acctLines = purapAccountingService.generateSummary(po.getItemsActiveOnly());
288         HashMap<String, ExpiredOrClosedAccountEntry> eocAcctMap = new HashMap<String, ExpiredOrClosedAccountEntry>();
289 
290         
291         for (SourceAccountingLine acctLine : acctLines) {
292             Account account = accountService.getByPrimaryId(acctLine.getChartOfAccountsCode(), acctLine.getAccountNumber());
293             Account repAccount = null;
294             boolean replace = false;
295 
296             
297             if (!account.isActive()) {
298                 repAccount = getReplaceAccountForClosedAccount(account, document);
299                 replace = true;
300             }
301             
302             else if (account.isExpired()) {
303                 
304                 String expirationExtensionDays = parameterService.getParameterValueAsString(ScrubberStep.class, OLEConstants.SystemGroupParameterNames.GL_SCRUBBER_VALIDATION_DAYS_OFFSET);
305                 int expirationExtensionDaysInt = 90; 
306                 if (expirationExtensionDays.trim().length() > 0) {
307                     expirationExtensionDaysInt = new Integer(expirationExtensionDays).intValue();
308                 }
309                 
310                 if ((account.isForContractsAndGrants() && dateTimeService.dateDiff(account.getAccountExpirationDate(), dateTimeService.getCurrentDate(), true) > expirationExtensionDaysInt)) {
311                     repAccount = getReplaceAccountForExpiredAccount(account, document);
312                     replace = true;
313                 }
314                 
315             }
316 
317             
318             if (replace) {
319                 ExpiredOrClosedAccountEntry eocAcctEntry = new ExpiredOrClosedAccountEntry();
320                 ExpiredOrClosedAccount originAcct = new ExpiredOrClosedAccount(acctLine.getChartOfAccountsCode(), acctLine.getAccountNumber(), acctLine.getSubAccountNumber());
321                 ExpiredOrClosedAccount replaceAcct = null;
322                 if (repAccount == null) {
323                     replaceAcct = new ExpiredOrClosedAccount();
324                     originAcct.setContinuationAccountMissing(true);
325                 } else {
326                     replaceAcct = new ExpiredOrClosedAccount(repAccount.getChartOfAccountsCode(), repAccount.getAccountNumber(), acctLine.getSubAccountNumber());
327                 }
328                 eocAcctEntry.setOriginalAccount(originAcct);
329                 eocAcctEntry.setReplacementAccount(replaceAcct);
330                 eocAcctMap.put(createChartAccountString(originAcct), eocAcctEntry);
331             }
332         }
333 
334         return eocAcctMap;
335     }
336 
337     
338 
339 
340 
341 
342 
343 
344 
345     @Override
346     public HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountsList(PurchaseOrderDocument po) {
347         HashMap<String, ExpiredOrClosedAccountEntry> list = new HashMap<String, ExpiredOrClosedAccountEntry>();
348         ExpiredOrClosedAccountEntry entry = null;
349         ExpiredOrClosedAccount originalAcct = null;
350         ExpiredOrClosedAccount replaceAcct = null;
351         String chartAccount = null;
352 
353         if (po != null) {
354             
355             List<SourceAccountingLine> accountList = purapAccountingService.generateSummary(po.getItemsActiveOnly());
356 
357             
358             for (SourceAccountingLine poAccountingLine : accountList) {
359                 Account account = accountService.getByPrimaryId(poAccountingLine.getChartOfAccountsCode(), poAccountingLine.getAccountNumber());
360                 entry = new ExpiredOrClosedAccountEntry();
361                 originalAcct = new ExpiredOrClosedAccount(poAccountingLine.getChartOfAccountsCode(), poAccountingLine.getAccountNumber(), poAccountingLine.getSubAccountNumber());
362 
363                 if (!account.isActive()) {
364                     
365                     Account continuationAccount = accountService.getByPrimaryId(account.getContinuationFinChrtOfAcctCd(), account.getContinuationAccountNumber());
366 
367                     if (continuationAccount == null) {
368                         replaceAcct = new ExpiredOrClosedAccount();
369                         originalAcct.setContinuationAccountMissing(true);
370 
371                         entry.setOriginalAccount(originalAcct);
372                         entry.setReplacementAccount(replaceAcct);
373 
374                         list.put(createChartAccountString(originalAcct), entry);
375                     } else {
376                         replaceAcct = new ExpiredOrClosedAccount(continuationAccount.getChartOfAccountsCode(), continuationAccount.getAccountNumber(), poAccountingLine.getSubAccountNumber());
377 
378                         entry.setOriginalAccount(originalAcct);
379                         entry.setReplacementAccount(replaceAcct);
380 
381                         list.put(createChartAccountString(originalAcct), entry);
382                     }
383                     
384                     
385                     
386                 } else if (account.isExpired()) {
387                     Account continuationAccount = accountService.getByPrimaryId(account.getContinuationFinChrtOfAcctCd(), account.getContinuationAccountNumber());
388                     String expirationExtensionDays = parameterService.getParameterValueAsString(ScrubberStep.class, OLEConstants.SystemGroupParameterNames.GL_SCRUBBER_VALIDATION_DAYS_OFFSET);
389                     int expirationExtensionDaysInt = 3 * 30; 
390 
391                     if (expirationExtensionDays.trim().length() > 0) {
392 
393                         expirationExtensionDaysInt = new Integer(expirationExtensionDays).intValue();
394                     }
395 
396                     
397                     if ((account.isForContractsAndGrants() && dateTimeService.dateDiff(account.getAccountExpirationDate(), dateTimeService.getCurrentDate(), true) > expirationExtensionDaysInt)) {
398 
399                         if (continuationAccount == null) {
400                             replaceAcct = new ExpiredOrClosedAccount();
401                             originalAcct.setContinuationAccountMissing(true);
402 
403                             entry.setOriginalAccount(originalAcct);
404                             entry.setReplacementAccount(replaceAcct);
405 
406                             list.put(createChartAccountString(originalAcct), entry);
407                         } else {
408                             replaceAcct = new ExpiredOrClosedAccount(continuationAccount.getChartOfAccountsCode(), continuationAccount.getAccountNumber(), poAccountingLine.getSubAccountNumber());
409 
410                             entry.setOriginalAccount(originalAcct);
411                             entry.setReplacementAccount(replaceAcct);
412 
413                             list.put(createChartAccountString(originalAcct), entry);
414                         }
415                     }
416 
417                     
418                 }
419             }
420         }
421         return list;
422     }
423 
424     
425 
426 
427 
428 
429 
430     protected String createChartAccountString(ExpiredOrClosedAccount ecAccount) {
431         StringBuffer buff = new StringBuffer("");
432 
433         buff.append(ecAccount.getChartOfAccountsCode());
434         buff.append("-");
435         buff.append(ecAccount.getAccountNumber());
436 
437         return buff.toString();
438     }
439 
440     
441 
442 
443 
444 
445 
446 
447     protected boolean isFiscalUser(AccountsPayableDocument document, Person user) {
448         boolean isFiscalUser = false;
449 
450         if (PaymentRequestStatuses.APPDOC_AWAITING_FISCAL_REVIEW.equals(document.getApplicationDocumentStatus()) && document.getDocumentHeader().getWorkflowDocument().isApprovalRequested()) {
451             isFiscalUser = true;
452         }
453 
454         return isFiscalUser;
455     }
456 
457     
458 
459 
460 
461 
462 
463 
464     protected boolean isAPUser(AccountsPayableDocument document, Person user) {
465         boolean isFiscalUser = false;
466 
467         if ((PaymentRequestStatuses.APPDOC_AWAITING_ACCOUNTS_PAYABLE_REVIEW.equals(document.getApplicationDocumentStatus()) &&
468                 document.getDocumentHeader().getWorkflowDocument().isApprovalRequested()) ||
469                 PaymentRequestStatuses.APPDOC_IN_PROCESS.equals(document.getApplicationDocumentStatus())) {
470             isFiscalUser = true;
471         }
472 
473         return isFiscalUser;
474     }
475 
476     
477 
478 
479     @Override
480     public void cancelAccountsPayableDocument(AccountsPayableDocument apDocument, String currentNodeName) {
481         if (purapService.isFullDocumentEntryCompleted(apDocument)) {
482             purapGeneralLedgerService.generateEntriesCancelAccountsPayableDocument(apDocument);
483         }
484         AccountsPayableDocumentSpecificService accountsPayableDocumentSpecificService = apDocument.getDocumentSpecificService();
485         accountsPayableDocumentSpecificService.updateStatusByNode(currentNodeName, apDocument);
486 
487         
488         accountsPayableDocumentSpecificService.takePurchaseOrderCancelAction(apDocument);
489     }
490 
491     
492 
493 
494     @Override
495     public void cancelAccountsPayableDocumentByCheckingDocumentStatus(AccountsPayableDocument document, String noteText) throws Exception {
496         DocumentService documentService = SpringContext.getBean(DocumentService.class);
497 
498         if (PurapConstants.CreditMemoStatuses.APPDOC_IN_PROCESS.equals(document.getApplicationDocumentStatus())) {
499             
500             documentService.cancelDocument(document, noteText);
501         } else if (PurapConstants.CreditMemoStatuses.APPDOC_AWAITING_ACCOUNTS_PAYABLE_REVIEW.equals(document.getApplicationDocumentStatus())) {
502             
503             documentService.disapproveDocument(document, noteText);
504         } else if (document instanceof PaymentRequestDocument && PurapConstants.PaymentRequestStatuses.APPDOC_AWAITING_FISCAL_REVIEW.equals(document.getApplicationDocumentStatus()) && ((PaymentRequestDocument) document).isPaymentRequestedCancelIndicator()) {
505             
506             DocumentActionParameters.Builder p = DocumentActionParameters.Builder.create(document.getDocumentNumber(), document.getLastActionPerformedByPersonId());
507             p.setAnnotation("Document cancelled after requested cancel by " + GlobalVariables.getUserSession().getPrincipalName());
508             KewApiServiceLocator.getWorkflowDocumentActionsService().disapprove(p.build());
509         } else {
510             UserSession originalUserSession = GlobalVariables.getUserSession();
511             WorkflowDocument originalWorkflowDocument = document.getDocumentHeader().getWorkflowDocument();
512             
513             if (!document.getDocumentHeader().getWorkflowDocument().isApproved()) {
514                 try {
515                     
516                     Person userRequestedCancel = SpringContext.getBean(PersonService.class).getPerson(document.getLastActionPerformedByPersonId());
517                     GlobalVariables.setUserSession(new UserSession(getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER)));
518 
519                     WorkflowDocumentService workflowDocumentService = SpringContext.getBean(WorkflowDocumentService.class);
520                     WorkflowDocument newWorkflowDocument = workflowDocumentService.loadWorkflowDocument(document.getDocumentNumber(), GlobalVariables.getUserSession().getPerson());
521                     document.getDocumentHeader().setWorkflowDocument(newWorkflowDocument);
522 
523                     String annotation = "Document Cancelled by user " + originalUserSession.getPerson().getName() + " (" + originalUserSession.getPerson().getPrincipalName() + ")";
524                     if (ObjectUtils.isNotNull(userRequestedCancel)) {
525                         annotation.concat(" per request of user " + userRequestedCancel.getName() + " (" + userRequestedCancel.getPrincipalName() + ")");
526                     }
527                     documentService.superUserDisapproveDocument(document, annotation);
528                 } finally {
529                     GlobalVariables.setUserSession(originalUserSession);
530                     document.getDocumentHeader().setWorkflowDocument(originalWorkflowDocument);
531                 }
532             } else {
533                 
534                 SpringContext.getBean(AccountsPayableService.class).cancelAccountsPayableDocument(document, "");
535                 document.getDocumentHeader().getWorkflowDocument().logAnnotation("Document Cancelled by user " + originalUserSession.getPerson().getName() + " (" + originalUserSession.getPerson().getPrincipalName() + ")");
536             }
537         }
538 
539         Note noteObj = documentService.createNoteFromDocument(document, noteText);
540         document.addNote(noteObj);
541         SpringContext.getBean(NoteService.class).save(noteObj);
542     }
543 
544     
545 
546 
547     @Override
548     public void performLogicForFullEntryCompleted(PurchasingAccountsPayableDocument purapDocument) {
549         AccountsPayableDocument apDocument = (AccountsPayableDocument) purapDocument;
550         AccountsPayableDocumentSpecificService accountsPayableDocumentSpecificService = apDocument.getDocumentSpecificService();
551 
552         
553         purapService.deleteUnenteredItems(apDocument);
554 
555         
556         purapAccountingService.updateAccountAmounts(apDocument);
557 
558         
559         apDocument.setAccountsPayableApprovalTimestamp(dateTimeService.getCurrentTimestamp());
560 
561         
562         SpringContext.getBean(BusinessObjectService.class).save(apDocument);
563 
564         
565         accountsPayableDocumentSpecificService.generateGLEntriesCreateAccountsPayableDocument(apDocument);
566 
567     }
568 
569     
570 
571 
572     @Override
573     public void updateItemList(AccountsPayableDocument apDocument) {
574         
575         if (purapService.isFullDocumentEntryCompleted(apDocument)) {
576             return;
577         }
578         if (apDocument instanceof VendorCreditMemoDocument) {
579             VendorCreditMemoDocument cm = (VendorCreditMemoDocument) apDocument;
580             if (cm.isSourceDocumentPaymentRequest()) {
581                 
582                 List<PaymentRequestItem> items = cm.getPaymentRequestDocument().getItems();
583                 for (PaymentRequestItem preqItem : items) {
584                     
585                     if (preqItem.getItemType().isAdditionalChargeIndicator()) {
586                         continue;
587                     }
588                     PurchaseOrderItem poItem = preqItem.getPurchaseOrderItem();
589                     CreditMemoItem cmItem = (CreditMemoItem) cm.getAPItemFromPOItem(poItem);
590                     
591                     updateEncumberances(preqItem, poItem, cmItem);
592                 }
593             } else if (cm.isSourceDocumentPurchaseOrder()) {
594                 PurchaseOrderDocument po = purchaseOrderService.getCurrentPurchaseOrder(apDocument.getPurchaseOrderIdentifier());
595                 List<PurchaseOrderItem> poItems = po.getItems();
596                 List<CreditMemoItem> cmItems = cm.getItems();
597                 
598                 for (PurchaseOrderItem purchaseOrderItem : poItems) {
599                     
600                     if (purchaseOrderItem.getItemType().isAdditionalChargeIndicator()) {
601                         continue;
602                     }
603 
604                     CreditMemoItem cmItem = (CreditMemoItem) cm.getAPItemFromPOItem(purchaseOrderItem);
605                     
606                     if (apDocument.getDocumentSpecificService().poItemEligibleForAp(apDocument, purchaseOrderItem)) {
607                         
608                         if (ObjectUtils.isNull(cmItem)) {
609                             CreditMemoItem cmi = new CreditMemoItem(cm, purchaseOrderItem);
610                             cmi.setPurapDocument(apDocument);
611                             cmItems.add(cmi);
612                         } else {
613                             
614                             
615                             
616                             updateEncumberance(purchaseOrderItem, cmItem);
617                         }
618                     } else { 
619                         if (ObjectUtils.isNotNull(cmItem)) {
620                             cmItems.remove(cmItem);
621                             
622                             continue;
623                         }
624                     }
625 
626                 }
627             } 
628             return;
629 
630             
631         } else if (apDocument instanceof PaymentRequestDocument) {
632 
633             
634             PurchaseOrderDocument po = purchaseOrderService.getCurrentPurchaseOrder(apDocument.getPurchaseOrderIdentifier());
635             PaymentRequestDocument preq = (PaymentRequestDocument) apDocument;
636 
637             List<PurchaseOrderItem> poItems = po.getItems();
638             List<PaymentRequestItem> preqItems = preq.getItems();
639             
640             for (PurchaseOrderItem purchaseOrderItem : poItems) {
641                 
642                 if (purchaseOrderItem.getItemType().isAdditionalChargeIndicator()) {
643                     continue;
644                 }
645                 PaymentRequestItem preqItem = (PaymentRequestItem) preq.getAPItemFromPOItem(purchaseOrderItem);
646                 
647                 if (apDocument.getDocumentSpecificService().poItemEligibleForAp(apDocument, purchaseOrderItem)) {
648                     
649                     if (ObjectUtils.isNull(preqItem)) {
650                         PaymentRequestItem pri = new PaymentRequestItem(purchaseOrderItem, preq);
651                         pri.setPurapDocument(apDocument);
652                         preqItems.add(pri);
653                     } else {
654                         updatePossibleAmmendedFields(purchaseOrderItem, preqItem);
655                     }
656                 } else { 
657                     if (ObjectUtils.isNotNull(preqItem)) {
658                         preqItems.remove(preqItem);
659                     }
660                 }
661 
662             }
663         }
664     }
665 
666     
667 
668 
669 
670 
671 
672     protected void updatePossibleAmmendedFields(PurchaseOrderItem sourceItem, PaymentRequestItem destItem) {
673         destItem.setPurchaseOrderItemUnitPrice(sourceItem.getItemUnitPrice());
674         destItem.setItemCatalogNumber(sourceItem.getItemCatalogNumber());
675         destItem.setItemDescription(sourceItem.getItemDescription());
676     }
677 
678     
679 
680 
681 
682 
683 
684 
685     protected void updateEncumberances(PaymentRequestItem preqItem, PurchaseOrderItem poItem, CreditMemoItem cmItem) {
686         if (poItem.getItemInvoicedTotalQuantity() != null && preqItem.getItemQuantity() != null && poItem.getItemInvoicedTotalQuantity().isLessThan(preqItem.getItemQuantity())) {
687             cmItem.setPreqInvoicedTotalQuantity(poItem.getItemInvoicedTotalQuantity());
688             cmItem.setPreqUnitPrice(poItem.getItemUnitPrice());
689             cmItem.setPreqTotalAmount(poItem.getItemInvoicedTotalAmount());
690         } else {
691             cmItem.setPreqInvoicedTotalQuantity(preqItem.getItemQuantity());
692             cmItem.setPreqUnitPrice(preqItem.getItemUnitPrice());
693             cmItem.setPreqTotalAmount(preqItem.getTotalAmount());
694         }
695     }
696 
697     
698 
699 
700 
701 
702 
703     protected void updateEncumberance(PurchaseOrderItem purchaseOrderItem, CreditMemoItem cmItem) {
704         cmItem.setPoInvoicedTotalQuantity(purchaseOrderItem.getItemInvoicedTotalQuantity());
705         cmItem.setPreqUnitPrice(purchaseOrderItem.getItemUnitPrice());
706         cmItem.setPoTotalAmount(purchaseOrderItem.getItemInvoicedTotalAmount());
707     }
708 
709     
710 
711 
712     @Override
713     public boolean purchaseOrderItemEligibleForPayment(PurchaseOrderItem poi) {
714         if (ObjectUtils.isNull(poi)) {
715             throw new RuntimeException("item null in purchaseOrderItemEligibleForPayment ... this should never happen");
716         }
717 
718         
719         if (!poi.isItemActiveIndicator()) {
720             return false;
721         }
722 
723         ItemType poiType = poi.getItemType();
724 
725         if (poiType.isQuantityBasedGeneralLedgerIndicator()) {
726             if (poi.getItemQuantity().isGreaterThan(poi.getItemInvoicedTotalQuantity())) {
727                 return true;
728             }
729             return false;
730         } else { 
731             if (poi.getItemOutstandingEncumberedAmount().isGreaterThan(KualiDecimal.ZERO)) {
732                 return true;
733             }
734             return false;
735         }
736     }
737 
738     
739 
740 
741     @Override
742     public boolean canCopyAccountingLinesWithZeroAmount() {
743         boolean canCopyLine = false;
744 
745         
746         String copyZeroAmountLine = parameterService.getParameterValueAsString(OleParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.COPY_ACCOUNTING_LINES_WITH_ZERO_AMOUNT_FROM_PO_TO_PREQ_IND);
747 
748         if ("Y".equalsIgnoreCase(copyZeroAmountLine)) {
749             return true;
750         }
751 
752         return canCopyLine;
753     }
754 
755     public OleSelectDocumentService getOleSelectDocumentService() {
756         if(oleSelectDocumentService == null){
757             oleSelectDocumentService = SpringContext.getBean(OleSelectDocumentService.class);
758         }
759         return oleSelectDocumentService;
760     }
761 
762     public void setOleSelectDocumentService(OleSelectDocumentService oleSelectDocumentService) {
763         this.oleSelectDocumentService = oleSelectDocumentService;
764     }
765 
766 }
767