001: /*
002: * Copyright 2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.module.vendor.service.impl;
017:
018: import java.util.HashMap;
019: import java.util.List;
020: import java.util.Map;
021:
022: import org.apache.commons.lang.StringUtils;
023: import org.apache.log4j.Logger;
024: import org.kuali.core.bo.user.PersonTaxId;
025: import org.kuali.core.bo.user.UniversalUser;
026: import org.kuali.core.document.MaintenanceDocument;
027: import org.kuali.core.exceptions.UserNotFoundException;
028: import org.kuali.core.service.BusinessObjectService;
029: import org.kuali.core.service.DocumentService;
030: import org.kuali.core.service.PersistenceService;
031: import org.kuali.core.service.UniversalUserService;
032: import org.kuali.core.util.KualiDecimal;
033: import org.kuali.core.util.ObjectUtils;
034: import org.kuali.module.vendor.VendorConstants;
035: import org.kuali.module.vendor.VendorPropertyConstants;
036: import org.kuali.module.vendor.bo.VendorAddress;
037: import org.kuali.module.vendor.bo.VendorContract;
038: import org.kuali.module.vendor.bo.VendorContractOrganization;
039: import org.kuali.module.vendor.bo.VendorDefaultAddress;
040: import org.kuali.module.vendor.bo.VendorDetail;
041: import org.kuali.module.vendor.bo.VendorHeader;
042: import org.kuali.module.vendor.service.VendorService;
043: import org.kuali.module.vendor.util.VendorRoutingComparable;
044: import org.springframework.transaction.annotation.Transactional;
045:
046: import edu.iu.uis.eden.exception.WorkflowException;
047:
048: @Transactional
049: public class VendorServiceImpl implements VendorService {
050: private static Logger LOG = Logger
051: .getLogger(VendorServiceImpl.class);
052:
053: private BusinessObjectService businessObjectService;
054: private DocumentService documentService;
055: private UniversalUserService universalUserService;
056: private PersistenceService persistenceService;
057:
058: public void saveVendorHeader(VendorDetail vendorDetail) {
059: businessObjectService.save(vendorDetail.getVendorHeader());
060: }
061:
062: public VendorDetail getVendorDetail(Integer headerId,
063: Integer detailId) {
064: LOG.debug("Entering getVendorDetail for headerId:" + headerId
065: + ", detailId:" + detailId);
066: Map keys = new HashMap();
067: keys.put("vendorHeaderGeneratedIdentifier", headerId);
068: keys.put("vendorDetailAssignedIdentifier", detailId);
069: return (VendorDetail) businessObjectService.findByPrimaryKey(
070: VendorDetail.class, keys);
071: }
072:
073: /**
074: * @see org.kuali.module.vendor.service.VendorService#getApoLimitFromContract(Integer, String, String)
075: */
076: public KualiDecimal getApoLimitFromContract(Integer contractId,
077: String chart, String org) {
078: LOG.debug("Entering getApoLimitFromContract with contractId:"
079: + contractId + ", chart:" + chart + ", org:" + org);
080:
081: // See if there is a contractOrg for this contract and look for the special case of APO limit in the contract orgs table,
082: // return the value found
083: if (ObjectUtils.isNotNull(contractId)
084: && ObjectUtils.isNotNull(chart)
085: && ObjectUtils.isNotNull(org)) {
086: VendorContractOrganization exampleContractOrg = new VendorContractOrganization();
087: exampleContractOrg
088: .setVendorContractGeneratedIdentifier(contractId);
089: exampleContractOrg.setChartOfAccountsCode(chart);
090: exampleContractOrg.setOrganizationCode(org);
091: Map orgKeys = persistenceService
092: .getPrimaryKeyFieldValues(exampleContractOrg);
093: VendorContractOrganization contractOrg = (VendorContractOrganization) businessObjectService
094: .findByPrimaryKey(VendorContractOrganization.class,
095: orgKeys);
096: if (ObjectUtils.isNotNull(contractOrg)) {
097: if (!contractOrg.isVendorContractExcludeIndicator()) { // It's not excluded.
098: return contractOrg
099: .getVendorContractPurchaseOrderLimitAmount();
100: }
101: }
102: }
103:
104: // didn't search the table or not found in the table and contract exists, return the default APO limit in contract
105: if (ObjectUtils.isNotNull(contractId)) {
106: VendorContract exampleContract = new VendorContract();
107: exampleContract
108: .setVendorContractGeneratedIdentifier(contractId);
109: Map contractKeys = persistenceService
110: .getPrimaryKeyFieldValues(exampleContract);
111: VendorContract contract = (VendorContract) businessObjectService
112: .findByPrimaryKey(VendorContract.class,
113: contractKeys);
114:
115: if (ObjectUtils.isNotNull(contract)) {
116: return contract
117: .getOrganizationAutomaticPurchaseOrderLimit();
118: }
119: }
120:
121: // otherwise no APO limit found
122: return null;
123: }
124:
125: /**
126: * @see org.kuali.module.vendor.service.VendorService#getParentVendor(java.lang.Integer)
127: */
128: public VendorDetail getParentVendor(
129: Integer vendorHeaderGeneratedIdentifier) {
130: LOG
131: .debug("Entering getParentVendor for vendorHeaderGeneratedIdentifier:"
132: + vendorHeaderGeneratedIdentifier);
133: Map criterion = new HashMap();
134: criterion.put("vendorHeaderGeneratedIdentifier",
135: vendorHeaderGeneratedIdentifier);
136: List<VendorDetail> vendors = (List<VendorDetail>) businessObjectService
137: .findMatching(VendorDetail.class, criterion);
138: VendorDetail result = null;
139: if (ObjectUtils.isNull(vendors)) {
140: LOG.warn("Error: No vendors exist with vendor header "
141: + vendorHeaderGeneratedIdentifier + ".");
142: } else {
143: for (VendorDetail vendor : vendors) {
144: if (vendor.isVendorParentIndicator()) {
145: if (ObjectUtils.isNull(result)) {
146: result = vendor;
147: } else {
148: LOG
149: .error("Error: More than one parent vendor for vendor header "
150: + vendorHeaderGeneratedIdentifier
151: + ".");
152: throw new RuntimeException(
153: "Error: More than one parent vendor for vendor header "
154: + vendorHeaderGeneratedIdentifier
155: + ".");
156: }
157: }
158: }
159: if (ObjectUtils.isNull(result)) {
160: LOG.error("Error: No parent vendor for vendor header "
161: + vendorHeaderGeneratedIdentifier + ".");
162: throw new RuntimeException(
163: "Error: No parent vendor for vendor header "
164: + vendorHeaderGeneratedIdentifier + ".");
165: }
166: }
167: LOG.debug("Exiting getParentVendor normally.");
168: return result;
169: }
170:
171: /**
172: * @see org.kuali.module.vendor.service.VendorService#getVendorDefaultAddress(Integer, Integer, String, String)
173: */
174: public VendorAddress getVendorDefaultAddress(
175: Integer vendorHeaderId, Integer vendorDetailId,
176: String addressType, String campus) {
177: LOG
178: .debug("Entering getVendorDefaultAddress for vendorHeaderId:"
179: + vendorHeaderId
180: + ", vendorDetailId:"
181: + vendorDetailId
182: + ", addressType:"
183: + addressType + ", campus:" + campus);
184: Map criteria = new HashMap();
185: criteria.put(
186: VendorPropertyConstants.VENDOR_HEADER_GENERATED_ID,
187: vendorHeaderId);
188: criteria.put(VendorPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID,
189: vendorDetailId);
190: criteria.put(VendorPropertyConstants.VENDOR_ADDRESS_TYPE_CODE,
191: addressType);
192: List<VendorAddress> addresses = (List) businessObjectService
193: .findMatching(VendorAddress.class, criteria);
194: LOG.debug("Exiting getVendorDefaultAddress.");
195: return getVendorDefaultAddress(addresses, addressType, campus);
196: }
197:
198: /**
199: * @see org.kuali.module.vendor.service.VendorService#getVendorDefaultAddress(List, String, String)
200: */
201: public VendorAddress getVendorDefaultAddress(
202: List<VendorAddress> addresses, String addressType,
203: String campus) {
204: LOG.debug("Entering getVendorDefaultAddress.");
205: VendorAddress allDefaultAddress = null;
206: for (VendorAddress address : addresses) {
207: // if address is of the right type, continue check
208: if (addressType.equals(address.getVendorAddressTypeCode())) {
209: // if campus was passed in and list of campuses on address exist, continue check
210: if (StringUtils.isNotEmpty(campus)
211: && address.getVendorDefaultAddresses() != null) {
212: // looping through list of campus defaults to find a match for the passed in campus
213: for (VendorDefaultAddress defaultCampus : address
214: .getVendorDefaultAddresses()) {
215: if (campus.equals(defaultCampus
216: .getVendorCampusCode())) {
217: // found campus default; return it
218: LOG
219: .debug("Exiting getVendorDefaultAddress with single campus default.");
220: return address;
221: }
222: }// endfor campuses
223: }
224:
225: // if this address is set as the default for this address type; keep it for possible future use
226: if (address.isVendorDefaultAddressIndicator()) {
227: allDefaultAddress = address;
228: }
229: }
230: }// endfor addresses
231:
232: // if we got this far, there is no campus default; so return the default set for all (could return null)
233: LOG
234: .debug("Exiting getVendorDefaultAddress with default set for all.");
235: return allDefaultAddress;
236: }
237:
238: /**
239: * @see org.kuali.module.vendor.service.VendorService#shouldVendorRouteForApproval(java.lang.String)
240: */
241: public boolean shouldVendorRouteForApproval(String documentId) {
242: LOG.debug("Entering shouldVendorRouteForApproval.");
243: boolean shouldRoute = true;
244: MaintenanceDocument newDoc = null;
245: try {
246: newDoc = (MaintenanceDocument) documentService
247: .getByDocumentHeaderId(documentId);
248: } catch (WorkflowException we) {
249: throw new RuntimeException(
250: "A WorkflowException was thrown which prevented the loading of "
251: + "the comparison document (" + documentId
252: + ")", we);
253: }
254:
255: if (ObjectUtils.isNotNull(newDoc)) {
256:
257: VendorDetail oldVDtl = (VendorDetail) (newDoc
258: .getOldMaintainableObject().getBusinessObject());
259: VendorHeader oldVHdr = oldVDtl.getVendorHeader();
260: VendorDetail newVDtl = (VendorDetail) (newDoc
261: .getNewMaintainableObject().getBusinessObject());
262: VendorHeader newVHdr = newVDtl.getVendorHeader();
263:
264: if ((ObjectUtils.isNotNull(oldVHdr))
265: && (ObjectUtils.isNotNull(oldVDtl))
266: && (ObjectUtils.isNotNull(newVHdr))
267: && (ObjectUtils.isNotNull(newVDtl))) {
268: shouldRoute = !(noRouteSignificantChangeOccurred(
269: newVDtl, newVHdr, oldVDtl, oldVHdr));
270: } else {
271: shouldRoute = true;
272: }
273: }
274: LOG.debug("Exiting shouldVendorRouteForApproval.");
275: return shouldRoute;
276: }
277:
278: /**
279: * @see org.kuali.module.vendor.service.VendorService#noRouteSignificantChangeOccurred(org.kuali.module.vendor.bo.VendorDetail,
280: * org.kuali.module.vendor.bo.VendorHeader, org.kuali.module.vendor.bo.VendorDetail,
281: * org.kuali.module.vendor.bo.VendorHeader)
282: */
283: public boolean noRouteSignificantChangeOccurred(
284: VendorDetail newVDtl, VendorHeader newVHdr,
285: VendorDetail oldVDtl, VendorHeader oldVHdr) {
286: LOG.debug("Entering noRouteSignificantChangeOccurred.");
287:
288: // The subcollections which are being compared here must implement VendorRoutingComparable.
289: boolean unchanged = ((oldVHdr.isEqualForRouting(newVHdr))
290: && (equalMemberLists(oldVHdr
291: .getVendorSupplierDiversities(), newVHdr
292: .getVendorSupplierDiversities()))
293: && (oldVDtl.isEqualForRouting(newVDtl))
294: && (equalMemberLists(oldVDtl.getVendorAddresses(),
295: newVDtl.getVendorAddresses()))
296: && (equalMemberLists(oldVDtl.getVendorContracts(),
297: newVDtl.getVendorContracts())) && (equalMemberLists(
298: oldVDtl.getVendorShippingSpecialConditions(), newVDtl
299: .getVendorShippingSpecialConditions())));
300:
301: LOG.debug("Exiting noRouteSignificantChangeOccurred.");
302: return unchanged;
303: }
304:
305: /**
306: * @see org.kuali.module.vendor.service.VendorService#equalMemberLists(java.util.List, java.util.List)
307: */
308: public boolean equalMemberLists(
309: List<? extends VendorRoutingComparable> list_a,
310: List<? extends VendorRoutingComparable> list_b) {
311: LOG.debug("Entering equalMemberLists.");
312: boolean result = true;
313: int listSize = list_a.size();
314: if (listSize != list_b.size()) {
315: LOG
316: .debug("Exiting equalMemberLists because list sizes are unequal.");
317: return false;
318: }
319: VendorRoutingComparable aMember = null;
320: for (int i = 0; i < listSize; i++) {
321: aMember = list_a.get(i);
322: if (!aMember.isEqualForRouting(list_b.get(i))) {
323: result = false;
324: break;
325: }
326: }
327: LOG.debug("Exiting equalMemberLists.");
328: return result;
329: }
330:
331: /**
332: * @see org.kuali.module.vendor.service.VendorService#isVendorInstitutionEmployee(java.lang.Integer)
333: */
334: public boolean isVendorInstitutionEmployee(
335: Integer vendorHeaderGeneratedIdentifier) {
336: VendorDetail vendorToUse = getParentVendor(vendorHeaderGeneratedIdentifier);
337: if (ObjectUtils.isNull(vendorToUse)) {
338: String errorMsg = "Vendor with header generated id '"
339: + vendorHeaderGeneratedIdentifier
340: + "' cannot be found in the system";
341: LOG.error(errorMsg);
342: throw new RuntimeException(errorMsg);
343: }
344: if (VendorConstants.TAX_TYPE_SSN.equals(vendorToUse
345: .getVendorHeader().getVendorTaxTypeCode())) {
346: String ssnTaxId = vendorToUse.getVendorHeader()
347: .getVendorTaxNumber();
348: if (StringUtils.isNotBlank(ssnTaxId)) {
349: try {
350: UniversalUser user = universalUserService
351: .getUniversalUser(new PersonTaxId(ssnTaxId));
352: return ObjectUtils.isNotNull(user);
353: } catch (UserNotFoundException e) {
354: // user is not in the system... assume non-employee
355: return false;
356: }
357: }
358: }
359: return false;
360: }
361:
362: /**
363: * @see org.kuali.module.vendor.service.VendorService#isVendorNonResidentAlien(java.lang.Integer)
364: */
365: public boolean isVendorForeign(
366: Integer vendorHeaderGeneratedIdentifier) {
367: VendorDetail vendorToUse = getParentVendor(vendorHeaderGeneratedIdentifier);
368: if (ObjectUtils.isNull(vendorToUse)) {
369: String errorMsg = "Vendor with header generated id '"
370: + vendorHeaderGeneratedIdentifier
371: + "' cannot be found in the system";
372: LOG.error(errorMsg);
373: throw new RuntimeException(errorMsg);
374: }
375: return vendorToUse.getVendorHeader()
376: .getVendorForeignIndicator();
377: }
378:
379: public void setUniversalUserService(
380: UniversalUserService universalUserService) {
381: this .universalUserService = universalUserService;
382: }
383:
384: public void setBusinessObjectService(BusinessObjectService boService) {
385: this .businessObjectService = boService;
386: }
387:
388: public void setDocumentService(DocumentService documentService) {
389: this .documentService = documentService;
390: }
391:
392: public void setPersistenceService(
393: PersistenceService persistenceService) {
394: this.persistenceService = persistenceService;
395: }
396: }
|