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.service.impl;
017    
018    import java.util.ArrayList;
019    import java.util.HashMap;
020    import java.util.List;
021    import java.util.Map;
022    
023    import org.apache.commons.lang.StringUtils;
024    import org.kuali.kfs.fp.businessobject.DisbursementPayee;
025    import org.kuali.kfs.fp.businessobject.PaymentReasonCode;
026    import org.kuali.kfs.fp.document.DisbursementVoucherConstants;
027    import org.kuali.kfs.fp.document.DisbursementVoucherDocument;
028    import org.kuali.kfs.fp.document.service.DisbursementVoucherPayeeService;
029    import org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService;
030    import org.kuali.kfs.sys.KFSConstants;
031    import org.kuali.kfs.sys.KFSKeyConstants;
032    import org.kuali.kfs.sys.KFSPropertyConstants;
033    import org.kuali.kfs.sys.context.SpringContext;
034    import org.kuali.kfs.vnd.businessobject.VendorDetail;
035    import org.kuali.kfs.vnd.document.service.VendorService;
036    import org.kuali.rice.kns.service.BusinessObjectService;
037    import org.kuali.rice.kns.service.ParameterService;
038    import org.kuali.rice.kns.util.ErrorMap;
039    import org.kuali.rice.kns.util.MessageList;
040    
041    /**
042     * implementing the service methods defined in DisbursementVoucherPaymentReasonService
043     * 
044     * @see DisbursementVoucherPaymentReasonService
045     */
046    public class DisbursementVoucherPaymentReasonServiceImpl implements DisbursementVoucherPaymentReasonService {
047        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherPaymentReasonServiceImpl.class);
048    
049        public ParameterService parameterService;
050        private BusinessObjectService businessObjectService;
051        private DisbursementVoucherPayeeService disbursementVoucherPayeeService;
052    
053        /**
054         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isPayeeQualifiedForPayment(org.kuali.kfs.fp.businessobject.DisbursementPayee,
055         *      java.lang.String)
056         */
057        public boolean isPayeeQualifiedForPayment(DisbursementPayee payee, String paymentReasonCode) {
058            List<String> payeeTypeCodes = this.getPayeeTypesByPaymentReason(paymentReasonCode);
059            return this.isPayeeQualifiedForPayment(payee, paymentReasonCode, payeeTypeCodes);
060        }
061    
062        /**
063         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isPayeeQualifiedForPayment(org.kuali.kfs.fp.businessobject.DisbursementPayee,
064         *      java.lang.String, java.util.List)
065         */
066        public boolean isPayeeQualifiedForPayment(DisbursementPayee payee, String paymentReasonCode, List<String> payeeTypeCodes) {
067            if (payeeTypeCodes == null || payeeTypeCodes.isEmpty()) {
068                return false;
069            }
070    
071            String payeeTypeCode = payee.getPayeeTypeCode();
072            if (!payeeTypeCodes.contains(payeeTypeCode)) {
073                return false;
074            }
075            
076            if (disbursementVoucherPayeeService.isVendor(payee)) {
077                List<String> vendorOwnershipTypeCodes = this.getVendorOwnershipTypesByPaymentReason(paymentReasonCode);
078                
079                if (vendorOwnershipTypeCodes != null && !vendorOwnershipTypeCodes.isEmpty()) {                
080                    String vendorOwnershipTypeCodeOfPayee = disbursementVoucherPayeeService.getVendorOwnershipTypeCode(payee);
081                    return vendorOwnershipTypeCodes.contains(vendorOwnershipTypeCodeOfPayee);
082                } 
083            }
084    
085            if (this.isPrepaidTravelPaymentReason(paymentReasonCode)) {
086                boolean isActiveVendorEmployee = payee.isActive();
087                isActiveVendorEmployee &= disbursementVoucherPayeeService.isVendor(payee);
088                isActiveVendorEmployee &= disbursementVoucherPayeeService.isEmployee(payee);
089    
090                // Active vendor employees cannot be paid for prepaid travel
091                return !isActiveVendorEmployee;
092            }
093    
094            return true;
095        }
096    
097        /**
098         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isMovingPaymentReason(java.lang.String)
099         */
100        public boolean isMovingPaymentReason(String paymentReasonCode) {
101            String typeParameterName = DisbursementVoucherConstants.MOVING_PAYMENT_REASONS_PARM_NM;
102            return this.isPaymentReasonOfType(typeParameterName, paymentReasonCode);
103        }
104    
105        /**
106         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isPrepaidTravelPaymentReason(java.lang.String)
107         */
108        public boolean isPrepaidTravelPaymentReason(String paymentReasonCode) {
109            String typeParameterName = DisbursementVoucherConstants.PREPAID_TRAVEL_PAYMENT_REASONS_PARM_NM;
110            return this.isPaymentReasonOfType(typeParameterName, paymentReasonCode);
111        }
112        
113        /**
114         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isNonEmployeeTravelPaymentReason(java.lang.String)
115         */
116        public boolean isNonEmployeeTravelPaymentReason(String paymentReasonCode) {
117            String typeParameterName = DisbursementVoucherConstants.NONEMPLOYEE_TRAVEL_PAY_REASONS_PARM_NM;
118            return this.isPaymentReasonOfType(typeParameterName, paymentReasonCode);
119        }
120    
121        /**
122         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isResearchPaymentReason(java.lang.String)
123         */
124        public boolean isResearchPaymentReason(String paymentReasonCode) {
125            String typeParameterName = DisbursementVoucherConstants.RESEARCH_PAYMENT_REASONS_PARM_NM;
126            return this.isPaymentReasonOfType(typeParameterName, paymentReasonCode);
127        }
128    
129        /**
130         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isRevolvingFundPaymentReason(java.lang.String)
131         */
132        public boolean isRevolvingFundPaymentReason(String paymentReasonCode) {
133            String typeParameterName = DisbursementVoucherConstants.REVOLVING_FUND_PAYMENT_REASONS_PARM_NM;
134            return this.isPaymentReasonOfType(typeParameterName, paymentReasonCode);
135        }
136        
137        /**
138         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isDecedentCompensationPaymentReason(java.lang.String)
139         */
140        public boolean isDecedentCompensationPaymentReason(String paymentReasonCode) {
141            String typeParameterName = DisbursementVoucherConstants.DECEDENT_COMPENSATION_PAYMENT_REASONS_PARM_NM;
142            return this.isPaymentReasonOfType(typeParameterName, paymentReasonCode);
143        }    
144    
145        /**
146         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isPaymentReasonOfType(java.lang.String,
147         *      java.lang.String)
148         */
149        public boolean isPaymentReasonOfType(String typeParameterName, String paymentReasonCode) {
150            return parameterService.getParameterEvaluator(DisbursementVoucherDocument.class, typeParameterName, paymentReasonCode).evaluationSucceeds();
151        }
152    
153        /**
154         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#getReserchNonVendorPayLimit()
155         */
156        public String getReserchNonVendorPayLimit() {
157            return parameterService.getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.RESEARCH_NON_VENDOR_PAY_LIMIT_AMOUNT_PARM_NM);
158        }
159    
160        /**
161         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#getPayeeTypesByPaymentReason(java.lang.String)
162         */
163        public List<String> getPayeeTypesByPaymentReason(String paymentReasonCode) {
164            return parameterService.getParameterValues(DisbursementVoucherDocument.class, DisbursementVoucherConstants.VALID_PAYEE_TYPES_BY_PAYMENT_REASON_PARM, paymentReasonCode);
165        }
166        
167        /**
168         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#getVendorOwnershipTypesByPaymentReason(java.lang.String)
169         */
170        public List<String> getVendorOwnershipTypesByPaymentReason(String paymentReasonCode) {
171            return parameterService.getParameterValues(DisbursementVoucherDocument.class, DisbursementVoucherConstants.VALID_VENDOR_OWNERSHIP_TYPES_BY_PAYMENT_REASON, paymentReasonCode);
172        }
173    
174        /**
175         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#getPaymentReasonByPrimaryId(java.lang.String)
176         */
177        public PaymentReasonCode getPaymentReasonByPrimaryId(String paymentReasonCode) {
178            Map<String, Object> primaryKeys = new HashMap<String, Object>();
179            primaryKeys.put(KFSPropertyConstants.CODE, paymentReasonCode);
180    
181            return (PaymentReasonCode) businessObjectService.findByPrimaryKey(PaymentReasonCode.class, primaryKeys);
182        }
183        
184        /**
185         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#isTaxReviewRequired(java.lang.String)
186         */
187        public boolean isTaxReviewRequired(String paymentReasonCode) {
188            String parameterName = DisbursementVoucherConstants.PAYMENT_REASONS_REQUIRING_TAX_REVIEW_PARM_NM;
189            List<String> values = parameterService.getParameterValues(DisbursementVoucherDocument.class, parameterName);
190            
191            return values != null && values.contains(paymentReasonCode);
192        }
193    
194        /**
195         * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentReasonService#postPaymentReasonCodeUsage(java.lang.String,
196         *      org.kuali.rice.kns.util.MessageList)
197         */
198        public void postPaymentReasonCodeUsage(String paymentReasonCode, MessageList messageList) {
199            List<String> payeeTypeCodes = this.getPayeeTypesByPaymentReason(paymentReasonCode);
200            if (payeeTypeCodes == null || payeeTypeCodes.isEmpty()) {
201                return;
202            }
203    
204            String descriptivePayeeTypes = this.getDescriptivePayeeTypesAsString(payeeTypeCodes);
205            String descriptivePaymentReason = this.getPaymentReasonByPrimaryId(paymentReasonCode).getCodeAndDescription();
206            if (payeeTypeCodes.size() > 1) {
207                String messageKey = KFSKeyConstants.WARNING_DV_PAYMENT_REASON_VALID_FOR_MULTIPLE_PAYEE_TYPES;
208                messageList.add(messageKey, descriptivePaymentReason, descriptivePayeeTypes);
209            }
210            else if (payeeTypeCodes.size() == 1) {
211                String messageKey = KFSKeyConstants.WARNING_DV_PAYMENT_REASON_VALID_FOR_SINGEL_PAYEE_TYPE;
212                messageList.add(messageKey, descriptivePaymentReason, descriptivePayeeTypes);
213            }
214    
215            if (this.isResearchPaymentReason(paymentReasonCode)) {
216                String payLimit = this.getReserchNonVendorPayLimit();
217                String messageKey = KFSKeyConstants.WARNING_DV_REASERCH_PAYMENT_REASON;
218    
219                List<String> vendorTypeCodes = new ArrayList<String>();
220                vendorTypeCodes.addAll(payeeTypeCodes);
221                vendorTypeCodes.remove(DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE);
222                String vendorTypes = this.getDescriptivePayeeTypesAsString(vendorTypeCodes);
223    
224                messageList.add(messageKey, descriptivePaymentReason, descriptivePayeeTypes, vendorTypes, payLimit);
225            }
226    
227            if (this.isMovingPaymentReason(paymentReasonCode)) {
228                List<String> individualOwnerShipTypeCodes = parameterService.getParameterValues(DisbursementVoucherDocument.class, DisbursementVoucherConstants.INDIVIDUAL_OWNERSHIP_TYPES_PARM_NM);
229                String ownerShipTypeAsString = this.convertListToString(individualOwnerShipTypeCodes);
230    
231                String messageKey = KFSKeyConstants.WARNING_DV_MOVING_PAYMENT_REASON;
232                messageList.add(messageKey, ownerShipTypeAsString);
233            }
234    
235            if (this.isPrepaidTravelPaymentReason(paymentReasonCode)) {
236                String messageKey = KFSKeyConstants.WARNING_DV_PREPAID_TRAVEL_PAYMENT_REASON;
237                messageList.add(messageKey, descriptivePaymentReason, descriptivePayeeTypes);
238            }
239        }
240    
241        // get and concatenate the descriptive payee types of the given codes
242        protected String getDescriptivePayeeTypesAsString(List<String> payeeTypeCodes) {
243            List<String> payeeTypeDescriptions = new ArrayList<String>();
244    
245            for (String payeeTypeCode : payeeTypeCodes) {
246                String description = SpringContext.getBean(DisbursementVoucherPayeeService.class).getPayeeTypeDescription(payeeTypeCode);
247                payeeTypeDescriptions.add(description);
248            }
249    
250            return this.convertListToString(payeeTypeDescriptions);
251        }
252    
253        protected String convertListToString(List<String> list) {
254            if (list == null || list.isEmpty()) {
255                return StringUtils.EMPTY;
256            }
257    
258            String oneSpace = " ";
259            StringBuilder listAsString = new StringBuilder();
260            for (int index = 0; index < list.size(); index++) {
261                String emlement = list.get(index);
262    
263                if (index == 0) {
264                    listAsString.append(emlement);
265                }
266                else if (index < list.size() - 1) {
267                    listAsString.append(KFSConstants.COMMA).append(oneSpace).append(emlement);
268                }
269                else if (index == list.size() - 1) {
270                    listAsString.append(oneSpace).append(KFSConstants.AND).append(oneSpace).append(emlement);
271                }
272            }
273    
274            return listAsString.toString();
275        }
276    
277        /**
278         * Sets the parameterService attribute value.
279         * 
280         * @param parameterService The parameterService to set.
281         */
282        public void setParameterService(ParameterService parameterService) {
283            this.parameterService = parameterService;
284        }
285    
286        /**
287         * Sets the businessObjectService attribute value.
288         * 
289         * @param businessObjectService The businessObjectService to set.
290         */
291        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
292            this.businessObjectService = businessObjectService;
293        }
294    
295        /**
296         * Sets the disbursementVoucherPayeeService attribute value.
297         * 
298         * @param disbursementVoucherPayeeService The disbursementVoucherPayeeService to set.
299         */
300        public void setDisbursementVoucherPayeeService(DisbursementVoucherPayeeService disbursementVoucherPayeeService) {
301            this.disbursementVoucherPayeeService = disbursementVoucherPayeeService;
302        }
303    }