001: /*
002: * Copyright 2006-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.purap.service.impl;
017:
018: import java.util.Iterator;
019:
020: import org.apache.commons.lang.StringUtils;
021: import org.kuali.core.bo.Note;
022: import org.kuali.core.service.BusinessObjectService;
023: import org.kuali.core.service.DocumentService;
024: import org.kuali.core.util.KualiDecimal;
025: import org.kuali.core.util.ObjectUtils;
026: import org.kuali.kfs.KFSConstants;
027: import org.kuali.kfs.rule.event.DocumentSystemSaveEvent;
028: import org.kuali.module.purap.PurapConstants;
029: import org.kuali.module.purap.bo.RequisitionItem;
030: import org.kuali.module.purap.dao.RequisitionDao;
031: import org.kuali.module.purap.document.RequisitionDocument;
032: import org.kuali.module.purap.service.PurapService;
033: import org.kuali.module.purap.service.RequisitionService;
034: import org.kuali.module.vendor.bo.VendorDetail;
035: import org.springframework.transaction.annotation.Transactional;
036:
037: import edu.iu.uis.eden.exception.WorkflowException;
038:
039: /**
040: * Implementation of RequisitionService
041: */
042: @Transactional
043: public class RequisitionServiceImpl implements RequisitionService {
044: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
045: .getLogger(RequisitionServiceImpl.class);
046:
047: private BusinessObjectService businessObjectService;
048: private DocumentService documentService;
049: private PurapService purapService;
050: private RequisitionDao requisitionDao;
051:
052: /**
053: * @see org.kuali.module.purap.service.RequisitionService#saveDocumentWithoutValidation(org.kuali.module.purap.document.RequisitionDocument)
054: */
055: public void saveDocumentWithoutValidation(
056: RequisitionDocument document) {
057: try {
058: documentService.saveDocument(document,
059: DocumentSystemSaveEvent.class);
060: } catch (WorkflowException we) {
061: String errorMsg = "Error saving document # "
062: + document.getDocumentHeader().getDocumentNumber()
063: + " " + we.getMessage();
064: LOG.error(errorMsg, we);
065: throw new RuntimeException(errorMsg, we);
066: }
067: }
068:
069: /**
070: * @see org.kuali.module.purap.service.RequisitionService#getRequisitionById(java.lang.Integer)
071: */
072: public RequisitionDocument getRequisitionById(Integer id) {
073: String documentNumber = requisitionDao
074: .getDocumentNumberForRequisitionId(id);
075: if (ObjectUtils.isNotNull(documentNumber)) {
076: try {
077: RequisitionDocument doc = (RequisitionDocument) documentService
078: .getByDocumentHeaderId(documentNumber);
079:
080: return doc;
081: } catch (WorkflowException e) {
082: String errorMessage = "Error getting requisition document from document service";
083: LOG.error("getRequisitionById() " + errorMessage, e);
084: throw new RuntimeException(errorMessage, e);
085: }
086: }
087:
088: return null;
089: }
090:
091: /**
092: * @see org.kuali.module.purap.service.RequisitionService#isAutomaticPurchaseOrderAllowed(org.kuali.module.purap.document.RequisitionDocument)
093: */
094: public boolean isAutomaticPurchaseOrderAllowed(
095: RequisitionDocument requisition) {
096: LOG.debug("isAutomaticPurchaseOrderAllowed() started");
097:
098: /*
099: * The private checkAutomaticPurchaseOrderRules method contains rules to check if a requisition can become an APO (Automatic
100: * Purchase Order). The method returns a string containing the reason why this method should return false. Save the reason
101: * as a note on the requisition.
102: */
103: String note = checkAutomaticPurchaseOrderRules(requisition);
104: if (StringUtils.isNotEmpty(note)) {
105: note = PurapConstants.REQ_REASON_NOT_APO + note;
106: try {
107: Note apoNote = documentService.createNoteFromDocument(
108: requisition, note);
109: documentService.addNoteToDocument(requisition, apoNote);
110: } catch (Exception e) {
111: throw new RuntimeException(
112: PurapConstants.REQ_UNABLE_TO_CREATE_NOTE + " "
113: + e);
114: }
115: LOG
116: .debug("isAutomaticPurchaseOrderAllowed() return false; "
117: + note);
118:
119: return false;
120: }
121:
122: LOG
123: .debug("isAutomaticPurchaseOrderAllowed() You made it! Your REQ can become an APO; return true.");
124:
125: return true;
126: }
127:
128: /**
129: * Checks the rule for Automatic Purchase Order eligibility of the requisition and return a String containing the reason why the
130: * requisition was not eligible to become an APO if it was not eligible, or return an empty String if the requisition is
131: * eligible to become an APO
132: *
133: * @param requisition the requisition document to be checked for APO eligibility.
134: * @return String containing the reason why the requisition was not eligible to become an APO if it was not eligible, or an
135: * empty String if the requisition is eligible to become an APO.
136: */
137: private String checkAutomaticPurchaseOrderRules(
138: RequisitionDocument requisition) {
139: String requisitionSource = requisition
140: .getRequisitionSourceCode();
141: KualiDecimal reqTotal = requisition.getTotalDollarAmount();
142: KualiDecimal apoLimit = purapService.getApoLimit(requisition
143: .getVendorContractGeneratedIdentifier(), requisition
144: .getChartOfAccountsCode(), requisition
145: .getOrganizationCode());
146: requisition
147: .setOrganizationAutomaticPurchaseOrderLimit(apoLimit);
148:
149: LOG.debug("isAPO() reqId = "
150: + requisition.getPurapDocumentIdentifier()
151: + "; apoLimit = " + apoLimit + "; reqTotal = "
152: + reqTotal);
153: if (apoLimit == null) {
154:
155: return "APO limit is empty.";
156: } else {
157: if (reqTotal.compareTo(apoLimit) == 1) {
158:
159: return "Requisition total is greater than the APO limit.";
160: }
161: }
162:
163: if (reqTotal.compareTo(KFSConstants.ZERO) <= 0) {
164:
165: return "Requisition total is not greater than zero.";
166: }
167:
168: for (Iterator iter = requisition.getItems().iterator(); iter
169: .hasNext();) {
170: RequisitionItem item = (RequisitionItem) iter.next();
171: if (item.isItemRestrictedIndicator()) {
172:
173: return "Requisition contains an item that is marked as restricted.";
174: }
175: }// endfor items
176:
177: LOG
178: .debug("isAPO() vendor #"
179: + requisition
180: .getVendorHeaderGeneratedIdentifier()
181: + "-"
182: + requisition
183: .getVendorDetailAssignedIdentifier());
184: if (requisition.getVendorHeaderGeneratedIdentifier() == null
185: || requisition.getVendorDetailAssignedIdentifier() == null) {
186:
187: return "Vendor was not selected from the vendor database.";
188: } else {
189: VendorDetail vendorDetail = new VendorDetail();
190: vendorDetail.setVendorHeaderGeneratedIdentifier(requisition
191: .getVendorHeaderGeneratedIdentifier());
192: vendorDetail.setVendorDetailAssignedIdentifier(requisition
193: .getVendorDetailAssignedIdentifier());
194: vendorDetail = (VendorDetail) businessObjectService
195: .retrieve(vendorDetail);
196: if (vendorDetail == null) {
197:
198: return "Error retrieving vendor from the database.";
199: }
200:
201: requisition.setVendorRestrictedIndicator(vendorDetail
202: .getVendorRestrictedIndicator());
203: if (requisition.getVendorRestrictedIndicator() != null
204: && requisition.getVendorRestrictedIndicator()) {
205:
206: return "Selected vendor is marked as restricted.";
207: }
208: }
209:
210: if (StringUtils.isNotEmpty(requisition
211: .getRecurringPaymentTypeCode())) {
212:
213: return "Payment type is marked as recurring.";
214: }
215:
216: if ((requisition.getPurchaseOrderTotalLimit() != null)
217: && (KFSConstants.ZERO.compareTo(requisition
218: .getPurchaseOrderTotalLimit()) != 0)) {
219: LOG
220: .debug("isAPO() po total limit is not null and not equal to zero; return false.");
221:
222: return "The 'PO not to exceed' amount has been entered.";
223: }
224:
225: if (StringUtils.isNotEmpty(requisition
226: .getAlternate1VendorName())
227: || StringUtils.isNotEmpty(requisition
228: .getAlternate2VendorName())
229: || StringUtils.isNotEmpty(requisition
230: .getAlternate3VendorName())
231: || StringUtils.isNotEmpty(requisition
232: .getAlternate4VendorName())
233: || StringUtils.isNotEmpty(requisition
234: .getAlternate5VendorName())) {
235: LOG
236: .debug("isAPO() alternate vendor name exists; return false.");
237:
238: return "Requisition contains alternate vendor names.";
239: }
240:
241: return "";
242: }
243:
244: public void setBusinessObjectService(BusinessObjectService boService) {
245: this .businessObjectService = boService;
246: }
247:
248: public void setDocumentService(DocumentService documentService) {
249: this .documentService = documentService;
250: }
251:
252: public void setRequisitionDao(RequisitionDao requisitionDao) {
253: this .requisitionDao = requisitionDao;
254: }
255:
256: public void setPurapService(PurapService purapService) {
257: this.purapService = purapService;
258: }
259:
260: }
|