0001: /*
0002: * Copyright 2007 The Kuali Foundation.
0003: *
0004: * Licensed under the Educational Community License, Version 1.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.opensource.org/licenses/ecl1.php
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016:
0017: package org.kuali.module.purap.document;
0018:
0019: import java.sql.Date;
0020: import java.util.ArrayList;
0021: import java.util.Arrays;
0022: import java.util.HashMap;
0023: import java.util.Iterator;
0024: import java.util.List;
0025:
0026: import org.apache.commons.lang.StringUtils;
0027: import org.kuali.core.bo.user.UniversalUser;
0028: import org.kuali.core.document.Document;
0029: import org.kuali.core.exceptions.UserNotFoundException;
0030: import org.kuali.core.rule.event.KualiDocumentEvent;
0031: import org.kuali.core.service.DataDictionaryService;
0032: import org.kuali.core.service.DateTimeService;
0033: import org.kuali.core.service.UniversalUserService;
0034: import org.kuali.core.util.GlobalVariables;
0035: import org.kuali.core.util.KualiDecimal;
0036: import org.kuali.core.util.ObjectUtils;
0037: import org.kuali.core.workflow.service.KualiWorkflowDocument;
0038: import org.kuali.core.workflow.service.WorkflowDocumentService;
0039: import org.kuali.kfs.context.SpringContext;
0040: import org.kuali.kfs.service.ConciseXmlDocumentConversionService;
0041: import org.kuali.kfs.service.ParameterService;
0042: import org.kuali.module.purap.PurapConstants;
0043: import org.kuali.module.purap.PurapParameterConstants;
0044: import org.kuali.module.purap.PurapPropertyConstants;
0045: import org.kuali.module.purap.PurapConstants.PaymentRequestStatuses;
0046: import org.kuali.module.purap.PurapWorkflowConstants.NodeDetails;
0047: import org.kuali.module.purap.PurapWorkflowConstants.PaymentRequestDocument.NodeDetailEnum;
0048: import org.kuali.module.purap.bo.ItemType;
0049: import org.kuali.module.purap.bo.PaymentRequestItem;
0050: import org.kuali.module.purap.bo.PurApAccountingLine;
0051: import org.kuali.module.purap.bo.PurApItem;
0052: import org.kuali.module.purap.bo.PurchaseOrderItem;
0053: import org.kuali.module.purap.bo.RecurringPaymentType;
0054: import org.kuali.module.purap.rule.event.ContinueAccountsPayableEvent;
0055: import org.kuali.module.purap.service.AccountsPayableDocumentSpecificService;
0056: import org.kuali.module.purap.service.AccountsPayableService;
0057: import org.kuali.module.purap.service.PaymentRequestService;
0058: import org.kuali.module.purap.service.PurapGeneralLedgerService;
0059: import org.kuali.module.purap.service.PurapService;
0060: import org.kuali.module.purap.util.ExpiredOrClosedAccountEntry;
0061: import org.kuali.module.vendor.VendorConstants;
0062: import org.kuali.module.vendor.VendorPropertyConstants;
0063: import org.kuali.module.vendor.bo.PaymentTermType;
0064: import org.kuali.module.vendor.bo.PurchaseOrderCostSource;
0065: import org.kuali.module.vendor.bo.ShippingPaymentTerms;
0066: import org.kuali.module.vendor.bo.VendorAddress;
0067: import org.kuali.module.vendor.service.VendorService;
0068:
0069: import edu.iu.uis.eden.clientapp.vo.ActionTakenEventVO;
0070: import edu.iu.uis.eden.exception.WorkflowException;
0071:
0072: /**
0073: * Payment Request Document Business Object. Contains the fields associated with the main document table.
0074: */
0075: public class PaymentRequestDocument extends AccountsPayableDocumentBase {
0076: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
0077: .getLogger(PaymentRequestDocument.class);
0078:
0079: private Date invoiceDate;
0080: private String invoiceNumber;
0081: private KualiDecimal vendorInvoiceAmount;
0082: private String vendorPaymentTermsCode;
0083: private String vendorShippingPaymentTermsCode;
0084: private Date paymentRequestPayDate;
0085: private String paymentRequestCostSourceCode;
0086: private boolean paymentRequestedCancelIndicator;
0087: private boolean paymentAttachmentIndicator;
0088: private boolean immediatePaymentIndicator;
0089: private String specialHandlingInstructionLine1Text;
0090: private String specialHandlingInstructionLine2Text;
0091: private String specialHandlingInstructionLine3Text;
0092: private Date paymentPaidDate;
0093: private boolean paymentRequestElectronicInvoiceIndicator;
0094: private String accountsPayableRequestCancelIdentifier;
0095: private Integer originalVendorHeaderGeneratedIdentifier;
0096: private Integer originalVendorDetailAssignedIdentifier;
0097: private Integer alternateVendorHeaderGeneratedIdentifier;
0098: private Integer alternateVendorDetailAssignedIdentifier;
0099: private String purchaseOrderNotes;
0100: private String recurringPaymentTypeCode;
0101:
0102: // NOT PERSISTED IN DB
0103: private String vendorShippingTitleCode;
0104: private Date purchaseOrderEndDate;
0105:
0106: // BELOW USED BY ROUTING
0107: private Integer requisitionIdentifier;
0108:
0109: // REFERENCE OBJECTS
0110: private PaymentTermType vendorPaymentTerms;
0111: private ShippingPaymentTerms vendorShippingPaymentTerms;
0112: private PurchaseOrderCostSource paymentRequestCostSource;
0113: private RecurringPaymentType recurringPaymentType;
0114:
0115: /**
0116: * Default constructor.
0117: */
0118: public PaymentRequestDocument() {
0119: super ();
0120: }
0121:
0122: /**
0123: * @see org.kuali.core.document.DocumentBase#getDocumentRepresentationForSerialization()
0124: */
0125: @Override
0126: protected Document getDocumentRepresentationForSerialization() {
0127: return SpringContext.getBean(
0128: ConciseXmlDocumentConversionService.class)
0129: .getDocumentForSerialization(this );
0130: }
0131:
0132: /**
0133: * @see org.kuali.core.bo.PersistableBusinessObjectBase#isBoNotesSupport()
0134: */
0135: @Override
0136: public boolean isBoNotesSupport() {
0137: return true;
0138: }
0139:
0140: public Integer getRequisitionIdentifier() {
0141: return requisitionIdentifier;
0142: }
0143:
0144: public void setRequisitionIdentifier(Integer requisitionIdentifier) {
0145: this .requisitionIdentifier = requisitionIdentifier;
0146: }
0147:
0148: /**
0149: * @see org.kuali.module.purap.document.AccountsPayableDocumentBase#populateDocumentForRouting()
0150: */
0151: @Override
0152: public void populateDocumentForRouting() {
0153: this .setRequisitionIdentifier(getPurchaseOrderDocument()
0154: .getRequisitionIdentifier());
0155: super .populateDocumentForRouting();
0156: }
0157:
0158: public Date getInvoiceDate() {
0159: return invoiceDate;
0160: }
0161:
0162: public void setInvoiceDate(Date invoiceDate) {
0163: this .invoiceDate = invoiceDate;
0164: }
0165:
0166: public String getInvoiceNumber() {
0167: return invoiceNumber;
0168: }
0169:
0170: public void setInvoiceNumber(String invoiceNumber) {
0171: this .invoiceNumber = invoiceNumber;
0172: }
0173:
0174: public KualiDecimal getVendorInvoiceAmount() {
0175: return vendorInvoiceAmount;
0176: }
0177:
0178: public void setVendorInvoiceAmount(KualiDecimal vendorInvoiceAmount) {
0179: this .vendorInvoiceAmount = vendorInvoiceAmount;
0180: }
0181:
0182: public String getVendorPaymentTermsCode() {
0183: return vendorPaymentTermsCode;
0184: }
0185:
0186: public void setVendorPaymentTermsCode(String vendorPaymentTermsCode) {
0187: this .vendorPaymentTermsCode = vendorPaymentTermsCode;
0188: }
0189:
0190: public PaymentTermType getVendorPaymentTerms() {
0191: if (ObjectUtils.isNull(vendorPaymentTerms)) {
0192: refreshReferenceObject(VendorPropertyConstants.VENDOR_PAYMENT_TERMS);
0193: }
0194: return vendorPaymentTerms;
0195: }
0196:
0197: public void setVendorPaymentTerms(PaymentTermType vendorPaymentTerms) {
0198: this .vendorPaymentTerms = vendorPaymentTerms;
0199: }
0200:
0201: public String getVendorShippingPaymentTermsCode() {
0202: if (ObjectUtils.isNull(vendorPaymentTerms)) {
0203: refreshReferenceObject(VendorPropertyConstants.VENDOR_SHIPPING_PAYMENT_TERMS);
0204: }
0205: return vendorShippingPaymentTermsCode;
0206: }
0207:
0208: public void setVendorShippingPaymentTermsCode(
0209: String vendorShippingPaymentTermsCode) {
0210: this .vendorShippingPaymentTermsCode = vendorShippingPaymentTermsCode;
0211: }
0212:
0213: public Date getPaymentRequestPayDate() {
0214: return paymentRequestPayDate;
0215: }
0216:
0217: public void setPaymentRequestPayDate(Date paymentRequestPayDate) {
0218: this .paymentRequestPayDate = paymentRequestPayDate;
0219: }
0220:
0221: public String getPaymentRequestCostSourceCode() {
0222: return paymentRequestCostSourceCode;
0223: }
0224:
0225: public void setPaymentRequestCostSourceCode(
0226: String paymentRequestCostSourceCode) {
0227: this .paymentRequestCostSourceCode = paymentRequestCostSourceCode;
0228: }
0229:
0230: public boolean getPaymentRequestedCancelIndicator() {
0231: return paymentRequestedCancelIndicator;
0232: }
0233:
0234: public boolean isPaymentRequestedCancelIndicator() {
0235: return paymentRequestedCancelIndicator;
0236: }
0237:
0238: public void setPaymentRequestedCancelIndicator(
0239: boolean paymentRequestedCancelIndicator) {
0240: this .paymentRequestedCancelIndicator = paymentRequestedCancelIndicator;
0241: }
0242:
0243: public boolean getPaymentAttachmentIndicator() {
0244: return paymentAttachmentIndicator;
0245: }
0246:
0247: public void setPaymentAttachmentIndicator(
0248: boolean paymentAttachmentIndicator) {
0249: this .paymentAttachmentIndicator = paymentAttachmentIndicator;
0250: }
0251:
0252: public boolean getImmediatePaymentIndicator() {
0253: return immediatePaymentIndicator;
0254: }
0255:
0256: public void setImmediatePaymentIndicator(
0257: boolean immediatePaymentIndicator) {
0258: this .immediatePaymentIndicator = immediatePaymentIndicator;
0259: }
0260:
0261: public String getSpecialHandlingInstructionLine1Text() {
0262: return specialHandlingInstructionLine1Text;
0263: }
0264:
0265: public void setSpecialHandlingInstructionLine1Text(
0266: String specialHandlingInstructionLine1Text) {
0267: this .specialHandlingInstructionLine1Text = specialHandlingInstructionLine1Text;
0268: }
0269:
0270: public String getSpecialHandlingInstructionLine2Text() {
0271: return specialHandlingInstructionLine2Text;
0272: }
0273:
0274: public void setSpecialHandlingInstructionLine2Text(
0275: String specialHandlingInstructionLine2Text) {
0276: this .specialHandlingInstructionLine2Text = specialHandlingInstructionLine2Text;
0277: }
0278:
0279: public String getSpecialHandlingInstructionLine3Text() {
0280: return specialHandlingInstructionLine3Text;
0281: }
0282:
0283: public void setSpecialHandlingInstructionLine3Text(
0284: String specialHandlingInstructionLine3Text) {
0285: this .specialHandlingInstructionLine3Text = specialHandlingInstructionLine3Text;
0286: }
0287:
0288: public Date getPaymentPaidDate() {
0289: return paymentPaidDate;
0290: }
0291:
0292: public void setPaymentPaidDate(Date paymentPaidDate) {
0293: this .paymentPaidDate = paymentPaidDate;
0294: }
0295:
0296: public boolean getPaymentRequestElectronicInvoiceIndicator() {
0297: return paymentRequestElectronicInvoiceIndicator;
0298: }
0299:
0300: public void setPaymentRequestElectronicInvoiceIndicator(
0301: boolean paymentRequestElectronicInvoiceIndicator) {
0302: this .paymentRequestElectronicInvoiceIndicator = paymentRequestElectronicInvoiceIndicator;
0303: }
0304:
0305: public String getAccountsPayableRequestCancelIdentifier() {
0306: return accountsPayableRequestCancelIdentifier;
0307: }
0308:
0309: public void setAccountsPayableRequestCancelIdentifier(
0310: String accountsPayableRequestCancelIdentifier) {
0311: this .accountsPayableRequestCancelIdentifier = accountsPayableRequestCancelIdentifier;
0312: }
0313:
0314: public Integer getOriginalVendorHeaderGeneratedIdentifier() {
0315: return originalVendorHeaderGeneratedIdentifier;
0316: }
0317:
0318: public void setOriginalVendorHeaderGeneratedIdentifier(
0319: Integer originalVendorHeaderGeneratedIdentifier) {
0320: this .originalVendorHeaderGeneratedIdentifier = originalVendorHeaderGeneratedIdentifier;
0321: }
0322:
0323: public Integer getOriginalVendorDetailAssignedIdentifier() {
0324: return originalVendorDetailAssignedIdentifier;
0325: }
0326:
0327: public void setOriginalVendorDetailAssignedIdentifier(
0328: Integer originalVendorDetailAssignedIdentifier) {
0329: this .originalVendorDetailAssignedIdentifier = originalVendorDetailAssignedIdentifier;
0330: }
0331:
0332: public Integer getAlternateVendorHeaderGeneratedIdentifier() {
0333: return alternateVendorHeaderGeneratedIdentifier;
0334: }
0335:
0336: public void setAlternateVendorHeaderGeneratedIdentifier(
0337: Integer alternateVendorHeaderGeneratedIdentifier) {
0338: this .alternateVendorHeaderGeneratedIdentifier = alternateVendorHeaderGeneratedIdentifier;
0339: }
0340:
0341: public Integer getAlternateVendorDetailAssignedIdentifier() {
0342: return alternateVendorDetailAssignedIdentifier;
0343: }
0344:
0345: public void setAlternateVendorDetailAssignedIdentifier(
0346: Integer alternateVendorDetailAssignedIdentifier) {
0347: this .alternateVendorDetailAssignedIdentifier = alternateVendorDetailAssignedIdentifier;
0348: }
0349:
0350: public ShippingPaymentTerms getVendorShippingPaymentTerms() {
0351: return vendorShippingPaymentTerms;
0352: }
0353:
0354: public void setVendorShippingPaymentTerms(
0355: ShippingPaymentTerms vendorShippingPaymentTerms) {
0356: this .vendorShippingPaymentTerms = vendorShippingPaymentTerms;
0357: }
0358:
0359: public String getVendorShippingTitleCode() {
0360: if (ObjectUtils.isNotNull(this .getPurchaseOrderDocument())) {
0361: return this .getPurchaseOrderDocument()
0362: .getVendorShippingTitleCode();
0363: }
0364: return vendorShippingTitleCode;
0365: }
0366:
0367: public void setVendorShippingTitleCode(
0368: String vendorShippingTitleCode) {
0369: this .vendorShippingTitleCode = vendorShippingTitleCode;
0370: }
0371:
0372: public Date getPurchaseOrderEndDate() {
0373: return purchaseOrderEndDate;
0374: }
0375:
0376: public void setPurchaseOrderEndDate(Date purchaseOrderEndDate) {
0377: this .purchaseOrderEndDate = purchaseOrderEndDate;
0378: }
0379:
0380: /**
0381: * Perform logic needed to initiate PREQ Document
0382: */
0383: public void initiateDocument() {
0384: LOG.debug("initiateDocument() started");
0385: UniversalUser currentUser = (UniversalUser) GlobalVariables
0386: .getUserSession().getUniversalUser();
0387: this
0388: .setStatusCode(PurapConstants.PaymentRequestStatuses.INITIATE);
0389: this .setAccountsPayableProcessorIdentifier(currentUser
0390: .getPersonUniversalIdentifier());
0391: this .setProcessingCampusCode(currentUser.getCampusCode());
0392: this .refreshNonUpdateableReferences();
0393: }
0394:
0395: /**
0396: * Perform logic needed to clear the initial fields on a PREQ Document
0397: */
0398: public void clearInitFields() {
0399: LOG.debug("clearDocument() started");
0400: // Clearing document overview fields
0401: this .getDocumentHeader().setFinancialDocumentDescription(null);
0402: this .getDocumentHeader().setExplanation(null);
0403: this .getDocumentHeader().setFinancialDocumentTotalAmount(null);
0404: this .getDocumentHeader().setOrganizationDocumentNumber(null);
0405:
0406: // Clearing document Init fields
0407: this .setPurchaseOrderIdentifier(null);
0408: this .setInvoiceNumber(null);
0409: this .setInvoiceDate(null);
0410: this .setVendorInvoiceAmount(null);
0411: this .setSpecialHandlingInstructionLine1Text(null);
0412: this .setSpecialHandlingInstructionLine2Text(null);
0413: this .setSpecialHandlingInstructionLine3Text(null);
0414: }
0415:
0416: /**
0417: * Populates a preq from a PO - delegate method
0418: *
0419: * @param po -
0420: */
0421: public void populatePaymentRequestFromPurchaseOrder(
0422: PurchaseOrderDocument po) {
0423: populatePaymentRequestFromPurchaseOrder(po,
0424: new HashMap<String, ExpiredOrClosedAccountEntry>());
0425: }
0426:
0427: /**
0428: * Populates a preq from a PO
0429: *
0430: * @param po Purchase Order Document used for populating the PREQ
0431: * @param expiredOrClosedAccountList a list of closed or expired accounts
0432: */
0433: public void populatePaymentRequestFromPurchaseOrder(
0434: PurchaseOrderDocument po,
0435: HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
0436: this
0437: .setPurchaseOrderIdentifier(po
0438: .getPurapDocumentIdentifier());
0439: this .getDocumentHeader().setOrganizationDocumentNumber(
0440: po.getDocumentHeader().getOrganizationDocumentNumber());
0441: this .setPostingYear(po.getPostingYear());
0442: this .setVendorCustomerNumber(po.getVendorCustomerNumber());
0443: if (po.getPurchaseOrderCostSource() != null) {
0444: this .setPaymentRequestCostSource(po
0445: .getPurchaseOrderCostSource());
0446: this .setPaymentRequestCostSourceCode(po
0447: .getPurchaseOrderCostSourceCode());
0448: }
0449: if (po.getVendorShippingPaymentTerms() != null) {
0450: this .setVendorShippingPaymentTerms(po
0451: .getVendorShippingPaymentTerms());
0452: this .setVendorShippingPaymentTermsCode(po
0453: .getVendorShippingPaymentTermsCode());
0454: }
0455:
0456: if (po.getRecurringPaymentType() != null) {
0457: this .setRecurringPaymentType(po.getRecurringPaymentType());
0458: this .setRecurringPaymentTypeCode(po
0459: .getRecurringPaymentTypeCode());
0460: }
0461:
0462: this .setVendorHeaderGeneratedIdentifier(po
0463: .getVendorHeaderGeneratedIdentifier());
0464: this .setVendorDetailAssignedIdentifier(po
0465: .getVendorDetailAssignedIdentifier());
0466: this .setVendorCustomerNumber(po.getVendorCustomerNumber());
0467: this .setVendorName(po.getVendorName());
0468:
0469: // populate preq vendor address with the default remit address type for the vendor if found
0470: String userCampus = GlobalVariables.getUserSession()
0471: .getUniversalUser().getCampusCode();
0472: VendorAddress vendorAddress = SpringContext.getBean(
0473: VendorService.class).getVendorDefaultAddress(
0474: po.getVendorHeaderGeneratedIdentifier(),
0475: po.getVendorDetailAssignedIdentifier(),
0476: VendorConstants.AddressTypes.REMIT, userCampus);
0477: if (vendorAddress != null) {
0478: this .templateVendorAddress(vendorAddress);
0479: this .setVendorAddressGeneratedIdentifier(vendorAddress
0480: .getVendorAddressGeneratedIdentifier());
0481: } else {
0482: // set address from PO
0483: this .setVendorAddressGeneratedIdentifier(po
0484: .getVendorAddressGeneratedIdentifier());
0485: this .setVendorLine1Address(po.getVendorLine1Address());
0486: this .setVendorLine2Address(po.getVendorLine2Address());
0487: this .setVendorCityName(po.getVendorCityName());
0488: this .setVendorStateCode(po.getVendorStateCode());
0489: this .setVendorPostalCode(po.getVendorPostalCode());
0490: this .setVendorCountryCode(po.getVendorCountryCode());
0491: }
0492:
0493: if ((po.getVendorPaymentTerms() == null)
0494: || ("".equals(po.getVendorPaymentTerms()
0495: .getVendorPaymentTermsCode()))) {
0496: this .setVendorPaymentTerms(new PaymentTermType());
0497: this .vendorPaymentTerms.setVendorPaymentTermsCode("");
0498: } else {
0499: this .setVendorPaymentTermsCode(po
0500: .getVendorPaymentTermsCode());
0501: this .setVendorPaymentTerms(po.getVendorPaymentTerms());
0502: }
0503: this .setPaymentRequestPayDate(SpringContext.getBean(
0504: PaymentRequestService.class).calculatePayDate(
0505: this .getInvoiceDate(), this .getVendorPaymentTerms()));
0506:
0507: AccountsPayableService accountsPayableService = SpringContext
0508: .getBean(AccountsPayableService.class);
0509: for (PurchaseOrderItem poi : (List<PurchaseOrderItem>) po
0510: .getItems()) {
0511: // check to make sure it's eligible for payment (i.e. active and has encumberance available
0512: if (getDocumentSpecificService().poItemEligibleForAp(this ,
0513: poi)) {
0514: this .getItems().add(
0515: new PaymentRequestItem(poi, this ,
0516: expiredOrClosedAccountList));
0517: }
0518: }
0519: // add missing below the line
0520: SpringContext.getBean(PurapService.class).addBelowLineItems(
0521: this );
0522: this .setAccountsPayablePurchasingDocumentLinkIdentifier(po
0523: .getAccountsPayablePurchasingDocumentLinkIdentifier());
0524:
0525: this .refreshNonUpdateableReferences();
0526: }
0527:
0528: /**
0529: * @see org.kuali.core.document.DocumentBase#getDocumentTitle()
0530: */
0531: @Override
0532: public String getDocumentTitle() {
0533: String specificTitle = SpringContext.getBean(
0534: ParameterService.class).getParameterValue(
0535: PaymentRequestDocument.class,
0536: PurapParameterConstants.PURAP_OVERRIDE_PREQ_DOC_TITLE);
0537: if (StringUtils.equalsIgnoreCase(specificTitle, Boolean.TRUE
0538: .toString())) {
0539: return getCustomDocumentTitle();
0540: }
0541: return super .getDocumentTitle();
0542: }
0543:
0544: /**
0545: * Returns a custom document title based on the workflow document title. Depending on what route level the document is currently
0546: * in, the PO, vendor, amount, account number, dept, campus may be added to the documents title.
0547: *
0548: * @return - Customized document title text dependent upon route level.
0549: */
0550: private String getCustomDocumentTitle() {
0551: try {
0552: // set the workflow document title
0553: String poNumber = getPurchaseOrderIdentifier().toString();
0554: String vendorName = StringUtils
0555: .trimToEmpty(getVendorName());
0556: String preqAmount = getGrandTotal().toString();
0557: String indicator = getTitleIndicator();
0558:
0559: String documentTitle = new StringBuffer("PO: ").append(
0560: poNumber).append(" Vendor: ").append(vendorName)
0561: .append(" Amount: ").append(preqAmount).append(" ")
0562: .append(indicator).toString();
0563: String[] nodeNames = getDocumentHeader()
0564: .getWorkflowDocument().getNodeNames();
0565: if ((nodeNames.length == 1)
0566: && (NodeDetailEnum.VENDOR_TAX_REVIEW.getName()
0567: .equals(nodeNames[0]))) {
0568: // tax review
0569: // grab the first account
0570: PurApAccountingLine theAccount = getFirstAccount();
0571: // setup variables
0572: String deliveryCampus = StringUtils
0573: .trimToEmpty((getProcessingCampus() != null ? getProcessingCampus()
0574: .getCampusShortName()
0575: : ""));
0576: String accountNumber = (theAccount != null ? StringUtils
0577: .trimToEmpty(theAccount.getAccountNumber())
0578: : "");
0579: String department = (theAccount != null ? StringUtils
0580: .trimToEmpty((((theAccount.getAccount() != null) && (theAccount
0581: .getAccount().getOrganization() != null)) ? theAccount
0582: .getAccount().getOrganization()
0583: .getOrganizationName()
0584: : ""))
0585: : "");
0586: documentTitle = new StringBuffer("Vendor: ").append(
0587: vendorName).append(" PO: ").append(poNumber)
0588: .append(" Account Number: ").append(
0589: accountNumber).append(" Dept: ")
0590: .append(department)
0591: .append(" Delivery Campus: ").append(
0592: deliveryCampus).toString();
0593: }
0594: return documentTitle;
0595: } catch (WorkflowException e) {
0596: LOG.error("Error updating Payment Request document: "
0597: + e.getMessage());
0598: throw new RuntimeException(
0599: "Error updating Payment Request document: "
0600: + e.getMessage());
0601: }
0602: }
0603:
0604: /**
0605: * Returns the first payment item's first account (assuming the item list is sequentially ordered).
0606: *
0607: * @return - Accounting Line object for first account of first payment item.
0608: */
0609: private PurApAccountingLine getFirstAccount() {
0610: // loop through items, and pick the first item
0611: if ((getItems() != null) && (!getItems().isEmpty())) {
0612: PaymentRequestItem itemToUse = null;
0613: for (Iterator iter = getItems().iterator(); iter.hasNext();) {
0614: PaymentRequestItem item = (PaymentRequestItem) iter
0615: .next();
0616: if ((item.isConsideredEntered())
0617: && ((item.getSourceAccountingLines() != null) && (!item
0618: .getSourceAccountingLines().isEmpty()))) {
0619: // accounting lines are not empty so pick the first account
0620: PurApAccountingLine accountLine = item
0621: .getSourceAccountingLine(0);
0622: accountLine.refreshNonUpdateableReferences();
0623: return accountLine;
0624: }
0625: }
0626: }
0627: return null;
0628: }
0629:
0630: /**
0631: * Determines the indicator text that will appear in the workflow document title
0632: *
0633: * @return - Text of hold or request cancel
0634: */
0635: private String getTitleIndicator() {
0636: if (isHoldIndicator()) {
0637: return PurapConstants.PaymentRequestIndicatorText.HOLD;
0638: } else if (isPaymentRequestedCancelIndicator()) {
0639: return PurapConstants.PaymentRequestIndicatorText.REQUEST_CANCEL;
0640: }
0641: return "";
0642: }
0643:
0644: /**
0645: * @see org.kuali.core.document.DocumentBase#handleRouteStatusChange()
0646: */
0647: @Override
0648: public void handleRouteStatusChange() {
0649: LOG.debug("handleRouteStatusChange() started");
0650: super .handleRouteStatusChange();
0651: try {
0652: // DOCUMENT PROCESSED
0653: if (this .getDocumentHeader().getWorkflowDocument()
0654: .stateIsProcessed()) {
0655: if (!PaymentRequestStatuses.AUTO_APPROVED
0656: .equals(getStatusCode())) {
0657: SpringContext
0658: .getBean(PurapService.class)
0659: .updateStatus(
0660: this ,
0661: PurapConstants.PaymentRequestStatuses.DEPARTMENT_APPROVED);
0662: populateDocumentForRouting();
0663: SpringContext.getBean(PaymentRequestService.class)
0664: .saveDocumentWithoutValidation(this );
0665: return;
0666: }
0667: }
0668: // DOCUMENT DISAPPROVED
0669: else if (this .getDocumentHeader().getWorkflowDocument()
0670: .stateIsDisapproved()) {
0671: String nodeName = SpringContext.getBean(
0672: WorkflowDocumentService.class)
0673: .getCurrentRouteLevelName(
0674: getDocumentHeader()
0675: .getWorkflowDocument());
0676: NodeDetails currentNode = NodeDetailEnum
0677: .getNodeDetailEnumByName(nodeName);
0678: if (ObjectUtils.isNotNull(currentNode)) {
0679: String newStatusCode = currentNode
0680: .getDisapprovedStatusCode();
0681: if ((StringUtils.isBlank(newStatusCode))
0682: && ((StringUtils.isBlank(currentNode
0683: .getDisapprovedStatusCode())) && ((PaymentRequestStatuses.INITIATE
0684: .equals(getStatusCode())) || (PaymentRequestStatuses.IN_PROCESS
0685: .equals(getStatusCode()))))) {
0686: newStatusCode = PaymentRequestStatuses.CANCELLED_IN_PROCESS;
0687: }
0688: if (StringUtils.isNotBlank(newStatusCode)) {
0689: SpringContext.getBean(
0690: AccountsPayableService.class)
0691: .cancelAccountsPayableDocument(this ,
0692: nodeName);
0693: return;
0694: }
0695: }
0696: logAndThrowRuntimeException("No status found to set for document being disapproved in node '"
0697: + nodeName + "'");
0698: }
0699: // DOCUMENT CANCELED
0700: else if (this .getDocumentHeader().getWorkflowDocument()
0701: .stateIsCanceled()) {
0702: String currentNodeName = SpringContext.getBean(
0703: WorkflowDocumentService.class)
0704: .getCurrentRouteLevelName(
0705: this .getDocumentHeader()
0706: .getWorkflowDocument());
0707: NodeDetails currentNode = NodeDetailEnum
0708: .getNodeDetailEnumByName(currentNodeName);
0709: if (ObjectUtils.isNotNull(currentNode)) {
0710: String cancelledStatusCode = currentNode
0711: .getDisapprovedStatusCode();
0712: if (StringUtils.isNotBlank(cancelledStatusCode)) {
0713: SpringContext
0714: .getBean(PurapService.class)
0715: .updateStatus(this , cancelledStatusCode);
0716: SpringContext.getBean(
0717: PaymentRequestService.class)
0718: .saveDocumentWithoutValidation(this );
0719: return;
0720: }
0721: }
0722: logAndThrowRuntimeException("No status found to set for document being canceled in node '"
0723: + currentNode + "'");
0724: }
0725: } catch (WorkflowException e) {
0726: logAndThrowRuntimeException(
0727: "Error saving routing data while saving document with id "
0728: + getDocumentNumber(), e);
0729: }
0730: }
0731:
0732: /**
0733: * Generates correcting entries to the GL if accounts are modified.
0734: *
0735: * @see org.kuali.core.document.Document#doActionTaken(edu.iu.uis.eden.clientapp.vo.ActionTakenEventVO)
0736: */
0737: @Override
0738: public void doActionTaken(ActionTakenEventVO event) {
0739: super .doActionTaken(event);
0740: KualiWorkflowDocument workflowDocument = getDocumentHeader()
0741: .getWorkflowDocument();
0742: try {
0743: String currentNode = null;
0744: if (workflowDocument.getNodeNames().length > 0) {
0745: currentNode = workflowDocument.getNodeNames()[0];
0746: }
0747:
0748: // everything in the below list requires correcting entries to be written to the GL
0749: if (NodeDetailEnum
0750: .getNodesRequiringCorrectingGeneralLedgerEntries()
0751: .contains(currentNode)) {
0752: if (NodeDetailEnum.ACCOUNT_REVIEW.getName().equals(
0753: currentNode)) {
0754: SpringContext.getBean(
0755: PurapGeneralLedgerService.class)
0756: .generateEntriesModifyPaymentRequest(this );
0757: }
0758: }
0759: } catch (WorkflowException e) {
0760: logAndThrowRuntimeException(
0761: "Error saving routing data while saving document with id "
0762: + getDocumentNumber(), e);
0763: }
0764: }
0765:
0766: /**
0767: * @see org.kuali.module.purap.document.AccountsPayableDocumentBase#preProcessNodeChange(java.lang.String, java.lang.String)
0768: */
0769: public boolean processNodeChange(String newNodeName,
0770: String oldNodeName) {
0771: if (PaymentRequestStatuses.AUTO_APPROVED
0772: .equals(getStatusCode())) {
0773: // do nothing for an auto approval
0774: return false;
0775: }
0776: if (NodeDetailEnum.ADHOC_REVIEW.getName().equals(oldNodeName)) {
0777: SpringContext.getBean(PurapService.class)
0778: .performLogicForFullEntryCompleted(this );
0779: } else if (NodeDetailEnum.ACCOUNTS_PAYABLE_REVIEW.getName()
0780: .equals(oldNodeName)) {
0781: setAccountsPayableApprovalDate(SpringContext.getBean(
0782: DateTimeService.class).getCurrentSqlDate());
0783: }
0784: return true;
0785: }
0786:
0787: /**
0788: * @see org.kuali.module.purap.document.AccountsPayableDocumentBase#getNodeDetailEnum(java.lang.String)
0789: */
0790: public NodeDetails getNodeDetailEnum(String nodeName) {
0791: return NodeDetailEnum.getNodeDetailEnumByName(nodeName);
0792: }
0793:
0794: /**
0795: * @see org.kuali.module.purap.document.AccountsPayableDocumentBase#saveDocumentFromPostProcessing()
0796: */
0797: public void saveDocumentFromPostProcessing() {
0798: SpringContext.getBean(PaymentRequestService.class)
0799: .saveDocumentWithoutValidation(this );
0800:
0801: // if we've hit full entry completed then close/reopen po
0802: if (PurapConstants.PaymentRequestStatuses.STATUS_ORDER
0803: .isFullDocumentEntryCompleted(this .getStatusCode())
0804: && this .isClosePurchaseOrderIndicator()) {
0805: SpringContext.getBean(PurapService.class)
0806: .performLogicForCloseReopenPO(this );
0807: }
0808: }
0809:
0810: /**
0811: * @see org.kuali.module.purap.document.PurchasingAccountsPayableDocumentBase#getItemClass()
0812: */
0813: @Override
0814: public Class getItemClass() {
0815: return PaymentRequestItem.class;
0816: }
0817:
0818: /**
0819: * @see org.kuali.module.purap.document.PurchasingAccountsPayableDocumentBase#getPurApSourceDocumentIfPossible()
0820: */
0821: @Override
0822: public PurchaseOrderDocument getPurApSourceDocumentIfPossible() {
0823: return getPurchaseOrderDocument();
0824: }
0825:
0826: /**
0827: * @see org.kuali.module.purap.document.PurchasingAccountsPayableDocumentBase#getPurApSourceDocumentLabelIfPossible()
0828: */
0829: @Override
0830: public String getPurApSourceDocumentLabelIfPossible() {
0831: return SpringContext.getBean(DataDictionaryService.class)
0832: .getDocumentLabelByClass(PurchaseOrderDocument.class);
0833: }
0834:
0835: public String getPurchaseOrderNotes() {
0836:
0837: ArrayList poNotes = (ArrayList) this .getPurchaseOrderDocument()
0838: .getBoNotes();
0839:
0840: if (poNotes.size() > 0) {
0841: return "Yes";
0842: }
0843: return "No";
0844: }
0845:
0846: public void setPurchaseOrderNotes(String purchaseOrderNotes) {
0847: this .purchaseOrderNotes = purchaseOrderNotes;
0848: }
0849:
0850: public String getRecurringPaymentTypeCode() {
0851: return recurringPaymentTypeCode;
0852: }
0853:
0854: public void setRecurringPaymentTypeCode(
0855: String recurringPaymentTypeCode) {
0856: this .recurringPaymentTypeCode = recurringPaymentTypeCode;
0857: }
0858:
0859: /**
0860: * Returns the total encumbered amount from the purchase order excluding below the line.
0861: *
0862: * @return Total cost excluding below the line
0863: */
0864: public KualiDecimal getItemTotalPoEncumbranceAmount() {
0865: // get total from po excluding below the line and inactive
0866: return this .getPurchaseOrderDocument().getTotalDollarAmount(
0867: false, false);
0868: }
0869:
0870: public KualiDecimal getItemTotalPoEncumbranceAmountRelieved() {
0871: return getItemTotalPoEncumbranceAmountRelieved(false);
0872: }
0873:
0874: public KualiDecimal getItemTotalPoEncumbranceAmountRelieved(
0875: boolean includeBelowTheLine) {
0876:
0877: KualiDecimal total = KualiDecimal.ZERO;
0878:
0879: for (PurchaseOrderItem item : (List<PurchaseOrderItem>) getPurchaseOrderDocument()
0880: .getItems()) {
0881: ItemType it = item.getItemType();
0882: if (includeBelowTheLine
0883: || it.isItemTypeAboveTheLineIndicator()) {
0884: total = total.add(item
0885: .getItemEncumbranceRelievedAmount());
0886: }
0887: }
0888: return total;
0889: }
0890:
0891: public KualiDecimal getLineItemTotal() {
0892: return this .getTotalDollarAmountAboveLineItems();
0893: }
0894:
0895: public KualiDecimal getGrandTotal() {
0896: return this .getTotalDollarAmount();
0897: }
0898:
0899: public KualiDecimal getGrandTotalExcludingDiscount() {
0900: String[] discountCode = new String[] { PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE };
0901: return this .getTotalDollarAmountWithExclusions(discountCode,
0902: true);
0903: }
0904:
0905: public boolean isDiscount() {
0906: return SpringContext.getBean(PaymentRequestService.class)
0907: .hasDiscountItem(this );
0908: }
0909:
0910: /**
0911: * The total that was paid on the po excluding below the line
0912: *
0913: * @return total paid
0914: */
0915: public KualiDecimal getItemTotalPoPaidAmount() {
0916: KualiDecimal total = KualiDecimal.ZERO;
0917: for (PurchaseOrderItem item : (List<PurchaseOrderItem>) getPurchaseOrderDocument()
0918: .getItems()) {
0919: ItemType iT = item.getItemType();
0920: if (iT.isItemTypeAboveTheLineIndicator()) {
0921: KualiDecimal itemPaid = item.getItemPaidAmount();
0922: total = total.add(itemPaid);
0923: }
0924: }
0925: return total;
0926: }
0927:
0928: /**
0929: * Returns the name of who requested cancel.
0930: *
0931: * @return - name of who requested cancel.
0932: */
0933: public String getAccountsPayableRequestCancelPersonName() {
0934: String personName = null;
0935: try {
0936: UniversalUser user = SpringContext.getBean(
0937: UniversalUserService.class).getUniversalUser(
0938: getAccountsPayableRequestCancelIdentifier());
0939: personName = user.getPersonName();
0940: } catch (UserNotFoundException unfe) {
0941: personName = "";
0942: }
0943:
0944: return personName;
0945: }
0946:
0947: /**
0948: * Exists due to a setter requirement by the htmlControlAttribute
0949: *
0950: * @param amount - total po amount paid
0951: */
0952: public void setItemTotalPoPaidAmount(KualiDecimal amount) {
0953: // do nothing
0954: }
0955:
0956: /**
0957: * Exists due to a setter requirement by the htmlControlAttribute
0958: *
0959: * @param amount - total po encumbrance
0960: */
0961: public void setItemTotalPoEncumbranceAmount(KualiDecimal amount) {
0962: // do nothing
0963: }
0964:
0965: /**
0966: * Exists due to a setter requirement by the htmlControlAttribute
0967: *
0968: * @param amount - total po encumbrance amount relieved
0969: */
0970: public void setItemTotalPoEncumbranceAmountRelieved(
0971: KualiDecimal amount) {
0972: // do nothing
0973: }
0974:
0975: /**
0976: * Determinines the route levels for a given document.
0977: *
0978: * @param workflowDocument - work flow document
0979: * @return List - list of route levels
0980: */
0981: protected List getCurrentRouteLevels(
0982: KualiWorkflowDocument workflowDocument) {
0983: try {
0984: return Arrays.asList(workflowDocument.getNodeNames());
0985: } catch (WorkflowException e) {
0986: throw new RuntimeException(e);
0987: }
0988: }
0989:
0990: /**
0991: * Updates the extended price for each payment request item.
0992: */
0993: public void updateExtendedPriceOnItems() {
0994: for (PaymentRequestItem item : (List<PaymentRequestItem>) this
0995: .getItems()) {
0996: if ((ObjectUtils.isNull(item.getExtendedPrice()) || (KualiDecimal.ZERO
0997: .compareTo(item.getExtendedPrice()) == 0))
0998: && item.getItemType()
0999: .isQuantityBasedGeneralLedgerIndicator()) {
1000: KualiDecimal newExtendedPrice = item
1001: .calculateExtendedPrice();
1002: item.setExtendedPrice(newExtendedPrice);
1003: }
1004: }
1005: }
1006:
1007: /**
1008: * USED FOR ROUTING ONLY
1009: *
1010: * @deprecated
1011: */
1012: public String getStatusDescription() {
1013: return "";
1014: }
1015:
1016: /**
1017: * USED FOR ROUTING ONLY
1018: *
1019: * @deprecated
1020: */
1021: public void setStatusDescription(String statusDescription) {
1022: }
1023:
1024: public RecurringPaymentType getRecurringPaymentType() {
1025: if (ObjectUtils.isNull(recurringPaymentType)) {
1026: refreshReferenceObject(PurapPropertyConstants.RECURRING_PAYMENT_TYPE);
1027: }
1028: return recurringPaymentType;
1029: }
1030:
1031: public void setRecurringPaymentType(
1032: RecurringPaymentType recurringPaymentType) {
1033: this .recurringPaymentType = recurringPaymentType;
1034: }
1035:
1036: public PurchaseOrderCostSource getPaymentRequestCostSource() {
1037: return paymentRequestCostSource;
1038: }
1039:
1040: public void setPaymentRequestCostSource(
1041: PurchaseOrderCostSource paymentRequestCostSource) {
1042: this .paymentRequestCostSource = paymentRequestCostSource;
1043: }
1044:
1045: /**
1046: * @see org.kuali.module.purap.document.AccountsPayableDocumentBase#getPoDocumentTypeForAccountsPayableDocumentApprove()
1047: */
1048: public String getPoDocumentTypeForAccountsPayableDocumentCancel() {
1049: return PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_REOPEN_DOCUMENT;
1050: }
1051:
1052: /**
1053: * @see org.kuali.module.purap.document.AccountsPayableDocumentBase#getInitialAmount()
1054: */
1055: public KualiDecimal getInitialAmount() {
1056: return this .getVendorInvoiceAmount();
1057: }
1058:
1059: /**
1060: * Populates the payment request document, then continues with preparing for save.
1061: *
1062: * @see org.kuali.core.document.Document#prepareForSave(org.kuali.core.rule.event.KualiDocumentEvent)
1063: */
1064: @Override
1065: public void prepareForSave(KualiDocumentEvent event) {
1066:
1067: // first populate, then call super
1068: if (event instanceof ContinueAccountsPayableEvent) {
1069: SpringContext.getBean(PaymentRequestService.class)
1070: .populatePaymentRequest(this );
1071: }
1072:
1073: super .prepareForSave(event);
1074: }
1075:
1076: /**
1077: * @see org.kuali.module.purap.document.AccountsPayableDocumentBase#isAttachmentRequired()
1078: */
1079: @Override
1080: protected boolean isAttachmentRequired() {
1081: return StringUtils.equalsIgnoreCase("Y", SpringContext.getBean(
1082: ParameterService.class).getParameterValue(
1083: PaymentRequestDocument.class,
1084: PurapParameterConstants.PURAP_PREQ_REQUIRE_ATTACHMENT));
1085: }
1086:
1087: /**
1088: * @see org.kuali.module.purap.document.AccountsPayableDocument#getDocumentSpecificService()
1089: */
1090: @Override
1091: public AccountsPayableDocumentSpecificService getDocumentSpecificService() {
1092: return (AccountsPayableDocumentSpecificService) SpringContext
1093: .getBean(PaymentRequestService.class);
1094: }
1095:
1096: /**
1097: * @see org.kuali.module.purap.document.PurchasingAccountsPayableDocumentBase#getItem(int)
1098: */
1099: @Override
1100: public PurApItem getItem(int pos) {
1101: PaymentRequestItem item = (PaymentRequestItem) super
1102: .getItem(pos);
1103: if (item.getPaymentRequest() == null) {
1104: item.setPaymentRequest(this);
1105: }
1106: return item;
1107: }
1108:
1109: }
|