1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.ole.module.purap.document;
18
19 import org.kuali.ole.module.purap.PurapConstants;
20 import org.kuali.ole.module.purap.PurapConstants.PurapDocTypeCodes;
21 import org.kuali.ole.module.purap.PurapConstants.PurchaseOrderStatuses;
22 import org.kuali.ole.module.purap.PurapWorkflowConstants;
23 import org.kuali.ole.module.purap.businessobject.PurchaseOrderAccount;
24 import org.kuali.ole.module.purap.businessobject.PurchaseOrderItem;
25 import org.kuali.ole.module.purap.document.service.PurapService;
26 import org.kuali.ole.module.purap.document.service.PurchaseOrderService;
27 import org.kuali.ole.module.purap.document.service.ReceivingService;
28 import org.kuali.ole.module.purap.service.PurapAccountingService;
29 import org.kuali.ole.module.purap.service.PurapGeneralLedgerService;
30 import org.kuali.ole.sys.OLEConstants;
31 import org.kuali.ole.sys.businessobject.AccountingLine;
32 import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
33 import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
34 import org.kuali.ole.sys.businessobject.SourceAccountingLine;
35 import org.kuali.ole.sys.context.SpringContext;
36 import org.kuali.ole.sys.document.AccountingDocument;
37 import org.kuali.rice.core.api.util.type.KualiDecimal;
38 import org.kuali.rice.kew.api.exception.WorkflowException;
39 import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
40 import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
41 import org.kuali.rice.krad.util.ObjectUtils;
42 import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
43
44 import java.math.BigDecimal;
45 import java.util.ArrayList;
46 import java.util.Collections;
47 import java.util.Iterator;
48 import java.util.List;
49
50 import static org.kuali.ole.sys.OLEConstants.GL_DEBIT_CODE;
51 import static org.kuali.rice.core.api.util.type.KualiDecimal.ZERO;
52
53
54
55
56 public class PurchaseOrderAmendmentDocument extends PurchaseOrderDocument {
57 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurchaseOrderAmendmentDocument.class);
58
59 boolean newUnorderedItem;
60 String receivingDeliveryCampusCode;
61
62
63
64
65
66
67
68 @Override
69 public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
70 super.doRouteStatusChange(statusChangeEvent);
71
72 try {
73
74 if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isProcessed()) {
75
76 SpringContext.getBean(PurapGeneralLedgerService.class).generateEntriesApproveAmendPurchaseOrder(this);
77
78
79 if ((getGlOnlySourceAccountingLines() != null && !getGlOnlySourceAccountingLines().isEmpty())) {
80 SpringContext.getBean(PurchaseOrderService.class).sendFyiForGLEntries(this);
81 }
82
83
84 SpringContext.getBean(PurchaseOrderService.class).completePurchaseOrderAmendment(this);
85
86
87 SpringContext.getBean(PurchaseOrderService.class).updateVendorCommodityCode(this);
88
89
90 updateAndSaveAppDocStatus(PurchaseOrderStatuses.APPDOC_OPEN);
91 }
92
93 else if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isDisapproved()) {
94 SpringContext.getBean(PurchaseOrderService.class).setCurrentAndPendingIndicatorsForDisapprovedChangePODocuments(this);
95 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(this);
96
97
98 try {
99 String nodeName = SpringContext.getBean(WorkflowDocumentService.class).getCurrentRouteLevelName(this.getFinancialSystemDocumentHeader().getWorkflowDocument());
100 String reqStatus = PurapConstants.PurchaseOrderStatuses.getPurchaseOrderAppDocDisapproveStatuses().get(nodeName);
101 updateAndSaveAppDocStatus(PurapConstants.PurchaseOrderStatuses.getPurchaseOrderAppDocDisapproveStatuses().get(reqStatus));
102
103 RequisitionDocument req = getPurApSourceDocumentIfPossible();
104 appSpecificRouteDocumentToUser(this.getFinancialSystemDocumentHeader().getWorkflowDocument(), req.getFinancialSystemDocumentHeader().getWorkflowDocument().getRoutedByPrincipalId(), "Notification of Order Disapproval for Requisition " + req.getPurapDocumentIdentifier() + "(document id " + req.getDocumentNumber() + ")", "Requisition Routed By User");
105 return;
106
107 } catch (WorkflowException e) {
108 logAndThrowRuntimeException("Error saving routing data while saving App Doc Status " + getDocumentNumber(), e);
109 }
110 }
111
112 else if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isCanceled()) {
113 SpringContext.getBean(PurchaseOrderService.class).setCurrentAndPendingIndicatorsForCancelledChangePODocuments(this);
114
115
116 updateAndSaveAppDocStatus(PurapConstants.PurchaseOrderStatuses.APPDOC_CANCELLED);
117 }
118 } catch (WorkflowException e) {
119 logAndThrowRuntimeException("Error saving routing data while saving document with id " + getDocumentNumber(), e);
120 }
121 }
122
123
124
125
126
127 @Override
128 public void customizeExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry) {
129
130
131 SpringContext.getBean(PurapGeneralLedgerService.class).customizeGeneralLedgerPendingEntry(this, (AccountingLine) postable, explicitEntry, getPurapDocumentIdentifier(), GL_DEBIT_CODE, PurapDocTypeCodes.PO_DOCUMENT, true);
132
133
134 explicitEntry.setFinancialDocumentTypeCode(PurapDocTypeCodes.PO_AMENDMENT_DOCUMENT);
135 explicitEntry.setFinancialDocumentApprovedCode(OLEConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.APPROVED);
136 }
137
138 @Override
139 public List<GeneralLedgerPendingEntrySourceDetail> getGeneralLedgerPendingEntrySourceDetails() {
140 List<GeneralLedgerPendingEntrySourceDetail> accountingLines = new ArrayList<GeneralLedgerPendingEntrySourceDetail>();
141 if (getGlOnlySourceAccountingLines() != null) {
142 Iterator iter = getGlOnlySourceAccountingLines().iterator();
143 while (iter.hasNext()) {
144 accountingLines.add((GeneralLedgerPendingEntrySourceDetail) iter.next());
145 }
146 }
147 return accountingLines;
148 }
149
150
151 @Override
152 public void populateDocumentForRouting() {
153 newUnorderedItem = SpringContext.getBean(PurchaseOrderService.class).hasNewUnorderedItem(this);
154 receivingDeliveryCampusCode = SpringContext.getBean(ReceivingService.class).getReceivingDeliveryCampusCode(this);
155 super.populateDocumentForRouting();
156 }
157
158 public boolean isNewUnorderedItem() {
159 return newUnorderedItem;
160 }
161
162 public void setNewUnorderedItem(boolean newUnorderedItem) {
163 this.newUnorderedItem = newUnorderedItem;
164 }
165
166 public String getReceivingDeliveryCampusCode() {
167 return receivingDeliveryCampusCode;
168 }
169
170 public void setReceivingDeliveryCampusCode(String receivingDeliveryCampusCode) {
171 this.receivingDeliveryCampusCode = receivingDeliveryCampusCode;
172 }
173
174 @Override
175 public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
176 if (nodeName.equals(PurapWorkflowConstants.HAS_NEW_UNORDERED_ITEMS)) {
177 return isNewUnorderedItem();
178 }
179 throw new UnsupportedOperationException("Cannot answer split question for this node you call \"" + nodeName + "\"");
180 }
181
182
183 @Override
184 public Class<? extends AccountingDocument> getDocumentClassForAccountingLineValueAllowedValidation() {
185 return PurchaseOrderDocument.class;
186 }
187
188
189 @Override
190 public void customPrepareForSave(KualiDocumentEvent event) {
191 super.customPrepareForSave(event);
192
193
194 List<PurchaseOrderItem> poItems = this.getItems();
195 for (PurchaseOrderItem item : poItems) {
196 if (item.isItemActiveIndicator()) {
197 KualiDecimal invoicedTotalQuantity = item.getItemInvoicedTotalQuantity();
198 if (item.getItemInvoicedTotalQuantity() == null) {
199 invoicedTotalQuantity = ZERO;
200 item.setItemInvoicedTotalQuantity(ZERO);
201 }
202
203 if (item.getItemInvoicedTotalAmount() == null) {
204 item.setItemInvoicedTotalAmount(ZERO);
205 }
206 if (item.getItemType().isQuantityBasedGeneralLedgerIndicator()) {
207 KualiDecimal itemQuantity = item.getItemQuantity() == null ? ZERO : item.getItemQuantity();
208 KualiDecimal outstandingEncumberedQuantity = itemQuantity.subtract(invoicedTotalQuantity);
209 item.setItemOutstandingEncumberedQuantity(outstandingEncumberedQuantity);
210 }
211 KualiDecimal outstandingEncumbrance = null;
212
213
214 if (item.getItemType().isAmountBasedGeneralLedgerIndicator()) {
215 KualiDecimal totalAmount = item.getTotalAmount() == null ? ZERO : item.getTotalAmount();
216 outstandingEncumbrance = totalAmount.subtract(item.getItemInvoicedTotalAmount());
217 item.setItemOutstandingEncumberedAmount(outstandingEncumbrance);
218 } else {
219
220 BigDecimal itemUnitPrice = ObjectUtils.isNull(item.getItemUnitPrice()) ? BigDecimal.ZERO : item
221 .getItemUnitPrice();
222 outstandingEncumbrance = new KualiDecimal(item.getItemOutstandingEncumberedQuantity()
223 .bigDecimalValue().multiply(itemUnitPrice));
224 item.setItemOutstandingEncumberedAmount(outstandingEncumbrance);
225 }
226
227 List accountLines = item.getSourceAccountingLines();
228 Collections.sort(accountLines);
229
230 updateEncumbranceOnAccountingLines(outstandingEncumbrance, accountLines);
231 }
232 }
233
234 List<SourceAccountingLine> sourceLines = SpringContext.getBean(PurapAccountingService.class)
235 .generateSummaryWithNoZeroTotals(this.getItems());
236 this.setSourceAccountingLines(sourceLines);
237 }
238
239
240 protected void updateEncumbranceOnAccountingLines(KualiDecimal outstandingEcumbrance, List accountLines) {
241 for (Object accountLineObject : accountLines) {
242 PurchaseOrderAccount accountLine = (PurchaseOrderAccount) accountLineObject;
243 if (!accountLine.isEmpty()) {
244 BigDecimal linePercent = accountLine.getAccountLinePercent();
245 KualiDecimal accountOutstandingEncumbrance = new KualiDecimal(outstandingEcumbrance.bigDecimalValue()
246 .multiply(linePercent).divide(OLEConstants.ONE_HUNDRED.bigDecimalValue()));
247 accountLine.setItemAccountOutstandingEncumbranceAmount(accountOutstandingEncumbrance);
248 }
249 }
250 }
251 }