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.util.ArrayList;
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.businessobject.HoldingTaxLot;
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.EndowmentUnitShareAdjustmentDocument;
034    import org.kuali.kfs.module.endow.document.service.HoldingTaxLotService;
035    import org.kuali.kfs.module.endow.document.validation.DeleteTaxLotLineRule;
036    import org.kuali.kfs.sys.context.SpringContext;
037    import org.kuali.rice.kns.document.Document;
038    
039    public class EndowmentUnitShareAdjustmentDocumentRules extends EndowmentTransactionLinesDocumentBaseRules implements DeleteTaxLotLineRule<EndowmentTaxLotLinesDocument, EndowmentTransactionTaxLotLine, EndowmentTransactionLine, Number, Number> {
040    
041        /**
042         * @see org.kuali.kfs.module.endow.document.validation.impl.EndowmentTransactionLinesDocumentBaseRules#processAddTransactionLineRules(org.kuali.kfs.module.endow.document.EndowmentTransactionLinesDocument,
043         *      org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine)
044         */
045        @Override
046        public boolean processAddTransactionLineRules(EndowmentTransactionLinesDocument document, EndowmentTransactionLine line) {
047            boolean isValid = true;
048    
049            EndowmentUnitShareAdjustmentDocument endowmentUnitShareAdjustmentDocument = (EndowmentUnitShareAdjustmentDocument) document;
050    
051            isValid &= validateSecurity(isValid, endowmentUnitShareAdjustmentDocument, true);
052            isValid &= validateSecurityClassCodeTypeNotLiability(endowmentUnitShareAdjustmentDocument, true);
053    
054            isValid &= validateRegistration(isValid, endowmentUnitShareAdjustmentDocument, true);
055    
056            isValid &= canOnlyAddSourceOrTargetTransactionLines(endowmentUnitShareAdjustmentDocument, line, -1);
057    
058            if (isValid) {
059                isValid &= super.processAddTransactionLineRules(endowmentUnitShareAdjustmentDocument, line);
060    
061                if (isValid) {
062                    isValid &= validateKemidHasTaxLots(endowmentUnitShareAdjustmentDocument, line, -1);
063                }
064            }
065    
066            return isValid;
067    
068        }
069    
070    
071        /**
072         * @see org.kuali.kfs.module.endow.document.validation.impl.EndowmentTransactionLinesDocumentBaseRules#validateTransactionLine(org.kuali.kfs.module.endow.document.EndowmentTransactionLinesDocument,
073         *      org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine, int)
074         */
075        @Override
076        protected boolean validateTransactionLine(EndowmentTransactionLinesDocument endowmentTransactionLinesDocument, EndowmentTransactionLine line, int index) {
077    
078            boolean isValid = super.validateTransactionLine(endowmentTransactionLinesDocument, line, index);
079    
080            if (isValid) {
081                isValid &= validateTransactionUnitsGreaterThanZero(line, getErrorPrefix(line, index));
082            }
083            return isValid;
084        }
085    
086    
087        /**
088         * @see org.kuali.rice.kns.rules.DocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.Document)
089         */
090        @Override
091        protected boolean processCustomRouteDocumentBusinessRules(Document document) {
092            boolean isValid = true;
093            EndowmentUnitShareAdjustmentDocument endowmentUnitShareAdjustmentDocument = (EndowmentUnitShareAdjustmentDocument) document;
094    
095            isValid &= validateSecurity(isValid, endowmentUnitShareAdjustmentDocument, true);
096            isValid &= validateSecurityClassCodeTypeNotLiability(endowmentUnitShareAdjustmentDocument, true);
097    
098            isValid &= validateRegistration(isValid, endowmentUnitShareAdjustmentDocument, true);
099    
100            // the document must have at least one transaction line
101            isValid &= hasAtLeastOneTransactionLine(endowmentUnitShareAdjustmentDocument);
102    
103            if (isValid) {
104                isValid &= hasOnlySourceOrTargetTransactionLines(endowmentUnitShareAdjustmentDocument);
105                isValid &= super.processCustomRouteDocumentBusinessRules(document);
106    
107                List<EndowmentTransactionLine> transLines = (endowmentUnitShareAdjustmentDocument.getSourceTransactionLines() != null && endowmentUnitShareAdjustmentDocument.getSourceTransactionLines().size() > 0) ? endowmentUnitShareAdjustmentDocument.getSourceTransactionLines() : endowmentUnitShareAdjustmentDocument.getTargetTransactionLines();
108    
109                for (int i = 0; i < transLines.size(); i++) {
110                    EndowmentTransactionLine transLine = transLines.get(i);
111                    isValid &= validateTransactionLineHasTaxLots(transLine, i);
112    
113                    if (isValid) {
114                        isValid &= validateTaxLots(endowmentUnitShareAdjustmentDocument, transLine, i);
115                        isValid &= validateTotalUnits(endowmentUnitShareAdjustmentDocument, transLine, i);
116                    }
117                    if (!isValid) {
118                        return false;
119                    }
120                }
121    
122            }
123    
124            return isValid;
125        }
126    
127        /**
128         * Validates that the document has at least one transaction line.
129         * 
130         * @param document
131         * @return true if valid, false otherwise
132         */
133        protected boolean hasAtLeastOneTransactionLine(EndowmentTransactionLinesDocumentBase document) {
134    
135            List<EndowmentTransactionLine> transactionLineList = new ArrayList<EndowmentTransactionLine>();
136            transactionLineList.addAll(document.getSourceTransactionLines());
137            transactionLineList.addAll(document.getTargetTransactionLines());
138    
139            if (transactionLineList.size() == 0) {
140                putFieldError(EndowConstants.TRANSACTION_LINE_ERRORS, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_UNIT_SHARE_ADJUSTMENT_MUST_HAVE_AT_LEAST_ONE_TRANS_LINE);
141                return false;
142            }
143    
144    
145            return true;
146        }
147    
148        /**
149         * @see org.kuali.kfs.module.endow.document.validation.impl.EndowmentTransactionalDocumentBaseRule#validateSecurityClassTypeCode(org.kuali.kfs.module.endow.document.EndowmentSecurityDetailsDocument,
150         *      boolean, java.lang.String)
151         */
152        @Override
153        protected boolean validateSecurityClassTypeCode(EndowmentSecurityDetailsDocument document, boolean isSource, String classCodeType) {
154    
155            return true;
156        }
157    
158        /**
159         * @see org.kuali.kfs.module.endow.document.validation.impl.EndowmentTransactionLinesDocumentBaseRules#hasEtranCode(org.kuali.kfs.module.endow.document.EndowmentTransactionLinesDocument)
160         */
161        @Override
162        protected boolean hasEtranCode(EndowmentTransactionLinesDocument endowmentTransactionLinesDocument) {
163            return false;
164        }
165    
166        /**
167         * Validates that the document has only source or target transaction lines, not both.
168         * 
169         * @param endowmentTransactionLinesDocument
170         * @return true if valid, false otherwise
171         */
172        protected boolean hasOnlySourceOrTargetTransactionLines(EndowmentTransactionLinesDocument endowmentTransactionLinesDocument) {
173            boolean isValid = true;
174    
175            boolean hasSourceTransLines = endowmentTransactionLinesDocument.getSourceTransactionLines() != null && endowmentTransactionLinesDocument.getSourceTransactionLines().size() > 0;
176            boolean hasTargetTransLines = endowmentTransactionLinesDocument.getTargetTransactionLines() != null && endowmentTransactionLinesDocument.getTargetTransactionLines().size() > 0;
177    
178            if (hasSourceTransLines && hasTargetTransLines) {
179                isValid = false;
180                putFieldError(EndowConstants.TRANSACTION_LINE_ERRORS, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_UNIT_SHARE_ADJUSTMENT_ADD_ONLY_SOURCE_OR_TARGET_TRAN_LINES);
181            }
182            return isValid;
183        }
184    
185        /**
186         * Validates that the user can only enter to or from transaction lines not both.
187         * 
188         * @param endowmentTransactionLinesDocument
189         * @param transLine
190         * @param index
191         * @return true if valid, false otherwise
192         */
193        private boolean canOnlyAddSourceOrTargetTransactionLines(EndowmentTransactionLinesDocument endowmentTransactionLinesDocument, EndowmentTransactionLine transLine, int index) {
194            boolean isValid = true;
195    
196            boolean isSource = transLine instanceof EndowmentSourceTransactionLine;
197    
198            // the user can only enter to or from transaction lines not both
199            if (isSource) {
200                if (endowmentTransactionLinesDocument.getTargetTransactionLines() != null && endowmentTransactionLinesDocument.getTargetTransactionLines().size() > 0) {
201    
202                    isValid = false;
203                    putFieldError(getErrorPrefix(transLine, index), EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_UNIT_SHARE_ADJUSTMENT_ADD_ONLY_SOURCE_OR_TARGET_TRAN_LINES);
204                }
205            }
206            else {
207                if (endowmentTransactionLinesDocument.getSourceTransactionLines() != null && endowmentTransactionLinesDocument.getSourceTransactionLines().size() > 0) {
208    
209                    isValid = false;
210                    putFieldError(getErrorPrefix(transLine, index), EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_UNIT_SHARE_ADJUSTMENT_ADD_ONLY_SOURCE_OR_TARGET_TRAN_LINES);
211                }
212            }
213    
214            return isValid;
215        }
216    
217        /**
218         * Checks that there are holding tax lots with positive units for the given kemid, security, registration code and IP indicator.
219         * 
220         * @param endowmentTransactionLinesDocument
221         * @param transLine
222         * @param index
223         * @return true if there are tax lots that meet the criteria, false otherwise
224         */
225        protected boolean validateKemidHasTaxLots(EndowmentTransactionLinesDocument endowmentTransactionLinesDocument, EndowmentTransactionLine transLine, int index) {
226            boolean isValid = true;
227            HoldingTaxLotService holdingTaxLotService = SpringContext.getBean(HoldingTaxLotService.class);
228            EndowmentUnitShareAdjustmentDocument unitShareAdjustmentDocument = (EndowmentUnitShareAdjustmentDocument) endowmentTransactionLinesDocument;
229            EndowmentTransactionSecurity endowmentTransactionSecurity = unitShareAdjustmentDocument.getSourceTransactionSecurity();
230    
231            List<HoldingTaxLot> holdingTaxLots = holdingTaxLotService.getAllTaxLotsWithPositiveUnits(transLine.getKemid(), endowmentTransactionSecurity.getSecurityID(), endowmentTransactionSecurity.getRegistrationCode(), transLine.getTransactionIPIndicatorCode());
232    
233            if (holdingTaxLots == null || holdingTaxLots.size() == 0) {
234                isValid = false;
235                putFieldError(getErrorPrefix(transLine, index) + EndowPropertyConstants.KEMID, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_UNIT_SHARE_ADJUSTMENT_NO_TAX_LOTS_FOUND);
236            }
237    
238            return isValid;
239        }
240    
241        /**
242         * @see org.kuali.kfs.module.endow.document.validation.DeleteTaxLotLineRule#processDeleteTaxLotLineRules(org.kuali.kfs.module.endow.document.EndowmentTaxLotLinesDocument,
243         *      org.kuali.kfs.module.endow.businessobject.EndowmentTransactionTaxLotLine,
244         *      org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine, java.lang.Number, java.lang.Number)
245         */
246        public boolean processDeleteTaxLotLineRules(EndowmentTaxLotLinesDocument endowmentTaxLotLinesDocument, EndowmentTransactionTaxLotLine endowmentTransactionTaxLotLine, EndowmentTransactionLine endowmentTransactionLine, Number transLineIndex, Number taxLotLineIndex) {
247            boolean isValid = true;
248    
249            if (endowmentTransactionLine.getTaxLotLines() != null && endowmentTransactionLine.getTaxLotLines().size() <= 1) {
250                isValid = false;
251                putFieldError(getErrorPrefix(endowmentTransactionLine, (Integer) transLineIndex) + EndowPropertyConstants.KEMID, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_UNIT_SHARE_ADJUSTMENT_TRANS_LINE_MUST_HAVE_AT_LEAST_ONE_TAX_LOT);
252            }
253    
254            return isValid;
255        }
256    
257        /**
258         * Validates that the transaction lines has at least one tax lot line associated.
259         * 
260         * @param endowmentTransactionLine
261         * @param transLineIndex
262         * @return true is valid, false otherwise
263         */
264        private boolean validateTransactionLineHasTaxLots(EndowmentTransactionLine endowmentTransactionLine, int transLineIndex) {
265            boolean isValid = true;
266    
267            if (endowmentTransactionLine.getTaxLotLines() != null && endowmentTransactionLine.getTaxLotLines().size() < 1) {
268                isValid = false;
269                putFieldError(getErrorPrefix(endowmentTransactionLine, transLineIndex) + EndowPropertyConstants.KEMID, EndowKeyConstants.EndowmentTransactionDocumentConstants.ERROR_UNIT_SHARE_ADJUSTMENT_TRANS_LINE_MUST_HAVE_AT_LEAST_ONE_TAX_LOT);
270            }
271    
272            return isValid;
273        }
274    }