1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.ole.fp.document.service.impl;
17  
18  import java.text.MessageFormat;
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.Set;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.kuali.ole.fp.businessobject.DisbursementPayee;
27  import org.kuali.ole.fp.businessobject.DisbursementVoucherPayeeDetail;
28  import org.kuali.ole.fp.document.DisbursementVoucherConstants;
29  import org.kuali.ole.fp.document.DisbursementVoucherDocument;
30  import org.kuali.ole.fp.document.service.DisbursementVoucherPayeeService;
31  import org.kuali.ole.sys.OLEConstants;
32  import org.kuali.ole.sys.OLEPropertyConstants;
33  import org.kuali.ole.sys.context.SpringContext;
34  import org.kuali.ole.sys.document.authorization.FinancialSystemTransactionalDocumentAuthorizerBase;
35  import org.kuali.ole.vnd.VendorConstants;
36  import org.kuali.ole.vnd.VendorPropertyConstants;
37  import org.kuali.ole.vnd.businessobject.VendorDetail;
38  import org.kuali.ole.vnd.businessobject.VendorType;
39  import org.kuali.ole.vnd.document.service.VendorService;
40  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
41  import org.kuali.rice.kew.api.KewApiConstants;
42  import org.kuali.rice.kew.api.exception.WorkflowException;
43  import org.kuali.rice.kim.api.identity.Person;
44  import org.kuali.rice.kim.api.identity.PersonService;
45  import org.kuali.rice.kim.impl.KIMPropertyConstants;
46  import org.kuali.rice.kns.service.DataDictionaryService;
47  import org.kuali.rice.krad.bo.AdHocRoutePerson;
48  import org.kuali.rice.krad.bo.Note;
49  import org.kuali.rice.krad.service.BusinessObjectService;
50  import org.kuali.rice.krad.service.DocumentService;
51  import org.kuali.rice.krad.util.ObjectUtils;
52  
53  
54  
55  
56  
57  
58  public class DisbursementVoucherPayeeServiceImpl implements DisbursementVoucherPayeeService {
59      private org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherPayeeServiceImpl.class);
60  
61      private BusinessObjectService businessObjectService;
62      private DataDictionaryService dataDictionaryService;
63      private DocumentService documentService;
64      private ParameterService parameterService;
65      private VendorService vendorService;
66  
67      public final static String addressPattern = "{0}, {1}, {2} {3}";
68  
69      
70  
71  
72      @Override
73      public String getPayeeTypeDescription(String payeeTypeCode) {
74          String payeeTypeDescription = StringUtils.EMPTY;
75  
76          if (DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE.equals(payeeTypeCode)) {
77  
78              payeeTypeDescription = DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE_DESC;
79          }
80          if (DisbursementVoucherConstants.DV_PAYEE_TYPE_VENDOR.equals(payeeTypeCode)) {
81              payeeTypeDescription = parameterService.getParameterValueAsString(DisbursementVoucherDocument.class, DisbursementVoucherConstants.PO_AND_DV_PAYEE_TYPE_LABEL_PARM_NM);
82          }
83          else if (DisbursementVoucherConstants.DV_PAYEE_TYPE_REVOLVING_FUND_VENDOR.equals(payeeTypeCode)) {
84              payeeTypeDescription = this.getVendorTypeDescription(VendorConstants.VendorTypes.REVOLVING_FUND);
85          }
86          else if (DisbursementVoucherConstants.DV_PAYEE_TYPE_SUBJECT_PAYMENT_VENDOR.equals(payeeTypeCode)) {
87              payeeTypeDescription = this.getVendorTypeDescription(VendorConstants.VendorTypes.SUBJECT_PAYMENT);
88          }
89  
90          return payeeTypeDescription;
91      }
92  
93      
94  
95  
96      @Override
97      public boolean isEmployee(DisbursementVoucherPayeeDetail dvPayeeDetail) {
98          
99          if (this.isVendor(dvPayeeDetail)) {
100             VendorDetail vendor = vendorService.getByVendorNumber(dvPayeeDetail.getDisbVchrPayeeIdNumber());
101             return vendor == null ? false : vendorService.isVendorInstitutionEmployee(vendor.getVendorHeaderGeneratedIdentifier());
102         }
103 
104         String payeeTypeCode = dvPayeeDetail.getDisbursementVoucherPayeeTypeCode();
105         return DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE.equals(payeeTypeCode);
106     }
107 
108     
109 
110 
111     @Override
112     public boolean isEmployee(DisbursementPayee payee) {
113         
114         if (this.isVendor(payee)) {
115             VendorDetail vendor = vendorService.getByVendorNumber(payee.getPayeeIdNumber());
116             return vendor == null ? false : vendorService.isVendorInstitutionEmployee(vendor.getVendorHeaderGeneratedIdentifier());
117         }
118 
119         String payeeTypeCode = payee.getPayeeTypeCode();
120         return DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE.equals(payeeTypeCode);
121     }
122 
123     
124 
125 
126     @Override
127     public boolean isVendor(DisbursementVoucherPayeeDetail dvPayeeDetail) {
128         String payeeTypeCode = dvPayeeDetail.getDisbursementVoucherPayeeTypeCode();
129         return DisbursementVoucherConstants.VENDOR_PAYEE_TYPE_CODES.contains(payeeTypeCode);
130     }
131 
132     
133 
134 
135     @Override
136     public boolean isVendor(DisbursementPayee payee) {
137         String payeeTypeCode = payee.getPayeeTypeCode();
138         return DisbursementVoucherConstants.VENDOR_PAYEE_TYPE_CODES.contains(payeeTypeCode);
139     }
140 
141     
142 
143 
144     @Override
145     public boolean isPayeeIndividualVendor(DisbursementVoucherPayeeDetail dvPayeeDetail) {
146         return this.isVendor(dvPayeeDetail) ? this.isPayeeIndividualVendor(dvPayeeDetail.getDisbVchrPayeeIdNumber()) : false;
147     }
148 
149     
150 
151 
152     @Override
153     public boolean isPayeeIndividualVendor(DisbursementPayee payee) {
154         return this.isVendor(payee) ? this.isPayeeIndividualVendor(payee.getPayeeIdNumber()) : false;
155     }
156 
157     
158 
159 
160     @Override
161     public String getVendorOwnershipTypeCode(DisbursementPayee payee) {
162         if(ObjectUtils.isNull(payee) || !this.isVendor(payee)) {
163             return null;
164         }
165 
166         VendorDetail vendor = vendorService.getByVendorNumber(payee.getPayeeIdNumber());
167         return vendor == null ? null : vendor.getVendorHeader().getVendorOwnershipCode();
168     }
169 
170     
171 
172 
173     @Override
174     public void checkPayeeAddressForChanges(DisbursementVoucherDocument dvDoc) {
175         Map<String, String> pks = new HashMap<String, String>();
176         pks.put("documentNumber", dvDoc.getDocumentNumber());
177 
178         DisbursementVoucherDocument savedDv = businessObjectService.findByPrimaryKey(DisbursementVoucherDocument.class, pks);
179         DisbursementVoucherPayeeDetail newPayeeDetail = dvDoc.getDvPayeeDetail();
180         DisbursementVoucherPayeeDetail oldPayeeDetail = savedDv.getDvPayeeDetail();
181 
182         if (ObjectUtils.isNotNull(oldPayeeDetail) && ObjectUtils.isNotNull(newPayeeDetail)) {
183             if (!oldPayeeDetail.hasSameAddress(newPayeeDetail)) {
184                 
185 
186                 
187                 try {
188                     String noteText = buildPayeeChangedNoteText(newPayeeDetail, oldPayeeDetail);
189 
190                     int noteMaxSize = dataDictionaryService.getAttributeMaxLength("Note", "noteText");
191 
192                     
193                     while (noteText.length() > noteMaxSize) {
194                         int fromIndex = 0;
195                         fromIndex = noteText.lastIndexOf(';', noteMaxSize);
196 
197                         String noteText1 = noteText.substring(0, fromIndex);
198                         Note note1 = documentService.createNoteFromDocument(dvDoc, noteText1);
199                         dvDoc.addNote(note1);
200                         noteText = noteText.substring(fromIndex);
201                     }
202 
203                     Note note = documentService.createNoteFromDocument(dvDoc, noteText);
204                     dvDoc.addNote(note);
205                 }
206                 catch (Exception e) {
207                     LOG.error("Exception while attempting to create or add note: " + e);
208                 }
209 
210                 
211                 try {
212                     Set<Person> priorApprovers = dvDoc.getAllPriorApprovers();
213 
214                     String initiatorUserId = dvDoc.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
215                     Person finSysUser = SpringContext.getBean(PersonService.class).getPerson(initiatorUserId);
216                     setupFYIs(dvDoc, priorApprovers, finSysUser.getPrincipalName());
217                 }
218                 catch (WorkflowException we) {
219                     LOG.error("Exception while attempting to retrieve all prior approvers from workflow: " + we);
220                 }
221                 catch (Exception unfe) {
222                     LOG.error("Exception while attempting to retrieve all prior approvers for a disbursement voucher: " + unfe);
223                 }
224             }
225         }
226     }
227 
228     
229 
230 
231     @Override
232     public Map<String, String> getFieldConversionBetweenPayeeAndVendor() {
233         Map<String, String> fieldConversionMap = new HashMap<String, String>();
234 
235         fieldConversionMap.put(OLEPropertyConstants.TAX_NUMBER, VendorPropertyConstants.VENDOR_TAX_NUMBER);
236         fieldConversionMap.put(OLEPropertyConstants.PAYEE_NAME, VendorPropertyConstants.VENDOR_NAME);
237 
238         fieldConversionMap.put(OLEPropertyConstants.VENDOR_NAME, VendorPropertyConstants.VENDOR_NAME);
239         fieldConversionMap.put(OLEPropertyConstants.VENDOR_NUMBER, VendorPropertyConstants.VENDOR_NUMBER);
240 
241         fieldConversionMap.put(OLEPropertyConstants.PERSON_FIRST_NAME, VendorPropertyConstants.VENDOR_FIRST_NAME);
242         fieldConversionMap.put(OLEPropertyConstants.PERSON_LAST_NAME, VendorPropertyConstants.VENDOR_LAST_NAME);
243 
244         fieldConversionMap.put(OLEPropertyConstants.ACTIVE, OLEPropertyConstants.ACTIVE_INDICATOR);
245 
246         return fieldConversionMap;
247     }
248 
249     
250 
251 
252     @Override
253     public Map<String, String> getFieldConversionBetweenPayeeAndPerson() {
254         Map<String, String> fieldConversionMap = new HashMap<String, String>();
255 
256         
257 
258         fieldConversionMap.put(OLEPropertyConstants.PAYEE_NAME, KIMPropertyConstants.Person.NAME);
259         fieldConversionMap.put(OLEPropertyConstants.PERSON_FIRST_NAME, KIMPropertyConstants.Person.FIRST_NAME);
260         fieldConversionMap.put(OLEPropertyConstants.PERSON_LAST_NAME, KIMPropertyConstants.Person.LAST_NAME);
261 
262         fieldConversionMap.put(OLEPropertyConstants.EMPLOYEE_ID, KIMPropertyConstants.Person.EMPLOYEE_ID);
263         fieldConversionMap.put(OLEPropertyConstants.ACTIVE, KIMPropertyConstants.Person.ACTIVE);
264 
265         return fieldConversionMap;
266     }
267 
268     
269 
270 
271     @Override
272     public DisbursementPayee getPayeeFromVendor(VendorDetail vendorDetail) {
273         DisbursementPayee disbursementPayee = new DisbursementPayee();
274 
275         disbursementPayee.setActive(vendorDetail.isActiveIndicator());
276 
277         disbursementPayee.setPayeeIdNumber(vendorDetail.getVendorNumber());
278         disbursementPayee.setPayeeName(vendorDetail.getAltVendorName());
279         disbursementPayee.setTaxNumber(vendorDetail.getVendorHeader().getVendorTaxNumber());
280 
281         String vendorTypeCode = vendorDetail.getVendorHeader().getVendorTypeCode();
282         String payeeTypeCode = getVendorPayeeTypeCodeMapping().get(vendorTypeCode);
283         disbursementPayee.setPayeeTypeCode(payeeTypeCode);
284 
285         String vendorAddress = MessageFormat.format(addressPattern, vendorDetail.getDefaultAddressLine1(), vendorDetail.getDefaultAddressCity(), vendorDetail.getDefaultAddressStateCode(), vendorDetail.getDefaultAddressCountryCode());
286         disbursementPayee.setAddress(vendorAddress);
287 
288         return disbursementPayee;
289     }
290 
291     
292 
293 
294     @Override
295     public DisbursementPayee getPayeeFromPerson(Person person) {
296         DisbursementPayee disbursementPayee = new DisbursementPayee();
297 
298         disbursementPayee.setActive(person.isActive());
299 
300         disbursementPayee.setPayeeIdNumber(person.getEmployeeId());
301         disbursementPayee.setPrincipalId(person.getPrincipalId());
302 
303         disbursementPayee.setPayeeName(person.getName());
304         disbursementPayee.setTaxNumber(OLEConstants.BLANK_SPACE);
305 
306         disbursementPayee.setPayeeTypeCode(DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE);
307 
308         String personAddress = MessageFormat.format(addressPattern, person.getAddressLine1(), person.getAddressCity(), person.getAddressStateProvinceCode(), person.getAddressCountryCode());
309         disbursementPayee.setAddress(personAddress);
310 
311         return disbursementPayee;
312     }
313 
314     
315 
316 
317 
318 
319 
320     protected String buildPayeeChangedNoteText(DisbursementVoucherPayeeDetail newPayeeDetail, DisbursementVoucherPayeeDetail oldPayeeDetail) {
321         StringBuilder noteText = new StringBuilder();
322         String valueLabel = "";
323         try {
324             noteText.append("The following changes were made to the payee address: ");
325 
326             valueLabel = dataDictionaryService.getAttributeLabel(DisbursementVoucherPayeeDetail.class, OLEPropertyConstants.DISB_VCHR_PAYEE_LINE1_ADDR);
327             noteText.append(buildAddressValueDifferenceText(valueLabel, oldPayeeDetail.getDisbVchrPayeeLine1Addr(), newPayeeDetail.getDisbVchrPayeeLine1Addr()));
328 
329             valueLabel = dataDictionaryService.getAttributeLabel(DisbursementVoucherPayeeDetail.class, OLEPropertyConstants.DISB_VCHR_PAYEE_LINE2_ADDR);
330             noteText.append(buildAddressValueDifferenceText(valueLabel, oldPayeeDetail.getDisbVchrPayeeLine2Addr(), newPayeeDetail.getDisbVchrPayeeLine2Addr()));
331 
332             valueLabel = dataDictionaryService.getAttributeLabel(DisbursementVoucherPayeeDetail.class, OLEPropertyConstants.DISB_VCHR_PAYEE_CITY_NAME);
333             noteText.append(buildAddressValueDifferenceText(valueLabel, oldPayeeDetail.getDisbVchrPayeeCityName(), newPayeeDetail.getDisbVchrPayeeCityName()));
334 
335             valueLabel = dataDictionaryService.getAttributeLabel(DisbursementVoucherPayeeDetail.class, OLEPropertyConstants.DISB_VCHR_PAYEE_STATE_CODE);
336             noteText.append(buildAddressValueDifferenceText(valueLabel, oldPayeeDetail.getDisbVchrPayeeStateCode(), newPayeeDetail.getDisbVchrPayeeStateCode()));
337 
338             valueLabel = dataDictionaryService.getAttributeLabel(DisbursementVoucherPayeeDetail.class, OLEPropertyConstants.DISB_VCHR_PAYEE_ZIP_CODE);
339             noteText.append(buildAddressValueDifferenceText(valueLabel, oldPayeeDetail.getDisbVchrPayeeZipCode(), newPayeeDetail.getDisbVchrPayeeZipCode()));
340 
341             valueLabel = dataDictionaryService.getAttributeLabel(DisbursementVoucherPayeeDetail.class, OLEPropertyConstants.DISB_VCHR_PAYEE_COUNTRY_CODE);
342             noteText.append(buildAddressValueDifferenceText(valueLabel, oldPayeeDetail.getDisbVchrPayeeCountryCode(), newPayeeDetail.getDisbVchrPayeeCountryCode()));
343         }
344         catch (Exception ex) {
345             LOG.error("Error while attempting to build out note text for payee address change note: " + ex);
346         }
347 
348         return noteText.toString();
349     }
350 
351     
352 
353 
354 
355 
356 
357 
358 
359     protected String buildAddressValueDifferenceText(String valueName, String oldValue, String newValue) {
360         
361         if (StringUtils.equals(oldValue, newValue)) {
362             return "";
363         }
364 
365         StringBuilder text = new StringBuilder();
366 
367         text.append(valueName).append(" was changed from ");
368         text.append(oldValue == null ? "(no value entered)" : oldValue).append(" to ");
369         text.append(newValue).append("; ");
370 
371         return text.toString();
372     }
373 
374     
375 
376 
377 
378 
379 
380 
381     protected void setupFYIs(DisbursementVoucherDocument dvDoc, Set<Person> priorApprovers, String initiatorUserId) {
382         List<AdHocRoutePerson> adHocRoutePersons = dvDoc.getAdHocRoutePersons();
383         final FinancialSystemTransactionalDocumentAuthorizerBase documentAuthorizer = getDocumentAuthorizer(dvDoc);
384 
385         
386         for (Person approver : priorApprovers) {
387             if (documentAuthorizer.canReceiveAdHoc(dvDoc, approver, KewApiConstants.ACTION_REQUEST_FYI_REQ)) {
388                 String approverPersonUserId = approver.getPrincipalName();
389                 adHocRoutePersons.add(buildFyiRecipient(approverPersonUserId));
390             }
391         }
392 
393         
394         adHocRoutePersons.add(buildFyiRecipient(initiatorUserId));
395     }
396 
397     
398 
399 
400 
401     protected FinancialSystemTransactionalDocumentAuthorizerBase getDocumentAuthorizer(DisbursementVoucherDocument dvDoc) {
402         final String docTypeName = dataDictionaryService.getDocumentTypeNameByClass(dvDoc.getClass());
403         Class<? extends org.kuali.rice.krad.document.DocumentAuthorizer> documentAuthorizerClass = dataDictionaryService.getDataDictionary().getDocumentEntry(docTypeName).getDocumentAuthorizerClass();
404 
405         FinancialSystemTransactionalDocumentAuthorizerBase documentAuthorizer = null;
406         try {
407             documentAuthorizer = (FinancialSystemTransactionalDocumentAuthorizerBase)documentAuthorizerClass.newInstance();
408         }
409         catch (InstantiationException ie) {
410             throw new RuntimeException("Could not construct document authorizer: "+documentAuthorizerClass.getName(), ie);
411         }
412         catch (IllegalAccessException iae) {
413             throw new RuntimeException("Could not construct document authorizer: "+documentAuthorizerClass.getName(), iae);
414         }
415 
416         return documentAuthorizer;
417     }
418 
419     
420 
421 
422 
423 
424 
425     protected AdHocRoutePerson buildFyiRecipient(String userId) {
426         AdHocRoutePerson adHocRoutePerson = new AdHocRoutePerson();
427         adHocRoutePerson.setActionRequested(KewApiConstants.ACTION_REQUEST_FYI_REQ);
428         adHocRoutePerson.setId(userId);
429         return adHocRoutePerson;
430     }
431 
432     
433     protected String getVendorTypeDescription(String vendorTypeCode) {
434         Map<String, String> primaryKeys = new HashMap<String, String>();
435         primaryKeys.put(OLEPropertyConstants.VENDOR_TYPE_CODE, vendorTypeCode);
436 
437         VendorType vendorType = businessObjectService.findByPrimaryKey(VendorType.class, primaryKeys);
438         return ObjectUtils.isNotNull(vendorType) ? vendorType.getVendorTypeDescription() : StringUtils.EMPTY;
439     }
440 
441     
442     protected boolean isPayeeIndividualVendor(String payeeIdNumber) {
443         List<String> individualOwnerShipTypeCodes = new ArrayList<String>( parameterService.getParameterValuesAsString(DisbursementVoucherDocument.class, DisbursementVoucherConstants.INDIVIDUAL_OWNERSHIP_TYPES_PARM_NM) );
444 
445         VendorDetail vendor = vendorService.getByVendorNumber(payeeIdNumber);
446         if (vendor != null && individualOwnerShipTypeCodes != null) {
447             return individualOwnerShipTypeCodes.contains(vendor.getVendorHeader().getVendorOwnershipCode());
448         }
449 
450         return false;
451     }
452 
453  
454     private static Map<String, String> getVendorPayeeTypeCodeMapping() {
455         Map<String, String> payeeVendorTypeCodeMapping = new HashMap<String, String>();
456 
457         payeeVendorTypeCodeMapping.put(VendorConstants.VendorTypes.PURCHASE_ORDER, DisbursementVoucherConstants.DV_PAYEE_TYPE_VENDOR);
458         payeeVendorTypeCodeMapping.put(VendorConstants.VendorTypes.DISBURSEMENT_VOUCHER, DisbursementVoucherConstants.DV_PAYEE_TYPE_VENDOR);
459         payeeVendorTypeCodeMapping.put(VendorConstants.VendorTypes.REVOLVING_FUND, DisbursementVoucherConstants.DV_PAYEE_TYPE_REVOLVING_FUND_VENDOR);
460         payeeVendorTypeCodeMapping.put(VendorConstants.VendorTypes.SUBJECT_PAYMENT, DisbursementVoucherConstants.DV_PAYEE_TYPE_SUBJECT_PAYMENT_VENDOR);
461 
462         return payeeVendorTypeCodeMapping;
463     }
464 
465     
466 
467 
468 
469 
470     public void setBusinessObjectService(BusinessObjectService businessObjectService) {
471         this.businessObjectService = businessObjectService;
472     }
473 
474     
475 
476 
477 
478 
479     public void setDocumentService(DocumentService documentService) {
480         this.documentService = documentService;
481     }
482 
483     
484 
485 
486 
487 
488     public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
489         this.dataDictionaryService = dataDictionaryService;
490     }
491 
492     
493 
494 
495 
496 
497     public void setParameterService(ParameterService parameterService) {
498         this.parameterService = parameterService;
499     }
500 
501     
502 
503 
504 
505     public void setVendorService(VendorService vendorService) {
506         this.vendorService = vendorService;
507     }
508 }