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.fp.document.validation.impl;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.kfs.fp.businessobject.DisbursementVoucherPayeeDetail;
020    import org.kuali.kfs.fp.document.DisbursementVoucherConstants;
021    import org.kuali.kfs.fp.document.DisbursementVoucherDocument;
022    import org.kuali.kfs.fp.document.service.DisbursementVoucherPayeeService;
023    import org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService;
024    import org.kuali.kfs.sys.KFSKeyConstants;
025    import org.kuali.kfs.sys.KFSPropertyConstants;
026    import org.kuali.kfs.sys.context.SpringContext;
027    import org.kuali.kfs.sys.document.AccountingDocument;
028    import org.kuali.kfs.sys.document.validation.GenericValidation;
029    import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
030    import org.kuali.kfs.vnd.businessobject.VendorDetail;
031    import org.kuali.kfs.vnd.document.service.VendorService;
032    import org.kuali.rice.kns.service.ParameterEvaluator;
033    import org.kuali.rice.kns.service.ParameterService;
034    import org.kuali.rice.kns.util.GlobalVariables;
035    import org.kuali.rice.kns.util.KualiDecimal;
036    import org.kuali.rice.kns.util.MessageMap;
037    
038    public class DisbursementVoucherPaymentReasonValidation extends GenericValidation implements DisbursementVoucherConstants {
039        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherPaymentReasonValidation.class);
040    
041        private ParameterService parameterService;
042        private AccountingDocument accountingDocumentForValidation;
043        private DisbursementVoucherPaymentReasonService disbursementVoucherPaymentReasonService;
044        private DisbursementVoucherPayeeService disbursementVoucherPayeeService;
045    
046        public static final String DV_PAYMENT_REASON_PROPERTY_PATH = KFSPropertyConstants.DV_PAYEE_DETAIL + "." + KFSPropertyConstants.DISB_VCHR_PAYMENT_REASON_CODE;
047        public static final String DV_PAYEE_ID_NUMBER_PROPERTY_PATH = KFSPropertyConstants.DV_PAYEE_DETAIL + "." + KFSPropertyConstants.DISB_VCHR_PAYEE_ID_NUMBER;
048    
049        /**
050         * @see org.kuali.kfs.sys.document.validation.Validation#validate(org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent)
051         */
052        public boolean validate(AttributedDocumentEvent event) {
053            LOG.debug("validate start");
054            
055            boolean isValid = true;
056    
057            DisbursementVoucherDocument document = (DisbursementVoucherDocument) accountingDocumentForValidation;
058            DisbursementVoucherPayeeDetail dvPayeeDetail = document.getDvPayeeDetail();
059            String paymentReasonCode = dvPayeeDetail.getDisbVchrPaymentReasonCode();
060    
061            boolean isVendor = dvPayeeDetail.isVendor();
062            boolean isEmployee = dvPayeeDetail.isEmployee();
063    
064            MessageMap errors = GlobalVariables.getMessageMap();
065            int initialErrorCount = errors.getErrorCount();
066            errors.addToErrorPath(KFSPropertyConstants.DOCUMENT);
067    
068            /* check payment reason is allowed for payee type */
069            ParameterEvaluator paymentReasonsByTypeEvaluator = parameterService.getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.VALID_PAYEE_TYPES_BY_PAYMENT_REASON_PARM, DisbursementVoucherConstants.INVALID_PAYEE_TYPES_BY_PAYMENT_REASON_PARM, paymentReasonCode, dvPayeeDetail.getDisbursementVoucherPayeeTypeCode());
070            paymentReasonsByTypeEvaluator.evaluateAndAddError(document.getClass(), DV_PAYMENT_REASON_PROPERTY_PATH);
071    
072            // restrictions on payment reason when alien indicator is checked
073            if (dvPayeeDetail.isDisbVchrAlienPaymentCode()) {
074                ParameterEvaluator alienPaymentReasonsEvaluator = parameterService.getParameterEvaluator(DisbursementVoucherDocument.class, ALIEN_PAYMENT_REASONS_PARM_NM, paymentReasonCode);
075                alienPaymentReasonsEvaluator.evaluateAndAddError(document.getClass(), DV_PAYMENT_REASON_PROPERTY_PATH);
076            }
077    
078            /* for vendors with a payee type of revolving fund, the payment reason must be a revolving fund payment reason */
079            final boolean isRevolvingFundPaymentReason = disbursementVoucherPaymentReasonService.isRevolvingFundPaymentReason(paymentReasonCode);
080            if (isVendor) {
081                final boolean isRevolvingFundCodeVendor = SpringContext.getBean(VendorService.class).isRevolvingFundCodeVendor(dvPayeeDetail.getDisbVchrVendorHeaderIdNumberAsInteger());
082                if (isRevolvingFundCodeVendor) {
083                    ParameterEvaluator revolvingFundPaymentReasonCodeEvaluator = parameterService.getParameterEvaluator(DisbursementVoucherDocument.class, REVOLVING_FUND_PAYMENT_REASONS_PARM_NM, paymentReasonCode);
084                    revolvingFundPaymentReasonCodeEvaluator.evaluateAndAddError(document.getClass(), DV_PAYMENT_REASON_PROPERTY_PATH);
085                } else if (isRevolvingFundPaymentReason) {
086                    errors.putError(DV_PAYEE_ID_NUMBER_PROPERTY_PATH, KFSKeyConstants.ERROR_DV_REVOLVING_PAYMENT_REASON, paymentReasonCode);
087                    isValid = false;
088                }
089            }
090            if (!isVendor && isRevolvingFundPaymentReason) {
091                errors.putError(DV_PAYEE_ID_NUMBER_PROPERTY_PATH, KFSKeyConstants.ERROR_DV_REVOLVING_PAYMENT_REASON, paymentReasonCode);
092                isValid = false;
093            }
094    
095            // if payment reason is moving, payee must be an employee or have vendor ownership type I (individual)
096            boolean isMovingPaymentReason = disbursementVoucherPaymentReasonService.isMovingPaymentReason(paymentReasonCode);
097            if (isMovingPaymentReason) {
098                // only need to review this rule if the payee is a vendor; NOTE that a vendor can be an employee also
099                if (isVendor && !isEmployee) {
100                    boolean isPayeeIndividualVendor = disbursementVoucherPayeeService.isPayeeIndividualVendor(dvPayeeDetail);
101    
102                    // only vendors who are individuals can be paid moving expenses
103                    if (!isPayeeIndividualVendor) {
104                        errors.putError(DV_PAYEE_ID_NUMBER_PROPERTY_PATH, KFSKeyConstants.ERROR_DV_MOVING_PAYMENT_PAYEE);
105                        isValid = false;
106                    }
107                }
108            }
109    
110            // for research payments over a certain limit the payee must be a vendor
111            boolean isResearchPaymentReason = disbursementVoucherPaymentReasonService.isResearchPaymentReason(paymentReasonCode);
112            if (isResearchPaymentReason) {
113                String researchPayLimit = disbursementVoucherPaymentReasonService.getReserchNonVendorPayLimit();
114    
115                if (StringUtils.isNotBlank(researchPayLimit)) {
116                    KualiDecimal payLimit = new KualiDecimal(researchPayLimit);
117    
118                    if (!isVendor && document.getDisbVchrCheckTotalAmount().isGreaterEqual(payLimit)) {
119                        errors.putError(DV_PAYEE_ID_NUMBER_PROPERTY_PATH, KFSKeyConstants.ERROR_DV_RESEARCH_PAYMENT_PAYEE, researchPayLimit);
120                        isValid = false;
121                    }
122                }
123            }
124    
125            errors.removeFromErrorPath(KFSPropertyConstants.DOCUMENT);
126    
127            isValid = initialErrorCount == errors.getErrorCount();
128            return isValid;
129        }
130    
131        /**
132         * Retrieves the VendorDetail object from the vendor id number.
133         * 
134         * @param vendorIdNumber vendor ID number
135         * @param vendorDetailIdNumber vendor detail ID number
136         * @return <code>VendorDetail</code>
137         */
138        protected VendorDetail retrieveVendorDetail(Integer vendorIdNumber, Integer vendorDetailIdNumber) {
139            return SpringContext.getBean(VendorService.class).getVendorDetail(vendorIdNumber, vendorDetailIdNumber);
140        }
141    
142        /**
143         * Gets the parameterService attribute. 
144         * @return Returns the parameterService.
145         */
146        public ParameterService getParameterService() {
147            return parameterService;
148        }
149    
150        /**
151         * Gets the disbursementVoucherPaymentReasonService attribute. 
152         * @return Returns the disbursementVoucherPaymentReasonService.
153         */
154        public DisbursementVoucherPaymentReasonService getDisbursementVoucherPaymentReasonService() {
155            return disbursementVoucherPaymentReasonService;
156        }
157    
158        /**
159         * Gets the disbursementVoucherPayeeService attribute. 
160         * @return Returns the disbursementVoucherPayeeService.
161         */
162        public DisbursementVoucherPayeeService getDisbursementVoucherPayeeService() {
163            return disbursementVoucherPayeeService;
164        }
165    
166        /**
167         * Sets the accountingDocumentForValidation attribute value.
168         * 
169         * @param accountingDocumentForValidation The accountingDocumentForValidation to set.
170         */
171        public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
172            this.accountingDocumentForValidation = accountingDocumentForValidation;
173        }
174    
175        /**
176         * Sets the parameterService attribute value.
177         * 
178         * @param parameterService The parameterService to set.
179         */
180        public void setParameterService(ParameterService parameterService) {
181            this.parameterService = parameterService;
182        }
183    
184        /**
185         * Gets the accountingDocumentForValidation attribute.
186         * 
187         * @return Returns the accountingDocumentForValidation.
188         */
189        public AccountingDocument getAccountingDocumentForValidation() {
190            return accountingDocumentForValidation;
191        }
192    
193        /**
194         * Sets the disbursementVoucherPaymentReasonService attribute value.
195         * 
196         * @param disbursementVoucherPaymentReasonService The disbursementVoucherPaymentReasonService to set.
197         */
198        public void setDisbursementVoucherPaymentReasonService(DisbursementVoucherPaymentReasonService disbursementVoucherPaymentReasonService) {
199            this.disbursementVoucherPaymentReasonService = disbursementVoucherPaymentReasonService;
200        }
201    
202        /**
203         * Sets the disbursementVoucherPayeeService attribute value.
204         * 
205         * @param disbursementVoucherPayeeService The disbursementVoucherPayeeService to set.
206         */
207        public void setDisbursementVoucherPayeeService(DisbursementVoucherPayeeService disbursementVoucherPayeeService) {
208            this.disbursementVoucherPayeeService = disbursementVoucherPayeeService;
209        }
210    }