1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sys.document.service.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.log4j.Logger;
20 import org.kuali.ole.coa.businessobject.Account;
21 import org.kuali.ole.coa.businessobject.Chart;
22 import org.kuali.ole.coa.businessobject.FundGroup;
23 import org.kuali.ole.coa.businessobject.ObjectCode;
24 import org.kuali.ole.coa.businessobject.ObjectSubType;
25 import org.kuali.ole.coa.businessobject.ObjectType;
26 import org.kuali.ole.coa.businessobject.Organization;
27 import org.kuali.ole.coa.businessobject.ProjectCode;
28 import org.kuali.ole.coa.businessobject.SubAccount;
29 import org.kuali.ole.coa.businessobject.SubFundGroup;
30 import org.kuali.ole.coa.businessobject.SubObjectCode;
31 import org.kuali.ole.coa.service.AccountService;
32 import org.kuali.ole.select.OleSelectConstant;
33 import org.kuali.ole.sys.OLEConstants;
34 import org.kuali.ole.sys.OLEKeyConstants;
35 import org.kuali.ole.sys.OLEPropertyConstants;
36 import org.kuali.ole.sys.businessobject.AccountingLine;
37 import org.kuali.ole.sys.businessobject.AccountingLineOverride;
38 import org.kuali.ole.sys.businessobject.OriginationCode;
39 import org.kuali.ole.sys.businessobject.SourceAccountingLine;
40 import org.kuali.ole.sys.context.SpringContext;
41 import org.kuali.ole.sys.document.service.AccountingLineRuleHelperService;
42 import org.kuali.ole.sys.document.service.FinancialSystemDocumentTypeService;
43 import org.kuali.rice.core.api.config.property.ConfigurationService;
44 import org.kuali.rice.kew.doctype.bo.DocumentTypeEBO;
45 import org.kuali.rice.kns.service.DataDictionaryService;
46 import org.kuali.rice.krad.datadictionary.DataDictionary;
47 import org.kuali.rice.krad.util.GlobalVariables;
48 import org.kuali.rice.krad.util.ObjectUtils;
49
50 public class AccountingLineRuleHelperServiceImpl implements AccountingLineRuleHelperService {
51 private static Logger LOG = Logger.getLogger(AccountingLineRuleHelperServiceImpl.class);
52 private DataDictionaryService dataDictionaryService;
53 private FinancialSystemDocumentTypeService financialSystemDocumentTypeService;
54
55
56
57
58 @Override
59 public String getAccountLabel() {
60 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(Account.class.getName()).getAttributeDefinition(OLEConstants.ACCOUNT_NUMBER_PROPERTY_NAME).getShortLabel();
61 }
62
63
64
65
66 @Override
67 public String getChartLabel() {
68 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(Chart.class.getName()).getAttributeDefinition(OLEConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME).getShortLabel();
69 }
70
71
72
73
74 @Override
75 public String getFundGroupCodeLabel() {
76 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(FundGroup.class.getName()).getAttributeDefinition(OLEPropertyConstants.CODE).getShortLabel();
77 }
78
79
80
81
82 @Override
83 public String getObjectCodeLabel() {
84 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(ObjectCode.class.getName()).getAttributeDefinition(OLEConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME).getShortLabel();
85 }
86
87
88
89
90 @Override
91 public String getObjectSubTypeCodeLabel() {
92 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(ObjectSubType.class.getName()).getAttributeDefinition(OLEPropertyConstants.CODE).getShortLabel();
93 }
94
95
96
97
98 @Override
99 public String getObjectTypeCodeLabel() {
100 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(ObjectType.class.getName()).getAttributeDefinition(OLEConstants.GENERIC_CODE_PROPERTY_NAME).getShortLabel();
101 }
102
103
104
105
106 @Override
107 public String getOrganizationCodeLabel() {
108 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(Organization.class.getName()).getAttributeDefinition(OLEPropertyConstants.ORGANIZATION_CODE).getShortLabel();
109 }
110
111
112
113
114 @Override
115 public String getProjectCodeLabel() {
116 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(ProjectCode.class.getName()).getAttributeDefinition(OLEPropertyConstants.CODE).getShortLabel();
117 }
118
119
120
121
122 @Override
123 public String getSubAccountLabel() {
124 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(SubAccount.class.getName()).getAttributeDefinition(OLEConstants.SUB_ACCOUNT_NUMBER_PROPERTY_NAME).getShortLabel();
125 }
126
127
128
129
130 @Override
131 public String getSubFundGroupCodeLabel() {
132 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(SubFundGroup.class.getName()).getAttributeDefinition(OLEPropertyConstants.SUB_FUND_GROUP_CODE).getShortLabel();
133 }
134
135
136
137
138 @Override
139 public String getSubObjectCodeLabel() {
140 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(SubObjectCode.class.getName()).getAttributeDefinition(OLEConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME).getShortLabel();
141 }
142
143
144
145
146 @Override
147 public boolean hasRequiredOverrides(AccountingLine line, String overrideCode) {
148 return hasAccountRequiredOverrides(line, overrideCode) && hasObjectBudgetRequiredOverrides(line, overrideCode);
149
150 }
151
152 public boolean hasAccountRequiredOverrides(AccountingLine line, String overrideCode) {
153 boolean retVal = true;
154 AccountingLineOverride override = AccountingLineOverride.valueOf(overrideCode);
155 Account account = line.getAccount();
156 if (AccountingLineOverride.needsExpiredAccountOverride(account) && !override.hasComponent(AccountingLineOverride.COMPONENT.EXPIRED_ACCOUNT)) {
157 Account continuation = getUnexpiredContinuationAccountOrNull(account);
158 if (continuation == null) {
159 GlobalVariables.getMessageMap().putError(OLEConstants.ACCOUNT_NUMBER_PROPERTY_NAME, OLEKeyConstants.ERROR_DOCUMENT_ACCOUNT_EXPIRED_NO_CONTINUATION, new String[] { account.getAccountNumber() });
160 }
161 else {
162 GlobalVariables.getMessageMap().putError(OLEConstants.ACCOUNT_NUMBER_PROPERTY_NAME, OLEKeyConstants.ERROR_DOCUMENT_ACCOUNT_EXPIRED, new String[] { account.getAccountNumber(), continuation.getChartOfAccountsCode(), continuation.getAccountNumber() });
163
164 }
165 retVal = false;
166 }
167 return retVal;
168 }
169
170 public boolean hasObjectBudgetRequiredOverrides(AccountingLine line, String overrideCode) {
171 boolean retVal = true;
172 ObjectCode objectCode = line.getObjectCode();
173 AccountingLineOverride override = AccountingLineOverride.valueOf(overrideCode);
174 Account account = line.getAccount();
175 if (AccountingLineOverride.needsObjectBudgetOverride(account, objectCode) && !override.hasComponent(AccountingLineOverride.COMPONENT.NON_BUDGETED_OBJECT)) {
176 GlobalVariables.getMessageMap().putError(OLEConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, OLEKeyConstants.ERROR_DOCUMENT_ACCOUNT_PRESENCE_NON_BUDGETED_OBJECT_CODE, new String[] { account.getAccountNumber(), objectCode.getFinancialObjectCode() });
177 retVal = false;
178 }
179 return retVal;
180 }
181
182
183
184
185
186 protected Account getUnexpiredContinuationAccountOrNull(Account account) {
187 int count = 0;
188 while (count++ < 10) {
189 String continuationChartCode = account.getContinuationFinChrtOfAcctCd();
190 String continuationAccountNumber = account.getContinuationAccountNumber();
191
192 if (StringUtils.isBlank(continuationChartCode) || StringUtils.isBlank(continuationAccountNumber)) {
193 return null;
194 }
195 account = SpringContext.getBean(AccountService.class).getByPrimaryId(continuationChartCode, continuationAccountNumber);
196 if (ObjectUtils.isNull(account)) {
197 return null;
198 }
199 if (account.isActive() && !account.isExpired()) {
200 return account;
201 }
202 }
203 return null;
204 }
205
206
207
208
209 @Override
210 public boolean isValidAccount(String accountIdentifyingPropertyName, Account account, DataDictionary dataDictionary) {
211 return isValidAccount(account, dataDictionary, OLEConstants.ACCOUNT_NUMBER_PROPERTY_NAME, accountIdentifyingPropertyName);
212 }
213
214
215
216
217 @Override
218 public boolean isValidAccount(Account account, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
219 String label = getAccountLabel();
220
221
222 if (ObjectUtils.isNull(account)) {
223 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
224 return false;
225 }
226
227
228 if (!account.isActive()) {
229 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_DOCUMENT_ACCOUNT_CLOSED_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
230 return false;
231 }
232
233
234
235 if(ObjectUtils.isNotNull(account.getAccountRestrictedStatusCode())){
236 if(account.getAccountRestrictedStatusCode().equalsIgnoreCase(OleSelectConstant.ACCOUNT_TEMPORARY_RESTRICTED_CODE)){
237 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_DOCUMENT_ACCOUNT_IS_TEMPORARY_RESTRICTED, label);
238 return false;
239 }
240 else if(account.getAccountRestrictedStatusCode().equalsIgnoreCase(OleSelectConstant.ACCOUNT_RESTRICTED_CODE)){
241 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_DOCUMENT_ACCOUNT_IS_RESTRICTED, label);
242 return false;
243 }
244 }
245
246
247
248 return true;
249 }
250
251
252
253
254 @Override
255 public boolean isValidChart(String accountIdentifyingPropertyName, Chart chart, DataDictionary dataDictionary) {
256 return isValidChart(chart, dataDictionary, OLEConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
257 }
258
259
260
261
262 @Override
263 public boolean isValidChart(Chart chart, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
264 String label = getChartLabel();
265
266
267 if (ObjectUtils.isNull(chart)) {
268 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
269 return false;
270 }
271
272
273 if (!chart.isActive()) {
274 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
275 return false;
276 }
277
278 return true;
279 }
280
281
282
283
284 @Override
285 public boolean isValidObjectCode(String accountIdentifyingPropertyName, ObjectCode objectCode, DataDictionary dataDictionary) {
286 return isValidObjectCode(objectCode, dataDictionary, OLEConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
287 }
288
289
290
291
292 @Override
293 public boolean isValidObjectCode(ObjectCode objectCode, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
294 String label = getObjectCodeLabel();
295
296
297 if (ObjectUtils.isNull(objectCode)) {
298 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
299 return false;
300 }
301
302
303 if (!objectCode.isFinancialObjectActiveCode()) {
304 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
305 return false;
306 }
307
308 return true;
309 }
310
311
312
313
314 @Override
315 public boolean isValidObjectTypeCode(String accountIdentifyingPropertyName, ObjectType objectTypeCode, DataDictionary dataDictionary) {
316 return isValidObjectTypeCode(objectTypeCode, dataDictionary, OLEConstants.OBJECT_TYPE_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
317 }
318
319
320
321
322 @Override
323 public boolean isValidObjectTypeCode(ObjectType objectTypeCode, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
324
325 String label = getObjectTypeCodeLabel();
326
327
328 if (ObjectUtils.isNull(objectTypeCode)) {
329 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
330 return false;
331 }
332
333
334 if (!objectTypeCode.isActive()) {
335 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
336 return false;
337 }
338
339 return true;
340 }
341
342
343
344
345 @Override
346 public boolean isValidProjectCode(String accountIdentifyingPropertyName, ProjectCode projectCode, DataDictionary dataDictionary) {
347 return isValidProjectCode(projectCode, dataDictionary, OLEConstants.PROJECT_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
348 }
349
350
351
352
353 @Override
354 public boolean isValidProjectCode(ProjectCode projectCode, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
355
356 String label = getProjectCodeLabel();
357
358
359 if (ObjectUtils.isNull(projectCode)) {
360 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
361 return false;
362 }
363
364
365 if (!projectCode.isActive()) {
366 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
367 return false;
368 }
369
370 return true;
371 }
372
373
374
375
376 @Override
377 public boolean isValidSubAccount(String accountIdentifyingPropertyName, SubAccount subAccount, DataDictionary dataDictionary) {
378 return isValidSubAccount(subAccount, dataDictionary, OLEConstants.SUB_ACCOUNT_NUMBER_PROPERTY_NAME, accountIdentifyingPropertyName);
379 }
380
381
382
383
384 @Override
385 public boolean isValidSubAccount(SubAccount subAccount, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
386 String label = getSubAccountLabel();
387
388
389 if (ObjectUtils.isNull(subAccount)) {
390 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
391 return false;
392 }
393
394
395 if (!subAccount.isActive()) {
396 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
397 return false;
398 }
399
400 return true;
401 }
402
403
404
405
406 @Override
407 public boolean isValidSubObjectCode(String accountIdentifyingPropertyName, SubObjectCode subObjectCode, DataDictionary dataDictionary) {
408 return isValidSubObjectCode(subObjectCode, dataDictionary, OLEConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
409 }
410
411
412
413
414 @Override
415 public boolean isValidSubObjectCode(SubObjectCode subObjectCode, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
416 String label = getSubObjectCodeLabel();
417
418
419 if (ObjectUtils.isNull(subObjectCode)) {
420 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
421 return false;
422 }
423
424
425 if (!subObjectCode.isActive()) {
426 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
427 return false;
428 }
429 return true;
430 }
431
432
433
434
435 @Override
436 public boolean validateAccountingLine(AccountingLine accountingLine) {
437 if (accountingLine == null) {
438 throw new IllegalStateException(SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(OLEKeyConstants.ERROR_DOCUMENT_NULL_ACCOUNTING_LINE));
439 }
440
441
442 DataDictionary dd = dataDictionaryService.getDataDictionary();
443
444 org.kuali.rice.krad.datadictionary.BusinessObjectEntry accountingLineEntry = dd.getBusinessObjectEntry(SourceAccountingLine.class.getName());
445
446
447 String accountIdentifyingPropertyName = getAccountIdentifyingPropertyName(accountingLine);
448
449
450 accountingLine.refreshReferenceObject("chart");
451 Chart chart = accountingLine.getChart();
452 accountingLine.refreshReferenceObject("account");
453 Account account = accountingLine.getAccount();
454 accountingLine.refreshReferenceObject("objectCode");
455 ObjectCode objectCode = accountingLine.getObjectCode();
456
457 boolean valid = true;
458 valid &= isValidChart(accountIdentifyingPropertyName, chart, dd);
459 valid &= isValidAccount(accountIdentifyingPropertyName, account, dd);
460
461 if (StringUtils.isNotBlank(accountingLine.getSubAccountNumber())) {
462 accountingLine.refreshReferenceObject("subAccount");
463 SubAccount subAccount = accountingLine.getSubAccount();
464 valid &= isValidSubAccount(accountIdentifyingPropertyName, subAccount, dd);
465 }
466 valid &= isValidObjectCode(accountIdentifyingPropertyName, objectCode, dd);
467
468 if (StringUtils.isNotBlank(accountingLine.getFinancialSubObjectCode())) {
469 accountingLine.refreshReferenceObject("subObjectCode");
470 SubObjectCode subObjectCode = accountingLine.getSubObjectCode();
471 valid &= isValidSubObjectCode(accountIdentifyingPropertyName, subObjectCode, dd);
472 }
473
474 if (StringUtils.isNotBlank(accountingLine.getProjectCode())) {
475 accountingLine.refreshReferenceObject("project");
476 ProjectCode projectCode = accountingLine.getProject();
477 valid &= isValidProjectCode(accountIdentifyingPropertyName, projectCode, dd);
478 }
479 if (StringUtils.isNotBlank(accountingLine.getReferenceOriginCode())) {
480 accountingLine.refreshReferenceObject("referenceOrigin");
481 OriginationCode referenceOrigin = accountingLine.getReferenceOrigin();
482 valid &= isValidReferenceOriginCode(accountIdentifyingPropertyName, referenceOrigin, accountingLineEntry);
483 }
484 if (StringUtils.isNotBlank(accountingLine.getReferenceTypeCode())) {
485 DocumentTypeEBO referenceType = accountingLine.getReferenceFinancialSystemDocumentTypeCode();
486 valid &= isValidReferenceTypeCode(accountingLine.getReferenceTypeCode(), referenceType, accountingLineEntry, accountIdentifyingPropertyName);
487 }
488 valid &= hasRequiredOverrides(accountingLine, accountingLine.getOverrideCode());
489 return valid;
490 }
491
492
493
494
495
496
497
498
499 protected boolean isValidReferenceOriginCode(String accountIdentifyingPropertyName, OriginationCode referenceOriginCode, org.kuali.rice.krad.datadictionary.BusinessObjectEntry accountingLineEntry) {
500 return checkExistence(referenceOriginCode, accountingLineEntry, OLEPropertyConstants.REFERENCE_ORIGIN_CODE, OLEPropertyConstants.REFERENCE_ORIGIN_CODE, accountIdentifyingPropertyName);
501 }
502
503
504
505
506
507
508
509
510
511 protected boolean isValidReferenceTypeCode(String documentTypeCode, DocumentTypeEBO referenceType, org.kuali.rice.krad.datadictionary.BusinessObjectEntry accountingLineEntry, String errorPropertyIdentifyingName) {
512 if (!StringUtils.isBlank(documentTypeCode) && !getFinancialSystemDocumentTypeService().isCurrentActiveAccountingDocumentType(documentTypeCode)) {
513 GlobalVariables.getMessageMap().putError(OLEPropertyConstants.REFERENCE_TYPE_CODE, OLEKeyConstants.ERROR_DOCUMENT_ACCOUNTING_LINE_NON_ACTIVE_CURRENT_ACCOUNTING_DOCUMENT_TYPE, documentTypeCode);
514 return false;
515 }
516 return checkExistence(referenceType, accountingLineEntry, OLEPropertyConstants.REFERENCE_TYPE_CODE, OLEPropertyConstants.REFERENCE_TYPE_CODE, errorPropertyIdentifyingName);
517 }
518
519
520
521
522
523
524
525
526
527
528
529 protected boolean checkExistence(Object toCheck, org.kuali.rice.krad.datadictionary.BusinessObjectEntry accountingLineEntry, String attributeName, String propertyName, String errorPropertyIdentifyingName) {
530 String label = accountingLineEntry.getAttributeDefinition(attributeName).getShortLabel();
531 if (ObjectUtils.isNull(toCheck)) {
532 GlobalVariables.getMessageMap().putError(propertyName, OLEKeyConstants.ERROR_EXISTENCE, errorPropertyIdentifyingName, label);
533
534 return false;
535 }
536 return true;
537 }
538
539 protected String getAccountIdentifyingPropertyName(AccountingLine accountingLine) {
540 String errorProperty = "";
541
542 if (accountingLine.getSequenceNumber() != null) {
543 errorProperty = "Accounting Line: " + accountingLine.getSequenceNumber() + ", Chart: " + accountingLine.getChartOfAccountsCode() + ", Account: " + accountingLine.getAccountNumber() + " - ";
544 }
545
546 return errorProperty;
547 }
548
549
550
551
552
553 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
554 this.dataDictionaryService = dataDictionaryService;
555 }
556
557 public DataDictionaryService getDataDictionaryService() {
558 return this.dataDictionaryService;
559 }
560
561
562
563
564
565 public FinancialSystemDocumentTypeService getFinancialSystemDocumentTypeService() {
566 return financialSystemDocumentTypeService;
567 }
568
569
570
571
572
573 public void setFinancialSystemDocumentTypeService(FinancialSystemDocumentTypeService financialSystemDocumentTypeService) {
574 this.financialSystemDocumentTypeService = financialSystemDocumentTypeService;
575 }
576 }