001 /* 002 * Copyright 2011 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 */ 016 017 package org.kuali.kfs.module.purap.document; 018 019 import static org.kuali.kfs.sys.KFSConstants.GL_DEBIT_CODE; 020 import static org.kuali.rice.kns.util.KualiDecimal.ZERO; 021 022 import java.math.BigDecimal; 023 import java.sql.Date; 024 import java.sql.Timestamp; 025 import java.util.ArrayList; 026 import java.util.Collections; 027 import java.util.HashMap; 028 import java.util.Iterator; 029 import java.util.List; 030 import java.util.Map; 031 032 import org.apache.commons.lang.StringUtils; 033 import org.kuali.kfs.coa.businessobject.Account; 034 import org.kuali.kfs.gl.service.SufficientFundsService; 035 import org.kuali.kfs.integration.purap.CapitalAssetSystem; 036 import org.kuali.kfs.module.purap.PurapConstants; 037 import org.kuali.kfs.module.purap.PurapKeyConstants; 038 import org.kuali.kfs.module.purap.PurapParameterConstants; 039 import org.kuali.kfs.module.purap.PurapPropertyConstants; 040 import org.kuali.kfs.module.purap.PurapWorkflowConstants; 041 import org.kuali.kfs.module.purap.PurapConstants.CreditMemoStatuses; 042 import org.kuali.kfs.module.purap.PurapConstants.PurapDocTypeCodes; 043 import org.kuali.kfs.module.purap.PurapConstants.PurchaseOrderStatuses; 044 import org.kuali.kfs.module.purap.PurapConstants.QuoteTypeDescriptions; 045 import org.kuali.kfs.module.purap.PurapConstants.RequisitionSources; 046 import org.kuali.kfs.module.purap.PurapWorkflowConstants.NodeDetails; 047 import org.kuali.kfs.module.purap.PurapWorkflowConstants.PurchaseOrderDocument.NodeDetailEnum; 048 import org.kuali.kfs.module.purap.businessobject.CreditMemoView; 049 import org.kuali.kfs.module.purap.businessobject.ItemType; 050 import org.kuali.kfs.module.purap.businessobject.PaymentRequestView; 051 import org.kuali.kfs.module.purap.businessobject.PurApAccountingLine; 052 import org.kuali.kfs.module.purap.businessobject.PurApItem; 053 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderAccount; 054 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderCapitalAssetItem; 055 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderCapitalAssetSystem; 056 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem; 057 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItemUseTax; 058 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderSensitiveData; 059 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderVendorChoice; 060 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderVendorQuote; 061 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderVendorStipulation; 062 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderView; 063 import org.kuali.kfs.module.purap.businessobject.RecurringPaymentFrequency; 064 import org.kuali.kfs.module.purap.businessobject.RequisitionCapitalAssetItem; 065 import org.kuali.kfs.module.purap.businessobject.RequisitionCapitalAssetSystem; 066 import org.kuali.kfs.module.purap.businessobject.RequisitionItem; 067 import org.kuali.kfs.module.purap.document.service.PurapService; 068 import org.kuali.kfs.module.purap.document.service.PurchaseOrderService; 069 import org.kuali.kfs.module.purap.document.service.PurchasingDocumentSpecificService; 070 import org.kuali.kfs.module.purap.document.service.RequisitionService; 071 import org.kuali.kfs.module.purap.service.PurapAccountingService; 072 import org.kuali.kfs.module.purap.service.PurapGeneralLedgerService; 073 import org.kuali.kfs.module.purap.util.PurApItemUtils; 074 import org.kuali.kfs.sys.KFSConstants; 075 import org.kuali.kfs.sys.businessobject.AccountingLine; 076 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry; 077 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail; 078 import org.kuali.kfs.sys.businessobject.SourceAccountingLine; 079 import org.kuali.kfs.sys.businessobject.SufficientFundsItem; 080 import org.kuali.kfs.sys.context.SpringContext; 081 import org.kuali.kfs.sys.document.MultiselectableDocSearchConversion; 082 import org.kuali.kfs.sys.service.UniversityDateService; 083 import org.kuali.kfs.vnd.VendorConstants; 084 import org.kuali.kfs.vnd.businessobject.ContractManager; 085 import org.kuali.kfs.vnd.businessobject.PaymentTermType; 086 import org.kuali.kfs.vnd.businessobject.ShippingPaymentTerms; 087 import org.kuali.kfs.vnd.businessobject.ShippingTitle; 088 import org.kuali.kfs.vnd.businessobject.VendorDetail; 089 import org.kuali.kfs.vnd.document.service.VendorService; 090 import org.kuali.rice.kew.docsearch.DocSearchCriteriaDTO; 091 import org.kuali.rice.kew.docsearch.SearchAttributeCriteriaComponent; 092 import org.kuali.rice.kew.dto.ActionTakenEventDTO; 093 import org.kuali.rice.kew.dto.DocumentRouteLevelChangeDTO; 094 import org.kuali.rice.kew.dto.DocumentRouteStatusChangeDTO; 095 import org.kuali.rice.kew.dto.ReportCriteriaDTO; 096 import org.kuali.rice.kew.exception.WorkflowException; 097 import org.kuali.rice.kew.util.KEWConstants; 098 import org.kuali.rice.kim.bo.Person; 099 import org.kuali.rice.kim.bo.entity.KimPrincipal; 100 import org.kuali.rice.kim.service.IdentityManagementService; 101 import org.kuali.rice.kim.service.PersonService; 102 import org.kuali.rice.kns.bo.PersistableBusinessObject; 103 import org.kuali.rice.kns.rule.event.KualiDocumentEvent; 104 import org.kuali.rice.kns.service.BusinessObjectService; 105 import org.kuali.rice.kns.service.DataDictionaryService; 106 import org.kuali.rice.kns.service.DateTimeService; 107 import org.kuali.rice.kns.service.DocumentHeaderService; 108 import org.kuali.rice.kns.service.ParameterService; 109 import org.kuali.rice.kns.service.SequenceAccessorService; 110 import org.kuali.rice.kns.util.GlobalVariables; 111 import org.kuali.rice.kns.util.KualiDecimal; 112 import org.kuali.rice.kns.util.ObjectUtils; 113 import org.kuali.rice.kns.util.TypedArrayList; 114 import org.kuali.rice.kns.web.ui.Field; 115 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument; 116 import org.kuali.rice.kns.workflow.service.KualiWorkflowInfo; 117 import org.kuali.rice.kns.workflow.service.WorkflowDocumentService; 118 119 /** 120 * Purchase Order Document 121 */ 122 public class PurchaseOrderDocument extends PurchasingDocumentBase implements MultiselectableDocSearchConversion { 123 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurchaseOrderDocument.class); 124 125 protected Timestamp purchaseOrderCreateTimestamp; 126 protected Integer requisitionIdentifier; 127 protected String purchaseOrderVendorChoiceCode; 128 protected String recurringPaymentFrequencyCode; 129 protected KualiDecimal recurringPaymentAmount; 130 protected Date recurringPaymentDate; 131 protected KualiDecimal initialPaymentAmount; 132 protected Date initialPaymentDate; 133 protected KualiDecimal finalPaymentAmount; 134 protected Date finalPaymentDate; 135 protected Timestamp purchaseOrderInitialOpenTimestamp; 136 protected Timestamp purchaseOrderLastTransmitTimestamp; 137 protected Date purchaseOrderQuoteDueDate; 138 protected String purchaseOrderQuoteTypeCode; 139 protected String purchaseOrderQuoteVendorNoteText; 140 protected boolean purchaseOrderConfirmedIndicator; 141 protected String purchaseOrderCommodityDescription; 142 protected Integer purchaseOrderPreviousIdentifier; 143 protected Integer alternateVendorHeaderGeneratedIdentifier; 144 protected Integer alternateVendorDetailAssignedIdentifier; 145 protected Integer newQuoteVendorHeaderGeneratedIdentifier; 146 protected Integer newQuoteVendorDetailAssignedIdentifier; 147 protected String alternateVendorName; 148 protected boolean purchaseOrderCurrentIndicator = false; 149 protected boolean pendingActionIndicator = false; 150 protected Timestamp purchaseOrderFirstTransmissionTimestamp; 151 protected Integer contractManagerCode; 152 protected Date purchaseOrderQuoteInitializationDate; 153 protected Date purchaseOrderQuoteAwardedDate; 154 protected String assignedUserPrincipalId; 155 156 // COLLECTIONS 157 protected List<PurchaseOrderVendorStipulation> purchaseOrderVendorStipulations; 158 protected List<PurchaseOrderVendorQuote> purchaseOrderVendorQuotes; 159 160 // NOT PERSISTED IN DB 161 protected String statusChange; 162 protected String alternateVendorNumber; 163 protected String purchaseOrderRetransmissionMethodCode; 164 protected String retransmitHeader; 165 protected Integer purchaseOrderQuoteListIdentifier; 166 protected KualiDecimal internalPurchasingLimit; 167 protected boolean pendingSplit = false; // Needed for authorization 168 protected boolean copyingNotesWhenSplitting; // Check box on Split PO tab 169 protected boolean assigningSensitiveData = false; // whether the form is currently used for assigning sensitive data to the PO 170 protected List<PurchaseOrderSensitiveData> purchaseOrderSensitiveData; 171 protected String assignedUserPrincipalName; // this serves as a temporary holder before validation is done 172 173 //this is a holder for the accountinglines for GL purposes only; used only for PO change docs 174 protected List<SourceAccountingLine> glOnlySourceAccountingLines; 175 176 // REFERENCE OBJECTS 177 protected PurchaseOrderVendorChoice purchaseOrderVendorChoice; 178 protected PaymentTermType vendorPaymentTerms; 179 protected ShippingTitle vendorShippingTitle; 180 protected ShippingPaymentTerms vendorShippingPaymentTerms; 181 protected RecurringPaymentFrequency recurringPaymentFrequency; 182 protected ContractManager contractManager; 183 //protected Person assignedUser; 184 185 public static final String FIN_COA_CD_KEY = "fin_coa_cd"; 186 protected static final String UNIVERSITY_FISCAL_YEAR_KEY = "univ_fiscal_year"; 187 protected static final String VENDOR_IS_EMPLOYEE = "Employee Vendor"; 188 protected static final String VENDOR_IS_FOREIGN = "Foreign Vendor"; 189 protected static final String VENDOR_IS_FOREIGN_EMPLOYEE = "Foreign and Employee Vendor"; 190 191 /** 192 * Default constructor. 193 */ 194 public PurchaseOrderDocument() { 195 super(); 196 this.purchaseOrderVendorStipulations = new TypedArrayList(PurchaseOrderVendorStipulation.class); 197 this.purchaseOrderVendorQuotes = new TypedArrayList(PurchaseOrderVendorQuote.class); 198 } 199 200 public PurchasingDocumentSpecificService getDocumentSpecificService() { 201 return SpringContext.getBean(PurchaseOrderService.class); 202 } 203 204 /** 205 * Overrides the method in PurchasingAccountsPayableDocumentBase to add the criteria 206 * specific to Purchase Order Document. 207 * 208 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#isInquiryRendered() 209 */ 210 @Override 211 public boolean isInquiryRendered() { 212 if ( isPostingYearPrior() && 213 ( getStatusCode().equals(PurapConstants.PurchaseOrderStatuses.CLOSED) || 214 getStatusCode().equals(PurapConstants.PurchaseOrderStatuses.CANCELLED) || 215 getStatusCode().equals(PurapConstants.PurchaseOrderStatuses.VOID) ) ) { 216 return false; 217 } 218 else { 219 return true; 220 } 221 } 222 223 /** 224 * @see org.kuali.rice.kns.document.DocumentBase#getDocumentTitle() 225 */ 226 @Override 227 public String getDocumentTitle() { 228 if (SpringContext.getBean(ParameterService.class).getIndicatorParameter(PurchaseOrderDocument.class, PurapParameterConstants.PURAP_OVERRIDE_PO_DOC_TITLE)) { 229 return getCustomDocumentTitle(); 230 } 231 232 return this.buildDocumentTitle(super.getDocumentTitle()); 233 } 234 235 /** 236 * Returns a custom document title based on the workflow document title. 237 * Depending on what route level the document is currently in, various info may be added to the documents title. 238 * 239 * @return - Customized document title text dependent upon route level. 240 */ 241 protected String getCustomDocumentTitle() { 242 try { 243 String poNumber = getPurapDocumentIdentifier().toString(); 244 String cmCode = getContractManagerCode().toString(); 245 String vendorName = StringUtils.trimToEmpty(getVendorName()); 246 String totalAmount = getTotalDollarAmount().toString(); 247 PurApAccountingLine accountingLine = getFirstAccount(); 248 String chartAcctCode = accountingLine != null ? accountingLine.getChartOfAccountsCode() : ""; 249 String accountNumber = accountingLine != null ? accountingLine.getAccountNumber() : ""; 250 String chartCode = getChartOfAccountsCode(); 251 String orgCode = getOrganizationCode(); 252 String deliveryCampus = getDeliveryCampus() != null ? getDeliveryCampus().getCampus().getCampusShortName() : ""; 253 String documentTitle = ""; 254 255 String[] nodeNames = getDocumentHeader().getWorkflowDocument().getNodeNames(); 256 String routeLevel = ""; 257 if (nodeNames.length == 1) 258 routeLevel = nodeNames[0]; 259 260 if (getStatusCode().equals(PurchaseOrderStatuses.OPEN)) { 261 documentTitle = super.getDocumentTitle(); 262 } 263 else if (routeLevel.equals(NodeDetailEnum.BUDGET_OFFICE_REVIEW.getName()) || routeLevel.equals(NodeDetailEnum.CONTRACTS_AND_GRANTS_REVIEW.getName())) { 264 // Budget & C&G approval levels 265 documentTitle = "PO: " + poNumber + " Account Number: " + chartAcctCode + "-" + accountNumber + " Dept: " + chartCode + "-" + orgCode + " Delivery Campus: " + deliveryCampus; 266 } 267 else if (routeLevel.equals(NodeDetailEnum.VENDOR_TAX_REVIEW.getName())) { 268 // Tax approval level 269 documentTitle = "Vendor: " + vendorName + " PO: " + poNumber + " Account Number: " + chartCode + "-" + accountNumber + " Dept: " + chartCode + "-" + orgCode + " Delivery Campus: " + deliveryCampus; 270 } 271 else 272 documentTitle += "PO: " + poNumber + " Contract Manager: " + cmCode + " Vendor: " + vendorName + " Amount: " + totalAmount; 273 274 return documentTitle; 275 } 276 catch (WorkflowException e) { 277 LOG.error("Error updating Purchase Order document: " + e.getMessage()); 278 throw new RuntimeException("Error updating Purchase Order document: " + e.getMessage()); 279 } 280 } 281 282 /** 283 * @see org.kuali.kfs.sys.document.AccountingDocument#getSourceAccountingLineClass() 284 */ 285 @Override 286 public Class getSourceAccountingLineClass() { 287 //NOTE: do not do anything with this method as it is used by routing etc! 288 return super.getSourceAccountingLineClass(); 289 } 290 291 /** 292 * Returns the first PO item's first accounting line (assuming the item list is sequentially ordered). 293 * 294 * @return - The first accounting line of the first PO item. 295 */ 296 protected PurApAccountingLine getFirstAccount() { 297 // loop through items, and pick the first item with non-empty accouting lines 298 if (getItems() != null && !getItems().isEmpty()) { 299 for (Iterator iter = getItems().iterator(); iter.hasNext();) { 300 PurchaseOrderItem item = (PurchaseOrderItem)iter.next(); 301 if (item.isConsideredEntered() && item.getSourceAccountingLines() != null && !item.getSourceAccountingLines().isEmpty()) { 302 // accounting lines are not empty so pick the first account 303 PurApAccountingLine accountingLine = item.getSourceAccountingLine(0); 304 accountingLine.refreshNonUpdateableReferences(); 305 return accountingLine; 306 } 307 } 308 } 309 return null; 310 } 311 312 public String getAssignedUserPrincipalId() { 313 return assignedUserPrincipalId; 314 } 315 316 public void setAssignedUserPrincipalId(String assignedUserPrincipalId) { 317 this.assignedUserPrincipalId = assignedUserPrincipalId; 318 } 319 320 public String getAssignedUserPrincipalName() { 321 // init this field when PO is first loaded and assigned user exists in PO 322 if (assignedUserPrincipalName == null && assignedUserPrincipalId != null) { 323 // extra caution in case ref obj didn't get refreshed 324 //if (assignedUser == null) 325 // this.refreshReferenceObject("assignedUser"); 326 Person assignedUser = SpringContext.getBean(PersonService.class).getPerson(assignedUserPrincipalId); 327 this.assignedUserPrincipalName = assignedUser.getPrincipalName(); 328 } 329 // otherwise return its current value directly 330 return assignedUserPrincipalName; 331 } 332 333 public void setAssignedUserPrincipalName(String assignedUserPrincipalName) { 334 this.assignedUserPrincipalName = assignedUserPrincipalName; 335 // each time this field changes we need to update the assigned user ID and ref obj to keep consistent 336 // this code can be moved to where PO is saved and with validation too, which may be more appropriate 337 Person assignedUser = null; 338 if (assignedUserPrincipalName != null) 339 assignedUser = SpringContext.getBean(PersonService.class).getPersonByPrincipalName(assignedUserPrincipalName); 340 if (assignedUser != null) 341 assignedUserPrincipalId = assignedUser.getPrincipalId(); 342 else 343 assignedUserPrincipalId = null; 344 } 345 346 /* 347 public Person getAssignedUser() { 348 return assignedUser; 349 } 350 351 public void setAssignedUser(Person assignedUser) { 352 this.assignedUser = assignedUser; 353 } 354 */ 355 356 /* 357 public String getAssignedUserName() { 358 // assignedUserPrincipalId is either null or returned from lookup (thus valid) 359 if (StringUtils.isEmpty(assignedUserPrincipalId)) 360 return null; 361 Person person = SpringContext.getBean(PersonService.class).getPersonByPrincipalName(assignedUserPrincipalId); 362 if (person == null) 363 return null; 364 return person.getName(); 365 } 366 */ 367 368 public boolean getAssigningSensitiveData() { 369 return assigningSensitiveData; 370 } 371 372 public void setAssigningSensitiveData(boolean assigningSensitiveData) { 373 this.assigningSensitiveData = assigningSensitiveData; 374 } 375 376 public List<PurchaseOrderSensitiveData> getPurchaseOrderSensitiveData() { 377 Map fieldValues = new HashMap(); 378 fieldValues.put(PurapPropertyConstants.PURAP_DOC_ID, getPurapDocumentIdentifier()); 379 return new ArrayList(SpringContext.getBean(BusinessObjectService.class).findMatching(PurchaseOrderSensitiveData.class, fieldValues)); 380 } 381 382 public void setPurchaseOrderSensitiveData(List<PurchaseOrderSensitiveData> purchaseOrderSensitiveData) { 383 this.purchaseOrderSensitiveData = purchaseOrderSensitiveData; 384 } 385 386 public ContractManager getContractManager() { 387 if (ObjectUtils.isNull(contractManager)) 388 refreshReferenceObject(PurapPropertyConstants.CONTRACT_MANAGER); 389 return contractManager; 390 } 391 392 public void setContractManager(ContractManager contractManager) { 393 this.contractManager = contractManager; 394 } 395 396 public Integer getContractManagerCode() { 397 return contractManagerCode; 398 } 399 400 public void setContractManagerCode(Integer contractManagerCode) { 401 this.contractManagerCode = contractManagerCode; 402 } 403 404 /** 405 * @see org.kuali.kfs.module.purap.document.PurchasingDocumentBase#buildListOfDeletionAwareLists() 406 */ 407 @Override 408 public List buildListOfDeletionAwareLists() { 409 List managedLists = super.buildListOfDeletionAwareLists(); 410 managedLists.add(this.getGeneralLedgerPendingEntries()); 411 if (allowDeleteAwareCollection) { 412 managedLists.add(this.getPurchaseOrderVendorQuotes()); 413 } 414 return managedLists; 415 } 416 417 /** 418 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getOverrideWorkflowButtons() 419 */ 420 @Override 421 public Boolean getOverrideWorkflowButtons() { 422 if (ObjectUtils.isNull(super.getOverrideWorkflowButtons())) { 423 // should only be null on the first call... never after 424 setOverrideWorkflowButtons(Boolean.TRUE); 425 } 426 return super.getOverrideWorkflowButtons(); 427 } 428 429 /** 430 * @see org.kuali.rice.kns.bo.PersistableBusinessObjectBase#isBoNotesSupport() 431 */ 432 @Override 433 public boolean isBoNotesSupport() { 434 return true; 435 } 436 437 /** 438 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#customPrepareForSave() 439 */ 440 @Override 441 public void customPrepareForSave(KualiDocumentEvent event) { 442 super.customPrepareForSave(event); 443 if (ObjectUtils.isNull(getPurapDocumentIdentifier())) { 444 // need retrieve the next available PO id to save in GL entries (only do if purap id is null which should be on first 445 // save) 446 SequenceAccessorService sas = SpringContext.getBean(SequenceAccessorService.class); 447 Long poSequenceNumber = sas.getNextAvailableSequenceNumber("PO_ID", this.getClass()); 448 setPurapDocumentIdentifier(poSequenceNumber.intValue()); 449 } 450 451 // Set outstanding encumbered quantity/amount on items 452 for (Iterator items = this.getItems().iterator(); items.hasNext();) { 453 PurchaseOrderItem item = (PurchaseOrderItem) items.next(); 454 455 // Set quantities 456 item.setItemOutstandingEncumberedQuantity(item.getItemQuantity()); 457 if (item.getItemInvoicedTotalQuantity() == null) { 458 item.setItemInvoicedTotalQuantity(ZERO); 459 } 460 if (item.getItemInvoicedTotalAmount() == null) { 461 item.setItemInvoicedTotalAmount(ZERO); 462 } 463 464 // Set amount 465 item.setItemOutstandingEncumberedAmount(item.getTotalAmount() == null ? ZERO : item.getTotalAmount()); 466 467 List accounts = (List) item.getSourceAccountingLines(); 468 Collections.sort(accounts); 469 470 for (Iterator iterator = accounts.iterator(); iterator.hasNext();) { 471 PurchaseOrderAccount account = (PurchaseOrderAccount) iterator.next(); 472 if (!account.isEmpty()) { 473 account.setItemAccountOutstandingEncumbranceAmount(account.getAmount()); 474 } 475 }// endfor accounts 476 }// endfor items 477 478 this.setSourceAccountingLines(SpringContext.getBean(PurapAccountingService.class).generateSummaryWithNoZeroTotals(this.getItems())); 479 }// end customPrepareForSave(KualiDocumentEvent) 480 481 /** 482 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#prepareForSave() 483 */ 484 @Override 485 public void prepareForSave(KualiDocumentEvent event) { 486 KualiWorkflowDocument workFlowDocument = getDocumentHeader().getWorkflowDocument(); 487 String documentType = workFlowDocument.getDocumentType(); 488 489 490 if ((documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_DOCUMENT)) || 491 (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_SPLIT_DOCUMENT))) { 492 if (workFlowDocument.stateIsCanceled()) { 493 // if doc is FINAL or canceled, saving should not be creating GL entries 494 setGeneralLedgerPendingEntries(new ArrayList()); 495 } else if (workFlowDocument.stateIsFinal()) { 496 } else { 497 super.prepareForSave(event); 498 } 499 } 500 } 501 502 /** 503 * Sets default values for APO. 504 */ 505 public void setDefaultValuesForAPO() { 506 this.setPurchaseOrderAutomaticIndicator(Boolean.TRUE); 507 if (!RequisitionSources.B2B.equals(this.getRequisitionSourceCode())) { 508 String paramName = PurapParameterConstants.DEFAULT_APO_VENDOR_CHOICE; 509 String paramValue = SpringContext.getBean(ParameterService.class).getParameterValue(PurchaseOrderDocument.class, paramName); 510 this.setPurchaseOrderVendorChoiceCode(paramValue); 511 } 512 } 513 514 /** 515 * Populates this Purchase Order from the related Requisition Document. 516 * 517 * @param requisitionDocument the Requisition Document from which field values are copied. 518 */ 519 public void populatePurchaseOrderFromRequisition(RequisitionDocument requisitionDocument) { 520 this.setPurchaseOrderCreateTimestamp(SpringContext.getBean(DateTimeService.class).getCurrentTimestamp()); 521 this.getDocumentHeader().setOrganizationDocumentNumber(requisitionDocument.getDocumentHeader().getOrganizationDocumentNumber()); 522 this.getDocumentHeader().setDocumentDescription(requisitionDocument.getDocumentHeader().getDocumentDescription()); 523 this.getDocumentHeader().setExplanation(requisitionDocument.getDocumentHeader().getExplanation()); 524 525 this.setBillingName(requisitionDocument.getBillingName()); 526 this.setBillingLine1Address(requisitionDocument.getBillingLine1Address()); 527 this.setBillingLine2Address(requisitionDocument.getBillingLine2Address()); 528 this.setBillingCityName(requisitionDocument.getBillingCityName()); 529 this.setBillingStateCode(requisitionDocument.getBillingStateCode()); 530 this.setBillingPostalCode(requisitionDocument.getBillingPostalCode()); 531 this.setBillingCountryCode(requisitionDocument.getBillingCountryCode()); 532 this.setBillingPhoneNumber(requisitionDocument.getBillingPhoneNumber()); 533 534 this.setReceivingName(requisitionDocument.getReceivingName()); 535 this.setReceivingCityName(requisitionDocument.getReceivingCityName()); 536 this.setReceivingLine1Address(requisitionDocument.getReceivingLine1Address()); 537 this.setReceivingLine2Address(requisitionDocument.getReceivingLine2Address()); 538 this.setReceivingStateCode(requisitionDocument.getReceivingStateCode()); 539 this.setReceivingPostalCode(requisitionDocument.getReceivingPostalCode()); 540 this.setReceivingCountryCode(requisitionDocument.getReceivingCountryCode()); 541 this.setAddressToVendorIndicator(requisitionDocument.getAddressToVendorIndicator()); 542 543 this.setDeliveryBuildingCode(requisitionDocument.getDeliveryBuildingCode()); 544 this.setDeliveryBuildingRoomNumber(requisitionDocument.getDeliveryBuildingRoomNumber()); 545 this.setDeliveryBuildingName(requisitionDocument.getDeliveryBuildingName()); 546 this.setDeliveryCampusCode(requisitionDocument.getDeliveryCampusCode()); 547 this.setDeliveryCityName(requisitionDocument.getDeliveryCityName()); 548 this.setDeliveryCountryCode(requisitionDocument.getDeliveryCountryCode()); 549 this.setDeliveryInstructionText(requisitionDocument.getDeliveryInstructionText()); 550 this.setDeliveryBuildingLine1Address(requisitionDocument.getDeliveryBuildingLine1Address()); 551 this.setDeliveryBuildingLine2Address(requisitionDocument.getDeliveryBuildingLine2Address()); 552 this.setDeliveryPostalCode(requisitionDocument.getDeliveryPostalCode()); 553 this.setDeliveryRequiredDate(requisitionDocument.getDeliveryRequiredDate()); 554 this.setDeliveryRequiredDateReasonCode(requisitionDocument.getDeliveryRequiredDateReasonCode()); 555 this.setDeliveryStateCode(requisitionDocument.getDeliveryStateCode()); 556 this.setDeliveryToEmailAddress(requisitionDocument.getDeliveryToEmailAddress()); 557 this.setDeliveryToName(requisitionDocument.getDeliveryToName()); 558 this.setDeliveryToPhoneNumber(requisitionDocument.getDeliveryToPhoneNumber()); 559 this.setDeliveryBuildingOtherIndicator(requisitionDocument.isDeliveryBuildingOtherIndicator()); 560 561 this.setPurchaseOrderBeginDate(requisitionDocument.getPurchaseOrderBeginDate()); 562 this.setPurchaseOrderCostSourceCode(requisitionDocument.getPurchaseOrderCostSourceCode()); 563 this.setPostingYear(requisitionDocument.getPostingYear()); 564 this.setPurchaseOrderEndDate(requisitionDocument.getPurchaseOrderEndDate()); 565 this.setChartOfAccountsCode(requisitionDocument.getChartOfAccountsCode()); 566 this.setDocumentFundingSourceCode(requisitionDocument.getDocumentFundingSourceCode()); 567 this.setInstitutionContactEmailAddress(requisitionDocument.getInstitutionContactEmailAddress()); 568 this.setInstitutionContactName(requisitionDocument.getInstitutionContactName()); 569 this.setInstitutionContactPhoneNumber(requisitionDocument.getInstitutionContactPhoneNumber()); 570 this.setNonInstitutionFundAccountNumber(requisitionDocument.getNonInstitutionFundAccountNumber()); 571 this.setNonInstitutionFundChartOfAccountsCode(requisitionDocument.getNonInstitutionFundChartOfAccountsCode()); 572 this.setNonInstitutionFundOrgChartOfAccountsCode(requisitionDocument.getNonInstitutionFundOrgChartOfAccountsCode()); 573 this.setNonInstitutionFundOrganizationCode(requisitionDocument.getNonInstitutionFundOrganizationCode()); 574 this.setOrganizationCode(requisitionDocument.getOrganizationCode()); 575 this.setRecurringPaymentTypeCode(requisitionDocument.getRecurringPaymentTypeCode()); 576 this.setRequestorPersonEmailAddress(requisitionDocument.getRequestorPersonEmailAddress()); 577 this.setRequestorPersonName(requisitionDocument.getRequestorPersonName()); 578 this.setRequestorPersonPhoneNumber(requisitionDocument.getRequestorPersonPhoneNumber()); 579 this.setRequisitionIdentifier(requisitionDocument.getPurapDocumentIdentifier()); 580 this.setPurchaseOrderTotalLimit(requisitionDocument.getPurchaseOrderTotalLimit()); 581 this.setPurchaseOrderTransmissionMethodCode(requisitionDocument.getPurchaseOrderTransmissionMethodCode()); 582 this.setUseTaxIndicator( requisitionDocument.isUseTaxIndicator() ); 583 584 this.setVendorCityName(requisitionDocument.getVendorCityName()); 585 this.setVendorContractGeneratedIdentifier(requisitionDocument.getVendorContractGeneratedIdentifier()); 586 this.setVendorCountryCode(requisitionDocument.getVendorCountryCode()); 587 this.setVendorCustomerNumber(requisitionDocument.getVendorCustomerNumber()); 588 this.setVendorAttentionName(requisitionDocument.getVendorAttentionName()); 589 this.setVendorDetailAssignedIdentifier(requisitionDocument.getVendorDetailAssignedIdentifier()); 590 this.setVendorFaxNumber(requisitionDocument.getVendorFaxNumber()); 591 this.setVendorHeaderGeneratedIdentifier(requisitionDocument.getVendorHeaderGeneratedIdentifier()); 592 this.setVendorLine1Address(requisitionDocument.getVendorLine1Address()); 593 this.setVendorLine2Address(requisitionDocument.getVendorLine2Address()); 594 this.setVendorAddressInternationalProvinceName(requisitionDocument.getVendorAddressInternationalProvinceName()); 595 this.setVendorName(requisitionDocument.getVendorName()); 596 this.setVendorNoteText(requisitionDocument.getVendorNoteText()); 597 this.setVendorPhoneNumber(requisitionDocument.getVendorPhoneNumber()); 598 this.setVendorPostalCode(requisitionDocument.getVendorPostalCode()); 599 this.setVendorStateCode(requisitionDocument.getVendorStateCode()); 600 this.setVendorRestrictedIndicator(requisitionDocument.getVendorRestrictedIndicator()); 601 602 this.setExternalOrganizationB2bSupplierIdentifier(requisitionDocument.getExternalOrganizationB2bSupplierIdentifier()); 603 this.setRequisitionSourceCode(requisitionDocument.getRequisitionSourceCode()); 604 this.setAccountsPayablePurchasingDocumentLinkIdentifier(requisitionDocument.getAccountsPayablePurchasingDocumentLinkIdentifier()); 605 this.setReceivingDocumentRequiredIndicator(requisitionDocument.isReceivingDocumentRequiredIndicator()); 606 this.setPaymentRequestPositiveApprovalIndicator(requisitionDocument.isPaymentRequestPositiveApprovalIndicator()); 607 608 this.setStatusCode(PurapConstants.PurchaseOrderStatuses.IN_PROCESS); 609 610 // Copy items from requisition (which will copy the item's accounts and capital assets) 611 List<PurchaseOrderItem> items = new ArrayList(); 612 for (PurApItem reqItem : ((PurchasingAccountsPayableDocument)requisitionDocument).getItems()) { 613 RequisitionCapitalAssetItem reqCamsItem = (RequisitionCapitalAssetItem)requisitionDocument.getPurchasingCapitalAssetItemByItemIdentifier(reqItem.getItemIdentifier().intValue()); 614 items.add(new PurchaseOrderItem((RequisitionItem)reqItem, this, reqCamsItem)); 615 } 616 this.setItems(items); 617 618 // Copy capital asset information that is directly off the document. 619 this.setCapitalAssetSystemTypeCode(requisitionDocument.getCapitalAssetSystemTypeCode()); 620 this.setCapitalAssetSystemStateCode(requisitionDocument.getCapitalAssetSystemStateCode()); 621 for (CapitalAssetSystem capitalAssetSystem : requisitionDocument.getPurchasingCapitalAssetSystems()) { 622 this.getPurchasingCapitalAssetSystems().add(new PurchaseOrderCapitalAssetSystem((RequisitionCapitalAssetSystem)capitalAssetSystem)); 623 } 624 625 this.fixItemReferences(); 626 } 627 628 /** 629 * Returns the Vendor Stipulation at the specified index in this Purchase Order. 630 * 631 * @param index the specified index. 632 * @return the Vendor Stipulation at the specified index. 633 */ 634 public PurchaseOrderVendorStipulation getPurchaseOrderVendorStipulation(int index) { 635 while (getPurchaseOrderVendorStipulations().size() <= index) { 636 getPurchaseOrderVendorStipulations().add(new PurchaseOrderVendorStipulation()); 637 } 638 return (PurchaseOrderVendorStipulation) purchaseOrderVendorStipulations.get(index); 639 } 640 641 @Override 642 public List<Long> getWorkflowEngineDocumentIdsToLock() { 643 List<String> docIdStrings = new ArrayList<String>(); 644 docIdStrings.add(getDocumentNumber()); 645 String currentDocumentTypeName = this.getDocumentHeader().getWorkflowDocument().getDocumentType(); 646 647 List<PurchaseOrderView> relatedPoViews = getRelatedViews().getRelatedPurchaseOrderViews(); 648 for (PurchaseOrderView poView : relatedPoViews) { 649 //don't lock related PO's if this is a split PO that's in process 650 if(!(PurapConstants.PurchaseOrderStatuses.IN_PROCESS.equals(this.getStatusCode()) && PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_SPLIT_DOCUMENT.equals(currentDocumentTypeName))){ 651 docIdStrings.add(poView.getDocumentNumber()); 652 } 653 } 654 655 // convert our easy to use List<String> to a Long[] 656 List<Long> docIds = new ArrayList<Long>(); 657 for (int i = 0; i < docIdStrings.size(); i++) { 658 docIds.add(new Long(docIdStrings.get(i))); 659 } 660 LOG.info("***** getWorkflowEngineDocumentIdsToLock(" + this.documentNumber + ") = '" + printList(docIds) + "'"); 661 return docIds; 662 } 663 664 // Only used for debugging in the getWorkflowEngineDocumentIdsToLock above 665 protected String printList(List<Long> docIds) { 666 StringBuffer sb = new StringBuffer("["); 667 for (int i = 0; i < docIds.size(); i++) { 668 sb.append(new Long(docIds.get(i)).toString() + ","); 669 } 670 return sb.append("]").toString(); 671 } 672 673 /** 674 * @see org.kuali.kfs.sys.document.GeneralLedgerPostingDocumentBase#doRouteStatusChange() 675 */ 676 @Override 677 public void doRouteStatusChange(DocumentRouteStatusChangeDTO statusChangeEvent) { 678 LOG.debug("doRouteStatusChange() started"); 679 super.doRouteStatusChange(statusChangeEvent); 680 String currentDocumentTypeName = this.getDocumentHeader().getWorkflowDocument().getDocumentType(); 681 // child classes need to call super, but we don't want to inherit the post-processing done by this PO class other than to the Split 682 if (PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_DOCUMENT.equals(currentDocumentTypeName) || PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_SPLIT_DOCUMENT.equals(currentDocumentTypeName)) { 683 try { 684 // DOCUMENT PROCESSED 685 if (getDocumentHeader().getWorkflowDocument().stateIsProcessed()) { 686 SpringContext.getBean(PurchaseOrderService.class).completePurchaseOrder(this); 687 } 688 // DOCUMENT DISAPPROVED 689 else if (getDocumentHeader().getWorkflowDocument().stateIsDisapproved()) { 690 String nodeName = SpringContext.getBean(WorkflowDocumentService.class).getCurrentRouteLevelName(getDocumentHeader().getWorkflowDocument()); 691 NodeDetails currentNode = NodeDetailEnum.getNodeDetailEnumByName(nodeName); 692 if (ObjectUtils.isNotNull(currentNode)) { 693 if (StringUtils.isNotBlank(currentNode.getDisapprovedStatusCode())) { 694 SpringContext.getBean(PurapService.class).updateStatus(this, currentNode.getDisapprovedStatusCode()); 695 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(this); 696 RequisitionDocument req = getPurApSourceDocumentIfPossible(); 697 appSpecificRouteDocumentToUser(getDocumentHeader().getWorkflowDocument(), req.getDocumentHeader().getWorkflowDocument().getRoutedByUserNetworkId(), "Notification of Order Disapproval for Requisition " + req.getPurapDocumentIdentifier() + "(document id " + req.getDocumentNumber() + ")", "Requisition Routed By User"); 698 return; 699 } 700 } 701 logAndThrowRuntimeException("No status found to set for document being disapproved in node '" + nodeName + "'"); 702 } 703 // DOCUMENT CANCELED 704 else if (getDocumentHeader().getWorkflowDocument().stateIsCanceled()) { 705 SpringContext.getBean(PurapService.class).updateStatus(this, PurchaseOrderStatuses.CANCELLED); 706 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(this); 707 } 708 } 709 catch (WorkflowException e) { 710 logAndThrowRuntimeException("Error saving routing data while saving document with id " + getDocumentNumber(), e); 711 } 712 } 713 } 714 715 /** 716 * Returns the name of the current route node. 717 * 718 * @param wd the current workflow document. 719 * @return the name of the current route node. 720 * @throws WorkflowException 721 */ 722 protected String getCurrentRouteNodeName(KualiWorkflowDocument wd) throws WorkflowException { 723 String[] nodeNames = wd.getNodeNames(); 724 if ((nodeNames == null) || (nodeNames.length == 0)) { 725 return null; 726 } 727 else { 728 return nodeNames[0]; 729 } 730 } 731 732 /** 733 * Sends FYI workflow request to the given user on this document. 734 * 735 * @param workflowDocument the associated workflow document. 736 * @param userNetworkId the network ID of the user to be sent to. 737 * @param annotation the annotation notes contained in this document. 738 * @param responsibility the responsibility specified in the request. 739 * @throws WorkflowException 740 */ 741 public void appSpecificRouteDocumentToUser(KualiWorkflowDocument workflowDocument, String userNetworkId, String annotation, String responsibility) throws WorkflowException { 742 if (ObjectUtils.isNotNull(workflowDocument)) { 743 String annotationNote = (ObjectUtils.isNull(annotation)) ? "" : annotation; 744 String responsibilityNote = (ObjectUtils.isNull(responsibility)) ? "" : responsibility; 745 String currentNodeName = getCurrentRouteNodeName(workflowDocument); 746 KimPrincipal principal = SpringContext.getBean(IdentityManagementService.class).getPrincipalByPrincipalName(userNetworkId); 747 workflowDocument.adHocRouteDocumentToPrincipal(KEWConstants.ACTION_REQUEST_FYI_REQ, currentNodeName, annotationNote, principal.getPrincipalId(), responsibilityNote, true); 748 } 749 } 750 751 /** 752 * @see org.kuali.rice.kns.document.DocumentBase#handleRouteLevelChange(org.kuali.rice.kew.clientapp.vo.DocumentRouteLevelChangeDTO) 753 */ 754 @Override 755 public void doRouteLevelChange(DocumentRouteLevelChangeDTO levelChangeEvent) { 756 LOG.debug("handleRouteLevelChange() started"); 757 super.doRouteLevelChange(levelChangeEvent); 758 759 LOG.debug("handleRouteLevelChange() started"); 760 String newNodeName = levelChangeEvent.getNewNodeName(); 761 if (StringUtils.isNotBlank(newNodeName)) { 762 ReportCriteriaDTO reportCriteriaDTO = new ReportCriteriaDTO(Long.valueOf(getDocumentNumber())); 763 reportCriteriaDTO.setTargetNodeName(newNodeName); 764 try { 765 NodeDetails newNodeDetails = NodeDetailEnum.getNodeDetailEnumByName(newNodeName); 766 if (ObjectUtils.isNotNull(newNodeDetails)) { 767 String newStatusCode = newNodeDetails.getAwaitingStatusCode(); 768 if (StringUtils.isNotBlank(newStatusCode)) { 769 if (SpringContext.getBean(KualiWorkflowInfo.class).documentWillHaveAtLeastOneActionRequest(reportCriteriaDTO, new String[] { KEWConstants.ACTION_REQUEST_APPROVE_REQ, KEWConstants.ACTION_REQUEST_COMPLETE_REQ }, false)) { 770 // if an approve or complete request will be created then we need to set the status as awaiting for 771 // the new node 772 SpringContext.getBean(PurapService.class).updateStatus(this, newStatusCode); 773 774 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(this); 775 } 776 } 777 } 778 } 779 catch (WorkflowException e) { 780 String errorMsg = "Workflow Error found checking actions requests on document with id " + getDocumentNumber() + ". *** WILL NOT UPDATE PURAP STATUS ***"; 781 LOG.warn(errorMsg, e); 782 } 783 } 784 } 785 786 /** 787 * @see org.kuali.rice.kns.document.DocumentBase#doActionTaken(org.kuali.rice.kew.clientapp.vo.ActionTakenEventDTO) 788 */ 789 @Override 790 public void doActionTaken(ActionTakenEventDTO event) { 791 super.doActionTaken(event); 792 // additional processing 793 } 794 795 /** 796 * Gets the active items in this Purchase Order. 797 * 798 * @return the list of all active items in this Purchase Order. 799 */ 800 public List getItemsActiveOnly() { 801 List returnList = new ArrayList(); 802 for (Iterator iter = getItems().iterator(); iter.hasNext();) { 803 PurchaseOrderItem item = (PurchaseOrderItem) iter.next(); 804 if (item.isItemActiveIndicator()) { 805 returnList.add(item); 806 } 807 } 808 return returnList; 809 } 810 811 /** 812 * Gets the active items in this Purchase Order, and sets up the alternate amount for GL entry creation. 813 * 814 * @return the list of all active items in this Purchase Order. 815 */ 816 public List getItemsActiveOnlySetupAlternateAmount() { 817 List returnList = new ArrayList(); 818 for (Iterator iter = getItems().iterator(); iter.hasNext();) { 819 PurchaseOrderItem item = (PurchaseOrderItem) iter.next(); 820 if (item.isItemActiveIndicator()) { 821 for (Iterator iterator = item.getSourceAccountingLines().iterator(); iterator.hasNext();) { 822 PurchaseOrderAccount account = (PurchaseOrderAccount) iterator.next(); 823 account.setAlternateAmountForGLEntryCreation(account.getItemAccountOutstandingEncumbranceAmount()); 824 } 825 returnList.add(item); 826 } 827 } 828 return returnList; 829 } 830 831 public Integer getAlternateVendorDetailAssignedIdentifier() { 832 return alternateVendorDetailAssignedIdentifier; 833 } 834 835 public void setAlternateVendorDetailAssignedIdentifier(Integer alternateVendorDetailAssignedIdentifier) { 836 this.alternateVendorDetailAssignedIdentifier = alternateVendorDetailAssignedIdentifier; 837 } 838 839 public Integer getAlternateVendorHeaderGeneratedIdentifier() { 840 return alternateVendorHeaderGeneratedIdentifier; 841 } 842 843 public void setAlternateVendorHeaderGeneratedIdentifier(Integer alternateVendorHeaderGeneratedIdentifier) { 844 this.alternateVendorHeaderGeneratedIdentifier = alternateVendorHeaderGeneratedIdentifier; 845 } 846 847 public String getAlternateVendorName() { 848 return alternateVendorName; 849 } 850 851 public void setAlternateVendorName(String alternateVendorName) { 852 this.alternateVendorName = alternateVendorName; 853 } 854 855 public KualiDecimal getFinalPaymentAmount() { 856 return finalPaymentAmount; 857 } 858 859 public void setFinalPaymentAmount(KualiDecimal finalPaymentAmount) { 860 this.finalPaymentAmount = finalPaymentAmount; 861 } 862 863 public Date getFinalPaymentDate() { 864 return finalPaymentDate; 865 } 866 867 public void setFinalPaymentDate(Date finalPaymentDate) { 868 this.finalPaymentDate = finalPaymentDate; 869 } 870 871 public KualiDecimal getInitialPaymentAmount() { 872 return initialPaymentAmount; 873 } 874 875 public void setInitialPaymentAmount(KualiDecimal initialPaymentAmount) { 876 this.initialPaymentAmount = initialPaymentAmount; 877 } 878 879 public Date getInitialPaymentDate() { 880 return initialPaymentDate; 881 } 882 883 public void setInitialPaymentDate(Date initialPaymentDate) { 884 this.initialPaymentDate = initialPaymentDate; 885 } 886 887 public String getPurchaseOrderCommodityDescription() { 888 return purchaseOrderCommodityDescription; 889 } 890 891 public void setPurchaseOrderCommodityDescription(String purchaseOrderCommodityDescription) { 892 this.purchaseOrderCommodityDescription = purchaseOrderCommodityDescription; 893 } 894 895 public boolean isPurchaseOrderConfirmedIndicator() { 896 return purchaseOrderConfirmedIndicator; 897 } 898 899 public void setPurchaseOrderConfirmedIndicator(boolean purchaseOrderConfirmedIndicator) { 900 this.purchaseOrderConfirmedIndicator = purchaseOrderConfirmedIndicator; 901 } 902 903 public Timestamp getPurchaseOrderCreateTimestamp() { 904 return purchaseOrderCreateTimestamp; 905 } 906 907 public void setPurchaseOrderCreateTimestamp(Timestamp purchaseOrderCreateTimestamp) { 908 this.purchaseOrderCreateTimestamp = purchaseOrderCreateTimestamp; 909 } 910 911 public Timestamp getPurchaseOrderInitialOpenTimestamp() { 912 return purchaseOrderInitialOpenTimestamp; 913 } 914 915 public void setPurchaseOrderInitialOpenTimestamp(Timestamp purchaseOrderInitialOpenDate) { 916 this.purchaseOrderInitialOpenTimestamp = purchaseOrderInitialOpenDate; 917 } 918 919 public Timestamp getPurchaseOrderLastTransmitTimestamp() { 920 return purchaseOrderLastTransmitTimestamp; 921 } 922 923 public void setPurchaseOrderLastTransmitTimestamp(Timestamp PurchaseOrderLastTransmitTimestamp) { 924 this.purchaseOrderLastTransmitTimestamp = PurchaseOrderLastTransmitTimestamp; 925 } 926 927 public Integer getPurchaseOrderPreviousIdentifier() { 928 return purchaseOrderPreviousIdentifier; 929 } 930 931 public void setPurchaseOrderPreviousIdentifier(Integer purchaseOrderPreviousIdentifier) { 932 this.purchaseOrderPreviousIdentifier = purchaseOrderPreviousIdentifier; 933 } 934 935 public Date getPurchaseOrderQuoteDueDate() { 936 return purchaseOrderQuoteDueDate; 937 } 938 939 public void setPurchaseOrderQuoteDueDate(Date purchaseOrderQuoteDueDate) { 940 this.purchaseOrderQuoteDueDate = purchaseOrderQuoteDueDate; 941 } 942 943 public String getPurchaseOrderQuoteTypeDescription() { 944 String descript = purchaseOrderQuoteTypeCode; 945 if (PurapConstants.QuoteTypes.COMPETITIVE.equals(purchaseOrderQuoteTypeCode)) { 946 descript = QuoteTypeDescriptions.COMPETITIVE; 947 } 948 else if (PurapConstants.QuoteTypes.PRICE_CONFIRMATION.equals(purchaseOrderQuoteTypeCode)){ 949 descript = QuoteTypeDescriptions.PRICE_CONFIRMATION; 950 } 951 return descript; 952 } 953 954 public String getPurchaseOrderQuoteTypeCode() { 955 return purchaseOrderQuoteTypeCode; 956 } 957 958 public void setPurchaseOrderQuoteTypeCode(String purchaseOrderQuoteTypeCode) { 959 this.purchaseOrderQuoteTypeCode = purchaseOrderQuoteTypeCode; 960 } 961 962 public String getPurchaseOrderQuoteVendorNoteText() { 963 return purchaseOrderQuoteVendorNoteText; 964 } 965 966 public void setPurchaseOrderQuoteVendorNoteText(String purchaseOrderQuoteVendorNoteText) { 967 this.purchaseOrderQuoteVendorNoteText = purchaseOrderQuoteVendorNoteText; 968 } 969 970 public String getPurchaseOrderVendorChoiceCode() { 971 return purchaseOrderVendorChoiceCode; 972 } 973 974 public void setPurchaseOrderVendorChoiceCode(String purchaseOrderVendorChoiceCode) { 975 this.purchaseOrderVendorChoiceCode = purchaseOrderVendorChoiceCode; 976 } 977 978 public KualiDecimal getRecurringPaymentAmount() { 979 return recurringPaymentAmount; 980 } 981 982 public void setRecurringPaymentAmount(KualiDecimal recurringPaymentAmount) { 983 this.recurringPaymentAmount = recurringPaymentAmount; 984 } 985 986 public Date getRecurringPaymentDate() { 987 return recurringPaymentDate; 988 } 989 990 public void setRecurringPaymentDate(Date recurringPaymentDate) { 991 this.recurringPaymentDate = recurringPaymentDate; 992 } 993 994 public String getRecurringPaymentFrequencyCode() { 995 return recurringPaymentFrequencyCode; 996 } 997 998 public void setRecurringPaymentFrequencyCode(String recurringPaymentFrequencyCode) { 999 this.recurringPaymentFrequencyCode = recurringPaymentFrequencyCode; 1000 } 1001 1002 public Integer getRequisitionIdentifier() { 1003 return requisitionIdentifier; 1004 } 1005 1006 public void setRequisitionIdentifier(Integer requisitionIdentifier) { 1007 this.requisitionIdentifier = requisitionIdentifier; 1008 } 1009 1010 public PurchaseOrderVendorChoice getPurchaseOrderVendorChoice() { 1011 return purchaseOrderVendorChoice; 1012 } 1013 1014 public void setPurchaseOrderVendorChoice(PurchaseOrderVendorChoice purchaseOrderVendorChoice) { 1015 this.purchaseOrderVendorChoice = purchaseOrderVendorChoice; 1016 } 1017 1018 public RecurringPaymentFrequency getRecurringPaymentFrequency() { 1019 return recurringPaymentFrequency; 1020 } 1021 1022 public void setRecurringPaymentFrequency(RecurringPaymentFrequency recurringPaymentFrequency) { 1023 this.recurringPaymentFrequency = recurringPaymentFrequency; 1024 } 1025 1026 public PaymentTermType getVendorPaymentTerms() { 1027 return vendorPaymentTerms; 1028 } 1029 1030 public void setVendorPaymentTerms(PaymentTermType vendorPaymentTerms) { 1031 this.vendorPaymentTerms = vendorPaymentTerms; 1032 } 1033 1034 public ShippingPaymentTerms getVendorShippingPaymentTerms() { 1035 return vendorShippingPaymentTerms; 1036 } 1037 1038 public void setVendorShippingPaymentTerms(ShippingPaymentTerms vendorShippingPaymentTerms) { 1039 this.vendorShippingPaymentTerms = vendorShippingPaymentTerms; 1040 } 1041 1042 public ShippingTitle getVendorShippingTitle() { 1043 1044 if( ObjectUtils.isNull(vendorShippingTitle) ){ 1045 this.refreshReferenceObject("vendorShippingTitle"); 1046 } 1047 1048 return vendorShippingTitle; 1049 } 1050 1051 public void setVendorShippingTitle(ShippingTitle vendorShippingTitle) { 1052 this.vendorShippingTitle = vendorShippingTitle; 1053 } 1054 1055 public List getPurchaseOrderVendorStipulations() { 1056 return purchaseOrderVendorStipulations; 1057 } 1058 1059 public String getStatusChange() { 1060 return statusChange; 1061 } 1062 1063 public void setPurchaseOrderVendorStipulations(List purchaseOrderVendorStipulations) { 1064 this.purchaseOrderVendorStipulations = purchaseOrderVendorStipulations; 1065 } 1066 1067 public List<PurchaseOrderVendorQuote> getPurchaseOrderVendorQuotes() { 1068 return purchaseOrderVendorQuotes; 1069 } 1070 1071 public void setPurchaseOrderVendorQuotes(List<PurchaseOrderVendorQuote> purchaseOrderVendorQuotes) { 1072 this.purchaseOrderVendorQuotes = purchaseOrderVendorQuotes; 1073 } 1074 1075 public PurchaseOrderVendorQuote getPurchaseOrderVendorQuote(int index) { 1076 while (getPurchaseOrderVendorQuotes().size() <= index) { 1077 getPurchaseOrderVendorQuotes().add(new PurchaseOrderVendorQuote()); 1078 } 1079 return (PurchaseOrderVendorQuote) purchaseOrderVendorQuotes.get(index); 1080 } 1081 1082 public void setStatusChange(String statusChange) { 1083 this.statusChange = statusChange; 1084 } 1085 1086 public String getPurchaseOrderRetransmissionMethodCode() { 1087 return purchaseOrderRetransmissionMethodCode; 1088 } 1089 1090 public void setPurchaseOrderRetransmissionMethodCode(String purchaseOrderRetransmissionMethodCode) { 1091 this.purchaseOrderRetransmissionMethodCode = purchaseOrderRetransmissionMethodCode; 1092 } 1093 1094 public String getRetransmitHeader() { 1095 return retransmitHeader; 1096 } 1097 1098 public void setRetransmitHeader(String retransmitHeader) { 1099 this.retransmitHeader = retransmitHeader; 1100 } 1101 1102 public boolean isPendingActionIndicator() { 1103 return pendingActionIndicator; 1104 } 1105 1106 public void setPendingActionIndicator(boolean pendingActionIndicator) { 1107 this.pendingActionIndicator = pendingActionIndicator; 1108 } 1109 1110 public boolean isPurchaseOrderCurrentIndicator() { 1111 return purchaseOrderCurrentIndicator; 1112 } 1113 1114 public void setPurchaseOrderCurrentIndicator(boolean purchaseOrderCurrentIndicator) { 1115 this.purchaseOrderCurrentIndicator = purchaseOrderCurrentIndicator; 1116 } 1117 1118 public Timestamp getPurchaseOrderFirstTransmissionTimestamp() { 1119 return purchaseOrderFirstTransmissionTimestamp; 1120 } 1121 1122 public void setPurchaseOrderFirstTransmissionTimestamp(Timestamp purchaseOrderFirstTransmissionTimestamp) { 1123 this.purchaseOrderFirstTransmissionTimestamp = purchaseOrderFirstTransmissionTimestamp; 1124 } 1125 1126 /** 1127 * Gets the purchaseOrderQuoteAwardedDate attribute. 1128 * @return Returns the purchaseOrderQuoteAwardedDate. 1129 */ 1130 public Date getPurchaseOrderQuoteAwardedDate() { 1131 return purchaseOrderQuoteAwardedDate; 1132 } 1133 1134 /** 1135 * Sets the purchaseOrderQuoteAwardedDate attribute value. 1136 * @param purchaseOrderQuoteAwardedDate The purchaseOrderQuoteAwardedDate to set. 1137 */ 1138 public void setPurchaseOrderQuoteAwardedDate(Date purchaseOrderQuoteAwardedDate) { 1139 this.purchaseOrderQuoteAwardedDate = purchaseOrderQuoteAwardedDate; 1140 } 1141 1142 /** 1143 * Gets the purchaseOrderQuoteInitializationDate attribute. 1144 * @return Returns the purchaseOrderQuoteInitializationDate. 1145 */ 1146 public Date getPurchaseOrderQuoteInitializationDate() { 1147 return purchaseOrderQuoteInitializationDate; 1148 } 1149 1150 /** 1151 * Sets the purchaseOrderQuoteInitializationDate attribute value. 1152 * @param purchaseOrderQuoteInitializationDate The purchaseOrderQuoteInitializationDate to set. 1153 */ 1154 public void setPurchaseOrderQuoteInitializationDate(Date purchaseOrderQuoteInitializationDate) { 1155 this.purchaseOrderQuoteInitializationDate = purchaseOrderQuoteInitializationDate; 1156 } 1157 1158 /** 1159 * Gets the alternateVendorNumber attribute. 1160 * 1161 * @return Returns the alternateVendorNumber. 1162 */ 1163 public String getAlternateVendorNumber() { 1164 String hdrGenId = ""; 1165 String detAssgndId = ""; 1166 String vendorNumber = ""; 1167 if (this.alternateVendorHeaderGeneratedIdentifier != null) { 1168 hdrGenId = this.alternateVendorHeaderGeneratedIdentifier.toString(); 1169 } 1170 if (this.alternateVendorDetailAssignedIdentifier != null) { 1171 detAssgndId = this.alternateVendorDetailAssignedIdentifier.toString(); 1172 } 1173 if (!StringUtils.isEmpty(hdrGenId) && !StringUtils.isEmpty(detAssgndId)) { 1174 vendorNumber = hdrGenId + "-" + detAssgndId; 1175 } 1176 return vendorNumber; 1177 } 1178 1179 /** 1180 * Sets the alternateVendorNumber attribute value. 1181 * 1182 * @param alternateVendorNumber The vendorNumber to set. 1183 */ 1184 public void setAlternateVendorNumber(String vendorNumber) { 1185 if (!StringUtils.isEmpty(vendorNumber)) { 1186 int dashInd = vendorNumber.indexOf("-"); 1187 if (vendorNumber.length() >= dashInd) { 1188 String vndrHdrGenId = vendorNumber.substring(0, dashInd); 1189 String vndrDetailAssgnedId = vendorNumber.substring(dashInd + 1); 1190 if (!StringUtils.isEmpty(vndrHdrGenId) && !StringUtils.isEmpty(vndrDetailAssgnedId)) { 1191 this.alternateVendorHeaderGeneratedIdentifier = new Integer(vndrHdrGenId); 1192 this.alternateVendorDetailAssignedIdentifier = new Integer(vndrDetailAssgnedId); 1193 } 1194 } 1195 } 1196 else { 1197 this.alternateVendorNumber = vendorNumber; 1198 } 1199 } 1200 1201 /** 1202 * Sets alternate vendor fields based on a given VendorDetail. 1203 * 1204 * @param vendorDetail the vendor detail used to set vendor fields. 1205 */ 1206 public void templateAlternateVendor(VendorDetail vendorDetail) { 1207 if (vendorDetail == null) { 1208 return; 1209 } 1210 this.setAlternateVendorNumber(vendorDetail.getVendorHeaderGeneratedIdentifier() + VendorConstants.DASH + vendorDetail.getVendorDetailAssignedIdentifier()); 1211 this.setAlternateVendorName(vendorDetail.getVendorName()); 1212 } 1213 1214 /** 1215 * Overriding this from the super class so that Note will use only the oldest PurchaseOrderDocument as the 1216 * documentBusinessObject. 1217 * 1218 * @see org.kuali.rice.kns.document.Document#getDocumentBusinessObject() 1219 */ 1220 @Override 1221 public PersistableBusinessObject getDocumentBusinessObject() { 1222 if (ObjectUtils.isNotNull(getPurapDocumentIdentifier()) && ((ObjectUtils.isNull(documentBusinessObject)) || ObjectUtils.isNull(((PurchaseOrderDocument) documentBusinessObject).getPurapDocumentIdentifier()))) { 1223 refreshDocumentBusinessObject(); 1224 } 1225 else if (ObjectUtils.isNull(getPurapDocumentIdentifier()) && ObjectUtils.isNull(documentBusinessObject)) { 1226 // needed to keep populate happy 1227 documentBusinessObject = new PurchaseOrderDocument(); 1228 } 1229 return documentBusinessObject; 1230 } 1231 1232 public void refreshDocumentBusinessObject() { 1233 documentBusinessObject = SpringContext.getBean(PurchaseOrderService.class).getOldestPurchaseOrder(this, (PurchaseOrderDocument) this.documentBusinessObject); 1234 } 1235 1236 public void setDocumentBusinessObject(PurchaseOrderDocument po) { 1237 documentBusinessObject = po; 1238 } 1239 1240 /** 1241 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getItemClass() 1242 */ 1243 @Override 1244 public Class getItemClass() { 1245 return PurchaseOrderItem.class; 1246 } 1247 1248 @Override 1249 public Class getItemUseTaxClass() { 1250 return PurchaseOrderItemUseTax.class; 1251 } 1252 1253 /** 1254 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getPurApSourceDocumentIfPossible() 1255 */ 1256 @Override 1257 public RequisitionDocument getPurApSourceDocumentIfPossible() { 1258 RequisitionDocument sourceDoc = null; 1259 if (ObjectUtils.isNotNull(getRequisitionIdentifier())) { 1260 sourceDoc = SpringContext.getBean(RequisitionService.class).getRequisitionById(getRequisitionIdentifier()); 1261 } 1262 return sourceDoc; 1263 } 1264 1265 /** 1266 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getPurApSourceDocumentLabelIfPossible() 1267 */ 1268 @Override 1269 public String getPurApSourceDocumentLabelIfPossible() { 1270 return SpringContext.getBean(DataDictionaryService.class).getDocumentLabelByTypeName(KFSConstants.FinancialDocumentTypeCodes.REQUISITION); 1271 } 1272 1273 public Integer getNewQuoteVendorDetailAssignedIdentifier() { 1274 return newQuoteVendorDetailAssignedIdentifier; 1275 } 1276 1277 public void setNewQuoteVendorDetailAssignedIdentifier(Integer newQuoteVendorDetailAssignedIdentifier) { 1278 this.newQuoteVendorDetailAssignedIdentifier = newQuoteVendorDetailAssignedIdentifier; 1279 } 1280 1281 public Integer getNewQuoteVendorHeaderGeneratedIdentifier() { 1282 return newQuoteVendorHeaderGeneratedIdentifier; 1283 } 1284 1285 public void setNewQuoteVendorHeaderGeneratedIdentifier(Integer newQuoteVendorHeaderGeneratedIdentifier) { 1286 this.newQuoteVendorHeaderGeneratedIdentifier = newQuoteVendorHeaderGeneratedIdentifier; 1287 } 1288 1289 public Integer getPurchaseOrderQuoteListIdentifier() { 1290 return purchaseOrderQuoteListIdentifier; 1291 } 1292 1293 public void setPurchaseOrderQuoteListIdentifier(Integer purchaseOrderQuoteListIdentifier) { 1294 this.purchaseOrderQuoteListIdentifier = purchaseOrderQuoteListIdentifier; 1295 } 1296 1297 /** 1298 * Returns true if a vendor has been awarded for this Purchase Order. 1299 * 1300 * @return true if a vendor has been awarded for this Purchase Order. 1301 */ 1302 public boolean isPurchaseOrderAwarded() { 1303 return (getAwardedVendorQuote() != null); 1304 } 1305 1306 /** 1307 * Returns the quote from the awarded vendor. 1308 * 1309 * @return the quote from the awarded vendor. 1310 */ 1311 public PurchaseOrderVendorQuote getAwardedVendorQuote() { 1312 for (PurchaseOrderVendorQuote vendorQuote : purchaseOrderVendorQuotes) { 1313 if (vendorQuote.getPurchaseOrderQuoteAwardTimestamp() != null) { 1314 return vendorQuote; 1315 } 1316 } 1317 return null; 1318 } 1319 1320 /** 1321 * @see org.kuali.kfs.module.purap.document.PurchasingDocumentBase#getTotalDollarAmount() 1322 */ 1323 @Override 1324 public KualiDecimal getTotalDollarAmount() { 1325 // return total without inactive and with below the line 1326 return getTotalDollarAmount(false, true); 1327 } 1328 1329 /** 1330 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getTotalDollarAmountAboveLineItems() 1331 */ 1332 @Override 1333 public KualiDecimal getTotalDollarAmountAboveLineItems() { 1334 return getTotalDollarAmount(false, false); 1335 } 1336 1337 /** 1338 * Gets the total dollar amount for this Purchase Order. 1339 * 1340 * @param includeInactive indicates whether inactive items shall be included. 1341 * @param includeBelowTheLine indicates whether below the line items shall be included. 1342 * @return the total dollar amount for this Purchase Order. 1343 */ 1344 public KualiDecimal getTotalDollarAmount(boolean includeInactive, boolean includeBelowTheLine) { 1345 KualiDecimal total = new KualiDecimal(BigDecimal.ZERO); 1346 for (PurApItem item : (List<PurApItem>) getItems()) { 1347 1348 if (item.getPurapDocument() == null) { 1349 item.setPurapDocument(this); 1350 } 1351 ItemType it = item.getItemType(); 1352 if ((includeBelowTheLine || it.isLineItemIndicator()) && (includeInactive || PurApItemUtils.checkItemActive(item))) { 1353 KualiDecimal totalAmount = item.getTotalAmount(); 1354 KualiDecimal itemTotal = (totalAmount != null) ? totalAmount : KualiDecimal.ZERO; 1355 total = total.add(itemTotal); 1356 } 1357 } 1358 return total; 1359 } 1360 1361 /** 1362 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getTotalPreTaxDollarAmount() 1363 */ 1364 @Override 1365 public KualiDecimal getTotalPreTaxDollarAmount() { 1366 // return total without inactive and with below the line 1367 return getTotalPreTaxDollarAmount(false, true); 1368 } 1369 1370 /** 1371 * @see org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase#getTotalPreTaxDollarAmountAboveLineItems() 1372 */ 1373 @Override 1374 public KualiDecimal getTotalPreTaxDollarAmountAboveLineItems() { 1375 return getTotalPreTaxDollarAmount(false, false); 1376 } 1377 1378 /** 1379 * Gets the pre tax total dollar amount for this Purchase Order. 1380 * 1381 * @param includeInactive indicates whether inactive items shall be included. 1382 * @param includeBelowTheLine indicates whether below the line items shall be included. 1383 * @return the total dollar amount for this Purchase Order. 1384 */ 1385 public KualiDecimal getTotalPreTaxDollarAmount(boolean includeInactive, boolean includeBelowTheLine) { 1386 KualiDecimal total = new KualiDecimal(BigDecimal.ZERO); 1387 for (PurchaseOrderItem item : (List<PurchaseOrderItem>) getItems()) { 1388 ItemType it = item.getItemType(); 1389 if ((includeBelowTheLine || it.isLineItemIndicator()) && (includeInactive || item.isItemActiveIndicator())) { 1390 KualiDecimal extendedPrice = item.getExtendedPrice(); 1391 KualiDecimal itemTotal = (extendedPrice != null) ? extendedPrice : KualiDecimal.ZERO; 1392 total = total.add(itemTotal); 1393 } 1394 } 1395 return total; 1396 } 1397 1398 1399 @Override 1400 public KualiDecimal getTotalTaxAmount() { 1401 // return total without inactive and with below the line 1402 return getTotalTaxAmount(false, true); 1403 } 1404 1405 @Override 1406 public KualiDecimal getTotalTaxAmountAboveLineItems() { 1407 return getTotalTaxAmount(false, false); 1408 } 1409 1410 /** 1411 * Gets the tax total amount for this Purchase Order. 1412 * 1413 * @param includeInactive indicates whether inactive items shall be included. 1414 * @param includeBelowTheLine indicates whether below the line items shall be included. 1415 * @return the total dollar amount for this Purchase Order. 1416 */ 1417 public KualiDecimal getTotalTaxAmount(boolean includeInactive, boolean includeBelowTheLine) { 1418 KualiDecimal total = new KualiDecimal(BigDecimal.ZERO); 1419 for (PurchaseOrderItem item : (List<PurchaseOrderItem>) getItems()) { 1420 ItemType it = item.getItemType(); 1421 if ((includeBelowTheLine || it.isLineItemIndicator()) && (includeInactive || item.isItemActiveIndicator())) { 1422 KualiDecimal taxAmount = item.getItemTaxAmount(); 1423 KualiDecimal itemTotal = (taxAmount != null) ? taxAmount : KualiDecimal.ZERO; 1424 total = total.add(itemTotal); 1425 } 1426 } 1427 return total; 1428 } 1429 1430 /** 1431 * Returns true if this Purchase Order contains unpaid items in the Payment Request or Credit Memo. 1432 * 1433 * @return true if this Purchase Order contains unpaid items in the Payment Request or Credit Memo. 1434 */ 1435 public boolean getContainsUnpaidPaymentRequestsOrCreditMemos() { 1436 if (getRelatedViews().getRelatedPaymentRequestViews() != null) { 1437 for (PaymentRequestView element : getRelatedViews().getRelatedPaymentRequestViews()) { 1438 // If the PREQ is neither cancelled nor voided, check whether the PREQ has been paid. 1439 // If it has not been paid, then this method will return true. 1440 if (!PurapConstants.PaymentRequestStatuses.CANCELLED_STATUSES.contains(element.getStatusCode())) { 1441 if (element.getPaymentPaidTimestamp() == null) { 1442 return true; 1443 } 1444 } 1445 }// endfor 1446 } 1447 if (getRelatedViews().getRelatedCreditMemoViews() != null) { 1448 for (CreditMemoView element : getRelatedViews().getRelatedCreditMemoViews()) { 1449 // If the CM is cancelled, check whether the CM has been paid. 1450 // If it has not been paid, then this method will return true. 1451 if (!CreditMemoStatuses.CANCELLED_STATUSES.contains(element.getCreditMemoStatusCode())) { 1452 if (element.getCreditMemoPaidTimestamp() == null) { 1453 return true; 1454 } 1455 } 1456 }// endfor 1457 } 1458 return false; 1459 } 1460 1461 public boolean getAdditionalChargesExist() { 1462 List<PurchaseOrderItem> items = this.getItems(); 1463 for( PurchaseOrderItem item : items ) { 1464 if ((item != null) && 1465 (item.getItemType() != null) && 1466 (item.getItemType().isAdditionalChargeIndicator()) && 1467 (item.getExtendedPrice() != null) && 1468 (!KualiDecimal.ZERO.equals(item.getExtendedPrice()))) { 1469 return true; 1470 } 1471 } 1472 return false; 1473 } 1474 1475 /** 1476 * Used for routing only. 1477 * 1478 * @deprecated 1479 */ 1480 public String getContractManagerName() { 1481 return ""; 1482 } 1483 1484 /** 1485 * Used for routing only. 1486 * 1487 * @deprecated 1488 */ 1489 public void setContractManagerName(String contractManagerName) { 1490 } 1491 1492 /** 1493 * Used for routing only. 1494 * 1495 * @deprecated 1496 */ 1497 public String getStatusDescription() { 1498 return ""; 1499 } 1500 1501 /** 1502 * Used for routing only. 1503 * 1504 * @deprecated 1505 */ 1506 public void setStatusDescription(String statusDescription) { 1507 } 1508 1509 public KualiDecimal getInternalPurchasingLimit() { 1510 //FIXME need the following because at places this field remains null because contract manager is not refreshed and null 1511 1512 if (internalPurchasingLimit == null) { 1513 setInternalPurchasingLimit(SpringContext.getBean(PurchaseOrderService.class).getInternalPurchasingDollarLimit(this)); 1514 } 1515 return internalPurchasingLimit; 1516 } 1517 1518 public void setInternalPurchasingLimit(KualiDecimal internalPurchasingLimit) { 1519 this.internalPurchasingLimit = internalPurchasingLimit; 1520 } 1521 1522 public boolean isPendingSplit() { 1523 return pendingSplit; 1524 } 1525 1526 public void setPendingSplit(boolean pendingSplit) { 1527 this.pendingSplit = pendingSplit; 1528 } 1529 1530 public boolean isCopyingNotesWhenSplitting() { 1531 return copyingNotesWhenSplitting; 1532 } 1533 1534 public void setCopyingNotesWhenSplitting(boolean copyingNotesWhenSplitting) { 1535 this.copyingNotesWhenSplitting = copyingNotesWhenSplitting; 1536 } 1537 1538 /** 1539 * @see org.kuali.module.purap.rules.PurapAccountingDocumentRuleBase#customizeExplicitGeneralLedgerPendingEntry(org.kuali.kfs.sys.document.AccountingDocument, 1540 * org.kuali.kfs.sys.businessobject.AccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry) 1541 */ 1542 @Override 1543 public void customizeExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry) { 1544 super.customizeExplicitGeneralLedgerPendingEntry(postable, explicitEntry); 1545 1546 SpringContext.getBean(PurapGeneralLedgerService.class).customizeGeneralLedgerPendingEntry(this, (AccountingLine)postable, explicitEntry, getPurapDocumentIdentifier(), GL_DEBIT_CODE, PurapDocTypeCodes.PO_DOCUMENT, true); 1547 1548 // don't think i should have to override this, but default isn't getting the right PO doc 1549 explicitEntry.setFinancialDocumentTypeCode(PurapDocTypeCodes.PO_DOCUMENT); 1550 } 1551 1552 @Override 1553 public Class getPurchasingCapitalAssetItemClass() { 1554 return PurchaseOrderCapitalAssetItem.class; 1555 } 1556 1557 @Override 1558 public Class getPurchasingCapitalAssetSystemClass() { 1559 return PurchaseOrderCapitalAssetSystem.class; 1560 } 1561 1562 /** 1563 * Validates whether we can indeed close the PO. Return false and give error if 1564 * the outstanding encumbrance amount of the trade in item is less than 0. 1565 * 1566 * @param po 1567 * @return 1568 */ 1569 public boolean canClosePOForTradeIn () { 1570 for (PurchaseOrderItem item : (List<PurchaseOrderItem>)getItems()) { 1571 if (item.getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_TRADE_IN_CODE) && item.getItemOutstandingEncumberedAmount().isLessThan(new KualiDecimal(0))) { 1572 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_TRADE_IN_OUTSTANDING_ENCUMBERED_AMOUNT_NEGATIVE, "amend the PO"); 1573 return false; 1574 } 1575 } 1576 return true; 1577 } 1578 1579 /** 1580 * Provides answers to the following splits: 1581 * RequiresContractManagementReview 1582 * RequiresBudgetReview 1583 * VendorIsEmployeeOrNonResidentAlien 1584 * TransmissionMethodIsPrint 1585 * 1586 * @see org.kuali.kfs.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String) 1587 */ 1588 @Override 1589 public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException { 1590 if (nodeName.equals(PurapWorkflowConstants.CONTRACT_MANAGEMENT_REVIEW_REQUIRED)) return isContractManagementReviewRequired(); 1591 if (nodeName.equals(PurapWorkflowConstants.AWARD_REVIEW_REQUIRED)) return isAwardReviewRequired(); 1592 if (nodeName.equals(PurapWorkflowConstants.BUDGET_REVIEW_REQUIRED)) return isBudgetReviewRequired(); 1593 if (nodeName.equals(PurapWorkflowConstants.VENDOR_IS_EMPLOYEE_OR_NON_RESIDENT_ALIEN)) return isVendorEmployeeOrNonResidentAlien(); 1594 throw new UnsupportedOperationException("Cannot answer split question for this node you call \""+nodeName+"\""); 1595 } 1596 1597 protected boolean isContractManagementReviewRequired() { 1598 KualiDecimal internalPurchasingLimit = SpringContext.getBean(PurchaseOrderService.class).getInternalPurchasingDollarLimit(this); 1599 return ((ObjectUtils.isNull(internalPurchasingLimit)) || (internalPurchasingLimit.compareTo(this.getTotalDollarAmount()) < 0)); 1600 1601 } 1602 1603 protected boolean isAwardReviewRequired() { 1604 ParameterService parameterService = SpringContext.getBean(ParameterService.class); 1605 boolean objectCodeAllowed = true; 1606 1607 for (PurApItem item : (List<PurApItem>) this.getItems()) { 1608 for (PurApAccountingLine accountingLine : item.getSourceAccountingLines()) { 1609 1610 objectCodeAllowed = isObjectCodeAllowedForAwardRouting(accountingLine, parameterService); 1611 // We should return true as soon as we have at least one objectCodeAllowed=true so that the PO will stop at Award 1612 // level. 1613 if (objectCodeAllowed) { 1614 return objectCodeAllowed; 1615 } 1616 1617 } 1618 } 1619 return objectCodeAllowed; 1620 } 1621 1622 protected boolean isObjectCodeAllowedForAwardRouting(PurApAccountingLine accountingLine, ParameterService parameterService) { 1623 if (ObjectUtils.isNull(accountingLine.getObjectCode())) { 1624 return false; 1625 } 1626 1627 // make sure object code is active 1628 if (!accountingLine.getObjectCode().isFinancialObjectActiveCode()) { 1629 return false; 1630 } 1631 1632 String chartCode = accountingLine.getChartOfAccountsCode(); 1633 // check object level is in permitted list for award routing 1634 boolean objectCodeAllowed = parameterService.getParameterEvaluator(PurchaseOrderDocument.class, PurapParameterConstants.CG_ROUTE_OBJECT_LEVELS_BY_CHART, PurapParameterConstants.NO_CG_ROUTE_OBJECT_LEVELS_BY_CHART, chartCode, accountingLine.getObjectCode().getFinancialObjectLevelCode()).evaluationSucceeds(); 1635 1636 if (!objectCodeAllowed) { 1637 // If the object level is not permitting for award routing, then we need to also 1638 // check object code is in permitted list for award routing 1639 objectCodeAllowed = parameterService.getParameterEvaluator(PurchaseOrderDocument.class, PurapParameterConstants.CG_ROUTE_OBJECT_CODES_BY_CHART, PurapParameterConstants.NO_CG_ROUTE_OBJECT_CODES_BY_CHART, chartCode, accountingLine.getFinancialObjectCode()).evaluationSucceeds(); 1640 } 1641 return objectCodeAllowed; 1642 } 1643 1644 protected boolean isBudgetReviewRequired() { 1645 boolean alwaysRoutes = true; 1646 String documentHeaderId = null; 1647 String currentXpathExpression = null; 1648 String documentFiscalYearString = this.getPostingYear().toString(); 1649 1650 // if document's fiscal year is less than or equal to the current fiscal year 1651 if (SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear().compareTo(Integer.valueOf(documentFiscalYearString)) >= 0) { 1652 // get list of sufficientfundItems 1653 List<SufficientFundsItem> fundsItems = SpringContext.getBean(SufficientFundsService.class).checkSufficientFunds(getPendingLedgerEntriesForSufficientFundsChecking()); 1654 for (SufficientFundsItem fundsItem : fundsItems) { 1655 if (this.getChartOfAccountsCode().equalsIgnoreCase(fundsItem.getAccount().getChartOfAccountsCode())) { 1656 LOG.debug("Chart code of rule extension matches chart code of at least one Sufficient Funds Item"); 1657 return true; 1658 } 1659 } 1660 } 1661 1662 return false; 1663 } 1664 1665 1666 protected boolean isVendorEmployeeOrNonResidentAlien() { 1667 if (ObjectUtils.isNull(this.getVendorHeaderGeneratedIdentifier())) { 1668 // no vendor header id so can't check for proper tax routing 1669 return false; 1670 } 1671 String vendorHeaderGeneratedId = this.getVendorHeaderGeneratedIdentifier().toString(); 1672 VendorService vendorService = SpringContext.getBean(VendorService.class); 1673 boolean routeDocumentAsEmployeeVendor = vendorService.isVendorInstitutionEmployee(Integer.valueOf(vendorHeaderGeneratedId)); 1674 boolean routeDocumentAsForeignVendor = vendorService.isVendorForeign(Integer.valueOf(vendorHeaderGeneratedId)); 1675 if ((!routeDocumentAsEmployeeVendor) && (!routeDocumentAsForeignVendor)) { 1676 // no need to route 1677 return false; 1678 } 1679 1680 return true; 1681 } 1682 1683 public List<Account> getAccountsForAwardRouting() { 1684 List<Account> accounts = new ArrayList<Account>(); 1685 1686 ParameterService parameterService = SpringContext.getBean(ParameterService.class); 1687 for (PurApItem item : (List<PurApItem>) this.getItems()) { 1688 for (PurApAccountingLine accountingLine : item.getSourceAccountingLines()) { 1689 if (isObjectCodeAllowedForAwardRouting(accountingLine, parameterService)) { 1690 if (ObjectUtils.isNull(accountingLine.getAccount())) { 1691 accountingLine.refreshReferenceObject("account"); 1692 } 1693 if (accountingLine.getAccount() != null && !accounts.contains(accountingLine.getAccount())) { 1694 accounts.add(accountingLine.getAccount()); 1695 } 1696 } 1697 } 1698 } 1699 return accounts; 1700 } 1701 1702 public DocSearchCriteriaDTO convertSelections(DocSearchCriteriaDTO searchCriteria) { 1703 1704 for (SearchAttributeCriteriaComponent comp : searchCriteria.getSearchableAttributes()) { 1705 if (comp.getLookupableFieldType().equals(Field.MULTISELECT)) { 1706 List<String> values = comp.getValues(); 1707 List<String> newVals = new ArrayList<String>(); 1708 if (values.contains("INCOMPLETE")) { 1709 for (String str : PurchaseOrderStatuses.INCOMPLETE_STATUSES) 1710 newVals.add(str); 1711 } if (values.contains("COMPLETE")) { 1712 for (String str : PurchaseOrderStatuses.COMPLETE_STATUSES) 1713 newVals.add(str); 1714 } 1715 1716 for (String str : values) { 1717 newVals.add(str); 1718 } 1719 1720 comp.setValues(newVals); 1721 } 1722 } 1723 return searchCriteria; 1724 } 1725 1726 /** 1727 * @return the purchase order current indicator 1728 */ 1729 public boolean getPurchaseOrderCurrentIndicatorForSearching() { 1730 return purchaseOrderCurrentIndicator; 1731 } 1732 1733 public String getDocumentTitleForResult() throws WorkflowException{ 1734 return SpringContext.getBean(KualiWorkflowInfo.class).getDocType(this.getDocumentHeader().getWorkflowDocument().getDocumentType()).getDocTypeLabel(); 1735 } 1736 1737 /** 1738 * Checks whether the purchase order needs a warning to be displayed, i.e. it never has been opened. 1739 * @return true if the purchase order needs a warning; false otherwise. 1740 */ 1741 public boolean getNeedWarning() { 1742 return getPurchaseOrderInitialOpenTimestamp() == null; 1743 } 1744 1745 public List<SourceAccountingLine> getGlOnlySourceAccountingLines() { 1746 return glOnlySourceAccountingLines; 1747 } 1748 1749 public void setGlOnlySourceAccountingLines(List<SourceAccountingLine> glOnlySourceAccountingLines) { 1750 this.glOnlySourceAccountingLines = glOnlySourceAccountingLines; 1751 } 1752 1753 }