org.kuali.kfs.module.purap.document.web.struts.ElectronicInvoiceTestAction.java Source code

Java tutorial

Introduction

Here is the source code for org.kuali.kfs.module.purap.document.web.struts.ElectronicInvoiceTestAction.java

Source

/*
 * 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.web.struts;

import java.io.ByteArrayOutputStream;
import java.io.StringBufferInputStream;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.kuali.kfs.module.purap.PurapKeyConstants;
import org.kuali.kfs.module.purap.PurapPropertyConstants;
import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem;
import org.kuali.kfs.module.purap.document.PurchaseOrderDocument;
import org.kuali.kfs.module.purap.document.service.PurchaseOrderService;
import org.kuali.kfs.module.purap.util.ElectronicInvoiceUtils;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.vnd.businessobject.PaymentTermType;
import org.kuali.rice.core.api.datetime.DateTimeService;
import org.kuali.rice.core.api.util.RiceConstants;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.kns.web.struts.action.KualiAction;
import org.kuali.rice.krad.exception.AuthorizationException;
import org.kuali.rice.krad.service.DocumentService;
import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.KRADUtils;

/**
 * Struts Action for printing Purap documents outside of a document action
 */
public class ElectronicInvoiceTestAction extends KualiAction {
    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
            .getLogger(ElectronicInvoiceTestAction.class);

    private static final String AREA_C0DE = "areaCode";
    private static final String PHONE_NUMBER = "phoneNumber";

    protected static volatile DocumentService documentService;

