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.sys.KFSConstants;
023    import org.kuali.kfs.sys.KFSKeyConstants;
024    import org.kuali.kfs.sys.KFSPropertyConstants;
025    import org.kuali.kfs.sys.context.SpringContext;
026    import org.kuali.kfs.sys.document.AccountingDocument;
027    import org.kuali.kfs.sys.document.validation.GenericValidation;
028    import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
029    import org.kuali.kfs.vnd.businessobject.VendorDetail;
030    import org.kuali.kfs.vnd.document.service.VendorService;
031    import org.kuali.rice.kim.bo.Person;
032    import org.kuali.rice.kim.bo.entity.dto.KimEntityInfo;
033    import org.kuali.rice.kim.bo.entity.dto.KimEntityNameInfo;
034    import org.kuali.rice.kim.service.IdentityManagementService;
035    import org.kuali.rice.kim.service.PersonService;
036    import org.kuali.rice.kim.util.KimConstants.PersonExternalIdentifierTypes;
037    import org.kuali.rice.kns.service.DataDictionaryService;
038    import org.kuali.rice.kns.service.ParameterEvaluator;
039    import org.kuali.rice.kns.service.ParameterService;
040    import org.kuali.rice.kns.util.GlobalVariables;
041    import org.kuali.rice.kns.util.MessageMap;
042    
043    public class DisbursementVoucherVendorInformationValidation extends GenericValidation implements DisbursementVoucherConstants {
044        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherPaymentReasonValidation.class);
045    
046        private ParameterService parameterService;
047        private AccountingDocument accountingDocumentForValidation;
048    
049        public static final String DV_PAYEE_ID_NUMBER_PROPERTY_PATH = KFSPropertyConstants.DV_PAYEE_DETAIL + "." + KFSPropertyConstants.DISB_VCHR_PAYEE_ID_NUMBER;
050    
051        /**
052         * @see org.kuali.kfs.sys.document.validation.Validation#validate(org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent)
053         */
054        public boolean validate(AttributedDocumentEvent event) {
055            LOG.debug("validate start");
056            boolean isValid = true;
057          
058            DisbursementVoucherDocument document = (DisbursementVoucherDocument) accountingDocumentForValidation;
059            DisbursementVoucherPayeeDetail payeeDetail = document.getDvPayeeDetail();
060    
061            if (!payeeDetail.isVendor()) {
062                
063                String initiator = document.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
064                final KimEntityInfo entityInfo= SpringContext.getBean(IdentityManagementService.class).getEntityInfoByPrincipalId(initiator);
065                String originatorId = entityInfo.getEmploymentInformation().get(0).getEmployeeId();
066                String employeeId = payeeDetail.getDisbVchrEmployeeIdNumber();
067                // verify that originator does not equal payee
068                if (originatorId.equals(employeeId)) {
069                    isValid = false;
070                    MessageMap errors = GlobalVariables.getMessageMap();
071                    errors.addToErrorPath(KFSPropertyConstants.DOCUMENT);
072                    String[] errorName = { "Payee ID " + employeeId ," Originator has the same ID ", "name" };
073                    errors.putError(DV_PAYEE_ID_NUMBER_PROPERTY_PATH, KFSKeyConstants.ERROR_DV_VENDOR_NAME_PERSON_NAME_CONFUSION, errorName);
074                }
075                return isValid;
076            }
077    
078            if (StringUtils.isBlank(payeeDetail.getDisbVchrPayeeIdNumber())) {
079                return false;
080            }
081    
082            VendorDetail vendor = retrieveVendorDetail(payeeDetail.getDisbVchrVendorHeaderIdNumberAsInteger(), payeeDetail.getDisbVchrVendorDetailAssignedIdNumberAsInteger());
083    
084            MessageMap errors = GlobalVariables.getMessageMap();
085            errors.addToErrorPath(KFSPropertyConstants.DOCUMENT);
086    
087            /* Retrieve Vendor */
088            if (vendor == null) {
089                errors.putError(DV_PAYEE_ID_NUMBER_PROPERTY_PATH, KFSKeyConstants.ERROR_EXISTENCE, SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(DisbursementVoucherPayeeDetail.class, KFSPropertyConstants.DISB_VCHR_PAYEE_ID_NUMBER));
090                errors.removeFromErrorPath(KFSPropertyConstants.DOCUMENT);
091                return false;
092            }
093    
094            /* DV Vendor Detail must be active */
095            if (!vendor.isActiveIndicator()) {
096                errors.putError(DV_PAYEE_ID_NUMBER_PROPERTY_PATH, KFSKeyConstants.ERROR_INACTIVE, SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(DisbursementVoucherPayeeDetail.class, KFSPropertyConstants.DISB_VCHR_PAYEE_ID_NUMBER));
097                errors.removeFromErrorPath(KFSPropertyConstants.DOCUMENT);
098                return false;
099            }
100    
101            /* for vendors with tax type ssn, check employee restrictions */
102            if (TAX_TYPE_SSN.equals(vendor.getVendorHeader().getVendorTaxTypeCode())) {
103                if (isActiveEmployeeSSN(vendor.getVendorHeader().getVendorTaxNumber())) {
104                    // determine if the rule is flagged off in the param setting
105                    boolean performPrepaidEmployeeInd = parameterService.getIndicatorParameter(DisbursementVoucherDocument.class, PERFORM_PREPAID_EMPL_PARM_NM);
106    
107                    if (performPrepaidEmployeeInd) {
108                        /* active vendor employees cannot be paid for prepaid travel */
109                        ParameterEvaluator travelPrepaidPaymentReasonCodeEvaluator = parameterService.getParameterEvaluator(DisbursementVoucherDocument.class, PREPAID_TRAVEL_PAYMENT_REASONS_PARM_NM, payeeDetail.getDisbVchrPaymentReasonCode());
110                        if (travelPrepaidPaymentReasonCodeEvaluator.evaluationSucceeds()) {
111                            errors.putError(DV_PAYEE_ID_NUMBER_PROPERTY_PATH, KFSKeyConstants.ERROR_DV_ACTIVE_EMPLOYEE_PREPAID_TRAVEL);
112                            isValid = false;
113                        }
114    
115                    }
116                }
117               
118                else if (isEmployeeSSN(vendor.getVendorHeader().getVendorTaxNumber())) {
119                    // check param setting for paid outside payroll check
120                    boolean performPaidOutsidePayrollInd = parameterService.getIndicatorParameter(DisbursementVoucherDocument.class, DisbursementVoucherConstants.CHECK_EMPLOYEE_PAID_OUTSIDE_PAYROLL_PARM_NM);
121    
122                    if (performPaidOutsidePayrollInd) {
123                        /* If vendor is type employee, vendor record must be flagged as paid outside of payroll */
124                        if (!SpringContext.getBean(VendorService.class).isVendorInstitutionEmployee(vendor.getVendorHeaderGeneratedIdentifier())) {
125                            errors.putError(DV_PAYEE_ID_NUMBER_PROPERTY_PATH, KFSKeyConstants.ERROR_DV_EMPLOYEE_PAID_OUTSIDE_PAYROLL);
126                            isValid = false;
127                        }
128                    }
129                }
130            }
131            
132            errors.removeFromErrorPath(KFSPropertyConstants.DOCUMENT);
133            
134            return isValid;
135        }
136    
137        /**
138         * Retrieves the VendorDetail object from the vendor id number.
139         * 
140         * @param vendorIdNumber vendor ID number
141         * @param vendorDetailIdNumber vendor detail ID number
142         * @return <code>VendorDetail</code>
143         */
144        protected VendorDetail retrieveVendorDetail(Integer vendorIdNumber, Integer vendorDetailIdNumber) {
145            return SpringContext.getBean(VendorService.class).getVendorDetail(vendorIdNumber, vendorDetailIdNumber);
146        }
147    
148        /**
149         * Retrieves Person from SSN
150         * 
151         * @param ssnNumber social security number
152         * @return <code>Person</code>
153         */
154        protected Person retrieveEmployeeBySSN(String ssnNumber) {
155            Person person = (Person) SpringContext.getBean(PersonService.class).getPersonByExternalIdentifier(PersonExternalIdentifierTypes.TAX, ssnNumber).get(0);
156            if (person == null) {
157                LOG.error("User Not Found");
158            }
159            return person;
160        }
161    
162        /**
163         * Confirms that the SSN provided is associated with an employee.
164         * 
165         * @param ssnNumber social security number
166         * @return true if the ssn number is a valid employee ssn
167         */
168        protected boolean isEmployeeSSN(String ssnNumber) {
169            return retrieveEmployeeBySSN(ssnNumber) != null;
170        }
171    
172        /**
173         * Performs a lookup on universal users for the given ssn number.
174         * 
175         * @param ssnNumber social security number
176         * @return true if the ssn number is a valid employee ssn and the employee is active
177         */
178        protected boolean isActiveEmployeeSSN(String ssnNumber) {
179            Person employee = retrieveEmployeeBySSN(ssnNumber);
180            return employee != null && KFSConstants.EMPLOYEE_ACTIVE_STATUS.equals(employee.getEmployeeStatusCode());
181        }
182    
183        /**
184         * Sets the accountingDocumentForValidation attribute value.
185         * 
186         * @param accountingDocumentForValidation The accountingDocumentForValidation to set.
187         */
188        public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
189            this.accountingDocumentForValidation = accountingDocumentForValidation;
190        }
191    
192        /**
193         * Sets the parameterService attribute value.
194         * @param parameterService The parameterService to set.
195         */
196        public void setParameterService(ParameterService parameterService) {
197            this.parameterService = parameterService;
198        }
199    
200        /**
201         * Gets the accountingDocumentForValidation attribute. 
202         * @return Returns the accountingDocumentForValidation.
203         */
204        public AccountingDocument getAccountingDocumentForValidation() {
205            return accountingDocumentForValidation;
206        }
207    }
208