/*
* 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.fixture.UserNameFixture.appleton;
import static org.kuali.kfs.sys.fixture.UserNameFixture.kfs;
import static org.kuali.kfs.sys.fixture.UserNameFixture.parke;
import java.util.ArrayList;
import java.util.List;
import junit.framework.Assert;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.module.purap.PurapConstants.PurchaseOrderDocTypes;
import org.kuali.kfs.module.purap.PurapConstants.PurchaseOrderStatuses;
import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem;
import org.kuali.kfs.module.purap.document.service.PurchaseOrderService;
import org.kuali.kfs.module.purap.fixture.PaymentRequestDocumentFixture;
import org.kuali.kfs.module.purap.fixture.PurApItemFixture;
import org.kuali.kfs.module.purap.fixture.PurchaseOrderDocumentFixture;
import org.kuali.kfs.module.purap.fixture.PurchaseOrderItemFixture;
import org.kuali.kfs.sys.ConfigureContext;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.context.KualiTestBase;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.document.AccountingDocumentTestUtils;
import org.kuali.rice.kew.api.document.DocumentStatus;
import org.kuali.rice.krad.exception.ValidationException;
import org.kuali.rice.krad.service.DocumentService;
import org.kuali.rice.krad.util.GlobalVariables;
public class PurchaseOrderChangeDocumentTest extends KualiTestBase {
protected static DocumentService docService = null;
protected static PurchaseOrderService poService = null;
protected static PurchaseOrderDocument poTest = null;
protected static PurchaseOrderDocument poChange = null;
@Override
protected void setUp() throws Exception {
super.setUp();
docService = SpringContext.getBean(DocumentService.class);
poService = SpringContext.getBean(PurchaseOrderService.class);
// Create and save a minimally-populated basic PO document for each test.
poTest = PurchaseOrderDocumentFixture.PO_ONLY_REQUIRED_FIELDS_MULTI_ITEMS.createPurchaseOrderDocument();
poTest.setApplicationDocumentStatus(PurchaseOrderStatuses.APPDOC_OPEN);
poTest.refreshNonUpdateableReferences();
poTest.prepareForSave();
AccountingDocumentTestUtils.saveDocument(poTest, docService);
}
@Override
protected void tearDown() throws Exception {
docService = null;
poService = null;
poTest = null;
poChange = null;
super.tearDown();
}
/**
* Refreshes poTest and poChange by fetching them from DB,
* so that changes made to them during routing will be reflected.
*/
private void refreshPO() {
poTest = poService.getPurchaseOrderByDocumentNumber(poTest.getDocumentNumber());
//poChange = poService.getPurchaseOrderByDocumentNumber(poChange.getDocumentNumber());
}
/**
* Calls PO service to create and save a PO change document and assigns the new document to poChange;
* refreshes poTest by fetching it from DB so that changes made to the existing PO will be reflected;
* also, makes reasons for test exceptions more obvious by inserting into the exception's
* message the error maps which contain the keys to human-readable reasons for rule failure.
*
* @param documentType A String, one of the PurchaseOrderDocumentTypes.
* @param documentStatus A String, one of the PurchaseOrderDocumentStatuses.
*
* @throws Exception
*/
private void createAndSavePOChangeDocument(String documentType, String documentStatus) throws Exception {
try {
poChange = poService.createAndSavePotentialChangeDocument(
poTest.getDocumentNumber(), documentType, documentStatus);
poChange = (PurchaseOrderDocument) docService.getByDocumentHeaderId(poChange.getDocumentNumber());
poTest = poService.getPurchaseOrderByDocumentNumber(poTest.getDocumentNumber());
}
catch (ValidationException ve) {
throw new ValidationException(GlobalVariables.getMessageMap().toString() + ve);
}
}
/**
* Calls PO service to create and route a PO change document and assigns the new document to poChange;
* refreshes poTest by fetching it from DB so that changes made to the existing PO will be reflected;
* also, makes reasons for test exceptions more obvious by inserting into the exception's
* message the error maps which contain the keys to human-readable reasons for rule failure.
*
* @param documentType A String, one of the PurchaseOrderDocumentTypes.
* @param documentStatus A String, one of the PurchaseOrderDocumentStatuses.
*
* @throws Exception
*/
private void createAndRoutePOChangeDocument(String documentType, String documentStatus) throws Exception {
try {
poChange = poService.createAndRoutePotentialChangeDocument(
poTest.getDocumentNumber(), documentType, "unit test", new ArrayList(), documentStatus);
poTest = poService.getPurchaseOrderByDocumentNumber(poTest.getDocumentNumber());
}
catch (ValidationException ve) {
throw new ValidationException(GlobalVariables.getMessageMap().toString() + ve);
}
}
private void createAndSavePOSplitDocument(List<PurchaseOrderItem> newPOItems, boolean copyNotes, String splitNoteText) throws Exception {
try {
poTest.setApplicationDocumentStatus(PurchaseOrderStatuses.APPDOC_IN_PROCESS);
poChange = poService.createAndSavePurchaseOrderSplitDocument(
newPOItems, poTest, copyNotes, splitNoteText);
poTest = poService.getPurchaseOrderByDocumentNumber(poTest.getDocumentNumber());
}
catch (ValidationException ve) {
throw new ValidationException(GlobalVariables.getMessageMap().toString() + ve);
}
}
@ConfigureContext(session = kfs, shouldCommitTransactions=true)
public final void testPurchaseOrderClose() throws Exception {
// There must be a PREQ against this PO in order to close this PO.
changeCurrentUser(appleton);
PaymentRequestDocument preq = PaymentRequestDocumentFixture.PREQ_FOR_PO_CLOSE_DOC.createPaymentRequestDocument();
preq.setPurchaseOrderIdentifier(poTest.getPurapDocumentIdentifier());
AccountingDocumentTestUtils.saveDocument(preq, docService);
createAndRoutePOChangeDocument(
PurchaseOrderDocTypes.PURCHASE_ORDER_CLOSE_DOCUMENT,
PurchaseOrderStatuses.APPDOC_PENDING_CLOSE);
assertMatchChangePO(poTest, poChange); /*
if (!poChange.getDocumentHeader().getWorkflowDocument().getStatus().equals(DocumentStatus.FINAL)) {
assertTrue(poTest.isPurchaseOrderCurrentIndicator());
assertTrue(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.PENDING_CLOSE));
assertFalse(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_CHANGE_IN_PROCESS));
}
WorkflowTestUtils.waitForStatusChange(poChange.getDocumentHeader().getWorkflowDocument(), DocumentStatus.FINAL);
refreshPO();
if (poChange.getDocumentHeader().getWorkflowDocument().isFinal()) { */
assertFalse(poTest.isPurchaseOrderCurrentIndicator());
assertFalse(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_RETIRED_VERSION));
assertTrue(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_CLOSED));
//}
}
@ConfigureContext(session = parke, shouldCommitTransactions=true)
public void testSplitPurchaseOrder() throws Exception {
List<PurchaseOrderItem> items = new ArrayList<PurchaseOrderItem>();
items.add((PurchaseOrderItem)PurchaseOrderItemFixture.PO_QTY_UNRESTRICTED_ITEM_2.createPurchaseOrderItem(PurApItemFixture.BASIC_QTY_ITEM_2));
createAndSavePOSplitDocument(items, true, "Reason for splitting.");
// Proving that most things other than items are the same.
assertMatchChangePO(poTest, poChange);
assertTrue(poTest.getPurapDocumentIdentifier().compareTo(poChange.getPurapDocumentIdentifier()) < 0);
// Neither the original nor the resulting PO may have no items.
assertFalse(poChange.getItems().size() == 1);
assertFalse(poTest.getItems().size() == 1);
List<PurchaseOrderItem> splitPOItems = poChange.getItems();
// Check renumbering.
int i = 0;
for (PurchaseOrderItem splitPOItem : splitPOItems ) {
if (splitPOItem.getItemType().isLineItemIndicator()) {
assertTrue(splitPOItem.getItemLineNumber().intValue() == ++i);
}
}
}
@ConfigureContext(session = parke, shouldCommitTransactions=true)
public final void testAmendPurchaseOrder() throws Exception {
createAndSavePOChangeDocument(
PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT,
PurchaseOrderStatuses.APPDOC_AMENDMENT);
assertMatchChangePO(poTest, poChange);
if (!poChange.getDocumentHeader().getWorkflowDocument().getStatus().equals(DocumentStatus.FINAL)) {
assertTrue(poTest.isPurchaseOrderCurrentIndicator());
assertTrue(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_AMENDMENT));
assertFalse(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_CHANGE_IN_PROCESS));
} /*
WorkflowTestUtils.waitForStatusChange(poChange.getDocumentHeader().getWorkflowDocument(), DocumentStatus.FINAL);
refreshPO();
if (poChange.getDocumentHeader().getWorkflowDocument().isFinal()) {
assertFalse(poTest.isPurchaseOrderCurrentIndicator());
assertFalse(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_RETIRED_VERSION));
assertTrue(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_OPEN));
} */
}
/**
* Creates and saves a PurchaseOrderAmendmentDocument, then calls
* the documentService to cancel the PurchaseOrderAmendmentDocument.
* This is to test the case for canceling a PurchaseOrderAmendmentDocument.
*
* @throws Exception
*/
@ConfigureContext(session = kfs, shouldCommitTransactions=true)
public final void testCancelAmendPurchaseOrder() throws Exception {
createAndSavePOChangeDocument(
PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT,
PurchaseOrderStatuses.APPDOC_AMENDMENT);
assertMatchChangePO(poTest, poChange);
if (!poChange.getDocumentHeader().getWorkflowDocument().getStatus().equals(DocumentStatus.FINAL)) {
assertTrue(poTest.isPurchaseOrderCurrentIndicator());
assertTrue(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_AMENDMENT));
assertFalse(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_CHANGE_IN_PROCESS));
}
SpringContext.getBean(DocumentService.class).cancelDocument(poChange, "");
assertTrue(poChange.getDocumentHeader().getWorkflowDocument().getStatus().getCode().equals(KFSConstants.DocumentStatusCodes.CANCELLED));
}
@ConfigureContext(session = kfs, shouldCommitTransactions=true)
public final void testPurchaseOrderPaymentHold() throws Exception {
createAndRoutePOChangeDocument(
PurchaseOrderDocTypes.PURCHASE_ORDER_PAYMENT_HOLD_DOCUMENT,
PurchaseOrderStatuses.APPDOC_PENDING_PAYMENT_HOLD);
assertMatchChangePO(poTest, poChange); /*
if (!poChange.getDocumentHeader().getWorkflowDocument().getStatus().equals(DocumentStatus.FINAL)) {
assertTrue(poTest.isPurchaseOrderCurrentIndicator());
assertTrue(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_PENDING_APPDOC_PAYMENT_HOLD));
assertFalse(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_CHANGE_IN_PROCESS));
}
WorkflowTestUtils.waitForStatusChange(poChange.getDocumentHeader().getWorkflowDocument(), DocumentStatus.FINAL);
refreshPO();
if (poChange.getDocumentHeader().getWorkflowDocument().isFinal()) { */
assertFalse(poTest.isPurchaseOrderCurrentIndicator());
assertFalse(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_RETIRED_VERSION));
assertTrue(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_PAYMENT_HOLD));
//}
}
@ConfigureContext(session = kfs, shouldCommitTransactions=true)
public final void testPurchaseOrderRemoveHold() throws Exception {
poTest.setApplicationDocumentStatus(PurchaseOrderStatuses.APPDOC_PAYMENT_HOLD);
poTest.refreshNonUpdateableReferences();
createAndRoutePOChangeDocument(
PurchaseOrderDocTypes.PURCHASE_ORDER_REMOVE_HOLD_DOCUMENT,
PurchaseOrderStatuses.APPDOC_PENDING_REMOVE_HOLD);
assertMatchChangePO(poTest, poChange); /*
if (!poChange.getDocumentHeader().getWorkflowDocument().getStatus().equals(DocumentStatus.FINAL)) {
assertTrue(poTest.isPurchaseOrderCurrentIndicator());
assertTrue(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_PENDING_REMOVE_HOLD));
assertFalse(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_CHANGE_IN_PROCESS));
}
WorkflowTestUtils.waitForStatusChange(poChange.getDocumentHeader().getWorkflowDocument(), DocumentStatus.FINAL);
refreshPO();
if (poChange.getDocumentHeader().getWorkflowDocument().isFinal()) { */
assertFalse(poTest.isPurchaseOrderCurrentIndicator());
assertFalse(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_RETIRED_VERSION));
assertTrue(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_OPEN));
//}
}
@ConfigureContext(session = parke, shouldCommitTransactions=true)
public final void testPurchaseOrderReopen() throws Exception {
poTest.setApplicationDocumentStatus(PurchaseOrderStatuses.APPDOC_CLOSED);
poTest.refreshNonUpdateableReferences();
createAndRoutePOChangeDocument(
PurchaseOrderDocTypes.PURCHASE_ORDER_REOPEN_DOCUMENT,
PurchaseOrderStatuses.APPDOC_PENDING_REOPEN);
assertMatchChangePO(poTest, poChange); /*
if (!poChange.getDocumentHeader().getWorkflowDocument().getStatus().equals(DocumentStatus.FINAL)) {
assertTrue(poTest.isPurchaseOrderCurrentIndicator());
assertTrue(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_PENDING_REOPEN));
assertFalse(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_CHANGE_IN_PROCESS));
}
WorkflowTestUtils.waitForStatusChange(poChange.getDocumentHeader().getWorkflowDocument(), DocumentStatus.FINAL);
refreshPO();
if (poChange.getDocumentHeader().getWorkflowDocument().isFinal()) { */
assertFalse(poTest.isPurchaseOrderCurrentIndicator());
assertFalse(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_RETIRED_VERSION));
assertTrue(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_OPEN));
//}
}
@ConfigureContext(session = parke, shouldCommitTransactions=true)
public final void testPurchaseOrderVoid() throws Exception {
createAndRoutePOChangeDocument(
PurchaseOrderDocTypes.PURCHASE_ORDER_VOID_DOCUMENT,
PurchaseOrderStatuses.APPDOC_PENDING_VOID);
assertMatchChangePO(poTest, poChange); /*
if (!poChange.getDocumentHeader().getWorkflowDocument().getStatus().equals(DocumentStatus.FINAL)) {
assertTrue(poTest.isPurchaseOrderCurrentIndicator());
assertTrue(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_PENDING_VOID));
assertFalse(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_CHANGE_IN_PROCESS));
}
WorkflowTestUtils.waitForStatusChange(poChange.getDocumentHeader().getWorkflowDocument(), DocumentStatus.FINAL);
refreshPO();
if (poChange.getDocumentHeader().getWorkflowDocument().isFinal()) { */
assertFalse(poTest.isPurchaseOrderCurrentIndicator());
assertFalse(poTest.isPendingActionIndicator());
assertTrue(poTest.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_RETIRED_VERSION));
assertTrue(poChange.isPurchaseOrderCurrentIndicator());
assertFalse(poChange.isPendingActionIndicator());
assertTrue(poChange.getApplicationDocumentStatus().equals(PurchaseOrderStatuses.APPDOC_VOID));
//}
}
/**
* Matches an existing Purchase Order Document with a change PO Document newly generated from it;
* Fails the assertion if any of the copied persistent fields don't match.
*/
public static void assertMatchChangePO(PurchaseOrderDocument doc1, PurchaseOrderDocument doc2) {
// match posting year
if (StringUtils.isNotBlank(doc1.getPostingPeriodCode()) && StringUtils.isNotBlank(doc2.getPostingPeriodCode())) {
Assert.assertEquals(doc1.getPostingPeriodCode(), doc2.getPostingPeriodCode());
}
Assert.assertEquals(doc1.getPostingYear(), doc2.getPostingYear());
// match important fields in PO
Assert.assertEquals(doc1.getVendorHeaderGeneratedIdentifier(), doc2.getVendorHeaderGeneratedIdentifier());
Assert.assertEquals(doc1.getVendorDetailAssignedIdentifier(), doc2.getVendorDetailAssignedIdentifier());
Assert.assertEquals(doc1.getVendorName(), doc2.getVendorName());
Assert.assertEquals(doc1.getVendorNumber(), doc2.getVendorNumber());
Assert.assertEquals(doc1.getChartOfAccountsCode(), doc2.getChartOfAccountsCode());
Assert.assertEquals(doc1.getOrganizationCode(), doc2.getOrganizationCode());
Assert.assertEquals(doc1.getDeliveryCampusCode(), doc2.getDeliveryCampusCode());
Assert.assertEquals(doc1.getDeliveryRequiredDate(), doc2.getDeliveryRequiredDate());
Assert.assertEquals(doc1.getRequestorPersonName(), doc2.getRequestorPersonName());
Assert.assertEquals(doc1.getContractManagerCode(), doc2.getContractManagerCode());
Assert.assertEquals(doc1.getVendorContractName(), doc2.getVendorContractName());
Assert.assertEquals(doc1.getPurchaseOrderAutomaticIndicator(), doc2.getPurchaseOrderAutomaticIndicator());
Assert.assertEquals(doc1.getPurchaseOrderTransmissionMethodCode(), doc2.getPurchaseOrderTransmissionMethodCode());
Assert.assertEquals(doc1.getRequisitionIdentifier(), doc2.getRequisitionIdentifier());
Assert.assertEquals(doc1.getPurchaseOrderPreviousIdentifier(), doc2.getPurchaseOrderPreviousIdentifier());
Assert.assertEquals(doc1.getPurchaseOrderCreateTimestamp(), doc2.getPurchaseOrderCreateTimestamp());
Assert.assertEquals(doc1.getPurchaseOrderLastTransmitTimestamp(), doc2.getPurchaseOrderLastTransmitTimestamp());
}
}