1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.fp.document.validation.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.ole.fp.businessobject.DisbursementVoucherNonEmployeeTravel;
20 import org.kuali.ole.fp.document.DisbursementVoucherConstants;
21 import org.kuali.ole.fp.document.DisbursementVoucherDocument;
22 import org.kuali.ole.fp.document.service.DisbursementVoucherTaxService;
23 import org.kuali.ole.fp.document.service.DisbursementVoucherTravelService;
24 import org.kuali.ole.sys.OLEConstants;
25 import org.kuali.ole.sys.OLEKeyConstants;
26 import org.kuali.ole.sys.OLEPropertyConstants;
27 import org.kuali.ole.sys.context.SpringContext;
28 import org.kuali.ole.sys.document.AccountingDocument;
29 import org.kuali.ole.sys.document.validation.GenericValidation;
30 import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
31 import org.kuali.rice.core.api.parameter.ParameterEvaluator;
32 import org.kuali.rice.core.api.parameter.ParameterEvaluatorService;
33 import org.kuali.rice.core.api.util.type.KualiDecimal;
34 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
35 import org.kuali.rice.kns.service.DictionaryValidationService;
36 import org.kuali.rice.krad.util.GlobalVariables;
37 import org.kuali.rice.krad.util.MessageMap;
38 import org.kuali.rice.krad.util.ObjectUtils;
39
40 public class DisbursementVoucherNonEmployeeTravelValidation extends GenericValidation {
41 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherNonEmployeeTravelValidation.class);
42
43 private ParameterService parameterService;
44 private DisbursementVoucherTaxService disbursementVoucherTaxService;
45 private DisbursementVoucherTravelService disbursementVoucherTravelService;
46 private DictionaryValidationService dictionaryValidationService;
47 private AccountingDocument accountingDocumentForValidation;
48
49
50
51
52 public boolean validate(AttributedDocumentEvent event) {
53 LOG.debug("validate start");
54 boolean isValid = true;
55
56 DisbursementVoucherDocument document = (DisbursementVoucherDocument) accountingDocumentForValidation;
57 DisbursementVoucherNonEmployeeTravel nonEmployeeTravel = document.getDvNonEmployeeTravel();
58
59
60 if (!isTravelNonEmplPaymentReason(document) || document.getDvPayeeDetail().isEmployee()) {
61 return true;
62 }
63
64 MessageMap errors = GlobalVariables.getMessageMap();
65 errors.addToErrorPath(OLEPropertyConstants.DOCUMENT);
66 errors.addToErrorPath(OLEPropertyConstants.DV_NON_EMPLOYEE_TRAVEL);
67
68 getDictionaryValidationService().validateBusinessObjectsRecursively(document.getDvNonEmployeeTravel(), 1);
69
70
71 if (OLEConstants.COUNTRY_CODE_UNITED_STATES.equals(nonEmployeeTravel.getDvTravelFromCountryCode()) && StringUtils.isBlank(nonEmployeeTravel.getDisbVchrTravelFromStateCode())) {
72 errors.putError(OLEPropertyConstants.DISB_VCHR_TRAVEL_FROM_STATE_CODE, OLEKeyConstants.ERROR_DV_TRAVEL_FROM_STATE);
73 isValid = false;
74 }
75
76 if (OLEConstants.COUNTRY_CODE_UNITED_STATES.equals(nonEmployeeTravel.getDisbVchrTravelToCountryCode()) && StringUtils.isBlank(nonEmployeeTravel.getDisbVchrTravelToStateCode())) {
77 errors.putError(OLEPropertyConstants.DISB_VCHR_TRAVEL_TO_STATE_CODE, OLEKeyConstants.ERROR_DV_TRAVEL_TO_STATE);
78 isValid = false;
79 }
80
81 if (!isValid) {
82 errors.removeFromErrorPath(OLEPropertyConstants.DV_NON_EMPLOYEE_TRAVEL);
83 errors.removeFromErrorPath(OLEPropertyConstants.DOCUMENT);
84 return false;
85 }
86
87
88 boolean perDiemSectionComplete = validatePerDiemSection(document, errors);
89
90
91 boolean personalVehicleSectionComplete = validatePersonalVehicleSection(document, errors);
92
93
94 if (perDiemSectionComplete) {
95 if (nonEmployeeTravel.getDisbVchrPerdiemCalculatedAmt().compareTo(nonEmployeeTravel.getDisbVchrPerdiemActualAmount()) != 0 && StringUtils.isBlank(nonEmployeeTravel.getDvPerdiemChangeReasonText())) {
96 errors.putError(OLEPropertyConstants.DV_PERDIEM_CHANGE_REASON_TEXT, OLEKeyConstants.ERROR_DV_PERDIEM_CHANGE_REQUIRED);
97 isValid = false;
98 }
99 }
100
101
102 if (perDiemSectionComplete) {
103 KualiDecimal calculatedPerDiem = getDisbursementVoucherTravelService().calculatePerDiemAmount(nonEmployeeTravel.getDvPerdiemStartDttmStamp(), nonEmployeeTravel.getDvPerdiemEndDttmStamp(), nonEmployeeTravel.getDisbVchrPerdiemRate());
104 if (calculatedPerDiem.compareTo(nonEmployeeTravel.getDisbVchrPerdiemCalculatedAmt()) != 0) {
105 errors.putErrorWithoutFullErrorPath(OLEConstants.GENERAL_NONEMPLOYEE_TAB_ERRORS, OLEKeyConstants.ERROR_DV_PER_DIEM_CALC_CHANGE);
106 isValid = false;
107 }
108 }
109
110
111 isValid &= validateTravelAmount(document);
112
113
114 if (personalVehicleSectionComplete) {
115 KualiDecimal currentCalcAmt = document.getDvNonEmployeeTravel().getDisbVchrMileageCalculatedAmt();
116 KualiDecimal currentActualAmt = document.getDvNonEmployeeTravel().getDisbVchrPersonalCarAmount();
117 if (ObjectUtils.isNotNull(currentCalcAmt) && ObjectUtils.isNotNull(currentActualAmt)) {
118 KualiDecimal calculatedMileageAmount = getDisbursementVoucherTravelService().calculateMileageAmount(document.getDvNonEmployeeTravel().getDvPersonalCarMileageAmount(), document.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp());
119 if (calculatedMileageAmount.compareTo(document.getDvNonEmployeeTravel().getDisbVchrMileageCalculatedAmt()) != 0) {
120 errors.putErrorWithoutFullErrorPath(OLEConstants.GENERAL_NONEMPLOYEE_TAB_ERRORS, OLEKeyConstants.ERROR_DV_MILEAGE_CALC_CHANGE);
121 isValid = false;
122 }
123
124
125 boolean performTravelMileageLimitInd = parameterService.getParameterValueAsBoolean(DisbursementVoucherDocument.class, DisbursementVoucherConstants.NONEMPLOYEE_TRAVEL_ACTUAL_MILEAGE_LIMIT_PARM_NM);
126 if (performTravelMileageLimitInd) {
127
128 if (currentCalcAmt.subtract(currentActualAmt).isNegative()) {
129 errors.putError(OLEPropertyConstants.DV_PERSONAL_CAR_AMOUNT, OLEKeyConstants.ERROR_DV_ACTUAL_MILEAGE_TOO_HIGH);
130 isValid = false;
131 }
132 }
133 }
134 }
135
136 errors.removeFromErrorPath(OLEPropertyConstants.DV_NON_EMPLOYEE_TRAVEL);
137 errors.removeFromErrorPath(OLEPropertyConstants.DOCUMENT);
138
139 return isValid;
140 }
141
142
143
144
145
146
147 protected boolean hasIncomeClassCode(DisbursementVoucherDocument document) {
148 return StringUtils.isNotBlank(document.getDvNonResidentAlienTax().getIncomeClassCode());
149 }
150
151
152
153
154
155
156 protected boolean isGrossUp(DisbursementVoucherDocument document) {
157 return document.getDvNonResidentAlienTax().isIncomeTaxGrossUpCode();
158 }
159
160
161
162
163
164
165 protected boolean validateTravelAmount(DisbursementVoucherDocument document) {
166
167 KualiDecimal paidAmount = document.getDisbVchrCheckTotalAmount();
168 final boolean incomeClassCoded = hasIncomeClassCode(document);
169 final boolean grossUp = isGrossUp(document);
170 final KualiDecimal travelAmount = document.getDvNonEmployeeTravel().getTotalTravelAmount();
171 if (incomeClassCoded && !grossUp) {
172 paidAmount = paidAmount.add(getDisbursementVoucherTaxService().getNonResidentAlienTaxAmount(document));
173 }
174 if (paidAmount.compareTo(travelAmount) != 0) {
175 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(OLEConstants.DV_CHECK_TRAVEL_TOTAL_ERROR, OLEKeyConstants.ERROR_DV_TRAVEL_CHECK_TOTAL);
176 return false;
177 }
178 return true;
179 }
180
181
182
183
184
185
186
187
188
189 private boolean validatePerDiemSection(DisbursementVoucherDocument document, MessageMap errors) {
190 boolean perDiemSectionComplete = true;
191
192
193 boolean perDiemUsed = StringUtils.isNotBlank(document.getDvNonEmployeeTravel().getDisbVchrPerdiemCategoryName()) || ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDisbVchrPerdiemRate()) || ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDisbVchrPerdiemCalculatedAmt()) || ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDisbVchrPerdiemActualAmount());
194
195
196 if (perDiemUsed) {
197 if (StringUtils.isBlank(document.getDvNonEmployeeTravel().getDisbVchrPerdiemCategoryName())) {
198 errors.putError(OLEPropertyConstants.DISB_VCHR_PERDIEM_CATEGORY_NAME, OLEKeyConstants.ERROR_DV_PER_DIEM_CATEGORY);
199 perDiemSectionComplete = false;
200 }
201 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDisbVchrPerdiemRate())) {
202 errors.putError(OLEPropertyConstants.DISB_VCHR_PERDIEM_RATE, OLEKeyConstants.ERROR_DV_PER_DIEM_RATE);
203 perDiemSectionComplete = false;
204 }
205 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDisbVchrPerdiemCalculatedAmt())) {
206 errors.putError(OLEPropertyConstants.DISB_VCHR_PERDIEM_CALCULATED_AMT, OLEKeyConstants.ERROR_DV_PER_DIEM_CALC_AMT);
207 perDiemSectionComplete = false;
208 }
209 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDisbVchrPerdiemActualAmount())) {
210 errors.putError(OLEPropertyConstants.DISB_VCHR_PERDIEM_ACTUAL_AMOUNT, OLEKeyConstants.ERROR_DV_PER_DIEM_ACTUAL_AMT);
211 perDiemSectionComplete = false;
212 }
213 }
214 perDiemSectionComplete = perDiemSectionComplete && perDiemUsed;
215 return perDiemSectionComplete;
216 }
217
218
219
220
221
222
223
224
225
226 private boolean validatePersonalVehicleSection(DisbursementVoucherDocument document, MessageMap errors) {
227 boolean personalVehicleSectionComplete = true;
228
229
230 boolean personalVehilcleUsed = ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDisbVchrAutoFromCityName()) || ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDisbVchrAutoFromStateCode()) || ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDisbVchrAutoToCityName()) || ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDisbVchrAutoToStateCode()) || ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDvPersonalCarMileageAmount()) || ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDisbVchrMileageCalculatedAmt()) || ObjectUtils.isNotNull(document.getDvNonEmployeeTravel().getDisbVchrPersonalCarAmount());
231
232
233
234 if (personalVehilcleUsed) {
235 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDisbVchrAutoFromCityName())) {
236 errors.putError(OLEPropertyConstants.DISB_VCHR_AUTO_FROM_CITY_NAME, OLEKeyConstants.ERROR_DV_AUTO_FROM_CITY);
237 personalVehicleSectionComplete = false;
238 }
239 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDisbVchrAutoToCityName())) {
240 errors.putError(OLEPropertyConstants.DISB_VCHR_AUTO_TO_CITY_NAME, OLEKeyConstants.ERROR_DV_AUTO_TO_CITY);
241 personalVehicleSectionComplete = false;
242 }
243
244
245 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDisbVchrAutoFromStateCode())) {
246 errors.putError(OLEPropertyConstants.DISB_VCHR_AUTO_FROM_STATE_CODE, OLEKeyConstants.ERROR_DV_AUTO_FROM_STATE);
247 personalVehicleSectionComplete = false;
248 }
249 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDisbVchrAutoToStateCode())) {
250 errors.putError(OLEPropertyConstants.DISB_VCHR_AUTO_TO_STATE_CODE, OLEKeyConstants.ERROR_DV_AUTO_TO_STATE);
251 personalVehicleSectionComplete = false;
252 }
253
254
255
256 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDvPersonalCarMileageAmount())) {
257 errors.putError(OLEPropertyConstants.DV_PERSONAL_CAR_MILEAGE_AMOUNT, OLEKeyConstants.ERROR_DV_MILEAGE_AMT);
258 personalVehicleSectionComplete = false;
259 }
260 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDisbVchrMileageCalculatedAmt())) {
261 errors.putError(OLEPropertyConstants.DISB_VCHR_MILEAGE_CALCULATED_AMT, OLEKeyConstants.ERROR_DV_MILEAGE_CALC_AMT);
262 personalVehicleSectionComplete = false;
263 }
264 if (ObjectUtils.isNull(document.getDvNonEmployeeTravel().getDisbVchrPersonalCarAmount())) {
265 errors.putError(OLEPropertyConstants.DISB_VCHR_PERSONAL_CAR_AMOUNT, OLEKeyConstants.ERROR_DV_MILEAGE_ACTUAL_AMT);
266 personalVehicleSectionComplete = false;
267 }
268 }
269 personalVehicleSectionComplete = personalVehicleSectionComplete && personalVehilcleUsed;
270 return personalVehicleSectionComplete;
271 }
272
273
274
275
276
277
278
279
280 private boolean isTravelNonEmplPaymentReason(DisbursementVoucherDocument disbursementVoucherDocument) {
281 ParameterEvaluator travelNonEmplPaymentReasonEvaluator = SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.NONEMPLOYEE_TRAVEL_PAY_REASONS_PARM_NM, disbursementVoucherDocument.getDvPayeeDetail().getDisbVchrPaymentReasonCode());
282 return travelNonEmplPaymentReasonEvaluator.evaluationSucceeds();
283 }
284
285
286
287
288
289
290 public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
291 this.accountingDocumentForValidation = accountingDocumentForValidation;
292 }
293
294
295
296
297
298 public void setParameterService(ParameterService parameterService) {
299 this.parameterService = parameterService;
300 }
301
302
303
304
305
306 public AccountingDocument getAccountingDocumentForValidation() {
307 return accountingDocumentForValidation;
308 }
309
310
311
312
313
314 public DisbursementVoucherTaxService getDisbursementVoucherTaxService() {
315 return disbursementVoucherTaxService;
316 }
317
318
319
320
321
322 public void setDisbursementVoucherTaxService(DisbursementVoucherTaxService disbursementVoucherTaxService) {
323 this.disbursementVoucherTaxService = disbursementVoucherTaxService;
324 }
325
326
327
328
329
330 public DisbursementVoucherTravelService getDisbursementVoucherTravelService() {
331 return disbursementVoucherTravelService;
332 }
333
334
335
336
337
338 public void setDisbursementVoucherTravelService(DisbursementVoucherTravelService disbursementVoucherTravelService) {
339 this.disbursementVoucherTravelService = disbursementVoucherTravelService;
340 }
341
342
343
344
345
346 public DictionaryValidationService getDictionaryValidationService() {
347 return dictionaryValidationService;
348 }
349
350
351
352
353
354 public void setDictionaryValidationService(DictionaryValidationService dictionaryValidationService) {
355 this.dictionaryValidationService = dictionaryValidationService;
356 }
357
358 }