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 }