/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.module.purap.document;
import static org.kuali.kfs.sys.document.AccountingDocumentTestUtils.testGetNewDocument_byDocumentClass;
import static org.kuali.kfs.sys.fixture.UserNameFixture.appleton;
import static org.kuali.kfs.sys.fixture.UserNameFixture.parke;
import static org.kuali.kfs.sys.fixture.UserNameFixture.rorenfro;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.kuali.kfs.module.purap.PurapConstants.PurchaseOrderStatuses;
import org.kuali.kfs.module.purap.businessobject.AccountsPayableItem;
import org.kuali.kfs.module.purap.businessobject.PaymentRequestItem;
import org.kuali.kfs.module.purap.businessobject.PurApAccountingLine;
import org.kuali.kfs.module.purap.businessobject.PurchaseOrderAccount;
import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem;
import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItemUseTax;
import org.kuali.kfs.module.purap.document.service.PaymentRequestService;
import org.kuali.kfs.module.purap.document.service.PurapService;
import org.kuali.kfs.module.purap.document.service.PurchaseOrderService;
import org.kuali.kfs.module.purap.fixture.PaymentRequestDocumentFixture;
import org.kuali.kfs.module.purap.fixture.PaymentRequestItemFixture;
import org.kuali.kfs.module.purap.fixture.PurchaseOrderDocumentFixture;
import org.kuali.kfs.sys.ConfigureContext;
import org.kuali.kfs.sys.DocumentTestUtils;
import org.kuali.kfs.sys.context.KualiTestBase;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.document.AccountingDocumentTestUtils;
import org.kuali.kfs.sys.document.workflow.WorkflowTestUtils;
import org.kuali.kfs.vnd.VendorConstants;
import org.kuali.kfs.vnd.businessobject.PaymentTermType;
import org.kuali.kfs.vnd.businessobject.VendorAddress;
import org.kuali.kfs.vnd.document.service.VendorService;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.kns.service.TransactionalDocumentDictionaryService;
import org.kuali.rice.krad.service.DocumentService;
import org.kuali.rice.krad.service.SequenceAccessorService;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.ObjectUtils;
/**
* This class is used to create and test populated Payment Request Documents of various kinds.
*/
@ConfigureContext(session = appleton)
public class PaymentRequestDocumentTest extends KualiTestBase {
private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PaymentRequestItem.class);
public static final Class<PaymentRequestDocument> DOCUMENT_CLASS = PaymentRequestDocument.class;
private static final String ACCOUNT_REVIEW = "Account";
protected static DocumentService documentService = null;
protected static PurchaseOrderService purchaseOrderService = null;
private PaymentRequestDocument paymentRequestDocument = null;
protected static PurchaseOrderDocument purchaseOrderDocument = null;
@Override
protected void setUp() throws Exception {
documentService = SpringContext.getBean(DocumentService.class);
purchaseOrderService = SpringContext.getBean(PurchaseOrderService.class);
super.setUp();
}
@Override
protected void tearDown() throws Exception {
paymentRequestDocument = null;
super.tearDown();
}
private int getExpectedPrePeCount() {
return 4;
}
public final void testAddItem() throws Exception {
List<AccountsPayableItem> items = new ArrayList<AccountsPayableItem>();
items.add(PaymentRequestItemFixture.PREQ_QTY_UNRESTRICTED_ITEM_1.createPaymentRequestItem());
int expectedItemTotal = items.size();
AccountsPayableDocumentTestUtils.testAddItem(DocumentTestUtils.createDocument(documentService, DOCUMENT_CLASS), items, expectedItemTotal);
}
public final void testNothing() throws Exception {
}
public final void testGetNewDocument() throws Exception {
testGetNewDocument_byDocumentClass(DOCUMENT_CLASS, documentService);
}
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testConvertIntoErrorCorrection() throws Exception {
purchaseOrderDocument = createPurchaseOrderDocument(PurchaseOrderDocumentFixture.PO_APPROVAL_REQUIRED, false);
paymentRequestDocument = createPaymentRequestDocument(PaymentRequestDocumentFixture.PREQ_APPROVAL_REQUIRED, purchaseOrderDocument, true, new KualiDecimal[] { new KualiDecimal(100) });
AccountingDocumentTestUtils.testConvertIntoErrorCorrection(paymentRequestDocument, getExpectedPrePeCount(), documentService, SpringContext.getBean(TransactionalDocumentDictionaryService.class));
}
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testSaveDocument() throws Exception {
purchaseOrderDocument = createPurchaseOrderDocument(PurchaseOrderDocumentFixture.PO_APPROVAL_REQUIRED, false);
paymentRequestDocument = createPaymentRequestDocument(PaymentRequestDocumentFixture.PREQ_APPROVAL_REQUIRED, purchaseOrderDocument, true, new KualiDecimal[] { new KualiDecimal(100) });
}
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testRouteDocument() throws Exception {
purchaseOrderDocument = createPurchaseOrderDocument(PurchaseOrderDocumentFixture.PO_APPROVAL_REQUIRED, true);
purchaseOrderDocument.setAccountDistributionMethod("S");
paymentRequestDocument = createPaymentRequestDocument(PaymentRequestDocumentFixture.PREQ_APPROVAL_REQUIRED, purchaseOrderDocument, true, new KualiDecimal[] { new KualiDecimal(100) });
paymentRequestDocument.setAccountDistributionMethod("S");
AccountingDocumentTestUtils.testRouteDocument(paymentRequestDocument, documentService);
}
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testRouteDocumentToFinal() throws Exception {
purchaseOrderDocument = createPurchaseOrderDocument(PurchaseOrderDocumentFixture.PO_APPROVAL_REQUIRED, true);
paymentRequestDocument = createPaymentRequestDocument(PaymentRequestDocumentFixture.PREQ_APPROVAL_REQUIRED, purchaseOrderDocument, true, new KualiDecimal[] { new KualiDecimal(100) });
final String docId = paymentRequestDocument.getDocumentNumber();
AccountingDocumentTestUtils.routeDocument(paymentRequestDocument, documentService);
WorkflowTestUtils.waitForNodeChange(paymentRequestDocument.getDocumentHeader().getWorkflowDocument(), ACCOUNT_REVIEW);
// the document should now be routed to vputman as Fiscal Officer
changeCurrentUser(rorenfro);
paymentRequestDocument = (PaymentRequestDocument) documentService.getByDocumentHeaderId(docId);
assertTrue("At incorrect node.", WorkflowTestUtils.isAtNode(paymentRequestDocument, ACCOUNT_REVIEW));
assertTrue("Document should be enroute.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isEnroute());
assertTrue("rorenfro should have an approve request.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isApprovalRequested());
documentService.approveDocument(paymentRequestDocument, "Test approving as rorenfro", null);
WorkflowTestUtils.waitForDocumentApproval(paymentRequestDocument.getDocumentNumber());
paymentRequestDocument = (PaymentRequestDocument) documentService.getByDocumentHeaderId(docId);
assertTrue("Document should now be final.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isFinal());
}
// Commented due to Jira issue preventing documents created by PREQ from going to final
// the underlying issue with this test is that the way it is written causes an exception we are unable to solve. The result is:
//
// Caused by: org.apache.ojb.broker.OptimisticLockException: Object has been modified by someone else
//
// This test needs to be re-written to alleviate the OptimisticLockException.
//
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testClosePo() throws Exception {
// route a preq and mark the close po indicator
/*
purchaseOrderDocument = createPurchaseOrderDocument(PurchaseOrderDocumentFixture.CLOSE_PO_WITH_PREQ, true);
paymentRequestDocument = createPaymentRequestDocument(PaymentRequestDocumentFixture.CLOSE_PO_WITH_PREQ,
purchaseOrderDocument, true, new KualiDecimal[] {new KualiDecimal(100)});
final String docId = paymentRequestDocument.getDocumentNumber();
final String poDocId = paymentRequestDocument.getPurchaseOrderDocument().getDocumentNumber();
Thread.sleep(5000); // attempt to make sure any other async processing on this document is done
// another attempt to solve the problem of OptimisticLockException in the call to routeDocument... still no good.
// for (int i = 0; i < 10; i++) {
// try {
// AccountingDocumentTestUtils.routeDocument(paymentRequestDocument, documentService);
// break;
// } catch (Exception e) {
// LOG.warn("attempt #" + (i + 1) + " exception trying to routDocument: [" + e + "]");
// Thread.sleep(6000);
// }
// }
WorkflowTestUtils.waitForNodeChange(paymentRequestDocument.getDocumentHeader().getWorkflowDocument(), ACCOUNT_REVIEW);
// now route
changeCurrentUser(rorenfro);
paymentRequestDocument = (PaymentRequestDocument) documentService.getByDocumentHeaderId(docId);
assertTrue("At incorrect node.", WorkflowTestUtils.isAtNode(paymentRequestDocument, ACCOUNT_REVIEW));
assertTrue("Document should be enroute.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isEnroute());
assertTrue("rorenfro should have an approve request.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isApprovalRequested());
documentService.approveDocument(paymentRequestDocument, "Test approving as rorenfro", null);
WorkflowTestUtils.waitForStatusChange(paymentRequestDocument.getDocumentHeader().getWorkflowDocument(), KewApiConstants.ROUTE_HEADER_FINAL_CD);
// check if the purchase order document is closed
PurchaseOrderDocument purchaseOrderDocument =(PurchaseOrderDocument) purchaseOrderService.getCurrentPurchaseOrder(paymentRequestDocument.getPurchaseOrderDocument().getPurapDocumentIdentifier()); //documentService.getByDocumentHeaderId(poDocId);
assertTrue( "Purchase order should be closed.", PurchaseOrderStatuses.CLOSED.equals( purchaseOrderDocument.getStatusCode() ) );
*/
}
// Commented due to Jira issue preventing documents created by PREQ from going to final
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testReopenPo() throws Exception {
// route a preq and mark the close po indicator
/*
purchaseOrderDocument = createPurchaseOrderDocument(PurchaseOrderDocumentFixture.REOPEN_PO_WITH_PREQ, true);
paymentRequestDocument = createPaymentRequestDocument(PaymentRequestDocumentFixture.REOPEN_PO_WITH_PREQ,
purchaseOrderDocument, true, new KualiDecimal[] {new KualiDecimal(100)});
final String docId = paymentRequestDocument.getDocumentNumber();
final String poDocId = paymentRequestDocument.getPurchaseOrderDocument().getDocumentNumber();
AccountingDocumentTestUtils.routeDocument(paymentRequestDocument, documentService);
WorkflowTestUtils.waitForNodeChange(paymentRequestDocument.getDocumentHeader().getWorkflowDocument(), ACCOUNT_REVIEW);
//close po
changeCurrentUser(parke);
purchaseOrderDocument.setStatusCode(PurchaseOrderStatuses.CLOSED);
AccountingDocumentTestUtils.testSaveDocument(purchaseOrderDocument, documentService);
purchaseOrderDocument =(PurchaseOrderDocument) documentService.getByDocumentHeaderId(poDocId);
// now route
changeCurrentUser(rorenfro);
paymentRequestDocument = (PaymentRequestDocument) documentService.getByDocumentHeaderId(docId);
assertTrue("At incorrect node.", WorkflowTestUtils.isAtNode(paymentRequestDocument, ACCOUNT_REVIEW));
assertTrue("Document should be enroute.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isEnroute());
assertTrue("rorenfro should have an approve request.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isApprovalRequested());
documentService.approveDocument(paymentRequestDocument, "Test approving as rorenfro", null);
WorkflowTestUtils.waitForStatusChange(paymentRequestDocument.getDocumentHeader().getWorkflowDocument(), KewApiConstants.ROUTE_HEADER_FINAL_CD);
// check if the purchase order document is open
PurchaseOrderDocument purchaseOrderDocument =(PurchaseOrderDocument)purchaseOrderService.getCurrentPurchaseOrder(paymentRequestDocument.getPurchaseOrderDocument().getPurapDocumentIdentifier()); //documentService.getByDocumentHeaderId(poDocId);
assertTrue( "Purchase order should be opened.", PurchaseOrderStatuses.OPEN.equals( purchaseOrderDocument.getStatusCode() ) );
*/
}
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testRequestCancel() throws Exception {
// route a preq and mark the preq as requested cancel
/*purchaseOrderDocument = createPurchaseOrderDocument(PurchaseOrderDocumentFixture.PO_APPROVAL_REQUIRED, false);
paymentRequestDocument = createPaymentRequestDocument(PaymentRequestDocumentFixture.PREQ_APPROVAL_REQUIRED,
purchaseOrderDocument, true, new KualiDecimal[] {new KualiDecimal(100)});
final String docId = paymentRequestDocument.getDocumentNumber();
final String poDocId = paymentRequestDocument.getPurchaseOrderDocument().getDocumentNumber();
AccountingDocumentTestUtils.testRouteDocument(paymentRequestDocument, documentService);
WorkflowTestUtils.waitForNodeChange(paymentRequestDocument.getDocumentHeader().getWorkflowDocument(), ACCOUNT_REVIEW);
paymentRequestDocument = (PaymentRequestDocument) documentService.getByDocumentHeaderId(docId);
PaymentRequestDocumentActionAuthorizer preqAA = new PaymentRequestDocumentActionAuthorizer(paymentRequestDocument);
assertTrue( "Payment Request should allow remove request cancel.", preqAA.canRemoveRequestCancel() );*/
}
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testRequestHold() throws Exception {
// route a preq and mark the preq as requested hold
/*purchaseOrderDocument = createPurchaseOrderDocument(PurchaseOrderDocumentFixture.REQUEST_HOLD_PREQ, false);
paymentRequestDocument = createPaymentRequestDocument(PaymentRequestDocumentFixture.REQUEST_HOLD_PREQ,
purchaseOrderDocument, true, new KualiDecimal[] {new KualiDecimal(100)});
final String docId = paymentRequestDocument.getDocumentNumber();
final String poDocId = paymentRequestDocument.getPurchaseOrderDocument().getDocumentNumber();
AccountingDocumentTestUtils.routeDocument(paymentRequestDocument, documentService);
WorkflowTestUtils.waitForNodeChange(paymentRequestDocument.getDocumentHeader().getWorkflowDocument(), ACCOUNT_REVIEW);
paymentRequestDocument = (PaymentRequestDocument) documentService.getByDocumentHeaderId(docId);
PaymentRequestDocumentActionAuthorizer preqAA = new PaymentRequestDocumentActionAuthorizer(paymentRequestDocument);
assertTrue( "Payment Request should allow remove hold.", preqAA.canRemoveHold());*/
}
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testCalculate() throws Exception {
}
/**
*
* Test Usetax and split accounting
* @throws Exception
*/
@ConfigureContext(session = appleton, shouldCommitTransactions = false)
public final void testUseTax() throws Exception {
purchaseOrderDocument = createPurchaseOrderDocument(PurchaseOrderDocumentFixture.PO_APPROVAL_REQUIRED, true);
purchaseOrderDocument.setDeliveryBuildingCode("BL");
purchaseOrderDocument.setDeliveryBuildingLine1Address("2332 Correa Rd");
purchaseOrderDocument.setDeliveryBuildingRoomNumber("124");
purchaseOrderDocument.setDeliveryCityName("Tuscon");
purchaseOrderDocument.setDeliveryStateCode("AZ");
purchaseOrderDocument.setDeliveryPostalCode("85034");
purchaseOrderDocument.setDeliveryCountryCode("US");
purchaseOrderDocument.setBillingLine1Address("2332 Correa Rd");
purchaseOrderDocument.setBillingCityName("Tuscon");
purchaseOrderDocument.setBillingStateCode("AZ");
purchaseOrderDocument.setBillingPostalCode("85034");
purchaseOrderDocument.setBillingCountryCode("US");
purchaseOrderDocument.setVendorName("Prepotech");
purchaseOrderDocument.setVendorCityName("Rocky Hill");
purchaseOrderDocument.setVendorNumber("4105-0");
purchaseOrderDocument.setVendorStateCode("NJ");
purchaseOrderDocument.setVendorPostalCode("08553");
purchaseOrderDocument.setVendorCountryCode("US");
purchaseOrderDocument.setUseTaxIndicator(true);
List<PurchaseOrderItem> poiList = generateItems();
purchaseOrderDocument.setItems(poiList); // add items
purchaseOrderDocument.fixItemReferences();
purchaseOrderDocument.setTotalDollarAmount(new KualiDecimal(1000));
paymentRequestDocument = createPaymentRequestDocument(PaymentRequestDocumentFixture.PREQ_APPROVAL_REQUIRED, purchaseOrderDocument, true, new KualiDecimal[] { new KualiDecimal(1) });
// setup payment request items
for (PurchaseOrderItem poi : poiList) {
if (poi.isItemActiveIndicator() && (poi.getItemQuantity().isPositive()) && (poi.getItemUnitPrice().intValue() > 0)) {
PaymentRequestItem pri = new PaymentRequestItem(poi, paymentRequestDocument);
// pri.setUseTaxItems(poi.getUseTaxItems());
paymentRequestDocument.addItem(pri);
}
}
updateQuantityAndPrice(paymentRequestDocument, new KualiDecimal[] { new KualiDecimal(1) });
paymentRequestDocument.setUseTaxIndicator(true);
AccountingDocumentTestUtils.testSaveDocument(paymentRequestDocument, documentService);
// retrieve saved payment request
final String preqDocId = paymentRequestDocument.getDocumentNumber();
paymentRequestDocument = (PaymentRequestDocument) documentService.getByDocumentHeaderId(preqDocId);
final String docId = paymentRequestDocument.getDocumentNumber();
AccountingDocumentTestUtils.routeDocument(paymentRequestDocument, documentService);
WorkflowTestUtils.waitForNodeChange(paymentRequestDocument.getDocumentHeader().getWorkflowDocument(), ACCOUNT_REVIEW);
// the document should now be routed to vputman as Fiscal Officer
changeCurrentUser(rorenfro);
paymentRequestDocument = (PaymentRequestDocument) documentService.getByDocumentHeaderId(docId);
assertTrue("At incorrect node.", WorkflowTestUtils.isAtNode(paymentRequestDocument, ACCOUNT_REVIEW));
assertTrue("Document should be enroute.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isEnroute());
assertTrue("rorenfro should have an approve request.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isApprovalRequested());
// TODO: This assert needs to be based on non-DB data. Until this is re-written, it will have to be manually changed every time the DB changes.
// assertTrue("total values should be 183", paymentRequestDocument.getTotalDollarAmount().equals(new KualiDecimal(183)));
documentService.approveDocument(paymentRequestDocument, "Test approving as rorenfro", null);
WorkflowTestUtils.waitForDocumentApproval(paymentRequestDocument.getDocumentNumber());
paymentRequestDocument = (PaymentRequestDocument) documentService.getByDocumentHeaderId(docId);
assertTrue("Document should now be final.", paymentRequestDocument.getDocumentHeader().getWorkflowDocument().isFinal());
// paymentRequestDocument.getItems();
}
/**
* Creates a purchase order document with a provided purchase order document.
* At a minimum saves the document, but can additionally route the document (stipulation: coded to work only for budget review).
*
* @param poFixture - purchase order document fixture to source test data
* @param routePO - An option to route the purchase order if set to true
* @return
* @throws Exception
* @ConfigureContext(shouldCommitTransactions=false)
*/
public final PurchaseOrderDocument createPurchaseOrderDocument(PurchaseOrderDocumentFixture poFixture, boolean routePO) throws Exception {
return createPurchaseOrderDocument(poFixture, routePO, null);
}
/**
* Creates a purchase order document with a provided purchase order document.
* At a minimum saves the document, but can additionally route the document (stipulation: coded to work only for budget review).
*
* @param poFixture - purchase order document fixture to source test data
* @param routePO - An option to route the purchase order if set to true
* @param accountsPayablePurchasingDocumentLinkIdentifier - Integer accountsPayablePurchasingDocumentLinkIdentifier to set on the PO if not null
* @return
* @throws Exception
* @ConfigureContext(shouldCommitTransactions=false)
*/
public final PurchaseOrderDocument createPurchaseOrderDocument(PurchaseOrderDocumentFixture poFixture, boolean routePO, Integer accountsPayablePurchasingDocumentLinkIdentifier) throws Exception {
// check if test has been setup
if (documentService == null) {
documentService = SpringContext.getBean(DocumentService.class);
}
// setup purchase order and save
changeCurrentUser(parke);
PurchaseOrderDocument po = poFixture.createPurchaseOrderDocument();
po.setApplicationDocumentStatus(PurchaseOrderStatuses.APPDOC_OPEN);
po.refreshNonUpdateableReferences();
if (ObjectUtils.isNotNull(accountsPayablePurchasingDocumentLinkIdentifier)) {
po.setAccountsPayablePurchasingDocumentLinkIdentifier(accountsPayablePurchasingDocumentLinkIdentifier);
}
AccountingDocumentTestUtils.testSaveDocument(po, documentService);
// retrieve saved purchase order
final String poDocId = po.getDocumentNumber();
po = (PurchaseOrderDocument) documentService.getByDocumentHeaderId(poDocId);
// route if requested
if (routePO) {
AccountingDocumentTestUtils.testRouteDocument(po, documentService);
WorkflowTestUtils.waitForDocumentApproval(po.getDocumentNumber());
po = (PurchaseOrderDocument) documentService.getByDocumentHeaderId(poDocId);
}
po.setAccountDistributionMethod("S");
return po;
}
/* Populates the Purchase Order Item using the info contained in this fixture with split accounting 30/70
*
* @return the populated Purchase Order Item.
*/
private PurchaseOrderItem createPoItem() {
String chart_code = "BL";
BigDecimal percentage = BigDecimal.valueOf(100);
String item_desc = "Iphones";
String item_um = "CT";
String item_catalog_number = "1F742";
PurchaseOrderItem poi = new PurchaseOrderItem();
SequenceAccessorService sas = SpringContext.getBean(SequenceAccessorService.class);
Integer itemIdentifier = sas.getNextAvailableSequenceNumber("PO_ITM_ID", PurchaseOrderDocument.class).intValue();
poi.setItemIdentifier(itemIdentifier);
poi.setItemDescription(item_desc);
poi.setItemUnitOfMeasureCode(item_um);
poi.setItemUnitPrice(BigDecimal.valueOf(100));
poi.setItemTypeCode("ITEM");
poi.setItemQuantity(new KualiDecimal(2));
poi.setItemLineNumber(new Integer(1));
poi.setItemUnitPrice(BigDecimal.valueOf(100));
poi.setTotalAmount(new KualiDecimal(5000));
poi.setItemCatalogNumber(item_catalog_number);
itemIdentifier = sas.getNextAvailableSequenceNumber("PO_ITM_ID", PurchaseOrderDocument.class).intValue();
PurchaseOrderItemUseTax newItemUseTax = new PurchaseOrderItemUseTax();
// newItemUseTax.setAutoIncrementSet(true);
newItemUseTax.setChartOfAccountsCode(chart_code);
newItemUseTax.setAccountNumber("0102395");
newItemUseTax.setFinancialObjectCode("9016");
newItemUseTax.setTaxAmount(new KualiDecimal(56));
newItemUseTax.setRateCode("5");
newItemUseTax.setItemIdentifier(itemIdentifier);
poi.getUseTaxItems().add(newItemUseTax);
itemIdentifier = sas.getNextAvailableSequenceNumber("PO_ITM_ID", PurchaseOrderDocument.class).intValue();
newItemUseTax = new PurchaseOrderItemUseTax();
// newItemUseTax.setAutoIncrementSet(true);
newItemUseTax.setChartOfAccountsCode(chart_code);
newItemUseTax.setAccountNumber("0102395");
newItemUseTax.setFinancialObjectCode("9015");
newItemUseTax.setTaxAmount(new KualiDecimal(20));
newItemUseTax.setRateCode("7");
newItemUseTax.setItemIdentifier(itemIdentifier);
poi.getUseTaxItems().add(newItemUseTax);
itemIdentifier = sas.getNextAvailableSequenceNumber("PO_ITM_ID", PurchaseOrderDocument.class).intValue();
newItemUseTax = new PurchaseOrderItemUseTax();
// newItemUseTax.setAutoIncrementSet(true);
newItemUseTax.setChartOfAccountsCode(chart_code);
newItemUseTax.setAccountNumber("0102395");
newItemUseTax.setFinancialObjectCode("9016");
newItemUseTax.setTaxAmount(new KualiDecimal(7));
newItemUseTax.setRateCode("12");
newItemUseTax.setItemIdentifier(itemIdentifier);
poi.getUseTaxItems().add(newItemUseTax);
// poi.refreshNonUpdateableReferences();
List<PurApAccountingLine> lines = new ArrayList<PurApAccountingLine>();
PurchaseOrderAccount poAccount = new PurchaseOrderAccount();
poAccount.setAccountNumber("1031400");
poAccount.setAccountLinePercent(BigDecimal.valueOf(70));
poAccount.setAmount(new KualiDecimal(70));
poAccount.setChartOfAccountsCode(chart_code);
poAccount.setFinancialObjectCode("5000");
lines.add(poAccount);
PurchaseOrderAccount poAccount1 = new PurchaseOrderAccount();
poAccount1.setAccountNumber("1031420");
poAccount1.setAccountLinePercent(BigDecimal.valueOf(30));
poAccount1.setAmount(new KualiDecimal(30));
poAccount1.setChartOfAccountsCode(chart_code);
poAccount1.setFinancialObjectCode("5000");
lines.add(poAccount1);
poi.setSourceAccountingLines(lines);
poi.setItemActiveIndicator(true);
poi.refreshNonUpdateableReferences();
return poi;
}
/**
*
* generate list of usetax items to test with
* @return
* @throws Exception
*/
private List<PurchaseOrderItem> generateItems() throws Exception {
List<PurchaseOrderItem> items = new ArrayList<PurchaseOrderItem>();
// set items to document
items.add(createPoItem());
return items;
}
/**
* Creates a new payment request document and additionally saves it.
*
* @param preqFixture - The payment request document fixture to source test data from
* @param po - The purchase order to copy select values from and to link to the payment request document
* @param copyPoItems - An option to copy the items from the purchase order if set to true
* @param itemQuantityList - A list of quantity values for each item in your payment request document
* @return
* @throws Exception
* @ConfigureContext(shouldCommitTransactions=false)
*/
public final PaymentRequestDocument createPaymentRequestDocument(PaymentRequestDocumentFixture preqFixture, PurchaseOrderDocument po, boolean copyPoItems, KualiDecimal[] itemQuantityList) throws Exception {
// check if test has been setup
if (documentService == null) {
documentService = SpringContext.getBean(DocumentService.class);
}
// setup purchase order and save
changeCurrentUser(appleton);
PaymentRequestDocument preq = preqFixture.createPaymentRequestDocument();
preq.initiateDocument();
// set payment request from po, and optionally copy the items
if (copyPoItems) {
preq.populatePaymentRequestFromPurchaseOrder(po, new HashMap());
} else {
populatePaymentRequestFromPurchaseOrderWithoutItems(preq, po);
}
// set quantity and calculate price
updateQuantityAndPrice(preq, itemQuantityList);
AccountingDocumentTestUtils.testSaveDocument(preq, documentService);
// retrieve saved payment request
final String preqDocId = preq.getDocumentNumber();
preq = (PaymentRequestDocument) documentService.getByDocumentHeaderId(preqDocId);
preq.setAccountDistributionMethod("S");
return preq;
}
/**
* Populates fields on a payment request with data from a purchase order, but
* does not copy the purchase order items.
*
* @param preq
* @param po
*/
private void populatePaymentRequestFromPurchaseOrderWithoutItems(PaymentRequestDocument preq, PurchaseOrderDocument po) {
preq.setPurchaseOrderIdentifier(po.getPurapDocumentIdentifier());
preq.getDocumentHeader().setOrganizationDocumentNumber(po.getDocumentHeader().getOrganizationDocumentNumber());
preq.setPostingYear(po.getPostingYear());
preq.setVendorCustomerNumber(po.getVendorCustomerNumber());
if (po.getPurchaseOrderCostSource() != null) {
preq.setPaymentRequestCostSource(po.getPurchaseOrderCostSource());
preq.setPaymentRequestCostSourceCode(po.getPurchaseOrderCostSourceCode());
}
if (po.getVendorShippingPaymentTerms() != null) {
preq.setVendorShippingPaymentTerms(po.getVendorShippingPaymentTerms());
preq.setVendorShippingPaymentTermsCode(po.getVendorShippingPaymentTermsCode());
}
if (po.getRecurringPaymentType() != null) {
preq.setRecurringPaymentType(po.getRecurringPaymentType());
preq.setRecurringPaymentTypeCode(po.getRecurringPaymentTypeCode());
}
preq.setVendorHeaderGeneratedIdentifier(po.getVendorHeaderGeneratedIdentifier());
preq.setVendorDetailAssignedIdentifier(po.getVendorDetailAssignedIdentifier());
preq.setVendorCustomerNumber(po.getVendorCustomerNumber());
preq.setVendorName(po.getVendorName());
// populate preq vendor address with the default remit address type for the vendor if found
String userCampus = GlobalVariables.getUserSession().getPerson().getCampusCode();
VendorAddress vendorAddress = SpringContext.getBean(VendorService.class).getVendorDefaultAddress(po.getVendorHeaderGeneratedIdentifier(), po.getVendorDetailAssignedIdentifier(), VendorConstants.AddressTypes.REMIT, userCampus);
if (vendorAddress != null) {
preq.templateVendorAddress(vendorAddress);
preq.setVendorAddressGeneratedIdentifier(vendorAddress.getVendorAddressGeneratedIdentifier());
} else {
// set address from PO
preq.setVendorAddressGeneratedIdentifier(po.getVendorAddressGeneratedIdentifier());
preq.setVendorLine1Address(po.getVendorLine1Address());
preq.setVendorLine2Address(po.getVendorLine2Address());
preq.setVendorCityName(po.getVendorCityName());
preq.setVendorStateCode(po.getVendorStateCode());
preq.setVendorPostalCode(po.getVendorPostalCode());
preq.setVendorCountryCode(po.getVendorCountryCode());
}
if ((po.getVendorPaymentTerms() == null) || ("".equals(po.getVendorPaymentTerms().getVendorPaymentTermsCode()))) {
preq.setVendorPaymentTerms(new PaymentTermType());
preq.setVendorPaymentTermsCode("");
} else {
preq.setVendorPaymentTermsCode(po.getVendorPaymentTermsCode());
preq.setVendorPaymentTerms(po.getVendorPaymentTerms());
}
preq.setPaymentRequestPayDate(SpringContext.getBean(PaymentRequestService.class).calculatePayDate(preq.getInvoiceDate(), preq.getVendorPaymentTerms()));
// add missing below the line
SpringContext.getBean(PurapService.class).addBelowLineItems(preq);
preq.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier());
preq.refreshNonUpdateableReferences();
}
/**
* Updates the quanities for each payment request item in order.
* Also updates the extended price for above and below the line items,
* and finally updates the amounts for each accounting line.
*
* @param preq
* @param quantityList
*/
public void updateQuantityAndPrice(PaymentRequestDocument preq, KualiDecimal[] quantityList) {
int quantityIndex = 0;
KualiDecimal quantity = null;
for (PaymentRequestItem pri : (List<PaymentRequestItem>) preq.getItems()) {
if (pri.getItemType().isLineItemIndicator()) {
if (pri.getItemType().isQuantityBasedGeneralLedgerIndicator()) {
// if within range of passed in quantities
if (quantityIndex <= (quantityList.length - 1)) {
quantity = quantityList[quantityIndex];
} else {
quantity = new KualiDecimal(0);
}
pri.setItemQuantity(quantity);
pri.setExtendedPrice(pri.calculateExtendedPrice());
BigDecimal calcExtendedPrice = pri.getItemUnitPrice().multiply(pri.getItemQuantity().bigDecimalValue());
} else {
pri.setExtendedPrice(pri.calculateExtendedPrice());
}
} else {
pri.setExtendedPrice(pri.calculateExtendedPrice());
// LOG.info("updateQuantityandPrice() no gl"+ pri.getItemQuantity() + " : "+ pri.getItemDescription() +
// " : up "+ pri.getItemUnitPrice() + " calc " + pri.calculateExtendedPrice());
}
for (PurApAccountingLine accountingLine : pri.getSourceAccountingLines()) {
accountingLine.setAmount(pri.getExtendedPrice().multiply(new KualiDecimal(accountingLine.getAccountLinePercent())).divide(new KualiDecimal(100)));
}
}
}
}