Java tutorial
/* ************************************************************************* * The contents of this file are subject to the Openbravo Public License * Version 1.0 (the "License"), being the Mozilla Public License * Version 1.1 with a permitted attribution clause; you may not use this * file except in compliance with the License. You may obtain a copy of * the License at http://www.openbravo.com/legal/license.html * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * The Original Code is Openbravo ERP. * The Initial Developer of the Original Code is Openbravo SLU * All portions are Copyright (C) 2010-2014 Openbravo SLU * All Rights Reserved. * Contributor(s): ______________________________________. ************************************************************************* */ package org.openbravo.advpaymentmngt.ad_actionbutton; import java.io.IOException; import java.io.PrintWriter; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.hibernate.criterion.Restrictions; import org.openbravo.advpaymentmngt.dao.AdvPaymentMngtDao; import org.openbravo.advpaymentmngt.process.FIN_AddPayment; import org.openbravo.advpaymentmngt.utility.FIN_Utility; import org.openbravo.base.filter.IsIDFilter; import org.openbravo.base.filter.RequestFilter; import org.openbravo.base.filter.ValueListFilter; import org.openbravo.base.secureApp.HttpSecureAppServlet; import org.openbravo.base.secureApp.VariablesSecureApp; import org.openbravo.dal.core.DalUtil; import org.openbravo.dal.core.OBContext; import org.openbravo.dal.service.OBCriteria; import org.openbravo.dal.service.OBDal; import org.openbravo.data.FieldProvider; import org.openbravo.erpCommon.ad_forms.AcctServer; import org.openbravo.erpCommon.utility.ComboTableData; import org.openbravo.erpCommon.utility.DateTimeData; import org.openbravo.erpCommon.utility.DimensionDisplayUtility; import org.openbravo.erpCommon.utility.FieldProviderFactory; import org.openbravo.erpCommon.utility.OBError; import org.openbravo.erpCommon.utility.Utility; import org.openbravo.model.common.businesspartner.BusinessPartner; import org.openbravo.model.common.currency.Currency; import org.openbravo.model.common.enterprise.Organization; import org.openbravo.model.common.plm.Product; import org.openbravo.model.financialmgmt.accounting.Costcenter; import org.openbravo.model.financialmgmt.accounting.UserDimension1; import org.openbravo.model.financialmgmt.accounting.UserDimension2; import org.openbravo.model.financialmgmt.gl.GLItem; import org.openbravo.model.financialmgmt.payment.FIN_FinancialAccount; import org.openbravo.model.financialmgmt.payment.FIN_Payment; import org.openbravo.model.financialmgmt.payment.FIN_PaymentDetail; import org.openbravo.model.financialmgmt.payment.FIN_PaymentScheduleDetail; import org.openbravo.model.marketing.Campaign; import org.openbravo.model.materialmgmt.cost.ABCActivity; import org.openbravo.model.project.Project; import org.openbravo.xmlEngine.XmlDocument; public class AddOrderOrInvoice extends HttpSecureAppServlet { private static final long serialVersionUID = 1L; private AdvPaymentMngtDao dao; private static final RequestFilter filterYesNo = new ValueListFilter("Y", "N", ""); public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { VariablesSecureApp vars = new VariablesSecureApp(request); dao = new AdvPaymentMngtDao(); if (vars.commandIn("DEFAULT")) { String strWindowId = vars.getGlobalVariable("inpwindowId", "AddOrderOrInvoice|Window_ID"); String strTabId = vars.getGlobalVariable("inpTabId", "AddOrderOrInvoice|Tab_ID"); String strPaymentId = vars.getGlobalVariable("inpfinPaymentId", strWindowId + "|" + "FIN_Payment_ID"); String strFinancialAccountId = vars.getStringParameter("inpfinFinancialAccountId"); printPage(response, vars, strPaymentId, strWindowId, strTabId, strFinancialAccountId); } else if (vars.commandIn("GRIDLIST")) { String strBusinessPartnerId = vars.getRequestGlobalVariable("inpBusinessPartnerId", ""); if ("".equals(strBusinessPartnerId)) { strBusinessPartnerId = vars.getRequestGlobalVariable("inpcBPartnerId", ""); } String strOrgId = vars.getRequestGlobalVariable("inpadOrgId", ""); String strPaymentId = vars.getRequestGlobalVariable("inpfinPaymentId", ""); String strExpectedDateFrom = vars.getStringParameter("inpExpectedDateFrom", ""); String strExpectedDateTo = vars.getStringParameter("inpExpectedDateTo", ""); String strDocumentType = vars.getStringParameter("inpDocumentType", ""); String strSelectedPaymentDetails = vars.getInStringParameter("inpScheduledPaymentDetailId", "", null); boolean isReceipt = vars.getRequiredStringParameter("isReceipt").equals("Y"); Boolean showAlternativePM = "Y" .equals(vars.getStringParameter("inpAlternativePaymentMethod", filterYesNo)); printGrid(response, vars, strBusinessPartnerId, strPaymentId, strOrgId, strExpectedDateFrom, strExpectedDateTo, strDocumentType, strSelectedPaymentDetails, isReceipt, showAlternativePM); } else if (vars.commandIn("BPARTNERBLOCK")) { boolean isReceipt = vars.getRequiredStringParameter("isReceipt").equals("Y"); String strBusinessPartnerId = vars.getRequestGlobalVariable("inpBusinessPartnerId", ""); if ("".equals(strBusinessPartnerId)) { strBusinessPartnerId = vars.getRequestGlobalVariable("inpcBPartnerId", ""); } if (!"".equals(strBusinessPartnerId)) { BusinessPartner businessPartner = OBDal.getInstance().get(BusinessPartner.class, strBusinessPartnerId); if (FIN_Utility.isBlockedBusinessPartner(businessPartner.getId(), isReceipt, 4)) { businessPartnerBlocked(response, vars, businessPartner.getIdentifier()); } } else { String strSelectedScheduledPaymentDetailIds = vars .getInStringParameter("inpScheduledPaymentDetailId", "", null); if (!"".equals(strSelectedScheduledPaymentDetailIds)) { OBContext.setAdminMode(true); try { List<FIN_PaymentScheduleDetail> selectedPaymentDetails = FIN_Utility.getOBObjectList( FIN_PaymentScheduleDetail.class, strSelectedScheduledPaymentDetailIds); for (FIN_PaymentScheduleDetail psd : selectedPaymentDetails) { BusinessPartner bPartner; if (psd.getInvoicePaymentSchedule() == null) { bPartner = psd.getOrderPaymentSchedule().getOrder().getBusinessPartner(); } else { bPartner = psd.getInvoicePaymentSchedule().getInvoice().getBusinessPartner(); } if (FIN_Utility.isBlockedBusinessPartner(bPartner.getId(), isReceipt, 4)) { businessPartnerBlocked(response, vars, bPartner.getIdentifier()); } } } finally { OBContext.restorePreviousMode(); } } } } else if (vars.commandIn("SAVE") || vars.commandIn("SAVEANDPROCESS")) { boolean isReceipt = vars.getRequiredStringParameter("isReceipt").equals("Y"); String strAction = null; if (vars.commandIn("SAVEANDPROCESS")) { // The default option is process strAction = (isReceipt ? "PRP" : "PPP"); } else { strAction = vars.getRequiredStringParameter("inpActionDocument"); } String strPaymentId = vars.getRequiredStringParameter("inpfinPaymentId"); String strSelectedScheduledPaymentDetailIds = vars.getInStringParameter("inpScheduledPaymentDetailId", "", null); String strAddedGLItems = vars.getStringParameter("inpGLItems"); JSONArray addedGLITemsArray = null; try { addedGLITemsArray = new JSONArray(strAddedGLItems); } catch (JSONException e) { log4j.error("Error parsing received GLItems JSON Array: " + strAddedGLItems, e); bdErrorGeneralPopUp(request, response, "Error", "Error parsing received GLItems JSON Array: " + strAddedGLItems); return; } String strDifferenceAction = ""; BigDecimal refundAmount = BigDecimal.ZERO; String strDifference = vars.getNumericParameter("inpDifference", "0"); if (!"0".equals(strDifference)) { refundAmount = new BigDecimal(vars.getRequiredNumericParameter("inpDifference")); strDifferenceAction = vars.getStringParameter("inpDifferenceAction", ""); } String strTabId = vars.getRequiredStringParameter("inpTabId"); String strPaymentAmount = vars.getRequiredNumericParameter("inpActualPayment"); String paymentCurrencyId = vars.getRequiredStringParameter("inpCurrencyId"); BigDecimal exchangeRate = new BigDecimal(vars.getRequiredNumericParameter("inpExchangeRate", "1")); BigDecimal convertedAmount = new BigDecimal( vars.getRequiredNumericParameter("inpActualConverted", strPaymentAmount)); OBError message = null; // FIXME: added to access the FIN_PaymentSchedule and FIN_PaymentScheduleDetail tables to be // removed when new security implementation is done OBContext.setAdminMode(); try { List<FIN_PaymentScheduleDetail> selectedPaymentDetails = FIN_Utility .getOBObjectList(FIN_PaymentScheduleDetail.class, strSelectedScheduledPaymentDetailIds); HashMap<String, BigDecimal> selectedPaymentDetailAmounts = getSelectedPaymentDetailsAndAmount(vars, strSelectedScheduledPaymentDetailIds); FIN_Payment payment = dao.getObject(FIN_Payment.class, strPaymentId); // Remove edited lines which are not in final selection and adjust outstanding amount for // documents removeNonSelectedDetails(payment, selectedPaymentDetails); BigDecimal newPaymentAmount = new BigDecimal(strPaymentAmount); if (newPaymentAmount.compareTo(payment.getAmount()) != 0) { payment.setAmount(newPaymentAmount); OBDal.getInstance().save(payment); } // load object in memory payment.getFINPaymentDetailList(); if (addedGLITemsArray != null) { for (int i = 0; i < addedGLITemsArray.length(); i++) { JSONObject glItem = addedGLITemsArray.getJSONObject(i); BigDecimal glItemOutAmt = new BigDecimal(glItem.getString("glitemPaidOutAmt")); BigDecimal glItemInAmt = new BigDecimal(glItem.getString("glitemReceivedInAmt")); BigDecimal glItemAmt = BigDecimal.ZERO; if (isReceipt) { glItemAmt = glItemInAmt.subtract(glItemOutAmt); } else { glItemAmt = glItemOutAmt.subtract(glItemInAmt); } final String strGLItemId = glItem.getString("glitemId"); checkID(strGLItemId); // Accounting Dimensions final String strElement_BP = glItem.getString("cBpartnerDim"); checkID(strElement_BP); final BusinessPartner businessPartner = dao.getObject(BusinessPartner.class, strElement_BP); final String strElement_PR = glItem.getString("mProductDim"); checkID(strElement_PR); final Product product = dao.getObject(Product.class, strElement_PR); final String strElement_PJ = glItem.getString("cProjectDim"); checkID(strElement_PJ); final Project project = dao.getObject(Project.class, strElement_PJ); final String strElement_AY = glItem.getString("cActivityDim"); checkID(strElement_AY); final ABCActivity activity = dao.getObject(ABCActivity.class, strElement_AY); final String strElement_CC = glItem.getString("cCostcenterDim"); checkID(strElement_CC); final Costcenter costCenter = dao.getObject(Costcenter.class, strElement_CC); final String strElement_MC = glItem.getString("cCampaignDim"); checkID(strElement_MC); final Campaign campaign = dao.getObject(Campaign.class, strElement_MC); final String strElement_U1 = glItem.getString("user1Dim"); checkID(strElement_U1); final UserDimension1 user1 = dao.getObject(UserDimension1.class, strElement_U1); final String strElement_U2 = glItem.getString("user2Dim"); checkID(strElement_U2); final UserDimension2 user2 = dao.getObject(UserDimension2.class, strElement_U2); FIN_AddPayment.saveGLItem(payment, glItemAmt, dao.getObject(GLItem.class, strGLItemId), businessPartner, product, project, campaign, activity, null, costCenter, user1, user2); } } FIN_AddPayment.setFinancialTransactionAmountAndRate(vars, payment, exchangeRate, convertedAmount); payment = FIN_AddPayment.savePayment(payment, isReceipt, null, null, null, null, null, strPaymentAmount, null, null, null, selectedPaymentDetails, selectedPaymentDetailAmounts, strDifferenceAction.equals("writeoff"), strDifferenceAction.equals("refund"), dao.getObject(Currency.class, paymentCurrencyId), exchangeRate, convertedAmount); if (strAction.equals("PRP") || strAction.equals("PPP") || strAction.equals("PRD") || strAction.equals("PPW")) { try { // Process just in case there are lines, empty Refund payment does not need to call // process if (payment.getFINPaymentDetailList().size() > 0) { // If Action PRP o PPW, Process payment but as well create a financial transaction message = FIN_AddPayment.processPayment(vars, this, (strAction.equals("PRP") || strAction.equals("PPP")) ? "P" : "D", payment); } if (strDifferenceAction.equals("refund") && (message == null || !"Error".equalsIgnoreCase(message.getType()))) { Boolean newPayment = !payment.getFINPaymentDetailList().isEmpty(); FIN_Payment refundPayment = FIN_AddPayment.createRefundPayment(this, vars, payment, refundAmount.negate(), exchangeRate); OBError auxMessage = FIN_AddPayment.processPayment(vars, this, (strAction.equals("PRP") || strAction.equals("PPP")) ? "P" : "D", refundPayment); if (newPayment) { final String strNewRefundPaymentMessage = Utility.parseTranslation(this, vars, vars.getLanguage(), "@APRM_RefundPayment@" + ": " + refundPayment.getDocumentNo()) + "."; message.setMessage(strNewRefundPaymentMessage + " " + message.getMessage()); if (payment.getGeneratedCredit().compareTo(BigDecimal.ZERO) != 0) { payment.setDescription( payment.getDescription() + strNewRefundPaymentMessage + "\n"); OBDal.getInstance().save(payment); OBDal.getInstance().flush(); } } else { message = auxMessage; } } } catch (Exception ex) { message = Utility.translateError(this, vars, vars.getLanguage(), ex.getMessage()); log4j.error(ex); if (!message.isConnectionAvailable()) { bdErrorConnection(response); return; } } } } catch (Exception ex) { String strMessage = FIN_Utility.getExceptionMessage(ex); if (message != null && "Error".equals(message.getType())) { strMessage = message.getMessage(); } bdErrorGeneralPopUp(request, response, "Error", strMessage); OBDal.getInstance().rollbackAndClose(); log4j.error("AddOrderOrInvoice - SAVE AND PROCESS", ex); return; } finally { OBContext.restorePreviousMode(); } vars.setMessage(strTabId, message); printPageClosePopUpAndRefreshParent(response, vars); } } /* * Removes lines and schedule details which are not included in the given selected list */ private void removeNonSelectedDetails(FIN_Payment payment, List<FIN_PaymentScheduleDetail> selectedPaymentDetails) { Set<String> toRemovePDs = new HashSet<String>(); for (FIN_PaymentDetail pd : payment.getFINPaymentDetailList()) { for (FIN_PaymentScheduleDetail psd : pd.getFINPaymentScheduleDetailList()) { if (!selectedPaymentDetails.contains(psd)) { if (pd.getGLItem() != null) { toRemovePDs.add(pd.getId()); continue; } // update outstanding amount List<FIN_PaymentScheduleDetail> outStandingPSDs = FIN_AddPayment.getOutstandingPSDs(psd); if (outStandingPSDs.size() == 0) { FIN_PaymentScheduleDetail newOutstanding = (FIN_PaymentScheduleDetail) DalUtil.copy(psd, false); newOutstanding.setPaymentDetails(null); newOutstanding.setWriteoffAmount(BigDecimal.ZERO); OBDal.getInstance().save(newOutstanding); toRemovePDs.add(pd.getId()); } else { // First make sure outstanding amount is not equal zero if (outStandingPSDs.get(0).getAmount().add(psd.getAmount()).signum() == 0) { OBDal.getInstance().remove(outStandingPSDs.get(0)); } else { // update existing PD with difference outStandingPSDs.get(0) .setAmount(outStandingPSDs.get(0).getAmount().add(psd.getAmount())); outStandingPSDs.get(0).setDoubtfulDebtAmount(outStandingPSDs.get(0) .getDoubtfulDebtAmount().add(psd.getDoubtfulDebtAmount())); OBDal.getInstance().save(outStandingPSDs.get(0)); } toRemovePDs.add(pd.getId()); } } } } for (String pdID : toRemovePDs) { FIN_PaymentDetail pd = OBDal.getInstance().get(FIN_PaymentDetail.class, pdID); boolean hasPSD = pd.getFINPaymentScheduleDetailList().size() > 0; if (hasPSD) { FIN_PaymentScheduleDetail psd = OBDal.getInstance().get(FIN_PaymentScheduleDetail.class, pd.getFINPaymentScheduleDetailList().get(0).getId()); pd.getFINPaymentScheduleDetailList().remove(psd); OBDal.getInstance().save(pd); OBDal.getInstance().remove(psd); } payment.getFINPaymentDetailList().remove(pd); OBDal.getInstance().save(payment); OBDal.getInstance().remove(pd); OBDal.getInstance().flush(); OBDal.getInstance().refresh(payment); } } private void checkID(final String id) throws ServletException { if (!IsIDFilter.instance.accept(id)) { log4j.error("Input: " + id + " not accepted by filter: IsIDFilter"); throw new ServletException("Input: " + id + " is not an accepted input"); } } private void printPage(HttpServletResponse response, VariablesSecureApp vars, String strPaymentId, String strWindowId, String strTabId, String strFinancialAccountId) throws IOException, ServletException { log4j.debug("Output: Add Payment button pressed on Make / Receipt Payment windows"); OBContext.setAdminMode(true); try { FIN_Payment payment = new AdvPaymentMngtDao().getObject(FIN_Payment.class, strPaymentId); if (payment.getPaymentDate() == null) { OBError message = new OBError(); message.setType("Error"); message.setTitle(Utility.messageBD(this, "Error", vars.getLanguage())); message.setMessage(Utility.messageBD(this, "APRM_PaymentDateMandatory", vars.getLanguage())); vars.setMessage(strTabId, message); printPageClosePopUpAndRefreshParent(response, vars); } else { String[] discard = { "discard" }; if (payment.getBusinessPartner() != null) { discard[0] = "bpGridColumn"; } XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/advpaymentmngt/ad_actionbutton/AddOrderOrInvoice", discard) .createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); if (payment.isReceipt()) xmlDocument.setParameter("title", Utility.messageBD(this, "APRM_AddPaymentIn", vars.getLanguage())); else xmlDocument.setParameter("title", Utility.messageBD(this, "APRM_AddPaymentOut", vars.getLanguage())); xmlDocument.setParameter("dateDisplayFormat", vars.getSessionValue("#AD_SqlDateFormat")); if (payment.getBusinessPartner() != null) { xmlDocument.setParameter("businessPartner", payment.getBusinessPartner().getIdentifier()); xmlDocument.setParameter("businessPartnerId", payment.getBusinessPartner().getId()); xmlDocument.setParameter("credit", dao.getCustomerCredit(payment.getBusinessPartner(), payment.isReceipt(), payment.getOrganization()).toString()); xmlDocument.setParameter("customerBalance", payment.getBusinessPartner().getCreditUsed() != null ? payment.getBusinessPartner().getCreditUsed().toString() : BigDecimal.ZERO.toString()); } else { xmlDocument.setParameter("businessPartner", ""); xmlDocument.setParameter("businessPartnerId", ""); xmlDocument.setParameter("credit", ""); xmlDocument.setParameter("customerBalance", ""); } xmlDocument.setParameter("windowId", strWindowId); xmlDocument.setParameter("tabId", strTabId); xmlDocument.setParameter("orgId", payment.getOrganization().getId()); xmlDocument.setParameter("paymentId", strPaymentId); xmlDocument.setParameter("actualPayment", payment.getAmount().toString()); xmlDocument.setParameter("headerAmount", payment.getAmount().toString()); xmlDocument.setParameter("isReceipt", (payment.isReceipt() ? "Y" : "N")); xmlDocument.setParameter("isSoTrx", (payment.isReceipt()) ? "Y" : "N"); if (payment.getBusinessPartner() == null && (payment.getGeneratedCredit() == null || BigDecimal.ZERO.compareTo(payment.getGeneratedCredit()) != 0)) { payment.setGeneratedCredit(BigDecimal.ZERO); OBDal.getInstance().save(payment); OBDal.getInstance().flush(); } xmlDocument.setParameter("generatedCredit", payment.getGeneratedCredit() != null ? payment.getGeneratedCredit().toString() : BigDecimal.ZERO.toString()); final Currency financialAccountCurrency = payment.getAccount().getCurrency(); if (financialAccountCurrency != null) { xmlDocument.setParameter("financialAccountCurrencyId", financialAccountCurrency.getId()); xmlDocument.setParameter("financialAccountCurrencyName", financialAccountCurrency.getISOCode()); xmlDocument.setParameter("financialAccountCurrencyPrecision", financialAccountCurrency.getStandardPrecision().toString()); } xmlDocument.setParameter("exchangeRate", payment.getFinancialTransactionConvertRate() == null ? "" : payment.getFinancialTransactionConvertRate().toPlainString()); xmlDocument.setParameter("actualConverted", payment.getFinancialTransactionAmount() == null ? "" : payment.getFinancialTransactionAmount().toString()); xmlDocument.setParameter("expectedConverted", payment.getFinancialTransactionAmount() == null ? "" : payment.getFinancialTransactionAmount().toPlainString()); xmlDocument.setParameter("currencyId", payment.getCurrency().getId()); xmlDocument.setParameter("currencyName", payment.getCurrency().getISOCode()); boolean forcedFinancialAccountTransaction = false; forcedFinancialAccountTransaction = FIN_AddPayment.isForcedFinancialAccountTransaction(payment); // Action Regarding Document xmlDocument.setParameter("ActionDocument", (payment.isReceipt() ? "PRP" : "PPP")); try { ComboTableData comboTableData = new ComboTableData(vars, this, "LIST", "", (payment.isReceipt() ? "F903F726B41A49D3860243101CEEBA25" : "F15C13A199A748F1B0B00E985A64C036"), forcedFinancialAccountTransaction ? "29010995FD39439D97A5C0CE8CE27D70" : "", Utility.getContext(this, vars, "#AccessibleOrgTree", "AddPaymentFromInvoice"), Utility.getContext(this, vars, "#User_Client", "AddPaymentFromInvoice"), 0); Utility.fillSQLParameters(this, vars, null, comboTableData, "AddOrderOrInvoice", ""); xmlDocument.setData("reportActionDocument", "liststructure", comboTableData.select(false)); comboTableData = null; } catch (Exception ex) { throw new ServletException(ex); } // Accounting Dimensions String doctype; if (payment.isReceipt()) { doctype = AcctServer.DOCTYPE_ARReceipt; } else { doctype = AcctServer.DOCTYPE_APPayment; } final String strCentrally = Utility.getContext(this, vars, DimensionDisplayUtility.IsAcctDimCentrally, strWindowId); final String strElement_BP = Utility.getContext(this, vars, DimensionDisplayUtility.displayAcctDimensions(strCentrally, DimensionDisplayUtility.DIM_BPartner, doctype, DimensionDisplayUtility.DIM_Header), strWindowId); final String strElement_PR = Utility.getContext(this, vars, DimensionDisplayUtility.displayAcctDimensions(strCentrally, DimensionDisplayUtility.DIM_Product, doctype, DimensionDisplayUtility.DIM_Header), strWindowId); final String strElement_PJ = Utility.getContext(this, vars, DimensionDisplayUtility.displayAcctDimensions(strCentrally, DimensionDisplayUtility.DIM_Project, doctype, DimensionDisplayUtility.DIM_Header), strWindowId); final String strElement_AY = Utility.getContext(this, vars, "$Element_AY", strWindowId); final String strElement_CC = Utility.getContext(this, vars, DimensionDisplayUtility.displayAcctDimensions(strCentrally, DimensionDisplayUtility.DIM_CostCenter, doctype, DimensionDisplayUtility.DIM_Header), strWindowId); final String strElement_MC = Utility.getContext(this, vars, "$Element_MC", strWindowId); final String strElement_U1 = Utility.getContext(this, vars, DimensionDisplayUtility.displayAcctDimensions(strCentrally, DimensionDisplayUtility.DIM_User1, doctype, DimensionDisplayUtility.DIM_Header), strWindowId); final String strElement_U2 = Utility.getContext(this, vars, DimensionDisplayUtility.displayAcctDimensions(strCentrally, DimensionDisplayUtility.DIM_User2, doctype, DimensionDisplayUtility.DIM_Header), strWindowId); xmlDocument.setParameter("strElement_BP", strElement_BP); xmlDocument.setParameter("strElement_PR", strElement_PR); xmlDocument.setParameter("strElement_PJ", strElement_PJ); xmlDocument.setParameter("strElement_AY", strElement_AY); xmlDocument.setParameter("strElement_CC", strElement_CC); xmlDocument.setParameter("strElement_MC", strElement_MC); xmlDocument.setParameter("strElement_U1", strElement_U1); xmlDocument.setParameter("strElement_U2", strElement_U2); // Add GL Items JSONArray addedGLITemsArray = new JSONArray(); List<FIN_PaymentScheduleDetail> gLItemScheduleDetailLines = FIN_AddPayment .getGLItemScheduleDetails(payment); for (FIN_PaymentScheduleDetail psdGLItem : gLItemScheduleDetailLines) { try { JSONObject glItem = new JSONObject(); glItem.put("glitemId", psdGLItem.getPaymentDetails().getGLItem().getId()); glItem.put("glitemDesc", psdGLItem.getPaymentDetails().getGLItem().getIdentifier()); glItem.put("finPaymentScheduleDetailId", psdGLItem.getId()); // Amounts if (payment.isReceipt()) { glItem.put("glitemPaidOutAmt", psdGLItem.getAmount().signum() < 0 ? psdGLItem.getAmount().abs() : BigDecimal.ZERO); glItem.put("glitemReceivedInAmt", psdGLItem.getAmount().signum() > 0 ? psdGLItem.getAmount() : BigDecimal.ZERO); } else { glItem.put("glitemReceivedInAmt", psdGLItem.getAmount().signum() < 0 ? psdGLItem.getAmount().abs() : BigDecimal.ZERO); glItem.put("glitemPaidOutAmt", psdGLItem.getAmount().signum() > 0 ? psdGLItem.getAmount() : BigDecimal.ZERO); } // Accounting Dimensions glItem.put("cBpartnerDim", psdGLItem.getBusinessPartner() != null ? psdGLItem.getBusinessPartner().getId() : ""); glItem.put("cBpartnerDimDesc", psdGLItem.getBusinessPartner() != null ? psdGLItem.getBusinessPartner().getIdentifier() : ""); glItem.put("mProductDim", psdGLItem.getProduct() != null ? psdGLItem.getProduct().getId() : ""); glItem.put("mProductDimDesc", psdGLItem.getProduct() != null ? psdGLItem.getProduct().getIdentifier() : ""); glItem.put("cProjectDim", psdGLItem.getProject() != null ? psdGLItem.getProject().getId() : ""); glItem.put("cProjectDimDesc", psdGLItem.getProject() != null ? psdGLItem.getProject().getIdentifier() : ""); glItem.put("cActivityDim", psdGLItem.getActivity() != null ? psdGLItem.getActivity().getId() : ""); glItem.put("cActivityDimDesc", psdGLItem.getActivity() != null ? psdGLItem.getActivity().getIdentifier() : ""); glItem.put("cCostcenterDim", psdGLItem.getCostCenter() != null ? psdGLItem.getCostCenter().getId() : ""); glItem.put("cCostcenterDimDesc", psdGLItem.getCostCenter() != null ? psdGLItem.getCostCenter().getIdentifier() : ""); glItem.put("cCampaignDim", psdGLItem.getSalesCampaign() != null ? psdGLItem.getSalesCampaign().getId() : ""); glItem.put("cCampaignDimDesc", psdGLItem.getSalesCampaign() != null ? psdGLItem.getSalesCampaign().getIdentifier() : ""); glItem.put("user1Dim", psdGLItem.getStDimension() != null ? psdGLItem.getStDimension().getId() : ""); glItem.put("user1DimDesc", psdGLItem.getStDimension() != null ? psdGLItem.getStDimension().getIdentifier() : ""); glItem.put("user2Dim", psdGLItem.getNdDimension() != null ? psdGLItem.getNdDimension().getId() : ""); glItem.put("user2DimDesc", psdGLItem.getNdDimension() != null ? psdGLItem.getNdDimension().getIdentifier() : ""); // DisplayLogics glItem.put("cBpartnerDimDisplayed", strElement_BP); glItem.put("mProductDimDisplayed", strElement_PR); glItem.put("cProjectDimDisplayed", strElement_PJ); glItem.put("cActivityDimDisplayed", strElement_AY); glItem.put("cCostcenterDimDisplayed", strElement_CC); glItem.put("cCampaignDimDisplayed", strElement_MC); glItem.put("user1DimDisplayed", strElement_U1); glItem.put("user2DimDisplayed", strElement_U2); addedGLITemsArray.put(glItem); } catch (JSONException e) { log4j.error(e); } } xmlDocument.setParameter("glItems", addedGLITemsArray.toString().replace("'", "").replaceAll("\"", "'")); // If UsedCredit is not equal zero, check Use available credit xmlDocument.setParameter("useCredit", payment.getUsedCredit().signum() != 0 ? "Y" : "N"); // Not allow to change exchange rate and amount final String strNotAllowExchange = Utility.getContext(this, vars, "NotAllowChangeExchange", strWindowId); xmlDocument.setParameter("strNotAllowExchange", strNotAllowExchange); dao = new AdvPaymentMngtDao(); FIN_FinancialAccount financialAccount = dao.getObject(FIN_FinancialAccount.class, strFinancialAccountId); if (financialAccount.getWriteofflimit() != null) { final String strtypewriteoff; final String strAmountwriteoff; strtypewriteoff = financialAccount.getTypewriteoff(); strAmountwriteoff = financialAccount.getWriteofflimit().toString(); xmlDocument.setParameter("strtypewriteoff", strtypewriteoff); xmlDocument.setParameter("strAmountwriteoff", strAmountwriteoff); // Not allow to write off final String strWriteOffLimit = Utility.getContext(this, vars, "WriteOffLimitPreference", strWindowId); xmlDocument.setParameter("strWriteOffLimit", strWriteOffLimit); } response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); } } finally { OBContext.restorePreviousMode(); } } private void printGrid(HttpServletResponse response, VariablesSecureApp vars, String strBusinessPartnerId, String strPaymentId, String strOrgId, String strExpectedDateFrom, String strExpectedDateTo, String strDocumentType, String strSelectedPaymentDetails, boolean isReceipt, boolean showAlternativePM) throws IOException, ServletException { log4j.debug("Output: Grid with pending payments"); dao = new AdvPaymentMngtDao(); String[] discard = { "" }; if (!"".equals(vars.getRequestGlobalVariable("inpBusinessPartnerId", ""))) { discard[0] = "businessPartnerName"; } XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/advpaymentmngt/ad_actionbutton/AddPaymentGrid", discard) .createXmlDocument(); FIN_Payment payment = dao.getObject(FIN_Payment.class, strPaymentId); List<FIN_PaymentScheduleDetail> storedScheduledPaymentDetails = new ArrayList<FIN_PaymentScheduleDetail>(); // This is to identify first load of the grid String strFirstLoad = vars.getStringParameter("isFirstLoad"); if (payment.getFINPaymentDetailList().size() > 0) { // Add payment schedule details related to orders or invoices to storedSchedulePaymentDetails OBContext.setAdminMode(); try { OBCriteria<FIN_PaymentScheduleDetail> obc = OBDal.getInstance() .createCriteria(FIN_PaymentScheduleDetail.class); obc.add(Restrictions.in(FIN_PaymentScheduleDetail.PROPERTY_PAYMENTDETAILS, payment.getFINPaymentDetailList())); obc.add(Restrictions.or( Restrictions.isNotNull(FIN_PaymentScheduleDetail.PROPERTY_INVOICEPAYMENTSCHEDULE), Restrictions.isNotNull(FIN_PaymentScheduleDetail.PROPERTY_ORDERPAYMENTSCHEDULE))); storedScheduledPaymentDetails = obc.list(); } finally { OBContext.restorePreviousMode(); } } // Pending Payments from invoice final List<FIN_PaymentScheduleDetail> selectedScheduledPaymentDetails = FIN_AddPayment .getSelectedPaymentDetails("true".equals(strFirstLoad) ? new ArrayList<FIN_PaymentScheduleDetail>(storedScheduledPaymentDetails) : null, strSelectedPaymentDetails); // filtered scheduled payments list final List<FIN_PaymentScheduleDetail> filteredScheduledPaymentDetails = dao .getFilteredScheduledPaymentDetails(dao.getObject(Organization.class, strOrgId), dao.getObject(BusinessPartner.class, strBusinessPartnerId), payment.getCurrency(), null, null, FIN_Utility.getDate(strExpectedDateFrom), FIN_Utility.getDate(DateTimeData.nDaysAfter(this, strExpectedDateTo, "1")), null, null, strDocumentType, "", showAlternativePM ? null : payment.getPaymentMethod(), selectedScheduledPaymentDetails, isReceipt); // Remove related outstanding schedule details related to those ones being edited as amount will // be later added to storedScheduledPaymentDetails for (FIN_PaymentScheduleDetail psd : storedScheduledPaymentDetails) { filteredScheduledPaymentDetails.removeAll(FIN_AddPayment.getOutstandingPSDs(psd)); } // Get stored not selected PSDs List<FIN_PaymentScheduleDetail> storedNotSelectedPSDs = new ArrayList<FIN_PaymentScheduleDetail>( storedScheduledPaymentDetails); storedNotSelectedPSDs.removeAll(selectedScheduledPaymentDetails); // Add stored but not selected details which maps documenttype filteredScheduledPaymentDetails.addAll(filterDocumenttype(storedNotSelectedPSDs, strDocumentType)); FieldProvider[] data = FIN_AddPayment.getShownScheduledPaymentDetails(vars, selectedScheduledPaymentDetails, filteredScheduledPaymentDetails, false, null, strSelectedPaymentDetails); for (FIN_PaymentScheduleDetail psd : storedScheduledPaymentDetails) { // Calculate pending amount BigDecimal outstandingAmount = BigDecimal.ZERO; List<FIN_PaymentScheduleDetail> outStandingPSDs = FIN_AddPayment.getOutstandingPSDs(psd); if (outStandingPSDs.size() != 0) { for (FIN_PaymentScheduleDetail outPSD : outStandingPSDs) { outstandingAmount = outstandingAmount.add(outPSD.getAmount()); } } for (int i = 0; i < data.length; i++) { if (data[i].getField("finScheduledPaymentDetailId").equals(psd.getId())) { FieldProviderFactory.setField(data[i], "outstandingAmount", psd.getAmount().add(outstandingAmount).toPlainString()); if ("true".equals(strFirstLoad)) { FieldProviderFactory.setField(data[i], "difference", outstandingAmount.toPlainString()); FieldProviderFactory.setField(data[i], "paymentAmount", psd.getAmount().toPlainString()); } } } } data = groupPerDocumentType(data, strDocumentType); xmlDocument.setData("structure", (data == null) ? set() : data); response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); } private FieldProvider[] set() throws ServletException { HashMap<String, String> empty = new HashMap<String, String>(); empty.put("finScheduledPaymentId", ""); empty.put("salesOrderNr", ""); empty.put("salesInvoiceNr", ""); empty.put("expectedDate", ""); empty.put("invoicedAmount", ""); empty.put("expectedAmount", ""); empty.put("paymentAmount", ""); ArrayList<HashMap<String, String>> result = new ArrayList<HashMap<String, String>>(); result.add(empty); return FieldProviderFactory.getFieldProviderArray(result); } private FieldProvider[] groupPerDocumentType(FieldProvider[] data, String strDocumenType) { ArrayList<FieldProvider> gridLines = new ArrayList<FieldProvider>(); HashMap<String, Integer> amountsPerGroupingField = new HashMap<String, Integer>(); String groupingField = "finScheduledPaymentDetailId"; if ("I".equals(strDocumenType)) { groupingField = "invoicePaymentScheduleId"; } else if ("O".equals(strDocumenType)) { groupingField = "orderPaymentScheduleId"; } for (int i = 0; i < data.length; i++) { if (!amountsPerGroupingField.containsKey(data[i].getField(groupingField)) || "".equals(data[i].getField(groupingField))) { amountsPerGroupingField.put(data[i].getField(groupingField), gridLines.size()); FieldProviderFactory.setField(data[i], "rownum", String.valueOf(gridLines.size())); gridLines.add(data[i]); } else { Integer listIndex = amountsPerGroupingField.get(data[i].getField(groupingField)); FieldProvider row = gridLines.get(listIndex); FieldProviderFactory.setField(row, "finScheduledPaymentDetailId", row.getField("finScheduledPaymentDetailId") + "," + data[i].getField("finScheduledPaymentDetailId")); FieldProviderFactory.setField(row, "finSelectedPaymentDetailId", row.getField("finSelectedPaymentDetailId") + "," + data[i].getField("finScheduledPaymentDetailId")); FieldProviderFactory.setField(row, "outstandingAmount", new BigDecimal(row.getField("outstandingAmount")) .add(new BigDecimal(data[i].getField("outstandingAmount"))).toString()); BigDecimal payAmount = BigDecimal.ZERO; if (!"".equals(row.getField("paymentAmount"))) { payAmount = new BigDecimal(row.getField("paymentAmount")); } FieldProviderFactory.setField(row, "paymentAmount", !"".equals(data[i].getField("paymentAmount")) ? payAmount.add(new BigDecimal(data[i].getField("paymentAmount"))).toString() : (payAmount.compareTo(BigDecimal.ZERO) == 0 ? "" : payAmount.toString())); if ("O".equals(strDocumenType)) { String strGroupedInvoicesNr = row.getField("invoiceNr"); FieldProviderFactory.setField(row, "invoiceNr", (strGroupedInvoicesNr.isEmpty() ? "" : strGroupedInvoicesNr + ", ") + data[i].getField("invoiceNr")); String invoiceNumber = row.getField("invoiceNr"); String invoiceNumberTrunc = (invoiceNumber.length() > 17) ? invoiceNumber.substring(0, 14).concat("...").toString() : invoiceNumber; FieldProviderFactory.setField(row, "invoiceNrTrunc", invoiceNumberTrunc); } else if ("I".equals(strDocumenType)) { String strGroupedOrdersNr = row.getField("orderNr"); FieldProviderFactory.setField(row, "orderNr", (strGroupedOrdersNr.isEmpty() ? "" : strGroupedOrdersNr + ", ") + data[i].getField("orderNr")); String orderNumber = row.getField("orderNr"); String orderNumberTrunc = (orderNumber.length() > 17) ? orderNumber.substring(0, 14).concat("...").toString() : orderNumber; FieldProviderFactory.setField(row, "orderNrTrunc", orderNumberTrunc); } } } FieldProvider[] result = new FieldProvider[gridLines.size()]; gridLines.toArray(result); return result; } /** * Creates a HashMap with the FIN_PaymentScheduleDetail id's and the amount gotten from the * Session. * * The amounts are stored in Session like "inpPaymentAmount"+paymentScheduleDetail.Id * * @param vars * VariablseSecureApp with the session data. * @param _strSelectedScheduledPaymentDetailIds * List of id's of FIN_PaymentScheduleDetails that need to be included in the HashMap. * @return A HashMap mapping the FIN_PaymentScheduleDetail's Id with the corresponding amount. */ private HashMap<String, BigDecimal> getSelectedPaymentDetailsAndAmount(VariablesSecureApp vars, String _strSelectedScheduledPaymentDetailIds) throws ServletException { String strSelectedScheduledPaymentDetailIds = _strSelectedScheduledPaymentDetailIds; // Remove "(" ")" strSelectedScheduledPaymentDetailIds = strSelectedScheduledPaymentDetailIds.replace("(", ""); strSelectedScheduledPaymentDetailIds = strSelectedScheduledPaymentDetailIds.replace(")", ""); HashMap<String, BigDecimal> selectedPaymentScheduleDetailsAmounts = new HashMap<String, BigDecimal>(); // As selected items may contain records with multiple IDs we as well need the records list as // amounts are related to records StringTokenizer records = new StringTokenizer(strSelectedScheduledPaymentDetailIds, "'"); Set<String> recordSet = new LinkedHashSet<String>(); while (records.hasMoreTokens()) { recordSet.add(records.nextToken()); } for (String record : recordSet) { if (", ".equals(record)) { continue; } Set<String> psdSet = new LinkedHashSet<String>(); StringTokenizer psds = new StringTokenizer(record, ","); while (psds.hasMoreTokens()) { psdSet.add(psds.nextToken()); } BigDecimal recordAmount = new BigDecimal(vars.getNumericParameter("inpPaymentAmount" + record, "")); HashMap<String, BigDecimal> recordsAmounts = calculateAmounts(recordAmount, psdSet); selectedPaymentScheduleDetailsAmounts.putAll(recordsAmounts); } return selectedPaymentScheduleDetailsAmounts; } /** * This method returns a HashMap with pairs of UUID of payment schedule details and amounts * related to those ones. * * @param recordAmount * : amount to split among the set * @param psdSet * : set of payment schedule details where to allocate the amount */ private HashMap<String, BigDecimal> calculateAmounts(BigDecimal recordAmount, Set<String> psdSet) { BigDecimal remainingAmount = recordAmount; HashMap<String, BigDecimal> recordsAmounts = new HashMap<String, BigDecimal>(); // PSD needs to be properly ordered to ensure negative amounts are processed first List<FIN_PaymentScheduleDetail> psds = getOrderedPaymentScheduleDetails(psdSet); BigDecimal outstandingAmount = BigDecimal.ZERO; for (FIN_PaymentScheduleDetail paymentScheduleDetail : psds) { if (paymentScheduleDetail.getPaymentDetails() != null) { // This schedule detail comes from an edited payment so outstanding amount needs to be // properly calculated List<FIN_PaymentScheduleDetail> outStandingPSDs = FIN_AddPayment .getOutstandingPSDs(paymentScheduleDetail); if (outStandingPSDs.size() > 0) { outstandingAmount = paymentScheduleDetail.getAmount().add(outStandingPSDs.get(0).getAmount()); } else { outstandingAmount = paymentScheduleDetail.getAmount(); } } else { outstandingAmount = paymentScheduleDetail.getAmount(); } // Manage negative amounts if ((remainingAmount.compareTo(BigDecimal.ZERO) > 0 && remainingAmount.compareTo(outstandingAmount) >= 0) || ((remainingAmount.compareTo(BigDecimal.ZERO) == -1 && outstandingAmount.compareTo(BigDecimal.ZERO) == -1) && (remainingAmount.compareTo(outstandingAmount) <= 0))) { recordsAmounts.put(paymentScheduleDetail.getId(), outstandingAmount); remainingAmount = remainingAmount.subtract(outstandingAmount); } else { recordsAmounts.put(paymentScheduleDetail.getId(), remainingAmount); remainingAmount = BigDecimal.ZERO; } } return recordsAmounts; } private List<FIN_PaymentScheduleDetail> getOrderedPaymentScheduleDetails(Set<String> psdSet) { OBCriteria<FIN_PaymentScheduleDetail> orderedPSDs = OBDal.getInstance() .createCriteria(FIN_PaymentScheduleDetail.class); orderedPSDs.add(Restrictions.in(FIN_PaymentScheduleDetail.PROPERTY_ID, psdSet)); orderedPSDs.addOrderBy(FIN_PaymentScheduleDetail.PROPERTY_AMOUNT, true); return orderedPSDs.list(); } private List<FIN_PaymentScheduleDetail> filterDocumenttype( List<FIN_PaymentScheduleDetail> storedNotSelectedPSDs, String strDocumentType) { List<FIN_PaymentScheduleDetail> listIterator = new ArrayList<FIN_PaymentScheduleDetail>( storedNotSelectedPSDs); for (FIN_PaymentScheduleDetail paymentScheduleDetail : listIterator) { if (paymentScheduleDetail.getInvoicePaymentSchedule() != null && "O".equals(strDocumentType)) { storedNotSelectedPSDs.remove(paymentScheduleDetail); } else if (paymentScheduleDetail.getOrderPaymentSchedule() != null && "I".equals(strDocumentType)) { storedNotSelectedPSDs.remove(paymentScheduleDetail); } } return storedNotSelectedPSDs; } private void businessPartnerBlocked(HttpServletResponse response, VariablesSecureApp vars, String strBPartnerName) throws IOException, ServletException { try { JSONObject json = new JSONObject(); json.put("text", "SelectedBPartnerBlocked"); response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("objson = " + json); out.close(); } catch (JSONException e) { log4j.error("AddOrderOrInvoice - Callback", e); } } public String getServletInfo() { return "Servlet that presents the payment proposal"; // end of getServletInfo() method } }