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.krad.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().getDataObjectEntry(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().getDataObjectEntry(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().getDataObjectEntry(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().getDataObjectEntry(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 String accountNumber = account.getAccountNumber()+OLEConstants.ERR_MSG_FOR_ACC_LINE;
242 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_DOCUMENT_ACCOUNT_IS_RESTRICTED, new String[]{accountNumber});
243 return false;
244 }
245 }
246
247
248
249 return true;
250 }
251
252
253
254
255 @Override
256 public boolean isValidChart(String accountIdentifyingPropertyName, Chart chart, DataDictionary dataDictionary) {
257 return isValidChart(chart, dataDictionary, OLEConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
258 }
259
260
261
262
263 @Override
264 public boolean isValidChart(Chart chart, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
265 String label = getChartLabel();
266
267
268 if (ObjectUtils.isNull(chart)) {
269 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
270 return false;
271 }
272
273
274 if (!chart.isActive()) {
275 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
276 return false;
277 }
278
279 return true;
280 }
281
282
283
284
285 @Override
286 public boolean isValidObjectCode(String accountIdentifyingPropertyName, ObjectCode objectCode, DataDictionary dataDictionary) {
287 return isValidObjectCode(objectCode, dataDictionary, OLEConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
288 }
289
290
291
292
293 @Override
294 public boolean isValidObjectCode(ObjectCode objectCode, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
295 String label = getObjectCodeLabel();
296
297
298 if (ObjectUtils.isNull(objectCode)) {
299 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
300 return false;
301 }
302
303
304 if (!objectCode.isFinancialObjectActiveCode()) {
305 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
306 return false;
307 }
308
309 return true;
310 }
311
312
313
314
315 @Override
316 public boolean isValidObjectTypeCode(String accountIdentifyingPropertyName, ObjectType objectTypeCode, DataDictionary dataDictionary) {
317 return isValidObjectTypeCode(objectTypeCode, dataDictionary, OLEConstants.OBJECT_TYPE_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
318 }
319
320
321
322
323 @Override
324 public boolean isValidObjectTypeCode(ObjectType objectTypeCode, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
325
326 String label = getObjectTypeCodeLabel();
327
328
329 if (ObjectUtils.isNull(objectTypeCode)) {
330 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
331 return false;
332 }
333
334
335 if (!objectTypeCode.isActive()) {
336 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
337 return false;
338 }
339
340 return true;
341 }
342
343
344
345
346 @Override
347 public boolean isValidProjectCode(String accountIdentifyingPropertyName, ProjectCode projectCode, DataDictionary dataDictionary) {
348 return isValidProjectCode(projectCode, dataDictionary, OLEConstants.PROJECT_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
349 }
350
351
352
353
354 @Override
355 public boolean isValidProjectCode(ProjectCode projectCode, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
356
357 String label = getProjectCodeLabel();
358
359
360 if (ObjectUtils.isNull(projectCode)) {
361 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
362 return false;
363 }
364
365
366 if (!projectCode.isActive()) {
367 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
368 return false;
369 }
370
371 return true;
372 }
373
374
375
376
377 @Override
378 public boolean isValidSubAccount(String accountIdentifyingPropertyName, SubAccount subAccount, DataDictionary dataDictionary) {
379 return isValidSubAccount(subAccount, dataDictionary, OLEConstants.SUB_ACCOUNT_NUMBER_PROPERTY_NAME, accountIdentifyingPropertyName);
380 }
381
382
383
384
385 @Override
386 public boolean isValidSubAccount(SubAccount subAccount, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
387 String label = getSubAccountLabel();
388
389
390 if (ObjectUtils.isNull(subAccount)) {
391 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
392 return false;
393 }
394
395
396 if (!subAccount.isActive()) {
397 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
398 return false;
399 }
400
401 return true;
402 }
403
404
405
406
407 @Override
408 public boolean isValidSubObjectCode(String accountIdentifyingPropertyName, SubObjectCode subObjectCode, DataDictionary dataDictionary) {
409 return isValidSubObjectCode(subObjectCode, dataDictionary, OLEConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME, accountIdentifyingPropertyName);
410 }
411
412
413
414
415 @Override
416 public boolean isValidSubObjectCode(SubObjectCode subObjectCode, DataDictionary dataDictionary, String errorPropertyName, String accountIdentifyingPropertyName) {
417 String label = getSubObjectCodeLabel();
418
419
420 if (ObjectUtils.isNull(subObjectCode)) {
421 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_EXISTING_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
422 return false;
423 }
424
425
426 if (!subObjectCode.isActive()) {
427 GlobalVariables.getMessageMap().putError(errorPropertyName, OLEKeyConstants.ERROR_INACTIVE_WITH_IDENTIFYING_ACCOUNTING_LINE, label);
428 return false;
429 }
430 return true;
431 }
432
433
434
435
436 @Override
437 public boolean validateAccountingLine(AccountingLine accountingLine) {
438 if (accountingLine == null) {
439 throw new IllegalStateException(SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(OLEKeyConstants.ERROR_DOCUMENT_NULL_ACCOUNTING_LINE));
440 }
441
442
443 DataDictionary dd = dataDictionaryService.getDataDictionary();
444
445 org.kuali.rice.krad.datadictionary.BusinessObjectEntry accountingLineEntry = dd.getBusinessObjectEntry(SourceAccountingLine.class.getName());
446
447
448 String accountIdentifyingPropertyName = getAccountIdentifyingPropertyName(accountingLine);
449
450
451 accountingLine.refreshReferenceObject("chart");
452 Chart chart = accountingLine.getChart();
453 accountingLine.refreshReferenceObject("account");
454 Account account = accountingLine.getAccount();
455 accountingLine.refreshReferenceObject("objectCode");
456 ObjectCode objectCode = accountingLine.getObjectCode();
457
458 boolean valid = true;
459 valid &= isValidChart(accountIdentifyingPropertyName, chart, dd);
460 valid &= isValidAccount(accountIdentifyingPropertyName, account, dd);
461
462 if (StringUtils.isNotBlank(accountingLine.getSubAccountNumber())) {
463 accountingLine.refreshReferenceObject("subAccount");
464 SubAccount subAccount = accountingLine.getSubAccount();
465 valid &= isValidSubAccount(accountIdentifyingPropertyName, subAccount, dd);
466 }
467 valid &= isValidObjectCode(accountIdentifyingPropertyName, objectCode, dd);
468
469 if (StringUtils.isNotBlank(accountingLine.getFinancialSubObjectCode())) {
470 accountingLine.refreshReferenceObject("subObjectCode");
471 SubObjectCode subObjectCode = accountingLine.getSubObjectCode();
472 valid &= isValidSubObjectCode(accountIdentifyingPropertyName, subObjectCode, dd);
473 }
474
475 if (StringUtils.isNotBlank(accountingLine.getProjectCode())) {
476 accountingLine.refreshReferenceObject("project");
477 ProjectCode projectCode = accountingLine.getProject();
478 valid &= isValidProjectCode(accountIdentifyingPropertyName, projectCode, dd);
479 }
480 if (StringUtils.isNotBlank(accountingLine.getReferenceOriginCode())) {
481 accountingLine.refreshReferenceObject("referenceOrigin");
482 OriginationCode referenceOrigin = accountingLine.getReferenceOrigin();
483 valid &= isValidReferenceOriginCode(accountIdentifyingPropertyName, referenceOrigin, accountingLineEntry);
484 }
485 if (StringUtils.isNotBlank(accountingLine.getReferenceTypeCode())) {
486 DocumentTypeEBO referenceType = accountingLine.getReferenceFinancialSystemDocumentTypeCode();
487 valid &= isValidReferenceTypeCode(accountingLine.getReferenceTypeCode(), referenceType, accountingLineEntry, accountIdentifyingPropertyName);
488 }
489 valid &= hasRequiredOverrides(accountingLine, accountingLine.getOverrideCode());
490 return valid;
491 }
492
493
494
495
496
497
498
499
500 protected boolean isValidReferenceOriginCode(String accountIdentifyingPropertyName, OriginationCode referenceOriginCode, org.kuali.rice.krad.datadictionary.BusinessObjectEntry accountingLineEntry) {
501 return checkExistence(referenceOriginCode, accountingLineEntry, OLEPropertyConstants.REFERENCE_ORIGIN_CODE, OLEPropertyConstants.REFERENCE_ORIGIN_CODE, accountIdentifyingPropertyName);
502 }
503
504
505
506
507
508
509
510
511
512 protected boolean isValidReferenceTypeCode(String documentTypeCode, DocumentTypeEBO referenceType, org.kuali.rice.krad.datadictionary.BusinessObjectEntry accountingLineEntry, String errorPropertyIdentifyingName) {
513 if (!StringUtils.isBlank(documentTypeCode) && !getFinancialSystemDocumentTypeService().isCurrentActiveAccountingDocumentType(documentTypeCode)) {
514 GlobalVariables.getMessageMap().putError(OLEPropertyConstants.REFERENCE_TYPE_CODE, OLEKeyConstants.ERROR_DOCUMENT_ACCOUNTING_LINE_NON_ACTIVE_CURRENT_ACCOUNTING_DOCUMENT_TYPE, documentTypeCode);
515 return false;
516 }
517 return checkExistence(referenceType, accountingLineEntry, OLEPropertyConstants.REFERENCE_TYPE_CODE, OLEPropertyConstants.REFERENCE_TYPE_CODE, errorPropertyIdentifyingName);
518 }
519
520
521
522
523
524
525
526
527
528
529
530 protected boolean checkExistence(Object toCheck, org.kuali.rice.krad.datadictionary.BusinessObjectEntry accountingLineEntry, String attributeName, String propertyName, String errorPropertyIdentifyingName) {
531 String label = accountingLineEntry.getAttributeDefinition(attributeName).getShortLabel();
532 if (ObjectUtils.isNull(toCheck)) {
533 GlobalVariables.getMessageMap().putError(propertyName, OLEKeyConstants.ERROR_EXISTENCE, errorPropertyIdentifyingName, label);
534
535 return false;
536 }
537 return true;
538 }
539
540 protected String getAccountIdentifyingPropertyName(AccountingLine accountingLine) {
541 String errorProperty = "";
542
543 if (accountingLine.getSequenceNumber() != null) {
544 errorProperty = "Accounting Line: " + accountingLine.getSequenceNumber() + ", Chart: " + accountingLine.getChartOfAccountsCode() + ", Account: " + accountingLine.getAccountNumber() + " - ";
545 }
546
547 return errorProperty;
548 }
549
550
551
552
553
554 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
555 this.dataDictionaryService = dataDictionaryService;
556 }
557
558 public DataDictionaryService getDataDictionaryService() {
559 return this.dataDictionaryService;
560 }
561
562
563
564
565
566 public FinancialSystemDocumentTypeService getFinancialSystemDocumentTypeService() {
567 return financialSystemDocumentTypeService;
568 }
569
570
571
572
573
574 public void setFinancialSystemDocumentTypeService(FinancialSystemDocumentTypeService financialSystemDocumentTypeService) {
575 this.financialSystemDocumentTypeService = financialSystemDocumentTypeService;
576 }
577 }