1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.ole.module.purap.document.validation.impl;
17  
18  import org.kuali.ole.module.purap.PurapConstants;
19  import org.kuali.ole.module.purap.PurapConstants.ItemFields;
20  import org.kuali.ole.module.purap.PurapKeyConstants;
21  import org.kuali.ole.module.purap.PurapParameterConstants;
22  import org.kuali.ole.module.purap.businessobject.PaymentRequestItem;
23  import org.kuali.ole.module.purap.businessobject.PurApAccountingLine;
24  import org.kuali.ole.module.purap.businessobject.PurApItem;
25  import org.kuali.ole.module.purap.document.PaymentRequestDocument;
26  import org.kuali.ole.module.purap.document.service.PurapService;
27  import org.kuali.ole.select.businessobject.OlePaymentRequestItem;
28  import org.kuali.ole.sys.context.SpringContext;
29  import org.kuali.ole.sys.document.validation.GenericValidation;
30  import org.kuali.ole.sys.document.validation.Validation;
31  import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
32  import org.kuali.ole.sys.document.validation.impl.*;
33  import org.kuali.ole.sys.service.impl.OleParameterConstants;
34  import org.kuali.rice.core.api.util.type.KualiDecimal;
35  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
36  import org.kuali.rice.krad.util.GlobalVariables;
37  import org.kuali.rice.krad.util.ObjectUtils;
38  
39  import java.util.ArrayList;
40  import java.util.List;
41  
42  public class PaymentRequestProcessItemValidation extends GenericValidation {
43  
44      private PurapService purapService;
45      private PurApItem itemForValidation;
46      private AttributedDocumentEvent event;
47      private CompositeValidation reviewAccountingLineValidation;
48      private PaymentRequestDocument preqDocument;
49      private PurApAccountingLine preqAccountingLine;
50  
51      @Override
52      public boolean validate(AttributedDocumentEvent event) {
53          boolean valid = true;
54          this.event = event;
55  
56          PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) event.getDocument();
57          PaymentRequestItem preqItem = (PaymentRequestItem) itemForValidation;
58  
59          valid &= validateEachItem(paymentRequestDocument, preqItem);
60  
61          return valid;
62  
63      }
64  
65      
66  
67  
68  
69  
70  
71  
72      protected boolean validateEachItem(PaymentRequestDocument paymentRequestDocument, PaymentRequestItem item) {
73          boolean valid = true;
74          String identifierString = item.getItemIdentifierString();
75          valid &= validateItem(paymentRequestDocument, item, identifierString);
76          return valid;
77      }
78  
79      
80  
81  
82  
83  
84  
85  
86  
87  
88      public boolean validateItem(PaymentRequestDocument paymentRequestDocument, PaymentRequestItem item, String identifierString) {
89          boolean valid = true;
90          
91          if (!purapService.isFullDocumentEntryCompleted(paymentRequestDocument)) {
92              if (item.getItemType().isLineItemIndicator()) {
93                  valid &= validateAboveTheLineItems(item, identifierString, paymentRequestDocument.isReceivingDocumentRequiredIndicator());
94              }
95              valid &= validateItemWithoutAccounts(item, identifierString);
96          }
97          
98          valid &= validateItemAccounts(paymentRequestDocument, item, identifierString);
99          return valid;
100     }
101 
102     
103 
104 
105 
106 
107 
108 
109     protected boolean validateAboveTheLineItems(PaymentRequestItem item, String identifierString, boolean isReceivingDocumentRequiredIndicator) {
110         boolean valid = true;
111         
112         
113         if (ObjectUtils.isNotNull(item.getItemQuantity())) {
114             if (item.getItemQuantity().isNegative()) {
115                 
116                 valid = false;
117                 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_AMOUNT_BELOW_ZERO, ItemFields.INVOICE_QUANTITY, identifierString);
118             }
119             if (!isReceivingDocumentRequiredIndicator) {
120                 if (item.getPoOutstandingQuantity().isLessThan(item.getItemQuantity())) {
121                     valid = false;
122                     GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_QUANTITY_TOO_MANY, ItemFields.INVOICE_QUANTITY, identifierString, ItemFields.OPEN_QUANTITY);
123                 }
124             }
125         }
126         if (ObjectUtils.isNotNull(item.getExtendedPrice()) && item.getExtendedPrice().isPositive() && ObjectUtils.isNotNull(item.getPoOutstandingQuantity()) && item.getPoOutstandingQuantity().isPositive()) {
127 
128             
129             if (ObjectUtils.isNull(item.getItemQuantity()) || item.getItemQuantity().isZero()) {
130                 
131                 
132                 valid = false;
133                 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_QUANTITY_REQUIRED, ItemFields.INVOICE_QUANTITY, identifierString, ItemFields.OPEN_QUANTITY);
134             }
135         }
136 
137         
138         if ((ObjectUtils.isNull(item.getPaymentRequest().getPurapDocumentIdentifier())) || (PurapConstants.PaymentRequestStatuses.APPDOC_IN_PROCESS.equals(item.getPaymentRequest().getApplicationDocumentStatus()))) {
139 
140             if ((item.getItemType().isAmountBasedGeneralLedgerIndicator()) && ((item.getExtendedPrice() != null) && item.getExtendedPrice().isNonZero())) {
141                 if (item.getPoOutstandingAmount() == null || item.getPoOutstandingAmount().isZero()) {
142                     valid = false;
143                     GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_AMOUNT_ALREADY_PAID, identifierString);
144                 }
145             }
146         }
147 
148         return valid;
149     }
150 
151     
152 
153 
154 
155 
156 
157     public boolean validateItemWithoutAccounts(PaymentRequestItem item, String identifierString) {
158         boolean valid = true;
159         if (ObjectUtils.isNotNull(item.getItemUnitPrice()) && (new KualiDecimal(item.getItemUnitPrice())).isNonZero() && item.isAccountListEmpty()) {
160             valid = false;
161             GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_INCOMPLETE, identifierString);
162         }
163         return valid;
164     }
165 
166     
167 
168 
169 
170 
171 
172 
173 
174 
175     public boolean validateItemAccounts(PaymentRequestDocument paymentRequestDocument, PaymentRequestItem item, String identifierString) {
176         boolean valid = true;
177         List<PurApAccountingLine> accountingLines = item.getSourceAccountingLines();
178         KualiDecimal itemTotal = item.getTotalAmount();
179         KualiDecimal accountTotal = KualiDecimal.ZERO;
180         
181         OlePaymentRequestItem preqItem = (OlePaymentRequestItem) item;
182         if (preqItem.getItemType().isQuantityBasedGeneralLedgerIndicator() && preqItem.getExtendedPrice() != null && preqItem.getExtendedPrice().compareTo(KualiDecimal.ZERO) != 0) {
183             
184 
185 
186 
187         }
188         for (PurApAccountingLine accountingLine : accountingLines) {
189             if (accountingLine.getAmount().isZero()) {
190                 if (!canApproveAccountingLinesWithZeroAmount()) {
191                     GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_AMOUNT_INVALID, itemForValidation.getItemIdentifierString());
192                     valid &= false;
193                 }
194             }
195             valid &= reviewAccountingLineValidation(paymentRequestDocument, accountingLine);
196             accountTotal = accountTotal.add(accountingLine.getAmount());
197         }
198         if (purapService.isFullDocumentEntryCompleted(paymentRequestDocument)) {
199             
200             if (accountTotal.compareTo(itemTotal) != 0) {
201                 valid = false;
202                 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_AMOUNT_TOTAL, identifierString);
203             }
204         }
205         return  valid;
206     }
207 
208     public CompositeValidation getReviewAccountingLineValidation() {
209         return reviewAccountingLineValidation;
210     }
211 
212     public void setReviewAccountingLineValidation(CompositeValidation reviewAccountingLineValidation) {
213         this.reviewAccountingLineValidation = reviewAccountingLineValidation;
214     }
215 
216     public PurapService getPurapService() {
217         return purapService;
218     }
219 
220     public void setPurapService(PurapService purapService) {
221         this.purapService = purapService;
222     }
223 
224     public PurApItem getItemForValidation() {
225         return itemForValidation;
226     }
227 
228     public void setItemForValidation(PurApItem itemForValidation) {
229         this.itemForValidation = itemForValidation;
230     }
231 
232     protected boolean reviewAccountingLineValidation(PaymentRequestDocument document, PurApAccountingLine accountingLine) {
233         boolean valid = true;
234         List<Validation> gauntlet = new ArrayList<Validation>();
235         this.preqDocument = document;
236         this.preqAccountingLine = accountingLine;
237 
238         createGauntlet(reviewAccountingLineValidation);
239 
240         for (Validation validation : gauntlet) {
241             valid &= validation.validate(event);
242         }
243 
244         return valid;
245     }
246 
247     protected void createGauntlet(CompositeValidation validation) {
248         for (Validation val : validation.getValidations()) {
249             if (val instanceof CompositeValidation) {
250                 createGauntlet((CompositeValidation) val);
251             } else if (val instanceof BusinessObjectDataDictionaryValidation) {
252                 addParametersToValidation((BusinessObjectDataDictionaryValidation) val);
253             } else if (val instanceof AccountingLineAmountPositiveValidation) {
254                 addParametersToValidation((AccountingLineAmountPositiveValidation) val);
255             } else if (val instanceof AccountingLineDataDictionaryValidation) {
256                 addParametersToValidation((AccountingLineDataDictionaryValidation) val);
257             } else if (val instanceof AccountingLineValuesAllowedValidationHutch) {
258                 addParametersToValidation((AccountingLineValuesAllowedValidationHutch) val);
259             } else {
260                 throw new IllegalStateException("Validations in the PaymentRequestProcessItemValidation must contain specific instances of validation");
261             }
262         }
263     }
264 
265     
266 
267 
268 
269 
270 
271 
272     public boolean canApproveAccountingLinesWithZeroAmount() {
273         boolean canApproveLine = false;
274 
275         
276         String approveZeroAmountLine = SpringContext.getBean(ParameterService.class).getParameterValueAsString(OleParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.APPROVE_ACCOUNTING_LINES_WITH_ZERO_DOLLAR_AMOUNT_IND);
277 
278         if ("Y".equalsIgnoreCase(approveZeroAmountLine)) {
279             return true;
280         }
281 
282         return canApproveLine;
283     }
284 
285     protected void addParametersToValidation(BusinessObjectDataDictionaryValidation validation) {
286         validation.setBusinessObjectForValidation(this.preqAccountingLine);
287     }
288 
289     protected void addParametersToValidation(AccountingLineAmountPositiveValidation validation) {
290         validation.setAccountingDocumentForValidation(this.preqDocument);
291         validation.setAccountingLineForValidation(this.preqAccountingLine);
292     }
293 
294     protected void addParametersToValidation(AccountingLineDataDictionaryValidation validation) {
295         validation.setAccountingLineForValidation(this.preqAccountingLine);
296     }
297 
298     protected void addParametersToValidation(AccountingLineValuesAllowedValidationHutch validation) {
299         validation.setAccountingDocumentForValidation(this.preqDocument);
300         validation.setAccountingLineForValidation(this.preqAccountingLine);
301     }
302 
303     
304 
305 
306 
307 
308     protected AttributedDocumentEvent getEvent() {
309         return event;
310     }
311 
312     
313 
314 
315 
316 
317     protected void setEvent(AttributedDocumentEvent event) {
318         this.event = event;
319     }
320 
321     
322 
323 
324 
325 
326     protected PaymentRequestDocument getPreqDocument() {
327         return preqDocument;
328     }
329 
330     
331 
332 
333 
334 
335     protected void setPreqDocument(PaymentRequestDocument preqDocument) {
336         this.preqDocument = preqDocument;
337     }
338 
339     
340 
341 
342 
343 
344     protected PurApAccountingLine getPreqAccountingLine() {
345         return preqAccountingLine;
346     }
347 
348     
349 
350 
351 
352 
353     protected void setPreqAccountingLine(PurApAccountingLine preqAccountingLine) {
354         this.preqAccountingLine = preqAccountingLine;
355     }
356 
357 }