001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.module.endow.document.validation.impl;
017    
018    import java.math.BigDecimal;
019    import java.util.List;
020    
021    import org.kuali.kfs.module.endow.EndowConstants;
022    import org.kuali.kfs.module.endow.EndowKeyConstants;
023    import org.kuali.kfs.module.endow.EndowPropertyConstants;
024    import org.kuali.kfs.module.endow.businessobject.EndowmentSourceTransactionLine;
025    import org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine;
026    import org.kuali.kfs.module.endow.businessobject.EndowmentTransactionSecurity;
027    import org.kuali.kfs.module.endow.businessobject.EndowmentTransactionTaxLotLine;
028    import org.kuali.kfs.module.endow.document.AssetDecreaseDocument;
029    import org.kuali.kfs.module.endow.document.EndowmentSecurityDetailsDocument;
030    import org.kuali.kfs.module.endow.document.EndowmentTaxLotLinesDocument;
031    import org.kuali.kfs.module.endow.document.EndowmentTransactionLinesDocument;
032    import org.kuali.kfs.module.endow.document.EndowmentTransactionLinesDocumentBase;
033    import org.kuali.kfs.module.endow.document.validation.DeleteTaxLotLineRule;
034    import org.kuali.rice.kns.document.Document;
035    
036    public class AssetDecreaseDocumentRules extends EndowmentTransactionLinesDocumentBaseRules implements DeleteTaxLotLineRule<EndowmentTaxLotLinesDocument, EndowmentTransactionTaxLotLine, EndowmentTransactionLine, Number, Number> {
037    
038        /**
039         * @see org.kuali.rice.kns.rules.DocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.Document)
040         */
041        @Override
042        protected boolean processCustomRouteDocumentBusinessRules(Document document) {
043            AssetDecreaseDocument assetDecreaseDocument = (AssetDecreaseDocument) document;
044            EndowmentTransactionSecurity endowmentTransactionSecurity = assetDecreaseDocument.getSourceTransactionSecurity();
045    
046            // Validate at least one Tx was entered.
047            if (!transactionLineSizeGreaterThanZero(assetDecreaseDocument, true))
048                return false;
049    
050            boolean isValid = super.processCustomRouteDocumentBusinessRules(document);
051    
052            if (isValid) {
053                isValid &= validateSecurity(isValid, assetDecreaseDocument, true);
054                isValid &= validateRegistration(isValid, assetDecreaseDocument, true);
055            }
056    
057            for (int i = 0; i < assetDecreaseDocument.getSourceTransactionLines().size(); i++) {
058                EndowmentTransactionLine txLine = assetDecreaseDocument.getSourceTransactionLines().get(i);
059    
060                isValid &= validateAssetDecreaseTransactionLine(false, assetDecreaseDocument, txLine, i, -1);
061                if (isValid) {
062                    isValid &= validateTotalAmountAndUnits(assetDecreaseDocument, txLine, i);
063                    isValid &= validateTaxLots(assetDecreaseDocument, txLine, i);
064    
065                }
066            }
067    
068            return isValid;
069        }
070    
071        /**
072         * @see org.kuali.kfs.module.endow.document.validation.impl.EndowmentTransactionLinesDocumentBaseRules#processAddTransactionLineRules(org.kuali.kfs.module.endow.document.EndowmentTransactionLinesDocument,
073         *      org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine)
074         */
075        @Override
076        public boolean processAddTransactionLineRules(EndowmentTransactionLinesDocument document, EndowmentTransactionLine line) {
077            boolean isValid = true;
078            AssetDecreaseDocument assetDecreaseDocument = (AssetDecreaseDocument) document;
079    
080            isValid &= validateSecurity(isValid, assetDecreaseDocument, true);
081            isValid &= validateRegistration(isValid, assetDecreaseDocument, true);
082            isValid &= super.processAddTransactionLineRules(document, line);
083    
084            if (isValid) {
085                isValid &= validateAssetDecreaseTransactionLine(true, assetDecreaseDocument, line, -1, -1);
086            }
087    
088            return isValid;
089        }
090    
091        /**
092         * @see org.kuali.kfs.module.endow.document.validation.impl.EndowmentTransactionLinesDocumentBaseRules#processRefreshTransactionLineRules(org.kuali.kfs.module.endow.document.EndowmentTransactionLinesDocument,
093         *      org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine, java.lang.Number)
094         */
095        @Override
096        public boolean processRefreshTransactionLineRules(EndowmentTransactionLinesDocument endowmentTransactionLinesDocument, EndowmentTransactionLine endowmentTransactionLine, Number index) {
097    
098            boolean isValid = super.processRefreshTransactionLineRules(endowmentTransactionLinesDocument, endowmentTransactionLine, index);
099            if (isValid) {
100                isValid &= validateAssetDecreaseTransactionLine(false, endowmentTransactionLinesDocument, endowmentTransactionLine, (Integer) index, -1);
101            }
102            return isValid;
103        }
104    
105        /**
106         * @see org.kuali.kfs.module.endow.document.validation.impl.EndowmentTransactionalDocumentBaseRule#validateSecurityClassTypeCode(org.kuali.kfs.module.endow.document.EndowmentSecurityDetailsDocument,
107         *      boolean, java.lang.String)
108         */
109        @Override
110        protected boolean validateSecurityClassTypeCode(EndowmentSecurityDetailsDocument document, boolean isSource, String classCodeType) {
111            return validateSecurityClassCodeTypeNotLiability(document, true);
112        }
113    
114        /**
115         * Adds validations for the transaction line specific to the Asset decrease document.
116         * 
117         * @param isAdd
118         * @param endowmentTransactionLinesDocumentBase
119         * @param line
120         * @param index
121         * @return true if valid, false otherwise
122         */
123        protected boolean validateAssetDecreaseTransactionLine(boolean isAdd, EndowmentTransactionLinesDocument endowmentTransactionLinesDocument, EndowmentTransactionLine line, int index, int taxLotLineToDeleteIndex) {
124            boolean isValid = true;
125            AssetDecreaseDocument assetDecreaseDocument = (AssetDecreaseDocument) endowmentTransactionLinesDocument;
126            EndowmentSourceTransactionLine targetTransactionLine = (EndowmentSourceTransactionLine) line;
127    
128            isValid &= validateSecurity(isValid, assetDecreaseDocument, true);
129            isValid &= validateRegistration(isValid, assetDecreaseDocument, true);
130    
131            if (isValid) {
132                isValid &= checkCashTransactionEndowmentCode(endowmentTransactionLinesDocument, targetTransactionLine, getErrorPrefix(targetTransactionLine, index));
133    
134                if (EndowConstants.TransactionSubTypeCode.CASH.equalsIgnoreCase(assetDecreaseDocument.getTransactionSubTypeCode())) {
135                    if (endowmentTransactionLinesDocument.isErrorCorrectedDocument()) {
136                        // Validate Amount is Less than Zero.
137                        isValid &= validateTransactionAmountLessThanZero(line, getErrorPrefix(targetTransactionLine, index));
138                    }
139                    else {
140                        // Validate Greater then Zero(thus positive) value
141                        isValid &= validateTransactionAmountGreaterThanZero(line, getErrorPrefix(targetTransactionLine, index));
142                    }
143                }
144    
145                if (endowmentTransactionLinesDocument.isErrorCorrectedDocument()) {
146                    // Validate Units is Less than Zero.
147                    isValid &= validateTransactionUnitsLessThanZero(line, getErrorPrefix(targetTransactionLine, index));
148                }
149                else {
150                    isValid &= validateTransactionUnitsGreaterThanZero(line, getErrorPrefix(targetTransactionLine, index));
151                }
152    
153                if (isValid) {
154                    isValid &= validateSufficientUnits(isAdd, assetDecreaseDocument, line, index, taxLotLineToDeleteIndex);
155                    isValid &= validateSecurityEtranChartMatch(endowmentTransactionLinesDocument, line, getErrorPrefix(targetTransactionLine, index), true);
156                }
157            }
158    
159            return isValid;
160        }
161    
162    
163        /**
164         * @see org.kuali.kfs.module.endow.document.validation.DeleteTaxLotLineRule#processDeleteTaxLotLineRules(org.kuali.kfs.module.endow.document.EndowmentTaxLotLinesDocument,
165         *      org.kuali.kfs.module.endow.businessobject.EndowmentTransactionTaxLotLine,
166         *      org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine, java.lang.Number)
167         */
168        public boolean processDeleteTaxLotLineRules(EndowmentTaxLotLinesDocument endowmentTaxLotLinesDocument, EndowmentTransactionTaxLotLine taxLotLine, EndowmentTransactionLine transactionLine, Number index, Number taxLotLineIndex) {
169            boolean isValid = true;
170            isValid &= validateTransactionLine(endowmentTaxLotLinesDocument, transactionLine, (Integer) index);
171            if (isValid) {
172                isValid &= validateAssetDecreaseTransactionLine(false, endowmentTaxLotLinesDocument, transactionLine, (Integer) index, (Integer) taxLotLineIndex);
173            }
174            return isValid;
175        }
176    
177        /**
178         * Validates the the amount and units in the transaction line match the total cost and units in the associated tax lot lines.
179         * 
180         * @param endowmentTransactionLinesDocumentBase
181         * @param line
182         * @return true if valid, false otherwise
183         */
184        protected boolean validateTotalAmountAndUnits(EndowmentTransactionLinesDocumentBase endowmentTransactionLinesDocumentBase, EndowmentTransactionLine transactionLine, int index) {
185            boolean isValid = true;
186    
187            BigDecimal lineUnits = null;
188            BigDecimal lineAmount = null;
189    
190            lineUnits = transactionLine.getTransactionUnits().bigDecimalValue();
191            lineAmount = transactionLine.getTransactionAmount().bigDecimalValue();
192    
193            if (EndowConstants.TransactionSubTypeCode.NON_CASH.equalsIgnoreCase(endowmentTransactionLinesDocumentBase.getTransactionSubTypeCode())) {
194    
195                List<EndowmentTransactionTaxLotLine> taxLots = transactionLine.getTaxLotLines();
196                BigDecimal totalAmount = BigDecimal.ZERO;
197                BigDecimal totalUnits = BigDecimal.ZERO;
198    
199                if (taxLots != null && taxLots.size() > 0) {
200                    for (EndowmentTransactionTaxLotLine taxLotLine : taxLots) {
201                        totalAmount = totalAmount.add(taxLotLine.getLotHoldingCost());
202                        totalUnits = totalUnits.add(taxLotLine.getLotUnits());
203                    }
204                }
205    
206                if (lineAmount.compareTo(totalAmount.negate()) != 0) {
207                    isValid = false;
208                    putFieldError(getErrorPrefix(transactionLine, index) + EndowPropertyConstants.TRANSACTION_LINE_TRANSACTION_AMOUNT, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_ASSET_DECREASE_TOTAL_AMOUNT_DOES_NOT_MATCH);
209                }
210                if (lineUnits.compareTo(totalUnits.negate()) != 0) {
211                    isValid = false;
212                    putFieldError(getErrorPrefix(transactionLine, index) + EndowPropertyConstants.TRANSACTION_LINE_TRANSACTION_UNITS, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_ASSET_DECREASE_TOTAL_UNITS_DO_NOT_MATCH);
213                }
214            }
215    
216            if (EndowConstants.TransactionSubTypeCode.CASH.equalsIgnoreCase(endowmentTransactionLinesDocumentBase.getTransactionSubTypeCode())) {
217    
218                List<EndowmentTransactionTaxLotLine> taxLots = transactionLine.getTaxLotLines();
219                BigDecimal totalAmount = BigDecimal.ZERO;
220                BigDecimal totalUnits = BigDecimal.ZERO;
221    
222                if (taxLots != null && taxLots.size() > 0) {
223                    for (EndowmentTransactionTaxLotLine taxLotLine : taxLots) {
224                        totalAmount = totalAmount.add(taxLotLine.getLotHoldingCost().negate());
225    
226                        if (taxLotLine.getLotLongTermGainLoss() != null) {
227                            totalAmount = totalAmount.add(taxLotLine.getLotLongTermGainLoss());
228                        }
229    
230                        if (taxLotLine.getLotShortTermGainLoss() != null) {
231                            totalAmount = totalAmount.add(taxLotLine.getLotShortTermGainLoss());
232                        }
233    
234                        totalUnits = totalUnits.add(taxLotLine.getLotUnits());
235                    }
236                }
237    
238                if (lineAmount.compareTo(totalAmount) != 0) {
239                    isValid = false;
240                    putFieldError(getErrorPrefix(transactionLine, index) + EndowPropertyConstants.TRANSACTION_LINE_TRANSACTION_AMOUNT, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_ASSET_DECREASE_TOTAL_AMOUNT_DOES_NOT_MATCH);
241                }
242                if (lineUnits.compareTo(totalUnits.negate()) != 0) {
243                    isValid = false;
244                    putFieldError(getErrorPrefix(transactionLine, index) + EndowPropertyConstants.TRANSACTION_LINE_TRANSACTION_UNITS, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_ASSET_DECREASE_TOTAL_UNITS_DO_NOT_MATCH);
245                }
246            }
247    
248            return isValid;
249        }
250    
251    }