001/* 002 * Copyright 2006 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 */ 016package org.kuali.ole.module.purap.document.service.impl; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.ole.integration.cab.CapitalAssetBuilderModuleService; 020import org.kuali.ole.integration.purap.CapitalAssetSystem; 021import org.kuali.ole.module.purap.PurapConstants; 022import org.kuali.ole.module.purap.PurapPropertyConstants; 023import org.kuali.ole.module.purap.PurapRuleConstants; 024import org.kuali.ole.module.purap.businessobject.*; 025import org.kuali.ole.module.purap.document.PurchaseOrderDocument; 026import org.kuali.ole.module.purap.document.PurchasingDocument; 027import org.kuali.ole.module.purap.document.RequisitionDocument; 028import org.kuali.ole.module.purap.document.dataaccess.RequisitionDao; 029import org.kuali.ole.module.purap.document.service.PurapService; 030import org.kuali.ole.module.purap.document.service.RequisitionService; 031import org.kuali.ole.select.businessobject.OlePurchaseOrderItem; 032import org.kuali.ole.select.businessobject.OleRequisitionItem; 033import org.kuali.ole.select.document.OleRequisitionDocument; 034import org.kuali.ole.sys.context.SpringContext; 035import org.kuali.ole.sys.service.PostalCodeValidationService; 036import org.kuali.ole.sys.service.UniversityDateService; 037import org.kuali.ole.vnd.businessobject.VendorCommodityCode; 038import org.kuali.ole.vnd.businessobject.VendorContract; 039import org.kuali.ole.vnd.businessobject.VendorDetail; 040import org.kuali.ole.vnd.document.service.VendorService; 041import org.kuali.rice.core.api.config.property.ConfigurationService; 042import org.kuali.rice.core.api.datetime.DateTimeService; 043import org.kuali.rice.core.api.util.type.KualiDecimal; 044import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator; 045import org.kuali.rice.coreservice.framework.parameter.ParameterService; 046import org.kuali.rice.kew.actiontaken.ActionTakenValue; 047import org.kuali.rice.kew.api.KewApiServiceLocator; 048import org.kuali.rice.kew.api.document.DocumentStatus; 049import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria; 050import org.kuali.rice.kew.api.document.search.DocumentSearchResult; 051import org.kuali.rice.kew.api.document.search.DocumentSearchResults; 052import org.kuali.rice.kew.api.exception.WorkflowException; 053import org.kuali.rice.kew.service.KEWServiceLocator; 054import org.kuali.rice.kim.api.identity.Person; 055import org.kuali.rice.kim.api.identity.PersonService; 056import org.kuali.rice.krad.bo.Note; 057import org.kuali.rice.krad.service.BusinessObjectService; 058import org.kuali.rice.krad.service.DocumentService; 059import org.kuali.rice.krad.service.KualiRuleService; 060import org.kuali.rice.krad.service.SequenceAccessorService; 061import org.kuali.rice.krad.util.ObjectUtils; 062import org.springframework.transaction.annotation.Transactional; 063 064import java.math.BigDecimal; 065import java.util.*; 066 067 068/** 069 * Implementation of RequisitionService 070 */ 071@Transactional 072public class RequisitionServiceImpl implements RequisitionService { 073 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RequisitionServiceImpl.class); 074 075 private BusinessObjectService businessObjectService; 076 private CapitalAssetBuilderModuleService capitalAssetBuilderModuleService; 077 private DateTimeService dateTimeService; 078 private DocumentService documentService; 079 private KualiRuleService ruleService; 080 private ConfigurationService kualiConfigurationService; 081 private ParameterService parameterService; 082 private PersonService personService; 083 private PostalCodeValidationService postalCodeValidationService; 084 private PurapService purapService; 085 private RequisitionDao requisitionDao; 086 private UniversityDateService universityDateService; 087 private VendorService vendorService; 088 089 @Override 090 public PurchasingCapitalAssetItem createCamsItem(PurchasingDocument purDoc, PurApItem purapItem) { 091 PurchasingCapitalAssetItem camsItem = new RequisitionCapitalAssetItem(); 092 camsItem.setItemIdentifier(purapItem.getItemIdentifier()); 093 // If the system type is INDIVIDUAL then for each of the capital asset items, we need a system attached to it. 094 if (purDoc.getCapitalAssetSystemTypeCode().equals(PurapConstants.CapitalAssetTabStrings.INDIVIDUAL_ASSETS)) { 095 CapitalAssetSystem resultSystem = new RequisitionCapitalAssetSystem(); 096 camsItem.setPurchasingCapitalAssetSystem(resultSystem); 097 } 098 camsItem.setPurchasingDocument(purDoc); 099 100 return camsItem; 101 } 102 103 @Override 104 public CapitalAssetSystem createCapitalAssetSystem() { 105 CapitalAssetSystem resultSystem = new RequisitionCapitalAssetSystem(); 106 return resultSystem; 107 } 108 109 /** 110 * @see org.kuali.ole.module.purap.document.service.RequisitionService#getRequisitionById(java.lang.Integer) 111 */ 112 @Override 113 public RequisitionDocument getRequisitionById(Integer id) { 114 String documentNumber = requisitionDao.getDocumentNumberForRequisitionId(id); 115 if (ObjectUtils.isNotNull(documentNumber)) { 116 try { 117 RequisitionDocument doc = (RequisitionDocument) documentService.getByDocumentHeaderId(documentNumber); 118 119 return doc; 120 } catch (WorkflowException e) { 121 String errorMessage = "Error getting requisition document from document service"; 122 LOG.error("getRequisitionById() " + errorMessage, e); 123 throw new RuntimeException(errorMessage, e); 124 } 125 } 126 127 return null; 128 } 129 130 private boolean isReqCreatedByPo(String routeHeaderId) { 131 List<ActionTakenValue> result = (List<ActionTakenValue>) KEWServiceLocator.getActionTakenService().getActionsTaken(routeHeaderId); 132 if (result != null && result.size() > 0) { 133 for (ActionTakenValue val : result) { 134 if (val.getAnnotation() != null && 135 val.getAnnotation().trim().equals("Automatic Approval From PO")) { 136 return true; 137 } 138 } 139 } 140 return false; 141 } 142 143 /** 144 * @see org.kuali.ole.module.purap.document.service.RequisitionService#isAutomaticPurchaseOrderAllowed(org.kuali.ole.module.purap.document.RequisitionDocument) 145 */ 146 @Override 147 public boolean isAutomaticPurchaseOrderAllowed(RequisitionDocument requisition) { 148 LOG.debug("isAutomaticPurchaseOrderAllowed() started"); 149 150 /* 151 * The private checkAutomaticPurchaseOrderRules method contains rules to check if a requisition can become an APO (Automatic 152 * Purchase Order). The method returns a string containing the reason why this method should return false. Save the reason 153 * as a note on the requisition. 154 */ 155 String note = checkAutomaticPurchaseOrderRules(requisition); 156 if (StringUtils.isNotEmpty(note)) { 157 note = PurapConstants.REQ_REASON_NOT_APO + note; 158 try { 159 Note apoNote = documentService.createNoteFromDocument(requisition, note); 160 requisition.addNote(apoNote); 161 documentService.saveDocumentNotes(requisition); 162 } catch (Exception e) { 163 throw new RuntimeException(PurapConstants.REQ_UNABLE_TO_CREATE_NOTE + " " + e); 164 } 165 166 if (LOG.isDebugEnabled()) { 167 LOG.debug("isAutomaticPurchaseOrderAllowed() return false; " + note); 168 } 169 return false; 170 } 171 172 LOG.debug("isAutomaticPurchaseOrderAllowed() You made it! Your REQ can become an APO; return true."); 173 return true; 174 } 175 176 public Collection<String> getAPORules() { 177 return CoreFrameworkServiceLocator.getParameterService().getParameterValuesAsString( 178 PurchaseOrderDocument.class, "APORules"); 179 } 180 181 /** 182 * Checks the rule for Automatic Purchase Order eligibility of the requisition and return a String containing the reason why the 183 * requisition was not eligible to become an APO if it was not eligible, or return an empty String if the requisition is 184 * eligible to become an APO 185 * 186 * @param requisition the requisition document to be checked for APO eligibility. 187 * @return String containing the reason why the requisition was not eligible to become an APO if it was not eligible, or an 188 * empty String if the requisition is eligible to become an APO. 189 */ 190 protected String checkAutomaticPurchaseOrderRules(RequisitionDocument requisition) { 191 Collection<String> APORules = getAPORules(); 192 String requisitionSource = requisition.getRequisitionSourceCode(); 193 KualiDecimal reqTotal = requisition.getTotalDollarAmount(); 194 KualiDecimal apoLimit = purapService.getApoLimit(requisition.getVendorContractGeneratedIdentifier(), requisition.getChartOfAccountsCode(), requisition.getOrganizationCode()); 195 requisition.setOrganizationAutomaticPurchaseOrderLimit(apoLimit); 196 197 if (LOG.isDebugEnabled()) { 198 LOG.debug("isAPO() reqId = " + requisition.getPurapDocumentIdentifier() + "; apoLimit = " + apoLimit + "; reqTotal = " + reqTotal); 199 } 200 if (apoLimit == null) { 201 return "APO limit is empty."; 202 } else { 203 if (APORules.contains(PurapConstants.APO_LIMIT)) { 204 if (reqTotal.compareTo(apoLimit) == 1) { 205 return "Requisition total is greater than the APO limit."; 206 } 207 } 208 } 209 /* if (APORules.contains(PurapConstants.REQ_TOT)) { 210 if (reqTotal.compareTo(KualiDecimal.ZERO) <= 0) { 211 return "Requisition total is not greater than zero."; 212 } 213 }*/ 214 215 if (this.isReqCreatedByPo(requisition.getDocumentNumber())) { 216 return "Requsiusion is created by PO"; 217 } 218 219 LOG.debug("isAPO() vendor #" + requisition.getVendorHeaderGeneratedIdentifier() + "-" + requisition.getVendorDetailAssignedIdentifier()); 220 if (APORules.contains(PurapConstants.VEN_NOT_SEL)) { 221 if (requisition.getVendorHeaderGeneratedIdentifier() == null || requisition.getVendorDetailAssignedIdentifier() == null) { 222 return "Vendor was not selected from the vendor database."; 223 } 224 } else { 225 VendorDetail vendorDetail = vendorService.getVendorDetail(requisition.getVendorHeaderGeneratedIdentifier(), requisition.getVendorDetailAssignedIdentifier()); 226 if (APORules.contains(PurapConstants.ERR_RTV_VENDOR)) { 227 if (vendorDetail == null) { 228 return "Error retrieving vendor from the database."; 229 } 230 } 231 if (StringUtils.isBlank(requisition.getVendorLine1Address()) || 232 StringUtils.isBlank(requisition.getVendorCityName()) || 233 StringUtils.isBlank(requisition.getVendorCountryCode())) { 234 return "Requisition does not have all of the vendor address fields that are required for Purchase Order."; 235 } 236 requisition.setVendorRestrictedIndicator(vendorDetail.getVendorRestrictedIndicator()); 237 if (APORules.contains(PurapConstants.VENDOR_RESTRICTED)) { 238 if (requisition.getVendorRestrictedIndicator() != null && requisition.getVendorRestrictedIndicator()) { 239 return "Selected vendor is marked as restricted."; 240 } 241 if (vendorDetail.isVendorDebarred()) { 242 return "Selected vendor is marked as a debarred vendor"; 243 } 244 requisition.setVendorDetail(vendorDetail); 245 246 if ((!PurapConstants.RequisitionSources.B2B.equals(requisitionSource)) && ObjectUtils.isNull(requisition.getVendorContractGeneratedIdentifier())) { 247 Person initiator = getPersonService().getPerson(requisition.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId()); 248 VendorContract b2bContract = vendorService.getVendorB2BContract(vendorDetail, initiator.getCampusCode()); 249 if (APORules.contains(PurapConstants.REQ_WITH_NO_CONTRACT)) { 250 if (b2bContract != null) { 251 return "Standard requisition with no contract selected but a B2B contract exists for the selected vendor."; 252 } 253 } 254 } 255 } 256 257 //if vendor address isn't complete, no APO 258 if (StringUtils.isBlank(requisition.getVendorLine1Address()) || 259 StringUtils.isBlank(requisition.getVendorCityName()) || 260 StringUtils.isBlank(requisition.getVendorCountryCode()) || 261 !postalCodeValidationService.validateAddress(requisition.getVendorCountryCode(), requisition.getVendorStateCode(), requisition.getVendorPostalCode(), "", "")) { 262 return "Requistion does not contain a complete vendor address"; 263 } 264 265 // These are needed for commodity codes. They are put in here so that 266 // we don't have to loop through items too many times. 267 String purchaseOrderRequiresCommodityCode = parameterService.getParameterValueAsString(PurchaseOrderDocument.class, PurapRuleConstants.ITEMS_REQUIRE_COMMODITY_CODE_IND); 268 boolean commodityCodeRequired = purchaseOrderRequiresCommodityCode.equals("Y"); 269 270 for (Iterator iter = requisition.getItems().iterator(); iter.hasNext(); ) { 271 RequisitionItem item = (RequisitionItem) iter.next(); 272 if (APORules.contains(PurapConstants.ITM_RESTRICTED)) { 273 if (item.isItemRestrictedIndicator()) { 274 return "Requisition contains an item that is marked as restricted."; 275 } 276 } 277 278 //We only need to check the commodity codes if this is an above the line item. 279 if (item.getItemType().isLineItemIndicator()) { 280 String commodityCodesReason = ""; 281 List<VendorCommodityCode> vendorCommodityCodes = commodityCodeRequired ? requisition.getVendorDetail().getVendorCommodities() : null; 282 commodityCodesReason = checkAPORulesPerItemForCommodityCodes(item, vendorCommodityCodes, commodityCodeRequired); 283 if (StringUtils.isNotBlank(commodityCodesReason)) { 284 return commodityCodesReason; 285 } 286 } 287 288 if (PurapConstants.ItemTypeCodes.ITEM_TYPE_ORDER_DISCOUNT_CODE.equals(item.getItemType().getItemTypeCode()) 289 || PurapConstants.ItemTypeCodes.ITEM_TYPE_TRADE_IN_CODE.equals(item.getItemType().getItemTypeCode())) { 290 if (APORules.contains(PurapConstants.REQ_CON_TRADEIN)) { 291 if ((item.getItemUnitPrice() != null) && ((BigDecimal.ZERO.compareTo(item.getItemUnitPrice())) != 0)) { 292 // discount or trade-in item has unit price that is not empty or zero 293 return "Requisition contains a " + item.getItemType().getItemTypeDescription() + " item, so it does not qualify as an APO."; 294 } 295 } 296 } 297 if (APORules.contains(PurapConstants.REQ_CON_ACC_LINE)) { 298 if (!PurapConstants.RequisitionSources.B2B.equals(requisitionSource)) { 299 for (PurApAccountingLine accountingLine : item.getSourceAccountingLines()) { 300 if (capitalAssetBuilderModuleService.doesAccountingLineFailAutomaticPurchaseOrderRules(accountingLine)) { 301 return "Requisition contains accounting line with capital object level"; 302 } 303 } 304 } 305 } 306 } 307 308 }// endfor items 309 if (APORules.contains(PurapConstants.RECUR_REQ_TYPE)) { 310 if (capitalAssetBuilderModuleService.doesDocumentFailAutomaticPurchaseOrderRules(requisition)) { 311 return "Requisition contains capital asset items."; 312 } 313 } 314 if (APORules.contains(PurapConstants.RECUR_PAY_TYPE)) { 315 if (StringUtils.isNotEmpty(requisition.getRecurringPaymentTypeCode())) { 316 return "Payment type is marked as recurring."; 317 } 318 } 319 if (APORules.contains(PurapConstants.PO_TOT_NOT_EXCEED)) { 320 if ((requisition.getPurchaseOrderTotalLimit() != null) && (KualiDecimal.ZERO.compareTo(requisition.getPurchaseOrderTotalLimit()) != 0)) { 321 LOG.debug("isAPO() po total limit is not null and not equal to zero; return false."); 322 return "The 'PO not to exceed' amount has been entered."; 323 } 324 } 325 if (APORules.contains(new String("ALT_VEN_NAM"))) { 326 if (StringUtils.isNotEmpty(requisition.getAlternate1VendorName()) || StringUtils.isNotEmpty(requisition.getAlternate2VendorName()) || StringUtils.isNotEmpty(requisition.getAlternate3VendorName()) || StringUtils.isNotEmpty(requisition.getAlternate4VendorName()) || StringUtils.isNotEmpty(requisition.getAlternate5VendorName())) { 327 LOG.debug("isAPO() alternate vendor name exists; return false."); 328 return "Requisition contains additional suggested vendor names."; 329 } 330 } 331 if (APORules.contains(PurapConstants.ALT_VEN_NAME_EXISTS)) { 332 if (requisition.isPostingYearNext() && !purapService.isTodayWithinApoAllowedRange()) { 333 return "Requisition is set to encumber next fiscal year and approval is not within APO allowed date range."; 334 } 335 } 336 337 return ""; 338 } 339 340 /** 341 * Checks the APO rules for Commodity Codes. 342 * The rules are as follow: 343 * 1. If an institution does not require a commodity code on a requisition but 344 * does require a commodity code on a purchase order: 345 * a. If the requisition qualifies for an APO and the commodity code is blank 346 * on any line item then the system should use the default commodity code 347 * for the vendor. 348 * b. If there is not a default commodity code for the vendor then the 349 * requisition is not eligible to become an APO. 350 * 2. The commodity codes where the restricted indicator is Y should disallow 351 * the requisition from becoming an APO. 352 * 3. If the commodity code is Inactive when the requisition is finally approved 353 * do not allow the requisition to become an APO. 354 * 355 * @param purItem 356 * @param vendorCommodityCodes 357 * @param commodityCodeRequired 358 * @return 359 */ 360 protected String checkAPORulesPerItemForCommodityCodes(RequisitionItem purItem, List<VendorCommodityCode> vendorCommodityCodes, boolean commodityCodeRequired) { 361 // If the commodity code is blank on any line item and a commodity code is required, 362 // then the system should use the default commodity code for the vendor 363 if (purItem.getCommodityCode() == null && commodityCodeRequired) { 364 for (VendorCommodityCode vcc : vendorCommodityCodes) { 365 if (vcc.isCommodityDefaultIndicator()) { 366 purItem.setCommodityCode(vcc.getCommodityCode()); 367 purItem.setPurchasingCommodityCode(vcc.getPurchasingCommodityCode()); 368 } 369 } 370 } 371 if (purItem.getCommodityCode() == null) { 372 // If there is not a default commodity code for the vendor then the requisition is not eligible to become an APO. 373 if (commodityCodeRequired) { 374 return "There are missing commodity code(s)."; 375 } 376 } else if (!purItem.getCommodityCode().isActive()) { 377 return "Requisition contains inactive commodity codes."; 378 } else if (purItem.getCommodityCode().isRestrictedItemsIndicator()) { 379 return "Requisition contains an item with a restricted commodity code."; 380 } 381 return ""; 382 } 383 384 /** 385 * @see org.kuali.ole.module.purap.document.service.RequisitionService#getRequisitionsAwaitingContractManagerAssignment() 386 */ 387 @Override 388 public List<RequisitionDocument> getRequisitionsAwaitingContractManagerAssignment() { 389 List<RequisitionDocument> unassignedRequisitions = new ArrayList<RequisitionDocument>(); 390 List<RequisitionDocument> requisitions = new ArrayList<RequisitionDocument>(); 391 392 List<String> documentsNumbersAwaitingContractManagerAssignment = getDocumentsNumbersAwaitingContractManagerAssignment(); 393 394 for (String documentNumber : documentsNumbersAwaitingContractManagerAssignment) { 395 Map fieldValues = new HashMap(); 396 fieldValues.put(PurapPropertyConstants.DOCUMENT_NUMBER, documentNumber); 397 398 requisitions = (List<RequisitionDocument>) businessObjectService.findMatching(RequisitionDocument.class, fieldValues); 399 400 for (RequisitionDocument req : requisitions) { 401 unassignedRequisitions.add(req); 402 } 403 } 404 405 return unassignedRequisitions; 406 } 407 408 /** 409 * Gets a list of strings of document numbers from workflow documents where 410 * document status = 'P', 'F' and document type = 'REQS'. If appDocStatus status 411 * of 'Awaiting Contract Manager Assignment' then the document number is added to the list 412 * <p/> 413 * NOTE: simplify using DocSearch lookup with AppDocStatus 414 * 415 * @return list of documentNumbers to retrieve requisitions. 416 */ 417 protected List<String> getDocumentsNumbersAwaitingContractManagerAssignment() { 418 List<String> requisitionDocumentNumbers = new ArrayList<String>(); 419 420 DocumentSearchCriteria.Builder documentSearchCriteriaDTO = DocumentSearchCriteria.Builder.create(); 421 //Search for status of P and F and "Awaiting Contract Manager Assignment" application document status 422 documentSearchCriteriaDTO.setDocumentStatuses(Arrays.asList(DocumentStatus.PROCESSED, DocumentStatus.FINAL)); 423 documentSearchCriteriaDTO.setDocumentTypeName(PurapConstants.REQUISITION_DOCUMENT_TYPE); 424 documentSearchCriteriaDTO.setApplicationDocumentStatus(PurapConstants.RequisitionStatuses.APPDOC_AWAIT_CONTRACT_MANAGER_ASSGN); 425 documentSearchCriteriaDTO.setSaveName(null); 426 427 DocumentSearchResults results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(null, documentSearchCriteriaDTO.build()); 428 429 String documentHeaderId = null; 430 431 for (DocumentSearchResult result : results.getSearchResults()) { 432 requisitionDocumentNumbers.add(result.getDocument().getDocumentId()); 433 } 434 435 return requisitionDocumentNumbers; 436 } 437 438 /** 439 * @see org.kuali.ole.module.purap.document.service.RequisitionService#getCountOfRequisitionsAwaitingContractManagerAssignment() 440 */ 441 @Override 442 public int getCountOfRequisitionsAwaitingContractManagerAssignment() { 443 List<RequisitionDocument> unassignedRequisitions = getRequisitionsAwaitingContractManagerAssignment(); 444 if (ObjectUtils.isNotNull(unassignedRequisitions)) { 445 return unassignedRequisitions.size(); 446 } else { 447 return 0; 448 } 449 } 450 451 /** 452 * Create Purchase Order and populate with data from Purchase Order and other default data 453 * 454 * @param reqDocument The requisition document from which we create the purchase order document. 455 * @return The purchase order document created by this method. 456 * @throws WorkflowException 457 */ 458 @Override 459 public OleRequisitionDocument generateRequisitionFromPurchaseOrder(PurchaseOrderDocument purDocument) throws WorkflowException { 460 461 OleRequisitionDocument rdoc = null; 462 rdoc = (OleRequisitionDocument) documentService.getNewDocument("OLE_REQS"); 463 rdoc = populateRequisitionFromPurchaseOrder(rdoc, purDocument); 464 465// rdoc.setStatusCode(PurchaseOrderStatuses.IN_PROCESS); 466 if (ObjectUtils.isNotNull(purDocument.getVendorContract())) { 467 rdoc.setVendorPaymentTermsCode(purDocument.getVendorContract().getVendorPaymentTermsCode()); 468 rdoc.setVendorShippingPaymentTermsCode(purDocument.getVendorContract().getVendorShippingPaymentTermsCode()); 469 rdoc.setVendorShippingTitleCode(purDocument.getVendorContract().getVendorShippingTitleCode()); 470 } else { 471 VendorDetail vendor = vendorService.getVendorDetail(purDocument.getVendorHeaderGeneratedIdentifier(), purDocument.getVendorDetailAssignedIdentifier()); 472 if (ObjectUtils.isNotNull(vendor)) { 473 rdoc.setVendorPaymentTermsCode(vendor.getVendorPaymentTermsCode()); 474 rdoc.setVendorShippingPaymentTermsCode(vendor.getVendorShippingPaymentTermsCode()); 475 rdoc.setVendorShippingTitleCode(vendor.getVendorShippingTitleCode()); 476 } 477 } 478 479 if (!PurapConstants.RequisitionSources.B2B.equals(purDocument.getRequisitionSourceCode())) { 480 purapService.addBelowLineItems(rdoc); 481 } 482 // rdoc.fixItemReferences(); 483 484 return rdoc; 485 } 486 487 488 public OleRequisitionDocument populateRequisitionFromPurchaseOrder(OleRequisitionDocument requisitionDocument, PurchaseOrderDocument pdoc) { 489 490 requisitionDocument.getDocumentHeader().setOrganizationDocumentNumber(pdoc.getDocumentHeader().getOrganizationDocumentNumber()); 491 requisitionDocument.getDocumentHeader().setDocumentDescription(pdoc.getDocumentHeader().getDocumentDescription()); 492 requisitionDocument.getDocumentHeader().setExplanation(pdoc.getDocumentHeader().getExplanation()); 493 494 requisitionDocument.setBillingName(pdoc.getBillingName()); 495 requisitionDocument.setBillingLine1Address(pdoc.getBillingLine1Address()); 496 requisitionDocument.setBillingLine2Address(pdoc.getBillingLine2Address()); 497 requisitionDocument.setBillingCityName(pdoc.getBillingCityName()); 498 requisitionDocument.setBillingStateCode(pdoc.getBillingStateCode()); 499 requisitionDocument.setBillingPostalCode(pdoc.getBillingPostalCode()); 500 requisitionDocument.setBillingCountryCode(pdoc.getBillingCountryCode()); 501 requisitionDocument.setBillingPhoneNumber(pdoc.getBillingPhoneNumber()); 502 503 requisitionDocument.setReceivingName(pdoc.getReceivingName()); 504 requisitionDocument.setReceivingCityName(pdoc.getReceivingCityName()); 505 requisitionDocument.setReceivingLine1Address(pdoc.getReceivingLine1Address()); 506 requisitionDocument.setReceivingLine2Address(pdoc.getReceivingLine2Address()); 507 requisitionDocument.setReceivingStateCode(pdoc.getReceivingStateCode()); 508 requisitionDocument.setReceivingPostalCode(pdoc.getReceivingPostalCode()); 509 requisitionDocument.setReceivingCountryCode(pdoc.getReceivingCountryCode()); 510 requisitionDocument.setAddressToVendorIndicator(pdoc.getAddressToVendorIndicator()); 511 512 requisitionDocument.setDeliveryBuildingCode(pdoc.getDeliveryBuildingCode()); 513 requisitionDocument.setDeliveryBuildingRoomNumber(pdoc.getDeliveryBuildingRoomNumber()); 514 requisitionDocument.setDeliveryBuildingName(pdoc.getDeliveryBuildingName()); 515 requisitionDocument.setDeliveryCampusCode(pdoc.getDeliveryCampusCode()); 516 requisitionDocument.setDeliveryCityName(pdoc.getDeliveryCityName()); 517 requisitionDocument.setDeliveryCountryCode(pdoc.getDeliveryCountryCode()); 518 requisitionDocument.setDeliveryInstructionText(pdoc.getDeliveryInstructionText()); 519 requisitionDocument.setDeliveryBuildingLine1Address(pdoc.getDeliveryBuildingLine1Address()); 520 requisitionDocument.setDeliveryBuildingLine2Address(pdoc.getDeliveryBuildingLine2Address()); 521 requisitionDocument.setDeliveryPostalCode(pdoc.getDeliveryPostalCode()); 522 requisitionDocument.setDeliveryRequiredDate(pdoc.getDeliveryRequiredDate()); 523 requisitionDocument.setDeliveryRequiredDateReasonCode(pdoc.getDeliveryRequiredDateReasonCode()); 524 requisitionDocument.setDeliveryStateCode(pdoc.getDeliveryStateCode()); 525 requisitionDocument.setDeliveryToEmailAddress(pdoc.getDeliveryToEmailAddress()); 526 requisitionDocument.setDeliveryToName(pdoc.getDeliveryToName()); 527 requisitionDocument.setDeliveryToPhoneNumber(pdoc.getDeliveryToPhoneNumber()); 528 requisitionDocument.setDeliveryBuildingOtherIndicator(pdoc.isDeliveryBuildingOtherIndicator()); 529 530 requisitionDocument.setPurchaseOrderBeginDate(pdoc.getPurchaseOrderBeginDate()); 531 requisitionDocument.setPurchaseOrderCostSourceCode(pdoc.getPurchaseOrderCostSourceCode()); 532 requisitionDocument.setPostingYear(pdoc.getPostingYear()); 533 requisitionDocument.setPurchaseOrderEndDate(pdoc.getPurchaseOrderEndDate()); 534 requisitionDocument.setChartOfAccountsCode(pdoc.getChartOfAccountsCode()); 535 requisitionDocument.setDocumentFundingSourceCode(pdoc.getDocumentFundingSourceCode()); 536 requisitionDocument.setInstitutionContactEmailAddress(pdoc.getInstitutionContactEmailAddress()); 537 requisitionDocument.setInstitutionContactName(pdoc.getInstitutionContactName()); 538 requisitionDocument.setInstitutionContactPhoneNumber(pdoc.getInstitutionContactPhoneNumber()); 539 requisitionDocument.setNonInstitutionFundAccountNumber(pdoc.getNonInstitutionFundAccountNumber()); 540 requisitionDocument.setNonInstitutionFundChartOfAccountsCode(pdoc.getNonInstitutionFundChartOfAccountsCode()); 541 requisitionDocument.setNonInstitutionFundOrgChartOfAccountsCode(pdoc.getNonInstitutionFundOrgChartOfAccountsCode()); 542 requisitionDocument.setNonInstitutionFundOrganizationCode(pdoc.getNonInstitutionFundOrganizationCode()); 543 requisitionDocument.setOrganizationCode(pdoc.getOrganizationCode()); 544 requisitionDocument.setRecurringPaymentTypeCode(pdoc.getRecurringPaymentTypeCode()); 545 requisitionDocument.setRequestorPersonEmailAddress(pdoc.getRequestorPersonEmailAddress()); 546 requisitionDocument.setRequestorPersonName(pdoc.getRequestorPersonName()); 547 requisitionDocument.setRequestorPersonPhoneNumber(pdoc.getRequestorPersonPhoneNumber()); 548// requisitionDocument.setPurapDocumentIdentifier(pdoc.getRequisitionIdentifier()); 549 requisitionDocument.setPurchaseOrderTotalLimit(pdoc.getPurchaseOrderTotalLimit()); 550 requisitionDocument.setPurchaseOrderTransmissionMethodCode(pdoc.getPurchaseOrderTransmissionMethodCode()); 551 requisitionDocument.setUseTaxIndicator(pdoc.isUseTaxIndicator()); 552 requisitionDocument.setPurchaseOrderTypeId(pdoc.getPurchaseOrderTypeId()); 553 /*requisitionDocument.setLicensingRequirementIndicator(pdoc.isLicensingRequirementIndicator());*/ 554 /*requisitionDocument.setLicensingRequirementCode(pdoc.getLicensingRequirementCode());*/ 555 requisitionDocument.setVendorCityName(pdoc.getVendorCityName()); 556 requisitionDocument.setVendorContractGeneratedIdentifier(pdoc.getVendorContractGeneratedIdentifier()); 557 requisitionDocument.setVendorCountryCode(pdoc.getVendorCountryCode()); 558 requisitionDocument.setVendorCustomerNumber(pdoc.getVendorCustomerNumber()); 559 requisitionDocument.setVendorAttentionName(pdoc.getVendorAttentionName()); 560 requisitionDocument.setVendorDetailAssignedIdentifier(pdoc.getVendorDetailAssignedIdentifier()); 561 requisitionDocument.setVendorFaxNumber(pdoc.getVendorFaxNumber()); 562 requisitionDocument.setVendorHeaderGeneratedIdentifier(pdoc.getVendorHeaderGeneratedIdentifier()); 563 requisitionDocument.setVendorLine1Address(pdoc.getVendorLine1Address()); 564 requisitionDocument.setVendorLine2Address(pdoc.getVendorLine2Address()); 565 requisitionDocument.setVendorAddressInternationalProvinceName(pdoc.getVendorAddressInternationalProvinceName()); 566 requisitionDocument.setVendorName(pdoc.getVendorName()); 567 requisitionDocument.setVendorNoteText(pdoc.getVendorNoteText()); 568 requisitionDocument.setVendorPhoneNumber(pdoc.getVendorPhoneNumber()); 569 requisitionDocument.setVendorPostalCode(pdoc.getVendorPostalCode()); 570 requisitionDocument.setVendorStateCode(pdoc.getVendorStateCode()); 571 requisitionDocument.setVendorRestrictedIndicator(pdoc.getVendorRestrictedIndicator()); 572 573 requisitionDocument.setExternalOrganizationB2bSupplierIdentifier(pdoc.getExternalOrganizationB2bSupplierIdentifier()); 574 requisitionDocument.setRequisitionSourceCode(pdoc.getRequisitionSourceCode()); 575 requisitionDocument.setAccountsPayablePurchasingDocumentLinkIdentifier(pdoc.getAccountsPayablePurchasingDocumentLinkIdentifier()); 576 requisitionDocument.setReceivingDocumentRequiredIndicator(pdoc.isReceivingDocumentRequiredIndicator()); 577 requisitionDocument.setPaymentRequestPositiveApprovalIndicator(pdoc.isPaymentRequestPositiveApprovalIndicator()); 578 /*requisitionDocument.setLicensingRequirementIndicator(pdoc.isLicensingRequirementIndicator());*/ 579 /*requisitionDocument.setLicensingRequirementCode(pdoc.getLicensingRequirementCode());*/ 580 581// requisitionDocument.setStatusCode(PurapConstants.PurchaseOrderStatuses.IN_PROCESS); 582 583 // Copy items from requisition (which will copy the item's accounts and capital assets) 584 List<OleRequisitionItem> items = new ArrayList(); 585 for (OlePurchaseOrderItem reqItem : (List<OlePurchaseOrderItem>) pdoc.getItems()) { 586 PurchasingCapitalAssetItem reqCamsItem = null; 587 OleRequisitionItem ritem = getRequisitionItem(reqItem, requisitionDocument, reqCamsItem); 588 589 reqCamsItem = pdoc. 590 getPurchasingCapitalAssetItemByItemIdentifier(reqItem.getItemIdentifier().intValue()); 591 ritem = populateCapitalAssetItem(ritem, requisitionDocument, reqCamsItem); 592 items.add(ritem); 593 } 594 requisitionDocument.setItems(items); 595 596 // Copy capital asset information that is directly off the document. 597 requisitionDocument.setCapitalAssetSystemTypeCode(pdoc.getCapitalAssetSystemTypeCode()); 598 requisitionDocument.setCapitalAssetSystemStateCode(pdoc.getCapitalAssetSystemStateCode()); 599 requisitionDocument.setStatusCode(PurapConstants.RequisitionStatuses.APPDOC_CLOSED); 600 601 602 for (CapitalAssetSystem capitalAssetSystem : pdoc.getPurchasingCapitalAssetSystems()) { 603 RequisitionCapitalAssetSystem item = new RequisitionCapitalAssetSystem(capitalAssetSystem); 604 item.setPurapDocumentIdentifier(requisitionDocument.getPurapDocumentIdentifier()); 605 requisitionDocument.getPurchasingCapitalAssetSystems().add(new RequisitionCapitalAssetSystem(capitalAssetSystem)); 606 } 607 608// requisitionDocument.fixItemReferences(); 609 return requisitionDocument; 610 } 611 612 private OleRequisitionItem getRequisitionItem(OlePurchaseOrderItem pitem, RequisitionDocument requisitionDocument, PurchasingCapitalAssetItem reqCamsItem) { 613 OleRequisitionItem ritem = new OleRequisitionItem(); 614 ritem.setRequisition(requisitionDocument); 615 SequenceAccessorService sas = SpringContext.getBean(SequenceAccessorService.class); 616 Integer itemIdentifier = sas.getNextAvailableSequenceNumber("REQS_ITM_ID", RequisitionDocument.class).intValue(); 617 ritem.setItemIdentifier(itemIdentifier); 618 ritem.setItemLineNumber(pitem.getItemLineNumber()); 619 ritem.setItemUnitOfMeasureCode(pitem.getItemUnitOfMeasureCode()); 620 ritem.setItemQuantity(pitem.getItemQuantity()); 621 ritem.setItemCatalogNumber(pitem.getItemCatalogNumber()); 622 ritem.setItemDescription(pitem.getItemDescription()); 623 ritem.setItemUnitPrice(pitem.getItemUnitPrice()); 624 ritem.setItemAuxiliaryPartIdentifier(pitem.getItemAuxiliaryPartIdentifier()); 625 ritem.setItemAssignedToTradeInIndicator(pitem.getItemAssignedToTradeInIndicator()); 626 ritem.setItemTaxAmount(pitem.getItemTaxAmount()); 627 ritem.setItemTitleId(pitem.getItemTitleId()); 628 629 for (PurApItemUseTax useTaxItem : pitem.getUseTaxItems()) { 630 useTaxItem.setItemIdentifier(itemIdentifier); 631 ritem.getUseTaxItems().add(useTaxItem); 632 } 633 634 ritem.setExternalOrganizationB2bProductReferenceNumber(pitem.getExternalOrganizationB2bProductReferenceNumber()); 635 ritem.setExternalOrganizationB2bProductTypeName(pitem.getExternalOrganizationB2bProductTypeName()); 636 ritem.setItemTypeCode(pitem.getItemTypeCode()); 637 638 if (pitem.getSourceAccountingLines() != null && pitem.getSourceAccountingLines().size() > 0 && 639 !StringUtils.equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_ORDER_DISCOUNT_CODE, pitem.getItemType().getItemTypeCode())) { 640 List accounts = new ArrayList(); 641 for (PurApAccountingLine account : pitem.getSourceAccountingLines()) { 642 PurApAccountingLineBase poAccount = (PurApAccountingLineBase) account; 643 RequisitionAccount acc = convertAccount(poAccount, ritem); 644 accounts.add(acc); 645 } 646 ritem.setSourceAccountingLines(accounts); 647 } 648 ritem.setPurchasingCommodityCode(pitem.getPurchasingCommodityCode()); 649 ritem.setCommodityCode(pitem.getCommodityCode()); 650 651 if (ObjectUtils.isNotNull(reqCamsItem)) { 652 RequisitionCapitalAssetItem item = new RequisitionCapitalAssetItem(reqCamsItem, ritem.getItemIdentifier()); 653 requisitionDocument.getPurchasingCapitalAssetItems().add(item); 654 } 655 return ritem; 656 } 657 658 private OleRequisitionItem populateCapitalAssetItem(OleRequisitionItem ritem, RequisitionDocument requisitionDocument, PurchasingCapitalAssetItem reqCamsItem) { 659 if (ObjectUtils.isNotNull(reqCamsItem)) { 660 RequisitionCapitalAssetItem item = new RequisitionCapitalAssetItem(reqCamsItem, ritem.getItemIdentifier()); 661 requisitionDocument.getPurchasingCapitalAssetItems().add(item); 662 } 663 return ritem; 664 } 665 666 private RequisitionAccount convertAccount(PurApAccountingLine account, RequisitionItem requisitionItem) { 667 RequisitionAccount result = new RequisitionAccount(); 668 result.setAccountLinePercent(account.getAccountLinePercent()); 669 result.setAccountNumber(account.getAccountNumber()); 670 result.setChartOfAccountsCode(account.getChartOfAccountsCode()); 671 result.setFinancialObjectCode(account.getFinancialObjectCode()); 672 result.setFinancialSubObjectCode(account.getFinancialSubObjectCode()); 673 result.setOrganizationReferenceId(account.getOrganizationReferenceId()); 674 result.setProjectCode(account.getProjectCode()); 675 result.setSubAccountNumber(account.getSubAccountNumber()); 676 result.setRequisitionItem(requisitionItem); 677 return result; 678 } 679 680 private RequisitionCapitalAssetItem convert(PurchaseOrderCapitalAssetItem pitem) { 681 RequisitionCapitalAssetItem result = new RequisitionCapitalAssetItem(); 682 result.setCapitalAssetItemIdentifier(pitem.getCapitalAssetItemIdentifier()); 683 result.setCapitalAssetSystemIdentifier(pitem.getCapitalAssetSystemIdentifier()); 684 result.setCapitalAssetTransactionTypeCode(pitem.getCapitalAssetTransactionTypeCode()); 685 result.setItemIdentifier(pitem.getItemIdentifier()); 686 result.setPurapDocumentIdentifier(pitem.getPurchasingDocument().getPurapDocumentIdentifier()); 687 return result; 688 } 689 690 691 public void setBusinessObjectService(BusinessObjectService boService) { 692 this.businessObjectService = boService; 693 } 694 695 public void setDocumentService(DocumentService documentService) { 696 this.documentService = documentService; 697 } 698 699 public void setRequisitionDao(RequisitionDao requisitionDao) { 700 this.requisitionDao = requisitionDao; 701 } 702 703 public void setPurapService(PurapService purapService) { 704 this.purapService = purapService; 705 } 706 707 public KualiRuleService getRuleService() { 708 return ruleService; 709 } 710 711 public void setRuleService(KualiRuleService ruleService) { 712 this.ruleService = ruleService; 713 } 714 715 public void setParameterService(ParameterService parameterService) { 716 this.parameterService = parameterService; 717 } 718 719 public void setDateTimeService(DateTimeService dateTimeService) { 720 this.dateTimeService = dateTimeService; 721 } 722 723 public void setUniversityDateService(UniversityDateService universityDateService) { 724 this.universityDateService = universityDateService; 725 } 726 727 public void setVendorService(VendorService vendorService) { 728 this.vendorService = vendorService; 729 } 730 731 public void setConfigurationService(ConfigurationService kualiConfigurationService) { 732 this.kualiConfigurationService = kualiConfigurationService; 733 } 734 735 public void setCapitalAssetBuilderModuleService(CapitalAssetBuilderModuleService capitalAssetBuilderModuleService) { 736 this.capitalAssetBuilderModuleService = capitalAssetBuilderModuleService; 737 } 738 739 public void setPostalCodeValidationService(PostalCodeValidationService postalCodeValidationService) { 740 this.postalCodeValidationService = postalCodeValidationService; 741 } 742 743 /** 744 * @return Returns the personService. 745 */ 746 protected PersonService getPersonService() { 747 if (personService == null) { 748 personService = SpringContext.getBean(PersonService.class); 749 } 750 return personService; 751 } 752 753}