    /**
     * @see org.kuali.rice.kns.web.struts.action.KualiAction#execute(org.apache.struts.action.ActionMapping,
     *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        // TODO Uncomment the following code. This method doesn't need override. 
        // It's here as a temp get-around for a bug complaining method "generate" cannot be found 
        String methodToCall = findMethodToCall(form, request);
        if (StringUtils.equals(methodToCall, "generate")) {
            return generate(mapping, form, request, response);
        }
        return mapping.findForward(KFSConstants.MAPPING_BASIC);
    }

    /**
     * @see org.kuali.rice.kns.web.struts.action.KualiAction#checkAuthorization(org.apache.struts.action.ActionForm, java.lang.String)
     * 
     * Only allow users to test eInvoicing in the test environment
     */
    @Override
    protected void checkAuthorization(ActionForm form, String methodToCall) throws AuthorizationException {
        if (KRADUtils.isProductionEnvironment()) {
            //this process is not available for production
            throw new AuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalName(),
                    methodToCall, this.getClass().getSimpleName());
        }
    }

    /**
     * Generates Electronic Invoice xml file from a Purchase Order, for testing purpose only.     
     */
    public ActionForward generate(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        checkAuthorization(form, "");

        ElectronicInvoiceTestForm testForm = (ElectronicInvoiceTestForm) form;
        String poDocNumber = testForm.getPoDocNumber();
        LOG.info("Generating Electronic Invoice XML file for Purchase Order Document " + poDocNumber);
        PurchaseOrderService poService = SpringContext.getBean(PurchaseOrderService.class);
        PurchaseOrderDocument po = null;

        if (StringUtils.isBlank(poDocNumber)) {
            GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_DOCUMENT_NUMBER,
                    PurapKeyConstants.ERROR_ELECTRONIC_INVOICE_GENERATION_PURCHASE_ORDER_NUMBER_EMPTY,
                    new String[] { poDocNumber });
            return mapping.findForward(RiceConstants.MAPPING_BASIC);
        }
        if (!getDocumentService().documentExists(poDocNumber)) {
            GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_DOCUMENT_NUMBER,
                    PurapKeyConstants.ERROR_ELECTRONIC_INVOICE_GENERATION_PURCHASE_ORDER_DOES_NOT_EXIST,
                    poDocNumber);
            return mapping.findForward(RiceConstants.MAPPING_BASIC);
        }

        try {
            po = poService.getPurchaseOrderByDocumentNumber(poDocNumber);
        } catch (Exception e) {
            throw e;
        }

        response.setHeader("Cache-Control", "max-age=30");
        response.setContentType("application/xml");
        StringBuffer sbContentDispValue = new StringBuffer();
        String useJavascript = request.getParameter("useJavascript");
        if (useJavascript == null || useJavascript.equalsIgnoreCase("false")) {
            sbContentDispValue.append("attachment");
        } else {
            sbContentDispValue.append("inline");
        }
        StringBuffer sbFilename = new StringBuffer();
        sbFilename.append("PO_");
        sbFilename.append(poDocNumber);
        sbFilename.append(".xml");
        sbContentDispValue.append("; filename=");
        sbContentDispValue.append(sbFilename);
        response.setHeader("Content-disposition", sbContentDispValue.toString());

        // lookup the PO and fill in the XML with valid data
        if (po != null) {
            String duns = "";
            if (po.getVendorDetail() != null) {
                duns = StringUtils.defaultString(po.getVendorDetail().getVendorDunsNumber());
            }

            DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
            String currDate = ElectronicInvoiceUtils.getDateDisplayText(dateTimeService.getCurrentDate()); // getting date in kfs format
            String vendorNumber = po.getVendorDetail().getVendorNumber();

            String eInvoiceFile = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                    + "\n<!-- ******Testing tool generated XML****** Version 1.2." + "\n\n  Generated On "
                    + currDate + " for PO " + po.getPurapDocumentIdentifier() + " (Doc# " + poDocNumber
                    + ") -->\n\n" + "<!-- All the cXML attributes are junk values -->\n"
                    + "<cXML payloadID=\"200807260401062080.964@eai002\"\n"
                    + "    timestamp=\"2008-07-26T04:01:06-08:00\"\n" + "    version=\"1.2.014\" xml:lang=\"en\" \n"
                    + "    xmlns=\"http://www.kuali.org/kfs/purap/electronicInvoice\" \n"
                    + "    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + "  <Header>\n"
                    + "      <From>\n" + "          <Credential domain=\"DUNS\">\n" + "              <Identity>"
                    + duns + "</Identity> <!-- DUNS number from PO Vendor " + vendorNumber + "-->\n"
                    + "          </Credential>\n" + "      </From>\n" + "      <To>\n"
                    + "          <Credential domain=\"NetworkId\">\n" + "              <Identity>" + "IU"
                    + "</Identity> <!-- Hardcoded --> \n" + "          </Credential>\n" + "      </To>\n"
                    + "      <Sender>\n" + "          <Credential domain=\"DUNS\">\n" + "              <Identity>"
                    + duns + "</Identity> <!-- DUNS number from PO Vendor " + vendorNumber + "-->\n"
                    + "          </Credential>\n" + "          <UserAgent/>\n" + "      </Sender>\n"
                    + "  </Header>\n" + "  <Request deploymentMode=\"production\">\n"
                    + "      <InvoiceDetailRequest>\n" + "          <InvoiceDetailRequestHeader\n"
                    + "              invoiceDate=\"" + currDate + "\" invoiceID=\"" + RandomUtils.nextInt()
                    + "\" operation=\"new\" purpose=\"standard\"> <!-- invoiceID=Random unique Id, invoiceDate=Curr date -->\n"
                    + "              <InvoiceDetailHeaderIndicator/>\n"
                    + "              <InvoiceDetailLineIndicator/>\n" + "              <InvoicePartner>\n"
                    + getContactXMLChunk("billTo", po) + "              </InvoicePartner>\n"
                    + "              <InvoicePartner>\n" + "                  <Contact addressID=\""
                    + RandomUtils.nextInt() + "\" role=\"remitTo\"> <!-- Vendor address -->\n"
                    + "                      <Name xml:lang=\"en\">\n" + "                          "
                    + po.getVendorName() + "\n" + "                      </Name>\n"
                    + "                      <PostalAddress>\n" + "                          <Street>"
                    + StringUtils.defaultString(po.getVendorLine1Address()) + "</Street>\n"
                    + "                          <Street>" + StringUtils.defaultString(po.getVendorLine2Address())
                    + "</Street>\n" + "                          <City>"
                    + StringUtils.defaultString(po.getVendorCityName()) + "</City>\n"
                    + "                          <State>" + StringUtils.defaultString(po.getVendorStateCode())
                    + "</State>\n" + "                          <PostalCode>"
                    + StringUtils.defaultString(po.getVendorPostalCode()) + "</PostalCode>\n"
                    + "                          <Country isoCountryCode=\""
                    + StringUtils.defaultString(po.getVendorCountryCode()) + "\">\n"
                    + "                              " + StringUtils.defaultString(po.getVendorCountry().getName())
                    + "\n" + "                          </Country>\n" + "                      </PostalAddress>\n"
                    + "                  </Contact>\n" + "              </InvoicePartner>\n"
                    + getDeliveryAddressXMLChunk("shipTo", po) + getPaymentTermXML(po)
                    + "          </InvoiceDetailRequestHeader>\n" + "          <InvoiceDetailOrder>\n"
                    + "              <InvoiceDetailOrderInfo>\n" + "                  <OrderReference\n"
                    + "                      orderDate=\""
                    + ElectronicInvoiceUtils.getDateDisplayText(dateTimeService.getCurrentDate()) + "\" orderID=\""
                    + po.getPurapDocumentIdentifier() + "\"> <!--orderDate=Curr date,orderID=PO#-->\n"
                    + "                      <DocumentReference payloadID=\"NA\" /> <!--HardCoded-->\n"
                    + "                  </OrderReference>\n" + "              </InvoiceDetailOrderInfo>\n"
                    + "              <!-- No junk values in Items-->\n";

            for (int i = 0; i < po.getItems().size(); i++) {
                List items = po.getItems();
                PurchaseOrderItem item = (PurchaseOrderItem) items.get(i);
                if (!item.getItemType().isAdditionalChargeIndicator()) {
                    eInvoiceFile = eInvoiceFile + getPOItemXMLChunk(item);
                }
            }

            KualiDecimal totalDollarAmt = po.getTotalDollarAmount() == null ? KualiDecimal.ZERO
                    : po.getTotalDollarAmount();
            eInvoiceFile = eInvoiceFile +

                    "          </InvoiceDetailOrder>\n" + "          <InvoiceDetailSummary>\n"
                    + "              <SubtotalAmount>\n" + "                  <Money currency=\"USD\">"
                    + po.getTotalPreTaxDollarAmount() + "</Money>\n" + "              </SubtotalAmount>\n"
                    + "              <Tax>\n" + "                  <Money currency=\"USD\">"
                    + po.getTotalTaxAmount() + "</Money>\n"
                    + "                  <Description xml:lang=\"en\">Total Tax</Description>\n"
                    + "              </Tax>\n" + "              <SpecialHandlingAmount>\n"
                    + "                  <Money currency=\"USD\">0.00</Money>\n"
                    + "              </SpecialHandlingAmount>\n" + "              <ShippingAmount>\n"
                    + "                  <Money currency=\"USD\">0.00</Money>\n"
                    + "              </ShippingAmount>\n" + "              <GrossAmount>\n"
                    + "                  <Money currency=\"USD\">" + totalDollarAmt + "</Money>\n"
                    + "              </GrossAmount>\n" + "              <InvoiceDetailDiscount>\n"
                    + "                  <Money currency=\"USD\">0.00</Money>\n"
                    + "                  </InvoiceDetailDiscount>\n" + "              <NetAmount>\n"
                    + "                  <Money currency=\"USD\">" + totalDollarAmt + "</Money>\n"
                    + "              </NetAmount>\n" + "              <DepositAmount>\n"
                    + "                  <Money currency=\"USD\">0.00</Money>\n"
                    + "              </DepositAmount>\n" + "              <DueAmount>\n"
                    + "                  <Money currency=\"USD\">" + totalDollarAmt + "</Money>\n"
                    + "              </DueAmount>\n" + "          </InvoiceDetailSummary>\n"
                    + "      </InvoiceDetailRequest>\n" + "  </Request>\n" + "</cXML>";

            ServletOutputStream sos;
            sos = response.getOutputStream();
            ByteArrayOutputStream baOutStream = new ByteArrayOutputStream();
            StringBufferInputStream inStream = new StringBufferInputStream(eInvoiceFile);
            convert(baOutStream, inStream);
            response.setContentLength(baOutStream.size());
            baOutStream.writeTo(sos);
            sos.flush();
        }

        return mapping.findForward(KFSConstants.MAPPING_BASIC);
    }

    private String getPaymentTermXML(PurchaseOrderDocument po) {
        String returnXML = "";

        PaymentTermType paymentTerm = null;
        if (po.getVendorDetail() != null) {
            paymentTerm = po.getVendorDetail().getVendorPaymentTerms();
        }

        if (paymentTerm != null) {
            if (paymentTerm.getVendorNetDueNumber() != null) {
                returnXML = "              <InvoiceDetailPaymentTerm payInNumberOfDays=\""
                        + paymentTerm.getVendorNetDueNumber().toString() + "\" percentageRate=\"0\" />\n";
            } else if (paymentTerm.getVendorPaymentTermsPercent() != null) {
                returnXML = "              <InvoiceDetailPaymentTerm payInNumberOfDays=\"0\" percentageRate=\""
                        + paymentTerm.getVendorPaymentTermsPercent() + "\" />\n";
            }

        }

        return returnXML;
    }

    private String getPOItemXMLChunk(PurchaseOrderItem item) {

        String itemUnitPrice = item.getItemUnitPrice() == null ? StringUtils.EMPTY
                : item.getItemUnitPrice().toString();

        String subTotal = StringUtils.EMPTY;
        if (item.getItemUnitPrice() != null && item.getItemQuantity() != null) {
            subTotal = (item.getItemUnitPrice().multiply(item.getItemQuantity().bigDecimalValue())).toString();
        }

        return

        "              <InvoiceDetailItem invoiceLineNumber=\"" + item.getItemLineNumber() + "\"\n"
                + "                  quantity=\"" + item.getItemQuantity() + "\">\n"
                + "                  <UnitOfMeasure>" + item.getItemUnitOfMeasureCode() + "</UnitOfMeasure>\n"
                + "                  <UnitPrice>\n" + "                      <Money currency=\"USD\">"
                + itemUnitPrice + "</Money>\n" + "                  </UnitPrice>\n"
                + "                  <InvoiceDetailItemReference lineNumber=\"" + item.getItemLineNumber() + "\">\n"
                + "                      <ItemID>\n" + "                          <SupplierPartID>"
                + StringUtils.defaultString(item.getItemCatalogNumber()) + "</SupplierPartID>\n"
                + "                      </ItemID>\n" + "                      <Description xml:lang=\"en\">"
                + StringUtils.defaultString(item.getItemDescription()) + "</Description>\n"
                + "                  </InvoiceDetailItemReference>\n" + "                  <SubtotalAmount>\n"
                + "                      <Money currency=\"USD\" >" + subTotal + "</Money>\n"
                + "                  </SubtotalAmount>\n" + "              </InvoiceDetailItem>\n";

    }

    private String getDeliveryAddressXMLChunk(String addressType, PurchaseOrderDocument po) {

        String deliveryDate = "";
        if (po.getDeliveryRequiredDate() != null) {
            deliveryDate = ElectronicInvoiceUtils.getDateDisplayText(po.getDeliveryRequiredDate());
        }

        String returnXML = "";

        if (StringUtils.isNotEmpty(deliveryDate)) {
            returnXML += "              <InvoiceDetailShipping shippingDate=\"" + deliveryDate
                    + "\"> <!--Delivery reqd date -->\n";
        } else {
            returnXML += "              <InvoiceDetailShipping> <!-- shipTo address same as billTo-->\n";
        }
        returnXML += getContactXMLChunk("shipTo", po) + "              </InvoiceDetailShipping>\n";

        return returnXML;

    }

    private String getContactXMLChunk(String addressType, PurchaseOrderDocument po) {

        String returnXML =

                "                  <Contact addressID=\"" + RandomUtils.nextInt() + "\" role=\"" + addressType
                        + "\"> <!-- addressId=Random Unique Id -->\n"
                        + "                      <Name xml:lang=\"en\">" + po.getDeliveryCampusCode() + " - "
                        + po.getDeliveryBuildingName() + "</Name> <!-- Format:CampusCode - Bldg Nm -->\n"
                        + "                      <PostalAddress>\n" + "                          <Street>"
                        + StringUtils.defaultString(po.getDeliveryBuildingLine1Address()) + "</Street>\n"
                        + "                          <Street>"
                        + StringUtils.defaultString(po.getDeliveryBuildingLine2Address()) + "</Street>\n"
                        + "                          <City>" + StringUtils.defaultString(po.getDeliveryCityName())
                        + "</City>\n" + "                          <State>"
                        + StringUtils.defaultString(po.getDeliveryStateCode()) + "</State>\n"
                        + "                          <PostalCode>"
                        + StringUtils.defaultString(po.getDeliveryPostalCode()) + "</PostalCode>\n"
                        + "                          <Country isoCountryCode=\""
                        + StringUtils.defaultString(po.getDeliveryCountryCode()) + "\">\n"
                        + "                              " + StringUtils.defaultString(po.getDeliveryCountryName())
                        + "\n" + "                          </Country>\n"
                        + "                      </PostalAddress>\n";

        if (StringUtils.isNotEmpty(po.getDeliveryToEmailAddress())) {
            returnXML += "                      <Email name=\"" + po.getDeliveryToEmailAddress() + "\">"
                    + po.getDeliveryToEmailAddress() + "</Email>\n";
        }

        if (StringUtils.isNotEmpty(po.getDeliveryToPhoneNumber())) {
            returnXML += "                      <Phone name=\"" + po.getDeliveryToPhoneNumber() + "\">\n"
                    + "                          <TelephoneNumber>\n"
                    + "                              <CountryCode isoCountryCode=\"US\">1</CountryCode>\n"
                    + "                              <AreaOrCityCode>"
                    + getPhoneNumber(AREA_C0DE, po.getDeliveryToPhoneNumber()) + "</AreaOrCityCode>\n"
                    + "                              <Number>"
                    + getPhoneNumber(PHONE_NUMBER, po.getDeliveryToPhoneNumber()) + "</Number>\n"
                    + "                          </TelephoneNumber>\n" + "                      </Phone>\n";
        }

        returnXML += "                  </Contact>\n";
        return returnXML;
    }

    private String getPhoneNumber(String whichPart, String phNo) {

        if (StringUtils.isEmpty(phNo)) {
            return StringUtils.EMPTY;
        }

        if (StringUtils.equals(whichPart, AREA_C0DE)) {
            return phNo.substring(0, 3);
        } else if (StringUtils.equals(whichPart, PHONE_NUMBER)) {
            return phNo.substring(3, phNo.length());
        }

        return StringUtils.EMPTY;
    }

    private boolean convert(java.io.OutputStream out, java.io.InputStream in) {
        try {
            int r;
            while ((r = in.read()) != -1) {
                out.write(r);
            }
            return true;
        } catch (java.io.IOException ioe) {
            return false;
        }
    }

    /**
     * @return the default implementation of the KRAD DocumentService
     */
    protected DocumentService getDocumentService() {
        if (documentService == null) {
            documentService = KRADServiceLocatorWeb.getDocumentService();
        }
        return documentService;
    }
}