1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.vnd.document.service.impl;
17
18 import java.sql.Date;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.log4j.Logger;
28 import org.kuali.ole.sys.OLEConstants;
29 import org.kuali.ole.sys.businessobject.Building;
30 import org.kuali.ole.sys.context.SpringContext;
31 import org.kuali.ole.vnd.VendorConstants;
32 import org.kuali.ole.vnd.VendorPropertyConstants;
33 import org.kuali.ole.vnd.businessobject.VendorAddress;
34 import org.kuali.ole.vnd.businessobject.VendorContract;
35 import org.kuali.ole.vnd.businessobject.VendorContractOrganization;
36 import org.kuali.ole.vnd.businessobject.VendorDefaultAddress;
37 import org.kuali.ole.vnd.businessobject.VendorDetail;
38 import org.kuali.ole.vnd.businessobject.VendorHeader;
39 import org.kuali.ole.vnd.businessobject.VendorRoutingComparable;
40 import org.kuali.ole.vnd.dataaccess.VendorDao;
41 import org.kuali.ole.vnd.document.service.VendorService;
42 import org.kuali.rice.core.api.datetime.DateTimeService;
43 import org.kuali.rice.core.api.util.type.KualiDecimal;
44 import org.kuali.rice.kew.api.exception.WorkflowException;
45 import org.kuali.rice.kim.api.identity.Person;
46 import org.kuali.rice.kim.api.identity.PersonService;
47 import org.kuali.rice.kns.document.MaintenanceDocument;
48 import org.kuali.rice.krad.bo.Note;
49 import org.kuali.rice.krad.document.Document;
50 import org.kuali.rice.krad.service.BusinessObjectService;
51 import org.kuali.rice.krad.service.DocumentService;
52 import org.kuali.rice.krad.service.NoteService;
53 import org.kuali.rice.krad.util.GlobalVariables;
54 import org.kuali.rice.krad.util.KRADConstants;
55 import org.kuali.rice.krad.util.ObjectUtils;
56 import org.springframework.transaction.annotation.Transactional;
57
58 @Transactional
59 public class VendorServiceImpl implements VendorService {
60 private static final Logger LOG = Logger.getLogger(VendorServiceImpl.class);
61
62 protected BusinessObjectService businessObjectService;
63 protected DocumentService documentService;
64 protected DateTimeService dateTimeService;
65 protected VendorDao vendorDao;
66 protected NoteService noteService;
67
68
69
70
71 @Override
72 public void saveVendorHeader(VendorDetail vendorDetail) {
73 businessObjectService.save(vendorDetail.getVendorHeader());
74 }
75
76
77
78
79 @Override
80 public VendorDetail getByVendorNumber(String vendorNumber) {
81 return getVendorDetail(vendorNumber);
82 }
83
84
85
86
87 @Override
88 public VendorDetail getVendorDetail(String vendorNumber) {
89 if (LOG.isDebugEnabled()) {
90 LOG.debug("Entering getVendorDetail for vendorNumber: " + vendorNumber);
91 }
92 if (StringUtils.isBlank(vendorNumber)) {
93 return null;
94 }
95
96 int dashInd = vendorNumber.indexOf('-');
97
98 if (dashInd > 0 && dashInd < vendorNumber.length() - 1) {
99 try {
100 Integer headerId = new Integer(vendorNumber.substring(0, dashInd));
101 Integer detailId = new Integer(vendorNumber.substring(dashInd + 1));
102 return getVendorDetail(headerId, detailId);
103 }
104 catch (NumberFormatException e) {
105
106 return null;
107 }
108 }
109
110 return null;
111 }
112
113
114
115
116 @Override
117 public VendorDetail getVendorDetail(Integer headerId, Integer detailId) {
118 if (LOG.isDebugEnabled()) {
119 LOG.debug("Entering getVendorDetail for headerId:" + headerId + ", detailId:" + detailId);
120 }
121 HashMap<String, Integer> keys = new HashMap<String, Integer>();
122 keys.put("vendorHeaderGeneratedIdentifier", headerId);
123 keys.put("vendorDetailAssignedIdentifier", detailId);
124 return businessObjectService.findByPrimaryKey(VendorDetail.class, keys);
125 }
126
127
128
129
130 @Override
131 public KualiDecimal getApoLimitFromContract(Integer contractId, String chart, String org) {
132 if (LOG.isDebugEnabled()) {
133 LOG.debug("Entering getApoLimitFromContract with contractId:" + contractId + ", chart:" + chart + ", org:" + org);
134 }
135
136
137 if (ObjectUtils.isNotNull(contractId) && ObjectUtils.isNotNull(chart) && ObjectUtils.isNotNull(org)) {
138 Map<String,Object> pkFields = new HashMap<String, Object>(3);
139 pkFields.put("vendorContractGeneratedIdentifier", contractId);
140 pkFields.put("chartOfAccountsCode", chart);
141 pkFields.put("organizationCode", org);
142 VendorContractOrganization contractOrg = businessObjectService.findByPrimaryKey(VendorContractOrganization.class, pkFields);
143
144 if (ObjectUtils.isNotNull(contractOrg)) {
145
146 if (!contractOrg.isVendorContractExcludeIndicator()) {
147 return contractOrg.getVendorContractPurchaseOrderLimitAmount();
148 }
149
150 else {
151 return null;
152 }
153 }
154 }
155
156
157
158 if ( contractId != null ) {
159 VendorContract contract = businessObjectService.findBySinglePrimaryKey(VendorContract.class, contractId);
160 if (contract != null) {
161 return contract.getOrganizationAutomaticPurchaseOrderLimit();
162 }
163 }
164
165
166 return null;
167 }
168
169
170
171
172 @Override
173 public VendorDetail getParentVendor(Integer vendorHeaderGeneratedIdentifier) {
174 if (LOG.isDebugEnabled()) {
175 LOG.debug("Entering getParentVendor for vendorHeaderGeneratedIdentifier:" + vendorHeaderGeneratedIdentifier);
176 }
177 Collection<VendorDetail> vendors = businessObjectService.findMatching(VendorDetail.class,
178 Collections.singletonMap("vendorHeaderGeneratedIdentifier", vendorHeaderGeneratedIdentifier));
179 VendorDetail result = null;
180 if (vendors == null || vendors.isEmpty() ) {
181 LOG.warn("Error: No vendors exist with vendor header " + vendorHeaderGeneratedIdentifier + ".");
182 }
183 else {
184 for (VendorDetail vendor : vendors) {
185 if (vendor.isVendorParentIndicator()) {
186 if (ObjectUtils.isNull(result)) {
187 result = vendor;
188 }
189 else {
190 LOG.error("Error: More than one parent vendor for vendor header " + vendorHeaderGeneratedIdentifier + ".");
191 throw new RuntimeException("Error: More than one parent vendor for vendor header " + vendorHeaderGeneratedIdentifier + ".");
192 }
193 }
194 }
195 if (ObjectUtils.isNull(result)) {
196 LOG.error("Error: No parent vendor for vendor header " + vendorHeaderGeneratedIdentifier + ".");
197 throw new RuntimeException("Error: No parent vendor for vendor header " + vendorHeaderGeneratedIdentifier + ".");
198 }
199 }
200 LOG.debug("Exiting getParentVendor normally.");
201 return result;
202 }
203
204
205
206
207 @Override
208 public VendorDetail getVendorByDunsNumber(String vendorDunsNumber) {
209 if (LOG.isDebugEnabled()) {
210 LOG.debug("Entering getVendorByDunsNumber for vendorDunsNumber:" + vendorDunsNumber);
211 }
212 HashMap<String, String> criteria = new HashMap<String, String>();
213 criteria.put(VendorPropertyConstants.VENDOR_DUNS_NUMBER, vendorDunsNumber);
214 Collection<VendorDetail> vds = businessObjectService.findMatching(VendorDetail.class, criteria);
215 LOG.debug("Exiting getVendorByDunsNumber.");
216 if (vds.size() < 1) {
217 return null;
218 }
219 else {
220 return vds.iterator().next();
221 }
222 }
223
224
225
226
227 @Override
228 public VendorAddress getVendorDefaultAddress(Integer vendorHeaderId, Integer vendorDetailId, String addressType, String campus) {
229 if (LOG.isDebugEnabled()) {
230 LOG.debug("Entering getVendorDefaultAddress for vendorHeaderId:" + vendorHeaderId + ", vendorDetailId:" + vendorDetailId + ", addressType:" + addressType + ", campus:" + campus);
231 }
232 HashMap<String, Object> criteria = new HashMap<String, Object>();
233 criteria.put(VendorPropertyConstants.VENDOR_HEADER_GENERATED_ID, vendorHeaderId);
234 criteria.put(VendorPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID, vendorDetailId);
235 criteria.put(VendorPropertyConstants.VENDOR_ADDRESS_TYPE_CODE, addressType);
236 Collection<VendorAddress> addresses = businessObjectService.findMatching(VendorAddress.class, criteria);
237 LOG.debug("Exiting getVendorDefaultAddress.");
238 return getVendorDefaultAddress(addresses, addressType, campus);
239 }
240
241
242
243
244 @Override
245 public VendorAddress getVendorDefaultAddress(Collection<VendorAddress> addresses, String addressType, String campus) {
246 LOG.debug("Entering getVendorDefaultAddress.");
247 VendorAddress allDefaultAddress = null;
248 for (VendorAddress address : addresses) {
249
250 if (addressType.equals(address.getVendorAddressTypeCode())) {
251
252 if (StringUtils.isNotEmpty(campus) && address.getVendorDefaultAddresses() != null) {
253
254 for (VendorDefaultAddress defaultCampus : address.getVendorDefaultAddresses()) {
255 if (campus.equals(defaultCampus.getVendorCampusCode())) {
256
257 LOG.debug("Exiting getVendorDefaultAddress with single campus default.");
258 return address;
259 }
260 }
261 }
262
263
264 if (address.isVendorDefaultAddressIndicator()) {
265 allDefaultAddress = address;
266 }
267 }
268 }
269
270
271 LOG.debug("Exiting getVendorDefaultAddress with default set for all.");
272 return allDefaultAddress;
273 }
274
275
276
277
278 @Override
279 public boolean shouldVendorRouteForApproval(String documentId) {
280 LOG.debug("Entering shouldVendorRouteForApproval.");
281 boolean shouldRoute = true;
282 MaintenanceDocument document = null;
283 try {
284 document = (MaintenanceDocument) documentService.getByDocumentHeaderId(documentId);
285 }
286 catch (WorkflowException we) {
287 throw new RuntimeException("A WorkflowException was thrown which prevented the loading of the comparison document (" + documentId + ")", we);
288 }
289
290 if (document == null) {
291
292 LOG.error( "Unable to retrieve document in workflow: " + documentId);
293 return false;
294 }
295 String maintenanceAction = document.getNewMaintainableObject().getMaintenanceAction();
296 if ( StringUtils.equals(KRADConstants.MAINTENANCE_NEW_ACTION, maintenanceAction)
297 || StringUtils.equals(KRADConstants.MAINTENANCE_NEWWITHEXISTING_ACTION, maintenanceAction)
298 || StringUtils.equals(KRADConstants.MAINTENANCE_COPY_ACTION, maintenanceAction) ) {
299 return true;
300 }
301 VendorDetail oldVendorDetail = (VendorDetail)document.getOldMaintainableObject().getBusinessObject();
302 if ( oldVendorDetail == null ) {
303
304 return true;
305 }
306 VendorHeader oldVendorHeader = oldVendorDetail.getVendorHeader();
307 if ( ObjectUtils.isNull(oldVendorHeader) ) {
308
309 return true;
310 }
311
312 VendorDetail newVendorDetail = (VendorDetail)document.getNewMaintainableObject().getBusinessObject();
313 if ( newVendorDetail == null ) {
314
315 return true;
316 }
317 VendorHeader newVendorHeader = newVendorDetail.getVendorHeader();
318
319 if ( ObjectUtils.isNull(newVendorHeader) ) {
320
321 return true;
322 }
323 return !noRouteSignificantChangeOccurred(newVendorDetail, newVendorHeader, oldVendorDetail, oldVendorHeader);
324 }
325
326
327
328
329
330
331 @Override
332 public boolean noRouteSignificantChangeOccurred(VendorDetail newVDtl, VendorHeader newVHdr, VendorDetail oldVDtl, VendorHeader oldVHdr) {
333 LOG.debug("Entering noRouteSignificantChangeOccurred.");
334
335
336 boolean unchanged = ((oldVHdr.isEqualForRouting(newVHdr))
337 && (equalMemberLists(oldVHdr.getVendorSupplierDiversities(), newVHdr.getVendorSupplierDiversities()))
338 && (oldVDtl.isEqualForRouting(newVDtl))
339 && (equalMemberLists(oldVDtl.getVendorAddresses(), newVDtl.getVendorAddresses()))
340 && (equalMemberLists(oldVDtl.getVendorContracts(), newVDtl.getVendorContracts()))
341 && (equalMemberLists(oldVDtl.getVendorShippingSpecialConditions(), newVDtl.getVendorShippingSpecialConditions())));
342
343 LOG.debug("Exiting noRouteSignificantChangeOccurred.");
344 return unchanged;
345 }
346
347
348
349
350 @Override
351 public boolean equalMemberLists(List<? extends VendorRoutingComparable> list_a, List<? extends VendorRoutingComparable> list_b) {
352 LOG.debug("Entering equalMemberLists.");
353 boolean result = true;
354 int listSize = list_a.size();
355 if (listSize != list_b.size()) {
356 LOG.debug("Exiting equalMemberLists because list sizes are unequal.");
357 return false;
358 }
359 VendorRoutingComparable aMember = null;
360 for (int i = 0; i < listSize; i++) {
361 aMember = list_a.get(i);
362 if (!aMember.isEqualForRouting(list_b.get(i))) {
363 result = false;
364 break;
365 }
366 }
367 LOG.debug("Exiting equalMemberLists.");
368 return result;
369 }
370
371
372
373
374 @Override
375 public boolean isVendorInstitutionEmployee(Integer vendorHeaderGeneratedIdentifier) {
376 VendorDetail vendorToUse = getParentVendor(vendorHeaderGeneratedIdentifier);
377 if (ObjectUtils.isNull(vendorToUse)) {
378 String errorMsg = "Vendor with header generated id '" + vendorHeaderGeneratedIdentifier + "' cannot be found in the system";
379 LOG.error(errorMsg);
380 throw new RuntimeException(errorMsg);
381 }
382 if (VendorConstants.TAX_TYPE_SSN.equals(vendorToUse.getVendorHeader().getVendorTaxTypeCode())) {
383 String ssnTaxId = vendorToUse.getVendorHeader().getVendorTaxNumber();
384 if (StringUtils.isNotBlank(ssnTaxId)) {
385 List<Person> personList = SpringContext.getBean(PersonService.class).getPersonByExternalIdentifier(org.kuali.rice.kim.api.KimConstants.PersonExternalIdentifierTypes.TAX, ssnTaxId);
386 if (personList != null && !personList.isEmpty()) {
387 return ObjectUtils.isNotNull(personList.get(0));
388 }
389 else {
390
391 return false;
392 }
393 }
394 }
395 return false;
396 }
397
398 public void createVendorNote(VendorDetail vendorDetail, String vendorNote) {
399 try {
400 if (StringUtils.isNotBlank(vendorNote)) {
401 Note newBONote = new Note();
402 newBONote.setNoteText(vendorNote);
403 newBONote.setNotePostedTimestampToCurrent();
404 newBONote.setNoteTypeCode(OLEConstants.NoteTypeEnum.BUSINESS_OBJECT_NOTE_TYPE.getCode());
405 Note note = noteService.createNote(newBONote, vendorDetail, GlobalVariables.getUserSession().getPrincipalId());
406 noteService.save(note);
407 }
408 } catch (Exception e){
409 throw new RuntimeException("Problems creating note for Vendor " + vendorDetail);
410 }
411 }
412
413 @Override
414 public List<Note> getVendorNotes(VendorDetail vendorDetail) {
415 List<Note> notes = new ArrayList<Note>();
416 if (ObjectUtils.isNotNull(vendorDetail)) {
417 notes = noteService.getByRemoteObjectId(vendorDetail.getObjectId());
418 }
419 return notes;
420 }
421
422
423
424
425 @Override
426 public boolean isVendorForeign(Integer vendorHeaderGeneratedIdentifier) {
427 VendorDetail vendorToUse = getParentVendor(vendorHeaderGeneratedIdentifier);
428 if (ObjectUtils.isNull(vendorToUse)) {
429 String errorMsg = "Vendor with header generated id '" + vendorHeaderGeneratedIdentifier + "' cannot be found in the system";
430 LOG.error(errorMsg);
431 throw new RuntimeException(errorMsg);
432 }
433 return vendorToUse.getVendorHeader().getVendorForeignIndicator();
434 }
435
436
437
438
439 @Override
440 public boolean isSubjectPaymentVendor(Integer vendorHeaderGeneratedIdentifier) {
441 VendorDetail vendorToUse = getParentVendor(vendorHeaderGeneratedIdentifier);
442 if (ObjectUtils.isNull(vendorToUse)) {
443 String errorMsg = "Vendor with header generated id '" + vendorHeaderGeneratedIdentifier + "' cannot be found in the system";
444 LOG.error(errorMsg);
445 throw new RuntimeException(errorMsg);
446 }
447 return VendorConstants.VendorTypes.SUBJECT_PAYMENT.equals(vendorToUse.getVendorHeader().getVendorTypeCode());
448 }
449
450
451
452
453 @Override
454 public boolean isRevolvingFundCodeVendor(Integer vendorHeaderGeneratedIdentifier) {
455 VendorDetail vendorToUse = getParentVendor(vendorHeaderGeneratedIdentifier);
456 if (ObjectUtils.isNull(vendorToUse)) {
457 String errorMsg = "Vendor with header generated id '" + vendorHeaderGeneratedIdentifier + "' cannot be found in the system";
458 LOG.error(errorMsg);
459 throw new RuntimeException(errorMsg);
460 }
461 return VendorConstants.VendorTypes.REVOLVING_FUND.equals(vendorToUse.getVendorHeader().getVendorTypeCode());
462 }
463
464
465
466
467
468 @Override
469 public Building getBuildingDetails(String campusCode, String buildingCode) {
470
471 Map keys = new HashMap();
472 keys.put("campusCode", campusCode);
473 keys.put("buildingCode", buildingCode);
474 return businessObjectService.findByPrimaryKey(Building.class, keys);
475 }
476
477
478
479
480 @Override
481 public boolean isVendorContractExpired(Document document, VendorDetail vendorDetail) {
482 boolean isExpired = false;
483
484 Date currentDate = SpringContext.getBean(DateTimeService.class).getCurrentSqlDate();
485
486 List<VendorContract> vendorContracts = vendorDetail.getVendorContracts();
487 List<Note> notes = document.getNotes();
488
489 for (VendorContract vendorContract : vendorContracts) {
490 if (currentDate.compareTo(vendorContract.getVendorContractEndDate()) > 0 || !vendorContract.isActive()) {
491 Note newNote = new Note();
492 newNote.setNoteText("Vendor Contract: " + vendorContract.getVendorContractName() + " contract has expired contract end date.");
493 newNote.setNotePostedTimestampToCurrent();
494 newNote.setNoteTypeCode(OLEConstants.NoteTypeEnum.BUSINESS_OBJECT_NOTE_TYPE.getCode());
495 Note note = noteService.createNote(newNote, vendorDetail, GlobalVariables.getUserSession().getPrincipalId());
496 notes.add(note);
497 return true;
498 }
499 }
500
501 return isExpired;
502 }
503
504 @Override
505 public VendorContract getVendorB2BContract(VendorDetail vendorDetail, String campus) {
506 return SpringContext.getBean(org.kuali.ole.vnd.dataaccess.VendorDao.class).getVendorB2BContract(vendorDetail, campus, dateTimeService.getCurrentSqlDate());
507 }
508
509 public void setBusinessObjectService(BusinessObjectService boService) {
510 this.businessObjectService = boService;
511 }
512
513 public void setDocumentService(DocumentService documentService) {
514 this.documentService = documentService;
515 }
516
517 public void setVendorDao(VendorDao vendorDao) {
518 this.vendorDao = vendorDao;
519 }
520
521 public VendorDao getVendorDao() {
522 return this.vendorDao ;
523 }
524
525 public void setDateTimeService(DateTimeService dateTimeService) {
526 this.dateTimeService = dateTimeService;
527 }
528
529 }