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 }