1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.kuali.kfs.fp.document.validation.impl;
20
21 import static org.kuali.kfs.sys.KFSConstants.AMOUNT_PROPERTY_NAME;
22 import static org.kuali.kfs.sys.KFSConstants.CREDIT_AMOUNT_PROPERTY_NAME;
23 import static org.kuali.kfs.sys.KFSConstants.DEBIT_AMOUNT_PROPERTY_NAME;
24 import static org.kuali.kfs.sys.KFSConstants.GL_DEBIT_CODE;
25 import static org.kuali.kfs.sys.KFSConstants.JOURNAL_LINE_HELPER_PROPERTY_NAME;
26 import static org.kuali.kfs.sys.KFSConstants.NEW_SOURCE_ACCT_LINE_PROPERTY_NAME;
27 import static org.kuali.kfs.sys.KFSConstants.SQUARE_BRACKET_LEFT;
28 import static org.kuali.kfs.sys.KFSConstants.SQUARE_BRACKET_RIGHT;
29 import static org.kuali.kfs.sys.KFSConstants.VOUCHER_LINE_HELPER_CREDIT_PROPERTY_NAME;
30 import static org.kuali.kfs.sys.KFSConstants.VOUCHER_LINE_HELPER_DEBIT_PROPERTY_NAME;
31 import static org.kuali.kfs.sys.KFSKeyConstants.ERROR_ZERO_AMOUNT;
32 import static org.kuali.kfs.sys.KFSKeyConstants.ERROR_ZERO_OR_NEGATIVE_AMOUNT;
33 import static org.kuali.kfs.sys.KFSKeyConstants.JournalVoucher.ERROR_NEGATIVE_NON_BUDGET_AMOUNTS;
34 import static org.kuali.kfs.sys.KFSPropertyConstants.BALANCE_TYPE;
35
36 import java.util.Collection;
37
38 import org.apache.commons.lang.StringUtils;
39 import org.kuali.kfs.fp.document.JournalVoucherDocument;
40 import org.kuali.kfs.sys.KFSParameterKeyConstants;
41 import org.kuali.kfs.sys.businessobject.AccountingLine;
42 import org.kuali.kfs.sys.context.SpringContext;
43 import org.kuali.kfs.sys.document.validation.GenericValidation;
44 import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
45 import org.kuali.rice.core.api.util.type.KualiDecimal;
46 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
47 import org.kuali.rice.krad.util.GlobalVariables;
48
49
50
51
52 public class JournalVoucherAccountingLineAmountValidation extends GenericValidation {
53 private JournalVoucherDocument journalVoucherForValidation;
54 private AccountingLine accountingLineForValidation;
55
56
57
58
59
60
61
62
63
64 @Override
65 public boolean validate(AttributedDocumentEvent event) {
66 KualiDecimal amount = getAccountingLineForValidation().getAmount();
67
68 getJournalVoucherForValidation().refreshReferenceObject(BALANCE_TYPE);
69
70 if (getJournalVoucherForValidation().getBalanceType().isFinancialOffsetGenerationIndicator()) {
71
72 if (amount.isZero()) {
73 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(buildMessageMapKeyPathForDebitCreditAmount(true), ERROR_ZERO_OR_NEGATIVE_AMOUNT, "an accounting line");
74 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(buildMessageMapKeyPathForDebitCreditAmount(false), ERROR_ZERO_OR_NEGATIVE_AMOUNT, "an accounting line");
75
76 return false;
77 }
78 else if (amount.isNegative()) {
79 String debitCreditCode = getAccountingLineForValidation().getDebitCreditCode();
80 if (StringUtils.isNotBlank(debitCreditCode) && GL_DEBIT_CODE.equals(debitCreditCode)) {
81 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(buildMessageMapKeyPathForDebitCreditAmount(true), ERROR_ZERO_OR_NEGATIVE_AMOUNT, "an accounting line");
82 }
83 else {
84 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(buildMessageMapKeyPathForDebitCreditAmount(false), ERROR_ZERO_OR_NEGATIVE_AMOUNT, "an accounting line");
85 }
86
87 return false;
88 }
89 }
90 else {
91
92 if (amount.isZero()) {
93 GlobalVariables.getMessageMap().putError(AMOUNT_PROPERTY_NAME, ERROR_ZERO_AMOUNT, "an accounting line");
94 return false;
95 }
96 else if (amount.isNegative()) {
97 if (!allowNegativeAmounts(getAccountingLineForValidation())) {
98 GlobalVariables.getMessageMap().putError(AMOUNT_PROPERTY_NAME, ERROR_NEGATIVE_NON_BUDGET_AMOUNTS);
99 }
100 }
101 }
102
103 return true;
104 }
105
106
107
108
109
110
111
112
113 private boolean allowNegativeAmounts(AccountingLine acctLine) {
114 Collection<String> budgetTypes = SpringContext.getBean(ParameterService.class).getParameterValuesAsString(JournalVoucherDocument.class, KFSParameterKeyConstants.FpParameterConstants.FP_BUDGET_BALANCE_TYPES);
115 return budgetTypes.contains(acctLine.getBalanceTypeCode());
116 }
117
118
119
120
121
122
123
124
125
126
127
128
129
130 protected String buildMessageMapKeyPathForDebitCreditAmount(boolean isDebit) {
131
132 boolean isNewLineAdd = GlobalVariables.getMessageMap().getErrorPath().contains(NEW_SOURCE_ACCT_LINE_PROPERTY_NAME);
133 isNewLineAdd |= GlobalVariables.getMessageMap().getErrorPath().contains(NEW_SOURCE_ACCT_LINE_PROPERTY_NAME);
134
135 if (isNewLineAdd) {
136 return isDebit ? DEBIT_AMOUNT_PROPERTY_NAME : CREDIT_AMOUNT_PROPERTY_NAME;
137 }
138 else {
139 String index = StringUtils.substringBetween(GlobalVariables.getMessageMap().getKeyPath("", true), SQUARE_BRACKET_LEFT, SQUARE_BRACKET_RIGHT);
140 String indexWithParams = SQUARE_BRACKET_LEFT + index + SQUARE_BRACKET_RIGHT;
141 return isDebit ? (JOURNAL_LINE_HELPER_PROPERTY_NAME + indexWithParams + VOUCHER_LINE_HELPER_DEBIT_PROPERTY_NAME) : (JOURNAL_LINE_HELPER_PROPERTY_NAME + indexWithParams + VOUCHER_LINE_HELPER_CREDIT_PROPERTY_NAME);
142 }
143 }
144
145
146
147
148
149 public AccountingLine getAccountingLineForValidation() {
150 return accountingLineForValidation;
151 }
152
153
154
155
156
157 public void setAccountingLineForValidation(AccountingLine accountingLineForValidation) {
158 this.accountingLineForValidation = accountingLineForValidation;
159 }
160
161
162
163
164
165 public JournalVoucherDocument getJournalVoucherForValidation() {
166 return journalVoucherForValidation;
167 }
168
169
170
171
172
173 public void setJournalVoucherForValidation(JournalVoucherDocument journalVoucherForValidation) {
174 this.journalVoucherForValidation = journalVoucherForValidation;
175 }
176 }