diff --git a/base/src/org/compiere/model/CalloutOrder.java b/base/src/org/compiere/model/CalloutOrder.java index 622a8bccee..f8a41717ad 100644 --- a/base/src/org/compiere/model/CalloutOrder.java +++ b/base/src/org/compiere/model/CalloutOrder.java @@ -3,135 +3,135 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.math.*; -import java.sql.*; -import java.util.*; -import java.util.logging.*; -import org.compiere.util.*; - -/** - * Order Callouts. - * - * @author Jorg Janke - * @version $Id: CalloutOrder.java,v 1.5 2006/10/08 06:57:33 comdivision Exp $ - */ -public class CalloutOrder extends CalloutEngine -{ - /** Debug Steps */ - private boolean steps = false; - - /** - * Order Header Change - DocType. - * - InvoiceRuld/DeliveryRule/PaymentRule - * - temporary Document - * Context: - * - DocSubTypeSO - * - HasCharges - * - (re-sets Business Partner info of required) - * - * @param ctx Context - * @param WindowNo current Window No - * @param mTab Model Tab - * @param mField Model Field - * @param value The new value - * @return Error message or "" - */ - public String docType (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) - { - Integer C_DocType_ID = (Integer)value; // Actually C_DocTypeTarget_ID - if (C_DocType_ID == null || C_DocType_ID.intValue() == 0) - return ""; - - // Re-Create new DocNo, if there is a doc number already - // and the existing source used a different Sequence number - String oldDocNo = (String)mTab.getValue("DocumentNo"); - boolean newDocNo = (oldDocNo == null); - if (!newDocNo && oldDocNo.startsWith("<") && oldDocNo.endsWith(">")) - newDocNo = true; - Integer oldC_DocType_ID = (Integer)mTab.getValue("C_DocType_ID"); - - String sql = "SELECT d.DocSubTypeSO,d.HasCharges,'N'," // 1..3 - + "d.IsDocNoControlled,s.CurrentNext,s.CurrentNextSys," // 4..6 - + "s.AD_Sequence_ID,d.IsSOTrx " // 7..8 - + "FROM C_DocType d, AD_Sequence s " - + "WHERE C_DocType_ID=?" // #1 - + " AND d.DocNoSequence_ID=s.AD_Sequence_ID(+)"; - try - { - int AD_Sequence_ID = 0; - - // Get old AD_SeqNo for comparison - if (!newDocNo && oldC_DocType_ID.intValue() != 0) - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, oldC_DocType_ID.intValue()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - AD_Sequence_ID = rs.getInt(6); - rs.close(); - pstmt.close(); - } - - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, C_DocType_ID.intValue()); - ResultSet rs = pstmt.executeQuery(); - String DocSubTypeSO = ""; - boolean IsSOTrx = true; - if (rs.next()) // we found document type - { - // Set Context: Document Sub Type for Sales Orders - DocSubTypeSO = rs.getString(1); - if (DocSubTypeSO == null) - DocSubTypeSO = "--"; - Env.setContext(ctx, WindowNo, "OrderType", DocSubTypeSO); - // No Drop Ship other than Standard - if (!DocSubTypeSO.equals(MOrder.DocSubTypeSO_Standard)) - mTab.setValue ("IsDropShip", "N"); + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.math.*; +import java.sql.*; +import java.util.*; +import java.util.logging.*; +import org.compiere.util.*; + +/** + * Order Callouts. + * + * @author Jorg Janke + * @version $Id: CalloutOrder.java,v 1.5 2006/10/08 06:57:33 comdivision Exp $ + */ +public class CalloutOrder extends CalloutEngine +{ + /** Debug Steps */ + private boolean steps = false; + + /** + * Order Header Change - DocType. + * - InvoiceRuld/DeliveryRule/PaymentRule + * - temporary Document + * Context: + * - DocSubTypeSO + * - HasCharges + * - (re-sets Business Partner info of required) + * + * @param ctx Context + * @param WindowNo current Window No + * @param mTab Model Tab + * @param mField Model Field + * @param value The new value + * @return Error message or "" + */ + public String docType (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) + { + Integer C_DocType_ID = (Integer)value; // Actually C_DocTypeTarget_ID + if (C_DocType_ID == null || C_DocType_ID.intValue() == 0) + return ""; + + // Re-Create new DocNo, if there is a doc number already + // and the existing source used a different Sequence number + String oldDocNo = (String)mTab.getValue("DocumentNo"); + boolean newDocNo = (oldDocNo == null); + if (!newDocNo && oldDocNo.startsWith("<") && oldDocNo.endsWith(">")) + newDocNo = true; + Integer oldC_DocType_ID = (Integer)mTab.getValue("C_DocType_ID"); + + String sql = "SELECT d.DocSubTypeSO,d.HasCharges,'N'," // 1..3 + + "d.IsDocNoControlled,s.CurrentNext,s.CurrentNextSys," // 4..6 + + "s.AD_Sequence_ID,d.IsSOTrx " // 7..8 + + "FROM C_DocType d, AD_Sequence s " + + "WHERE C_DocType_ID=?" // #1 + + " AND d.DocNoSequence_ID=s.AD_Sequence_ID(+)"; + try + { + int AD_Sequence_ID = 0; + + // Get old AD_SeqNo for comparison + if (!newDocNo && oldC_DocType_ID.intValue() != 0) + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, oldC_DocType_ID.intValue()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + AD_Sequence_ID = rs.getInt(6); + rs.close(); + pstmt.close(); + } + + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, C_DocType_ID.intValue()); + ResultSet rs = pstmt.executeQuery(); + String DocSubTypeSO = ""; + boolean IsSOTrx = true; + if (rs.next()) // we found document type + { + // Set Context: Document Sub Type for Sales Orders + DocSubTypeSO = rs.getString(1); + if (DocSubTypeSO == null) + DocSubTypeSO = "--"; + Env.setContext(ctx, WindowNo, "OrderType", DocSubTypeSO); + // No Drop Ship other than Standard + if (!DocSubTypeSO.equals(MOrder.DocSubTypeSO_Standard)) + mTab.setValue ("IsDropShip", "N"); // Delivery Rule if (DocSubTypeSO.equals(MOrder.DocSubTypeSO_POS)) - mTab.setValue ("DeliveryRule", MOrder.DELIVERYRULE_Force); + mTab.setValue ("DeliveryRule", X_C_Order.DELIVERYRULE_Force); else if (DocSubTypeSO.equals(MOrder.DocSubTypeSO_Prepay)) - mTab.setValue ("DeliveryRule", MOrder.DELIVERYRULE_AfterReceipt); + mTab.setValue ("DeliveryRule", X_C_Order.DELIVERYRULE_AfterReceipt); else - mTab.setValue ("DeliveryRule", MOrder.DELIVERYRULE_Availability); + mTab.setValue ("DeliveryRule", X_C_Order.DELIVERYRULE_Availability); // Invoice Rule if (DocSubTypeSO.equals(MOrder.DocSubTypeSO_POS) || DocSubTypeSO.equals(MOrder.DocSubTypeSO_Prepay) || DocSubTypeSO.equals(MOrder.DocSubTypeSO_OnCredit) ) - mTab.setValue ("InvoiceRule", MOrder.INVOICERULE_Immediate); + mTab.setValue ("InvoiceRule", X_C_Order.INVOICERULE_Immediate); else - mTab.setValue ("InvoiceRule", MOrder.INVOICERULE_AfterDelivery); + mTab.setValue ("InvoiceRule", X_C_Order.INVOICERULE_AfterDelivery); // Payment Rule - POS Order if (DocSubTypeSO.equals(MOrder.DocSubTypeSO_POS)) - mTab.setValue("PaymentRule", MOrder.PAYMENTRULE_Cash); + mTab.setValue("PaymentRule", X_C_Order.PAYMENTRULE_Cash); else - mTab.setValue("PaymentRule", MOrder.PAYMENTRULE_OnCredit); + mTab.setValue("PaymentRule", X_C_Order.PAYMENTRULE_OnCredit); // IsSOTrx if ("N".equals(rs.getString(8))) - IsSOTrx = false; - - // Set Context: - Env.setContext(ctx, WindowNo, "HasCharges", rs.getString(2)); - // DocumentNo - if (rs.getString(4).equals("Y")) // IsDocNoControlled - { + IsSOTrx = false; + + // Set Context: + Env.setContext(ctx, WindowNo, "HasCharges", rs.getString(2)); + // DocumentNo + if (rs.getString(4).equals("Y")) // IsDocNoControlled + { if (!newDocNo && AD_Sequence_ID != rs.getInt(7)) newDocNo = true; if (newDocNo) @@ -139,175 +139,175 @@ public class CalloutOrder extends CalloutEngine mTab.setValue("DocumentNo", "<" + rs.getString(6) + ">"); else mTab.setValue("DocumentNo", "<" + rs.getString(5) + ">"); - } - } - rs.close(); - pstmt.close(); - // When BPartner is changed, the Rules are not set if - // it is a POS or Credit Order (i.e. defaults from Standard BPartner) - // This re-reads the Rules and applies them. - if (DocSubTypeSO.equals(MOrder.DocSubTypeSO_POS) - || DocSubTypeSO.equals(MOrder.DocSubTypeSO_Prepay)) // not for POS/PrePay - ; - else - { - sql = "SELECT PaymentRule,C_PaymentTerm_ID," // 1..2 - + "InvoiceRule,DeliveryRule," // 3..4 - + "FreightCostRule,DeliveryViaRule, " // 5..6 - + "PaymentRulePO,PO_PaymentTerm_ID " - + "FROM C_BPartner " - + "WHERE C_BPartner_ID=?"; // #1 - pstmt = DB.prepareStatement(sql, null); - int C_BPartner_ID = Env.getContextAsInt(ctx, WindowNo, "C_BPartner_ID"); - pstmt.setInt(1, C_BPartner_ID); - // - rs = pstmt.executeQuery(); - if (rs.next()) - { - // PaymentRule - String s = rs.getString(IsSOTrx ? "PaymentRule" : "PaymentRulePO"); - if (s != null && s.length() != 0) - { - if (IsSOTrx && (s.equals("B") || s.equals("S") || s.equals("U"))) // No Cash/Check/Transfer for SO_Trx - s = "P"; // Payment Term - if (!IsSOTrx && (s.equals("B"))) // No Cash for PO_Trx - s = "P"; // Payment Term - mTab.setValue("PaymentRule", s); - } - // Payment Term - Integer ii =new Integer(rs.getInt(IsSOTrx ? "C_PaymentTerm_ID" : "PO_PaymentTerm_ID")); - if (!rs.wasNull()) - mTab.setValue("C_PaymentTerm_ID", ii); - // InvoiceRule - s = rs.getString(3); - if (s != null && s.length() != 0) - mTab.setValue("InvoiceRule", s); - // DeliveryRule - s = rs.getString(4); - if (s != null && s.length() != 0) - mTab.setValue("DeliveryRule", s); - // FreightCostRule - s = rs.getString(5); - if (s != null && s.length() != 0) - mTab.setValue("FreightCostRule", s); - // DeliveryViaRule - s = rs.getString(6); - if (s != null && s.length() != 0) - mTab.setValue("DeliveryViaRule", s); - } - rs.close(); - pstmt.close(); - } // re-read customer rules - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - return e.getLocalizedMessage(); - } - - return ""; - } // docType - - - /** - * Order Header - BPartner. - * - M_PriceList_ID (+ Context) - * - C_BPartner_Location_ID - * - Bill_BPartner_ID/Bill_Location_ID - * - AD_User_ID - * - POReference - * - SO_Description - * - IsDiscountPrinted - * - InvoiceRule/DeliveryRule/PaymentRule/FreightCost/DeliveryViaRule - * - C_PaymentTerm_ID - * @param ctx Context - * @param WindowNo current Window No - * @param mTab Model Tab - * @param mField Model Field - * @param value The new value - * @return Error message or "" - */ - public String bPartner (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) - { - Integer C_BPartner_ID = (Integer)value; - if (C_BPartner_ID == null || C_BPartner_ID.intValue() == 0) - return ""; - setCalloutActive(true); - - String sql = "SELECT p.AD_Language,p.C_PaymentTerm_ID," - + " COALESCE(p.M_PriceList_ID,g.M_PriceList_ID) AS M_PriceList_ID, p.PaymentRule,p.POReference," - + " p.SO_Description,p.IsDiscountPrinted," - + " p.InvoiceRule,p.DeliveryRule,p.FreightCostRule,DeliveryViaRule," - + " p.SO_CreditLimit, p.SO_CreditLimit-p.SO_CreditUsed AS CreditAvailable," - + " lship.C_BPartner_Location_ID,c.AD_User_ID," - + " COALESCE(p.PO_PriceList_ID,g.PO_PriceList_ID) AS PO_PriceList_ID, p.PaymentRulePO,p.PO_PaymentTerm_ID," - + " lbill.C_BPartner_Location_ID AS Bill_Location_ID, p.SOCreditStatus " - + "FROM C_BPartner p" - + " INNER JOIN C_BP_Group g ON (p.C_BP_Group_ID=g.C_BP_Group_ID)" - + " LEFT OUTER JOIN C_BPartner_Location lbill ON (p.C_BPartner_ID=lbill.C_BPartner_ID AND lbill.IsBillTo='Y' AND lbill.IsActive='Y')" - + " LEFT OUTER JOIN C_BPartner_Location lship ON (p.C_BPartner_ID=lship.C_BPartner_ID AND lship.IsShipTo='Y' AND lship.IsActive='Y')" - + " LEFT OUTER JOIN AD_User c ON (p.C_BPartner_ID=c.C_BPartner_ID) " - + "WHERE p.C_BPartner_ID=? AND p.IsActive='Y'"; // #1 - - boolean IsSOTrx = "Y".equals(Env.getContext(ctx, WindowNo, "IsSOTrx")); - - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, C_BPartner_ID.intValue()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - { - // PriceList (indirect: IsTaxIncluded & Currency) - Integer ii = new Integer(rs.getInt(IsSOTrx ? "M_PriceList_ID" : "PO_PriceList_ID")); - if (!rs.wasNull()) - mTab.setValue("M_PriceList_ID", ii); - else - { // get default PriceList - int i = Env.getContextAsInt(ctx, "#M_PriceList_ID"); - if (i != 0) - mTab.setValue("M_PriceList_ID", new Integer(i)); - } - - // Bill-To - mTab.setValue("Bill_BPartner_ID", C_BPartner_ID); - int bill_Location_ID = rs.getInt("Bill_Location_ID"); - if (bill_Location_ID == 0) - mTab.setValue("Bill_Location_ID", null); - else - mTab.setValue("Bill_Location_ID", new Integer(bill_Location_ID)); - // Ship-To Location - int shipTo_ID = rs.getInt("C_BPartner_Location_ID"); - // overwritten by InfoBP selection - works only if InfoWindow - // was used otherwise creates error (uses last value, may belong to differnt BP) - if (C_BPartner_ID.toString().equals(Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_ID"))) - { - String loc = Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_Location_ID"); - if (loc.length() > 0) - shipTo_ID = Integer.parseInt(loc); - } - if (shipTo_ID == 0) - mTab.setValue("C_BPartner_Location_ID", null); - else - mTab.setValue("C_BPartner_Location_ID", new Integer(shipTo_ID)); - - // Contact - overwritten by InfoBP selection - int contID = rs.getInt("AD_User_ID"); - if (C_BPartner_ID.toString().equals(Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_ID"))) - { - String cont = Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "AD_User_ID"); - if (cont.length() > 0) - contID = Integer.parseInt(cont); - } - if (contID == 0) - mTab.setValue("AD_User_ID", null); - else - { - mTab.setValue("AD_User_ID", new Integer(contID)); - mTab.setValue("Bill_User_ID", new Integer(contID)); - } - - // CreditAvailable + } + } + rs.close(); + pstmt.close(); + // When BPartner is changed, the Rules are not set if + // it is a POS or Credit Order (i.e. defaults from Standard BPartner) + // This re-reads the Rules and applies them. + if (DocSubTypeSO.equals(MOrder.DocSubTypeSO_POS) + || DocSubTypeSO.equals(MOrder.DocSubTypeSO_Prepay)) // not for POS/PrePay + ; + else + { + sql = "SELECT PaymentRule,C_PaymentTerm_ID," // 1..2 + + "InvoiceRule,DeliveryRule," // 3..4 + + "FreightCostRule,DeliveryViaRule, " // 5..6 + + "PaymentRulePO,PO_PaymentTerm_ID " + + "FROM C_BPartner " + + "WHERE C_BPartner_ID=?"; // #1 + pstmt = DB.prepareStatement(sql, null); + int C_BPartner_ID = Env.getContextAsInt(ctx, WindowNo, "C_BPartner_ID"); + pstmt.setInt(1, C_BPartner_ID); + // + rs = pstmt.executeQuery(); + if (rs.next()) + { + // PaymentRule + String s = rs.getString(IsSOTrx ? "PaymentRule" : "PaymentRulePO"); + if (s != null && s.length() != 0) + { + if (IsSOTrx && (s.equals("B") || s.equals("S") || s.equals("U"))) // No Cash/Check/Transfer for SO_Trx + s = "P"; // Payment Term + if (!IsSOTrx && (s.equals("B"))) // No Cash for PO_Trx + s = "P"; // Payment Term + mTab.setValue("PaymentRule", s); + } + // Payment Term + Integer ii =new Integer(rs.getInt(IsSOTrx ? "C_PaymentTerm_ID" : "PO_PaymentTerm_ID")); + if (!rs.wasNull()) + mTab.setValue("C_PaymentTerm_ID", ii); + // InvoiceRule + s = rs.getString(3); + if (s != null && s.length() != 0) + mTab.setValue("InvoiceRule", s); + // DeliveryRule + s = rs.getString(4); + if (s != null && s.length() != 0) + mTab.setValue("DeliveryRule", s); + // FreightCostRule + s = rs.getString(5); + if (s != null && s.length() != 0) + mTab.setValue("FreightCostRule", s); + // DeliveryViaRule + s = rs.getString(6); + if (s != null && s.length() != 0) + mTab.setValue("DeliveryViaRule", s); + } + rs.close(); + pstmt.close(); + } // re-read customer rules + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + return e.getLocalizedMessage(); + } + + return ""; + } // docType + + + /** + * Order Header - BPartner. + * - M_PriceList_ID (+ Context) + * - C_BPartner_Location_ID + * - Bill_BPartner_ID/Bill_Location_ID + * - AD_User_ID + * - POReference + * - SO_Description + * - IsDiscountPrinted + * - InvoiceRule/DeliveryRule/PaymentRule/FreightCost/DeliveryViaRule + * - C_PaymentTerm_ID + * @param ctx Context + * @param WindowNo current Window No + * @param mTab Model Tab + * @param mField Model Field + * @param value The new value + * @return Error message or "" + */ + public String bPartner (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) + { + Integer C_BPartner_ID = (Integer)value; + if (C_BPartner_ID == null || C_BPartner_ID.intValue() == 0) + return ""; + setCalloutActive(true); + + String sql = "SELECT p.AD_Language,p.C_PaymentTerm_ID," + + " COALESCE(p.M_PriceList_ID,g.M_PriceList_ID) AS M_PriceList_ID, p.PaymentRule,p.POReference," + + " p.SO_Description,p.IsDiscountPrinted," + + " p.InvoiceRule,p.DeliveryRule,p.FreightCostRule,DeliveryViaRule," + + " p.SO_CreditLimit, p.SO_CreditLimit-p.SO_CreditUsed AS CreditAvailable," + + " lship.C_BPartner_Location_ID,c.AD_User_ID," + + " COALESCE(p.PO_PriceList_ID,g.PO_PriceList_ID) AS PO_PriceList_ID, p.PaymentRulePO,p.PO_PaymentTerm_ID," + + " lbill.C_BPartner_Location_ID AS Bill_Location_ID, p.SOCreditStatus " + + "FROM C_BPartner p" + + " INNER JOIN C_BP_Group g ON (p.C_BP_Group_ID=g.C_BP_Group_ID)" + + " LEFT OUTER JOIN C_BPartner_Location lbill ON (p.C_BPartner_ID=lbill.C_BPartner_ID AND lbill.IsBillTo='Y' AND lbill.IsActive='Y')" + + " LEFT OUTER JOIN C_BPartner_Location lship ON (p.C_BPartner_ID=lship.C_BPartner_ID AND lship.IsShipTo='Y' AND lship.IsActive='Y')" + + " LEFT OUTER JOIN AD_User c ON (p.C_BPartner_ID=c.C_BPartner_ID) " + + "WHERE p.C_BPartner_ID=? AND p.IsActive='Y'"; // #1 + + boolean IsSOTrx = "Y".equals(Env.getContext(ctx, WindowNo, "IsSOTrx")); + + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, C_BPartner_ID.intValue()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + { + // PriceList (indirect: IsTaxIncluded & Currency) + Integer ii = new Integer(rs.getInt(IsSOTrx ? "M_PriceList_ID" : "PO_PriceList_ID")); + if (!rs.wasNull()) + mTab.setValue("M_PriceList_ID", ii); + else + { // get default PriceList + int i = Env.getContextAsInt(ctx, "#M_PriceList_ID"); + if (i != 0) + mTab.setValue("M_PriceList_ID", new Integer(i)); + } + + // Bill-To + mTab.setValue("Bill_BPartner_ID", C_BPartner_ID); + int bill_Location_ID = rs.getInt("Bill_Location_ID"); + if (bill_Location_ID == 0) + mTab.setValue("Bill_Location_ID", null); + else + mTab.setValue("Bill_Location_ID", new Integer(bill_Location_ID)); + // Ship-To Location + int shipTo_ID = rs.getInt("C_BPartner_Location_ID"); + // overwritten by InfoBP selection - works only if InfoWindow + // was used otherwise creates error (uses last value, may belong to differnt BP) + if (C_BPartner_ID.toString().equals(Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_ID"))) + { + String loc = Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_Location_ID"); + if (loc.length() > 0) + shipTo_ID = Integer.parseInt(loc); + } + if (shipTo_ID == 0) + mTab.setValue("C_BPartner_Location_ID", null); + else + mTab.setValue("C_BPartner_Location_ID", new Integer(shipTo_ID)); + + // Contact - overwritten by InfoBP selection + int contID = rs.getInt("AD_User_ID"); + if (C_BPartner_ID.toString().equals(Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_ID"))) + { + String cont = Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "AD_User_ID"); + if (cont.length() > 0) + contID = Integer.parseInt(cont); + } + if (contID == 0) + mTab.setValue("AD_User_ID", null); + else + { + mTab.setValue("AD_User_ID", new Integer(contID)); + mTab.setValue("Bill_User_ID", new Integer(contID)); + } + + // CreditAvailable if (IsSOTrx) { double CreditLimit = rs.getDouble("SO_CreditLimit"); @@ -315,874 +315,874 @@ public class CalloutOrder extends CalloutEngine if (CreditLimit != 0) { double CreditAvailable = rs.getDouble("CreditAvailable"); - if (!rs.wasNull() && CreditAvailable < 0) - mTab.fireDataStatusEEvent("CreditLimitOver", - DisplayType.getNumberFormat(DisplayType.Amount).format(CreditAvailable), - false); - } - } - - // PO Reference - String s = rs.getString("POReference"); - if (s != null && s.length() != 0) - mTab.setValue("POReference", s); - // should not be reset to null if we entered already value! VHARCQ, accepted YS makes sense that way - // TODO: should get checked and removed if no longer needed! - /*else - mTab.setValue("POReference", null);*/ - - // SO Description - s = rs.getString("SO_Description"); - if (s != null && s.trim().length() != 0) - mTab.setValue("Description", s); - // IsDiscountPrinted - s = rs.getString("IsDiscountPrinted"); - if (s != null && s.length() != 0) - mTab.setValue("IsDiscountPrinted", s); - else - mTab.setValue("IsDiscountPrinted", "N"); + if (!rs.wasNull() && CreditAvailable < 0) + mTab.fireDataStatusEEvent("CreditLimitOver", + DisplayType.getNumberFormat(DisplayType.Amount).format(CreditAvailable), + false); + } + } + + // PO Reference + String s = rs.getString("POReference"); + if (s != null && s.length() != 0) + mTab.setValue("POReference", s); + // should not be reset to null if we entered already value! VHARCQ, accepted YS makes sense that way + // TODO: should get checked and removed if no longer needed! + /*else + mTab.setValue("POReference", null);*/ + + // SO Description + s = rs.getString("SO_Description"); + if (s != null && s.trim().length() != 0) + mTab.setValue("Description", s); + // IsDiscountPrinted + s = rs.getString("IsDiscountPrinted"); + if (s != null && s.length() != 0) + mTab.setValue("IsDiscountPrinted", s); + else + mTab.setValue("IsDiscountPrinted", "N"); // Defaults, if not Walkin Receipt or Walkin Invoice String OrderType = Env.getContext(ctx, WindowNo, "OrderType"); - mTab.setValue("InvoiceRule", MOrder.INVOICERULE_AfterDelivery); - mTab.setValue("DeliveryRule", MOrder.DELIVERYRULE_Availability); - mTab.setValue("PaymentRule", MOrder.PAYMENTRULE_OnCredit); + mTab.setValue("InvoiceRule", X_C_Order.INVOICERULE_AfterDelivery); + mTab.setValue("DeliveryRule", X_C_Order.DELIVERYRULE_Availability); + mTab.setValue("PaymentRule", X_C_Order.PAYMENTRULE_OnCredit); if (OrderType.equals(MOrder.DocSubTypeSO_Prepay)) { - mTab.setValue("InvoiceRule", MOrder.INVOICERULE_Immediate); - mTab.setValue("DeliveryRule", MOrder.DELIVERYRULE_AfterReceipt); + mTab.setValue("InvoiceRule", X_C_Order.INVOICERULE_Immediate); + mTab.setValue("DeliveryRule", X_C_Order.DELIVERYRULE_AfterReceipt); } else if (OrderType.equals(MOrder.DocSubTypeSO_POS)) // for POS - mTab.setValue("PaymentRule", MOrder.PAYMENTRULE_Cash); + mTab.setValue("PaymentRule", X_C_Order.PAYMENTRULE_Cash); else { // PaymentRule - s = rs.getString(IsSOTrx ? "PaymentRule" : "PaymentRulePO"); - if (s != null && s.length() != 0) - { - if (s.equals("B")) // No Cache in Non POS - s = "P"; - if (IsSOTrx && (s.equals("S") || s.equals("U"))) // No Check/Transfer for SO_Trx - s = "P"; // Payment Term - mTab.setValue("PaymentRule", s); - } - // Payment Term - ii = new Integer(rs.getInt(IsSOTrx ? "C_PaymentTerm_ID" : "PO_PaymentTerm_ID")); - if (!rs.wasNull()) - mTab.setValue("C_PaymentTerm_ID", ii); - // InvoiceRule - s = rs.getString("InvoiceRule"); - if (s != null && s.length() != 0) - mTab.setValue("InvoiceRule", s); - // DeliveryRule - s = rs.getString("DeliveryRule"); - if (s != null && s.length() != 0) - mTab.setValue("DeliveryRule", s); - // FreightCostRule - s = rs.getString("FreightCostRule"); - if (s != null && s.length() != 0) - mTab.setValue("FreightCostRule", s); - // DeliveryViaRule - s = rs.getString("DeliveryViaRule"); - if (s != null && s.length() != 0) - mTab.setValue("DeliveryViaRule", s); - } - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - setCalloutActive(false); - return e.getLocalizedMessage(); - } - setCalloutActive(false); - return ""; - } // bPartner - - /** - * Order Header - Invoice BPartner. - * - M_PriceList_ID (+ Context) - * - Bill_Location_ID - * - Bill_User_ID - * - POReference - * - SO_Description - * - IsDiscountPrinted - * - InvoiceRule/PaymentRule - * - C_PaymentTerm_ID - * @param ctx Context - * @param WindowNo current Window No - * @param mTab Model Tab - * @param mField Model Field - * @param value The new value - * @return Error message or "" - */ - public String bPartnerBill (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) - { - if (isCalloutActive()) - return ""; - Integer bill_BPartner_ID = (Integer)value; - if (bill_BPartner_ID == null || bill_BPartner_ID.intValue() == 0) - return ""; - - String sql = "SELECT p.AD_Language,p.C_PaymentTerm_ID," - + "p.M_PriceList_ID,p.PaymentRule,p.POReference," - + "p.SO_Description,p.IsDiscountPrinted," - + "p.InvoiceRule,p.DeliveryRule,p.FreightCostRule,DeliveryViaRule," - + "p.SO_CreditLimit, p.SO_CreditLimit-p.SO_CreditUsed AS CreditAvailable," - + "c.AD_User_ID," - + "p.PO_PriceList_ID, p.PaymentRulePO, p.PO_PaymentTerm_ID," - + "lbill.C_BPartner_Location_ID AS Bill_Location_ID " - + "FROM C_BPartner p" - + " LEFT OUTER JOIN C_BPartner_Location lbill ON (p.C_BPartner_ID=lbill.C_BPartner_ID AND lbill.IsBillTo='Y' AND lbill.IsActive='Y')" - + " LEFT OUTER JOIN AD_User c ON (p.C_BPartner_ID=c.C_BPartner_ID) " - + "WHERE p.C_BPartner_ID=? AND p.IsActive='Y'"; // #1 - - boolean IsSOTrx = "Y".equals(Env.getContext(ctx, WindowNo, "IsSOTrx")); - - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, bill_BPartner_ID.intValue()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - { - // PriceList (indirect: IsTaxIncluded & Currency) - Integer ii = new Integer(rs.getInt(IsSOTrx ? "M_PriceList_ID" : "PO_PriceList_ID")); - if (!rs.wasNull()) - mTab.setValue("M_PriceList_ID", ii); - else - { // get default PriceList - int i = Env.getContextAsInt(ctx, "#M_PriceList_ID"); - if (i != 0) - mTab.setValue("M_PriceList_ID", new Integer(i)); - } - - int bill_Location_ID = rs.getInt("Bill_Location_ID"); - // overwritten by InfoBP selection - works only if InfoWindow - // was used otherwise creates error (uses last value, may belong to differnt BP) - if (bill_BPartner_ID.toString().equals(Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_ID"))) - { - String loc = Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_Location_ID"); - if (loc.length() > 0) - bill_Location_ID = Integer.parseInt(loc); - } - if (bill_Location_ID == 0) - mTab.setValue("Bill_Location_ID", null); - else - mTab.setValue("Bill_Location_ID", new Integer(bill_Location_ID)); - - // Contact - overwritten by InfoBP selection - int contID = rs.getInt("AD_User_ID"); - if (bill_BPartner_ID.toString().equals(Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_ID"))) - { - String cont = Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "AD_User_ID"); - if (cont.length() > 0) - contID = Integer.parseInt(cont); - } - if (contID == 0) - mTab.setValue("Bill_User_ID", null); - else - mTab.setValue("Bill_User_ID", new Integer(contID)); - - // CreditAvailable - if (IsSOTrx) - { - double CreditLimit = rs.getDouble("SO_CreditLimit"); - if (CreditLimit != 0) - { - double CreditAvailable = rs.getDouble("CreditAvailable"); - if (!rs.wasNull() && CreditAvailable < 0) - mTab.fireDataStatusEEvent("CreditLimitOver", - DisplayType.getNumberFormat(DisplayType.Amount).format(CreditAvailable), - false); - } - } - - // PO Reference - String s = rs.getString("POReference"); - if (s != null && s.length() != 0) - mTab.setValue("POReference", s); - else - mTab.setValue("POReference", null); - // SO Description - s = rs.getString("SO_Description"); - if (s != null && s.trim().length() != 0) - mTab.setValue("Description", s); - // IsDiscountPrinted - s = rs.getString("IsDiscountPrinted"); - if (s != null && s.length() != 0) - mTab.setValue("IsDiscountPrinted", s); - else - mTab.setValue("IsDiscountPrinted", "N"); + s = rs.getString(IsSOTrx ? "PaymentRule" : "PaymentRulePO"); + if (s != null && s.length() != 0) + { + if (s.equals("B")) // No Cache in Non POS + s = "P"; + if (IsSOTrx && (s.equals("S") || s.equals("U"))) // No Check/Transfer for SO_Trx + s = "P"; // Payment Term + mTab.setValue("PaymentRule", s); + } + // Payment Term + ii = new Integer(rs.getInt(IsSOTrx ? "C_PaymentTerm_ID" : "PO_PaymentTerm_ID")); + if (!rs.wasNull()) + mTab.setValue("C_PaymentTerm_ID", ii); + // InvoiceRule + s = rs.getString("InvoiceRule"); + if (s != null && s.length() != 0) + mTab.setValue("InvoiceRule", s); + // DeliveryRule + s = rs.getString("DeliveryRule"); + if (s != null && s.length() != 0) + mTab.setValue("DeliveryRule", s); + // FreightCostRule + s = rs.getString("FreightCostRule"); + if (s != null && s.length() != 0) + mTab.setValue("FreightCostRule", s); + // DeliveryViaRule + s = rs.getString("DeliveryViaRule"); + if (s != null && s.length() != 0) + mTab.setValue("DeliveryViaRule", s); + } + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + setCalloutActive(false); + return e.getLocalizedMessage(); + } + setCalloutActive(false); + return ""; + } // bPartner + + /** + * Order Header - Invoice BPartner. + * - M_PriceList_ID (+ Context) + * - Bill_Location_ID + * - Bill_User_ID + * - POReference + * - SO_Description + * - IsDiscountPrinted + * - InvoiceRule/PaymentRule + * - C_PaymentTerm_ID + * @param ctx Context + * @param WindowNo current Window No + * @param mTab Model Tab + * @param mField Model Field + * @param value The new value + * @return Error message or "" + */ + public String bPartnerBill (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) + { + if (isCalloutActive()) + return ""; + Integer bill_BPartner_ID = (Integer)value; + if (bill_BPartner_ID == null || bill_BPartner_ID.intValue() == 0) + return ""; + + String sql = "SELECT p.AD_Language,p.C_PaymentTerm_ID," + + "p.M_PriceList_ID,p.PaymentRule,p.POReference," + + "p.SO_Description,p.IsDiscountPrinted," + + "p.InvoiceRule,p.DeliveryRule,p.FreightCostRule,DeliveryViaRule," + + "p.SO_CreditLimit, p.SO_CreditLimit-p.SO_CreditUsed AS CreditAvailable," + + "c.AD_User_ID," + + "p.PO_PriceList_ID, p.PaymentRulePO, p.PO_PaymentTerm_ID," + + "lbill.C_BPartner_Location_ID AS Bill_Location_ID " + + "FROM C_BPartner p" + + " LEFT OUTER JOIN C_BPartner_Location lbill ON (p.C_BPartner_ID=lbill.C_BPartner_ID AND lbill.IsBillTo='Y' AND lbill.IsActive='Y')" + + " LEFT OUTER JOIN AD_User c ON (p.C_BPartner_ID=c.C_BPartner_ID) " + + "WHERE p.C_BPartner_ID=? AND p.IsActive='Y'"; // #1 + + boolean IsSOTrx = "Y".equals(Env.getContext(ctx, WindowNo, "IsSOTrx")); + + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, bill_BPartner_ID.intValue()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + { + // PriceList (indirect: IsTaxIncluded & Currency) + Integer ii = new Integer(rs.getInt(IsSOTrx ? "M_PriceList_ID" : "PO_PriceList_ID")); + if (!rs.wasNull()) + mTab.setValue("M_PriceList_ID", ii); + else + { // get default PriceList + int i = Env.getContextAsInt(ctx, "#M_PriceList_ID"); + if (i != 0) + mTab.setValue("M_PriceList_ID", new Integer(i)); + } + + int bill_Location_ID = rs.getInt("Bill_Location_ID"); + // overwritten by InfoBP selection - works only if InfoWindow + // was used otherwise creates error (uses last value, may belong to differnt BP) + if (bill_BPartner_ID.toString().equals(Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_ID"))) + { + String loc = Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_Location_ID"); + if (loc.length() > 0) + bill_Location_ID = Integer.parseInt(loc); + } + if (bill_Location_ID == 0) + mTab.setValue("Bill_Location_ID", null); + else + mTab.setValue("Bill_Location_ID", new Integer(bill_Location_ID)); + + // Contact - overwritten by InfoBP selection + int contID = rs.getInt("AD_User_ID"); + if (bill_BPartner_ID.toString().equals(Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "C_BPartner_ID"))) + { + String cont = Env.getContext(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "AD_User_ID"); + if (cont.length() > 0) + contID = Integer.parseInt(cont); + } + if (contID == 0) + mTab.setValue("Bill_User_ID", null); + else + mTab.setValue("Bill_User_ID", new Integer(contID)); + + // CreditAvailable + if (IsSOTrx) + { + double CreditLimit = rs.getDouble("SO_CreditLimit"); + if (CreditLimit != 0) + { + double CreditAvailable = rs.getDouble("CreditAvailable"); + if (!rs.wasNull() && CreditAvailable < 0) + mTab.fireDataStatusEEvent("CreditLimitOver", + DisplayType.getNumberFormat(DisplayType.Amount).format(CreditAvailable), + false); + } + } + + // PO Reference + String s = rs.getString("POReference"); + if (s != null && s.length() != 0) + mTab.setValue("POReference", s); + else + mTab.setValue("POReference", null); + // SO Description + s = rs.getString("SO_Description"); + if (s != null && s.trim().length() != 0) + mTab.setValue("Description", s); + // IsDiscountPrinted + s = rs.getString("IsDiscountPrinted"); + if (s != null && s.length() != 0) + mTab.setValue("IsDiscountPrinted", s); + else + mTab.setValue("IsDiscountPrinted", "N"); // Defaults, if not Walkin Receipt or Walkin Invoice String OrderType = Env.getContext(ctx, WindowNo, "OrderType"); - mTab.setValue("InvoiceRule", MOrder.INVOICERULE_AfterDelivery); - mTab.setValue("PaymentRule", MOrder.PAYMENTRULE_OnCredit); + mTab.setValue("InvoiceRule", X_C_Order.INVOICERULE_AfterDelivery); + mTab.setValue("PaymentRule", X_C_Order.PAYMENTRULE_OnCredit); if (OrderType.equals(MOrder.DocSubTypeSO_Prepay)) - mTab.setValue("InvoiceRule", MOrder.INVOICERULE_Immediate); + mTab.setValue("InvoiceRule", X_C_Order.INVOICERULE_Immediate); else if (OrderType.equals(MOrder.DocSubTypeSO_POS)) // for POS - mTab.setValue("PaymentRule", MOrder.PAYMENTRULE_Cash); + mTab.setValue("PaymentRule", X_C_Order.PAYMENTRULE_Cash); else { // PaymentRule - s = rs.getString(IsSOTrx ? "PaymentRule" : "PaymentRulePO"); - if (s != null && s.length() != 0) - { - if (s.equals("B")) // No Cache in Non POS - s = "P"; - if (IsSOTrx && (s.equals("S") || s.equals("U"))) // No Check/Transfer for SO_Trx - s = "P"; // Payment Term - mTab.setValue("PaymentRule", s); - } - // Payment Term - ii = new Integer(rs.getInt(IsSOTrx ? "C_PaymentTerm_ID" : "PO_PaymentTerm_ID")); - if (!rs.wasNull()) - mTab.setValue("C_PaymentTerm_ID", ii); - // InvoiceRule - s = rs.getString("InvoiceRule"); - if (s != null && s.length() != 0) - mTab.setValue("InvoiceRule", s); - } - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, "bPartnerBill", e); - return e.getLocalizedMessage(); - } - - return ""; - } // bPartnerBill - - - /** - * Order Header - PriceList. - * (used also in Invoice) - * - C_Currency_ID - * - IsTaxIncluded - * Window Context: - * - EnforcePriceLimit - * - StdPrecision - * - M_PriceList_Version_ID - * @param ctx context - * @param WindowNo current Window No - * @param mTab Grid Tab - * @param mField Grid Field - * @param value New Value - * @return null or error message - */ - public String priceList (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) - { - Integer M_PriceList_ID = (Integer)value; - if (M_PriceList_ID == null || M_PriceList_ID.intValue()== 0) - return ""; - if (steps) log.warning("init"); - - String sql = "SELECT pl.IsTaxIncluded,pl.EnforcePriceLimit,pl.C_Currency_ID,c.StdPrecision," - + "plv.M_PriceList_Version_ID,plv.ValidFrom " - + "FROM M_PriceList pl,C_Currency c,M_PriceList_Version plv " - + "WHERE pl.C_Currency_ID=c.C_Currency_ID" - + " AND pl.M_PriceList_ID=plv.M_PriceList_ID" - + " AND pl.M_PriceList_ID=? " // 1 - + "ORDER BY plv.ValidFrom DESC"; - // Use newest price list - may not be future - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, M_PriceList_ID.intValue()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - { - // Tax Included - mTab.setValue("IsTaxIncluded", new Boolean("Y".equals(rs.getString(1)))); - // Price Limit Enforce - Env.setContext(ctx, WindowNo, "EnforcePriceLimit", rs.getString(2)); - // Currency - Integer ii = new Integer(rs.getInt(3)); - mTab.setValue("C_Currency_ID", ii); - // PriceList Version - Env.setContext(ctx, WindowNo, "M_PriceList_Version_ID", rs.getInt(5)); - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - return e.getLocalizedMessage(); - } - if (steps) log.warning("fini"); - - return ""; - } // priceList - - - /************************************************************************* - * Order Line - Product. - * - reset C_Charge_ID / M_AttributeSetInstance_ID - * - PriceList, PriceStd, PriceLimit, C_Currency_ID, EnforcePriceLimit - * - UOM - * Calls Tax - * - * @param ctx context - * @param WindowNo current Window No - * @param mTab Grid Tab - * @param mField Grid Field - * @param value New Value - * @return null or error message - */ - public String product (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) - { - Integer M_Product_ID = (Integer)value; - if (M_Product_ID == null || M_Product_ID.intValue() == 0) - return ""; - setCalloutActive(true); - if (steps) log.warning("init"); - // - mTab.setValue("C_Charge_ID", null); - // Set Attribute - if (Env.getContextAsInt(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "M_Product_ID") == M_Product_ID.intValue() - && Env.getContextAsInt(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "M_AttributeSetInstance_ID") != 0) - mTab.setValue("M_AttributeSetInstance_ID", new Integer(Env.getContextAsInt(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "M_AttributeSetInstance_ID"))); - else - mTab.setValue("M_AttributeSetInstance_ID", null); - - /***** Price Calculation see also qty ****/ - int C_BPartner_ID = Env.getContextAsInt(ctx, WindowNo, "C_BPartner_ID"); - BigDecimal Qty = (BigDecimal)mTab.getValue("QtyOrdered"); - boolean IsSOTrx = Env.getContext(ctx, WindowNo, "IsSOTrx").equals("Y"); - MProductPricing pp = new MProductPricing (M_Product_ID.intValue(), C_BPartner_ID, Qty, IsSOTrx); - // - int M_PriceList_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_ID"); - pp.setM_PriceList_ID(M_PriceList_ID); - /** PLV is only accurate if PL selected in header */ - int M_PriceList_Version_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_Version_ID"); - pp.setM_PriceList_Version_ID(M_PriceList_Version_ID); - Timestamp orderDate = (Timestamp)mTab.getValue("DateOrdered"); - pp.setPriceDate(orderDate); - // - mTab.setValue("PriceList", pp.getPriceList()); - mTab.setValue("PriceLimit", pp.getPriceLimit()); - mTab.setValue("PriceActual", pp.getPriceStd()); - mTab.setValue("PriceEntered", pp.getPriceStd()); - mTab.setValue("C_Currency_ID", new Integer(pp.getC_Currency_ID())); - mTab.setValue("Discount", pp.getDiscount()); - mTab.setValue("C_UOM_ID", new Integer(pp.getC_UOM_ID())); - mTab.setValue("QtyOrdered", mTab.getValue("QtyEntered")); - Env.setContext(ctx, WindowNo, "EnforcePriceLimit", pp.isEnforcePriceLimit() ? "Y" : "N"); - Env.setContext(ctx, WindowNo, "DiscountSchema", pp.isDiscountSchema() ? "Y" : "N"); - - // Check/Update Warehouse Setting - // int M_Warehouse_ID = Env.getContextAsInt(ctx, Env.WINDOW_INFO, "M_Warehouse_ID"); - // Integer wh = (Integer)mTab.getValue("M_Warehouse_ID"); - // if (wh.intValue() != M_Warehouse_ID) - // { - // mTab.setValue("M_Warehouse_ID", new Integer(M_Warehouse_ID)); - // ADialog.warn(,WindowNo, "WarehouseChanged"); - // } - - - if (Env.isSOTrx(ctx, WindowNo)) - { - MProduct product = MProduct.get (ctx, M_Product_ID.intValue()); - if (product.isStocked()) - { - BigDecimal QtyOrdered = (BigDecimal)mTab.getValue("QtyOrdered"); - int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID"); - int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID"); - BigDecimal available = MStorage.getQtyAvailable - (M_Warehouse_ID, M_Product_ID.intValue(), M_AttributeSetInstance_ID, null); - if (available == null) - available = Env.ZERO; - if (available.signum() == 0) - mTab.fireDataStatusEEvent ("NoQtyAvailable", "0", false); - else if (available.compareTo(QtyOrdered) < 0) - mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", available.toString(), false); - else - { - Integer C_OrderLine_ID = (Integer)mTab.getValue("C_OrderLine_ID"); - if (C_OrderLine_ID == null) - C_OrderLine_ID = new Integer(0); - BigDecimal notReserved = MOrderLine.getNotReserved(ctx, - M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID, - C_OrderLine_ID.intValue()); - if (notReserved == null) - notReserved = Env.ZERO; - BigDecimal total = available.subtract(notReserved); - if (total.compareTo(QtyOrdered) < 0) - { - String info = Msg.parseTranslation(ctx, "@QtyAvailable@=" + available - + " - @QtyNotReserved@=" + notReserved + " = " + total); - mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", - info, false); - } - } - } - } - // - setCalloutActive(false); - if (steps) log.warning("fini"); - return tax (ctx, WindowNo, mTab, mField, value); - } // product - - /** - * Order Line - Charge. - * - updates PriceActual from Charge - * - sets PriceLimit, PriceList to zero - * Calles tax - * @param ctx context - * @param WindowNo current Window No - * @param mTab Grid Tab - * @param mField Grid Field - * @param value New Value - * @return null or error message - */ - public String charge (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) - { - Integer C_Charge_ID = (Integer)value; - if (C_Charge_ID == null || C_Charge_ID.intValue() == 0) - return ""; - // No Product defined - if (mTab.getValue("M_Product_ID") != null) - { - mTab.setValue("C_Charge_ID", null); - return "ChargeExclusively"; - } - mTab.setValue("M_AttributeSetInstance_ID", null); - mTab.setValue("S_ResourceAssignment_ID", null); - mTab.setValue("C_UOM_ID", new Integer(100)); // EA - - Env.setContext(ctx, WindowNo, "DiscountSchema", "N"); - String sql = "SELECT ChargeAmt FROM C_Charge WHERE C_Charge_ID=?"; - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, C_Charge_ID.intValue()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - { - mTab.setValue ("PriceEntered", rs.getBigDecimal (1)); - mTab.setValue ("PriceActual", rs.getBigDecimal (1)); - mTab.setValue ("PriceLimit", Env.ZERO); - mTab.setValue ("PriceList", Env.ZERO); - mTab.setValue ("Discount", Env.ZERO); - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - return e.getLocalizedMessage(); - } - // - return tax (ctx, WindowNo, mTab, mField, value); - } // charge - - - /** - * Order Line - Tax. - * - basis: Product, Charge, BPartner Location - * - sets C_Tax_ID - * Calles Amount - * @param ctx context - * @param WindowNo current Window No - * @param mTab Grid Tab - * @param mField Grid Field - * @param value New Value - * @return null or error message - */ - public String tax (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) - { - String column = mField.getColumnName(); - if (value == null) - return ""; - if (steps) log.warning("init"); - - // Check Product - int M_Product_ID = 0; - if (column.equals("M_Product_ID")) - M_Product_ID = ((Integer)value).intValue(); - else - M_Product_ID = Env.getContextAsInt(ctx, WindowNo, "M_Product_ID"); - int C_Charge_ID = 0; - if (column.equals("C_Charge_ID")) - C_Charge_ID = ((Integer)value).intValue(); - else - C_Charge_ID = Env.getContextAsInt(ctx, WindowNo, "C_Charge_ID"); - log.fine("Product=" + M_Product_ID + ", C_Charge_ID=" + C_Charge_ID); - if (M_Product_ID == 0 && C_Charge_ID == 0) - return amt(ctx, WindowNo, mTab, mField, value); // - - // Check Partner Location - int shipC_BPartner_Location_ID = 0; - if (column.equals("C_BPartner_Location_ID")) - shipC_BPartner_Location_ID = ((Integer)value).intValue(); - else - shipC_BPartner_Location_ID = Env.getContextAsInt(ctx, WindowNo, "C_BPartner_Location_ID"); - if (shipC_BPartner_Location_ID == 0) - return amt(ctx, WindowNo, mTab, mField, value); // - log.fine("Ship BP_Location=" + shipC_BPartner_Location_ID); - - // - Timestamp billDate = Env.getContextAsDate(ctx, WindowNo, "DateOrdered"); - log.fine("Bill Date=" + billDate); - - Timestamp shipDate = Env.getContextAsDate(ctx, WindowNo, "DatePromised"); - log.fine("Ship Date=" + shipDate); - - int AD_Org_ID = Env.getContextAsInt(ctx, WindowNo, "AD_Org_ID"); - log.fine("Org=" + AD_Org_ID); - - int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID"); - log.fine("Warehouse=" + M_Warehouse_ID); - - int billC_BPartner_Location_ID = Env.getContextAsInt(ctx, WindowNo, "Bill_Location_ID"); - if (billC_BPartner_Location_ID == 0) - billC_BPartner_Location_ID = shipC_BPartner_Location_ID; - log.fine("Bill BP_Location=" + billC_BPartner_Location_ID); - - // - int C_Tax_ID = Tax.get (ctx, M_Product_ID, C_Charge_ID, billDate, shipDate, - AD_Org_ID, M_Warehouse_ID, billC_BPartner_Location_ID, shipC_BPartner_Location_ID, - "Y".equals(Env.getContext(ctx, WindowNo, "IsSOTrx"))); - log.info("Tax ID=" + C_Tax_ID); - // - if (C_Tax_ID == 0) - mTab.fireDataStatusEEvent(CLogger.retrieveError()); - else - mTab.setValue("C_Tax_ID", new Integer(C_Tax_ID)); - // - if (steps) log.warning("fini"); - return amt(ctx, WindowNo, mTab, mField, value); - } // tax - - - /** - * Order Line - Amount. - * - called from QtyOrdered, Discount and PriceActual - * - calculates Discount or Actual Amount - * - calculates LineNetAmt - * - enforces PriceLimit - * @param ctx context - * @param WindowNo current Window No - * @param mTab Grid Tab - * @param mField Grid Field - * @param value New Value - * @return null or error message - */ - public String amt (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) - { - if (isCalloutActive() || value == null) - return ""; - setCalloutActive(true); - - if (steps) log.warning("init"); - int C_UOM_To_ID = Env.getContextAsInt(ctx, WindowNo, "C_UOM_ID"); - int M_Product_ID = Env.getContextAsInt(ctx, WindowNo, "M_Product_ID"); - int M_PriceList_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_ID"); - int StdPrecision = MPriceList.getStandardPrecision(ctx, M_PriceList_ID); - BigDecimal QtyEntered, QtyOrdered, PriceEntered, PriceActual, PriceLimit, Discount, PriceList; - // get values - QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); - QtyOrdered = (BigDecimal)mTab.getValue("QtyOrdered"); - log.fine("QtyEntered=" + QtyEntered + ", Ordered=" + QtyOrdered + ", UOM=" + C_UOM_To_ID); - // - PriceEntered = (BigDecimal)mTab.getValue("PriceEntered"); - PriceActual = (BigDecimal)mTab.getValue("PriceActual"); - Discount = (BigDecimal)mTab.getValue("Discount"); - PriceLimit = (BigDecimal)mTab.getValue("PriceLimit"); - PriceList = (BigDecimal)mTab.getValue("PriceList"); - log.fine("PriceList=" + PriceList + ", Limit=" + PriceLimit + ", Precision=" + StdPrecision); - log.fine("PriceEntered=" + PriceEntered + ", Actual=" + PriceActual + ", Discount=" + Discount); - - // Qty changed - recalc price - if ((mField.getColumnName().equals("QtyOrdered") - || mField.getColumnName().equals("QtyEntered") - || mField.getColumnName().equals("M_Product_ID")) - && !"N".equals(Env.getContext(ctx, WindowNo, "DiscountSchema"))) - { - int C_BPartner_ID = Env.getContextAsInt(ctx, WindowNo, "C_BPartner_ID"); - if (mField.getColumnName().equals("QtyEntered")) - QtyOrdered = MUOMConversion.convertProductTo (ctx, M_Product_ID, - C_UOM_To_ID, QtyEntered); - if (QtyOrdered == null) - QtyOrdered = QtyEntered; - boolean IsSOTrx = Env.getContext(ctx, WindowNo, "IsSOTrx").equals("Y"); - MProductPricing pp = new MProductPricing (M_Product_ID, C_BPartner_ID, QtyOrdered, IsSOTrx); - pp.setM_PriceList_ID(M_PriceList_ID); - int M_PriceList_Version_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_Version_ID"); - pp.setM_PriceList_Version_ID(M_PriceList_Version_ID); - Timestamp date = (Timestamp)mTab.getValue("DateOrdered"); - pp.setPriceDate(date); - // - PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, - C_UOM_To_ID, pp.getPriceStd()); - if (PriceEntered == null) - PriceEntered = pp.getPriceStd(); - // - log.fine("QtyChanged -> PriceActual=" + pp.getPriceStd() - + ", PriceEntered=" + PriceEntered + ", Discount=" + pp.getDiscount()); - mTab.setValue("PriceActual", pp.getPriceStd()); - mTab.setValue("Discount", pp.getDiscount()); - mTab.setValue("PriceEntered", PriceEntered); - Env.setContext(ctx, WindowNo, "DiscountSchema", pp.isDiscountSchema() ? "Y" : "N"); - } - else if (mField.getColumnName().equals("PriceActual")) - { - PriceActual = (BigDecimal)value; - PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, - C_UOM_To_ID, PriceActual); - if (PriceEntered == null) - PriceEntered = PriceActual; - // - log.fine("PriceActual=" + PriceActual - + " -> PriceEntered=" + PriceEntered); - mTab.setValue("PriceEntered", PriceEntered); - } - else if (mField.getColumnName().equals("PriceEntered")) - { - PriceEntered = (BigDecimal)value; - PriceActual = MUOMConversion.convertProductTo (ctx, M_Product_ID, - C_UOM_To_ID, PriceEntered); - if (PriceActual == null) - PriceActual = PriceEntered; - // - log.fine("PriceEntered=" + PriceEntered - + " -> PriceActual=" + PriceActual); - mTab.setValue("PriceActual", PriceActual); - } - - // Discount entered - Calculate Actual/Entered - if (mField.getColumnName().equals("Discount")) - { - PriceActual = new BigDecimal ((100.0 - Discount.doubleValue()) / 100.0 * PriceList.doubleValue()); - if (PriceActual.scale() > StdPrecision) - PriceActual = PriceActual.setScale(StdPrecision, BigDecimal.ROUND_HALF_UP); - PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, - C_UOM_To_ID, PriceActual); - if (PriceEntered == null) - PriceEntered = PriceActual; - mTab.setValue("PriceActual", PriceActual); - mTab.setValue("PriceEntered", PriceEntered); - } - // calculate Discount - else - { - if (PriceList.intValue() == 0) - Discount = Env.ZERO; - else - Discount = new BigDecimal ((PriceList.doubleValue() - PriceActual.doubleValue()) / PriceList.doubleValue() * 100.0); - if (Discount.scale() > 2) - Discount = Discount.setScale(2, BigDecimal.ROUND_HALF_UP); - mTab.setValue("Discount", Discount); - } - log.fine("PriceEntered=" + PriceEntered + ", Actual=" + PriceActual + ", Discount=" + Discount); - - // Check PriceLimit - String epl = Env.getContext(ctx, WindowNo, "EnforcePriceLimit"); - boolean enforce = Env.isSOTrx(ctx, WindowNo) && epl != null && epl.equals("Y"); - if (enforce && MRole.getDefault().isOverwritePriceLimit()) - enforce = false; - // Check Price Limit? - if (enforce && PriceLimit.doubleValue() != 0.0 - && PriceActual.compareTo(PriceLimit) < 0) - { - PriceActual = PriceLimit; - PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, - C_UOM_To_ID, PriceLimit); - if (PriceEntered == null) - PriceEntered = PriceLimit; - log.fine("(under) PriceEntered=" + PriceEntered + ", Actual" + PriceLimit); - mTab.setValue ("PriceActual", PriceLimit); - mTab.setValue ("PriceEntered", PriceEntered); - mTab.fireDataStatusEEvent ("UnderLimitPrice", "", false); - // Repeat Discount calc - if (PriceList.intValue() != 0) - { - Discount = new BigDecimal ((PriceList.doubleValue () - PriceActual.doubleValue ()) / PriceList.doubleValue () * 100.0); - if (Discount.scale () > 2) - Discount = Discount.setScale (2, BigDecimal.ROUND_HALF_UP); - mTab.setValue ("Discount", Discount); - } - } - - // Line Net Amt - BigDecimal LineNetAmt = QtyOrdered.multiply(PriceActual); - if (LineNetAmt.scale() > StdPrecision) - LineNetAmt = LineNetAmt.setScale(StdPrecision, BigDecimal.ROUND_HALF_UP); - log.info("LineNetAmt=" + LineNetAmt); - mTab.setValue("LineNetAmt", LineNetAmt); - // - setCalloutActive(false); - return ""; - } // amt - - /** - * Order Line - Quantity. - * - called from C_UOM_ID, QtyEntered, QtyOrdered - * - enforces qty UOM relationship - * @param ctx context - * @param WindowNo current Window No - * @param mTab Grid Tab - * @param mField Grid Field - * @param value New Value - * @return null or error message - */ - public String qty (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) - { - if (isCalloutActive() || value == null) - return ""; - setCalloutActive(true); - - int M_Product_ID = Env.getContextAsInt(ctx, WindowNo, "M_Product_ID"); - if (steps) log.warning("init - M_Product_ID=" + M_Product_ID + " - " ); - BigDecimal QtyOrdered = Env.ZERO; - BigDecimal QtyEntered, PriceActual, PriceEntered; - - // No Product - if (M_Product_ID == 0) - { - QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); - QtyOrdered = QtyEntered; - mTab.setValue("QtyOrdered", QtyOrdered); - } - // UOM Changed - convert from Entered -> Product - else if (mField.getColumnName().equals("C_UOM_ID")) - { - int C_UOM_To_ID = ((Integer)value).intValue(); - QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); - BigDecimal QtyEntered1 = QtyEntered.setScale(MUOM.getPrecision(ctx, C_UOM_To_ID), BigDecimal.ROUND_HALF_UP); - if (QtyEntered.compareTo(QtyEntered1) != 0) - { - log.fine("Corrected QtyEntered Scale UOM=" + C_UOM_To_ID - + "; QtyEntered=" + QtyEntered + "->" + QtyEntered1); - QtyEntered = QtyEntered1; - mTab.setValue("QtyEntered", QtyEntered); - } - QtyOrdered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, - C_UOM_To_ID, QtyEntered); - if (QtyOrdered == null) - QtyOrdered = QtyEntered; - boolean conversion = QtyEntered.compareTo(QtyOrdered) != 0; - PriceActual = (BigDecimal)mTab.getValue("PriceActual"); - PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, - C_UOM_To_ID, PriceActual); - if (PriceEntered == null) - PriceEntered = PriceActual; - log.fine("UOM=" + C_UOM_To_ID - + ", QtyEntered/PriceActual=" + QtyEntered + "/" + PriceActual - + " -> " + conversion - + " QtyOrdered/PriceEntered=" + QtyOrdered + "/" + PriceEntered); - Env.setContext(ctx, WindowNo, "UOMConversion", conversion ? "Y" : "N"); - mTab.setValue("QtyOrdered", QtyOrdered); - mTab.setValue("PriceEntered", PriceEntered); - } - // QtyEntered changed - calculate QtyOrdered - else if (mField.getColumnName().equals("QtyEntered")) - { - int C_UOM_To_ID = Env.getContextAsInt(ctx, WindowNo, "C_UOM_ID"); - QtyEntered = (BigDecimal)value; - BigDecimal QtyEntered1 = QtyEntered.setScale(MUOM.getPrecision(ctx, C_UOM_To_ID), BigDecimal.ROUND_HALF_UP); - if (QtyEntered.compareTo(QtyEntered1) != 0) - { - log.fine("Corrected QtyEntered Scale UOM=" + C_UOM_To_ID - + "; QtyEntered=" + QtyEntered + "->" + QtyEntered1); - QtyEntered = QtyEntered1; - mTab.setValue("QtyEntered", QtyEntered); - } - QtyOrdered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, - C_UOM_To_ID, QtyEntered); - if (QtyOrdered == null) - QtyOrdered = QtyEntered; - boolean conversion = QtyEntered.compareTo(QtyOrdered) != 0; - log.fine("UOM=" + C_UOM_To_ID - + ", QtyEntered=" + QtyEntered - + " -> " + conversion - + " QtyOrdered=" + QtyOrdered); - Env.setContext(ctx, WindowNo, "UOMConversion", conversion ? "Y" : "N"); - mTab.setValue("QtyOrdered", QtyOrdered); - } - // QtyOrdered changed - calculate QtyEntered (should not happen) - else if (mField.getColumnName().equals("QtyOrdered")) - { - int C_UOM_To_ID = Env.getContextAsInt(ctx, WindowNo, "C_UOM_ID"); - QtyOrdered = (BigDecimal)value; - int precision = MProduct.get(ctx, M_Product_ID).getUOMPrecision(); - BigDecimal QtyOrdered1 = QtyOrdered.setScale(precision, BigDecimal.ROUND_HALF_UP); - if (QtyOrdered.compareTo(QtyOrdered1) != 0) - { - log.fine("Corrected QtyOrdered Scale " - + QtyOrdered + "->" + QtyOrdered1); - QtyOrdered = QtyOrdered1; - mTab.setValue("QtyOrdered", QtyOrdered); - } - QtyEntered = MUOMConversion.convertProductTo (ctx, M_Product_ID, - C_UOM_To_ID, QtyOrdered); - if (QtyEntered == null) - QtyEntered = QtyOrdered; - boolean conversion = QtyOrdered.compareTo(QtyEntered) != 0; - log.fine("UOM=" + C_UOM_To_ID - + ", QtyOrdered=" + QtyOrdered - + " -> " + conversion - + " QtyEntered=" + QtyEntered); - Env.setContext(ctx, WindowNo, "UOMConversion", conversion ? "Y" : "N"); - mTab.setValue("QtyEntered", QtyEntered); - } - else - { - // QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); - QtyOrdered = (BigDecimal)mTab.getValue("QtyOrdered"); - } - - // Storage - if (M_Product_ID != 0 - && Env.isSOTrx(ctx, WindowNo) - && QtyOrdered.signum() > 0) // no negative (returns) - { - MProduct product = MProduct.get (ctx, M_Product_ID); - if (product.isStocked()) - { - int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID"); - int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID"); - BigDecimal available = MStorage.getQtyAvailable - (M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID, null); - if (available == null) - available = Env.ZERO; - if (available.signum() == 0) - mTab.fireDataStatusEEvent ("NoQtyAvailable", "0", false); - else if (available.compareTo(QtyOrdered) < 0) - mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", available.toString(), false); - else - { - Integer C_OrderLine_ID = (Integer)mTab.getValue("C_OrderLine_ID"); - if (C_OrderLine_ID == null) - C_OrderLine_ID = new Integer(0); - BigDecimal notReserved = MOrderLine.getNotReserved(ctx, - M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID, - C_OrderLine_ID.intValue()); - if (notReserved == null) - notReserved = Env.ZERO; - BigDecimal total = available.subtract(notReserved); - if (total.compareTo(QtyOrdered) < 0) - { - String info = Msg.parseTranslation(ctx, "@QtyAvailable@=" + available - + " - @QtyNotReserved@=" + notReserved + " = " + total); - mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", - info, false); - } - } - } - } - // - setCalloutActive(false); - return ""; - } // qty - -} // CalloutOrder - + s = rs.getString(IsSOTrx ? "PaymentRule" : "PaymentRulePO"); + if (s != null && s.length() != 0) + { + if (s.equals("B")) // No Cache in Non POS + s = "P"; + if (IsSOTrx && (s.equals("S") || s.equals("U"))) // No Check/Transfer for SO_Trx + s = "P"; // Payment Term + mTab.setValue("PaymentRule", s); + } + // Payment Term + ii = new Integer(rs.getInt(IsSOTrx ? "C_PaymentTerm_ID" : "PO_PaymentTerm_ID")); + if (!rs.wasNull()) + mTab.setValue("C_PaymentTerm_ID", ii); + // InvoiceRule + s = rs.getString("InvoiceRule"); + if (s != null && s.length() != 0) + mTab.setValue("InvoiceRule", s); + } + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, "bPartnerBill", e); + return e.getLocalizedMessage(); + } + + return ""; + } // bPartnerBill + + + /** + * Order Header - PriceList. + * (used also in Invoice) + * - C_Currency_ID + * - IsTaxIncluded + * Window Context: + * - EnforcePriceLimit + * - StdPrecision + * - M_PriceList_Version_ID + * @param ctx context + * @param WindowNo current Window No + * @param mTab Grid Tab + * @param mField Grid Field + * @param value New Value + * @return null or error message + */ + public String priceList (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) + { + Integer M_PriceList_ID = (Integer)value; + if (M_PriceList_ID == null || M_PriceList_ID.intValue()== 0) + return ""; + if (steps) log.warning("init"); + + String sql = "SELECT pl.IsTaxIncluded,pl.EnforcePriceLimit,pl.C_Currency_ID,c.StdPrecision," + + "plv.M_PriceList_Version_ID,plv.ValidFrom " + + "FROM M_PriceList pl,C_Currency c,M_PriceList_Version plv " + + "WHERE pl.C_Currency_ID=c.C_Currency_ID" + + " AND pl.M_PriceList_ID=plv.M_PriceList_ID" + + " AND pl.M_PriceList_ID=? " // 1 + + "ORDER BY plv.ValidFrom DESC"; + // Use newest price list - may not be future + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, M_PriceList_ID.intValue()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + { + // Tax Included + mTab.setValue("IsTaxIncluded", new Boolean("Y".equals(rs.getString(1)))); + // Price Limit Enforce + Env.setContext(ctx, WindowNo, "EnforcePriceLimit", rs.getString(2)); + // Currency + Integer ii = new Integer(rs.getInt(3)); + mTab.setValue("C_Currency_ID", ii); + // PriceList Version + Env.setContext(ctx, WindowNo, "M_PriceList_Version_ID", rs.getInt(5)); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + return e.getLocalizedMessage(); + } + if (steps) log.warning("fini"); + + return ""; + } // priceList + + + /************************************************************************* + * Order Line - Product. + * - reset C_Charge_ID / M_AttributeSetInstance_ID + * - PriceList, PriceStd, PriceLimit, C_Currency_ID, EnforcePriceLimit + * - UOM + * Calls Tax + * + * @param ctx context + * @param WindowNo current Window No + * @param mTab Grid Tab + * @param mField Grid Field + * @param value New Value + * @return null or error message + */ + public String product (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) + { + Integer M_Product_ID = (Integer)value; + if (M_Product_ID == null || M_Product_ID.intValue() == 0) + return ""; + setCalloutActive(true); + if (steps) log.warning("init"); + // + mTab.setValue("C_Charge_ID", null); + // Set Attribute + if (Env.getContextAsInt(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "M_Product_ID") == M_Product_ID.intValue() + && Env.getContextAsInt(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "M_AttributeSetInstance_ID") != 0) + mTab.setValue("M_AttributeSetInstance_ID", new Integer(Env.getContextAsInt(ctx, Env.WINDOW_INFO, Env.TAB_INFO, "M_AttributeSetInstance_ID"))); + else + mTab.setValue("M_AttributeSetInstance_ID", null); + + /***** Price Calculation see also qty ****/ + int C_BPartner_ID = Env.getContextAsInt(ctx, WindowNo, "C_BPartner_ID"); + BigDecimal Qty = (BigDecimal)mTab.getValue("QtyOrdered"); + boolean IsSOTrx = Env.getContext(ctx, WindowNo, "IsSOTrx").equals("Y"); + MProductPricing pp = new MProductPricing (M_Product_ID.intValue(), C_BPartner_ID, Qty, IsSOTrx); + // + int M_PriceList_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_ID"); + pp.setM_PriceList_ID(M_PriceList_ID); + /** PLV is only accurate if PL selected in header */ + int M_PriceList_Version_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_Version_ID"); + pp.setM_PriceList_Version_ID(M_PriceList_Version_ID); + Timestamp orderDate = (Timestamp)mTab.getValue("DateOrdered"); + pp.setPriceDate(orderDate); + // + mTab.setValue("PriceList", pp.getPriceList()); + mTab.setValue("PriceLimit", pp.getPriceLimit()); + mTab.setValue("PriceActual", pp.getPriceStd()); + mTab.setValue("PriceEntered", pp.getPriceStd()); + mTab.setValue("C_Currency_ID", new Integer(pp.getC_Currency_ID())); + mTab.setValue("Discount", pp.getDiscount()); + mTab.setValue("C_UOM_ID", new Integer(pp.getC_UOM_ID())); + mTab.setValue("QtyOrdered", mTab.getValue("QtyEntered")); + Env.setContext(ctx, WindowNo, "EnforcePriceLimit", pp.isEnforcePriceLimit() ? "Y" : "N"); + Env.setContext(ctx, WindowNo, "DiscountSchema", pp.isDiscountSchema() ? "Y" : "N"); + + // Check/Update Warehouse Setting + // int M_Warehouse_ID = Env.getContextAsInt(ctx, Env.WINDOW_INFO, "M_Warehouse_ID"); + // Integer wh = (Integer)mTab.getValue("M_Warehouse_ID"); + // if (wh.intValue() != M_Warehouse_ID) + // { + // mTab.setValue("M_Warehouse_ID", new Integer(M_Warehouse_ID)); + // ADialog.warn(,WindowNo, "WarehouseChanged"); + // } + + + if (Env.isSOTrx(ctx, WindowNo)) + { + MProduct product = MProduct.get (ctx, M_Product_ID.intValue()); + if (product.isStocked()) + { + BigDecimal QtyOrdered = (BigDecimal)mTab.getValue("QtyOrdered"); + int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID"); + int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID"); + BigDecimal available = MStorage.getQtyAvailable + (M_Warehouse_ID, M_Product_ID.intValue(), M_AttributeSetInstance_ID, null); + if (available == null) + available = Env.ZERO; + if (available.signum() == 0) + mTab.fireDataStatusEEvent ("NoQtyAvailable", "0", false); + else if (available.compareTo(QtyOrdered) < 0) + mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", available.toString(), false); + else + { + Integer C_OrderLine_ID = (Integer)mTab.getValue("C_OrderLine_ID"); + if (C_OrderLine_ID == null) + C_OrderLine_ID = new Integer(0); + BigDecimal notReserved = MOrderLine.getNotReserved(ctx, + M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID, + C_OrderLine_ID.intValue()); + if (notReserved == null) + notReserved = Env.ZERO; + BigDecimal total = available.subtract(notReserved); + if (total.compareTo(QtyOrdered) < 0) + { + String info = Msg.parseTranslation(ctx, "@QtyAvailable@=" + available + + " - @QtyNotReserved@=" + notReserved + " = " + total); + mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", + info, false); + } + } + } + } + // + setCalloutActive(false); + if (steps) log.warning("fini"); + return tax (ctx, WindowNo, mTab, mField, value); + } // product + + /** + * Order Line - Charge. + * - updates PriceActual from Charge + * - sets PriceLimit, PriceList to zero + * Calles tax + * @param ctx context + * @param WindowNo current Window No + * @param mTab Grid Tab + * @param mField Grid Field + * @param value New Value + * @return null or error message + */ + public String charge (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) + { + Integer C_Charge_ID = (Integer)value; + if (C_Charge_ID == null || C_Charge_ID.intValue() == 0) + return ""; + // No Product defined + if (mTab.getValue("M_Product_ID") != null) + { + mTab.setValue("C_Charge_ID", null); + return "ChargeExclusively"; + } + mTab.setValue("M_AttributeSetInstance_ID", null); + mTab.setValue("S_ResourceAssignment_ID", null); + mTab.setValue("C_UOM_ID", new Integer(100)); // EA + + Env.setContext(ctx, WindowNo, "DiscountSchema", "N"); + String sql = "SELECT ChargeAmt FROM C_Charge WHERE C_Charge_ID=?"; + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, C_Charge_ID.intValue()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + { + mTab.setValue ("PriceEntered", rs.getBigDecimal (1)); + mTab.setValue ("PriceActual", rs.getBigDecimal (1)); + mTab.setValue ("PriceLimit", Env.ZERO); + mTab.setValue ("PriceList", Env.ZERO); + mTab.setValue ("Discount", Env.ZERO); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + return e.getLocalizedMessage(); + } + // + return tax (ctx, WindowNo, mTab, mField, value); + } // charge + + + /** + * Order Line - Tax. + * - basis: Product, Charge, BPartner Location + * - sets C_Tax_ID + * Calles Amount + * @param ctx context + * @param WindowNo current Window No + * @param mTab Grid Tab + * @param mField Grid Field + * @param value New Value + * @return null or error message + */ + public String tax (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) + { + String column = mField.getColumnName(); + if (value == null) + return ""; + if (steps) log.warning("init"); + + // Check Product + int M_Product_ID = 0; + if (column.equals("M_Product_ID")) + M_Product_ID = ((Integer)value).intValue(); + else + M_Product_ID = Env.getContextAsInt(ctx, WindowNo, "M_Product_ID"); + int C_Charge_ID = 0; + if (column.equals("C_Charge_ID")) + C_Charge_ID = ((Integer)value).intValue(); + else + C_Charge_ID = Env.getContextAsInt(ctx, WindowNo, "C_Charge_ID"); + log.fine("Product=" + M_Product_ID + ", C_Charge_ID=" + C_Charge_ID); + if (M_Product_ID == 0 && C_Charge_ID == 0) + return amt(ctx, WindowNo, mTab, mField, value); // + + // Check Partner Location + int shipC_BPartner_Location_ID = 0; + if (column.equals("C_BPartner_Location_ID")) + shipC_BPartner_Location_ID = ((Integer)value).intValue(); + else + shipC_BPartner_Location_ID = Env.getContextAsInt(ctx, WindowNo, "C_BPartner_Location_ID"); + if (shipC_BPartner_Location_ID == 0) + return amt(ctx, WindowNo, mTab, mField, value); // + log.fine("Ship BP_Location=" + shipC_BPartner_Location_ID); + + // + Timestamp billDate = Env.getContextAsDate(ctx, WindowNo, "DateOrdered"); + log.fine("Bill Date=" + billDate); + + Timestamp shipDate = Env.getContextAsDate(ctx, WindowNo, "DatePromised"); + log.fine("Ship Date=" + shipDate); + + int AD_Org_ID = Env.getContextAsInt(ctx, WindowNo, "AD_Org_ID"); + log.fine("Org=" + AD_Org_ID); + + int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID"); + log.fine("Warehouse=" + M_Warehouse_ID); + + int billC_BPartner_Location_ID = Env.getContextAsInt(ctx, WindowNo, "Bill_Location_ID"); + if (billC_BPartner_Location_ID == 0) + billC_BPartner_Location_ID = shipC_BPartner_Location_ID; + log.fine("Bill BP_Location=" + billC_BPartner_Location_ID); + + // + int C_Tax_ID = Tax.get (ctx, M_Product_ID, C_Charge_ID, billDate, shipDate, + AD_Org_ID, M_Warehouse_ID, billC_BPartner_Location_ID, shipC_BPartner_Location_ID, + "Y".equals(Env.getContext(ctx, WindowNo, "IsSOTrx"))); + log.info("Tax ID=" + C_Tax_ID); + // + if (C_Tax_ID == 0) + mTab.fireDataStatusEEvent(CLogger.retrieveError()); + else + mTab.setValue("C_Tax_ID", new Integer(C_Tax_ID)); + // + if (steps) log.warning("fini"); + return amt(ctx, WindowNo, mTab, mField, value); + } // tax + + + /** + * Order Line - Amount. + * - called from QtyOrdered, Discount and PriceActual + * - calculates Discount or Actual Amount + * - calculates LineNetAmt + * - enforces PriceLimit + * @param ctx context + * @param WindowNo current Window No + * @param mTab Grid Tab + * @param mField Grid Field + * @param value New Value + * @return null or error message + */ + public String amt (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) + { + if (isCalloutActive() || value == null) + return ""; + setCalloutActive(true); + + if (steps) log.warning("init"); + int C_UOM_To_ID = Env.getContextAsInt(ctx, WindowNo, "C_UOM_ID"); + int M_Product_ID = Env.getContextAsInt(ctx, WindowNo, "M_Product_ID"); + int M_PriceList_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_ID"); + int StdPrecision = MPriceList.getStandardPrecision(ctx, M_PriceList_ID); + BigDecimal QtyEntered, QtyOrdered, PriceEntered, PriceActual, PriceLimit, Discount, PriceList; + // get values + QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); + QtyOrdered = (BigDecimal)mTab.getValue("QtyOrdered"); + log.fine("QtyEntered=" + QtyEntered + ", Ordered=" + QtyOrdered + ", UOM=" + C_UOM_To_ID); + // + PriceEntered = (BigDecimal)mTab.getValue("PriceEntered"); + PriceActual = (BigDecimal)mTab.getValue("PriceActual"); + Discount = (BigDecimal)mTab.getValue("Discount"); + PriceLimit = (BigDecimal)mTab.getValue("PriceLimit"); + PriceList = (BigDecimal)mTab.getValue("PriceList"); + log.fine("PriceList=" + PriceList + ", Limit=" + PriceLimit + ", Precision=" + StdPrecision); + log.fine("PriceEntered=" + PriceEntered + ", Actual=" + PriceActual + ", Discount=" + Discount); + + // Qty changed - recalc price + if ((mField.getColumnName().equals("QtyOrdered") + || mField.getColumnName().equals("QtyEntered") + || mField.getColumnName().equals("M_Product_ID")) + && !"N".equals(Env.getContext(ctx, WindowNo, "DiscountSchema"))) + { + int C_BPartner_ID = Env.getContextAsInt(ctx, WindowNo, "C_BPartner_ID"); + if (mField.getColumnName().equals("QtyEntered")) + QtyOrdered = MUOMConversion.convertProductTo (ctx, M_Product_ID, + C_UOM_To_ID, QtyEntered); + if (QtyOrdered == null) + QtyOrdered = QtyEntered; + boolean IsSOTrx = Env.getContext(ctx, WindowNo, "IsSOTrx").equals("Y"); + MProductPricing pp = new MProductPricing (M_Product_ID, C_BPartner_ID, QtyOrdered, IsSOTrx); + pp.setM_PriceList_ID(M_PriceList_ID); + int M_PriceList_Version_ID = Env.getContextAsInt(ctx, WindowNo, "M_PriceList_Version_ID"); + pp.setM_PriceList_Version_ID(M_PriceList_Version_ID); + Timestamp date = (Timestamp)mTab.getValue("DateOrdered"); + pp.setPriceDate(date); + // + PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, + C_UOM_To_ID, pp.getPriceStd()); + if (PriceEntered == null) + PriceEntered = pp.getPriceStd(); + // + log.fine("QtyChanged -> PriceActual=" + pp.getPriceStd() + + ", PriceEntered=" + PriceEntered + ", Discount=" + pp.getDiscount()); + mTab.setValue("PriceActual", pp.getPriceStd()); + mTab.setValue("Discount", pp.getDiscount()); + mTab.setValue("PriceEntered", PriceEntered); + Env.setContext(ctx, WindowNo, "DiscountSchema", pp.isDiscountSchema() ? "Y" : "N"); + } + else if (mField.getColumnName().equals("PriceActual")) + { + PriceActual = (BigDecimal)value; + PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, + C_UOM_To_ID, PriceActual); + if (PriceEntered == null) + PriceEntered = PriceActual; + // + log.fine("PriceActual=" + PriceActual + + " -> PriceEntered=" + PriceEntered); + mTab.setValue("PriceEntered", PriceEntered); + } + else if (mField.getColumnName().equals("PriceEntered")) + { + PriceEntered = (BigDecimal)value; + PriceActual = MUOMConversion.convertProductTo (ctx, M_Product_ID, + C_UOM_To_ID, PriceEntered); + if (PriceActual == null) + PriceActual = PriceEntered; + // + log.fine("PriceEntered=" + PriceEntered + + " -> PriceActual=" + PriceActual); + mTab.setValue("PriceActual", PriceActual); + } + + // Discount entered - Calculate Actual/Entered + if (mField.getColumnName().equals("Discount")) + { + PriceActual = new BigDecimal ((100.0 - Discount.doubleValue()) / 100.0 * PriceList.doubleValue()); + if (PriceActual.scale() > StdPrecision) + PriceActual = PriceActual.setScale(StdPrecision, BigDecimal.ROUND_HALF_UP); + PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, + C_UOM_To_ID, PriceActual); + if (PriceEntered == null) + PriceEntered = PriceActual; + mTab.setValue("PriceActual", PriceActual); + mTab.setValue("PriceEntered", PriceEntered); + } + // calculate Discount + else + { + if (PriceList.intValue() == 0) + Discount = Env.ZERO; + else + Discount = new BigDecimal ((PriceList.doubleValue() - PriceActual.doubleValue()) / PriceList.doubleValue() * 100.0); + if (Discount.scale() > 2) + Discount = Discount.setScale(2, BigDecimal.ROUND_HALF_UP); + mTab.setValue("Discount", Discount); + } + log.fine("PriceEntered=" + PriceEntered + ", Actual=" + PriceActual + ", Discount=" + Discount); + + // Check PriceLimit + String epl = Env.getContext(ctx, WindowNo, "EnforcePriceLimit"); + boolean enforce = Env.isSOTrx(ctx, WindowNo) && epl != null && epl.equals("Y"); + if (enforce && MRole.getDefault().isOverwritePriceLimit()) + enforce = false; + // Check Price Limit? + if (enforce && PriceLimit.doubleValue() != 0.0 + && PriceActual.compareTo(PriceLimit) < 0) + { + PriceActual = PriceLimit; + PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, + C_UOM_To_ID, PriceLimit); + if (PriceEntered == null) + PriceEntered = PriceLimit; + log.fine("(under) PriceEntered=" + PriceEntered + ", Actual" + PriceLimit); + mTab.setValue ("PriceActual", PriceLimit); + mTab.setValue ("PriceEntered", PriceEntered); + mTab.fireDataStatusEEvent ("UnderLimitPrice", "", false); + // Repeat Discount calc + if (PriceList.intValue() != 0) + { + Discount = new BigDecimal ((PriceList.doubleValue () - PriceActual.doubleValue ()) / PriceList.doubleValue () * 100.0); + if (Discount.scale () > 2) + Discount = Discount.setScale (2, BigDecimal.ROUND_HALF_UP); + mTab.setValue ("Discount", Discount); + } + } + + // Line Net Amt + BigDecimal LineNetAmt = QtyOrdered.multiply(PriceActual); + if (LineNetAmt.scale() > StdPrecision) + LineNetAmt = LineNetAmt.setScale(StdPrecision, BigDecimal.ROUND_HALF_UP); + log.info("LineNetAmt=" + LineNetAmt); + mTab.setValue("LineNetAmt", LineNetAmt); + // + setCalloutActive(false); + return ""; + } // amt + + /** + * Order Line - Quantity. + * - called from C_UOM_ID, QtyEntered, QtyOrdered + * - enforces qty UOM relationship + * @param ctx context + * @param WindowNo current Window No + * @param mTab Grid Tab + * @param mField Grid Field + * @param value New Value + * @return null or error message + */ + public String qty (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) + { + if (isCalloutActive() || value == null) + return ""; + setCalloutActive(true); + + int M_Product_ID = Env.getContextAsInt(ctx, WindowNo, "M_Product_ID"); + if (steps) log.warning("init - M_Product_ID=" + M_Product_ID + " - " ); + BigDecimal QtyOrdered = Env.ZERO; + BigDecimal QtyEntered, PriceActual, PriceEntered; + + // No Product + if (M_Product_ID == 0) + { + QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); + QtyOrdered = QtyEntered; + mTab.setValue("QtyOrdered", QtyOrdered); + } + // UOM Changed - convert from Entered -> Product + else if (mField.getColumnName().equals("C_UOM_ID")) + { + int C_UOM_To_ID = ((Integer)value).intValue(); + QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); + BigDecimal QtyEntered1 = QtyEntered.setScale(MUOM.getPrecision(ctx, C_UOM_To_ID), BigDecimal.ROUND_HALF_UP); + if (QtyEntered.compareTo(QtyEntered1) != 0) + { + log.fine("Corrected QtyEntered Scale UOM=" + C_UOM_To_ID + + "; QtyEntered=" + QtyEntered + "->" + QtyEntered1); + QtyEntered = QtyEntered1; + mTab.setValue("QtyEntered", QtyEntered); + } + QtyOrdered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, + C_UOM_To_ID, QtyEntered); + if (QtyOrdered == null) + QtyOrdered = QtyEntered; + boolean conversion = QtyEntered.compareTo(QtyOrdered) != 0; + PriceActual = (BigDecimal)mTab.getValue("PriceActual"); + PriceEntered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, + C_UOM_To_ID, PriceActual); + if (PriceEntered == null) + PriceEntered = PriceActual; + log.fine("UOM=" + C_UOM_To_ID + + ", QtyEntered/PriceActual=" + QtyEntered + "/" + PriceActual + + " -> " + conversion + + " QtyOrdered/PriceEntered=" + QtyOrdered + "/" + PriceEntered); + Env.setContext(ctx, WindowNo, "UOMConversion", conversion ? "Y" : "N"); + mTab.setValue("QtyOrdered", QtyOrdered); + mTab.setValue("PriceEntered", PriceEntered); + } + // QtyEntered changed - calculate QtyOrdered + else if (mField.getColumnName().equals("QtyEntered")) + { + int C_UOM_To_ID = Env.getContextAsInt(ctx, WindowNo, "C_UOM_ID"); + QtyEntered = (BigDecimal)value; + BigDecimal QtyEntered1 = QtyEntered.setScale(MUOM.getPrecision(ctx, C_UOM_To_ID), BigDecimal.ROUND_HALF_UP); + if (QtyEntered.compareTo(QtyEntered1) != 0) + { + log.fine("Corrected QtyEntered Scale UOM=" + C_UOM_To_ID + + "; QtyEntered=" + QtyEntered + "->" + QtyEntered1); + QtyEntered = QtyEntered1; + mTab.setValue("QtyEntered", QtyEntered); + } + QtyOrdered = MUOMConversion.convertProductFrom (ctx, M_Product_ID, + C_UOM_To_ID, QtyEntered); + if (QtyOrdered == null) + QtyOrdered = QtyEntered; + boolean conversion = QtyEntered.compareTo(QtyOrdered) != 0; + log.fine("UOM=" + C_UOM_To_ID + + ", QtyEntered=" + QtyEntered + + " -> " + conversion + + " QtyOrdered=" + QtyOrdered); + Env.setContext(ctx, WindowNo, "UOMConversion", conversion ? "Y" : "N"); + mTab.setValue("QtyOrdered", QtyOrdered); + } + // QtyOrdered changed - calculate QtyEntered (should not happen) + else if (mField.getColumnName().equals("QtyOrdered")) + { + int C_UOM_To_ID = Env.getContextAsInt(ctx, WindowNo, "C_UOM_ID"); + QtyOrdered = (BigDecimal)value; + int precision = MProduct.get(ctx, M_Product_ID).getUOMPrecision(); + BigDecimal QtyOrdered1 = QtyOrdered.setScale(precision, BigDecimal.ROUND_HALF_UP); + if (QtyOrdered.compareTo(QtyOrdered1) != 0) + { + log.fine("Corrected QtyOrdered Scale " + + QtyOrdered + "->" + QtyOrdered1); + QtyOrdered = QtyOrdered1; + mTab.setValue("QtyOrdered", QtyOrdered); + } + QtyEntered = MUOMConversion.convertProductTo (ctx, M_Product_ID, + C_UOM_To_ID, QtyOrdered); + if (QtyEntered == null) + QtyEntered = QtyOrdered; + boolean conversion = QtyOrdered.compareTo(QtyEntered) != 0; + log.fine("UOM=" + C_UOM_To_ID + + ", QtyOrdered=" + QtyOrdered + + " -> " + conversion + + " QtyEntered=" + QtyEntered); + Env.setContext(ctx, WindowNo, "UOMConversion", conversion ? "Y" : "N"); + mTab.setValue("QtyEntered", QtyEntered); + } + else + { + // QtyEntered = (BigDecimal)mTab.getValue("QtyEntered"); + QtyOrdered = (BigDecimal)mTab.getValue("QtyOrdered"); + } + + // Storage + if (M_Product_ID != 0 + && Env.isSOTrx(ctx, WindowNo) + && QtyOrdered.signum() > 0) // no negative (returns) + { + MProduct product = MProduct.get (ctx, M_Product_ID); + if (product.isStocked()) + { + int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID"); + int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID"); + BigDecimal available = MStorage.getQtyAvailable + (M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID, null); + if (available == null) + available = Env.ZERO; + if (available.signum() == 0) + mTab.fireDataStatusEEvent ("NoQtyAvailable", "0", false); + else if (available.compareTo(QtyOrdered) < 0) + mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", available.toString(), false); + else + { + Integer C_OrderLine_ID = (Integer)mTab.getValue("C_OrderLine_ID"); + if (C_OrderLine_ID == null) + C_OrderLine_ID = new Integer(0); + BigDecimal notReserved = MOrderLine.getNotReserved(ctx, + M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID, + C_OrderLine_ID.intValue()); + if (notReserved == null) + notReserved = Env.ZERO; + BigDecimal total = available.subtract(notReserved); + if (total.compareTo(QtyOrdered) < 0) + { + String info = Msg.parseTranslation(ctx, "@QtyAvailable@=" + available + + " - @QtyNotReserved@=" + notReserved + " = " + total); + mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", + info, false); + } + } + } + } + // + setCalloutActive(false); + return ""; + } // qty + +} // CalloutOrder + diff --git a/base/src/org/compiere/model/GridTab.java b/base/src/org/compiere/model/GridTab.java index 41d1fb9295..86227dd778 100644 --- a/base/src/org/compiere/model/GridTab.java +++ b/base/src/org/compiere/model/GridTab.java @@ -1,2473 +1,2463 @@ -/****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.beans.*; -import java.io.*; -import java.math.BigDecimal; -import java.sql.*; -import java.text.*; -import java.util.*; - -import java.util.logging.*; -import javax.swing.event.*; -import org.compiere.util.*; - -/** - * Tab Model. - * - a combination of AD_Tab (the display attributes) and AD_Table information. - *

- * The Tab owns also it's Table model - * and listens to data changes to update the Field values. - * - *

- * The Tab maintains the bound property: CurrentRow - * - *

- *  Event Hierarchies:
- *      - dataChanged (from MTable)
- *          - setCurrentRow
- *              - Update all Field Values
- *
- *      - setValue
- *          - Update Field Value
- *          - Callout
- *  
- * @author Jorg Janke - * @version $Id: GridTab.java,v 1.10 2006/10/02 05:18:39 jjanke Exp $ - */ -public class GridTab implements DataStatusListener, Evaluatee, Serializable -{ - /** - * Create Tab (Model) from Value Object. - *

- * MTab provides a property listener for changed rows and a - * DataStatusListener for communicating changes of the underlying data - * @param vo Value Object - */ - public GridTab(GridTabVO vo) - { - m_vo = vo; - // Create MTable - m_mTable = new GridTable (m_vo.ctx, m_vo.AD_Table_ID, m_vo.TableName, m_vo.WindowNo, m_vo.TabNo, true); - m_mTable.setReadOnly(m_vo.IsReadOnly || m_vo.IsView); - m_mTable.setDeleteable(m_vo.IsDeleteable); - // Load Tab - // if (vo.TabNo == 0) - initTab(false); - // else - // { - // m_loader = new Loader(); - // m_loader.setPriority(Thread.MIN_PRIORITY); - // m_loader.start(); - // } - // waitLoadCompete(); - } // GridTab - - /** Value Object */ - private GridTabVO m_vo; - - /** The Table Model for Query */ - private GridTable m_mTable = null; - - private String m_keyColumnName = ""; - private String m_linkColumnName = ""; - private String m_extendedWhere; - /** Attachments */ - private HashMap m_Attachments = null; - /** Chats */ - private HashMap m_Chats = null; - /** Locks */ - private ArrayList m_Lock = null; - - /** Current Row */ - private int m_currentRow = -1; - - /** Property Change */ - private PropertyChangeSupport m_propertyChangeSupport = new PropertyChangeSupport(this); - /** Property Change Type */ - public static final String PROPERTY = "CurrentRow"; - /** A list of event listeners for this component. */ - protected EventListenerList m_listenerList = new EventListenerList(); - /** Current Data Status Event */ - private DataStatusEvent m_DataStatusEvent = null; - /** Query */ - private MQuery m_query = new MQuery(); - private String m_oldQuery = "0=9"; - private String m_linkValue = "999999"; - - /** Order By Array if SortNo 1..3 */ - private String[] m_OrderBys = new String[3]; - /** List of Key Parents */ - private ArrayList m_parents = new ArrayList(2); - - /** Map of ColumnName of source field (key) and the dependant field (value) */ - private MultiMap m_depOnField = new MultiMap(); - - /** Async Loader */ - private Loader m_loader = null; - /** Async Loading complete */ - private volatile boolean m_loadComplete = false; - /** Is Tab Included in other Tab */ - private boolean m_included = false; - - /** Logger */ - protected CLogger log = CLogger.getCLogger(getClass()); - - private boolean m_parentNeedSave = false; - - - /************************************************************************** - * Tab loader for Tabs > 0 - */ - class Loader extends Thread - { - /** - * Async Loading of Tab > 0 - */ - public void run() - { - initTab (true); - } // run - } // Loader - - /** - * Wait until load is complete - */ - private void waitLoadCompete() - { - if (m_loadComplete) - return; - // - m_loader.setPriority(Thread.NORM_PRIORITY); - log.config (""); - while (m_loader.isAlive()) - { - try - { - Thread.sleep(100); // 1/10 sec - } - catch (Exception e) - { - log.log(Level.SEVERE, "", e); - } - } - log.config ("fini"); - } // waitLoadComplete - - /** - * Initialize Tab with record from AD_Tab_v - * @param async async - * @return true, if correctly initialized (ignored) - */ - protected boolean initTab (boolean async) - { - log.fine("#" + m_vo.TabNo + " - Async=" + async + " - Where=" + m_vo.WhereClause); - - m_extendedWhere = m_vo.WhereClause; - - // Get Field Data - if (!loadFields()) - { - m_loadComplete = true; - return false; - } - - // Order By - m_mTable.setOrderClause(getOrderByClause(m_vo.onlyCurrentRows)); - - if (async) - log.fine("#" + m_vo.TabNo + " - Async=" + async + " - fini"); - m_loadComplete = true; - return true; - } // initTab - - /** - * Dispose - clean up resources - */ - protected void dispose() - { - log.fine("#" + m_vo.TabNo); - m_OrderBys = null; - // - m_parents.clear(); - m_parents = null; - // - m_mTable.close (true); // also disposes Fields - m_mTable = null; - // - m_depOnField.clear(); - m_depOnField = null; - if (m_Attachments != null) - m_Attachments.clear(); - m_Attachments = null; - if (m_Chats != null) - m_Chats.clear(); - m_Chats = null; - // - m_vo.Fields.clear(); - m_vo.Fields = null; - m_vo = null; - } // dispose - - - /** - * Get Field data and add to MTable, if it's required or displayed. - * Reqiored fields are keys, parents, or standard Columns - * @return true if fields loaded - */ - private boolean loadFields() - { - log.fine("#" + m_vo.TabNo); - - if (m_vo.Fields == null) - return false; - - // Add Fields - for (int f = 0; f < m_vo.Fields.size(); f++) - { - GridFieldVO voF = (GridFieldVO)m_vo.Fields.get(f); - // Add Fields to Table - if (voF != null) - { - GridField field = new GridField (voF); - String columnName = field.getColumnName(); - // Record Info - if (field.isKey()) - m_keyColumnName = columnName; - // Parent Column(s) - if (field.isParentColumn()) - m_parents.add(columnName); - // Order By - int sortNo = field.getSortNo(); - if (sortNo == 0) - ; - else if (Math.abs(sortNo) == 1) - { - m_OrderBys[0] = columnName; - if (sortNo < 0) - m_OrderBys[0] += " DESC"; - } - else if (Math.abs(sortNo) == 2) - { - m_OrderBys[1] = columnName; - if (sortNo < 0) - m_OrderBys[1] += " DESC"; - } - else if (Math.abs(sortNo) == 3) - { - m_OrderBys[2] = columnName; - if (sortNo < 0) - m_OrderBys[2] += " DESC"; - } - // Add field - m_mTable.addField(field); - - // List of ColumnNames, this field is dependent on - ArrayList list = field.getDependentOn(); - for (int i = 0; i < list.size(); i++) - m_depOnField.put(list.get(i), field); // ColumnName, Field - // Add fields all fields are dependent on - if (columnName.equals("IsActive") - || columnName.equals("Processed") - || columnName.equals("Processing")) - m_depOnField.put(columnName, null); - } - } // for all fields - - // Add Standard Fields - if (m_mTable.getField("Created") == null) - { - GridField created = new GridField (GridFieldVO.createStdField(m_vo.ctx, - m_vo.WindowNo, m_vo.TabNo, - m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, true, true)); - m_mTable.addField(created); - } - if (m_mTable.getField("CreatedBy") == null) - { - GridField createdBy = new GridField (GridFieldVO.createStdField(m_vo.ctx, - m_vo.WindowNo, m_vo.TabNo, - m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, true, false)); - m_mTable.addField(createdBy); - } - if (m_mTable.getField("Updated") == null) - { - GridField updated = new GridField (GridFieldVO.createStdField(m_vo.ctx, - m_vo.WindowNo, m_vo.TabNo, - m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, false, true)); - m_mTable.addField(updated); - } - if (m_mTable.getField("UpdatedBy") == null) - { - GridField updatedBy = new GridField (GridFieldVO.createStdField(m_vo.ctx, - m_vo.WindowNo, m_vo.TabNo, - m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, false, false)); - m_mTable.addField(updatedBy); - } - return true; - } // loadFields - - /** - * Get a list of variables, this tab is dependent on. - * - for display purposes - * @return ArrayList - */ - public ArrayList getDependentOn() - { - ArrayList list = new ArrayList(); - // Display - Evaluator.parseDepends(list, m_vo.DisplayLogic); - // - if (list.size() > 0 && CLogMgt.isLevelFiner()) - { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < list.size(); i++) - sb.append(list.get(i)).append(" "); - log.finer("(" + m_vo.Name + ") " + sb.toString()); - } - return list; - } // getDependentOn - - /** - * Get Display Logic - * @return display logic - */ - public String getDisplayLogic() - { - return m_vo.DisplayLogic; - } // getDisplayLogic - - /** - * Get TableModel. - * Do not directly communicate with the table model, - * but through the methods of this class - * @return Table Model - */ - public GridTable getTableModel() - { - return m_mTable; - } // getTableModel - - /** - * Get Tab Icon - * @return Icon - */ - public javax.swing.Icon getIcon() - { - if (m_vo.AD_Image_ID == 0) - return null; - // - /** @todo Load Image */ - return null; - } // getIcon - - - /************************************************************************** - * Has this field dependents ? - * @param columnName column name - * @return true if column has dependent - */ - public boolean hasDependants (String columnName) - { - // m_depOnField.printToLog(); - return m_depOnField.containsKey(columnName); - } // isDependentOn - - /** - * Get dependents fields of columnName - * @param columnName column name - * @return ArrayList with GridFields dependent on columnName - */ - public ArrayList getDependantFields (String columnName) - { - return m_depOnField.getValues(columnName); - } // getDependentFields - - - /************************************************************************** - * Set Query - * @param query query - */ - public void setQuery(MQuery query) - { - if (query == null) - m_query = new MQuery(); - else - m_query = query; - } // setQuery - - /** - * Get Query - * @return query - */ - public MQuery getQuery() - { - return m_query; - } // getQuery - - /** - * Is Query Active - * @return true if query active - */ - public boolean isQueryActive() - { - if (m_query != null) - return m_query.isActive(); - return false; - } // isQueryActive - - /** - * Is Query New Record - * @return true if query active - */ - public boolean isQueryNewRecord() - { - if (m_query != null) - return m_query.isNewRecordQuery(); - return false; - } // isQueryNewRecord - - /** - * Enable Events - enable data events of tabs (add listeners) - */ - public void enableEvents() - { - // Setup Events - m_mTable.addDataStatusListener(this); - // m_mTable.addTableModelListener(this); - } // enableEvents - - /** - * Assemble whereClause and query MTable and position to row 0. - *

-	 *		Scenarios:
-	 *		- Never opened 					(full query)
-	 *		- query changed 				(full query)
-	 *		- Detail link value changed		(full query)
-	 *		- otherwise 					(refreshAll)
-	 *  
- * @param onlyCurrentRows only current rows (1 day) - */ - public void query (boolean onlyCurrentRows) - { - query (onlyCurrentRows, 0, 0); - } // query - - /** - * Assemble whereClause and query MTable and position to row 0. - *
-	 *		Scenarios:
-	 *		- Never opened 					(full query)
-	 *		- query changed 				(full query)
-	 *		- Detail link value changed		(full query)
-	 *		- otherwise 					(refreshAll)
-	 *  
- * @param onlyCurrentRows only current rows - * @param onlyCurrentDays if only current row, how many days back - * @param maxRows maximim rows or 0 for all - */ - public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows) - { - log.fine("#" + m_vo.TabNo - + " - Only Current Rows=" + onlyCurrentRows - + ", Days=" + onlyCurrentDays + ", Detail=" + isDetail()); - // is it same query? - boolean refresh = m_oldQuery.equals(m_query.getWhereClause()) - && m_vo.onlyCurrentRows == onlyCurrentRows && m_vo.onlyCurrentDays == onlyCurrentDays; - m_oldQuery = m_query.getWhereClause(); - m_vo.onlyCurrentRows = onlyCurrentRows; - m_vo.onlyCurrentDays = onlyCurrentDays; - - /** - * Set Where Clause - */ - // Tab Where Clause - StringBuffer where = new StringBuffer(m_vo.WhereClause); - if (m_vo.onlyCurrentDays > 0) - { - if (where.length() > 0) - where.append(" AND "); - where.append("Created >= "); - if (DB.isDerby()) - where.append("dateadd(dd,-").append(m_vo.onlyCurrentDays).append(",getdate())"); - else - where.append("SysDate-").append(m_vo.onlyCurrentDays); - } - // Detail Query - if (isDetail()) - { - m_parentNeedSave = false; - String lc = getLinkColumnName(); - if (lc.equals("")) - log.severe ("No link column"); - else - { - String value = Env.getContext(m_vo.ctx, m_vo.WindowNo, lc); - // Same link value? - if (refresh) - refresh = m_linkValue.equals(value); - m_linkValue = value; - // Check validity - if (value.length() == 0) - { - //log.severe ("No value for link column " + lc); - //parent is new, can't retrieve detail - m_parentNeedSave = true; - return; - } - else - { - // we have column and value - if (where.length() != 0) - where.append(" AND "); - where.append(lc).append("="); - if (lc.endsWith("_ID")) - where.append(value); - else - where.append("'").append(value).append("'"); - } - } - } // isDetail - - m_extendedWhere = where.toString(); - - // Final Query - if (m_query.isActive()) - { - String q = validateQuery(m_query); - if (q != null) - { - if (where.length() > 0 ) - where.append(" AND "); - where.append(q); - } - } - - /** - * Query - */ - log.fine("#" + m_vo.TabNo + " - " + where); - if (m_mTable.isOpen()) - { - if (refresh) - m_mTable.dataRefreshAll(); - else - m_mTable.dataRequery(where.toString(), m_vo.onlyCurrentRows && !isDetail(), onlyCurrentDays); - } - else - { - m_mTable.setSelectWhereClause(where.toString(), m_vo.onlyCurrentRows && !isDetail(), onlyCurrentDays); - m_mTable.open(maxRows); - } - // Go to Record 0 - setCurrentRow(0, true); - } // query - - /** - * Validate Query. - * If query column is not a tab column create EXISTS query - * @param query query - * @return where clause - */ - private String validateQuery (MQuery query) - { - if (query == null || query.getRestrictionCount() == 0) - return null; - - // Check: only one restriction - if (query.getRestrictionCount() != 1) - { - log.fine("Ignored(More than 1 Restriction): " + query); - return query.getWhereClause(); - } - - String colName = query.getColumnName(0); - if (colName == null) - { - log.fine("Ignored(No Column): " + query); - return query.getWhereClause(); - } - // a '(' in the name = function - don't try to resolve - if (colName.indexOf('(') != -1) - { - log.fine("Ignored(Function): " + colName); - return query.getWhereClause(); - } - // OK - Query is valid - - // Zooms to the same Window (Parents, ..) - String refColName = null; - if (colName.equals("R_RequestRelated_ID")) - refColName = "R_Request_ID"; - else if (colName.startsWith("C_DocType")) - refColName = "C_DocType_ID"; - if (refColName != null) - { - query.setColumnName(0, refColName); - if (getField(refColName) != null) - { - log.fine("Column " + colName + " replaced with synonym " + refColName); - return query.getWhereClause(); - } - refColName = null; - } - - // Simple Query. - if (getField(colName) != null) - { - log.fine("Field Found: " + colName); - return query.getWhereClause(); - } - - // Find Refernce Column e.g. BillTo_ID -> C_BPartner_Location_ID - String sql = "SELECT cc.ColumnName " - + "FROM AD_Column c" - + " INNER JOIN AD_Ref_Table r ON (c.AD_Reference_Value_ID=r.AD_Reference_ID)" - + " INNER JOIN AD_Column cc ON (r.AD_Key=cc.AD_Column_ID) " - + "WHERE c.AD_Reference_ID IN (18,30)" // Table/Search - + " AND c.ColumnName=?"; - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setString(1, colName); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - refColName = rs.getString(1); - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, "(ref) - Column=" + colName, e); - return query.getWhereClause(); - } - // Reference Column found - if (refColName != null) - { - query.setColumnName(0, refColName); - if (getField(refColName) != null) - { - log.fine("Column " + colName + " replaced with " + refColName); - return query.getWhereClause(); - } - colName = refColName; - } - - // Column NOT in Tab - create EXISTS subquery - String tableName = null; - String tabKeyColumn = getKeyColumnName(); - // Column=SalesRep_ID, Key=AD_User_ID, Query=SalesRep_ID=101 - - sql = "SELECT t.TableName " - + "FROM AD_Column c" - + " INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID) " - + "WHERE c.ColumnName=? AND IsKey='Y'" // #1 Link Column - + " AND EXISTS (SELECT * FROM AD_Column cc" - + " WHERE cc.AD_Table_ID=t.AD_Table_ID AND cc.ColumnName=?)"; // #2 Tab Key Column - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setString(1, colName); - pstmt.setString(2, tabKeyColumn); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - tableName = rs.getString(1); - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, "Column=" + colName + ", Key=" + tabKeyColumn, e); - return null; - } - - // Special Reference Handling - if (tabKeyColumn.equals("AD_Reference_ID")) - { - // Column=AccessLevel, Key=AD_Reference_ID, Query=AccessLevel='6' - sql = "SELECT AD_Reference_ID FROM AD_Column WHERE ColumnName=?"; - int AD_Reference_ID = DB.getSQLValue(null, sql, colName); - return "AD_Reference_ID=" + AD_Reference_ID; - } - - // Causes could be functions in query - // e.g. Column=UPPER(Name), Key=AD_Element_ID, Query=UPPER(AD_Element.Name) LIKE '%CUSTOMER%' - if (tableName == null) - { - log.info ("Not successfull - Column=" - + colName + ", Key=" + tabKeyColumn - + ", Query=" + query); - return query.getWhereClause(); - } - - query.setTableName("xx"); - StringBuffer result = new StringBuffer ("EXISTS (SELECT * FROM ") - .append(tableName).append(" xx WHERE ") - .append(query.getWhereClause(true)) - .append(" AND xx.").append(tabKeyColumn).append("=") - .append(getTableName()).append(".").append(tabKeyColumn).append(")"); - log.fine(result.toString()); - return result.toString(); - } // validateQuery - - - /************************************************************************** - * Refresh all data - */ - public void dataRefreshAll () - { - log.fine("#" + m_vo.TabNo); - /** @todo does not work with alpha key */ - int keyNo = m_mTable.getKeyID(m_currentRow); - m_mTable.dataRefreshAll(); - // Should use RowID - not working for tables with multiple keys - if (keyNo != -1) - { - if (keyNo != m_mTable.getKeyID(m_currentRow)) // something changed - { - int size = getRowCount(); - for (int i = 0; i < size; i++) - { - if (keyNo == m_mTable.getKeyID(i)) - { - m_currentRow = i; - break; - } - } - } - } - setCurrentRow(m_currentRow, true); - } // dataRefreshAll - - /** - * Refresh current row data - */ - public void dataRefresh () - { - dataRefresh (m_currentRow); - } // dataRefresh - - /** - * Refresh row data - * @param row index - */ - public void dataRefresh (int row) - { - log.fine("#" + m_vo.TabNo + " - row=" + row); - m_mTable.dataRefresh(row); - setCurrentRow(row, true); - } // dataRefresh - - - /************************************************************************** - * Uncoditionally Save data - * @param manualCmd if true, no vetoable PropertyChange will be fired for save confirmation from MTable - * @return true if save complete (or nor required) - */ - public boolean dataSave(boolean manualCmd) - { - log.fine("#" + m_vo.TabNo + " - row=" + m_currentRow); - try - { - boolean retValue = (m_mTable.dataSave(manualCmd) == GridTable.SAVE_OK); - if (manualCmd) - setCurrentRow(m_currentRow, false); - return retValue; - } - catch (Exception e) - { - log.log(Level.SEVERE, "#" + m_vo.TabNo + " - row=" + m_currentRow, e); - } - return false; - } // dataSave - - - /** - * Do we need to Save? - * @param rowChange row change - * @param onlyRealChange if true the value of a field was actually changed - * (e.g. for new records, which have not been changed) - default false - * @return true it needs to be saved - */ - public boolean needSave (boolean rowChange, boolean onlyRealChange) - { - if (rowChange) - { - return m_mTable.needSave(-2, onlyRealChange); - } - else - { - if (onlyRealChange) - return m_mTable.needSave(); - else - return m_mTable.needSave(onlyRealChange); - } - } // isDataChanged - - /** - * Ignore data changes - */ - public void dataIgnore() - { - log.fine("#" + m_vo.TabNo); - m_mTable.dataIgnore(); - setCurrentRow(m_currentRow, false); // re-load data - log.fine("#" + m_vo.TabNo + "- fini"); - } // dataIgnore - - - /** - * Create (copy) new Row - * and process Callouts - * @param copy copy - * @return true if copied/new - */ - public boolean dataNew (boolean copy) - { - log.fine("#" + m_vo.TabNo); - if (!isInsertRecord()) - { - log.warning ("Inset Not allowed in TabNo=" + m_vo.TabNo); - return false; - } - // Prevent New Where Main Record is processed - if (m_vo.TabNo > 0) - { - boolean processed = "Y".equals(Env.getContext(m_vo.ctx, m_vo.WindowNo, "Processed")); - // boolean active = "Y".equals(Env.getContext(m_vo.ctx, m_vo.WindowNo, "IsActive")); - if (processed) - { - log.warning ("Not allowed in TabNo=" + m_vo.TabNo + " -> Processed=" + processed); - return false; - } - log.finest("Processed=" + processed); - } - boolean retValue = m_mTable.dataNew (m_currentRow, copy); - if (!retValue) - return retValue; - setCurrentRow(m_currentRow + 1, true); - // process all Callouts (no dependency check - assumed that settings are valid) - for (int i = 0; i < getFieldCount(); i++) - processCallout(getField(i)); - // check validity of defaults - for (int i = 0; i < getFieldCount(); i++) - { - getField(i).refreshLookup(); - getField(i).validateValue(); - } - m_mTable.setChanged(false); - return retValue; - } // dataNew - - /** - * Delete current Row - * @return true if deleted - */ - public boolean dataDelete() - { - log.fine("#" + m_vo.TabNo + " - row=" + m_currentRow); - boolean retValue = m_mTable.dataDelete(m_currentRow); - setCurrentRow(m_currentRow, true); - return retValue; - } // dataDelete - - - /** - * Get Name of Tab - * @return name - */ - public String getName() - { - return m_vo.Name; - } // getName - - /** - * Get Description of Tab - * @return description - */ - public String getDescription() - { - return m_vo.Description; - } // getDescription - - /** - * Get Help of Tab - * @return help - */ - public String getHelp() - { - return m_vo.Help; - } // getHelp - - /** - * Get Tab Level - * @return tab level - */ - public int getTabLevel() - { - return m_vo.TabLevel; - } // getTabLevel - - /** - * Get Commit Warning - * @return commit warning - */ - public String getCommitWarning() - { - return m_vo.CommitWarning; - } // getCommitWarning - - /** - * Return Table Model - * @return MTable - */ - protected GridTable getMTable() - { - return m_mTable; - } // getMTable - - /** - * Return the name of the key column - may be "" - * @return key column name - */ - public String getKeyColumnName() - { - return m_keyColumnName; - } // getKeyColumnName - - /** - * Return Name of link column - * @return link column name - */ - public String getLinkColumnName() - { - return m_linkColumnName; - } // getLinkColumnName - - /** - * Set Name of link column. - * Set from MWindow.loadTabData - * Used in MTab.isCurreny, (.setCurrentRow) .query - APanel.cmd_report - * and MField.isEditable and .isDefault via context - * @param linkColumnName name of column - or sets name to AD_Column_ID, if exists - */ - public void setLinkColumnName (String linkColumnName) - { - if (linkColumnName != null) - m_linkColumnName = linkColumnName; - else - { - if (m_vo.AD_Column_ID == 0) - return; - // we have a link column identified (primary parent column) - else - { - String SQL = "SELECT ColumnName FROM AD_Column WHERE AD_Column_ID=?"; - try - { - PreparedStatement pstmt = DB.prepareStatement(SQL, null); - pstmt.setInt(1, m_vo.AD_Column_ID); // Parent Link Column - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - m_linkColumnName = rs.getString(1); - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, "", e); - } - log.fine("AD_Column_ID=" + m_vo.AD_Column_ID + " - " + m_linkColumnName); - } - } - Env.setContext(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, "LinkColumnName", m_linkColumnName); - } // setLinkColumnName - - /** - * Is the tab current?. - *
-	 *	Yes 	- Table must be open
-	 *			- Query String is the same
-	 *			- Not Detail
-	 *			- Old link column value is same as current one
-	 *  
- * @return true if current - */ - public boolean isCurrent() - { - // Open? - if (!m_mTable.isOpen()) - return false; - // Same Query - if (!m_oldQuery.equals(m_query.getWhereClause())) - return false; - // Detail? - if (!isDetail()) - return true; - // Same link column value - String value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getLinkColumnName()); - return m_linkValue.equals(value); - } // isCurrent - - /** - * Is the tab/table currently open - * @return true if open - */ - public boolean isOpen() - { - // Open? - if (m_mTable != null) - return m_mTable.isOpen(); - return false; - } // isCurrent - - - /** - * Is Tab Incluced in other Tab - * @return true if included - */ - public boolean isIncluded() - { - return m_included; - } // isIncluded - - /** - * Is Tab Incluced in other Tab - * @param isIncluded true if included - */ - public void setIncluded(boolean isIncluded) - { - m_included = isIncluded; - } // setIncluded - - /** - * Are Only Current Rows displayed - * @return true if no history - */ - public boolean isOnlyCurrentRows() - { - return m_vo.onlyCurrentRows; - } // isOnlyCurrentRows - /** - * Return Parent ArrayList - * @return parent column names - */ - public ArrayList getParentColumnNames() - { - return m_parents; - } // getParentColumnNames - - /** - * Get Tree ID of this tab - * @return ID - */ - private int getTreeID() - { - log.fine(m_vo.TableName); - String SQL = "SELECT * FROM AD_ClientInfo WHERE AD_Client=" - + Env.getContext(m_vo.ctx, m_vo.WindowNo, "AD_Client_ID") - + " ORDER BY AD_Org DESC"; - // - if (m_vo.TableName.equals("AD_Menu")) - return 10; // MM - else if (m_vo.TableName.equals("C_ElementValue")) - return 20; // EV - else if (m_vo.TableName.equals("M_Product")) - return 30; // PR - else if (m_vo.TableName.equals("C_BPartner")) - return 40; // BP - else if (m_vo.TableName.equals("AD_Org")) - return 50; // OO - else if (m_vo.TableName.equals("C_Project")) - return 60; // PJ - return 0; - } // getTreeID - - /** - * Returns true if this is a detail record - * @return true if not parent tab - */ - public boolean isDetail() - { - // We have IsParent columns and/or a link column - if (m_parents.size() > 0 || m_vo.AD_Column_ID != 0) - return true; - return false; - } // isDetail - - /** - * Is Printed (Document can be printed) - * @return true if printing - */ - public boolean isPrinted() - { - return m_vo.AD_Process_ID != 0; - } // isPrinted - - /** - * Get WindowNo - * @return window no - */ - public int getWindowNo() - { - return m_vo.WindowNo; - } // getWindowNo - - /** - * Get TabNo - * @return tab no - */ - public int getTabNo() - { - return m_vo.TabNo; - } // getTabNo - - /** - * Get Process ID - * @return Process ID - */ - public int getAD_Process_ID() - { - return m_vo.AD_Process_ID; - } // getAD_Process_ID - - /** - * Is High Volume? - * @return true if high volumen table - */ - public boolean isHighVolume() - { - return m_vo.IsHighVolume; - } // isHighVolume - - /** - * Is Read Only? - * @return true if read only - */ - public boolean isReadOnly() - { - if (m_vo.IsReadOnly) - return true; - - // no restrictions - if (m_vo.ReadOnlyLogic == null || m_vo.ReadOnlyLogic.equals("")) - return m_vo.IsReadOnly; - - // ** dynamic content ** uses get_ValueAsString - boolean retValue = Evaluator.evaluateLogic(this, m_vo.ReadOnlyLogic); - log.finest(m_vo.Name - + " (" + m_vo.ReadOnlyLogic + ") => " + retValue); - return retValue; - } // isReadOnly - - /** - * Tab contains Always Update Field - * @return true if field with always updateable - */ - public boolean isAlwaysUpdateField() - { - for (int i = 0; i < m_mTable.getColumnCount(); i++) - { - GridField field = m_mTable.getField(i); - if (field.isAlwaysUpdateable()) - return true; - } - return false; - } // isAlwaysUpdateField - - /** - * Can we Insert Records? - * @return true not read only and allowed - */ - public boolean isInsertRecord() - { - if (isReadOnly()) - return false; - return m_vo.IsInsertRecord; - } // isInsertRecord - - /** - * Is the Tab Visible. - * Called when constructing the window. - * @return true, if displayed - */ - public boolean isDisplayed () - { - // no restrictions - String dl = m_vo.DisplayLogic; - if (dl == null || dl.equals("")) - return true; - - // ** dynamic content ** - String parsed = Env.parseContext (m_vo.ctx, 0, dl, false, false).trim(); - if (parsed.length() == 0) - return true; - boolean retValue = Evaluator.evaluateLogic(this, dl); - log.config(m_vo.Name + " (" + dl + ") => " + retValue); - return retValue; - } // isDisplayed - - /** - * Get Variable Value (Evaluatee) - * @param variableName name - * @return value - */ - public String get_ValueAsString (String variableName) - { - return Env.getContext (m_vo.ctx, m_vo.WindowNo, variableName, true); - } // get_ValueAsString - - /** - * Is Single Row - * @return true if single row - */ - public boolean isSingleRow() - { - return m_vo.IsSingleRow; - } // isSingleRow; - - /** - * Set Single Row. - * Temporary store of current value - * @param isSingleRow toggle - */ - public void setSingleRow (boolean isSingleRow) - { - m_vo.IsSingleRow = isSingleRow; - } // setSingleRow - - - /** - * Has Tree - * @return true if tree exists - */ - public boolean isTreeTab() - { - return m_vo.HasTree; - } // isTreeTab - - /** - * Get Tab ID - * @return Tab ID - */ - public int getAD_Tab_ID() - { - return m_vo.AD_Tab_ID; - } // getAD_Tab_ID - - /** - * Get Table ID - * @return Table ID - */ - public int getAD_Table_ID() - { - return m_vo.AD_Table_ID; - } // getAD_Table_ID - - /** - * Get Window ID - * @return Window ID - */ - public int getAD_Window_ID() - { - return m_vo.AD_Window_ID; - } // getAD_Window_ID - - /** - * Get Included Tab ID - * @return Included_Tab_ID - */ - public int getIncluded_Tab_ID() - { - return m_vo.Included_Tab_ID; - } // getIncluded_Tab_ID - - /** - * Get TableName - * @return Table Name - */ - public String getTableName() - { - return m_vo.TableName; - } // getTableName - - /** - * Get Tab Where Clause - * @return where clause - */ - public String getWhereClause() - { - return m_vo.WhereClause; - } // getWhereClause - - /** - * Is Sort Tab - * @return true if sort tab - */ - public boolean isSortTab() - { - return m_vo.IsSortTab; - } // isSortTab - - /** - * Get Order column for sort tab - * @return AD_Column_ID - */ - public int getAD_ColumnSortOrder_ID() - { - return m_vo.AD_ColumnSortOrder_ID; - } // getAD_ColumnSortOrder_ID - - /** - * Get Yes/No column for sort tab - * @return AD_Column_ID - */ - public int getAD_ColumnSortYesNo_ID() - { - return m_vo.AD_ColumnSortYesNo_ID; - } // getAD_ColumnSortYesNo_ID - - - /************************************************************************** - * Get extended Where Clause (parent link) - * @return parent link - */ - public String getWhereExtended() - { - return m_extendedWhere; - } // getWhereExtended - - /** - * Get Order By Clause - * @param onlyCurrentRows only current rows - * @return Order By Clause - */ - private String getOrderByClause(boolean onlyCurrentRows) - { - // First Prio: Tab Order By - if (m_vo.OrderByClause.length() > 0) - return m_vo.OrderByClause; - - // Second Prio: Fields (save it) - m_vo.OrderByClause = ""; - for (int i = 0; i < 3; i++) - { - String order = m_OrderBys[i]; - if (order != null && order.length() > 0) - { - if (m_vo.OrderByClause.length() > 0) - m_vo.OrderByClause += ","; - m_vo.OrderByClause += order; - } - } - if (m_vo.OrderByClause.length() > 0) - return m_vo.OrderByClause; - - // Third Prio: onlyCurrentRows - m_vo.OrderByClause = "Created"; - if (onlyCurrentRows && !isDetail()) // first tab only - m_vo.OrderByClause += " DESC"; - return m_vo.OrderByClause; - } // getOrderByClause - - - /************************************************************************** - * Transaction support. - * Depending on Table returns transaction info - * @return info - */ - public String getTrxInfo() - { - // InvoiceBatch - if (m_vo.TableName.startsWith("C_InvoiceBatch")) - { - int Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "C_InvoiceBatch_ID"); - log.fine(m_vo.TableName + " - " + Record_ID); - MessageFormat mf = null; - try - { - mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "InvoiceBatchSummary")); - } - catch (Exception e) - { - log.log(Level.SEVERE, "InvoiceBatchSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "InvoiceBatchSummary"), e); - } - if (mf == null) - return " "; - /********************************************************************** - * ** Message: ExpenseSummary ** - * {0} Line(s) {1,number,#,##0.00} - Total: {2,number,#,##0.00} - * - * {0} - Number of lines - * {1} - Toral - * {2} - Currency - */ - Object[] arguments = new Object[3]; - boolean filled = false; - // - String sql = "SELECT COUNT(*), NVL(SUM(LineNetAmt),0), NVL(SUM(LineTotalAmt),0) " - + "FROM C_InvoiceBatchLine " - + "WHERE C_InvoiceBatch_ID=? AND IsActive='Y'"; - // - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, Record_ID); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - { - // {0} - Number of lines - Integer lines = new Integer(rs.getInt(1)); - arguments[0] = lines; - // {1} - Line net - Double net = new Double(rs.getDouble(2)); - arguments[1] = net; - // {2} - Line net - Double total = new Double(rs.getDouble(3)); - arguments[2] = total; - filled = true; - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, m_vo.TableName + "\nSQL=" + sql, e); - } - if (filled) - return mf.format (arguments); - return " "; - } // InvoiceBatch - - // Order || Invoice - else if (m_vo.TableName.startsWith("C_Order") || m_vo.TableName.startsWith("C_Invoice")) - { - int Record_ID; - boolean isOrder = m_vo.TableName.startsWith("C_Order"); - // - StringBuffer sql = new StringBuffer("SELECT COUNT(*) AS Lines,c.ISO_Code,o.TotalLines,o.GrandTotal," - + "currencyBase(o.GrandTotal,o.C_Currency_ID,o.DateAcct, o.AD_Client_ID,o.AD_Org_ID) AS ConvAmt "); - if (isOrder) - { - Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "C_Order_ID"); - sql.append("FROM C_Order o" - + " INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)" - + " INNER JOIN C_OrderLine l ON (o.C_Order_ID=l.C_Order_ID) " - + "WHERE o.C_Order_ID=? "); - } - else - { - Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "C_Invoice_ID"); - sql.append("FROM C_Invoice o" - + " INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)" - + " INNER JOIN C_InvoiceLine l ON (o.C_Invoice_ID=l.C_Invoice_ID) " - + "WHERE o.C_Invoice_ID=? "); - } - sql.append("GROUP BY o.C_Currency_ID, c.ISO_Code, o.TotalLines, o.GrandTotal, o.DateAcct, o.AD_Client_ID, o.AD_Org_ID"); - - log.fine(m_vo.TableName + " - " + Record_ID); - MessageFormat mf = null; - try - { - mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "OrderSummary")); - } - catch (Exception e) - { - log.log(Level.SEVERE, "OrderSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "OrderSummary"), e); - } - if (mf == null) - return " "; - /********************************************************************** - * ** Message: OrderSummary ** - * {0} Line(s) - {1,number,#,##0.00} - Toral: {2,number,#,##0.00} {3} = {4,number,#,##0.00} - * - * {0} - Number of lines - * {1} - Line toral - * {2} - Grand total (including tax, etc.) - * {3} - Currency - * (4) - Grand total converted to local currency - */ - Object[] arguments = new Object[5]; - boolean filled = false; - // - try - { - PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null); - pstmt.setInt(1, Record_ID); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - { - // {0} - Number of lines - Integer lines = new Integer(rs.getInt(1)); - arguments[0] = lines; - // {1} - Line toral - Double lineTotal = new Double(rs.getDouble(3)); - arguments[1] = lineTotal; - // {2} - Grand total (including tax, etc.) - Double grandTotal = new Double(rs.getDouble(4)); - arguments[2] = grandTotal; - // {3} - Currency - String currency = rs.getString(2); - arguments[3] = currency; - // (4) - Grand total converted to Euro - Double grandEuro = new Double(rs.getDouble(5)); - arguments[4] = grandEuro; - filled = true; - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, m_vo.TableName + "\nSQL=" + sql, e); - } - if (filled) - return mf.format (arguments); - return " "; - } // Order || Invoice - - // Expense Report - else if (m_vo.TableName.startsWith("S_TimeExpense") && m_vo.TabNo == 0) - { - int Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "S_TimeExpense_ID"); - log.fine(m_vo.TableName + " - " + Record_ID); - MessageFormat mf = null; - try - { - mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "ExpenseSummary")); - } - catch (Exception e) - { - log.log(Level.SEVERE, "ExpenseSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "ExpenseSummary"), e); - } - if (mf == null) - return " "; - /********************************************************************** - * ** Message: ExpenseSummary ** - * {0} Line(s) - Total: {1,number,#,##0.00} {2} - * - * {0} - Number of lines - * {1} - Toral - * {2} - Currency - */ - Object[] arguments = new Object[3]; - boolean filled = false; - // - String SQL = "SELECT COUNT(*) AS Lines, SUM(ConvertedAmt*Qty) " - + "FROM S_TimeExpenseLine " - + "WHERE S_TimeExpense_ID=?"; - - // - try - { - PreparedStatement pstmt = DB.prepareStatement(SQL, null); - pstmt.setInt(1, Record_ID); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - { - // {0} - Number of lines - Integer lines = new Integer(rs.getInt(1)); - arguments[0] = lines; - // {1} - Line toral - Double total = new Double(rs.getDouble(2)); - arguments[1] = total; - // {3} - Currency - arguments[2] = " "; - filled = true; - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, m_vo.TableName + "\nSQL=" + SQL, e); - } - if (filled) - return mf.format (arguments); - return " "; - } // S_TimeExpense - - - // Default - No Trx Info - return null; - } // getTrxInfo - - /** - * Load Dependant Information - */ - private void loadDependentInfo() - { - /** - * Load Order Type from C_DocTypeTarget_ID - */ - if (m_vo.TableName.equals("C_Order")) - { - int C_DocTyp_ID = 0; - Integer target = (Integer)getValue("C_DocTypeTarget_ID"); - if (target != null) - C_DocTyp_ID = target.intValue(); - if (C_DocTyp_ID == 0) - return; - - String sql = "SELECT DocSubTypeSO FROM C_DocType WHERE C_DocType_ID=?"; - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, C_DocTyp_ID); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - Env.setContext(m_vo.ctx, m_vo.WindowNo, "OrderType", rs.getString(1)); - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - } - } // loadOrderInfo - } // loadDependentInfo - - - /************************************************************************** - * Load Attachments for this table - */ - public void loadAttachments() - { - log.fine("#" + m_vo.TabNo); - if (!canHaveAttachment()) - return; - - String SQL = "SELECT AD_Attachment_ID, Record_ID FROM AD_Attachment " - + "WHERE AD_Table_ID=?"; - try - { - if (m_Attachments == null) - m_Attachments = new HashMap(); - else - m_Attachments.clear(); - PreparedStatement pstmt = DB.prepareStatement(SQL, null); - pstmt.setInt(1, m_vo.AD_Table_ID); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) - { - Integer key = new Integer(rs.getInt(2)); - Integer value = new Integer(rs.getInt(1)); - m_Attachments.put(key, value); - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, "loadAttachments", e); - } - log.config("#" + m_Attachments.size()); - } // loadAttachment - - /** - * Can this tab have Attachments?. - *

- * It can have an attachment if it has a key column ending with _ID. - * The key column is empty, if there is no single identifying key. - * @return true if record can have attachment - */ - public boolean canHaveAttachment() - { - if (getKeyColumnName().endsWith("_ID")) - return true; - return false; - } // canHaveAttachment - - /** - * Returns true, if current row has an Attachment - * @return true if record has attchment - */ - public boolean hasAttachment() - { - if (m_Attachments == null) - loadAttachments(); - if (m_Attachments == null || m_Attachments.isEmpty()) - return false; - // - Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); - return m_Attachments.containsKey(key); - } // hasAttachment - - /** - * Get Attachment_ID for current record. - * @return ID or 0, if not found - */ - public int getAD_AttachmentID() - { - if (m_Attachments == null) - loadAttachments(); - if (m_Attachments.isEmpty()) - return 0; - // - Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); - Integer value = (Integer)m_Attachments.get(key); - if (value == null) - return 0; - else - return value.intValue(); - } // getAttachmentID - - /************************************************************************** - * Load Chats for this table - */ - public void loadChats() - { - log.fine("#" + m_vo.TabNo); - if (!canHaveAttachment()) - return; - - String sql = "SELECT CM_Chat_ID, Record_ID FROM CM_Chat " - + "WHERE AD_Table_ID=?"; - try - { - if (m_Chats == null) - m_Chats = new HashMap(); - else - m_Chats.clear(); - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, m_vo.AD_Table_ID); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) - { - Integer key = new Integer(rs.getInt(2)); // Record_ID - Integer value = new Integer(rs.getInt(1)); // CM_Chat_ID - m_Chats.put(key, value); - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - } - log.config("#" + m_Chats.size()); - } // loadChats - - /** - * Returns true, if current row has a Chat - * @return true if record has chat - */ - public boolean hasChat() - { - if (m_Chats == null) - loadChats(); - if (m_Chats == null || m_Chats.isEmpty()) - return false; - // - Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); - return m_Chats.containsKey(key); - } // hasChat - - /** - * Get Chat_ID for this record. - * @return ID or 0, if not found - */ - public int getCM_ChatID() - { - if (m_Chats == null) - loadChats(); - if (m_Chats.isEmpty()) - return 0; - // - Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); - Integer value = (Integer)m_Chats.get(key); - if (value == null) - return 0; - else - return value.intValue(); - } // getCM_ChatID - - - /************************************************************************** - * Load Locks for Table and User - */ - public void loadLocks() - { - int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID"); - log.fine("#" + m_vo.TabNo + " - AD_User_ID=" + AD_User_ID); - if (!canHaveAttachment()) - return; - - String sql = "SELECT Record_ID " - + "FROM AD_Private_Access " - + "WHERE AD_User_ID=? AND AD_Table_ID=? AND IsActive='Y' " - + "ORDER BY Record_ID"; - try - { - if (m_Lock == null) - m_Lock = new ArrayList(); - else - m_Lock.clear(); - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, AD_User_ID); - pstmt.setInt(2, m_vo.AD_Table_ID); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) - { - Integer key = new Integer(rs.getInt(1)); - m_Lock.add(key); - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - } - log.fine("#" + m_Lock.size()); - } // loadLooks - - /** - * Record Is Locked - * @return true if locked - */ - public boolean isLocked() - { - if (!MRole.getDefault(m_vo.ctx, false).isPersonalLock()) - return false; - if (m_Lock == null) - loadLocks(); - if (m_Lock == null || m_Lock.isEmpty()) - return false; - // - Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); - return m_Lock.contains(key); - } // isLocked - - /** - * Lock Record - * @param ctx context - * @param Record_ID id - * @param lock true if lock, otherwise unlock - */ - public void lock (Properties ctx, int Record_ID, boolean lock) - { - int AD_User_ID = Env.getContextAsInt(ctx, "#AD_User_ID"); - log.fine("Lock=" + lock + ", AD_User_ID=" + AD_User_ID - + ", AD_Table_ID=" + m_vo.AD_Table_ID + ", Record_ID=" + Record_ID); - MPrivateAccess access = MPrivateAccess.get (ctx, AD_User_ID, m_vo.AD_Table_ID, Record_ID); - if (access == null) - access = new MPrivateAccess (ctx, AD_User_ID, m_vo.AD_Table_ID, Record_ID); - access.setIsActive(lock); - access.save(); - // - loadLocks(); - } // lock - - - /************************************************************************** - * Data Status Listener from MTable. - * - get raw info and add current row information - * - update the current row - * - redistribute (fire) Data Status event - * @param e event - */ - public void dataStatusChanged (DataStatusEvent e) - { - log.fine("#" + m_vo.TabNo + " - " + e.toString()); - int oldCurrentRow = e.getCurrentRow(); - m_DataStatusEvent = e; // save it - // when sorted set current row to 0 - String msg = m_DataStatusEvent.getAD_Message(); - if (msg != null && msg.equals("Sorted")) - setCurrentRow(0, true); - // set current row - m_DataStatusEvent.setCurrentRow(m_currentRow); - // Same row - update value - if (oldCurrentRow == m_currentRow) - { - GridField field = m_mTable.getField(e.getChangedColumn()); - if (field != null) - { - Object value = m_mTable.getValueAt(m_currentRow, e.getChangedColumn()); - field.setValue(value, m_mTable.isInserting()); - } - } - else // Redistribute Info with current row info - fireDataStatusChanged(m_DataStatusEvent); - // log.fine("dataStatusChanged #" + m_vo.TabNo + "- fini", e.toString()); - } // dataStatusChanged - - /** - * Inform Listeners and build WHO info - * @param e event - */ - private void fireDataStatusChanged (DataStatusEvent e) - { - DataStatusListener[] listeners = m_listenerList.getListeners(DataStatusListener.class); - if (listeners.length == 0) - return; - log.fine(e.toString()); - // WHO Info - if (e.getCurrentRow() >= 0) - { - e.Created = (Timestamp)getValue("Created"); - e.CreatedBy = (Integer)getValue("CreatedBy"); - e.Updated = (Timestamp)getValue("Updated"); - e.UpdatedBy = (Integer)getValue("UpdatedBy"); - e.Record_ID = getValue(m_keyColumnName); - // Info - StringBuffer info = new StringBuffer(getTableName()); - // We have a key column - if (m_keyColumnName != null && m_keyColumnName.length() > 0) - { - info.append(" - ") - .append(m_keyColumnName).append("=").append(e.Record_ID); - } - else // we have multiple parents - { - for (int i = 0; i < m_parents.size(); i++) - { - String keyCol = (String)m_parents.get(i); - info.append(" - ") - .append(keyCol).append("=").append(getValue(keyCol)); - } - } - e.Info = info.toString(); - } - e.setInserting(m_mTable.isInserting()); - // Distribute/fire it - for (int i = 0; i < listeners.length; i++) - listeners[i].dataStatusChanged(e); - // log.fine("fini - " + e.toString()); - } // fireDataStatusChanged - - /** - * Create and fire Data Status Error Event - * @param AD_Message message - * @param info info - * @param isError if not true, it is a Warning - */ - protected void fireDataStatusEEvent(String AD_Message, String info, boolean isError) - { - m_mTable.fireDataStatusEEvent(AD_Message, info, isError); - } // fireDataStatusEvent - - /** - * Create and fire Data Status Error Event (from Error Log) - * @param errorLog log - */ - protected void fireDataStatusEEvent (ValueNamePair errorLog) - { - if (errorLog != null) - m_mTable.fireDataStatusEEvent(errorLog); - } // fireDataStatusEvent - - /** - * Get Current Row - * @return current row - */ - public int getCurrentRow() - { - if (m_currentRow != verifyRow(m_currentRow)) - setCurrentRow(m_mTable.getRowCount()-1, true); - return m_currentRow; - } // getCurrentRow - - /** - * Get Current Table Key ID - * @return Record_ID - */ - public int getRecord_ID() - { - return m_mTable.getKeyID(m_currentRow); - } // getRecord_ID - - /** - * Get Key ID of row - * @param row row number - * @return The Key ID of the row or -1 if not found - */ - public int getKeyID (int row) - { - return m_mTable.getKeyID (row); - } // getCurrentKeyID - - /** - * Navigate absolute - goto Row - (zero based). - * - does nothing, if in current row - * - saves old row if required - * @param targetRow target row - * @return current row - */ - public int navigate (int targetRow) - { - // nothing to do - if (targetRow == m_currentRow) - return m_currentRow; - log.info ("Row=" + targetRow); - - // Row range check - int newRow = verifyRow(targetRow); - - // Check, if we have old uncommitted data - m_mTable.dataSave(newRow, false); - - // new position - return setCurrentRow(newRow, true); - } // navigate - - /** - * Navigate relatively - i.e. plus/minus from current position - * @param rowChange row change - * @return current row - */ - public int navigateRelative (int rowChange) - { - return navigate (m_currentRow + rowChange); - } // navigateRelative - - /** - * Navigate to current now (reload) - * @return current row - */ - public int navigateCurrent() - { - log.info("Row=" + m_currentRow); - return setCurrentRow(m_currentRow, true); - } // navigateCurrent - - /** - * Row Range check - * @param targetRow target row - * @return checked row - */ - private int verifyRow (int targetRow) - { - int newRow = targetRow; - // Table Open? - if (!m_mTable.isOpen()) - { - log.severe ("Table not open"); - return -1; - } - // Row Count - int rows = getRowCount(); - if (rows == 0) - { - log.fine("No Rows"); - return -1; - } - if (newRow >= rows) - { - newRow = rows-1; - log.fine("Set to max Row: " + newRow); - } - else if (newRow < 0) - { - newRow = 0; - log.fine("Set to first Row"); - } - return newRow; - } // verifyRow - - /** - * Set current row and load data into fields. - * If there is no row - load nulls - * @param newCurrentRow new current row - * @param fireEvents fire events - * @return current row - */ - private int setCurrentRow (int newCurrentRow, boolean fireEvents) - { - int oldCurrentRow = m_currentRow; - m_currentRow = verifyRow (newCurrentRow); - log.fine("Row=" + m_currentRow + " - fire=" + fireEvents); - - // Update Field Values - int size = m_mTable.getColumnCount(); - for (int i = 0; i < size; i++) - { - GridField mField = m_mTable.getField(i); - // get Value from Table - if (m_currentRow >= 0) - { - Object value = m_mTable.getValueAt(m_currentRow, i); - mField.setValue(value, m_mTable.isInserting()); - if (m_mTable.isInserting()) // set invalid values to null - mField.validateValue(); - } - else - { // no rows - set to a reasonable value - not updateable -// Object value = null; -// if (mField.isKey() || mField.isParent() || mField.getColumnName().equals(m_linkColumnName)) -// value = mField.getDefault(); - mField.setValue(); - } - } - loadDependentInfo(); - - if (!fireEvents) // prevents informing twice - return m_currentRow; - - // inform VTable/.. -> rowChanged - m_propertyChangeSupport.firePropertyChange(PROPERTY, oldCurrentRow, m_currentRow); - - // inform APanel/.. -> dataStatus with row updated - if (m_DataStatusEvent == null) - m_DataStatusEvent = new DataStatusEvent(this, getRowCount(), - m_mTable.isInserting(), // changed - Env.isAutoCommit(Env.getCtx(), m_vo.WindowNo), m_mTable.isInserting()); - // - m_DataStatusEvent.setCurrentRow(m_currentRow); - String status = m_DataStatusEvent.getAD_Message(); - if (status == null || status.length() == 0) - m_DataStatusEvent.setInfo("NavigateOrUpdate", null, false,false); - fireDataStatusChanged(m_DataStatusEvent); - return m_currentRow; - } // setCurrentRow - - - /** - * Set current row - used for deleteSelection - * @return current row - */ - public void setCurrentRow(int row){ - setCurrentRow(row, false); - } - - - /************************************************************************** - * Get RowCount - * @return row count - */ - public int getRowCount() - { - int count = m_mTable.getRowCount(); - // Wait a bit if currently loading - if (count == 0 && m_mTable.isLoading()) - { - try - { - Thread.sleep(100); // .1 sec - } - catch (Exception e) {} - count = m_mTable.getRowCount(); - } - return count; - } // getRowCount - - /** - * Get Column/Field Count - * @return field count - */ - public int getFieldCount() - { - return m_mTable.getColumnCount(); - } // getFieldCount - - /** - * Get Field by index - * @param index index - * @return MField - */ - public GridField getField (int index) - { - return m_mTable.getField(index); - } // getField - - /** - * Get Field by DB column name - * @param columnName column name - * @return MField - */ - public GridField getField (String columnName) - { - return m_mTable.getField(columnName); - } // getField - - /** - * Get all Fields - * @return MFields - */ - public GridField[] getFields () - { - return m_mTable.getFields(); - } // getField - - /** - * Set New Value & call Callout - * @param columnName database column name - * @param value value - * @return error message or "" - */ - public String setValue (String columnName, Object value) - { - if (columnName == null) - return "NoColumn"; - return setValue(m_mTable.getField(columnName), value); - } // setValue - - /** - * Set New Value & call Callout - * @param field field - * @param value value - * @return error message or "" - */ - public String setValue (GridField field, Object value) - { - if (field == null) - return "NoField"; - - log.fine(field.getColumnName() + "=" + value + " - Row=" + m_currentRow); - - int col = m_mTable.findColumn(field.getColumnName()); - m_mTable.setValueAt(value, m_currentRow, col, false); - // - return processFieldChange (field); - } // setValue - - /** - * Is Processed - * @return true if current record is processed - */ - public boolean isProcessed() - { - int index = m_mTable.findColumn("Processed"); - if (index != -1) - { - Object oo = m_mTable.getValueAt(m_currentRow, index); - if (oo instanceof String) - return "Y".equals(oo); - if (oo instanceof Boolean) - return ((Boolean)oo).booleanValue(); - } - return "Y".equals(Env.getContext(m_vo.ctx, m_vo.WindowNo, "Processed")); - } // isProcessed - - /** - * Process Field Change - evaluate Dependencies and process Callouts. - * - * called from MTab.setValue or GridController.dataStatusChanged - * @param changedField changed field - * @return error message or "" - */ - public String processFieldChange (GridField changedField) - { - processDependencies (changedField); - return processCallout (changedField); - } // processFieldChange - - /** - * Evaluate Dependencies - * @param changedField changed field - */ - private void processDependencies (GridField changedField) - { - String columnName = changedField.getColumnName(); - // log.trace(log.l4_Data, "Changed Column", columnName); - - // when column name is not in list of DependentOn fields - fini - if (!hasDependants(columnName)) - return; - - // Get dependent MFields (may be because of display or dynamic lookup) - ArrayList list = getDependantFields(columnName); - for (int i = 0; i < list.size(); i++) - { - GridField dependentField = (GridField)list.get(i); - // log.trace(log.l5_DData, "Dependent Field", dependentField==null ? "null" : dependentField.getColumnName()); - // if the field has a lookup - if (dependentField != null && dependentField.getLookup() instanceof MLookup) - { - MLookup mLookup = (MLookup)dependentField.getLookup(); - // log.trace(log.l6_Database, "Lookup Validation", mLookup.getValidation()); - // if the lookup is dynamic (i.e. contains this columnName as variable) - if (mLookup.getValidation().indexOf("@"+columnName+"@") != -1) - { - log.fine(columnName + " changed - " - + dependentField.getColumnName() + " set to null"); - // invalidate current selection - setValue(dependentField, null); - } - } - } // for all dependent fields - } // processDependencies - - - /************************************************************************** - * Process Callout(s). - *

- * The Callout is in the string of - * "class.method;class.method;" - * If there is no class name, i.e. only a method name, the class is regarded - * as CalloutSystem. - * The class needs to comply with the Interface Callout. - * - * For a limited time, the old notation of Sx_matheod / Ux_menthod is maintained. - * - * @param field field - * @return error message or "" - * @see org.compiere.model.Callout - */ - private String processCallout (GridField field) - { - String callout = field.getCallout(); - if (callout.length() == 0) - return ""; - // - if (isProcessed()) // only active records - return ""; // "DocProcessed"; - - Object value = field.getValue(); - Object oldValue = field.getOldValue(); - log.fine(field.getColumnName() + "=" + value - + " (" + callout + ") - old=" + oldValue); - - StringTokenizer st = new StringTokenizer(callout, ";,", false); - while (st.hasMoreTokens()) // for each callout - { - String cmd = st.nextToken().trim(); - Callout call = null; - String method = null; - int methodStart = cmd.lastIndexOf("."); - try - { - if (methodStart != -1) // no class - { - Class cClass = Class.forName(cmd.substring(0,methodStart)); - call = (Callout)cClass.newInstance(); - method = cmd.substring(methodStart+1); - } - } - catch (Exception e) - { - log.log(Level.SEVERE, "class", e); - return "Callout Invalid: " + cmd + " (" + e.toString() + ")"; - } - - if (call == null || method == null || method.length() == 0) - return "Callout Invalid: " + method; - - String retValue = ""; - try - { - retValue = call.start(m_vo.ctx, method, m_vo.WindowNo, this, field, value, oldValue); - } - catch (Exception e) - { - log.log(Level.SEVERE, "start", e); - retValue = "Callout Invalid: " + e.toString(); - return retValue; - } - if (!retValue.equals("")) // interrupt on first error - { - log.severe (retValue); - return retValue; - } - } // for each callout - return ""; - } // processCallout - - - /** - * Get Value of Field with columnName - * @param columnName column name - * @return value - */ - public Object getValue (String columnName) - { - if (columnName == null) - return null; - GridField field = m_mTable.getField(columnName); - return getValue(field); - } // getValue - - /** - * Get Value of Field - * @param field field - * @return value - */ - public Object getValue (GridField field) - { - if (field == null) - return null; - return field.getValue(); - } // getValue - - /** - * Get Value of Field in row - * @param row row - * @param columnName column name - * @return value - */ - public Object getValue (int row, String columnName) - { - int col = m_mTable.findColumn(columnName); - if (col == -1) - return null; - return m_mTable.getValueAt(row, col); - } // getValue - - public boolean isNeedToSaveParent() - { - if (isDetail()) - return m_parentNeedSave; - else - return false; - } - - /** - * toString - * @return String representation - */ - public String toString() - { - String retValue = "MTab #" + m_vo.TabNo; - if (m_vo != null) - retValue += " " + m_vo.Name + " (" + m_vo.AD_Tab_ID + ")"; - return retValue; - } // toString - - - /************************************************************************** - * @param l listener - */ - public synchronized void removePropertyChangeListener(PropertyChangeListener l) - { - m_propertyChangeSupport.removePropertyChangeListener(l); - } - /** - * @param l listener - */ - public synchronized void addPropertyChangeListener(PropertyChangeListener l) - { - m_propertyChangeSupport.addPropertyChangeListener(l); - } - - /** - * @param l listener - */ - public synchronized void removeDataStatusListener(DataStatusListener l) - { - m_listenerList.remove(DataStatusListener.class, l); - } - /** - * @param l listener - */ - public synchronized void addDataStatusListener(DataStatusListener l) - { - m_listenerList.add(DataStatusListener.class, l); - } - - -} // MTab +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.beans.*; +import java.io.*; +import java.math.BigDecimal; +import java.sql.*; +import java.text.*; +import java.util.*; + +import java.util.logging.*; +import javax.swing.event.*; +import org.compiere.util.*; + +/** + * Tab Model. + * - a combination of AD_Tab (the display attributes) and AD_Table information. + *

+ * The Tab owns also it's Table model + * and listens to data changes to update the Field values. + * + *

+ * The Tab maintains the bound property: CurrentRow + * + *

+ *  Event Hierarchies:
+ *      - dataChanged (from MTable)
+ *          - setCurrentRow
+ *              - Update all Field Values
+ *
+ *      - setValue
+ *          - Update Field Value
+ *          - Callout
+ *  
+ * @author Jorg Janke + * @version $Id: GridTab.java,v 1.10 2006/10/02 05:18:39 jjanke Exp $ + */ +public class GridTab implements DataStatusListener, Evaluatee, Serializable +{ + /** + * Create Tab (Model) from Value Object. + *

+ * MTab provides a property listener for changed rows and a + * DataStatusListener for communicating changes of the underlying data + * @param vo Value Object + */ + public GridTab(GridTabVO vo) + { + m_vo = vo; + // Create MTable + m_mTable = new GridTable (m_vo.ctx, m_vo.AD_Table_ID, m_vo.TableName, m_vo.WindowNo, m_vo.TabNo, true); + m_mTable.setReadOnly(m_vo.IsReadOnly || m_vo.IsView); + m_mTable.setDeleteable(m_vo.IsDeleteable); + // Load Tab + // if (vo.TabNo == 0) + initTab(false); + // else + // { + // m_loader = new Loader(); + // m_loader.setPriority(Thread.MIN_PRIORITY); + // m_loader.start(); + // } + // waitLoadCompete(); + } // GridTab + + /** Value Object */ + private GridTabVO m_vo; + + /** The Table Model for Query */ + private GridTable m_mTable = null; + + private String m_keyColumnName = ""; + private String m_linkColumnName = ""; + private String m_extendedWhere; + /** Attachments */ + private HashMap m_Attachments = null; + /** Chats */ + private HashMap m_Chats = null; + /** Locks */ + private ArrayList m_Lock = null; + + /** Current Row */ + private int m_currentRow = -1; + + /** Property Change */ + private PropertyChangeSupport m_propertyChangeSupport = new PropertyChangeSupport(this); + /** Property Change Type */ + public static final String PROPERTY = "CurrentRow"; + /** A list of event listeners for this component. */ + protected EventListenerList m_listenerList = new EventListenerList(); + /** Current Data Status Event */ + private DataStatusEvent m_DataStatusEvent = null; + /** Query */ + private MQuery m_query = new MQuery(); + private String m_oldQuery = "0=9"; + private String m_linkValue = "999999"; + + /** Order By Array if SortNo 1..3 */ + private String[] m_OrderBys = new String[3]; + /** List of Key Parents */ + private ArrayList m_parents = new ArrayList(2); + + /** Map of ColumnName of source field (key) and the dependant field (value) */ + private MultiMap m_depOnField = new MultiMap(); + + /** Async Loader */ + private Loader m_loader = null; + /** Async Loading complete */ + private volatile boolean m_loadComplete = false; + /** Is Tab Included in other Tab */ + private boolean m_included = false; + + /** Logger */ + protected CLogger log = CLogger.getCLogger(getClass()); + + private boolean m_parentNeedSave = false; + + + /************************************************************************** + * Tab loader for Tabs > 0 + */ + class Loader extends Thread + { + /** + * Async Loading of Tab > 0 + */ + public void run() + { + initTab (true); + } // run + } // Loader + + /** + * Wait until load is complete + */ + private void waitLoadCompete() + { + if (m_loadComplete) + return; + // + m_loader.setPriority(Thread.NORM_PRIORITY); + log.config (""); + while (m_loader.isAlive()) + { + try + { + Thread.sleep(100); // 1/10 sec + } + catch (Exception e) + { + log.log(Level.SEVERE, "", e); + } + } + log.config ("fini"); + } // waitLoadComplete + + /** + * Initialize Tab with record from AD_Tab_v + * @param async async + * @return true, if correctly initialized (ignored) + */ + protected boolean initTab (boolean async) + { + log.fine("#" + m_vo.TabNo + " - Async=" + async + " - Where=" + m_vo.WhereClause); + + m_extendedWhere = m_vo.WhereClause; + + // Get Field Data + if (!loadFields()) + { + m_loadComplete = true; + return false; + } + + // Order By + m_mTable.setOrderClause(getOrderByClause(m_vo.onlyCurrentRows)); + + if (async) + log.fine("#" + m_vo.TabNo + " - Async=" + async + " - fini"); + m_loadComplete = true; + return true; + } // initTab + + /** + * Dispose - clean up resources + */ + protected void dispose() + { + log.fine("#" + m_vo.TabNo); + m_OrderBys = null; + // + m_parents.clear(); + m_parents = null; + // + m_mTable.close (true); // also disposes Fields + m_mTable = null; + // + m_depOnField.clear(); + m_depOnField = null; + if (m_Attachments != null) + m_Attachments.clear(); + m_Attachments = null; + if (m_Chats != null) + m_Chats.clear(); + m_Chats = null; + // + m_vo.Fields.clear(); + m_vo.Fields = null; + m_vo = null; + } // dispose + + + /** + * Get Field data and add to MTable, if it's required or displayed. + * Reqiored fields are keys, parents, or standard Columns + * @return true if fields loaded + */ + private boolean loadFields() + { + log.fine("#" + m_vo.TabNo); + + if (m_vo.Fields == null) + return false; + + // Add Fields + for (int f = 0; f < m_vo.Fields.size(); f++) + { + GridFieldVO voF = (GridFieldVO)m_vo.Fields.get(f); + // Add Fields to Table + if (voF != null) + { + GridField field = new GridField (voF); + String columnName = field.getColumnName(); + // Record Info + if (field.isKey()) + m_keyColumnName = columnName; + // Parent Column(s) + if (field.isParentColumn()) + m_parents.add(columnName); + // Order By + int sortNo = field.getSortNo(); + if (sortNo == 0) + ; + else if (Math.abs(sortNo) == 1) + { + m_OrderBys[0] = columnName; + if (sortNo < 0) + m_OrderBys[0] += " DESC"; + } + else if (Math.abs(sortNo) == 2) + { + m_OrderBys[1] = columnName; + if (sortNo < 0) + m_OrderBys[1] += " DESC"; + } + else if (Math.abs(sortNo) == 3) + { + m_OrderBys[2] = columnName; + if (sortNo < 0) + m_OrderBys[2] += " DESC"; + } + // Add field + m_mTable.addField(field); + + // List of ColumnNames, this field is dependent on + ArrayList list = field.getDependentOn(); + for (int i = 0; i < list.size(); i++) + m_depOnField.put(list.get(i), field); // ColumnName, Field + // Add fields all fields are dependent on + if (columnName.equals("IsActive") + || columnName.equals("Processed") + || columnName.equals("Processing")) + m_depOnField.put(columnName, null); + } + } // for all fields + + // Add Standard Fields + if (m_mTable.getField("Created") == null) + { + GridField created = new GridField (GridFieldVO.createStdField(m_vo.ctx, + m_vo.WindowNo, m_vo.TabNo, + m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, true, true)); + m_mTable.addField(created); + } + if (m_mTable.getField("CreatedBy") == null) + { + GridField createdBy = new GridField (GridFieldVO.createStdField(m_vo.ctx, + m_vo.WindowNo, m_vo.TabNo, + m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, true, false)); + m_mTable.addField(createdBy); + } + if (m_mTable.getField("Updated") == null) + { + GridField updated = new GridField (GridFieldVO.createStdField(m_vo.ctx, + m_vo.WindowNo, m_vo.TabNo, + m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, false, true)); + m_mTable.addField(updated); + } + if (m_mTable.getField("UpdatedBy") == null) + { + GridField updatedBy = new GridField (GridFieldVO.createStdField(m_vo.ctx, + m_vo.WindowNo, m_vo.TabNo, + m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, false, false)); + m_mTable.addField(updatedBy); + } + return true; + } // loadFields + + /** + * Get a list of variables, this tab is dependent on. + * - for display purposes + * @return ArrayList + */ + public ArrayList getDependentOn() + { + ArrayList list = new ArrayList(); + // Display + Evaluator.parseDepends(list, m_vo.DisplayLogic); + // + if (list.size() > 0 && CLogMgt.isLevelFiner()) + { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < list.size(); i++) + sb.append(list.get(i)).append(" "); + log.finer("(" + m_vo.Name + ") " + sb.toString()); + } + return list; + } // getDependentOn + + /** + * Get Display Logic + * @return display logic + */ + public String getDisplayLogic() + { + return m_vo.DisplayLogic; + } // getDisplayLogic + + /** + * Get TableModel. + * Do not directly communicate with the table model, + * but through the methods of this class + * @return Table Model + */ + public GridTable getTableModel() + { + return m_mTable; + } // getTableModel + + /** + * Get Tab Icon + * @return Icon + */ + public javax.swing.Icon getIcon() + { + if (m_vo.AD_Image_ID == 0) + return null; + // + /** @todo Load Image */ + return null; + } // getIcon + + + /************************************************************************** + * Has this field dependents ? + * @param columnName column name + * @return true if column has dependent + */ + public boolean hasDependants (String columnName) + { + // m_depOnField.printToLog(); + return m_depOnField.containsKey(columnName); + } // isDependentOn + + /** + * Get dependents fields of columnName + * @param columnName column name + * @return ArrayList with GridFields dependent on columnName + */ + public ArrayList getDependantFields (String columnName) + { + return m_depOnField.getValues(columnName); + } // getDependentFields + + + /************************************************************************** + * Set Query + * @param query query + */ + public void setQuery(MQuery query) + { + if (query == null) + m_query = new MQuery(); + else + m_query = query; + } // setQuery + + /** + * Get Query + * @return query + */ + public MQuery getQuery() + { + return m_query; + } // getQuery + + /** + * Is Query Active + * @return true if query active + */ + public boolean isQueryActive() + { + if (m_query != null) + return m_query.isActive(); + return false; + } // isQueryActive + + /** + * Is Query New Record + * @return true if query active + */ + public boolean isQueryNewRecord() + { + if (m_query != null) + return m_query.isNewRecordQuery(); + return false; + } // isQueryNewRecord + + /** + * Enable Events - enable data events of tabs (add listeners) + */ + public void enableEvents() + { + // Setup Events + m_mTable.addDataStatusListener(this); + // m_mTable.addTableModelListener(this); + } // enableEvents + + /** + * Assemble whereClause and query MTable and position to row 0. + *

+	 *		Scenarios:
+	 *		- Never opened 					(full query)
+	 *		- query changed 				(full query)
+	 *		- Detail link value changed		(full query)
+	 *		- otherwise 					(refreshAll)
+	 *  
+ * @param onlyCurrentRows only current rows (1 day) + */ + public void query (boolean onlyCurrentRows) + { + query (onlyCurrentRows, 0, 0); + } // query + + /** + * Assemble whereClause and query MTable and position to row 0. + *
+	 *		Scenarios:
+	 *		- Never opened 					(full query)
+	 *		- query changed 				(full query)
+	 *		- Detail link value changed		(full query)
+	 *		- otherwise 					(refreshAll)
+	 *  
+ * @param onlyCurrentRows only current rows + * @param onlyCurrentDays if only current row, how many days back + * @param maxRows maximim rows or 0 for all + */ + public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows) + { + log.fine("#" + m_vo.TabNo + + " - Only Current Rows=" + onlyCurrentRows + + ", Days=" + onlyCurrentDays + ", Detail=" + isDetail()); + // is it same query? + boolean refresh = m_oldQuery.equals(m_query.getWhereClause()) + && m_vo.onlyCurrentRows == onlyCurrentRows && m_vo.onlyCurrentDays == onlyCurrentDays; + m_oldQuery = m_query.getWhereClause(); + m_vo.onlyCurrentRows = onlyCurrentRows; + m_vo.onlyCurrentDays = onlyCurrentDays; + + /** + * Set Where Clause + */ + // Tab Where Clause + StringBuffer where = new StringBuffer(m_vo.WhereClause); + if (m_vo.onlyCurrentDays > 0) + { + if (where.length() > 0) + where.append(" AND "); + where.append("Created >= "); + if (DB.isDerby()) + where.append("dateadd(dd,-").append(m_vo.onlyCurrentDays).append(",getdate())"); + else + where.append("SysDate-").append(m_vo.onlyCurrentDays); + } + // Detail Query + if (isDetail()) + { + m_parentNeedSave = false; + String lc = getLinkColumnName(); + if (lc.equals("")) + log.severe ("No link column"); + else + { + String value = Env.getContext(m_vo.ctx, m_vo.WindowNo, lc); + // Same link value? + if (refresh) + refresh = m_linkValue.equals(value); + m_linkValue = value; + // Check validity + if (value.length() == 0) + { + //log.severe ("No value for link column " + lc); + //parent is new, can't retrieve detail + m_parentNeedSave = true; + return; + } + else + { + // we have column and value + if (where.length() != 0) + where.append(" AND "); + where.append(lc).append("="); + if (lc.endsWith("_ID")) + where.append(value); + else + where.append("'").append(value).append("'"); + } + } + } // isDetail + + m_extendedWhere = where.toString(); + + // Final Query + if (m_query.isActive()) + { + String q = validateQuery(m_query); + if (q != null) + { + if (where.length() > 0 ) + where.append(" AND "); + where.append(q); + } + } + + /** + * Query + */ + log.fine("#" + m_vo.TabNo + " - " + where); + if (m_mTable.isOpen()) + { + if (refresh) + m_mTable.dataRefreshAll(); + else + m_mTable.dataRequery(where.toString(), m_vo.onlyCurrentRows && !isDetail(), onlyCurrentDays); + } + else + { + m_mTable.setSelectWhereClause(where.toString(), m_vo.onlyCurrentRows && !isDetail(), onlyCurrentDays); + m_mTable.open(maxRows); + } + // Go to Record 0 + setCurrentRow(0, true); + } // query + + /** + * Validate Query. + * If query column is not a tab column create EXISTS query + * @param query query + * @return where clause + */ + private String validateQuery (MQuery query) + { + if (query == null || query.getRestrictionCount() == 0) + return null; + + // Check: only one restriction + if (query.getRestrictionCount() != 1) + { + log.fine("Ignored(More than 1 Restriction): " + query); + return query.getWhereClause(); + } + + String colName = query.getColumnName(0); + if (colName == null) + { + log.fine("Ignored(No Column): " + query); + return query.getWhereClause(); + } + // a '(' in the name = function - don't try to resolve + if (colName.indexOf('(') != -1) + { + log.fine("Ignored(Function): " + colName); + return query.getWhereClause(); + } + // OK - Query is valid + + // Zooms to the same Window (Parents, ..) + String refColName = null; + if (colName.equals("R_RequestRelated_ID")) + refColName = "R_Request_ID"; + else if (colName.startsWith("C_DocType")) + refColName = "C_DocType_ID"; + if (refColName != null) + { + query.setColumnName(0, refColName); + if (getField(refColName) != null) + { + log.fine("Column " + colName + " replaced with synonym " + refColName); + return query.getWhereClause(); + } + refColName = null; + } + + // Simple Query. + if (getField(colName) != null) + { + log.fine("Field Found: " + colName); + return query.getWhereClause(); + } + + // Find Refernce Column e.g. BillTo_ID -> C_BPartner_Location_ID + String sql = "SELECT cc.ColumnName " + + "FROM AD_Column c" + + " INNER JOIN AD_Ref_Table r ON (c.AD_Reference_Value_ID=r.AD_Reference_ID)" + + " INNER JOIN AD_Column cc ON (r.AD_Key=cc.AD_Column_ID) " + + "WHERE c.AD_Reference_ID IN (18,30)" // Table/Search + + " AND c.ColumnName=?"; + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setString(1, colName); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + refColName = rs.getString(1); + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, "(ref) - Column=" + colName, e); + return query.getWhereClause(); + } + // Reference Column found + if (refColName != null) + { + query.setColumnName(0, refColName); + if (getField(refColName) != null) + { + log.fine("Column " + colName + " replaced with " + refColName); + return query.getWhereClause(); + } + colName = refColName; + } + + // Column NOT in Tab - create EXISTS subquery + String tableName = null; + String tabKeyColumn = getKeyColumnName(); + // Column=SalesRep_ID, Key=AD_User_ID, Query=SalesRep_ID=101 + + sql = "SELECT t.TableName " + + "FROM AD_Column c" + + " INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID) " + + "WHERE c.ColumnName=? AND IsKey='Y'" // #1 Link Column + + " AND EXISTS (SELECT * FROM AD_Column cc" + + " WHERE cc.AD_Table_ID=t.AD_Table_ID AND cc.ColumnName=?)"; // #2 Tab Key Column + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setString(1, colName); + pstmt.setString(2, tabKeyColumn); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + tableName = rs.getString(1); + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, "Column=" + colName + ", Key=" + tabKeyColumn, e); + return null; + } + + // Special Reference Handling + if (tabKeyColumn.equals("AD_Reference_ID")) + { + // Column=AccessLevel, Key=AD_Reference_ID, Query=AccessLevel='6' + sql = "SELECT AD_Reference_ID FROM AD_Column WHERE ColumnName=?"; + int AD_Reference_ID = DB.getSQLValue(null, sql, colName); + return "AD_Reference_ID=" + AD_Reference_ID; + } + + // Causes could be functions in query + // e.g. Column=UPPER(Name), Key=AD_Element_ID, Query=UPPER(AD_Element.Name) LIKE '%CUSTOMER%' + if (tableName == null) + { + log.info ("Not successfull - Column=" + + colName + ", Key=" + tabKeyColumn + + ", Query=" + query); + return query.getWhereClause(); + } + + query.setTableName("xx"); + StringBuffer result = new StringBuffer ("EXISTS (SELECT * FROM ") + .append(tableName).append(" xx WHERE ") + .append(query.getWhereClause(true)) + .append(" AND xx.").append(tabKeyColumn).append("=") + .append(getTableName()).append(".").append(tabKeyColumn).append(")"); + log.fine(result.toString()); + return result.toString(); + } // validateQuery + + + /************************************************************************** + * Refresh all data + */ + public void dataRefreshAll () + { + log.fine("#" + m_vo.TabNo); + /** @todo does not work with alpha key */ + int keyNo = m_mTable.getKeyID(m_currentRow); + m_mTable.dataRefreshAll(); + // Should use RowID - not working for tables with multiple keys + if (keyNo != -1) + { + if (keyNo != m_mTable.getKeyID(m_currentRow)) // something changed + { + int size = getRowCount(); + for (int i = 0; i < size; i++) + { + if (keyNo == m_mTable.getKeyID(i)) + { + m_currentRow = i; + break; + } + } + } + } + setCurrentRow(m_currentRow, true); + } // dataRefreshAll + + /** + * Refresh current row data + */ + public void dataRefresh () + { + dataRefresh (m_currentRow); + } // dataRefresh + + /** + * Refresh row data + * @param row index + */ + public void dataRefresh (int row) + { + log.fine("#" + m_vo.TabNo + " - row=" + row); + m_mTable.dataRefresh(row); + setCurrentRow(row, true); + } // dataRefresh + + + /************************************************************************** + * Uncoditionally Save data + * @param manualCmd if true, no vetoable PropertyChange will be fired for save confirmation from MTable + * @return true if save complete (or nor required) + */ + public boolean dataSave(boolean manualCmd) + { + log.fine("#" + m_vo.TabNo + " - row=" + m_currentRow); + try + { + boolean retValue = (m_mTable.dataSave(manualCmd) == GridTable.SAVE_OK); + if (manualCmd) + setCurrentRow(m_currentRow, false); + return retValue; + } + catch (Exception e) + { + log.log(Level.SEVERE, "#" + m_vo.TabNo + " - row=" + m_currentRow, e); + } + return false; + } // dataSave + + + /** + * Do we need to Save? + * @param rowChange row change + * @param onlyRealChange if true the value of a field was actually changed + * (e.g. for new records, which have not been changed) - default false + * @return true it needs to be saved + */ + public boolean needSave (boolean rowChange, boolean onlyRealChange) + { + if (rowChange) + { + return m_mTable.needSave(-2, onlyRealChange); + } + else + { + if (onlyRealChange) + return m_mTable.needSave(); + else + return m_mTable.needSave(onlyRealChange); + } + } // isDataChanged + + /** + * Ignore data changes + */ + public void dataIgnore() + { + log.fine("#" + m_vo.TabNo); + m_mTable.dataIgnore(); + setCurrentRow(m_currentRow, false); // re-load data + log.fine("#" + m_vo.TabNo + "- fini"); + } // dataIgnore + + + /** + * Create (copy) new Row + * and process Callouts + * @param copy copy + * @return true if copied/new + */ + public boolean dataNew (boolean copy) + { + log.fine("#" + m_vo.TabNo); + if (!isInsertRecord()) + { + log.warning ("Inset Not allowed in TabNo=" + m_vo.TabNo); + return false; + } + // Prevent New Where Main Record is processed + if (m_vo.TabNo > 0) + { + boolean processed = "Y".equals(Env.getContext(m_vo.ctx, m_vo.WindowNo, "Processed")); + // boolean active = "Y".equals(Env.getContext(m_vo.ctx, m_vo.WindowNo, "IsActive")); + if (processed) + { + log.warning ("Not allowed in TabNo=" + m_vo.TabNo + " -> Processed=" + processed); + return false; + } + log.finest("Processed=" + processed); + } + boolean retValue = m_mTable.dataNew (m_currentRow, copy); + if (!retValue) + return retValue; + setCurrentRow(m_currentRow + 1, true); + // process all Callouts (no dependency check - assumed that settings are valid) + for (int i = 0; i < getFieldCount(); i++) + processCallout(getField(i)); + // check validity of defaults + for (int i = 0; i < getFieldCount(); i++) + { + getField(i).refreshLookup(); + getField(i).validateValue(); + } + m_mTable.setChanged(false); + return retValue; + } // dataNew + + /** + * Delete current Row + * @return true if deleted + */ + public boolean dataDelete() + { + log.fine("#" + m_vo.TabNo + " - row=" + m_currentRow); + boolean retValue = m_mTable.dataDelete(m_currentRow); + setCurrentRow(m_currentRow, true); + return retValue; + } // dataDelete + + + /** + * Get Name of Tab + * @return name + */ + public String getName() + { + return m_vo.Name; + } // getName + + /** + * Get Description of Tab + * @return description + */ + public String getDescription() + { + return m_vo.Description; + } // getDescription + + /** + * Get Help of Tab + * @return help + */ + public String getHelp() + { + return m_vo.Help; + } // getHelp + + /** + * Get Tab Level + * @return tab level + */ + public int getTabLevel() + { + return m_vo.TabLevel; + } // getTabLevel + + /** + * Get Commit Warning + * @return commit warning + */ + public String getCommitWarning() + { + return m_vo.CommitWarning; + } // getCommitWarning + + /** + * Return Table Model + * @return MTable + */ + protected GridTable getMTable() + { + return m_mTable; + } // getMTable + + /** + * Return the name of the key column - may be "" + * @return key column name + */ + public String getKeyColumnName() + { + return m_keyColumnName; + } // getKeyColumnName + + /** + * Return Name of link column + * @return link column name + */ + public String getLinkColumnName() + { + return m_linkColumnName; + } // getLinkColumnName + + /** + * Set Name of link column. + * Set from MWindow.loadTabData + * Used in MTab.isCurreny, (.setCurrentRow) .query - APanel.cmd_report + * and MField.isEditable and .isDefault via context + * @param linkColumnName name of column - or sets name to AD_Column_ID, if exists + */ + public void setLinkColumnName (String linkColumnName) + { + if (linkColumnName != null) + m_linkColumnName = linkColumnName; + else + { + if (m_vo.AD_Column_ID == 0) + return; + // we have a link column identified (primary parent column) + else + { + String SQL = "SELECT ColumnName FROM AD_Column WHERE AD_Column_ID=?"; + try + { + PreparedStatement pstmt = DB.prepareStatement(SQL, null); + pstmt.setInt(1, m_vo.AD_Column_ID); // Parent Link Column + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + m_linkColumnName = rs.getString(1); + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, "", e); + } + log.fine("AD_Column_ID=" + m_vo.AD_Column_ID + " - " + m_linkColumnName); + } + } + Env.setContext(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, "LinkColumnName", m_linkColumnName); + } // setLinkColumnName + + /** + * Is the tab current?. + *
+	 *	Yes 	- Table must be open
+	 *			- Query String is the same
+	 *			- Not Detail
+	 *			- Old link column value is same as current one
+	 *  
+ * @return true if current + */ + public boolean isCurrent() + { + // Open? + if (!m_mTable.isOpen()) + return false; + // Same Query + if (!m_oldQuery.equals(m_query.getWhereClause())) + return false; + // Detail? + if (!isDetail()) + return true; + // Same link column value + String value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getLinkColumnName()); + return m_linkValue.equals(value); + } // isCurrent + + /** + * Is the tab/table currently open + * @return true if open + */ + public boolean isOpen() + { + // Open? + if (m_mTable != null) + return m_mTable.isOpen(); + return false; + } // isCurrent + + + /** + * Is Tab Incluced in other Tab + * @return true if included + */ + public boolean isIncluded() + { + return m_included; + } // isIncluded + + /** + * Is Tab Incluced in other Tab + * @param isIncluded true if included + */ + public void setIncluded(boolean isIncluded) + { + m_included = isIncluded; + } // setIncluded + + /** + * Are Only Current Rows displayed + * @return true if no history + */ + public boolean isOnlyCurrentRows() + { + return m_vo.onlyCurrentRows; + } // isOnlyCurrentRows + /** + * Return Parent ArrayList + * @return parent column names + */ + public ArrayList getParentColumnNames() + { + return m_parents; + } // getParentColumnNames + + /** + * Get Tree ID of this tab + * @return ID + */ + private int getTreeID() + { + log.fine(m_vo.TableName); + String SQL = "SELECT * FROM AD_ClientInfo WHERE AD_Client=" + + Env.getContext(m_vo.ctx, m_vo.WindowNo, "AD_Client_ID") + + " ORDER BY AD_Org DESC"; + // + if (m_vo.TableName.equals("AD_Menu")) + return 10; // MM + else if (m_vo.TableName.equals("C_ElementValue")) + return 20; // EV + else if (m_vo.TableName.equals("M_Product")) + return 30; // PR + else if (m_vo.TableName.equals("C_BPartner")) + return 40; // BP + else if (m_vo.TableName.equals("AD_Org")) + return 50; // OO + else if (m_vo.TableName.equals("C_Project")) + return 60; // PJ + return 0; + } // getTreeID + + /** + * Returns true if this is a detail record + * @return true if not parent tab + */ + public boolean isDetail() + { + // We have IsParent columns and/or a link column + if (m_parents.size() > 0 || m_vo.AD_Column_ID != 0) + return true; + return false; + } // isDetail + + /** + * Is Printed (Document can be printed) + * @return true if printing + */ + public boolean isPrinted() + { + return m_vo.AD_Process_ID != 0; + } // isPrinted + + /** + * Get WindowNo + * @return window no + */ + public int getWindowNo() + { + return m_vo.WindowNo; + } // getWindowNo + + /** + * Get TabNo + * @return tab no + */ + public int getTabNo() + { + return m_vo.TabNo; + } // getTabNo + + /** + * Get Process ID + * @return Process ID + */ + public int getAD_Process_ID() + { + return m_vo.AD_Process_ID; + } // getAD_Process_ID + + /** + * Is High Volume? + * @return true if high volumen table + */ + public boolean isHighVolume() + { + return m_vo.IsHighVolume; + } // isHighVolume + + /** + * Is Read Only? + * @return true if read only + */ + public boolean isReadOnly() + { + if (m_vo.IsReadOnly) + return true; + + // no restrictions + if (m_vo.ReadOnlyLogic == null || m_vo.ReadOnlyLogic.equals("")) + return m_vo.IsReadOnly; + + // ** dynamic content ** uses get_ValueAsString + boolean retValue = Evaluator.evaluateLogic(this, m_vo.ReadOnlyLogic); + log.finest(m_vo.Name + + " (" + m_vo.ReadOnlyLogic + ") => " + retValue); + return retValue; + } // isReadOnly + + /** + * Tab contains Always Update Field + * @return true if field with always updateable + */ + public boolean isAlwaysUpdateField() + { + for (int i = 0; i < m_mTable.getColumnCount(); i++) + { + GridField field = m_mTable.getField(i); + if (field.isAlwaysUpdateable()) + return true; + } + return false; + } // isAlwaysUpdateField + + /** + * Can we Insert Records? + * @return true not read only and allowed + */ + public boolean isInsertRecord() + { + if (isReadOnly()) + return false; + return m_vo.IsInsertRecord; + } // isInsertRecord + + /** + * Is the Tab Visible. + * Called when constructing the window. + * @return true, if displayed + */ + public boolean isDisplayed () + { + // no restrictions + String dl = m_vo.DisplayLogic; + if (dl == null || dl.equals("")) + return true; + + // ** dynamic content ** + String parsed = Env.parseContext (m_vo.ctx, 0, dl, false, false).trim(); + if (parsed.length() == 0) + return true; + boolean retValue = Evaluator.evaluateLogic(this, dl); + log.config(m_vo.Name + " (" + dl + ") => " + retValue); + return retValue; + } // isDisplayed + + /** + * Get Variable Value (Evaluatee) + * @param variableName name + * @return value + */ + public String get_ValueAsString (String variableName) + { + return Env.getContext (m_vo.ctx, m_vo.WindowNo, variableName, true); + } // get_ValueAsString + + /** + * Is Single Row + * @return true if single row + */ + public boolean isSingleRow() + { + return m_vo.IsSingleRow; + } // isSingleRow; + + /** + * Set Single Row. + * Temporary store of current value + * @param isSingleRow toggle + */ + public void setSingleRow (boolean isSingleRow) + { + m_vo.IsSingleRow = isSingleRow; + } // setSingleRow + + + /** + * Has Tree + * @return true if tree exists + */ + public boolean isTreeTab() + { + return m_vo.HasTree; + } // isTreeTab + + /** + * Get Tab ID + * @return Tab ID + */ + public int getAD_Tab_ID() + { + return m_vo.AD_Tab_ID; + } // getAD_Tab_ID + + /** + * Get Table ID + * @return Table ID + */ + public int getAD_Table_ID() + { + return m_vo.AD_Table_ID; + } // getAD_Table_ID + + /** + * Get Window ID + * @return Window ID + */ + public int getAD_Window_ID() + { + return m_vo.AD_Window_ID; + } // getAD_Window_ID + + /** + * Get Included Tab ID + * @return Included_Tab_ID + */ + public int getIncluded_Tab_ID() + { + return m_vo.Included_Tab_ID; + } // getIncluded_Tab_ID + + /** + * Get TableName + * @return Table Name + */ + public String getTableName() + { + return m_vo.TableName; + } // getTableName + + /** + * Get Tab Where Clause + * @return where clause + */ + public String getWhereClause() + { + return m_vo.WhereClause; + } // getWhereClause + + /** + * Is Sort Tab + * @return true if sort tab + */ + public boolean isSortTab() + { + return m_vo.IsSortTab; + } // isSortTab + + /** + * Get Order column for sort tab + * @return AD_Column_ID + */ + public int getAD_ColumnSortOrder_ID() + { + return m_vo.AD_ColumnSortOrder_ID; + } // getAD_ColumnSortOrder_ID + + /** + * Get Yes/No column for sort tab + * @return AD_Column_ID + */ + public int getAD_ColumnSortYesNo_ID() + { + return m_vo.AD_ColumnSortYesNo_ID; + } // getAD_ColumnSortYesNo_ID + + + /************************************************************************** + * Get extended Where Clause (parent link) + * @return parent link + */ + public String getWhereExtended() + { + return m_extendedWhere; + } // getWhereExtended + + /** + * Get Order By Clause + * @param onlyCurrentRows only current rows + * @return Order By Clause + */ + private String getOrderByClause(boolean onlyCurrentRows) + { + // First Prio: Tab Order By + if (m_vo.OrderByClause.length() > 0) + return m_vo.OrderByClause; + + // Second Prio: Fields (save it) + m_vo.OrderByClause = ""; + for (int i = 0; i < 3; i++) + { + String order = m_OrderBys[i]; + if (order != null && order.length() > 0) + { + if (m_vo.OrderByClause.length() > 0) + m_vo.OrderByClause += ","; + m_vo.OrderByClause += order; + } + } + if (m_vo.OrderByClause.length() > 0) + return m_vo.OrderByClause; + + // Third Prio: onlyCurrentRows + m_vo.OrderByClause = "Created"; + if (onlyCurrentRows && !isDetail()) // first tab only + m_vo.OrderByClause += " DESC"; + return m_vo.OrderByClause; + } // getOrderByClause + + + /************************************************************************** + * Transaction support. + * Depending on Table returns transaction info + * @return info + */ + public String getTrxInfo() + { + // InvoiceBatch + if (m_vo.TableName.startsWith("C_InvoiceBatch")) + { + int Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "C_InvoiceBatch_ID"); + log.fine(m_vo.TableName + " - " + Record_ID); + MessageFormat mf = null; + try + { + mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "InvoiceBatchSummary")); + } + catch (Exception e) + { + log.log(Level.SEVERE, "InvoiceBatchSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "InvoiceBatchSummary"), e); + } + if (mf == null) + return " "; + /********************************************************************** + * ** Message: ExpenseSummary ** + * {0} Line(s) {1,number,#,##0.00} - Total: {2,number,#,##0.00} + * + * {0} - Number of lines + * {1} - Toral + * {2} - Currency + */ + Object[] arguments = new Object[3]; + boolean filled = false; + // + String sql = "SELECT COUNT(*), NVL(SUM(LineNetAmt),0), NVL(SUM(LineTotalAmt),0) " + + "FROM C_InvoiceBatchLine " + + "WHERE C_InvoiceBatch_ID=? AND IsActive='Y'"; + // + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, Record_ID); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + { + // {0} - Number of lines + Integer lines = new Integer(rs.getInt(1)); + arguments[0] = lines; + // {1} - Line net + Double net = new Double(rs.getDouble(2)); + arguments[1] = net; + // {2} - Line net + Double total = new Double(rs.getDouble(3)); + arguments[2] = total; + filled = true; + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, m_vo.TableName + "\nSQL=" + sql, e); + } + if (filled) + return mf.format (arguments); + return " "; + } // InvoiceBatch + + // Order || Invoice + else if (m_vo.TableName.startsWith("C_Order") || m_vo.TableName.startsWith("C_Invoice")) + { + int Record_ID; + boolean isOrder = m_vo.TableName.startsWith("C_Order"); + // + StringBuffer sql = new StringBuffer("SELECT COUNT(*) AS Lines,c.ISO_Code,o.TotalLines,o.GrandTotal," + + "currencyBase(o.GrandTotal,o.C_Currency_ID,o.DateAcct, o.AD_Client_ID,o.AD_Org_ID) AS ConvAmt "); + if (isOrder) + { + Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "C_Order_ID"); + sql.append("FROM C_Order o" + + " INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)" + + " INNER JOIN C_OrderLine l ON (o.C_Order_ID=l.C_Order_ID) " + + "WHERE o.C_Order_ID=? "); + } + else + { + Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "C_Invoice_ID"); + sql.append("FROM C_Invoice o" + + " INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)" + + " INNER JOIN C_InvoiceLine l ON (o.C_Invoice_ID=l.C_Invoice_ID) " + + "WHERE o.C_Invoice_ID=? "); + } + sql.append("GROUP BY o.C_Currency_ID, c.ISO_Code, o.TotalLines, o.GrandTotal, o.DateAcct, o.AD_Client_ID, o.AD_Org_ID"); + + log.fine(m_vo.TableName + " - " + Record_ID); + MessageFormat mf = null; + try + { + mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "OrderSummary")); + } + catch (Exception e) + { + log.log(Level.SEVERE, "OrderSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "OrderSummary"), e); + } + if (mf == null) + return " "; + /********************************************************************** + * ** Message: OrderSummary ** + * {0} Line(s) - {1,number,#,##0.00} - Toral: {2,number,#,##0.00} {3} = {4,number,#,##0.00} + * + * {0} - Number of lines + * {1} - Line toral + * {2} - Grand total (including tax, etc.) + * {3} - Currency + * (4) - Grand total converted to local currency + */ + Object[] arguments = new Object[5]; + boolean filled = false; + // + try + { + PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null); + pstmt.setInt(1, Record_ID); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + { + // {0} - Number of lines + Integer lines = new Integer(rs.getInt(1)); + arguments[0] = lines; + // {1} - Line toral + Double lineTotal = new Double(rs.getDouble(3)); + arguments[1] = lineTotal; + // {2} - Grand total (including tax, etc.) + Double grandTotal = new Double(rs.getDouble(4)); + arguments[2] = grandTotal; + // {3} - Currency + String currency = rs.getString(2); + arguments[3] = currency; + // (4) - Grand total converted to Euro + Double grandEuro = new Double(rs.getDouble(5)); + arguments[4] = grandEuro; + filled = true; + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, m_vo.TableName + "\nSQL=" + sql, e); + } + if (filled) + return mf.format (arguments); + return " "; + } // Order || Invoice + + // Expense Report + else if (m_vo.TableName.startsWith("S_TimeExpense") && m_vo.TabNo == 0) + { + int Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "S_TimeExpense_ID"); + log.fine(m_vo.TableName + " - " + Record_ID); + MessageFormat mf = null; + try + { + mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "ExpenseSummary")); + } + catch (Exception e) + { + log.log(Level.SEVERE, "ExpenseSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "ExpenseSummary"), e); + } + if (mf == null) + return " "; + /********************************************************************** + * ** Message: ExpenseSummary ** + * {0} Line(s) - Total: {1,number,#,##0.00} {2} + * + * {0} - Number of lines + * {1} - Toral + * {2} - Currency + */ + Object[] arguments = new Object[3]; + boolean filled = false; + // + String SQL = "SELECT COUNT(*) AS Lines, SUM(ConvertedAmt*Qty) " + + "FROM S_TimeExpenseLine " + + "WHERE S_TimeExpense_ID=?"; + + // + try + { + PreparedStatement pstmt = DB.prepareStatement(SQL, null); + pstmt.setInt(1, Record_ID); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + { + // {0} - Number of lines + Integer lines = new Integer(rs.getInt(1)); + arguments[0] = lines; + // {1} - Line toral + Double total = new Double(rs.getDouble(2)); + arguments[1] = total; + // {3} - Currency + arguments[2] = " "; + filled = true; + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, m_vo.TableName + "\nSQL=" + SQL, e); + } + if (filled) + return mf.format (arguments); + return " "; + } // S_TimeExpense + + + // Default - No Trx Info + return null; + } // getTrxInfo + + /** + * Load Dependant Information + */ + private void loadDependentInfo() + { + /** + * Load Order Type from C_DocTypeTarget_ID + */ + if (m_vo.TableName.equals("C_Order")) + { + int C_DocTyp_ID = 0; + Integer target = (Integer)getValue("C_DocTypeTarget_ID"); + if (target != null) + C_DocTyp_ID = target.intValue(); + if (C_DocTyp_ID == 0) + return; + + String sql = "SELECT DocSubTypeSO FROM C_DocType WHERE C_DocType_ID=?"; + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, C_DocTyp_ID); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + Env.setContext(m_vo.ctx, m_vo.WindowNo, "OrderType", rs.getString(1)); + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + } + } // loadOrderInfo + } // loadDependentInfo + + + /************************************************************************** + * Load Attachments for this table + */ + public void loadAttachments() + { + log.fine("#" + m_vo.TabNo); + if (!canHaveAttachment()) + return; + + String SQL = "SELECT AD_Attachment_ID, Record_ID FROM AD_Attachment " + + "WHERE AD_Table_ID=?"; + try + { + if (m_Attachments == null) + m_Attachments = new HashMap(); + else + m_Attachments.clear(); + PreparedStatement pstmt = DB.prepareStatement(SQL, null); + pstmt.setInt(1, m_vo.AD_Table_ID); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + Integer key = new Integer(rs.getInt(2)); + Integer value = new Integer(rs.getInt(1)); + m_Attachments.put(key, value); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, "loadAttachments", e); + } + log.config("#" + m_Attachments.size()); + } // loadAttachment + + /** + * Can this tab have Attachments?. + *

+ * It can have an attachment if it has a key column ending with _ID. + * The key column is empty, if there is no single identifying key. + * @return true if record can have attachment + */ + public boolean canHaveAttachment() + { + if (getKeyColumnName().endsWith("_ID")) + return true; + return false; + } // canHaveAttachment + + /** + * Returns true, if current row has an Attachment + * @return true if record has attchment + */ + public boolean hasAttachment() + { + if (m_Attachments == null) + loadAttachments(); + if (m_Attachments == null || m_Attachments.isEmpty()) + return false; + // + Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); + return m_Attachments.containsKey(key); + } // hasAttachment + + /** + * Get Attachment_ID for current record. + * @return ID or 0, if not found + */ + public int getAD_AttachmentID() + { + if (m_Attachments == null) + loadAttachments(); + if (m_Attachments.isEmpty()) + return 0; + // + Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); + Integer value = (Integer)m_Attachments.get(key); + if (value == null) + return 0; + else + return value.intValue(); + } // getAttachmentID + + /************************************************************************** + * Load Chats for this table + */ + public void loadChats() + { + log.fine("#" + m_vo.TabNo); + if (!canHaveAttachment()) + return; + + String sql = "SELECT CM_Chat_ID, Record_ID FROM CM_Chat " + + "WHERE AD_Table_ID=?"; + try + { + if (m_Chats == null) + m_Chats = new HashMap(); + else + m_Chats.clear(); + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, m_vo.AD_Table_ID); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + Integer key = new Integer(rs.getInt(2)); // Record_ID + Integer value = new Integer(rs.getInt(1)); // CM_Chat_ID + m_Chats.put(key, value); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + } + log.config("#" + m_Chats.size()); + } // loadChats + + /** + * Returns true, if current row has a Chat + * @return true if record has chat + */ + public boolean hasChat() + { + if (m_Chats == null) + loadChats(); + if (m_Chats == null || m_Chats.isEmpty()) + return false; + // + Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); + return m_Chats.containsKey(key); + } // hasChat + + /** + * Get Chat_ID for this record. + * @return ID or 0, if not found + */ + public int getCM_ChatID() + { + if (m_Chats == null) + loadChats(); + if (m_Chats.isEmpty()) + return 0; + // + Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); + Integer value = (Integer)m_Chats.get(key); + if (value == null) + return 0; + else + return value.intValue(); + } // getCM_ChatID + + + /************************************************************************** + * Load Locks for Table and User + */ + public void loadLocks() + { + int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID"); + log.fine("#" + m_vo.TabNo + " - AD_User_ID=" + AD_User_ID); + if (!canHaveAttachment()) + return; + + String sql = "SELECT Record_ID " + + "FROM AD_Private_Access " + + "WHERE AD_User_ID=? AND AD_Table_ID=? AND IsActive='Y' " + + "ORDER BY Record_ID"; + try + { + if (m_Lock == null) + m_Lock = new ArrayList(); + else + m_Lock.clear(); + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, AD_User_ID); + pstmt.setInt(2, m_vo.AD_Table_ID); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + Integer key = new Integer(rs.getInt(1)); + m_Lock.add(key); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + } + log.fine("#" + m_Lock.size()); + } // loadLooks + + /** + * Record Is Locked + * @return true if locked + */ + public boolean isLocked() + { + if (!MRole.getDefault(m_vo.ctx, false).isPersonalLock()) + return false; + if (m_Lock == null) + loadLocks(); + if (m_Lock == null || m_Lock.isEmpty()) + return false; + // + Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); + return m_Lock.contains(key); + } // isLocked + + /** + * Lock Record + * @param ctx context + * @param Record_ID id + * @param lock true if lock, otherwise unlock + */ + public void lock (Properties ctx, int Record_ID, boolean lock) + { + int AD_User_ID = Env.getContextAsInt(ctx, "#AD_User_ID"); + log.fine("Lock=" + lock + ", AD_User_ID=" + AD_User_ID + + ", AD_Table_ID=" + m_vo.AD_Table_ID + ", Record_ID=" + Record_ID); + MPrivateAccess access = MPrivateAccess.get (ctx, AD_User_ID, m_vo.AD_Table_ID, Record_ID); + if (access == null) + access = new MPrivateAccess (ctx, AD_User_ID, m_vo.AD_Table_ID, Record_ID); + access.setIsActive(lock); + access.save(); + // + loadLocks(); + } // lock + + + /************************************************************************** + * Data Status Listener from MTable. + * - get raw info and add current row information + * - update the current row + * - redistribute (fire) Data Status event + * @param e event + */ + public void dataStatusChanged (DataStatusEvent e) + { + log.fine("#" + m_vo.TabNo + " - " + e.toString()); + int oldCurrentRow = e.getCurrentRow(); + m_DataStatusEvent = e; // save it + // when sorted set current row to 0 + String msg = m_DataStatusEvent.getAD_Message(); + if (msg != null && msg.equals("Sorted")) + setCurrentRow(0, true); + // set current row + m_DataStatusEvent.setCurrentRow(m_currentRow); + // Same row - update value + if (oldCurrentRow == m_currentRow) + { + GridField field = m_mTable.getField(e.getChangedColumn()); + if (field != null) + { + Object value = m_mTable.getValueAt(m_currentRow, e.getChangedColumn()); + field.setValue(value, m_mTable.isInserting()); + } + } + else // Redistribute Info with current row info + fireDataStatusChanged(m_DataStatusEvent); + // log.fine("dataStatusChanged #" + m_vo.TabNo + "- fini", e.toString()); + } // dataStatusChanged + + /** + * Inform Listeners and build WHO info + * @param e event + */ + private void fireDataStatusChanged (DataStatusEvent e) + { + DataStatusListener[] listeners = m_listenerList.getListeners(DataStatusListener.class); + if (listeners.length == 0) + return; + log.fine(e.toString()); + // WHO Info + if (e.getCurrentRow() >= 0) + { + e.Created = (Timestamp)getValue("Created"); + e.CreatedBy = (Integer)getValue("CreatedBy"); + e.Updated = (Timestamp)getValue("Updated"); + e.UpdatedBy = (Integer)getValue("UpdatedBy"); + e.Record_ID = getValue(m_keyColumnName); + // Info + StringBuffer info = new StringBuffer(getTableName()); + // We have a key column + if (m_keyColumnName != null && m_keyColumnName.length() > 0) + { + info.append(" - ") + .append(m_keyColumnName).append("=").append(e.Record_ID); + } + else // we have multiple parents + { + for (int i = 0; i < m_parents.size(); i++) + { + String keyCol = (String)m_parents.get(i); + info.append(" - ") + .append(keyCol).append("=").append(getValue(keyCol)); + } + } + e.Info = info.toString(); + } + e.setInserting(m_mTable.isInserting()); + // Distribute/fire it + for (int i = 0; i < listeners.length; i++) + listeners[i].dataStatusChanged(e); + // log.fine("fini - " + e.toString()); + } // fireDataStatusChanged + + /** + * Create and fire Data Status Error Event + * @param AD_Message message + * @param info info + * @param isError if not true, it is a Warning + */ + protected void fireDataStatusEEvent(String AD_Message, String info, boolean isError) + { + m_mTable.fireDataStatusEEvent(AD_Message, info, isError); + } // fireDataStatusEvent + + /** + * Create and fire Data Status Error Event (from Error Log) + * @param errorLog log + */ + protected void fireDataStatusEEvent (ValueNamePair errorLog) + { + if (errorLog != null) + m_mTable.fireDataStatusEEvent(errorLog); + } // fireDataStatusEvent + + /** + * Get Current Row + * @return current row + */ + public int getCurrentRow() + { + if (m_currentRow != verifyRow(m_currentRow)) + setCurrentRow(m_mTable.getRowCount()-1, true); + return m_currentRow; + } // getCurrentRow + + /** + * Get Current Table Key ID + * @return Record_ID + */ + public int getRecord_ID() + { + return m_mTable.getKeyID(m_currentRow); + } // getRecord_ID + + /** + * Get Key ID of row + * @param row row number + * @return The Key ID of the row or -1 if not found + */ + public int getKeyID (int row) + { + return m_mTable.getKeyID (row); + } // getCurrentKeyID + + /** + * Navigate absolute - goto Row - (zero based). + * - does nothing, if in current row + * - saves old row if required + * @param targetRow target row + * @return current row + */ + public int navigate (int targetRow) + { + // nothing to do + if (targetRow == m_currentRow) + return m_currentRow; + log.info ("Row=" + targetRow); + + // Row range check + int newRow = verifyRow(targetRow); + + // Check, if we have old uncommitted data + m_mTable.dataSave(newRow, false); + + // new position + return setCurrentRow(newRow, true); + } // navigate + + /** + * Navigate relatively - i.e. plus/minus from current position + * @param rowChange row change + * @return current row + */ + public int navigateRelative (int rowChange) + { + return navigate (m_currentRow + rowChange); + } // navigateRelative + + /** + * Navigate to current now (reload) + * @return current row + */ + public int navigateCurrent() + { + log.info("Row=" + m_currentRow); + return setCurrentRow(m_currentRow, true); + } // navigateCurrent + + /** + * Row Range check + * @param targetRow target row + * @return checked row + */ + private int verifyRow (int targetRow) + { + int newRow = targetRow; + // Table Open? + if (!m_mTable.isOpen()) + { + log.severe ("Table not open"); + return -1; + } + // Row Count + int rows = getRowCount(); + if (rows == 0) + { + log.fine("No Rows"); + return -1; + } + if (newRow >= rows) + { + newRow = rows-1; + log.fine("Set to max Row: " + newRow); + } + else if (newRow < 0) + { + newRow = 0; + log.fine("Set to first Row"); + } + return newRow; + } // verifyRow + + /** + * Set current row and load data into fields. + * If there is no row - load nulls + * @param newCurrentRow new current row + * @param fireEvents fire events + * @return current row + */ + private int setCurrentRow (int newCurrentRow, boolean fireEvents) + { + int oldCurrentRow = m_currentRow; + m_currentRow = verifyRow (newCurrentRow); + log.fine("Row=" + m_currentRow + " - fire=" + fireEvents); + + // Update Field Values + int size = m_mTable.getColumnCount(); + for (int i = 0; i < size; i++) + { + GridField mField = m_mTable.getField(i); + // get Value from Table + if (m_currentRow >= 0) + { + Object value = m_mTable.getValueAt(m_currentRow, i); + mField.setValue(value, m_mTable.isInserting()); + if (m_mTable.isInserting()) // set invalid values to null + mField.validateValue(); + } + else + { // no rows - set to a reasonable value - not updateable +// Object value = null; +// if (mField.isKey() || mField.isParent() || mField.getColumnName().equals(m_linkColumnName)) +// value = mField.getDefault(); + mField.setValue(); + } + } + loadDependentInfo(); + + if (!fireEvents) // prevents informing twice + return m_currentRow; + + // inform VTable/.. -> rowChanged + m_propertyChangeSupport.firePropertyChange(PROPERTY, oldCurrentRow, m_currentRow); + + // inform APanel/.. -> dataStatus with row updated + if (m_DataStatusEvent == null) + m_DataStatusEvent = new DataStatusEvent(this, getRowCount(), + m_mTable.isInserting(), // changed + Env.isAutoCommit(Env.getCtx(), m_vo.WindowNo), m_mTable.isInserting()); + // + m_DataStatusEvent.setCurrentRow(m_currentRow); + String status = m_DataStatusEvent.getAD_Message(); + if (status == null || status.length() == 0) + m_DataStatusEvent.setInfo("NavigateOrUpdate", null, false,false); + fireDataStatusChanged(m_DataStatusEvent); + return m_currentRow; + } // setCurrentRow + + + /************************************************************************** + * Get RowCount + * @return row count + */ + public int getRowCount() + { + int count = m_mTable.getRowCount(); + // Wait a bit if currently loading + if (count == 0 && m_mTable.isLoading()) + { + try + { + Thread.sleep(100); // .1 sec + } + catch (Exception e) {} + count = m_mTable.getRowCount(); + } + return count; + } // getRowCount + + /** + * Get Column/Field Count + * @return field count + */ + public int getFieldCount() + { + return m_mTable.getColumnCount(); + } // getFieldCount + + /** + * Get Field by index + * @param index index + * @return MField + */ + public GridField getField (int index) + { + return m_mTable.getField(index); + } // getField + + /** + * Get Field by DB column name + * @param columnName column name + * @return MField + */ + public GridField getField (String columnName) + { + return m_mTable.getField(columnName); + } // getField + + /** + * Get all Fields + * @return MFields + */ + public GridField[] getFields () + { + return m_mTable.getFields(); + } // getField + + /** + * Set New Value & call Callout + * @param columnName database column name + * @param value value + * @return error message or "" + */ + public String setValue (String columnName, Object value) + { + if (columnName == null) + return "NoColumn"; + return setValue(m_mTable.getField(columnName), value); + } // setValue + + /** + * Set New Value & call Callout + * @param field field + * @param value value + * @return error message or "" + */ + public String setValue (GridField field, Object value) + { + if (field == null) + return "NoField"; + + log.fine(field.getColumnName() + "=" + value + " - Row=" + m_currentRow); + + int col = m_mTable.findColumn(field.getColumnName()); + m_mTable.setValueAt(value, m_currentRow, col, false); + // + return processFieldChange (field); + } // setValue + + /** + * Is Processed + * @return true if current record is processed + */ + public boolean isProcessed() + { + int index = m_mTable.findColumn("Processed"); + if (index != -1) + { + Object oo = m_mTable.getValueAt(m_currentRow, index); + if (oo instanceof String) + return "Y".equals(oo); + if (oo instanceof Boolean) + return ((Boolean)oo).booleanValue(); + } + return "Y".equals(Env.getContext(m_vo.ctx, m_vo.WindowNo, "Processed")); + } // isProcessed + + /** + * Process Field Change - evaluate Dependencies and process Callouts. + * + * called from MTab.setValue or GridController.dataStatusChanged + * @param changedField changed field + * @return error message or "" + */ + public String processFieldChange (GridField changedField) + { + processDependencies (changedField); + return processCallout (changedField); + } // processFieldChange + + /** + * Evaluate Dependencies + * @param changedField changed field + */ + private void processDependencies (GridField changedField) + { + String columnName = changedField.getColumnName(); + // log.trace(log.l4_Data, "Changed Column", columnName); + + // when column name is not in list of DependentOn fields - fini + if (!hasDependants(columnName)) + return; + + // Get dependent MFields (may be because of display or dynamic lookup) + ArrayList list = getDependantFields(columnName); + for (int i = 0; i < list.size(); i++) + { + GridField dependentField = (GridField)list.get(i); + // log.trace(log.l5_DData, "Dependent Field", dependentField==null ? "null" : dependentField.getColumnName()); + // if the field has a lookup + if (dependentField != null && dependentField.getLookup() instanceof MLookup) + { + MLookup mLookup = (MLookup)dependentField.getLookup(); + // log.trace(log.l6_Database, "Lookup Validation", mLookup.getValidation()); + // if the lookup is dynamic (i.e. contains this columnName as variable) + if (mLookup.getValidation().indexOf("@"+columnName+"@") != -1) + { + log.fine(columnName + " changed - " + + dependentField.getColumnName() + " set to null"); + // invalidate current selection + setValue(dependentField, null); + } + } + } // for all dependent fields + } // processDependencies + + + /************************************************************************** + * Process Callout(s). + *

+ * The Callout is in the string of + * "class.method;class.method;" + * If there is no class name, i.e. only a method name, the class is regarded + * as CalloutSystem. + * The class needs to comply with the Interface Callout. + * + * For a limited time, the old notation of Sx_matheod / Ux_menthod is maintained. + * + * @param field field + * @return error message or "" + * @see org.compiere.model.Callout + */ + private String processCallout (GridField field) + { + String callout = field.getCallout(); + if (callout.length() == 0) + return ""; + // + if (isProcessed()) // only active records + return ""; // "DocProcessed"; + + Object value = field.getValue(); + Object oldValue = field.getOldValue(); + log.fine(field.getColumnName() + "=" + value + + " (" + callout + ") - old=" + oldValue); + + StringTokenizer st = new StringTokenizer(callout, ";,", false); + while (st.hasMoreTokens()) // for each callout + { + String cmd = st.nextToken().trim(); + Callout call = null; + String method = null; + int methodStart = cmd.lastIndexOf("."); + try + { + if (methodStart != -1) // no class + { + Class cClass = Class.forName(cmd.substring(0,methodStart)); + call = (Callout)cClass.newInstance(); + method = cmd.substring(methodStart+1); + } + } + catch (Exception e) + { + log.log(Level.SEVERE, "class", e); + return "Callout Invalid: " + cmd + " (" + e.toString() + ")"; + } + + if (call == null || method == null || method.length() == 0) + return "Callout Invalid: " + method; + + String retValue = ""; + try + { + retValue = call.start(m_vo.ctx, method, m_vo.WindowNo, this, field, value, oldValue); + } + catch (Exception e) + { + log.log(Level.SEVERE, "start", e); + retValue = "Callout Invalid: " + e.toString(); + return retValue; + } + if (!retValue.equals("")) // interrupt on first error + { + log.severe (retValue); + return retValue; + } + } // for each callout + return ""; + } // processCallout + + + /** + * Get Value of Field with columnName + * @param columnName column name + * @return value + */ + public Object getValue (String columnName) + { + if (columnName == null) + return null; + GridField field = m_mTable.getField(columnName); + return getValue(field); + } // getValue + + /** + * Get Value of Field + * @param field field + * @return value + */ + public Object getValue (GridField field) + { + if (field == null) + return null; + return field.getValue(); + } // getValue + + /** + * Get Value of Field in row + * @param row row + * @param columnName column name + * @return value + */ + public Object getValue (int row, String columnName) + { + int col = m_mTable.findColumn(columnName); + if (col == -1) + return null; + return m_mTable.getValueAt(row, col); + } // getValue + + public boolean isNeedToSaveParent() + { + if (isDetail()) + return m_parentNeedSave; + else + return false; + } + + /** + * toString + * @return String representation + */ + public String toString() + { + String retValue = "MTab #" + m_vo.TabNo; + if (m_vo != null) + retValue += " " + m_vo.Name + " (" + m_vo.AD_Tab_ID + ")"; + return retValue; + } // toString + + + /************************************************************************** + * @param l listener + */ + public synchronized void removePropertyChangeListener(PropertyChangeListener l) + { + m_propertyChangeSupport.removePropertyChangeListener(l); + } + /** + * @param l listener + */ + public synchronized void addPropertyChangeListener(PropertyChangeListener l) + { + m_propertyChangeSupport.addPropertyChangeListener(l); + } + + /** + * @param l listener + */ + public synchronized void removeDataStatusListener(DataStatusListener l) + { + m_listenerList.remove(DataStatusListener.class, l); + } + /** + * @param l listener + */ + public synchronized void addDataStatusListener(DataStatusListener l) + { + m_listenerList.add(DataStatusListener.class, l); + } + +} // MTab diff --git a/base/src/org/compiere/model/MBPBankAccount.java b/base/src/org/compiere/model/MBPBankAccount.java index 2d86be58a2..52f61634e9 100644 --- a/base/src/org/compiere/model/MBPBankAccount.java +++ b/base/src/org/compiere/model/MBPBankAccount.java @@ -3,95 +3,216 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; import java.sql.*; import java.util.*; +import java.util.logging.Level; + +import org.compiere.util.CLogger; +import org.compiere.util.DB; /** * BP Bank Account Model - * - * @author Jorg Janke - * @version $Id: MBPBankAccount.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ + * + * @author Jorg Janke + * @version $Id: MBPBankAccount.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ public class MBPBankAccount extends X_C_BP_BankAccount { + /** + * Get Accounst Of BPartner + * @param ctx context + * @param C_BPartner_ID bpartner + * @return + */ + public static MBPBankAccount[] getOfBPartner (Properties ctx, int C_BPartner_ID) + { + String sql = "SELECT * FROM C_BP_BankAccount WHERE C_BPartner_ID=? AND IsActive='Y'"; + ArrayList list = new ArrayList(); + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, C_BPartner_ID); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + list.add(new MBPBankAccount(ctx, rs, null)); + } + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } catch (Exception e) { + pstmt = null; + } + + + MBPBankAccount[] retValue = new MBPBankAccount[list.size()]; + list.toArray(retValue); + return retValue; + } // getOfBPartner + + /** Logger */ + private static CLogger s_log = CLogger.getCLogger(MBPBankAccount.class); + + /************************************************************************** * Constructor * @param ctx context * @param C_BP_BankAccount_ID BP bank account - * @param trxName transaction - */ - public MBPBankAccount (Properties ctx, int C_BP_BankAccount_ID, String trxName) - { - super (ctx, C_BP_BankAccount_ID, trxName); - if (C_BP_BankAccount_ID == 0) + * @param trxName transaction + */ + public MBPBankAccount (Properties ctx, int C_BP_BankAccount_ID, String trxName) + { + super (ctx, C_BP_BankAccount_ID, trxName); + if (C_BP_BankAccount_ID == 0) { // setC_BPartner_ID (0); setIsACH (false); + setBPBankAcctUse(BPBANKACCTUSE_Both); } } // MBP_BankAccount - /** - * Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MBPBankAccount (Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MBP_BankAccount - - /** - * Constructor - * @param ctx context - * @param bp BP - * @param bpc BP Contact - * @param location Location + /** + * Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MBPBankAccount (Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MBP_BankAccount + + /** + * Constructor + * @param ctx context + * @param bp BP + * @param bpc BP Contact + * @param location Location */ public MBPBankAccount (Properties ctx, MBPartner bp, MUser bpc, MLocation location) { - super(ctx, 0, bp.get_TrxName()); + this(ctx, 0, bp.get_TrxName()); setIsACH (false); // setC_BPartner_ID(bp.getC_BPartner_ID()); - // - setA_Name(bpc.getName()); - setA_EMail(bpc.getEMail()); - // - setA_Street(location.getAddress1()); - setA_City(location.getCity()); - setA_Zip(location.getPostal()); - setA_State(location.getRegionName(true)); + // + setA_Name(bpc.getName()); + setA_EMail(bpc.getEMail()); + // + setA_Street(location.getAddress1()); + setA_City(location.getCity()); + setA_Zip(location.getPostal()); + setA_State(location.getRegionName(true)); setA_Country(location.getCountryName()); } // MBP_BankAccount + /** Bank Link */ + private MBank m_bank = null; - /*************************************************************************/ + /** + * Is Direct Deposit + * @return true if dd + */ + public boolean isDirectDeposit() + { + if (!isACH()) + return false; + String s = getBPBankAcctUse(); + if (s == null) + return true; + return (s.equals(BPBANKACCTUSE_Both) || s.equals(BPBANKACCTUSE_DirectDeposit)); + } // isDirectDeposit + + /** + * Is Direct Debit + * @return true if dd + */ + public boolean isDirectDebit() + { + if (!isACH()) + return false; + String s = getBPBankAcctUse(); + if (s == null) + return true; + return (s.equals(BPBANKACCTUSE_Both) || s.equals(BPBANKACCTUSE_DirectDebit)); + } // isDirectDebit + + + /** + * Get Bank + * @return bank + */ + public MBank getBank() + { + int C_BP_BankAccount_ID = getC_BP_BankAccount_ID(); + if (C_BP_BankAccount_ID == 0) + return null; + if (m_bank == null) + m_bank = new MBank (getCtx(), C_BP_BankAccount_ID, get_TrxName()); + return m_bank; + } // getBank + + /** + * Get Routing No + * @return routing No + */ + public String getRoutingNo() + { + MBank bank = getBank(); + String rt = super.getRoutingNo(); + if (bank != null) + rt = bank.getRoutingNo(); + return rt; + } // getRoutingNo + /** + * Before Save + * @param newRecord new + * @return true + */ + protected boolean beforeSave(boolean newRecord) + { + // maintain routing on bank level + if (isACH() && getBank() != null) + setRoutingNo(null); + // + return true; + } // beforeSave + /** * String Representation * @return info */ - public String toString () - { - StringBuffer sb = new StringBuffer ("MBP_BankAccount[") - .append (get_ID ()) - .append(", Name=").append(getA_Name()) - .append ("]"); - return sb.toString (); - } // toString - -} // MBPBankAccount + public String toString () + { + StringBuffer sb = new StringBuffer ("MBP_BankAccount[") + .append (get_ID ()) + .append(", Name=").append(getA_Name()) + .append ("]"); + return sb.toString (); + } // toString + +} // MBPBankAccount diff --git a/base/src/org/compiere/model/MChat.java b/base/src/org/compiere/model/MChat.java index e483580912..a5a1f5308c 100644 --- a/base/src/org/compiere/model/MChat.java +++ b/base/src/org/compiere/model/MChat.java @@ -3,237 +3,238 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.sql.*; -import java.text.*; -import java.util.*; -import java.util.logging.*; -import org.apache.ecs.xhtml.*; -import org.compiere.util.*; - -/** - * Chat Model - * - * @author Jorg Janke - * @version $Id: MChat.java,v 1.4 2006/07/30 00:51:05 jjanke Exp $ - */ -public class MChat extends X_CM_Chat -{ - /** - * Get Chats Of Table - of client in context - * @param ctx context - * @param AD_Table_ID table - * @return array of chats - */ - public static MChat[] getOfTable (Properties ctx, int AD_Table_ID) - { - int AD_Client_ID = Env.getAD_Client_ID(ctx); - ArrayList list = new ArrayList(); - // - String sql = "SELECT * FROM CM_Chat " - + "WHERE AD_Client_ID=? AND AD_Table_ID=? ORDER BY Record_ID"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, null); - pstmt.setInt (1, AD_Client_ID); - pstmt.setInt (2, AD_Table_ID); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - list.add (new MChat (ctx, rs, null)); - } - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - s_log.log (Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - // - MChat[] retValue = new MChat[list.size()]; - list.toArray (retValue); - return retValue; - } // get - - /** Logger */ - private static CLogger s_log = CLogger.getCLogger (MChat.class); - - - /************************************************************************** - * Standard Constructor - * @param ctx context - * @param CM_Chat_ID id - * @param trxName transcation - */ - public MChat (Properties ctx, int CM_Chat_ID, String trxName) - { - super (ctx, CM_Chat_ID, trxName); - if (CM_Chat_ID == 0) - { + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.sql.*; +import java.text.*; +import java.util.*; +import java.util.logging.*; +import org.apache.ecs.xhtml.*; +import org.compiere.util.*; + +/** + * Chat Model + * + * @author Jorg Janke + * @version $Id: MChat.java,v 1.4 2006/07/30 00:51:05 jjanke Exp $ + */ +public class MChat extends X_CM_Chat +{ + /** + * Get Chats Of Table - of client in context + * @param ctx context + * @param AD_Table_ID table + * @return array of chats + */ + public static MChat[] getOfTable (Properties ctx, int AD_Table_ID) + { + int AD_Client_ID = Env.getAD_Client_ID(ctx); + ArrayList list = new ArrayList(); + // + String sql = "SELECT * FROM CM_Chat " + + "WHERE AD_Client_ID=? AND AD_Table_ID=? ORDER BY Record_ID"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, null); + pstmt.setInt (1, AD_Client_ID); + pstmt.setInt (2, AD_Table_ID); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + list.add (new MChat (ctx, rs, null)); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + s_log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // + MChat[] retValue = new MChat[list.size()]; + list.toArray (retValue); + return retValue; + } // get + + /** Logger */ + private static CLogger s_log = CLogger.getCLogger (MChat.class); + + + /************************************************************************** + * Standard Constructor + * @param ctx context + * @param CM_Chat_ID id + * @param trxName transcation + */ + public MChat (Properties ctx, int CM_Chat_ID, String trxName) + { + super (ctx, CM_Chat_ID, trxName); + if (CM_Chat_ID == 0) + { // setAD_Table_ID (0); // setRecord_ID (0); setConfidentialType (CONFIDENTIALTYPE_PublicInformation); + setModerationType (MODERATIONTYPE_NotModerated); // setDescription (null); } } // MChat - - /** - * Full Constructor - * @param ctx context - * @param AD_Table_ID table - * @param Record_ID record - * @param Description description - * @param trxName transaction - */ - public MChat (Properties ctx, int AD_Table_ID, int Record_ID, - String Description, String trxName) - { - this (ctx, 0, trxName); - setAD_Table_ID (AD_Table_ID); - setRecord_ID (Record_ID); - setDescription (Description); - } // MChat - - /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MChat (Properties ctx, ResultSet rs, String trxName) - { - super (ctx, rs, trxName); - } // MChat - - /** The Lines */ - private MChatEntry[] m_entries = null; - /** Date Format */ - private SimpleDateFormat m_format = null; - - - /** - * Get Entries - * @param reload reload data - * @return array of lines - */ - public MChatEntry[] getEntries (boolean reload) - { - if (m_entries != null && !reload) - return m_entries; - ArrayList list = new ArrayList(); - String sql = "SELECT * FROM CM_ChatEntry WHERE CM_Chat_ID=? ORDER BY Created"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, null); - pstmt.setInt (1, getCM_Chat_ID()); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - list.add (new MChatEntry (getCtx(), rs, get_TrxName())); - } - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - log.log (Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - // - m_entries = new MChatEntry[list.size ()]; - list.toArray (m_entries); - return m_entries; - } // getEntries - - - /** - * Set Description - * - * @param Description - */ - public void setDescription (String Description) - { - if (Description != null && Description.length() > 0) - super.setDescription (Description); - else - super.setDescription (getAD_Table_ID() + "#" + getRecord_ID()); - } // setDescription - - /** - * Get History as htlp paragraph - * @param ConfidentialType confidentiality - * @return html paragraph - */ - public p getHistory (String ConfidentialType) - { - p history = new p(); - getEntries(false); - boolean first = true; - for (int i = 0; i < m_entries.length; i++) - { - MChatEntry entry = m_entries[i]; - if (!entry.isActive() || !entry.isConfidentialType(ConfidentialType)) - continue; - if (first) - first = false; - else - history.addElement(new hr()); - // User & Date - b b = new b(); - MUser user = MUser.get(getCtx(), entry.getCreatedBy()); - b.addElement(user.getName()); - b.addElement(" \t"); - Timestamp created = entry.getCreated(); - if (m_format == null) - m_format = DisplayType.getDateFormat(DisplayType.DateTime); - b.addElement(m_format.format(created)); - history.addElement(b); - // history.addElement(new br()); - // - p p = new p(); - String data = entry.getCharacterData(); - data = Util.maskHTML(data, true); - p.addElement(data); - history.addElement(p); - } // entry - // - return history; - } // getHistory - - -} // MChat + + /** + * Full Constructor + * @param ctx context + * @param AD_Table_ID table + * @param Record_ID record + * @param Description description + * @param trxName transaction + */ + public MChat (Properties ctx, int AD_Table_ID, int Record_ID, + String Description, String trxName) + { + this (ctx, 0, trxName); + setAD_Table_ID (AD_Table_ID); + setRecord_ID (Record_ID); + setDescription (Description); + } // MChat + + /** + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MChat (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } // MChat + + /** The Lines */ + private MChatEntry[] m_entries = null; + /** Date Format */ + private SimpleDateFormat m_format = null; + + + /** + * Get Entries + * @param reload reload data + * @return array of lines + */ + public MChatEntry[] getEntries (boolean reload) + { + if (m_entries != null && !reload) + return m_entries; + ArrayList list = new ArrayList(); + String sql = "SELECT * FROM CM_ChatEntry WHERE CM_Chat_ID=? ORDER BY Created"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, null); + pstmt.setInt (1, getCM_Chat_ID()); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + list.add (new MChatEntry (getCtx(), rs, get_TrxName())); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // + m_entries = new MChatEntry[list.size ()]; + list.toArray (m_entries); + return m_entries; + } // getEntries + + + /** + * Set Description + * + * @param Description + */ + public void setDescription (String Description) + { + if (Description != null && Description.length() > 0) + super.setDescription (Description); + else + super.setDescription (getAD_Table_ID() + "#" + getRecord_ID()); + } // setDescription + + /** + * Get History as htlp paragraph + * @param ConfidentialType confidentiality + * @return html paragraph + */ + public p getHistory (String ConfidentialType) + { + p history = new p(); + getEntries(false); + boolean first = true; + for (int i = 0; i < m_entries.length; i++) + { + MChatEntry entry = m_entries[i]; + if (!entry.isActive() || !entry.isConfidentialType(ConfidentialType)) + continue; + if (first) + first = false; + else + history.addElement(new hr()); + // User & Date + b b = new b(); + MUser user = MUser.get(getCtx(), entry.getCreatedBy()); + b.addElement(user.getName()); + b.addElement(" \t"); + Timestamp created = entry.getCreated(); + if (m_format == null) + m_format = DisplayType.getDateFormat(DisplayType.DateTime); + b.addElement(m_format.format(created)); + history.addElement(b); + // history.addElement(new br()); + // + p p = new p(); + String data = entry.getCharacterData(); + data = Util.maskHTML(data, true); + p.addElement(data); + history.addElement(p); + } // entry + // + return history; + } // getHistory + + +} // MChat diff --git a/base/src/org/compiere/model/MChatEntry.java b/base/src/org/compiere/model/MChatEntry.java index 1e7055be3d..7b209c7973 100644 --- a/base/src/org/compiere/model/MChatEntry.java +++ b/base/src/org/compiere/model/MChatEntry.java @@ -3,91 +3,116 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; import java.sql.*; import java.util.*; -import org.compiere.util.*; /** * Chat Entry Model - * - * @author Jorg Janke - * @version $Id: MChatEntry.java,v 1.2 2006/07/30 00:51:03 jjanke Exp $ - */ -public class MChatEntry extends X_CM_ChatEntry -{ - /** - * Standard Constructor - * @param ctx cintext - * @param CM_ChatEntry_ID id - * @param trxName transaction - */ + * + * @author Jorg Janke + * @version $Id: MChatEntry.java,v 1.2 2006/07/30 00:51:03 jjanke Exp $ + */ +public class MChatEntry extends X_CM_ChatEntry +{ + /** + * Standard Constructor + * @param ctx cintext + * @param CM_ChatEntry_ID id + * @param trxName transaction + */ public MChatEntry (Properties ctx, int CM_ChatEntry_ID, String trxName) { super (ctx, CM_ChatEntry_ID, trxName); + if (CM_ChatEntry_ID == 0) + { + setChatEntryType (CHATENTRYTYPE_NoteFlat); // N + setConfidentialType (CONFIDENTIALTYPE_PublicInformation); + } } // MChatEntry /** - * Parent Constructor - * @param chat parent - * @param data text - */ - public MChatEntry (MChat chat, String data) - { - this (chat.getCtx(), 0, chat.get_TrxName()); + * Parent Constructor + * @param chat parent + * @param data text + */ + public MChatEntry (MChat chat, String data) + { + this (chat.getCtx(), 0, chat.get_TrxName()); setCM_Chat_ID(chat.getCM_Chat_ID()); setConfidentialType(chat.getConfidentialType()); setCharacterData(data); + setChatEntryType (CHATENTRYTYPE_NoteFlat); // N } // MChatEntry /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction + * Thread Constructor + * @param entry peer + * @param data text */ - public MChatEntry (Properties ctx, ResultSet rs, String trxName) + public MChatEntry (MChatEntry peer, String data) { - super (ctx, rs, trxName); + this (peer.getCtx(), 0, peer.get_TrxName()); + setCM_Chat_ID(peer.getCM_Chat_ID()); + setCM_ChatEntryParent_ID (peer.getCM_ChatEntryParent_ID()); + // Set GrandParent + int id = peer.getCM_ChatEntryGrandParent_ID(); + if (id == 0) + id = peer.getCM_ChatEntryParent_ID(); + setCM_ChatEntryGrandParent_ID (id); + setConfidentialType(peer.getConfidentialType()); + setCharacterData(data); + setChatEntryType (CHATENTRYTYPE_ForumThreaded); } // MChatEntry /** - * Can be published - * @param ConfidentialType minimum confidential type - * @return true if withing confidentiality - */ - public boolean isConfidentialType(String ConfidentialType) - { - String ct = getConfidentialType(); - if (ConfidentialType == null - || CONFIDENTIALTYPE_PublicInformation.equals(ct)) - return true; - if (CONFIDENTIALTYPE_PartnerConfidential.equals(ct)) - { - return CONFIDENTIALTYPE_PartnerConfidential.equals(ConfidentialType); - } - else if (CONFIDENTIALTYPE_PrivateInformation.equals(ct)) - { - return CONFIDENTIALTYPE_Internal.equals(ConfidentialType) - || CONFIDENTIALTYPE_PrivateInformation.equals(ConfidentialType); - } - else if (CONFIDENTIALTYPE_Internal.equals(ct)) - { - return CONFIDENTIALTYPE_Internal.equals(ConfidentialType); - } - return false; - } // - -} // MChatEntry + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MChatEntry (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } // MChatEntry + + /** + * Can be published + * @param ConfidentialType minimum confidential type + * @return true if withing confidentiality + */ + public boolean isConfidentialType(String ConfidentialType) + { + String ct = getConfidentialType(); + if (ConfidentialType == null + || CONFIDENTIALTYPE_PublicInformation.equals(ct)) + return true; + if (CONFIDENTIALTYPE_PartnerConfidential.equals(ct)) + { + return CONFIDENTIALTYPE_PartnerConfidential.equals(ConfidentialType); + } + else if (CONFIDENTIALTYPE_PrivateInformation.equals(ct)) + { + return CONFIDENTIALTYPE_Internal.equals(ConfidentialType) + || CONFIDENTIALTYPE_PrivateInformation.equals(ConfidentialType); + } + else if (CONFIDENTIALTYPE_Internal.equals(ct)) + { + return CONFIDENTIALTYPE_Internal.equals(ConfidentialType); + } + return false; + } // + +} // MChatEntry diff --git a/base/src/org/compiere/model/MChatType.java b/base/src/org/compiere/model/MChatType.java index 25c3ddbb14..5e5c653984 100644 --- a/base/src/org/compiere/model/MChatType.java +++ b/base/src/org/compiere/model/MChatType.java @@ -3,73 +3,75 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.sql.*; -import java.util.*; -import org.compiere.util.*; - -/** - * Chat Type Model - * - * @author Jorg Janke - * @version $Id: MChatType.java,v 1.2 2006/07/30 00:51:03 jjanke Exp $ - */ -public class MChatType extends X_CM_ChatType -{ - /** - * Get MChatType from Cache - * @param ctx context - * @param CM_ChatType_ID id - * @return MChatType - */ - public static MChatType get (Properties ctx, int CM_ChatType_ID) - { - Integer key = new Integer (CM_ChatType_ID); - MChatType retValue = (MChatType)s_cache.get (key); - if (retValue != null) - return retValue; - retValue = new MChatType (ctx, CM_ChatType_ID, null); - if (retValue.get_ID () != CM_ChatType_ID) - s_cache.put (key, retValue); - return retValue; - } // get - - /** Cache */ - private static CCache s_cache - = new CCache ("CM_ChatType", 20); - - /** - * Standard Constructor - * @param ctx context - * @param CM_ChatType_ID id - * @param trxName transaction - */ + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.sql.*; +import java.util.*; +import org.compiere.util.*; + +/** + * Chat Type Model + * + * @author Jorg Janke + * @version $Id: MChatType.java,v 1.2 2006/07/30 00:51:03 jjanke Exp $ + */ +public class MChatType extends X_CM_ChatType +{ + /** + * Get MChatType from Cache + * @param ctx context + * @param CM_ChatType_ID id + * @return MChatType + */ + public static MChatType get (Properties ctx, int CM_ChatType_ID) + { + Integer key = new Integer (CM_ChatType_ID); + MChatType retValue = (MChatType)s_cache.get (key); + if (retValue != null) + return retValue; + retValue = new MChatType (ctx, CM_ChatType_ID, null); + if (retValue.get_ID () != CM_ChatType_ID) + s_cache.put (key, retValue); + return retValue; + } // get + + /** Cache */ + private static CCache s_cache + = new CCache ("CM_ChatType", 20); + + /** + * Standard Constructor + * @param ctx context + * @param CM_ChatType_ID id + * @param trxName transaction + */ public MChatType (Properties ctx, int CM_ChatType_ID, String trxName) { super (ctx, CM_ChatType_ID, trxName); + if (CM_ChatType_ID == 0) + setModerationType (MODERATIONTYPE_NotModerated); } // MChatType /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MChatType (Properties ctx, ResultSet rs, String trxName) - { - super (ctx, rs, trxName); - } // MChatType - -} // MChatType + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MChatType (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } // MChatType + +} // MChatType diff --git a/base/src/org/compiere/model/MContainer.java b/base/src/org/compiere/model/MContainer.java index a2acedd8a0..e28e74462b 100644 --- a/base/src/org/compiere/model/MContainer.java +++ b/base/src/org/compiere/model/MContainer.java @@ -3,530 +3,616 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.sql.*; -import java.util.*; -import java.util.logging.*; -import org.compiere.util.*; - -/** - * Container Model - * - * @author Yves Sandfort - * @version $Id: MContainer.java,v 1.20 2006/09/05 23:22:53 comdivision Exp $ + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.sql.*; +import java.util.*; +import java.util.logging.*; +import org.compiere.util.*; + +/** + * Container Model + * + * @author Yves Sandfort + * @version $Id: MContainer.java,v 1.20 2006/09/05 23:22:53 comdivision Exp $ */ public class MContainer extends X_CM_Container { - + /** serialVersionUID */ + private static final long serialVersionUID = 395679572291279730L; + + /** + * get Container by Relative URL + * @param ctx + * @param relURL + * @param CM_WebProject_Id + * @param trxName + * @return Container or null if not found + */ + public static MContainer get(Properties ctx, String relURL, int CM_WebProject_Id, String trxName) { + MContainer thisContainer = null; + String sql = "SELECT * FROM CM_Container WHERE (RelativeURL LIKE ? OR RelativeURL LIKE ?) AND CM_WebProject_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, trxName); + pstmt.setString (1,relURL); + pstmt.setString (2,relURL+"/"); + pstmt.setInt(3, CM_WebProject_Id); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + thisContainer = (new MContainer(ctx, rs, trxName)); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + return thisContainer; + } + + + /** + * get Container + * @param ctx + * @param CM_Container_ID + * @param CM_WebProject_Id + * @param trxName + * @return Container or null if not found + */ + public static MContainer get(Properties ctx, int CM_Container_ID, int CM_WebProject_Id, String trxName) { + MContainer thisContainer = null; + String sql = "SELECT * FROM CM_Container WHERE CM_Container_ID=? AND CM_WebProject_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, trxName); + pstmt.setInt(1, CM_Container_ID); + pstmt.setInt(2, CM_WebProject_Id); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + thisContainer = (new MContainer(ctx, rs, trxName)); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + return thisContainer; + } + /** * Copy Stage into Container * - * @param project WebProject - * @param stage Stage to copy from - * @param path Relative URL to it - * @return Container - */ - public static MContainer copy (MWebProject project, MCStage stage, - String path) - { - MContainer cc = getDirect (stage.getCtx(), stage.getCM_CStage_ID (), - stage.get_TrxName ()); - if (cc == null) // new - cc = new MContainer (stage.getCtx (), 0, stage.get_TrxName ()); - cc.setStage (project, stage, path); - cc.save (); - if (!stage.isSummary ()) - { - cc.updateElements (project, stage, stage.get_TrxName ()); - cc.updateTTables (project, stage, stage.get_TrxName ()); - } - return cc; - } // copy - - /** - * Get Container directly from DB (not cached) - * - * @param ctx context - * @param CM_Container_ID Container ID - * @param trxName transaction - * @return Container or null - */ - public static MContainer getDirect (Properties ctx, int CM_Container_ID, - String trxName) - { - MContainer cc = null; - PreparedStatement pstmt = null; - String sql = "SELECT * FROM CM_Container WHERE CM_Container_ID=?"; - try - { - pstmt = DB.prepareStatement (sql, null); - pstmt.setInt (1, CM_Container_ID); - ResultSet rs = pstmt.executeQuery (); - if (rs.next ()) - cc = new MContainer (ctx, rs, trxName); - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - s_log.log (Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - return cc; - } // getDirect - - /** - * Get Containers - * - * @param project - * Project to use - * @return stages - */ - public static MContainer[] getContainers (MWebProject project) - { - ArrayList list = new ArrayList (); - PreparedStatement pstmt = null; - String sql = "SELECT * FROM CM_Container WHERE CM_WebProject_ID=? ORDER BY CM_Container_ID"; - try - { - pstmt = DB.prepareStatement (sql, project.get_TrxName ()); - pstmt.setInt (1, project.getCM_WebProject_ID ()); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - list.add (new MContainer (project.getCtx (), rs, project - .get_TrxName ())); - } - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - s_log.log (Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - MContainer[] retValue = new MContainer[list.size ()]; - list.toArray (retValue); - return retValue; - } // getContainers - - /** Logger */ - private static CLogger s_log = CLogger.getCLogger (MContainer.class); - - - /*************************************************************************** - * Standard Constructor - * - * @param ctx context - * @param CM_Container_ID id - * @param trxName transaction - */ - public MContainer (Properties ctx, int CM_Container_ID, String trxName) - { - super (ctx, CM_Container_ID, trxName); - if (CM_Container_ID == 0) - { - setIsValid(false); - setIsIndexed(false); - setIsSecure(false); - setIsSummary(false); - } - } // MContainer - - /** - * Load Constructor - * - * @param ctx - * context - * @param rs - * result set - * @param trxName - * transaction - */ - public MContainer (Properties ctx, ResultSet rs, String trxName) - { - super (ctx, rs, trxName); - } // MContainer - - /** Web Project */ - private MWebProject m_project = null; - - /** Stage Source */ - private MCStage m_stage = null; - - /** Template */ - private MTemplate m_template = null; - - /** - * Get Web Project - * - * @return web project - */ - public MWebProject getWebProject () - { - if (m_project == null) - m_project = MWebProject.get (getCtx (), getCM_WebProject_ID ()); - return m_project; - } // getWebProject - - /** - * Get Template from Cache, or load it - * @return Template - */ - public MTemplate getTemplate() - { - if (getCM_Template_ID()>0 && m_template==null) - m_template = MTemplate.get(getCtx(), getCM_Template_ID(), null); - return m_template; - } // getTemplate - - /** - * Get AD_Tree_ID - * - * @return tree - */ - public int getAD_Tree_ID () - { - return getWebProject ().getAD_TreeCMC_ID (); - } // getAD_Tree_ID; - - /** - * Set/Copy Stage - * - * @param project - * parent - * @param stage - * stage - * @param path - * path - */ - protected void setStage (MWebProject project, MCStage stage, String path) - { - m_stage = stage; - PO.copyValues (stage, this); - setAD_Client_ID (project.getAD_Client_ID ()); - setAD_Org_ID (project.getAD_Org_ID ()); - setIsActive (stage.isActive ()); - setCM_ContainerLink_ID (stage.getCM_CStageLink_ID ()); - // - setRelativeURL (path + stage.getRelativeURL ()); - // - if (getMeta_Author () == null || getMeta_Author ().length () == 0) - setMeta_Author (project.getMeta_Author ()); - if (getMeta_Content () == null || getMeta_Content ().length () == 0) - setMeta_Content (project.getMeta_Content ()); - if (getMeta_Copyright () == null || getMeta_Copyright ().length () == 0) - setMeta_Copyright (project.getMeta_Copyright ()); - if (getMeta_Publisher () == null || getMeta_Publisher ().length () == 0) - setMeta_Publisher (project.getMeta_Publisher ()); - if (getMeta_RobotsTag () == null || getMeta_RobotsTag ().length () == 0) - setMeta_RobotsTag (project.getMeta_RobotsTag ()); - } // setStage - - /** - * Update Elements in Container from Stage - * - * @param project - * project - * @param stage - * stage - * @param trxName - * Transaction - */ - protected void updateElements (MWebProject project, MCStage stage, - String trxName) - { - org.compiere.cm.CacheHandler thisHandler = new org.compiere.cm.CacheHandler ( - org.compiere.cm.CacheHandler.convertJNPURLToCacheURL (getCtx () - .getProperty ("java.naming.provider.url")), log, getCtx (), - get_TrxName ()); - // First update the new ones... - int[] tableKeys = X_CM_CStage_Element.getAllIDs ("CM_CStage_Element", - "CM_CStage_ID=" + stage.get_ID (), trxName); - if (tableKeys != null && tableKeys.length > 0) - { - for (int i = 0; i < tableKeys.length; i++) - { - X_CM_CStage_Element thisStageElement = new X_CM_CStage_Element ( - project.getCtx (), tableKeys[i], trxName); - int[] thisContainerElementKeys = X_CM_Container_Element - .getAllIDs ("CM_Container_Element", "CM_Container_ID=" - + stage.get_ID () + " AND Name LIKE '" - + thisStageElement.getName () + "'", trxName); - X_CM_Container_Element thisContainerElement; - if (thisContainerElementKeys != null - && thisContainerElementKeys.length > 0) - { - thisContainerElement = new X_CM_Container_Element (project - .getCtx (), thisContainerElementKeys[0], trxName); - } - else - { - thisContainerElement = new X_CM_Container_Element (project - .getCtx (), 0, trxName); - } - thisContainerElement.setCM_Container_ID (stage.get_ID ()); - X_CM_CStage_Element stageElement = new X_CM_CStage_Element ( - project.getCtx (), tableKeys[i], trxName); - thisContainerElement.setName (stageElement.getName ()); - thisContainerElement.setDescription (stageElement.getDescription()); - thisContainerElement.setHelp (stageElement.getHelp ()); - thisContainerElement.setIsActive (stageElement.isActive ()); - thisContainerElement.setIsValid (stageElement.isValid ()); - String contentHTML = thisStageElement.getContentHTML (); - thisContainerElement.setContentHTML (contentHTML); - // PO.copyValues(new - // X_CM_CStage_Element(project.getCtx(),tableKeys[i],trxName), - // thisContainerElement); - thisContainerElement.save (trxName); - // Remove Container from cache - thisHandler.cleanContainerElement (thisContainerElement - .get_ID ()); - } - } - // Now we are checking the existing ones to delete the unneeded ones... - tableKeys = X_CM_Container_Element.getAllIDs ("CM_Container_Element", - "CM_Container_ID=" + stage.get_ID (), trxName); - if (tableKeys != null && tableKeys.length > 0) - { - for (int i = 0; i < tableKeys.length; i++) - { - X_CM_Container_Element thisContainerElement = new X_CM_Container_Element ( - project.getCtx (), tableKeys[i], trxName); - int[] thisCStageElementKeys = X_CM_CStage_Element - .getAllIDs ("CM_CStage_Element", "CM_CStage_ID=" - + stage.get_ID () + " AND Name LIKE '" - + thisContainerElement.getName () + "'", trxName); - // If we cannot find a representative in the Stage we will delete from production - if (thisCStageElementKeys == null - || thisCStageElementKeys.length < 1) - { - // First delete it from cache, then delete the record itself - thisHandler.cleanContainerElement (thisContainerElement - .get_ID ()); - thisContainerElement.delete (true); - } - } - } - } - - /** - * Update Elements in Container from Stage - * - * @param project - * project - * @param stage - * stage - * @param trxName - * Transaction - */ - protected void updateTTables (MWebProject project, MCStage stage, - String trxName) - { - int[] tableKeys = X_CM_CStageTTable.getAllIDs ("CM_CStageTTable", - "CM_CStage_ID=" + stage.get_ID (), trxName); - if (tableKeys != null && tableKeys.length > 0) - { - for (int i = 0; i < tableKeys.length; i++) - { - X_CM_CStageTTable thisStageTTable = new X_CM_CStageTTable ( - project.getCtx (), tableKeys[i], trxName); - int[] thisContainerTTableKeys = X_CM_ContainerTTable.getAllIDs ( - "CM_ContainerTTable", "CM_Container_ID=" + stage.get_ID () - + " AND CM_TemplateTable_ID=" - + thisStageTTable.getCM_TemplateTable_ID (), trxName); - X_CM_ContainerTTable thisContainerTTable; - if (thisContainerTTableKeys != null - && thisContainerTTableKeys.length > 0) - { - thisContainerTTable = new X_CM_ContainerTTable (project - .getCtx (), thisContainerTTableKeys[0], trxName); - } - else - { - thisContainerTTable = new X_CM_ContainerTTable (project - .getCtx (), 0, trxName); - } - thisContainerTTable.setCM_Container_ID (stage.get_ID ()); - PO.copyValues (new X_CM_CStageTTable (project.getCtx (), - tableKeys[i], trxName), thisContainerTTable); - thisContainerTTable.save (trxName); - } - } - } - - /** - * SaveNew getID - * - * @return ID - */ - protected int saveNew_getID () - { - if (m_stage != null) - return m_stage.getCM_CStage_ID (); - return 0; - } // saveNew_getID - - /** - * String Representation - * - * @return info - */ - public String toString () - { - StringBuffer sb = new StringBuffer ("MContainer[").append (get_ID ()) - .append ("-").append (getName ()).append ("]"); - return sb.toString (); - } // toString - - /** - * After Save. Insert - create tree - * - * @param newRecord - * insert - * @param success - * save success - * @return true if saved - */ - protected boolean afterSave (boolean newRecord, boolean success) - { - if (!success) - return success; - if (newRecord) - { - StringBuffer sb = new StringBuffer ( - "INSERT INTO AD_TreeNodeCMC " - + "(AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, " - + "AD_Tree_ID, Node_ID, Parent_ID, SeqNo) " + "VALUES (") - .append (getAD_Client_ID ()).append ( - ",0, 'Y', SysDate, 0, SysDate, 0,").append ( - getAD_Tree_ID ()).append (",").append (get_ID ()).append ( - ", 0, 999)"); - int no = DB.executeUpdate (sb.toString (), get_TrxName ()); - if (no > 0) - log.fine ("#" + no + " - TreeType=CMC"); - else - log.warning ("#" + no + " - TreeType=CMC"); - return no > 0; - } - return success; - } // afterSave - - protected MContainerElement[] getAllElements() - { - int elements[] = MContainerElement.getAllIDs("CM_Container_Element", "CM_Container_ID=" + get_ID(), get_TrxName()); - if (elements.length>0) - { - MContainerElement[] containerElements = new MContainerElement[elements.length]; - for (int i=0;i 0; - } - - /** - * After Delete - * - * @param success - * @return deleted - */ - protected boolean afterDelete (boolean success) - { - if (!success) - return success; - // - StringBuffer sb = new StringBuffer ("DELETE FROM AD_TreeNodeCMC ") - .append (" WHERE Node_ID=").append (get_IDOld ()).append ( - " AND AD_Tree_ID=").append (getAD_Tree_ID ()); - int no = DB.executeUpdate (sb.toString (), get_TrxName ()); - // If 0 than there is nothing to delete which is okay. - if (no > 0) - log.fine ("#" + no + " - TreeType=CMC"); - else - log.warning ("#" + no + " - TreeType=CMC"); - return true; - } // afterDelete - - /** - * reIndex - * @param newRecord - */ - public void reIndex(boolean newRecord) - { - String [] toBeIndexed = new String[8]; - toBeIndexed[0] = this.getName(); - toBeIndexed[1] = this.getDescription(); - toBeIndexed[2] = this.getRelativeURL(); - toBeIndexed[3] = this.getMeta_Author(); - toBeIndexed[4] = this.getMeta_Copyright(); - toBeIndexed[5] = this.getMeta_Description(); - toBeIndexed[6] = this.getMeta_Keywords(); - toBeIndexed[7] = this.getMeta_Publisher(); - MIndex.reIndex (newRecord, toBeIndexed, getCtx(), getAD_Client_ID(), get_Table_ID(), get_ID(), getCM_WebProject_ID(), this.getUpdated()); - MContainerElement[] theseElements = getAllElements(); - if (theseElements!=null) - for (int i=0;i list = new ArrayList (); + PreparedStatement pstmt = null; + String sql = "SELECT * FROM CM_Container WHERE CM_WebProject_ID=? ORDER BY CM_Container_ID"; + try + { + pstmt = DB.prepareStatement (sql, project.get_TrxName ()); + pstmt.setInt (1, project.getCM_WebProject_ID ()); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + list.add (new MContainer (project.getCtx (), rs, project + .get_TrxName ())); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + s_log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + MContainer[] retValue = new MContainer[list.size ()]; + list.toArray (retValue); + return retValue; + } // getContainers + + /** Logger */ + private static CLogger s_log = CLogger.getCLogger (MContainer.class); + + + /*************************************************************************** + * Standard Constructor + * + * @param ctx context + * @param CM_Container_ID id + * @param trxName transaction + */ + public MContainer (Properties ctx, int CM_Container_ID, String trxName) + { + super (ctx, CM_Container_ID, trxName); + if (CM_Container_ID == 0) + { + setIsValid(false); + setIsIndexed(false); + setIsSecure(false); + setIsSummary(false); + } + } // MContainer + + /** + * Load Constructor + * + * @param ctx + * context + * @param rs + * result set + * @param trxName + * transaction + */ + public MContainer (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } // MContainer + + /** Web Project */ + private MWebProject m_project = null; + + /** Stage Source */ + private MCStage m_stage = null; + + /** Template */ + private MTemplate m_template = null; + + /** + * Get Web Project + * + * @return web project + */ + public MWebProject getWebProject () + { + if (m_project == null) + m_project = MWebProject.get (getCtx (), getCM_WebProject_ID ()); + return m_project; + } // getWebProject + + /** + * Get Template from Cache, or load it + * @return Template + */ + public MTemplate getTemplate() + { + if (getCM_Template_ID()>0 && m_template==null) + m_template = MTemplate.get(getCtx(), getCM_Template_ID(), null); + return m_template; + } // getTemplate + + /** + * Get AD_Tree_ID + * + * @return tree + */ + public int getAD_Tree_ID () + { + return getWebProject ().getAD_TreeCMC_ID (); + } // getAD_Tree_ID; + + /** + * Set/Copy Stage + * + * @param project + * parent + * @param stage + * stage + * @param path + * path + */ + protected void setStage (MWebProject project, MCStage stage, String path) + { + m_stage = stage; + PO.copyValues (stage, this); + setAD_Client_ID (project.getAD_Client_ID ()); + setAD_Org_ID (project.getAD_Org_ID ()); + setIsActive (stage.isActive ()); + setCM_ContainerLink_ID (stage.getCM_CStageLink_ID ()); + // + setRelativeURL (path + stage.getRelativeURL ()); + // + if (getMeta_Author () == null || getMeta_Author ().length () == 0) + setMeta_Author (project.getMeta_Author ()); + if (getMeta_Content () == null || getMeta_Content ().length () == 0) + setMeta_Content (project.getMeta_Content ()); + if (getMeta_Copyright () == null || getMeta_Copyright ().length () == 0) + setMeta_Copyright (project.getMeta_Copyright ()); + if (getMeta_Publisher () == null || getMeta_Publisher ().length () == 0) + setMeta_Publisher (project.getMeta_Publisher ()); + if (getMeta_RobotsTag () == null || getMeta_RobotsTag ().length () == 0) + setMeta_RobotsTag (project.getMeta_RobotsTag ()); + } // setStage + + /** + * Update Elements in Container from Stage + * + * @param project + * project + * @param stage + * stage + * @param trxName + * Transaction + */ + protected void updateElements (MWebProject project, MCStage stage, + String trxName) + { + org.compiere.cm.CacheHandler thisHandler = new org.compiere.cm.CacheHandler ( + org.compiere.cm.CacheHandler.convertJNPURLToCacheURL (getCtx () + .getProperty ("java.naming.provider.url")), log, getCtx (), + get_TrxName ()); + // First update the new ones... + int[] tableKeys = X_CM_CStage_Element.getAllIDs ("CM_CStage_Element", + "CM_CStage_ID=" + stage.get_ID (), trxName); + if (tableKeys != null && tableKeys.length > 0) + { + for (int i = 0; i < tableKeys.length; i++) + { + X_CM_CStage_Element thisStageElement = new X_CM_CStage_Element ( + project.getCtx (), tableKeys[i], trxName); + int[] thisContainerElementKeys = X_CM_Container_Element + .getAllIDs ("CM_Container_Element", "CM_Container_ID=" + + stage.get_ID () + " AND Name LIKE '" + + thisStageElement.getName () + "'", trxName); + X_CM_Container_Element thisContainerElement; + if (thisContainerElementKeys != null + && thisContainerElementKeys.length > 0) + { + thisContainerElement = new X_CM_Container_Element (project + .getCtx (), thisContainerElementKeys[0], trxName); + } + else + { + thisContainerElement = new X_CM_Container_Element (project + .getCtx (), 0, trxName); + } + thisContainerElement.setCM_Container_ID (stage.get_ID ()); + X_CM_CStage_Element stageElement = new X_CM_CStage_Element ( + project.getCtx (), tableKeys[i], trxName); + thisContainerElement.setName (stageElement.getName ()); + thisContainerElement.setDescription (stageElement.getDescription()); + thisContainerElement.setHelp (stageElement.getHelp ()); + thisContainerElement.setIsActive (stageElement.isActive ()); + thisContainerElement.setIsValid (stageElement.isValid ()); + String contentHTML = thisStageElement.getContentHTML (); + thisContainerElement.setContentHTML (contentHTML); + // PO.copyValues(new + // X_CM_CStage_Element(project.getCtx(),tableKeys[i],trxName), + // thisContainerElement); + thisContainerElement.save (trxName); + // Remove Container from cache + thisHandler.cleanContainerElement (thisContainerElement + .get_ID ()); + } + } + // Now we are checking the existing ones to delete the unneeded ones... + tableKeys = X_CM_Container_Element.getAllIDs ("CM_Container_Element", + "CM_Container_ID=" + stage.get_ID (), trxName); + if (tableKeys != null && tableKeys.length > 0) + { + for (int i = 0; i < tableKeys.length; i++) + { + X_CM_Container_Element thisContainerElement = new X_CM_Container_Element ( + project.getCtx (), tableKeys[i], trxName); + int[] thisCStageElementKeys = X_CM_CStage_Element + .getAllIDs ("CM_CStage_Element", "CM_CStage_ID=" + + stage.get_ID () + " AND Name LIKE '" + + thisContainerElement.getName () + "'", trxName); + // If we cannot find a representative in the Stage we will delete from production + if (thisCStageElementKeys == null + || thisCStageElementKeys.length < 1) + { + // First delete it from cache, then delete the record itself + thisHandler.cleanContainerElement (thisContainerElement + .get_ID ()); + thisContainerElement.delete (true); + } + } + } + } + + /** + * Update Elements in Container from Stage + * + * @param project + * project + * @param stage + * stage + * @param trxName + * Transaction + */ + protected void updateTTables (MWebProject project, MCStage stage, + String trxName) + { + int[] tableKeys = X_CM_CStageTTable.getAllIDs ("CM_CStageTTable", + "CM_CStage_ID=" + stage.get_ID (), trxName); + if (tableKeys != null && tableKeys.length > 0) + { + for (int i = 0; i < tableKeys.length; i++) + { + X_CM_CStageTTable thisStageTTable = new X_CM_CStageTTable ( + project.getCtx (), tableKeys[i], trxName); + int[] thisContainerTTableKeys = X_CM_ContainerTTable.getAllIDs ( + "CM_ContainerTTable", "CM_Container_ID=" + stage.get_ID () + + " AND CM_TemplateTable_ID=" + + thisStageTTable.getCM_TemplateTable_ID (), trxName); + X_CM_ContainerTTable thisContainerTTable; + if (thisContainerTTableKeys != null + && thisContainerTTableKeys.length > 0) + { + thisContainerTTable = new X_CM_ContainerTTable (project + .getCtx (), thisContainerTTableKeys[0], trxName); + } + else + { + thisContainerTTable = new X_CM_ContainerTTable (project + .getCtx (), 0, trxName); + } + thisContainerTTable.setCM_Container_ID (stage.get_ID ()); + PO.copyValues (new X_CM_CStageTTable (project.getCtx (), + tableKeys[i], trxName), thisContainerTTable); + thisContainerTTable.save (trxName); + } + } + } + + /** + * SaveNew getID + * + * @return ID + */ + protected int saveNew_getID () + { + if (m_stage != null) + return m_stage.getCM_CStage_ID (); + return 0; + } // saveNew_getID + + /** + * String Representation + * + * @return info + */ + public String toString () + { + StringBuffer sb = new StringBuffer ("MContainer[").append (get_ID ()) + .append ("-").append (getName ()).append ("]"); + return sb.toString (); + } // toString + + /** + * After Save. Insert - create tree + * + * @param newRecord + * insert + * @param success + * save success + * @return true if saved + */ + protected boolean afterSave (boolean newRecord, boolean success) + { + if (!success) + return success; + if (newRecord) + { + StringBuffer sb = new StringBuffer ( + "INSERT INTO AD_TreeNodeCMC " + + "(AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, " + + "AD_Tree_ID, Node_ID, Parent_ID, SeqNo) " + "VALUES (") + .append (getAD_Client_ID ()).append ( + ",0, 'Y', SysDate, 0, SysDate, 0,").append ( + getAD_Tree_ID ()).append (",").append (get_ID ()).append ( + ", 0, 999)"); + int no = DB.executeUpdate (sb.toString (), get_TrxName ()); + if (no > 0) + log.fine ("#" + no + " - TreeType=CMC"); + else + log.warning ("#" + no + " - TreeType=CMC"); + return no > 0; + } + return success; + } // afterSave + + protected MContainerElement[] getAllElements() + { + int elements[] = MContainerElement.getAllIDs("CM_Container_Element", "CM_Container_ID=" + get_ID(), get_TrxName()); + if (elements.length>0) + { + MContainerElement[] containerElements = new MContainerElement[elements.length]; + for (int i=0;i 0; + } + + /** + * After Delete + * + * @param success + * @return deleted + */ + protected boolean afterDelete (boolean success) + { + if (!success) + return success; + // + StringBuffer sb = new StringBuffer ("DELETE FROM AD_TreeNodeCMC ") + .append (" WHERE Node_ID=").append (get_IDOld ()).append ( + " AND AD_Tree_ID=").append (getAD_Tree_ID ()); + int no = DB.executeUpdate (sb.toString (), get_TrxName ()); + // If 0 than there is nothing to delete which is okay. + if (no > 0) + log.fine ("#" + no + " - TreeType=CMC"); + else + log.warning ("#" + no + " - TreeType=CMC"); + return true; + } // afterDelete + + /** + * reIndex + * @param newRecord + */ + public void reIndex(boolean newRecord) + { + String [] toBeIndexed = new String[8]; + toBeIndexed[0] = this.getName(); + toBeIndexed[1] = this.getDescription(); + toBeIndexed[2] = this.getRelativeURL(); + toBeIndexed[3] = this.getMeta_Author(); + toBeIndexed[4] = this.getMeta_Copyright(); + toBeIndexed[5] = this.getMeta_Description(); + toBeIndexed[6] = this.getMeta_Keywords(); + toBeIndexed[7] = this.getMeta_Publisher(); + MIndex.reIndex (newRecord, toBeIndexed, getCtx(), getAD_Client_ID(), get_Table_ID(), get_ID(), getCM_WebProject_ID(), this.getUpdated()); + MContainerElement[] theseElements = getAllElements(); + if (theseElements!=null) + for (int i=0;i list = new ArrayList(); + String sql = "SELECT * FROM C_DunningLevel WHERE C_Dunning_ID=? AND DaysAfterDue+DaysBetweenDunning list = new ArrayList(); + String sql = "SELECT * FROM C_DunningRunLine WHERE C_DunningRunEntry_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, get_ID ()); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + list.add(new MDunningRunLine(getCtx(), rs, get_TrxName())); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + + // + MDunningRunLine[] retValue = new MDunningRunLine[list.size()]; + list.toArray(retValue); + return retValue; + } + + + protected boolean beforeSave (boolean newRecord) + { + // Set Amt + if (isProcessed ()) + { + MDunningRunLine[] theseLines = getLines(); + for (int i=0;i s_cache = new CCache("R_InterestArea", 5); + private static CCache s_cache = + new CCache("R_InterestArea", 5); + /** Logger */ + private static CLogger s_log = CLogger.getCLogger (MInterestArea.class); /** - * Constructor - * @param ctx context - * @param R_InterestArea_ID interest area - * @param trxName transaction - */ - public MInterestArea (Properties ctx, int R_InterestArea_ID, String trxName) - { - super (ctx, R_InterestArea_ID, trxName); - if (R_InterestArea_ID == 0) + * Constructor + * @param ctx context + * @param R_InterestArea_ID interest area + * @param trxName transaction + */ + public MInterestArea (Properties ctx, int R_InterestArea_ID, String trxName) + { + super (ctx, R_InterestArea_ID, trxName); + if (R_InterestArea_ID == 0) { // setName (null); // setR_InterestArea_ID (0); + setIsSelfService (false); } } // MInterestArea - /** - * Loader Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MInterestArea (Properties ctx, ResultSet rs, String trxName) - { + /** + * Loader Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MInterestArea (Properties ctx, ResultSet rs, String trxName) + { super(ctx, rs, trxName); } // MInterestArea + + /** + * Get Value + * @return value + */ + public String getValue() + { + String s = super.getValue (); + if (s != null && s.length () > 0) + return s; + return super.getName(); + } // getValue /** * String representation - * @return info - */ - public String toString () - { - StringBuffer sb = new StringBuffer ("MInterestArea[") + * @return info + */ + public String toString () + { + StringBuffer sb = new StringBuffer ("MInterestArea[") .append (get_ID()).append(" - ").append(getName()) .append ("]"); return sb.toString (); - } + } // toString /*************************************************************************/ - private int m_AD_User_ID = -1; - private MContactInterest m_ci = null; - - /** - * Set Subscription info "constructor". - * Create inactive Subscription - * @param AD_User_ID contact - */ - public void setSubscriptionInfo (int AD_User_ID) - { - m_AD_User_ID = AD_User_ID; - m_ci = MContactInterest.get(getCtx(), getR_InterestArea_ID(), AD_User_ID, - false, get_TrxName()); - } // setSubscription - - /** - * Set AD_User_ID - * @param AD_User_ID user - */ - public void setAD_User_ID (int AD_User_ID) - { - m_AD_User_ID = AD_User_ID; - } - - /** - * Get AD_User_ID - * @return user - */ - public int getAD_User_ID () - { - return m_AD_User_ID; - } - - /** - * Get Subscribe Date - * @return subscribe date - */ - public Timestamp getSubscribeDate () - { - if (m_ci != null) - return m_ci.getSubscribeDate(); - return null; - } - - /** - * Get Opt Out Date - * @return opt-out date - */ - public Timestamp getOptOutDate () - { - if (m_ci != null) - return m_ci.getOptOutDate(); - return null; - } - - /** - * Is Subscribed - * @return true if sunscribed - */ - public boolean isSubscribed() - { - if (m_AD_User_ID <= 0 || m_ci == null) - return false; - // We have a BPartner Contact - return m_ci.isSubscribed(); - } // isSubscribed - -} // MInterestArea + private int m_AD_User_ID = -1; + private MContactInterest m_ci = null; + + /** + * Set Subscription info "constructor". + * Create inactive Subscription + * @param AD_User_ID contact + */ + public void setSubscriptionInfo (int AD_User_ID) + { + m_AD_User_ID = AD_User_ID; + m_ci = MContactInterest.get(getCtx(), getR_InterestArea_ID(), AD_User_ID, + false, get_TrxName()); + } // setSubscription + + /** + * Set AD_User_ID + * @param AD_User_ID user + */ + public void setAD_User_ID (int AD_User_ID) + { + m_AD_User_ID = AD_User_ID; + } + + /** + * Get AD_User_ID + * @return user + */ + public int getAD_User_ID () + { + return m_AD_User_ID; + } + + /** + * Get Subscribe Date + * @return subscribe date + */ + public Timestamp getSubscribeDate () + { + if (m_ci != null) + return m_ci.getSubscribeDate(); + return null; + } + + /** + * Get Opt Out Date + * @return opt-out date + */ + public Timestamp getOptOutDate () + { + if (m_ci != null) + return m_ci.getOptOutDate(); + return null; + } + + /** + * Is Subscribed + * @return true if sunscribed + */ + public boolean isSubscribed() + { + if (m_AD_User_ID <= 0 || m_ci == null) + return false; + // We have a BPartner Contact + return m_ci.isSubscribed(); + } // isSubscribed + +} // MInterestArea diff --git a/base/src/org/compiere/model/MInventoryLine.java b/base/src/org/compiere/model/MInventoryLine.java index fdaea9019a..9edd1f9049 100644 --- a/base/src/org/compiere/model/MInventoryLine.java +++ b/base/src/org/compiere/model/MInventoryLine.java @@ -3,413 +3,413 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.math.*; -import java.sql.*; -import java.util.*; -import java.util.logging.*; - -import org.compiere.util.*; - -/** - * Physical Inventory Line Model - * - * @author Jorg Janke - * @version $Id: MInventoryLine.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $ - */ -public class MInventoryLine extends X_M_InventoryLine -{ - /** - * Get Inventory Line with parameters - * @param inventory inventory - * @param M_Locator_ID locator - * @param M_Product_ID product - * @param M_AttributeSetInstance_ID asi - * @return line or null - */ - public static MInventoryLine get (MInventory inventory, - int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID) - { - MInventoryLine retValue = null; - String sql = "SELECT * FROM M_InventoryLine " - + "WHERE M_Inventory_ID=? AND M_Locator_ID=?" - + " AND M_Product_ID=? AND M_AttributeSetInstance_ID=?"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, inventory.get_TrxName()); - pstmt.setInt (1, inventory.getM_Inventory_ID()); - pstmt.setInt(2, M_Locator_ID); - pstmt.setInt(3, M_Product_ID); - pstmt.setInt(4, M_AttributeSetInstance_ID); - ResultSet rs = pstmt.executeQuery (); - if (rs.next ()) - retValue = new MInventoryLine (inventory.getCtx(), rs, inventory.get_TrxName()); - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - s_log.log (Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - - return retValue; - } // get - - - /** Logger */ - private static CLogger s_log = CLogger.getCLogger (MInventoryLine.class); - - - /************************************************************************** - * Default Constructor - * @param ctx context - * @param M_InventoryLine_ID line - * @param trxName transaction - */ - public MInventoryLine (Properties ctx, int M_InventoryLine_ID, String trxName) - { - super (ctx, M_InventoryLine_ID, trxName); - if (M_InventoryLine_ID == 0) - { - // setM_Inventory_ID (0); // Parent - // setM_InventoryLine_ID (0); // PK - // setM_Locator_ID (0); // FK - setLine(0); - // setM_Product_ID (0); // FK - setM_AttributeSetInstance_ID(0); // FK - setInventoryType (INVENTORYTYPE_InventoryDifference); - setQtyBook (Env.ZERO); - setQtyCount (Env.ZERO); - setProcessed(false); - } - } // MInventoryLine - - /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MInventoryLine (Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MInventoryLine - - /** - * Detail Constructor. - * Locator/Product/AttributeSetInstance must be unique - * @param inventory parent - * @param M_Locator_ID locator - * @param M_Product_ID product - * @param M_AttributeSetInstance_ID instance - * @param QtyBook book value - * @param QtyCount count value - */ - public MInventoryLine (MInventory inventory, - int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID, - BigDecimal QtyBook, BigDecimal QtyCount) - { - this (inventory.getCtx(), 0, inventory.get_TrxName()); - if (inventory.get_ID() == 0) - throw new IllegalArgumentException("Header not saved"); - m_parent = inventory; - setM_Inventory_ID (inventory.getM_Inventory_ID()); // Parent - setClientOrg (inventory.getAD_Client_ID(), inventory.getAD_Org_ID()); - setM_Locator_ID (M_Locator_ID); // FK - setM_Product_ID (M_Product_ID); // FK - setM_AttributeSetInstance_ID (M_AttributeSetInstance_ID); - // - if (QtyBook != null) - setQtyBook (QtyBook); - if (QtyCount != null && QtyCount.signum() != 0) - setQtyCount (QtyCount); - m_isManualEntry = false; - } // MInventoryLine - - /** Manually created */ - private boolean m_isManualEntry = true; - /** Parent */ - private MInventory m_parent = null; - /** Product */ - private MProduct m_product = null; - - /** - * Get Qty Book - * @return Qty Book - */ - public BigDecimal getQtyBook () - { - BigDecimal bd = super.getQtyBook (); - if (bd == null) - bd = Env.ZERO; - return bd; - } // getQtyBook - - /** - * Get Qty Count - * @return Qty Count - */ - public BigDecimal getQtyCount () - { - BigDecimal bd = super.getQtyCount(); - if (bd == null) - bd = Env.ZERO; - return bd; - } // getQtyBook - - /** - * Get Product - * @return product or null if not defined - */ - public MProduct getProduct() - { - int M_Product_ID = getM_Product_ID(); - if (M_Product_ID == 0) - return null; - if (m_product != null && m_product.getM_Product_ID() != M_Product_ID) - m_product = null; // reset - if (m_product == null) - m_product = MProduct.get(getCtx(), M_Product_ID); - return m_product; - } // getProduct - - /** - * Set Count Qty - enforce UOM - * @param QtyCount qty - */ - public void setQtyCount (BigDecimal QtyCount) - { - if (QtyCount != null) - { - MProduct product = getProduct(); - if (product != null) - { - int precision = product.getUOMPrecision(); - QtyCount = QtyCount.setScale(precision, BigDecimal.ROUND_HALF_UP); - } - } - super.setQtyCount(QtyCount); - } // setQtyCount - - /** - * Set Internal Use Qty - enforce UOM - * @param QtyInternalUse qty - */ - public void setQtyInternalUse (BigDecimal QtyInternalUse) - { - if (QtyInternalUse != null) - { - MProduct product = getProduct(); - if (product != null) - { - int precision = product.getUOMPrecision(); - QtyInternalUse = QtyInternalUse.setScale(precision, BigDecimal.ROUND_HALF_UP); - } - } - super.setQtyInternalUse(QtyInternalUse); - } // setQtyInternalUse - - - /** - * Add to Description - * @param description text - */ - public void addDescription (String description) - { - String desc = getDescription(); - if (desc == null) - setDescription(description); - else - setDescription(desc + " | " + description); - } // addDescription - - /** - * Get Parent - * @param parent parent - */ - protected void setParent(MInventory parent) - { - m_parent = parent; - } // setParent - - /** + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.math.*; +import java.sql.*; +import java.util.*; +import java.util.logging.*; + +import org.compiere.util.*; + +/** + * Physical Inventory Line Model + * + * @author Jorg Janke + * @version $Id: MInventoryLine.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $ + */ +public class MInventoryLine extends X_M_InventoryLine +{ + /** + * Get Inventory Line with parameters + * @param inventory inventory + * @param M_Locator_ID locator + * @param M_Product_ID product + * @param M_AttributeSetInstance_ID asi + * @return line or null + */ + public static MInventoryLine get (MInventory inventory, + int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID) + { + MInventoryLine retValue = null; + String sql = "SELECT * FROM M_InventoryLine " + + "WHERE M_Inventory_ID=? AND M_Locator_ID=?" + + " AND M_Product_ID=? AND M_AttributeSetInstance_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, inventory.get_TrxName()); + pstmt.setInt (1, inventory.getM_Inventory_ID()); + pstmt.setInt(2, M_Locator_ID); + pstmt.setInt(3, M_Product_ID); + pstmt.setInt(4, M_AttributeSetInstance_ID); + ResultSet rs = pstmt.executeQuery (); + if (rs.next ()) + retValue = new MInventoryLine (inventory.getCtx(), rs, inventory.get_TrxName()); + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + s_log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + + return retValue; + } // get + + + /** Logger */ + private static CLogger s_log = CLogger.getCLogger (MInventoryLine.class); + + + /************************************************************************** + * Default Constructor + * @param ctx context + * @param M_InventoryLine_ID line + * @param trxName transaction + */ + public MInventoryLine (Properties ctx, int M_InventoryLine_ID, String trxName) + { + super (ctx, M_InventoryLine_ID, trxName); + if (M_InventoryLine_ID == 0) + { + // setM_Inventory_ID (0); // Parent + // setM_InventoryLine_ID (0); // PK + // setM_Locator_ID (0); // FK + setLine(0); + // setM_Product_ID (0); // FK + setM_AttributeSetInstance_ID(0); // FK + setInventoryType (INVENTORYTYPE_InventoryDifference); + setQtyBook (Env.ZERO); + setQtyCount (Env.ZERO); + setProcessed(false); + } + } // MInventoryLine + + /** + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MInventoryLine (Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MInventoryLine + + /** + * Detail Constructor. + * Locator/Product/AttributeSetInstance must be unique + * @param inventory parent + * @param M_Locator_ID locator + * @param M_Product_ID product + * @param M_AttributeSetInstance_ID instance + * @param QtyBook book value + * @param QtyCount count value + */ + public MInventoryLine (MInventory inventory, + int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID, + BigDecimal QtyBook, BigDecimal QtyCount) + { + this (inventory.getCtx(), 0, inventory.get_TrxName()); + if (inventory.get_ID() == 0) + throw new IllegalArgumentException("Header not saved"); + m_parent = inventory; + setM_Inventory_ID (inventory.getM_Inventory_ID()); // Parent + setClientOrg (inventory.getAD_Client_ID(), inventory.getAD_Org_ID()); + setM_Locator_ID (M_Locator_ID); // FK + setM_Product_ID (M_Product_ID); // FK + setM_AttributeSetInstance_ID (M_AttributeSetInstance_ID); + // + if (QtyBook != null) + setQtyBook (QtyBook); + if (QtyCount != null && QtyCount.signum() != 0) + setQtyCount (QtyCount); + m_isManualEntry = false; + } // MInventoryLine + + /** Manually created */ + private boolean m_isManualEntry = true; + /** Parent */ + private MInventory m_parent = null; + /** Product */ + private MProduct m_product = null; + + /** + * Get Qty Book + * @return Qty Book + */ + public BigDecimal getQtyBook () + { + BigDecimal bd = super.getQtyBook (); + if (bd == null) + bd = Env.ZERO; + return bd; + } // getQtyBook + + /** + * Get Qty Count + * @return Qty Count + */ + public BigDecimal getQtyCount () + { + BigDecimal bd = super.getQtyCount(); + if (bd == null) + bd = Env.ZERO; + return bd; + } // getQtyBook + + /** + * Get Product + * @return product or null if not defined + */ + public MProduct getProduct() + { + int M_Product_ID = getM_Product_ID(); + if (M_Product_ID == 0) + return null; + if (m_product != null && m_product.getM_Product_ID() != M_Product_ID) + m_product = null; // reset + if (m_product == null) + m_product = MProduct.get(getCtx(), M_Product_ID); + return m_product; + } // getProduct + + /** + * Set Count Qty - enforce UOM + * @param QtyCount qty + */ + public void setQtyCount (BigDecimal QtyCount) + { + if (QtyCount != null) + { + MProduct product = getProduct(); + if (product != null) + { + int precision = product.getUOMPrecision(); + QtyCount = QtyCount.setScale(precision, BigDecimal.ROUND_HALF_UP); + } + } + super.setQtyCount(QtyCount); + } // setQtyCount + + /** + * Set Internal Use Qty - enforce UOM + * @param QtyInternalUse qty + */ + public void setQtyInternalUse (BigDecimal QtyInternalUse) + { + if (QtyInternalUse != null) + { + MProduct product = getProduct(); + if (product != null) + { + int precision = product.getUOMPrecision(); + QtyInternalUse = QtyInternalUse.setScale(precision, BigDecimal.ROUND_HALF_UP); + } + } + super.setQtyInternalUse(QtyInternalUse); + } // setQtyInternalUse + + + /** + * Add to Description + * @param description text + */ + public void addDescription (String description) + { + String desc = getDescription(); + if (desc == null) + setDescription(description); + else + setDescription(desc + " | " + description); + } // addDescription + + /** + * Get Parent + * @param parent parent + */ + protected void setParent(MInventory parent) + { + m_parent = parent; + } // setParent + + /** * Get Parent * @return parent */ - private MInventory getParent() + public MInventory getParent() { if (m_parent == null) m_parent = new MInventory (getCtx(), getM_Inventory_ID(), get_TrxName()); - return m_parent; - } // getParent - - /** - * String Representation - * @return info - */ - public String toString () - { - StringBuffer sb = new StringBuffer ("MInventoryLine["); - sb.append (get_ID()) - .append("-M_Product_ID=").append (getM_Product_ID()) - .append(",QtyCount=").append(getQtyCount()) - .append(",QtyInternalUse=").append(getQtyInternalUse()) - .append(",QtyBook=").append(getQtyBook()) - .append(",M_AttributeSetInstance_ID=").append(getM_AttributeSetInstance_ID()) - .append("]"); - return sb.toString (); - } // toString - - /** - * Before Save - * @param newRecord new - * @return true if can be saved - */ - protected boolean beforeSave (boolean newRecord) - { - if (newRecord && m_isManualEntry) - { - // Product requires ASI - if (getM_AttributeSetInstance_ID() == 0) - { - MProduct product = MProduct.get(getCtx(), getM_Product_ID()); - if (product.getM_AttributeSet_ID() != 0) - { - MAttributeSet mas = MAttributeSet.get(getCtx(), product.getM_AttributeSet_ID()); - if (mas.isInstanceAttribute() - && (mas.isMandatory() || mas.isMandatoryAlways())) - { - log.saveError("FillMandatory", Msg.getElement(getCtx(), "M_AttributeSetInstance_ID")); - return false; - } - } - } // No ASI - } // new or manual - - // Set Line No - if (getLine() == 0) - { - String sql = "SELECT COALESCE(MAX(Line),0)+10 AS DefaultValue FROM M_InventoryLine WHERE M_Inventory_ID=?"; - int ii = DB.getSQLValue (get_TrxName(), sql, getM_Inventory_ID()); - setLine (ii); - } - - // Enforce Qty UOM - if (newRecord || is_ValueChanged("QtyCount")) - setQtyCount(getQtyCount()); - if (newRecord || is_ValueChanged("QtyInternalUse")) - setQtyInternalUse(getQtyInternalUse()); - - // InternalUse Inventory - if (getQtyInternalUse().signum() != 0) - { - if (!INVENTORYTYPE_ChargeAccount.equals(getInventoryType())) - setInventoryType(INVENTORYTYPE_ChargeAccount); - // - if (getC_Charge_ID() == 0) - { - log.saveError("InternalUseNeedsCharge", ""); - return false; - } - } - else if (INVENTORYTYPE_ChargeAccount.equals(getInventoryType())) - { - if (getC_Charge_ID() == 0) - { - log.saveError("FillMandatory", Msg.getElement(getCtx(), "C_Charge_ID")); - return false; - } - } - else if (getC_Charge_ID() != 0) - setC_Charge_ID(0); - - // Set AD_Org to parent if not charge - if (getC_Charge_ID() == 0) - setAD_Org_ID(getParent().getAD_Org_ID()); - - return true; - } // beforeSave - - /** - * After Save - * @param newRecord new - * @param success success - * @return true - */ - protected boolean afterSave (boolean newRecord, boolean success) - { - // Create MA - if (newRecord && success - && m_isManualEntry && getM_AttributeSetInstance_ID() == 0) - createMA(); - return true; - } // afterSave - - /** - * Create Material Allocations for new Instances - */ - private void createMA() - { - MStorage[] storages = MStorage.getAll(getCtx(), getM_Product_ID(), - getM_Locator_ID(), get_TrxName()); - boolean allZeroASI = true; - for (int i = 0; i < storages.length; i++) - { - if (storages[i].getM_AttributeSetInstance_ID() != 0) - { - allZeroASI = false; - break; - } - } - if (allZeroASI) - return; - - MInventoryLineMA ma = null; - BigDecimal sum = Env.ZERO; - for (int i = 0; i < storages.length; i++) - { - MStorage storage = storages[i]; - if (storage.getQtyOnHand().signum() == 0) - continue; - if (ma != null - && ma.getM_AttributeSetInstance_ID() == storage.getM_AttributeSetInstance_ID()) - ma.setMovementQty(ma.getMovementQty().add(storage.getQtyOnHand())); - else - ma = new MInventoryLineMA (this, - storage.getM_AttributeSetInstance_ID(), storage.getQtyOnHand()); - if (!ma.save()) - ; - sum = sum.add(storage.getQtyOnHand()); - } - if (sum.compareTo(getQtyBook()) != 0) - { - log.warning("QtyBook=" + getQtyBook() + " corrected to Sum of MA=" + sum); - setQtyBook(sum); - } - } // createMA - -} // MInventoryLine + return m_parent; + } // getParent + + /** + * String Representation + * @return info + */ + public String toString () + { + StringBuffer sb = new StringBuffer ("MInventoryLine["); + sb.append (get_ID()) + .append("-M_Product_ID=").append (getM_Product_ID()) + .append(",QtyCount=").append(getQtyCount()) + .append(",QtyInternalUse=").append(getQtyInternalUse()) + .append(",QtyBook=").append(getQtyBook()) + .append(",M_AttributeSetInstance_ID=").append(getM_AttributeSetInstance_ID()) + .append("]"); + return sb.toString (); + } // toString + + /** + * Before Save + * @param newRecord new + * @return true if can be saved + */ + protected boolean beforeSave (boolean newRecord) + { + if (newRecord && m_isManualEntry) + { + // Product requires ASI + if (getM_AttributeSetInstance_ID() == 0) + { + MProduct product = MProduct.get(getCtx(), getM_Product_ID()); + if (product.getM_AttributeSet_ID() != 0) + { + MAttributeSet mas = MAttributeSet.get(getCtx(), product.getM_AttributeSet_ID()); + if (mas.isInstanceAttribute() + && (mas.isMandatory() || mas.isMandatoryAlways())) + { + log.saveError("FillMandatory", Msg.getElement(getCtx(), "M_AttributeSetInstance_ID")); + return false; + } + } + } // No ASI + } // new or manual + + // Set Line No + if (getLine() == 0) + { + String sql = "SELECT COALESCE(MAX(Line),0)+10 AS DefaultValue FROM M_InventoryLine WHERE M_Inventory_ID=?"; + int ii = DB.getSQLValue (get_TrxName(), sql, getM_Inventory_ID()); + setLine (ii); + } + + // Enforce Qty UOM + if (newRecord || is_ValueChanged("QtyCount")) + setQtyCount(getQtyCount()); + if (newRecord || is_ValueChanged("QtyInternalUse")) + setQtyInternalUse(getQtyInternalUse()); + + // InternalUse Inventory + if (getQtyInternalUse().signum() != 0) + { + if (!INVENTORYTYPE_ChargeAccount.equals(getInventoryType())) + setInventoryType(INVENTORYTYPE_ChargeAccount); + // + if (getC_Charge_ID() == 0) + { + log.saveError("InternalUseNeedsCharge", ""); + return false; + } + } + else if (INVENTORYTYPE_ChargeAccount.equals(getInventoryType())) + { + if (getC_Charge_ID() == 0) + { + log.saveError("FillMandatory", Msg.getElement(getCtx(), "C_Charge_ID")); + return false; + } + } + else if (getC_Charge_ID() != 0) + setC_Charge_ID(0); + + // Set AD_Org to parent if not charge + if (getC_Charge_ID() == 0) + setAD_Org_ID(getParent().getAD_Org_ID()); + + return true; + } // beforeSave + + /** + * After Save + * @param newRecord new + * @param success success + * @return true + */ + protected boolean afterSave (boolean newRecord, boolean success) + { + // Create MA + if (newRecord && success + && m_isManualEntry && getM_AttributeSetInstance_ID() == 0) + createMA(); + return true; + } // afterSave + + /** + * Create Material Allocations for new Instances + */ + private void createMA() + { + MStorage[] storages = MStorage.getAll(getCtx(), getM_Product_ID(), + getM_Locator_ID(), get_TrxName()); + boolean allZeroASI = true; + for (int i = 0; i < storages.length; i++) + { + if (storages[i].getM_AttributeSetInstance_ID() != 0) + { + allZeroASI = false; + break; + } + } + if (allZeroASI) + return; + + MInventoryLineMA ma = null; + BigDecimal sum = Env.ZERO; + for (int i = 0; i < storages.length; i++) + { + MStorage storage = storages[i]; + if (storage.getQtyOnHand().signum() == 0) + continue; + if (ma != null + && ma.getM_AttributeSetInstance_ID() == storage.getM_AttributeSetInstance_ID()) + ma.setMovementQty(ma.getMovementQty().add(storage.getQtyOnHand())); + else + ma = new MInventoryLineMA (this, + storage.getM_AttributeSetInstance_ID(), storage.getQtyOnHand()); + if (!ma.save()) + ; + sum = sum.add(storage.getQtyOnHand()); + } + if (sum.compareTo(getQtyBook()) != 0) + { + log.warning("QtyBook=" + getQtyBook() + " corrected to Sum of MA=" + sum); + setQtyBook(sum); + } + } // createMA + +} // MInventoryLine diff --git a/base/src/org/compiere/model/MLdapAccess.java b/base/src/org/compiere/model/MLdapAccess.java new file mode 100755 index 0000000000..1f62ee6ebf --- /dev/null +++ b/base/src/org/compiere/model/MLdapAccess.java @@ -0,0 +1,56 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. + * This program is free software; you can redistribute it and/or modify it + * under the terms version 2 of the GNU General Public License as published + * by the Free Software Foundation. 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 General Public License for more details. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * You may reach us at: ComPiere, Inc. - http://www.compiere.org/license.html + * 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@compiere.org + *****************************************************************************/ +package org.compiere.model; + +import java.sql.*; +import java.util.*; + + +/** + * Ldap Access Log + * + * @author Jorg Janke + * @version $Id$ + */ +public class MLdapAccess extends X_AD_LdapAccess +{ + + /** + * Standard Constructor + * @param ctx context + * @param AD_LdapAccess_ID id + * @param trxName trx + */ + public MLdapAccess(Properties ctx, int AD_LdapAccess_ID, String trxName) + { + super (ctx, AD_LdapAccess_ID, trxName); + } // MLdapAccess + + /** + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MLdapAccess(Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } // MLdapAccess + + + + +} // MLdapAccess diff --git a/base/src/org/compiere/model/MLdapProcessor.java b/base/src/org/compiere/model/MLdapProcessor.java new file mode 100755 index 0000000000..2bc7913908 --- /dev/null +++ b/base/src/org/compiere/model/MLdapProcessor.java @@ -0,0 +1,545 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. + * This program is free software; you can redistribute it and/or modify it + * under the terms version 2 of the GNU General Public License as published + * by the Free Software Foundation. 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 General Public License for more details. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * You may reach us at: ComPiere, Inc. - http://www.compiere.org/license.html + * 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@compiere.org + *****************************************************************************/ +package org.compiere.model; + +import java.sql.*; +import java.util.*; +import java.util.logging.*; +import org.compiere.util.*; + + +/** + * LDAP Server Model + * + * @author Jorg Janke + * @version $Id$ + */ +public class MLdapProcessor extends X_AD_LdapProcessor implements AdempiereProcessor +{ + /** + * Get Active LDAP Server + * @return array of Servers + */ + public static MLdapProcessor[] getActive(Properties ctx) + { + ArrayList list = new ArrayList(); + String sql = "SELECT * FROM AD_LdapProcessor WHERE IsActive='Y'"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, null); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + list.add (new MLdapProcessor (ctx, rs, null)); + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + + MLdapProcessor[] retValue = new MLdapProcessor[list.size()]; + list.toArray(retValue); + return retValue; + } // getActive + + /** Logger */ + private static CLogger log = CLogger.getCLogger (MLdapProcessor.class); + + /************************************************************************** + * Ldap Processor + * @param ctx context + * @param AD_LdapProcessor_ID id + * @param trxName transaction + */ + public MLdapProcessor(Properties ctx, int AD_LdapProcessor_ID, String trxName) + { + super (ctx, AD_LdapProcessor_ID, trxName); + } // MLdapProcessor + + /** + * Ldap Processor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MLdapProcessor(Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } // MLdapProcessor + + /** Array of Clients */ + private MClient[] m_clients = null; + /** Array of Interest Areas */ + private MInterestArea[] m_interests = null; + + private int m_auth = 0; + private int m_ok = 0; + private int m_error = 0; + + /** + * Get Server ID + * @return id + */ + public String getServerID () + { + return "Ldap" + get_ID(); + } // getServerID + + /** + * Get Info + * @return info + */ + public String getInfo() + { + return "Auth=" + m_auth + + ", OK=" + m_ok + ", Error=" + m_error; + } // getInfo + + /** + * Get Date Next Run + * @param requery requery + * @return date next run + */ + public Timestamp getDateNextRun (boolean requery) + { + if (requery) + load(get_TrxName()); + return getDateNextRun(); + } // getDateNextRun + + /** + * Get Logs + * @return logs + */ + public AdempiereProcessorLog[] getLogs () + { + ArrayList list = new ArrayList(); + String sql = "SELECT * " + + "FROM AD_LdapProcessorLog " + + "WHERE AD_LdapProcessor_ID=? " + + "ORDER BY Created DESC"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, get_TrxName()); + pstmt.setInt (1, getAD_LdapProcessor_ID()); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + list.add (new MLdapProcessorLog (getCtx(), rs, get_TrxName())); + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + MLdapProcessorLog[] retValue = new MLdapProcessorLog[list.size ()]; + list.toArray (retValue); + return retValue; + } // getLogs + + /** + * Delete old Request Log + * @return number of records + */ + public int deleteLog() + { + if (getKeepLogDays() < 1) + return 0; + String sql = "DELETE AD_LdapProcessorLog " + + "WHERE AD_LdapProcessor_ID=" + getAD_LdapProcessor_ID() + + " AND (Created+" + getKeepLogDays() + ") < SysDate"; + int no = DB.executeUpdate(sql, get_TrxName()); + return no; + } // deleteLog + + /** + * Get Frequency (n/a) + * @return 1 + */ + public int getFrequency() + { + return 1; + } // getFrequency + + /** + * Get Frequency Type (n/a) + * @return minute + */ + public String getFrequencyType() + { + return X_R_RequestProcessor.FREQUENCYTYPE_Minute; + } // getFrequencyType + + /** + * String Representation + * @return info + */ + public String toString() + { + StringBuffer sb = new StringBuffer ("MLdapProcessor["); + sb.append (get_ID()).append ("-").append (getName()) + .append (",Port=").append (getLdapPort()) + .append ("]"); + return sb.toString (); + } // toString + + + /************************************************************************** + * Authenticate and Authorize + * @param ldapUser MLdapUser object + * @param usr user name + * @param o organization = Client Name + * @param ou optional organization unit = Interest Group + * @return ldapUser MLdapUser with updated information + */ + public MLdapUser authenticate(MLdapUser ldapUser, String usr, String o, String ou) + { + // Ensure something to return + if (ldapUser == null) + ldapUser = new MLdapUser(); + + String error = null; + String info = null; + + // User + if (usr == null || usr.trim().length () == 0) + { + error = "@NotFound@ User"; + ldapUser.setErrorString(error); + m_error++; + log.warning (error); + return ldapUser; + } + usr = usr.trim(); + // Client + if (o == null || o.length () == 0) + { + error = "@NotFound@ O"; + ldapUser.setErrorString(error); + m_error++; + log.warning (error); + return ldapUser; + } + int AD_Client_ID = findClient(o); + if (AD_Client_ID == 0) + { + error = "@NotFound@ O=" + o; + ldapUser.setErrorString(error); + m_error++; + log.config (error); + return ldapUser; + } + // Optional Interest Area + int R_InterestArea_ID = 0; + if (ou != null && ou.length () > 0) + { + R_InterestArea_ID = findInterestArea (AD_Client_ID, ou); + if (R_InterestArea_ID == 0) + { + error = "@NotFound@ OU=" + ou; + ldapUser.setErrorString(error); + m_error++; + log.config (error); + return ldapUser; + } + } + + m_auth++; + // Query 1 - Validate User + int AD_User_ID = 0; + String Value = null; + String LdapUser = null; + String EMail = null; + String Name = null; + String Password = null; + boolean IsActive = false; + String EMailVerify = null; // is timestamp + boolean isUnique = false; + // + String sql = "SELECT AD_User_ID, Value, LdapUser, EMail," // 1..4 + + " Name, Password, IsActive, EMailVerify " + + "FROM AD_User " + + "WHERE AD_Client_ID=? AND (EMail=? OR Value=? OR LdapUser=?)"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, null); + pstmt.setInt (1, AD_Client_ID); + pstmt.setString (2, usr); + pstmt.setString (3, usr); + pstmt.setString (4, usr); + ResultSet rs = pstmt.executeQuery (); + if (rs.next()) + { + AD_User_ID = rs.getInt (1); + Value = rs.getString (2); + LdapUser = rs.getString (3); + EMail = rs.getString (4); + // + Name = rs.getString (5); + Password = rs.getString (6); + IsActive = "Y".equals (rs.getString (7)); + EMailVerify = rs.getString (8); + isUnique = rs.next(); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + error = "System Error"; + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + if (error != null) + { + m_error++; + ldapUser.setErrorString(error); + return ldapUser; + } + // + if (AD_User_ID == 0) + { + error = "@NotFound@ User=" + usr; + info = "User not found - " + usr; + } + else if (!IsActive) + { + error = "@NotFound@ User=" + usr; + info = "User not active - " + usr; + } + else if (EMailVerify == null) + { + error = "@UserNotVerified@ User=" + usr; + info = "User EMail not verified - " + usr; + } + else if (usr.equalsIgnoreCase(LdapUser)) + info = "User verified - Ldap=" + usr + + (isUnique ? "" : " - Not Unique"); + else if (usr.equalsIgnoreCase(Value)) + info = "User verified - Value=" + usr + + (isUnique ? "" : " - Not Unique"); + else if (usr.equalsIgnoreCase(EMail)) + info = "User verified - EMail=" + usr + + (isUnique ? "" : " - Not Unique"); + else + info = "User verified ?? " + usr + + " - Name=" + Name + + ", Ldap=" + LdapUser + ", Value=" + Value + + (isUnique ? "" : " - Not Unique"); + + // Error + if (error != null) // should use Language of the User + { + logAccess (AD_Client_ID, AD_User_ID, R_InterestArea_ID, info, error); + ldapUser.setErrorString(Msg.translate (getCtx(), error)); + return ldapUser; + } + // Done + if (R_InterestArea_ID == 0) + { + logAccess (AD_Client_ID, AD_User_ID, R_InterestArea_ID, info, null); + ldapUser.setOrg(o); + ldapUser.setOrgUnit(ou); + ldapUser.setUserId(usr); + ldapUser.setPassword(Password); + return ldapUser; + } + + // Query 2 - Validate Subscription + String OptOutDate = null; + boolean found = false; + sql = "SELECT IsActive, OptOutDate " + + "FROM R_ContactInterest " + + "WHERE R_InterestArea_ID=? AND AD_User_ID=?"; + try + { + pstmt = DB.prepareStatement (sql, null); + pstmt.setInt (1, R_InterestArea_ID); + pstmt.setInt (2, AD_User_ID); + ResultSet rs = pstmt.executeQuery (); + if (rs.next()) + { + found = true; + IsActive = "Y".equals (rs.getString (1)); + OptOutDate = rs.getString (2); + isUnique = rs.next(); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + error = "System Error (2)"; + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // System Error + if (error != null) + { + m_error++; + ldapUser.setErrorString(error); + return ldapUser; + } + + if (!found) + { + error = "@UserNotSubscribed@ User=" + usr; + info = "No User Interest - " + usr + + " - R_InterestArea_ID=" + R_InterestArea_ID; + } + else if (OptOutDate != null) + { + error = "@UserNotSubscribed@ User=" + usr + " @OptOutDate@=" + OptOutDate; + info = "Opted out - " + usr + " - OptOutDate=" + OptOutDate; + } + else if (!IsActive) + { + error = "@UserNotSubscribed@ User=" + usr; + info = "User Interest Not Active - " + usr; + } + else + info = "User subscribed - " + usr; + + + if (error != null) // should use Language of the User + { + logAccess (AD_Client_ID, AD_User_ID, R_InterestArea_ID, info, error); + ldapUser.setErrorString(Msg.translate (getCtx(), error)); + return ldapUser; + } + // Done + logAccess (AD_Client_ID, AD_User_ID, R_InterestArea_ID, info, null); + ldapUser.setOrg(o); + ldapUser.setOrgUnit(ou); + ldapUser.setUserId(usr); + ldapUser.setPassword(Password); + return ldapUser; + } // authenticate + + /** + * Find Client + * @param client client name + * @return AD_Client_ID + */ + private int findClient (String client) + { + if (m_clients == null) + m_clients = MClient.getAll(getCtx()); + for (int i = 0; i < m_clients.length; i++) + { + if ((client.equalsIgnoreCase (m_clients[i].getValue()))) + return m_clients[i].getAD_Client_ID (); + } + return 0; + } // findClient + + /** + * Find Interest Area + * @param interset Name client name + * @return AD_Client_ID + */ + private int findInterestArea (int AD_Client_ID, String interestArea) + { + if (m_interests == null) + m_interests = MInterestArea.getAll(getCtx()); + for (int i = 0; i < m_interests.length; i++) + { + if (AD_Client_ID == m_interests[i].getAD_Client_ID() + && interestArea.equalsIgnoreCase (m_interests[i].getValue ())) + return m_interests[i].getR_InterestArea_ID(); + } + return 0; + } // findInterestArea + + /** + * Log Access + * @param AD_Client_ID client + * @param AD_User_ID user + * @param R_InterestArea_ID interest area + * @param info info + * @param error error + */ + private void logAccess (int AD_Client_ID, + int AD_User_ID, int R_InterestArea_ID, + String info, String error) + { + if (error != null) + { + log.log (Level.CONFIG, info); + m_error++; + } + else + { + log.log (Level.INFO, info); + m_ok++; + } + // + MLdapAccess access = new MLdapAccess (getCtx(), 0, null); + access.setAD_Client_ID (AD_Client_ID); + access.setAD_User_ID (AD_User_ID); + access.setR_InterestArea_ID (R_InterestArea_ID); + access.setIsError (error != null); + access.setSummary (info); + access.save (); + } // logAccess + +} // MLdapProcessor diff --git a/base/src/org/compiere/model/MLdapProcessorLog.java b/base/src/org/compiere/model/MLdapProcessorLog.java new file mode 100755 index 0000000000..7fcfdd3d5b --- /dev/null +++ b/base/src/org/compiere/model/MLdapProcessorLog.java @@ -0,0 +1,72 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. + * This program is free software; you can redistribute it and/or modify it + * under the terms version 2 of the GNU General Public License as published + * by the Free Software Foundation. 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 General Public License for more details. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * You may reach us at: ComPiere, Inc. - http://www.compiere.org/license.html + * 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@compiere.org + *****************************************************************************/ +package org.compiere.model; + +import java.sql.*; +import java.util.*; + + +/** + * LDAP Server Log + * @author Jorg Janke + * @version $Id$ + */ +public class MLdapProcessorLog extends X_AD_LdapProcessorLog implements AdempiereProcessorLog +{ + + /** + * Standard Constructor + * @param ctx context + * @param AD_LdapProcessorLog_ID id + * @param trxName trx + */ + public MLdapProcessorLog(Properties ctx, int AD_LdapProcessorLog_ID, + String trxName) + { + super (ctx, AD_LdapProcessorLog_ID, trxName); + if (AD_LdapProcessorLog_ID == 0) + { + // setAD_LdapProcessorLog_ID (0); + // setAD_LdapProcessor_ID (0); + setIsError (false); + } + } // MLdapProcessorLog + + /** + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MLdapProcessorLog(Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } // MLdapProcessorLog + + /** + * Parent Constructor + * @param parent parent + * @param summary summary + */ + public MLdapProcessorLog(MLdapProcessor parent, String summary) + { + this (parent.getCtx (), 0, null); + setClientOrg (parent); + setAD_LdapProcessor_ID (parent.getAD_LdapProcessor_ID()); + setSummary (summary); + } // MLdapProcessorLog + +} // MLdapProcessorLog diff --git a/base/src/org/compiere/model/MLdapUser.java b/base/src/org/compiere/model/MLdapUser.java new file mode 100755 index 0000000000..82ccb1c819 --- /dev/null +++ b/base/src/org/compiere/model/MLdapUser.java @@ -0,0 +1,140 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. + * This program is free software; you can redistribute it and/or modify it + * under the terms version 2 of the GNU General Public License as published + * by the Free Software Foundation. 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 General Public License for more details. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * You may reach us at: ComPiere, Inc. - http://www.compiere.org/license.html + * 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@compiere.org + *****************************************************************************/ +package org.compiere.model; + +/* + * MLdapUser, data object stores the user information such as userid, + * password, organization and so on. + */ +public class MLdapUser +{ + /** organization */ + private String org = null; + /** organization unit */ + private String orgUnit = null; + /** user password */ + private String passwd = null; + /** user id */ + private String userId = null; + /** error string */ + private String errStr = null; + + public MLdapUser() + { + } + + /* + * Reset attributes + */ + public void reset() + { + org = null; + orgUnit = null; + passwd = null; + userId = null; + errStr = null; + } // reset() + + /** + * Set the organization + * @param org organization + */ + public void setOrg(String org) + { + this.org = org; + } // setOrg() + + /** + * Set the organization unit + * @param orgUnit organization unit + */ + public void setOrgUnit(String orgUnit) + { + this.orgUnit = orgUnit; + } // setOrg() + + /** + * Set the user password + * @param passwd User password string + */ + public void setPassword(String passwd) + { + this.passwd = passwd; + } // setPassword() + + /** + * Set the user id + * @param passwd User id string + */ + public void setUserId(String userId) + { + this.userId = userId; + } // setUserId() + + /** + * Set the error String + * @param errStr Error String + */ + public void setErrorString(String errStr) + { + this.errStr = errStr; + } // setErrorStr() + + /** + * Get the organization + * @return org organization + */ + public String getOrg() + { + return org; + } // getOrg() + + /** + * Get the organization unit + * @return orgUnit organization unit + */ + public String getOrgUnit() + { + return orgUnit; + } // getOrgUnit() + + /** + * Get the user password + * @return passwd User password string + */ + public String getPassword() + { + return passwd; + } // getPassword() + + /** + * Get the user id + * @return User id string + */ + public String getUserId() + { + return userId; + } // getUserId() + + /** + * Get the error string + * @return errStr Error String + */ + public String getErrorMsg() + { + return errStr; + } // getErrorString() +} // MLdapUser diff --git a/base/src/org/compiere/model/MMovementLine.java b/base/src/org/compiere/model/MMovementLine.java index 88a1283b0c..97054d49d1 100644 --- a/base/src/org/compiere/model/MMovementLine.java +++ b/base/src/org/compiere/model/MMovementLine.java @@ -3,167 +3,181 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.math.*; -import java.sql.*; -import java.util.*; -import org.compiere.util.*; + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.math.*; +import java.sql.*; +import java.util.*; +import org.compiere.util.*; /** * Inventory Move Line Model - * + * * @author Jorg Janke * @version $Id: MMovementLine.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ */ -public class MMovementLine extends X_M_MovementLine -{ - /** - * Standard Cosntructor - * @param ctx context - * @param M_MovementLine_ID id - * @param trxName transaction - */ - public MMovementLine (Properties ctx, int M_MovementLine_ID, String trxName) - { - super (ctx, M_MovementLine_ID, trxName); - if (M_MovementLine_ID == 0) +public class MMovementLine extends X_M_MovementLine +{ + /** + * Standard Cosntructor + * @param ctx context + * @param M_MovementLine_ID id + * @param trxName transaction + */ + public MMovementLine (Properties ctx, int M_MovementLine_ID, String trxName) + { + super (ctx, M_MovementLine_ID, trxName); + if (M_MovementLine_ID == 0) { // setM_LocatorTo_ID (0); // @M_LocatorTo_ID@ // setM_Locator_ID (0); // @M_Locator_ID@ - // setM_MovementLine_ID (0); - // setLine (0); + // setM_MovementLine_ID (0); + // setLine (0); // setM_Product_ID (0); setM_AttributeSetInstance_ID(0); // ID setMovementQty (Env.ZERO); // 1 - setTargetQty (Env.ZERO); // 0 + setTargetQty (Env.ZERO); // 0 setScrappedQty(Env.ZERO); setConfirmedQty(Env.ZERO); setProcessed (false); - } + } } // MMovementLine /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MMovementLine (Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MMovementLine - - /** - * Parent constructor - * @param parent parent - */ - public MMovementLine (MMovement parent) - { - this (parent.getCtx(), 0, parent.get_TrxName()); + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MMovementLine (Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MMovementLine + + /** + * Parent constructor + * @param parent parent + */ + public MMovementLine (MMovement parent) + { + this (parent.getCtx(), 0, parent.get_TrxName()); setClientOrg(parent); setM_Movement_ID(parent.getM_Movement_ID()); } // MMovementLine - + /** * Get AttributeSetInstance To * @return ASI - */ - public int getM_AttributeSetInstanceTo_ID () - { - int M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstanceTo_ID(); - if (M_AttributeSetInstanceTo_ID == 0) + */ + public int getM_AttributeSetInstanceTo_ID () + { + int M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstanceTo_ID(); + if (M_AttributeSetInstanceTo_ID == 0) M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstance_ID(); return M_AttributeSetInstanceTo_ID; } // getM_AttributeSetInstanceTo_ID - + /** * Add to Description * @param description text - */ - public void addDescription (String description) - { - String desc = getDescription(); - if (desc == null) - setDescription(description); - else - setDescription(desc + " | " + description); - } // addDescription - - /** - * Get Product - * @return product or null if not defined - */ - public MProduct getProduct() - { - if (getM_Product_ID() != 0) + */ + public void addDescription (String description) + { + String desc = getDescription(); + if (desc == null) + setDescription(description); + else + setDescription(desc + " | " + description); + } // addDescription + + /** + * Get Product + * @return product or null if not defined + */ + public MProduct getProduct() + { + if (getM_Product_ID() != 0) return MProduct.get(getCtx(), getM_Product_ID()); return null; } // getProduct - + /** - * Set Movement Qty - enforce UOM + * Set Movement Qty - enforce UOM * @param MovementQty qty */ public void setMovementQty (BigDecimal MovementQty) - { - if (MovementQty != null) - { + { + if (MovementQty != null) + { MProduct product = getProduct(); if (product != null) { - int precision = product.getUOMPrecision(); + int precision = product.getUOMPrecision(); MovementQty = MovementQty.setScale(precision, BigDecimal.ROUND_HALF_UP); } } super.setMovementQty(MovementQty); } // setMovementQty + + /** Parent */ + private MMovement m_parent = null; + + /** + * get Parent + * @return Parent Movement + */ + public MMovement getParent() + { + if (m_parent == null) + m_parent = new MMovement (getCtx(), getM_Movement_ID(), get_TrxName()); + return m_parent; + } // getParent - + /** * Before Save * @param newRecord new - * @return true - */ - protected boolean beforeSave (boolean newRecord) - { + * @return true + */ + protected boolean beforeSave (boolean newRecord) + { // Set Line No if (getLine() == 0) { - String sql = "SELECT COALESCE(MAX(Line),0)+10 AS DefaultValue FROM M_MovementLine WHERE M_Movement_ID=?"; + String sql = "SELECT COALESCE(MAX(Line),0)+10 AS DefaultValue FROM C_M_MovementLine WHERE M_Movement_ID=?"; int ii = DB.getSQLValue (get_TrxName(), sql, getM_Movement_ID()); setLine (ii); } - + if (getM_Locator_ID() == getM_LocatorTo_ID()) { log.saveError("Error", Msg.parseTranslation(getCtx(), "@M_Locator_ID@ == @M_LocatorTo_ID@")); - return false; - } - - if (getMovementQty().signum() == 0) - { - log.saveError("FillMandatory", Msg.getElement(getCtx(), "MovementQty")); - return false; - } - - // Qty Precision - if (newRecord || is_ValueChanged("QtyEntered")) - setMovementQty(getMovementQty()); - + return false; + } + + if (getMovementQty().signum() == 0) + { + log.saveError("FillMandatory", Msg.getElement(getCtx(), "MovementQty")); + return false; + } + + // Qty Precision + if (newRecord || is_ValueChanged("QtyEntered")) + setMovementQty(getMovementQty()); + return true; } // beforeSave - + } // MMovementLine diff --git a/base/src/org/compiere/model/MNewsItem.java b/base/src/org/compiere/model/MNewsItem.java index 8f7ea0e6d1..9940732a37 100644 --- a/base/src/org/compiere/model/MNewsItem.java +++ b/base/src/org/compiere/model/MNewsItem.java @@ -3,135 +3,134 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.sql.*; -import java.util.*; - -/** - * News ItemModel - * - * @author Yves Sandfort - * @version $Id$ - */ -public class MNewsItem extends X_CM_NewsItem -{ - /*** - * Standard Constructor - * - * @param ctx context - * @param CM_NewsItem_ID id - * @param trxName transaction - */ - public MNewsItem (Properties ctx, int CM_NewsItem_ID, String trxName) - { - super (ctx, CM_NewsItem_ID, trxName); - } // MNewsItem - - /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MNewsItem (Properties ctx, ResultSet rs, String trxName) - { - super (ctx, rs, trxName); - } // MNewsItem - - /** - * getNewsChannel - * @return NewsChannel - */ - public MNewsChannel getNewsChannel() - { - int[] thisNewsChannel = MNewsChannel.getAllIDs("CM_NewsChannel","CM_NewsChannel_ID=" + this.getCM_NewsChannel_ID(), get_TrxName()); - if (thisNewsChannel!=null) - { - if (thisNewsChannel.length==1) - return new MNewsChannel(getCtx(), thisNewsChannel[0], get_TrxName()); - } - return null; - } // getNewsChannel - - /** - * Get rss2 Item Code - * @param xmlCode xml - * @param thisChannel channel - * @return rss item code - */ - public StringBuffer get_rss2ItemCode(StringBuffer xmlCode, MNewsChannel thisChannel) - { - if (this != null) // never null ?? - { - xmlCode.append (""); - xmlCode.append (""+ this.get_ID() + ""); - xmlCode.append (" <![CDATA[" - + this.getTitle () + "]]>"); - xmlCode.append (" "); - xmlCode.append (" "); - xmlCode.append (" " - + thisChannel.getLink () - + "?CM_NewsItem_ID=" + this.get_ID() + ""); - xmlCode.append (" "); - xmlCode.append (" " - + this.getPubDate () + ""); - xmlCode.append (""); - } - return xmlCode; - } - - /** - * After Save. - * Insert - * - create / update index - * @param newRecord insert - * @param success save success - * @return true if saved - */ - protected boolean afterSave (boolean newRecord, boolean success) - { - if (!success) - return success; - if (!newRecord) - { - MIndex.cleanUp(get_TrxName(), getAD_Client_ID(), get_Table_ID(), get_ID()); - } - reIndex(newRecord); - return success; - } // afterSave - + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.sql.*; +import java.util.*; + +/** + * News ItemModel + * + * @author Yves Sandfort + * @version $Id$ + */ +public class MNewsItem extends X_CM_NewsItem +{ + /*** + * Standard Constructor + * + * @param ctx context + * @param CM_NewsItem_ID id + * @param trxName transaction + */ + public MNewsItem (Properties ctx, int CM_NewsItem_ID, String trxName) + { + super (ctx, CM_NewsItem_ID, trxName); + } // MNewsItem + + /** + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MNewsItem (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } // MNewsItem + + /** + * getNewsChannel + * @return NewsChannel + */ + public MNewsChannel getNewsChannel() + { + int[] thisNewsChannel = MNewsChannel.getAllIDs("CM_NewsChannel","CM_NewsChannel_ID=" + this.getCM_NewsChannel_ID(), get_TrxName()); + if (thisNewsChannel!=null) + { + if (thisNewsChannel.length==1) + return new MNewsChannel(getCtx(), thisNewsChannel[0], get_TrxName()); + } + return null; + } // getNewsChannel + + /** + * Get rss2 Item Code + * @param xmlCode xml + * @param thisChannel channel + * @return rss item code + */ + public StringBuffer get_rss2ItemCode(StringBuffer xmlCode, MNewsChannel thisChannel) + { + if (this != null) // never null ?? + { + xmlCode.append (""); + xmlCode.append (""+ this.get_ID() + ""); + xmlCode.append (" <![CDATA[" + + this.getTitle () + "]]>"); + xmlCode.append (" "); + xmlCode.append (" "); + xmlCode.append (" " + + thisChannel.getLink () + + "?CM_NewsItem_ID=" + this.get_ID() + ""); + xmlCode.append (" "); + xmlCode.append (" " + + this.getPubDate () + ""); + xmlCode.append (""); + } + return xmlCode; + } + + /** + * After Save. + * Insert + * - create / update index + * @param newRecord insert + * @param success save success + * @return true if saved + */ + protected boolean afterSave (boolean newRecord, boolean success) + { + if (!success) + return success; + if (!newRecord) + { + MIndex.cleanUp(get_TrxName(), getAD_Client_ID(), get_Table_ID(), get_ID()); + } + reIndex(newRecord); + return success; + } // afterSave + /** * reIndex * @param newRecord - * @throws SQLException */ public void reIndex(boolean newRecord) { - int CMWebProjectID = 0; - if (getNewsChannel()!=null) - CMWebProjectID = getNewsChannel().getCM_WebProject_ID(); - String [] toBeIndexed = new String[4]; - toBeIndexed[0] = this.getAuthor(); - toBeIndexed[1] = this.getDescription(); - toBeIndexed[2] = this.getTitle(); - toBeIndexed[3] = this.getContentHTML(); - MIndex.reIndex (newRecord, toBeIndexed, getCtx(), getAD_Client_ID(), get_Table_ID(), get_ID(), CMWebProjectID, this.getUpdated()); - } // reIndex -} + int CMWebProjectID = 0; + if (getNewsChannel()!=null) + CMWebProjectID = getNewsChannel().getCM_WebProject_ID(); + String [] toBeIndexed = new String[4]; + toBeIndexed[0] = this.getAuthor(); + toBeIndexed[1] = this.getDescription(); + toBeIndexed[2] = this.getTitle(); + toBeIndexed[3] = this.getContentHTML(); + MIndex.reIndex (newRecord, toBeIndexed, getCtx(), getAD_Client_ID(), get_Table_ID(), get_ID(), CMWebProjectID, this.getUpdated()); + } // reIndex +} diff --git a/base/src/org/compiere/model/MOrderLine.java b/base/src/org/compiere/model/MOrderLine.java index b4d65b7239..bfd45a7013 100644 --- a/base/src/org/compiere/model/MOrderLine.java +++ b/base/src/org/compiere/model/MOrderLine.java @@ -3,934 +3,937 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.math.*; -import java.sql.*; -import java.util.*; -import java.util.logging.*; -import org.compiere.util.*; - -/** - * Order Line Model. - * - * MOrderLine ol = new MOrderLine(m_order); - ol.setM_Product_ID(wbl.getM_Product_ID()); - ol.setQtyOrdered(wbl.getQuantity()); - ol.setPrice(); - ol.setPriceActual(wbl.getPrice()); - ol.setTax(); - ol.save(); - - * - * @author Jorg Janke - * @version $Id: MOrderLine.java,v 1.6 2006/10/02 05:18:39 jjanke Exp $ - */ -public class MOrderLine extends X_C_OrderLine -{ - - /** - * Get Order Unreserved Qty - * @param ctx context - * @param M_Warehouse_ID wh - * @param M_Product_ID product - * @param M_AttributeSetInstance_ID asi - * @param excludeC_OrderLine_ID exclude C_OrderLine_ID - * @return Unreserved Qty - */ - public static BigDecimal getNotReserved (Properties ctx, int M_Warehouse_ID, - int M_Product_ID, int M_AttributeSetInstance_ID, int excludeC_OrderLine_ID) - { - BigDecimal retValue = Env.ZERO; - String sql = "SELECT SUM(QtyOrdered-QtyDelivered-QtyReserved) " - + "FROM C_OrderLine ol" - + " INNER JOIN C_Order o ON (ol.C_Order_ID=o.C_Order_ID) " - + "WHERE ol.M_Warehouse_ID=?" // #1 - + " AND M_Product_ID=?" // #2 - + " AND o.IsSOTrx='Y' AND o.DocStatus='DR'" - + " AND QtyOrdered-QtyDelivered-QtyReserved<>0" - + " AND ol.C_OrderLine_ID<>?"; - if (M_AttributeSetInstance_ID != 0) - sql += " AND M_AttributeSetInstance_ID=?"; - - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, null); - pstmt.setInt (1, M_Warehouse_ID); - pstmt.setInt (2, M_Product_ID); - pstmt.setInt (3, excludeC_OrderLine_ID); - if (M_AttributeSetInstance_ID != 0) - pstmt.setInt (4, M_AttributeSetInstance_ID); - ResultSet rs = pstmt.executeQuery (); - if (rs.next ()) - retValue = rs.getBigDecimal(1); - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - s_log.log (Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - if (retValue == null) - s_log.fine("-"); - else - s_log.fine(retValue.toString()); - return retValue; - } // getNotReserved - - /** Logger */ - private static CLogger s_log = CLogger.getCLogger (MOrderLine.class); - - /************************************************************************** - * Default Constructor - * @param ctx context - * @param C_OrderLine_ID order line to load - * @param trxName trx name - */ - public MOrderLine (Properties ctx, int C_OrderLine_ID, String trxName) - { - super (ctx, C_OrderLine_ID, trxName); - if (C_OrderLine_ID == 0) - { - // setC_Order_ID (0); - // setLine (0); - // setM_Warehouse_ID (0); // @M_Warehouse_ID@ - // setC_BPartner_ID(0); - // setC_BPartner_Location_ID (0); // @C_BPartner_Location_ID@ - // setC_Currency_ID (0); // @C_Currency_ID@ - // setDateOrdered (new Timestamp(System.currentTimeMillis())); // @DateOrdered@ - // - // setC_Tax_ID (0); - // setC_UOM_ID (0); - // - setFreightAmt (Env.ZERO); - setLineNetAmt (Env.ZERO); - // - setPriceEntered(Env.ZERO); - setPriceActual (Env.ZERO); - setPriceLimit (Env.ZERO); - setPriceList (Env.ZERO); - // - setM_AttributeSetInstance_ID(0); - // - setQtyEntered (Env.ZERO); - setQtyOrdered (Env.ZERO); // 1 - setQtyDelivered (Env.ZERO); - setQtyInvoiced (Env.ZERO); - setQtyReserved (Env.ZERO); - // - setIsDescription (false); // N - setProcessed (false); - setLine (0); - } - } // MOrderLine - - /** - * Parent Constructor. - ol.setM_Product_ID(wbl.getM_Product_ID()); - ol.setQtyOrdered(wbl.getQuantity()); - ol.setPrice(); - ol.setPriceActual(wbl.getPrice()); - ol.setTax(); - ol.save(); - * @param order parent order - */ - public MOrderLine (MOrder order) - { - this (order.getCtx(), 0, order.get_TrxName()); - if (order.get_ID() == 0) - throw new IllegalArgumentException("Header not saved"); - setC_Order_ID (order.getC_Order_ID()); // parent - setOrder(order); - } // MOrderLine - - /** - * Load Constructor - * @param ctx context - * @param rs result set record - * @param trxName transaction - */ - public MOrderLine (Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MOrderLine - - private int m_M_PriceList_ID = 0; - // - private boolean m_IsSOTrx = true; - // Product Pricing - private MProductPricing m_productPrice = null; - - /** Cached Currency Precision */ - private Integer m_precision = null; - /** Product */ - private MProduct m_product = null; - /** Parent */ - private MOrder m_parent = null; - - /** - * Set Defaults from Order. - * Does not set Parent !! - * @param order order - */ - public void setOrder (MOrder order) - { - setClientOrg(order); - setC_BPartner_ID(order.getC_BPartner_ID()); - setC_BPartner_Location_ID(order.getC_BPartner_Location_ID()); - setM_Warehouse_ID(order.getM_Warehouse_ID()); - setDateOrdered(order.getDateOrdered()); - setDatePromised(order.getDatePromised()); - setC_Currency_ID(order.getC_Currency_ID()); - // - setHeaderInfo(order); // sets m_order - // Don't set Activity, etc as they are overwrites - } // setOrder - - /** - * Set Header Info - * @param order order - */ - public void setHeaderInfo (MOrder order) - { - m_parent = order; - m_precision = new Integer(order.getPrecision()); - m_M_PriceList_ID = order.getM_PriceList_ID(); - m_IsSOTrx = order.isSOTrx(); - } // setHeaderInfo - - /** - * Get Parent - * @return parent - */ - public MOrder getParent() - { - if (m_parent == null) - m_parent = new MOrder(getCtx(), getC_Order_ID(), get_TrxName()); - return m_parent; - } // getParent - - /** - * Set Price Entered/Actual. - * Use this Method if the Line UOM is the Product UOM - * @param PriceActual price - */ - public void setPrice (BigDecimal PriceActual) - { - setPriceEntered(PriceActual); - setPriceActual (PriceActual); - } // setPrice - - /** - * Set Price Actual. - * (actual price is not updateable) - * @param PriceActual actual price - */ - public void setPriceActual (BigDecimal PriceActual) - { - if (PriceActual == null) - throw new IllegalArgumentException ("PriceActual is mandatory"); - set_ValueNoCheck("PriceActual", PriceActual); - } // setPriceActual - - /** - * Set Price for Product and PriceList. - * Use only if newly created. - * Uses standard price list of not set by order constructor - */ - public void setPrice() - { - if (getM_Product_ID() == 0) - return; - if (m_M_PriceList_ID == 0) - throw new IllegalStateException("PriceList unknown!"); - setPrice (m_M_PriceList_ID); - } // setPrice - - /** - * Set Price for Product and PriceList - * @param M_PriceList_ID price list - */ - public void setPrice (int M_PriceList_ID) - { - if (getM_Product_ID() == 0) - return; - // - log.fine(toString() + " - M_PriceList_ID=" + M_PriceList_ID); - getProductPricing (M_PriceList_ID); - setPriceActual (m_productPrice.getPriceStd()); - setPriceList (m_productPrice.getPriceList()); - setPriceLimit (m_productPrice.getPriceLimit()); - // - if (getQtyEntered().compareTo(getQtyOrdered()) == 0) - setPriceEntered(getPriceActual()); - else - setPriceEntered(getPriceActual().multiply(getQtyOrdered() - .divide(getQtyEntered(), 12, BigDecimal.ROUND_HALF_UP))); // recision - - // Calculate Discount - setDiscount(m_productPrice.getDiscount()); - // Set UOM - setC_UOM_ID(m_productPrice.getC_UOM_ID()); - } // setPrice - - /** - * Get and calculate Product Pricing - * @param M_PriceList_ID id - * @return product pricing - */ - private MProductPricing getProductPricing (int M_PriceList_ID) - { - m_productPrice = new MProductPricing (getM_Product_ID(), - getC_BPartner_ID(), getQtyOrdered(), m_IsSOTrx); - m_productPrice.setM_PriceList_ID(M_PriceList_ID); - m_productPrice.setPriceDate(getDateOrdered()); - // - m_productPrice.calculatePrice(); - return m_productPrice; - } // getProductPrice - - /** - * Set Tax - * @return true if tax is set - */ - public boolean setTax() - { - int ii = Tax.get(getCtx(), getM_Product_ID(), getC_Charge_ID(), getDateOrdered(), getDateOrdered(), - getAD_Org_ID(), getM_Warehouse_ID(), - getC_BPartner_Location_ID(), // should be bill to - getC_BPartner_Location_ID(), m_IsSOTrx); - if (ii == 0) - { - log.log(Level.SEVERE, "No Tax found"); - return false; - } - setC_Tax_ID (ii); - return true; - } // setTax - - /** - * Calculate Extended Amt. - * May or may not include tax - */ - public void setLineNetAmt () - { - BigDecimal bd = getPriceActual().multiply(getQtyOrdered()); - if (bd.scale() > getPrecision()) - bd = bd.setScale(getPrecision(), BigDecimal.ROUND_HALF_UP); - super.setLineNetAmt (bd); - } // setLineNetAmt - - /** - * Get Currency Precision from Currency - * @return precision - */ - public int getPrecision() - { - if (m_precision != null) - return m_precision.intValue(); - // - if (getC_Currency_ID() == 0) - { - setOrder (getParent()); - if (m_precision != null) - return m_precision.intValue(); - } - if (getC_Currency_ID() != 0) - { - MCurrency cur = MCurrency.get(getCtx(), getC_Currency_ID()); - if (cur.get_ID() != 0) - { - m_precision = new Integer (cur.getStdPrecision()); - return m_precision.intValue(); - } - } - // Fallback - String sql = "SELECT c.StdPrecision " - + "FROM C_Currency c INNER JOIN C_Order x ON (x.C_Currency_ID=c.C_Currency_ID) " - + "WHERE x.C_Order_ID=?"; - int i = DB.getSQLValue(get_TrxName(), sql, getC_Order_ID()); - m_precision = new Integer(i); - return m_precision.intValue(); - } // getPrecision - - /** - * Set Product - * @param product product - */ - public void setProduct (MProduct product) - { - m_product = product; - if (m_product != null) - { - setM_Product_ID(m_product.getM_Product_ID()); - setC_UOM_ID (m_product.getC_UOM_ID()); - } - else - { - setM_Product_ID(0); - set_ValueNoCheck ("C_UOM_ID", null); - } - setM_AttributeSetInstance_ID(0); - } // setProduct - - - /** - * Set M_Product_ID - * @param M_Product_ID product - * @param setUOM set also UOM - */ - public void setM_Product_ID (int M_Product_ID, boolean setUOM) - { - if (setUOM) - setProduct(MProduct.get(getCtx(), M_Product_ID)); - else - super.setM_Product_ID (M_Product_ID); - setM_AttributeSetInstance_ID(0); - } // setM_Product_ID - - /** - * Set Product and UOM - * @param M_Product_ID product - * @param C_UOM_ID uom - */ - public void setM_Product_ID (int M_Product_ID, int C_UOM_ID) - { - super.setM_Product_ID (M_Product_ID); - if (C_UOM_ID != 0) - super.setC_UOM_ID(C_UOM_ID); - setM_AttributeSetInstance_ID(0); - } // setM_Product_ID - - - /** - * Get Product - * @return product or null - */ - public MProduct getProduct() - { - if (m_product == null && getM_Product_ID() != 0) - m_product = MProduct.get (getCtx(), getM_Product_ID()); - return m_product; - } // getProduct - - /** - * Set M_AttributeSetInstance_ID - * @param M_AttributeSetInstance_ID id - */ - public void setM_AttributeSetInstance_ID (int M_AttributeSetInstance_ID) - { - if (M_AttributeSetInstance_ID == 0) // 0 is valid ID - set_Value("M_AttributeSetInstance_ID", new Integer(0)); - else - super.setM_AttributeSetInstance_ID (M_AttributeSetInstance_ID); - } // setM_AttributeSetInstance_ID - - /** - * Set Warehouse - * @param M_Warehouse_ID warehouse - */ - public void setM_Warehouse_ID (int M_Warehouse_ID) - { - if (getM_Warehouse_ID() > 0 - && getM_Warehouse_ID() != M_Warehouse_ID - && !canChangeWarehouse()) - log.severe("Ignored - Already Delivered/Invoiced/Reserved"); - else - super.setM_Warehouse_ID (M_Warehouse_ID); - } // setM_Warehouse_ID - - /** - * Can Change Warehouse - * @return true if warehouse can be changed - */ - public boolean canChangeWarehouse() - { - if (getQtyDelivered().signum() != 0) - { - log.saveError("Error", Msg.translate(getCtx(), "QtyDelivered") + "=" + getQtyDelivered()); - return false; - } - if (getQtyInvoiced().signum() != 0) - { - log.saveError("Error", Msg.translate(getCtx(), "QtyInvoiced") + "=" + getQtyInvoiced()); - return false; - } - if (getQtyReserved().signum() != 0) - { - log.saveError("Error", Msg.translate(getCtx(), "QtyReserved") + "=" + getQtyReserved()); - return false; - } - // We can change - return true; - } // canChangeWarehouse - - /** - * Get C_Project_ID - * @return project - */ - public int getC_Project_ID() - { - int ii = super.getC_Project_ID (); - if (ii == 0) - ii = getParent().getC_Project_ID(); - return ii; - } // getC_Project_ID - - /** - * Get C_Activity_ID - * @return Activity - */ - public int getC_Activity_ID() - { - int ii = super.getC_Activity_ID (); - if (ii == 0) - ii = getParent().getC_Activity_ID(); - return ii; - } // getC_Activity_ID - - /** - * Get C_Campaign_ID - * @return Campaign - */ - public int getC_Campaign_ID() - { - int ii = super.getC_Campaign_ID (); - if (ii == 0) - ii = getParent().getC_Campaign_ID(); - return ii; - } // getC_Campaign_ID - - /** - * Get User2_ID - * @return User2 - */ - public int getUser1_ID () - { - int ii = super.getUser1_ID (); - if (ii == 0) - ii = getParent().getUser1_ID(); - return ii; - } // getUser1_ID - - /** - * Get User2_ID - * @return User2 - */ - public int getUser2_ID () - { - int ii = super.getUser2_ID (); - if (ii == 0) - ii = getParent().getUser2_ID(); - return ii; - } // getUser2_ID - - /** - * Get AD_OrgTrx_ID - * @return trx org - */ - public int getAD_OrgTrx_ID() - { - int ii = super.getAD_OrgTrx_ID(); - if (ii == 0) - ii = getParent().getAD_OrgTrx_ID(); - return ii; - } // getAD_OrgTrx_ID - - /************************************************************************** - * String Representation - * @return info - */ - public String toString () - { - StringBuffer sb = new StringBuffer ("MOrderLine[") - .append(get_ID()).append(",Line=").append(getLine()) - .append(",Ordered=").append(getQtyOrdered()) - .append(",Delivered=").append(getQtyDelivered()) - .append(",Invoiced=").append(getQtyInvoiced()) - .append(",Reserved=").append(getQtyReserved()) - .append(", LineNet=").append(getLineNetAmt()) - .append ("]"); - return sb.toString (); - } // toString - - /** - * Add to Description - * @param description text - */ - public void addDescription (String description) - { - String desc = getDescription(); - if (desc == null) - setDescription(description); - else - setDescription(desc + " | " + description); - } // addDescription - - /** - * Get Description Text. - * For jsp access (vs. isDescription) - * @return description - */ - public String getDescriptionText() - { - return super.getDescription(); - } // getDescriptionText - - /** - * Get Name - * @return get the name of the line (from Product) - */ - public String getName() - { - getProduct(); - if (m_product != null) - return m_product.getName(); - if (getC_Charge_ID() != 0) - { - MCharge charge = MCharge.get(getCtx(), getC_Charge_ID()); - return charge.getName(); - } - return ""; - } // getName - - /** - * Set C_Charge_ID - * @param C_Charge_ID charge - */ - public void setC_Charge_ID (int C_Charge_ID) - { - super.setC_Charge_ID (C_Charge_ID); - if (C_Charge_ID > 0) - set_ValueNoCheck ("C_UOM_ID", null); - } // setC_Charge_ID - /** - * Set Discount - */ - public void setDiscount() - { - BigDecimal list = getPriceList(); - // No List Price - if (Env.ZERO.compareTo(list) == 0) - return; - BigDecimal discount = list.subtract(getPriceActual()) - .multiply(new BigDecimal(100)) - .divide(list, getPrecision(), BigDecimal.ROUND_HALF_UP); - setDiscount(discount); - } // setDiscount - - /** - * Is Tax Included in Amount - * @return true if tax calculated - */ - public boolean isTaxIncluded() - { - if (m_M_PriceList_ID == 0) - { - m_M_PriceList_ID = DB.getSQLValue(get_TrxName(), - "SELECT M_PriceList_ID FROM C_Order WHERE C_Order_ID=?", - getC_Order_ID()); - } - MPriceList pl = MPriceList.get(getCtx(), m_M_PriceList_ID, get_TrxName()); - return pl.isTaxIncluded(); - } // isTaxIncluded - - - /** - * Set Qty Entered/Ordered. - * Use this Method if the Line UOM is the Product UOM - * @param Qty QtyOrdered/Entered - */ - public void setQty (BigDecimal Qty) - { - super.setQtyEntered (Qty); - super.setQtyOrdered (getQtyEntered()); - } // setQty - - /** - * Set Qty Entered - enforce entered UOM - * @param QtyEntered - */ - public void setQtyEntered (BigDecimal QtyEntered) - { - if (QtyEntered != null && getC_UOM_ID() != 0) - { - int precision = MUOM.getPrecision(getCtx(), getC_UOM_ID()); - QtyEntered = QtyEntered.setScale(precision, BigDecimal.ROUND_HALF_UP); - } - super.setQtyEntered (QtyEntered); - } // setQtyEntered - - /** - * Set Qty Ordered - enforce Product UOM - * @param QtyOrdered - */ - public void setQtyOrdered (BigDecimal QtyOrdered) - { - MProduct product = getProduct(); - if (QtyOrdered != null && product != null) - { - int precision = product.getUOMPrecision(); - QtyOrdered = QtyOrdered.setScale(precision, BigDecimal.ROUND_HALF_UP); - } - super.setQtyOrdered(QtyOrdered); - } // setQtyOrdered - - /************************************************************************** - * Before Save - * @param newRecord - * @return true if it can be sabed - */ - protected boolean beforeSave (boolean newRecord) - { - // Get Defaults from Parent - if (getC_BPartner_ID() == 0 || getC_BPartner_Location_ID() == 0 - || getM_Warehouse_ID() == 0 - || getC_Currency_ID() == 0) - setOrder (getParent()); - if (m_M_PriceList_ID == 0) - setHeaderInfo(getParent()); - - - // R/O Check - Product/Warehouse Change - if (!newRecord - && (is_ValueChanged("M_Product_ID") || is_ValueChanged("M_Warehouse_ID"))) - { - if (!canChangeWarehouse()) - return false; - } // Product Changed - - // Charge - if (getC_Charge_ID() != 0 && getM_Product_ID() != 0) - setM_Product_ID(0); - // No Product - if (getM_Product_ID() == 0) - setM_AttributeSetInstance_ID(0); - // Product - else // Set/check Product Price - { - // Set Price if Actual = 0 - if (m_productPrice == null - && Env.ZERO.compareTo(getPriceActual()) == 0 - && Env.ZERO.compareTo(getPriceList()) == 0) - setPrice(); - // Check if on Price list - if (m_productPrice == null) - getProductPricing(m_M_PriceList_ID); - if (!m_productPrice.isCalculated()) - { - log.saveError("Error", Msg.getMsg(getCtx(), "ProductNotOnPriceList")); - return false; - } - } - - // UOM - if (getC_UOM_ID() == 0 - && (getM_Product_ID() != 0 - || getPriceEntered().compareTo(Env.ZERO) != 0 - || getC_Charge_ID() != 0)) - { - int C_UOM_ID = MUOM.getDefault_UOM_ID(getCtx()); - if (C_UOM_ID > 0) - setC_UOM_ID (C_UOM_ID); - } - // Qty Precision - if (newRecord || is_ValueChanged("QtyEntered")) - setQtyEntered(getQtyEntered()); - if (newRecord || is_ValueChanged("QtyOrdered")) - setQtyOrdered(getQtyOrdered()); - - // Qty on instance ASI for SO - if (m_IsSOTrx - && getM_AttributeSetInstance_ID() != 0 - && (newRecord || is_ValueChanged("M_Product_ID") - || is_ValueChanged("M_AttributeSetInstance_ID") + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.math.*; +import java.sql.*; +import java.util.*; +import java.util.logging.*; +import org.compiere.util.*; + +/** + * Order Line Model. + * + * MOrderLine ol = new MOrderLine(m_order); + ol.setM_Product_ID(wbl.getM_Product_ID()); + ol.setQtyOrdered(wbl.getQuantity()); + ol.setPrice(); + ol.setPriceActual(wbl.getPrice()); + ol.setTax(); + ol.save(); + + * + * @author Jorg Janke + * @version $Id: MOrderLine.java,v 1.6 2006/10/02 05:18:39 jjanke Exp $ + */ +public class MOrderLine extends X_C_OrderLine +{ + + /** + * Get Order Unreserved Qty + * @param ctx context + * @param M_Warehouse_ID wh + * @param M_Product_ID product + * @param M_AttributeSetInstance_ID asi + * @param excludeC_OrderLine_ID exclude C_OrderLine_ID + * @return Unreserved Qty + */ + public static BigDecimal getNotReserved (Properties ctx, int M_Warehouse_ID, + int M_Product_ID, int M_AttributeSetInstance_ID, int excludeC_OrderLine_ID) + { + BigDecimal retValue = Env.ZERO; + String sql = "SELECT SUM(QtyOrdered-QtyDelivered-QtyReserved) " + + "FROM C_OrderLine ol" + + " INNER JOIN C_Order o ON (ol.C_Order_ID=o.C_Order_ID) " + + "WHERE ol.M_Warehouse_ID=?" // #1 + + " AND M_Product_ID=?" // #2 + + " AND o.IsSOTrx='Y' AND o.DocStatus='DR'" + + " AND QtyOrdered-QtyDelivered-QtyReserved<>0" + + " AND ol.C_OrderLine_ID<>?"; + if (M_AttributeSetInstance_ID != 0) + sql += " AND M_AttributeSetInstance_ID=?"; + + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, null); + pstmt.setInt (1, M_Warehouse_ID); + pstmt.setInt (2, M_Product_ID); + pstmt.setInt (3, excludeC_OrderLine_ID); + if (M_AttributeSetInstance_ID != 0) + pstmt.setInt (4, M_AttributeSetInstance_ID); + ResultSet rs = pstmt.executeQuery (); + if (rs.next ()) + retValue = rs.getBigDecimal(1); + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + s_log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + if (retValue == null) + s_log.fine("-"); + else + s_log.fine(retValue.toString()); + return retValue; + } // getNotReserved + + /** Logger */ + private static CLogger s_log = CLogger.getCLogger (MOrderLine.class); + + /************************************************************************** + * Default Constructor + * @param ctx context + * @param C_OrderLine_ID order line to load + * @param trxName trx name + */ + public MOrderLine (Properties ctx, int C_OrderLine_ID, String trxName) + { + super (ctx, C_OrderLine_ID, trxName); + if (C_OrderLine_ID == 0) + { + // setC_Order_ID (0); + // setLine (0); + // setM_Warehouse_ID (0); // @M_Warehouse_ID@ + // setC_BPartner_ID(0); + // setC_BPartner_Location_ID (0); // @C_BPartner_Location_ID@ + // setC_Currency_ID (0); // @C_Currency_ID@ + // setDateOrdered (new Timestamp(System.currentTimeMillis())); // @DateOrdered@ + // + // setC_Tax_ID (0); + // setC_UOM_ID (0); + // + setFreightAmt (Env.ZERO); + setLineNetAmt (Env.ZERO); + // + setPriceEntered(Env.ZERO); + setPriceActual (Env.ZERO); + setPriceLimit (Env.ZERO); + setPriceList (Env.ZERO); + // + setM_AttributeSetInstance_ID(0); + // + setQtyEntered (Env.ZERO); + setQtyOrdered (Env.ZERO); // 1 + setQtyDelivered (Env.ZERO); + setQtyInvoiced (Env.ZERO); + setQtyReserved (Env.ZERO); + // + setIsDescription (false); // N + setProcessed (false); + setLine (0); + } + } // MOrderLine + + /** + * Parent Constructor. + ol.setM_Product_ID(wbl.getM_Product_ID()); + ol.setQtyOrdered(wbl.getQuantity()); + ol.setPrice(); + ol.setPriceActual(wbl.getPrice()); + ol.setTax(); + ol.save(); + * @param order parent order + */ + public MOrderLine (MOrder order) + { + this (order.getCtx(), 0, order.get_TrxName()); + if (order.get_ID() == 0) + throw new IllegalArgumentException("Header not saved"); + setC_Order_ID (order.getC_Order_ID()); // parent + setOrder(order); + } // MOrderLine + + /** + * Load Constructor + * @param ctx context + * @param rs result set record + * @param trxName transaction + */ + public MOrderLine (Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MOrderLine + + private int m_M_PriceList_ID = 0; + // + private boolean m_IsSOTrx = true; + // Product Pricing + private MProductPricing m_productPrice = null; + + /** Cached Currency Precision */ + private Integer m_precision = null; + /** Product */ + private MProduct m_product = null; + /** Parent */ + private MOrder m_parent = null; + + /** + * Set Defaults from Order. + * Does not set Parent !! + * @param order order + */ + public void setOrder (MOrder order) + { + setClientOrg(order); + setC_BPartner_ID(order.getC_BPartner_ID()); + setC_BPartner_Location_ID(order.getC_BPartner_Location_ID()); + setM_Warehouse_ID(order.getM_Warehouse_ID()); + setDateOrdered(order.getDateOrdered()); + setDatePromised(order.getDatePromised()); + setC_Currency_ID(order.getC_Currency_ID()); + // + setHeaderInfo(order); // sets m_order + // Don't set Activity, etc as they are overwrites + } // setOrder + + /** + * Set Header Info + * @param order order + */ + public void setHeaderInfo (MOrder order) + { + m_parent = order; + m_precision = new Integer(order.getPrecision()); + m_M_PriceList_ID = order.getM_PriceList_ID(); + m_IsSOTrx = order.isSOTrx(); + } // setHeaderInfo + + /** + * Get Parent + * @return parent + */ + public MOrder getParent() + { + if (m_parent == null) + m_parent = new MOrder(getCtx(), getC_Order_ID(), get_TrxName()); + return m_parent; + } // getParent + + /** + * Set Price Entered/Actual. + * Use this Method if the Line UOM is the Product UOM + * @param PriceActual price + */ + public void setPrice (BigDecimal PriceActual) + { + setPriceEntered(PriceActual); + setPriceActual (PriceActual); + } // setPrice + + /** + * Set Price Actual. + * (actual price is not updateable) + * @param PriceActual actual price + */ + public void setPriceActual (BigDecimal PriceActual) + { + if (PriceActual == null) + throw new IllegalArgumentException ("PriceActual is mandatory"); + set_ValueNoCheck("PriceActual", PriceActual); + } // setPriceActual + + /** + * Set Price for Product and PriceList. + * Use only if newly created. + * Uses standard price list of not set by order constructor + */ + public void setPrice() + { + if (getM_Product_ID() == 0) + return; + if (m_M_PriceList_ID == 0) + throw new IllegalStateException("PriceList unknown!"); + setPrice (m_M_PriceList_ID); + } // setPrice + + /** + * Set Price for Product and PriceList + * @param M_PriceList_ID price list + */ + public void setPrice (int M_PriceList_ID) + { + if (getM_Product_ID() == 0) + return; + // + log.fine(toString() + " - M_PriceList_ID=" + M_PriceList_ID); + getProductPricing (M_PriceList_ID); + setPriceActual (m_productPrice.getPriceStd()); + setPriceList (m_productPrice.getPriceList()); + setPriceLimit (m_productPrice.getPriceLimit()); + // + if (getQtyEntered().compareTo(getQtyOrdered()) == 0) + setPriceEntered(getPriceActual()); + else + setPriceEntered(getPriceActual().multiply(getQtyOrdered() + .divide(getQtyEntered(), 12, BigDecimal.ROUND_HALF_UP))); // recision + + // Calculate Discount + setDiscount(m_productPrice.getDiscount()); + // Set UOM + setC_UOM_ID(m_productPrice.getC_UOM_ID()); + } // setPrice + + /** + * Get and calculate Product Pricing + * @param M_PriceList_ID id + * @return product pricing + */ + private MProductPricing getProductPricing (int M_PriceList_ID) + { + m_productPrice = new MProductPricing (getM_Product_ID(), + getC_BPartner_ID(), getQtyOrdered(), m_IsSOTrx); + m_productPrice.setM_PriceList_ID(M_PriceList_ID); + m_productPrice.setPriceDate(getDateOrdered()); + // + m_productPrice.calculatePrice(); + return m_productPrice; + } // getProductPrice + + /** + * Set Tax + * @return true if tax is set + */ + public boolean setTax() + { + int ii = Tax.get(getCtx(), getM_Product_ID(), getC_Charge_ID(), getDateOrdered(), getDateOrdered(), + getAD_Org_ID(), getM_Warehouse_ID(), + getC_BPartner_Location_ID(), // should be bill to + getC_BPartner_Location_ID(), m_IsSOTrx); + if (ii == 0) + { + log.log(Level.SEVERE, "No Tax found"); + return false; + } + setC_Tax_ID (ii); + return true; + } // setTax + + /** + * Calculate Extended Amt. + * May or may not include tax + */ + public void setLineNetAmt () + { + BigDecimal bd = getPriceActual().multiply(getQtyOrdered()); + if (bd.scale() > getPrecision()) + bd = bd.setScale(getPrecision(), BigDecimal.ROUND_HALF_UP); + super.setLineNetAmt (bd); + } // setLineNetAmt + + /** + * Get Currency Precision from Currency + * @return precision + */ + public int getPrecision() + { + if (m_precision != null) + return m_precision.intValue(); + // + if (getC_Currency_ID() == 0) + { + setOrder (getParent()); + if (m_precision != null) + return m_precision.intValue(); + } + if (getC_Currency_ID() != 0) + { + MCurrency cur = MCurrency.get(getCtx(), getC_Currency_ID()); + if (cur.get_ID() != 0) + { + m_precision = new Integer (cur.getStdPrecision()); + return m_precision.intValue(); + } + } + // Fallback + String sql = "SELECT c.StdPrecision " + + "FROM C_Currency c INNER JOIN C_Order x ON (x.C_Currency_ID=c.C_Currency_ID) " + + "WHERE x.C_Order_ID=?"; + int i = DB.getSQLValue(get_TrxName(), sql, getC_Order_ID()); + m_precision = new Integer(i); + return m_precision.intValue(); + } // getPrecision + + /** + * Set Product + * @param product product + */ + public void setProduct (MProduct product) + { + m_product = product; + if (m_product != null) + { + setM_Product_ID(m_product.getM_Product_ID()); + setC_UOM_ID (m_product.getC_UOM_ID()); + } + else + { + setM_Product_ID(0); + set_ValueNoCheck ("C_UOM_ID", null); + } + setM_AttributeSetInstance_ID(0); + } // setProduct + + + /** + * Set M_Product_ID + * @param M_Product_ID product + * @param setUOM set also UOM + */ + public void setM_Product_ID (int M_Product_ID, boolean setUOM) + { + if (setUOM) + setProduct(MProduct.get(getCtx(), M_Product_ID)); + else + super.setM_Product_ID (M_Product_ID); + setM_AttributeSetInstance_ID(0); + } // setM_Product_ID + + /** + * Set Product and UOM + * @param M_Product_ID product + * @param C_UOM_ID uom + */ + public void setM_Product_ID (int M_Product_ID, int C_UOM_ID) + { + super.setM_Product_ID (M_Product_ID); + if (C_UOM_ID != 0) + super.setC_UOM_ID(C_UOM_ID); + setM_AttributeSetInstance_ID(0); + } // setM_Product_ID + + + /** + * Get Product + * @return product or null + */ + public MProduct getProduct() + { + if (m_product == null && getM_Product_ID() != 0) + m_product = MProduct.get (getCtx(), getM_Product_ID()); + return m_product; + } // getProduct + + /** + * Set M_AttributeSetInstance_ID + * @param M_AttributeSetInstance_ID id + */ + public void setM_AttributeSetInstance_ID (int M_AttributeSetInstance_ID) + { + if (M_AttributeSetInstance_ID == 0) // 0 is valid ID + set_Value("M_AttributeSetInstance_ID", new Integer(0)); + else + super.setM_AttributeSetInstance_ID (M_AttributeSetInstance_ID); + } // setM_AttributeSetInstance_ID + + /** + * Set Warehouse + * @param M_Warehouse_ID warehouse + */ + public void setM_Warehouse_ID (int M_Warehouse_ID) + { + if (getM_Warehouse_ID() > 0 + && getM_Warehouse_ID() != M_Warehouse_ID + && !canChangeWarehouse()) + log.severe("Ignored - Already Delivered/Invoiced/Reserved"); + else + super.setM_Warehouse_ID (M_Warehouse_ID); + } // setM_Warehouse_ID + + /** + * Can Change Warehouse + * @return true if warehouse can be changed + */ + public boolean canChangeWarehouse() + { + if (getQtyDelivered().signum() != 0) + { + log.saveError("Error", Msg.translate(getCtx(), "QtyDelivered") + "=" + getQtyDelivered()); + return false; + } + if (getQtyInvoiced().signum() != 0) + { + log.saveError("Error", Msg.translate(getCtx(), "QtyInvoiced") + "=" + getQtyInvoiced()); + return false; + } + if (getQtyReserved().signum() != 0) + { + log.saveError("Error", Msg.translate(getCtx(), "QtyReserved") + "=" + getQtyReserved()); + return false; + } + // We can change + return true; + } // canChangeWarehouse + + /** + * Get C_Project_ID + * @return project + */ + public int getC_Project_ID() + { + int ii = super.getC_Project_ID (); + if (ii == 0) + ii = getParent().getC_Project_ID(); + return ii; + } // getC_Project_ID + + /** + * Get C_Activity_ID + * @return Activity + */ + public int getC_Activity_ID() + { + int ii = super.getC_Activity_ID (); + if (ii == 0) + ii = getParent().getC_Activity_ID(); + return ii; + } // getC_Activity_ID + + /** + * Get C_Campaign_ID + * @return Campaign + */ + public int getC_Campaign_ID() + { + int ii = super.getC_Campaign_ID (); + if (ii == 0) + ii = getParent().getC_Campaign_ID(); + return ii; + } // getC_Campaign_ID + + /** + * Get User2_ID + * @return User2 + */ + public int getUser1_ID () + { + int ii = super.getUser1_ID (); + if (ii == 0) + ii = getParent().getUser1_ID(); + return ii; + } // getUser1_ID + + /** + * Get User2_ID + * @return User2 + */ + public int getUser2_ID () + { + int ii = super.getUser2_ID (); + if (ii == 0) + ii = getParent().getUser2_ID(); + return ii; + } // getUser2_ID + + /** + * Get AD_OrgTrx_ID + * @return trx org + */ + public int getAD_OrgTrx_ID() + { + int ii = super.getAD_OrgTrx_ID(); + if (ii == 0) + ii = getParent().getAD_OrgTrx_ID(); + return ii; + } // getAD_OrgTrx_ID + + /************************************************************************** + * String Representation + * @return info + */ + public String toString () + { + StringBuffer sb = new StringBuffer ("MOrderLine[") + .append(get_ID()).append(",Line=").append(getLine()) + .append(",Ordered=").append(getQtyOrdered()) + .append(",Delivered=").append(getQtyDelivered()) + .append(",Invoiced=").append(getQtyInvoiced()) + .append(",Reserved=").append(getQtyReserved()) + .append(", LineNet=").append(getLineNetAmt()) + .append ("]"); + return sb.toString (); + } // toString + + /** + * Add to Description + * @param description text + */ + public void addDescription (String description) + { + String desc = getDescription(); + if (desc == null) + setDescription(description); + else + setDescription(desc + " | " + description); + } // addDescription + + /** + * Get Description Text. + * For jsp access (vs. isDescription) + * @return description + */ + public String getDescriptionText() + { + return super.getDescription(); + } // getDescriptionText + + /** + * Get Name + * @return get the name of the line (from Product) + */ + public String getName() + { + getProduct(); + if (m_product != null) + return m_product.getName(); + if (getC_Charge_ID() != 0) + { + MCharge charge = MCharge.get(getCtx(), getC_Charge_ID()); + return charge.getName(); + } + return ""; + } // getName + + /** + * Set C_Charge_ID + * @param C_Charge_ID charge + */ + public void setC_Charge_ID (int C_Charge_ID) + { + super.setC_Charge_ID (C_Charge_ID); + if (C_Charge_ID > 0) + set_ValueNoCheck ("C_UOM_ID", null); + } // setC_Charge_ID + /** + * Set Discount + */ + public void setDiscount() + { + BigDecimal list = getPriceList(); + // No List Price + if (Env.ZERO.compareTo(list) == 0) + return; + BigDecimal discount = list.subtract(getPriceActual()) + .multiply(new BigDecimal(100)) + .divide(list, getPrecision(), BigDecimal.ROUND_HALF_UP); + setDiscount(discount); + } // setDiscount + + /** + * Is Tax Included in Amount + * @return true if tax calculated + */ + public boolean isTaxIncluded() + { + if (m_M_PriceList_ID == 0) + { + m_M_PriceList_ID = DB.getSQLValue(get_TrxName(), + "SELECT M_PriceList_ID FROM C_Order WHERE C_Order_ID=?", + getC_Order_ID()); + } + MPriceList pl = MPriceList.get(getCtx(), m_M_PriceList_ID, get_TrxName()); + return pl.isTaxIncluded(); + } // isTaxIncluded + + + /** + * Set Qty Entered/Ordered. + * Use this Method if the Line UOM is the Product UOM + * @param Qty QtyOrdered/Entered + */ + public void setQty (BigDecimal Qty) + { + super.setQtyEntered (Qty); + super.setQtyOrdered (getQtyEntered()); + } // setQty + + /** + * Set Qty Entered - enforce entered UOM + * @param QtyEntered + */ + public void setQtyEntered (BigDecimal QtyEntered) + { + if (QtyEntered != null && getC_UOM_ID() != 0) + { + int precision = MUOM.getPrecision(getCtx(), getC_UOM_ID()); + QtyEntered = QtyEntered.setScale(precision, BigDecimal.ROUND_HALF_UP); + } + super.setQtyEntered (QtyEntered); + } // setQtyEntered + + /** + * Set Qty Ordered - enforce Product UOM + * @param QtyOrdered + */ + public void setQtyOrdered (BigDecimal QtyOrdered) + { + MProduct product = getProduct(); + if (QtyOrdered != null && product != null) + { + int precision = product.getUOMPrecision(); + QtyOrdered = QtyOrdered.setScale(precision, BigDecimal.ROUND_HALF_UP); + } + super.setQtyOrdered(QtyOrdered); + } // setQtyOrdered + + /************************************************************************** + * Before Save + * @param newRecord + * @return true if it can be sabed + */ + protected boolean beforeSave (boolean newRecord) + { + // Get Defaults from Parent + if (getC_BPartner_ID() == 0 || getC_BPartner_Location_ID() == 0 + || getM_Warehouse_ID() == 0 + || getC_Currency_ID() == 0) + setOrder (getParent()); + if (m_M_PriceList_ID == 0) + setHeaderInfo(getParent()); + + + // R/O Check - Product/Warehouse Change + if (!newRecord + && (is_ValueChanged("M_Product_ID") || is_ValueChanged("M_Warehouse_ID"))) + { + if (!canChangeWarehouse()) + return false; + } // Product Changed + + // Charge + if (getC_Charge_ID() != 0 && getM_Product_ID() != 0) + setM_Product_ID(0); + // No Product + if (getM_Product_ID() == 0) + setM_AttributeSetInstance_ID(0); + // Product + else // Set/check Product Price + { + // Set Price if Actual = 0 + if (m_productPrice == null + && Env.ZERO.compareTo(getPriceActual()) == 0 + && Env.ZERO.compareTo(getPriceList()) == 0) + setPrice(); + // Check if on Price list + if (m_productPrice == null) + getProductPricing(m_M_PriceList_ID); + if (!m_productPrice.isCalculated()) + { + log.saveError("Error", Msg.getMsg(getCtx(), "ProductNotOnPriceList")); + return false; + } + } + + // UOM + if (getC_UOM_ID() == 0 + && (getM_Product_ID() != 0 + || getPriceEntered().compareTo(Env.ZERO) != 0 + || getC_Charge_ID() != 0)) + { + int C_UOM_ID = MUOM.getDefault_UOM_ID(getCtx()); + if (C_UOM_ID > 0) + setC_UOM_ID (C_UOM_ID); + } + // Qty Precision + if (newRecord || is_ValueChanged("QtyEntered")) + setQtyEntered(getQtyEntered()); + if (newRecord || is_ValueChanged("QtyOrdered")) + setQtyOrdered(getQtyOrdered()); + + // Qty on instance ASI for SO + if (m_IsSOTrx + && getM_AttributeSetInstance_ID() != 0 + && (newRecord || is_ValueChanged("M_Product_ID") + || is_ValueChanged("M_AttributeSetInstance_ID") || is_ValueChanged("M_Warehouse_ID"))) { MProduct product = getProduct(); - int M_AttributeSet_ID = product.getM_AttributeSet_ID(); - boolean isInstance = M_AttributeSet_ID != 0; - if (isInstance) + if (product.isStocked()) { - MAttributeSet mas = MAttributeSet.get(getCtx(), M_AttributeSet_ID); - isInstance = mas.isInstanceAttribute(); - } - // Max - if (isInstance) - { - MStorage[] storages = MStorage.getWarehouse(getCtx(), - getM_Warehouse_ID(), getM_Product_ID(), getM_AttributeSetInstance_ID(), - M_AttributeSet_ID, false, null, true, get_TrxName()); - BigDecimal qty = Env.ZERO; - for (int i = 0; i < storages.length; i++) + int M_AttributeSet_ID = product.getM_AttributeSet_ID(); + boolean isInstance = M_AttributeSet_ID != 0; + if (isInstance) { - if (storages[i].getM_AttributeSetInstance_ID() == getM_AttributeSetInstance_ID()) - qty = qty.add(storages[i].getQtyOnHand()); + MAttributeSet mas = MAttributeSet.get(getCtx(), M_AttributeSet_ID); + isInstance = mas.isInstanceAttribute(); } - if (getQtyOrdered().compareTo(qty) > 0) + // Max + if (isInstance) { - log.warning("Qty - Stock=" + qty + ", Ordered=" + getQtyOrdered()); - log.saveError("QtyInsufficient", "=" + qty); - return false; + MStorage[] storages = MStorage.getWarehouse(getCtx(), + getM_Warehouse_ID(), getM_Product_ID(), getM_AttributeSetInstance_ID(), + M_AttributeSet_ID, false, null, true, get_TrxName()); + BigDecimal qty = Env.ZERO; + for (int i = 0; i < storages.length; i++) + { + if (storages[i].getM_AttributeSetInstance_ID() == getM_AttributeSetInstance_ID()) + qty = qty.add(storages[i].getQtyOnHand()); + } + if (getQtyOrdered().compareTo(qty) > 0) + { + log.warning("Qty - Stock=" + qty + ", Ordered=" + getQtyOrdered()); + log.saveError("QtyInsufficient", "=" + qty); + return false; + } } - } - } + } // stocked + } // SO instance // FreightAmt Not used if (Env.ZERO.compareTo(getFreightAmt()) != 0) - setFreightAmt(Env.ZERO); - - // Set Tax - if (getC_Tax_ID() == 0) - setTax(); - - // Get Line No - if (getLine() == 0) - { - String sql = "SELECT COALESCE(MAX(Line),0)+10 FROM C_OrderLine WHERE C_Order_ID=?"; - int ii = DB.getSQLValue (get_TrxName(), sql, getC_Order_ID()); - setLine (ii); - } - - // Calculations & Rounding - setLineNetAmt(); // extended Amount with or without tax - setDiscount(); - - return true; - } // beforeSave - - - /** - * Before Delete - * @return true if it can be deleted - */ - protected boolean beforeDelete () - { - // R/O Check - Something delivered. etc. - if (Env.ZERO.compareTo(getQtyDelivered()) != 0) - { - log.saveError("DeleteError", Msg.translate(getCtx(), "QtyDelivered") + "=" + getQtyDelivered()); - return false; - } - if (Env.ZERO.compareTo(getQtyInvoiced()) != 0) - { - log.saveError("DeleteError", Msg.translate(getCtx(), "QtyInvoiced") + "=" + getQtyInvoiced()); - return false; - } - if (Env.ZERO.compareTo(getQtyReserved()) != 0) - { - // For PO should be On Order - log.saveError("DeleteError", Msg.translate(getCtx(), "QtyReserved") + "=" + getQtyReserved()); - return false; - } - - return true; - } // beforeDelete - - /** - * After Save - * @param newRecord new - * @param success success - * @return saved - */ - protected boolean afterSave (boolean newRecord, boolean success) - { - if (!success) - return success; - if (!newRecord && is_ValueChanged("C_Tax_ID")) - { - // Recalculate Tax for old Tax - MOrderTax tax = MOrderTax.get (this, getPrecision(), - true, get_TrxName()); // old Tax - if (tax != null) - { - if (!tax.calculateTaxFromLines()) - return false; - if (!tax.save(get_TrxName())) - return false; - } - } - return updateHeaderTax(); - } // afterSave - - /** - * After Delete - * @param success success - * @return deleted - */ - protected boolean afterDelete (boolean success) - { - if (!success) - return success; - if (getS_ResourceAssignment_ID() != 0) - { - MResourceAssignment ra = new MResourceAssignment(getCtx(), getS_ResourceAssignment_ID(), get_TrxName()); - ra.delete(true); - } - - return updateHeaderTax(); - } // afterDelete - - /** - * Update Tax & Header - * @return true if header updated - */ - private boolean updateHeaderTax() - { - // Recalculate Tax for this Tax - MOrderTax tax = MOrderTax.get (this, getPrecision(), - false, get_TrxName()); // current Tax - if (!tax.calculateTaxFromLines()) - return false; - if (!tax.save(get_TrxName())) - return false; - - // Update Order Header - String sql = "UPDATE C_Order i" - + " SET TotalLines=" - + "(SELECT COALESCE(SUM(LineNetAmt),0) FROM C_OrderLine il WHERE i.C_Order_ID=il.C_Order_ID) " - + "WHERE C_Order_ID=" + getC_Order_ID(); - int no = DB.executeUpdate(sql, get_TrxName()); - if (no != 1) - log.warning("(1) #" + no); - - if (isTaxIncluded()) - sql = "UPDATE C_Order i " - + " SET GrandTotal=TotalLines " - + "WHERE C_Order_ID=" + getC_Order_ID(); - else - sql = "UPDATE C_Order i " - + " SET GrandTotal=TotalLines+" - + "(SELECT COALESCE(SUM(TaxAmt),0) FROM C_OrderTax it WHERE i.C_Order_ID=it.C_Order_ID) " - + "WHERE C_Order_ID=" + getC_Order_ID(); - no = DB.executeUpdate(sql, get_TrxName()); - if (no != 1) - log.warning("(2) #" + no); - m_parent = null; - return no == 1; - } // updateHeaderTax - -} // MOrderLine + setFreightAmt(Env.ZERO); + + // Set Tax + if (getC_Tax_ID() == 0) + setTax(); + + // Get Line No + if (getLine() == 0) + { + String sql = "SELECT COALESCE(MAX(Line),0)+10 FROM C_OrderLine WHERE C_Order_ID=?"; + int ii = DB.getSQLValue (get_TrxName(), sql, getC_Order_ID()); + setLine (ii); + } + + // Calculations & Rounding + setLineNetAmt(); // extended Amount with or without tax + setDiscount(); + + return true; + } // beforeSave + + + /** + * Before Delete + * @return true if it can be deleted + */ + protected boolean beforeDelete () + { + // R/O Check - Something delivered. etc. + if (Env.ZERO.compareTo(getQtyDelivered()) != 0) + { + log.saveError("DeleteError", Msg.translate(getCtx(), "QtyDelivered") + "=" + getQtyDelivered()); + return false; + } + if (Env.ZERO.compareTo(getQtyInvoiced()) != 0) + { + log.saveError("DeleteError", Msg.translate(getCtx(), "QtyInvoiced") + "=" + getQtyInvoiced()); + return false; + } + if (Env.ZERO.compareTo(getQtyReserved()) != 0) + { + // For PO should be On Order + log.saveError("DeleteError", Msg.translate(getCtx(), "QtyReserved") + "=" + getQtyReserved()); + return false; + } + + return true; + } // beforeDelete + + /** + * After Save + * @param newRecord new + * @param success success + * @return saved + */ + protected boolean afterSave (boolean newRecord, boolean success) + { + if (!success) + return success; + if (!newRecord && is_ValueChanged("C_Tax_ID")) + { + // Recalculate Tax for old Tax + MOrderTax tax = MOrderTax.get (this, getPrecision(), + true, get_TrxName()); // old Tax + if (tax != null) + { + if (!tax.calculateTaxFromLines()) + return false; + if (!tax.save(get_TrxName())) + return false; + } + } + return updateHeaderTax(); + } // afterSave + + /** + * After Delete + * @param success success + * @return deleted + */ + protected boolean afterDelete (boolean success) + { + if (!success) + return success; + if (getS_ResourceAssignment_ID() != 0) + { + MResourceAssignment ra = new MResourceAssignment(getCtx(), getS_ResourceAssignment_ID(), get_TrxName()); + ra.delete(true); + } + + return updateHeaderTax(); + } // afterDelete + + /** + * Update Tax & Header + * @return true if header updated + */ + private boolean updateHeaderTax() + { + // Recalculate Tax for this Tax + MOrderTax tax = MOrderTax.get (this, getPrecision(), + false, get_TrxName()); // current Tax + if (!tax.calculateTaxFromLines()) + return false; + if (!tax.save(get_TrxName())) + return false; + + // Update Order Header + String sql = "UPDATE C_Order i" + + " SET TotalLines=" + + "(SELECT COALESCE(SUM(LineNetAmt),0) FROM C_OrderLine il WHERE i.C_Order_ID=il.C_Order_ID) " + + "WHERE C_Order_ID=" + getC_Order_ID(); + int no = DB.executeUpdate(sql, get_TrxName()); + if (no != 1) + log.warning("(1) #" + no); + + if (isTaxIncluded()) + sql = "UPDATE C_Order i " + + " SET GrandTotal=TotalLines " + + "WHERE C_Order_ID=" + getC_Order_ID(); + else + sql = "UPDATE C_Order i " + + " SET GrandTotal=TotalLines+" + + "(SELECT COALESCE(SUM(TaxAmt),0) FROM C_OrderTax it WHERE i.C_Order_ID=it.C_Order_ID) " + + "WHERE C_Order_ID=" + getC_Order_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 1) + log.warning("(2) #" + no); + m_parent = null; + return no == 1; + } // updateHeaderTax + +} // MOrderLine diff --git a/base/src/org/compiere/model/MPaySelectionCheck.java b/base/src/org/compiere/model/MPaySelectionCheck.java index bf2f282560..d8a23325f6 100644 --- a/base/src/org/compiere/model/MPaySelectionCheck.java +++ b/base/src/org/compiere/model/MPaySelectionCheck.java @@ -3,681 +3,730 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.io.*; -import java.math.*; -import java.sql.*; -import java.util.*; -import java.util.logging.*; -import org.compiere.process.*; -import org.compiere.util.*; - -/** - * Payment Print/Export model. - * - * @author Jorg Janke - * @version $Id: MPaySelectionCheck.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $ - */ -public final class MPaySelectionCheck extends X_C_PaySelectionCheck -{ - /** - * Get Check for Payment - * @param ctx context - * @param C_Payment_ID id - * @param trxName transaction - * @return pay selection check for payment or null - */ - public static MPaySelectionCheck getOfPayment (Properties ctx, int C_Payment_ID, String trxName) - { - MPaySelectionCheck retValue = null; - String sql = "SELECT * FROM C_PaySelectionCheck WHERE C_Payment_ID=?"; - int count = 0; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, trxName); - pstmt.setInt (1, C_Payment_ID); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - MPaySelectionCheck psc = new MPaySelectionCheck (ctx, rs, trxName); - if (retValue == null) - retValue = psc; - else if (!retValue.isProcessed() && psc.isProcessed()) - retValue = psc; - count++; - } - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - s_log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - if (count > 1) - s_log.warning ("More then one for C_Payment_ID=" + C_Payment_ID); + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.io.*; +import java.math.*; +import java.sql.*; +import java.util.*; +import java.util.logging.*; +import org.compiere.process.*; +import org.compiere.util.*; + +/** + * Payment Print/Export model. + * + * @author Jorg Janke + * @version $Id: MPaySelectionCheck.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $ + */ +public final class MPaySelectionCheck extends X_C_PaySelectionCheck +{ + /** + * Get Check for Payment + * @param ctx context + * @param C_Payment_ID id + * @param trxName transaction + * @return pay selection check for payment or null + */ + public static MPaySelectionCheck getOfPayment (Properties ctx, int C_Payment_ID, String trxName) + { + MPaySelectionCheck retValue = null; + String sql = "SELECT * FROM C_PaySelectionCheck WHERE C_Payment_ID=?"; + int count = 0; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, trxName); + pstmt.setInt (1, C_Payment_ID); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + MPaySelectionCheck psc = new MPaySelectionCheck (ctx, rs, trxName); + if (retValue == null) + retValue = psc; + else if (!retValue.isProcessed() && psc.isProcessed()) + retValue = psc; + count++; + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + if (count > 1) + s_log.warning ("More then one for C_Payment_ID=" + C_Payment_ID); + return retValue; + } // getOfPayment + + /** + * Create Check for Payment + * @param ctx context + * @param C_Payment_ID id + * @param trxName transaction + * @return pay selection check for payment or null + */ + public static MPaySelectionCheck createForPayment (Properties ctx, int C_Payment_ID, String trxName) + { + if (C_Payment_ID == 0) + return null; + MPayment payment = new MPayment (ctx, C_Payment_ID, null); + // Map Payment Rule <- Tender Type + String PaymentRule = PAYMENTRULE_Check; + if (payment.getTenderType().equals(X_C_Payment.TENDERTYPE_CreditCard)) + PaymentRule = PAYMENTRULE_CreditCard; + else if (payment.getTenderType().equals(X_C_Payment.TENDERTYPE_DirectDebit)) + PaymentRule = PAYMENTRULE_DirectDebit; + else if (payment.getTenderType().equals(X_C_Payment.TENDERTYPE_DirectDeposit)) + PaymentRule = PAYMENTRULE_DirectDeposit; + // else if (payment.getTenderType().equals(MPayment.TENDERTYPE_Check)) + // PaymentRule = MPaySelectionCheck.PAYMENTRULE_Check; + + // Create new PaySelection + MPaySelection ps = new MPaySelection(ctx, 0, trxName); + ps.setC_BankAccount_ID (payment.getC_BankAccount_ID()); + ps.setName (Msg.translate(ctx, "C_Payment_ID") + ": " + payment.getDocumentNo()); + ps.setDescription(payment.getDescription()); + ps.setPayDate (payment.getDateTrx()); + ps.setTotalAmt (payment.getPayAmt()); + ps.setIsApproved (true); + ps.save(); + + // Create new PaySelection Line + MPaySelectionLine psl = null; + if (payment.getC_Invoice_ID() != 0) + { + psl = new MPaySelectionLine (ps, 10, PaymentRule); + psl.setC_Invoice_ID(payment.getC_Invoice_ID()); + psl.setIsSOTrx (payment.isReceipt()); + psl.setOpenAmt(payment.getPayAmt().add(payment.getDiscountAmt())); + psl.setPayAmt (payment.getPayAmt()); + psl.setDiscountAmt(payment.getDiscountAmt()); + psl.setDifferenceAmt (Env.ZERO); + psl.save(); + } + + // Create new PaySelection Check + MPaySelectionCheck psc = new MPaySelectionCheck(ps, PaymentRule); + psc.setC_BPartner_ID (payment.getC_BPartner_ID()); + psc.setC_Payment_ID(payment.getC_Payment_ID()); + psc.setIsReceipt(payment.isReceipt()); + psc.setPayAmt (payment.getPayAmt()); + psc.setDiscountAmt(payment.getDiscountAmt()); + psc.setQty (1); + psc.setDocumentNo(payment.getDocumentNo()); + psc.setProcessed(true); + psc.save(); + + // Update optional Line + if (psl != null) + { + psl.setC_PaySelectionCheck_ID(psc.getC_PaySelectionCheck_ID()); + psl.setProcessed(true); + psl.save(); + } + + // Indicate Done + ps.setProcessed(true); + ps.save(); + return psc; + } // createForPayment + + + /************************************************************************** + * Get Checks of Payment Selection + * + * @param C_PaySelection_ID Payment Selection + * @param PaymentRule Payment Rule + * @param startDocumentNo start document no + * @param trxName transaction + * @return array of checks + */ + static public MPaySelectionCheck[] get (int C_PaySelection_ID, + String PaymentRule, int startDocumentNo, String trxName) + { + s_log.fine("C_PaySelection_ID=" + C_PaySelection_ID + + ", PaymentRule=" + PaymentRule + ", startDocumentNo=" + startDocumentNo); + ArrayList list = new ArrayList(); + + int docNo = startDocumentNo; + String sql = "SELECT * FROM C_PaySelectionCheck " + + "WHERE C_PaySelection_ID=? AND PaymentRule=?"; + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, trxName); + pstmt.setInt(1, C_PaySelection_ID); + pstmt.setString(2, PaymentRule); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + MPaySelectionCheck check = new MPaySelectionCheck (Env.getCtx(), rs, trxName); + // Set new Check Document No - saved in confirmPrint + check.setDocumentNo(String.valueOf(docNo++)); + list.add(check); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + s_log.log(Level.SEVERE, sql, e); + } + + // convert to Array + MPaySelectionCheck[] retValue = new MPaySelectionCheck[list.size()]; + list.toArray(retValue); return retValue; - } // getOfPayment - - /** - * Create Check for Payment - * @param ctx context - * @param C_Payment_ID id - * @param trxName transaction - * @return pay selection check for payment or null - */ - public static MPaySelectionCheck createForPayment (Properties ctx, int C_Payment_ID, String trxName) - { - if (C_Payment_ID == 0) - return null; - MPayment payment = new MPayment (ctx, C_Payment_ID, null); - // Map Payment Rule <- Tender Type - String PaymentRule = PAYMENTRULE_Check; - if (payment.getTenderType().equals(X_C_Payment.TENDERTYPE_CreditCard)) - PaymentRule = PAYMENTRULE_CreditCard; - else if (payment.getTenderType().equals(X_C_Payment.TENDERTYPE_DirectDebit)) - PaymentRule = PAYMENTRULE_DirectDebit; - else if (payment.getTenderType().equals(X_C_Payment.TENDERTYPE_DirectDeposit)) - PaymentRule = PAYMENTRULE_DirectDeposit; - // else if (payment.getTenderType().equals(MPayment.TENDERTYPE_Check)) - // PaymentRule = MPaySelectionCheck.PAYMENTRULE_Check; - - // Create new PaySelection - MPaySelection ps = new MPaySelection(ctx, 0, trxName); - ps.setC_BankAccount_ID (payment.getC_BankAccount_ID()); - ps.setName (Msg.translate(ctx, "C_Payment_ID") + ": " + payment.getDocumentNo()); - ps.setDescription(payment.getDescription()); - ps.setPayDate (payment.getDateTrx()); - ps.setTotalAmt (payment.getPayAmt()); - ps.setIsApproved (true); - ps.save(); - - // Create new PaySelection Line - MPaySelectionLine psl = null; - if (payment.getC_Invoice_ID() != 0) - { - psl = new MPaySelectionLine (ps, 10, PaymentRule); - psl.setC_Invoice_ID(payment.getC_Invoice_ID()); - psl.setIsSOTrx (payment.isReceipt()); - psl.setOpenAmt(payment.getPayAmt().add(payment.getDiscountAmt())); - psl.setPayAmt (payment.getPayAmt()); - psl.setDiscountAmt(payment.getDiscountAmt()); - psl.setDifferenceAmt (Env.ZERO); - psl.save(); - } - - // Create new PaySelection Check - MPaySelectionCheck psc = new MPaySelectionCheck(ps, PaymentRule); - psc.setC_BPartner_ID (payment.getC_BPartner_ID()); - psc.setC_Payment_ID(payment.getC_Payment_ID()); - psc.setIsReceipt(payment.isReceipt()); - psc.setPayAmt (payment.getPayAmt()); - psc.setDiscountAmt(payment.getDiscountAmt()); - psc.setQty (1); - psc.setDocumentNo(payment.getDocumentNo()); - psc.setProcessed(true); - psc.save(); - - // Update optional Line - if (psl != null) - { - psl.setC_PaySelectionCheck_ID(psc.getC_PaySelectionCheck_ID()); - psl.setProcessed(true); - psl.save(); - } - - // Indicate Done - ps.setProcessed(true); - ps.save(); - return psc; - } // createForPayment + } // get /************************************************************************** - * Get Checks of Payment Selection - * - * @param C_PaySelection_ID Payment Selection - * @param PaymentRule Payment Rule - * @param startDocumentNo start document no - * @param trxName transaction - * @return array of checks - */ - static public MPaySelectionCheck[] get (int C_PaySelection_ID, - String PaymentRule, int startDocumentNo, String trxName) - { - s_log.fine("C_PaySelection_ID=" + C_PaySelection_ID - + ", PaymentRule=" + PaymentRule + ", startDocumentNo=" + startDocumentNo); - ArrayList list = new ArrayList(); - - int docNo = startDocumentNo; - String sql = "SELECT * FROM C_PaySelectionCheck " - + "WHERE C_PaySelection_ID=? AND PaymentRule=?"; - try + * Export to File + * @param checks array of checks + * @param file file to export checks + * @return number of lines + */ + public static int exportToFile (MPaySelectionCheck[] checks, File file) + { + if (checks == null || checks.length == 0) + return 0; + // Must be a file + if (file.isDirectory()) { - PreparedStatement pstmt = DB.prepareStatement(sql, trxName); - pstmt.setInt(1, C_PaySelection_ID); - pstmt.setString(2, PaymentRule); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) - { - MPaySelectionCheck check = new MPaySelectionCheck (Env.getCtx(), rs, trxName); - // Set new Check Document No - saved in confirmPrint - check.setDocumentNo(String.valueOf(docNo++)); - list.add(check); - } - rs.close(); - pstmt.close(); + s_log.log(Level.WARNING, "File is directory - " + file.getAbsolutePath()); + return 0; + } + // delete if exists + try + { + if (file.exists()) + file.delete(); + } + catch (Exception e) + { + s_log.log(Level.WARNING, "Could not delete - " + file.getAbsolutePath(), e); + } + + char x = '"'; // ease + int noLines = 0; + StringBuffer line = null; + try + { + FileWriter fw = new FileWriter(file); + + // write header + line = new StringBuffer(); + line.append(x).append("Value").append(x).append(",") + .append(x).append("Name").append(x).append(",") + .append(x).append("Contact").append(x).append(",") + .append(x).append("Addr1").append(x).append(",") + .append(x).append("Addr2").append(x).append(",") + .append(x).append("City").append(x).append(",") + .append(x).append("State").append(x).append(",") + .append(x).append("ZIP").append(x).append(",") + .append(x).append("Country").append(x).append(",") + .append(x).append("ReferenceNo").append(x).append(",") + .append(x).append("DocumentNo").append(x).append(",") + .append(x).append("PayDate").append(x).append(",") + .append(x).append("Currency").append(x).append(",") + .append(x).append("PayAmount").append(x).append(",") + .append(x).append("Comment").append(x) + .append(Env.NL); + fw.write(line.toString()); + noLines++; + + // write lines + for (int i = 0; i < checks.length; i++) + { + MPaySelectionCheck mpp = checks[i]; + if (mpp == null) + continue; + // BPartner Info + String bp[] = getBPartnerInfo(mpp.getC_BPartner_ID()); + + // Comment - list of invoice document no + StringBuffer comment = new StringBuffer(); + MPaySelectionLine[] psls = mpp.getPaySelectionLines(false); + for (int l = 0; l < psls.length; l++) + { + if (l > 0) + comment.append(", "); + comment.append(psls[l].getInvoice().getDocumentNo()); + } + line = new StringBuffer(); + line.append(x).append(bp[BP_VALUE]).append(x).append(",") // Value + .append(x).append(bp[BP_NAME]).append(x).append(",") // Name + .append(x).append(bp[BP_CONTACT]).append(x).append(",") // Contact + .append(x).append(bp[BP_ADDR1]).append(x).append(",") // Addr1 + .append(x).append(bp[BP_ADDR2]).append(x).append(",") // Addr2 + .append(x).append(bp[BP_CITY]).append(x).append(",") // City + .append(x).append(bp[BP_REGION]).append(x).append(",") // State + .append(x).append(bp[BP_POSTAL]).append(x).append(",") // ZIP + .append(x).append(bp[BP_COUNTRY]).append(x).append(",") // Country + .append(x).append(bp[BP_REFNO]).append(x).append(",") // ReferenceNo + // Payment Info + .append(x).append(mpp.getDocumentNo()).append(x).append(",") // DocumentNo + .append(mpp.getParent().getPayDate()).append(",") // PayDate + .append(x).append(MCurrency.getISO_Code(Env.getCtx(), mpp.getParent().getC_Currency_ID())).append(x).append(",") // Currency + .append(mpp.getPayAmt()).append(",") // PayAmount + .append(x).append(comment.toString()).append(x) // Comment + .append(Env.NL); + fw.write(line.toString()); + noLines++; + } // write line + + fw.flush(); + fw.close(); + } + catch (Exception e) + { + s_log.log(Level.SEVERE, "", e); + } + + return noLines; + } // exportToFile + + + /** + * Get Customer/Vendor Info. + * Based on BP_ static variables + * @param C_BPartner_ID BPartner + * @return info array + */ + private static String[] getBPartnerInfo (int C_BPartner_ID) + { + String[] bp = new String[10]; + + String sql = "SELECT bp.Value, bp.Name, c.Name AS Contact, " + + "a.Address1, a.Address2, a.City, r.Name AS Region, a.Postal, " + + "cc.Name AS Country, bp.ReferenceNo " + + "FROM C_BPartner bp, AD_User c, C_BPartner_Location l, C_Location a, C_Region r, C_Country cc " + + "WHERE bp.C_BPartner_ID=?" // #1 + + " AND bp.C_BPartner_ID=c.C_BPartner_ID(+)" + + " AND bp.C_BPartner_ID=l.C_BPartner_ID" + + " AND l.C_Location_ID=a.C_Location_ID" + + " AND a.C_Region_ID=r.C_Region_ID(+)" + + " AND a.C_Country_ID=cc.C_Country_ID " + + "ORDER BY l.IsBillTo DESC"; + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, C_BPartner_ID); + ResultSet rs = pstmt.executeQuery(); + // + if (rs.next()) + { + bp[BP_VALUE] = rs.getString(1); + if (bp[BP_VALUE] == null) + bp[BP_VALUE] = ""; + bp[BP_NAME] = rs.getString(2); + if (bp[BP_NAME] == null) + bp[BP_NAME] = ""; + bp[BP_CONTACT] = rs.getString(3); + if (bp[BP_CONTACT] == null) + bp[BP_CONTACT] = ""; + bp[BP_ADDR1] = rs.getString(4); + if (bp[BP_ADDR1] == null) + bp[BP_ADDR1] = ""; + bp[BP_ADDR2] = rs.getString(5); + if (bp[BP_ADDR2] == null) + bp[BP_ADDR2] = ""; + bp[BP_CITY] = rs.getString(6); + if (bp[BP_CITY] == null) + bp[BP_CITY] = ""; + bp[BP_REGION] = rs.getString(7); + if (bp[BP_REGION] == null) + bp[BP_REGION] = ""; + bp[BP_POSTAL] = rs.getString(8); + if (bp[BP_POSTAL] == null) + bp[BP_POSTAL] = ""; + bp[BP_COUNTRY] = rs.getString(9); + if (bp[BP_COUNTRY] == null) + bp[BP_COUNTRY] = ""; + bp[BP_REFNO] = rs.getString(10); + if (bp[BP_REFNO] == null) + bp[BP_REFNO] = ""; + } + rs.close(); + pstmt.close(); } catch (SQLException e) { s_log.log(Level.SEVERE, sql, e); } - - // convert to Array - MPaySelectionCheck[] retValue = new MPaySelectionCheck[list.size()]; - list.toArray(retValue); - return retValue; - } // createPayments - - - /************************************************************************** - * Export to File - * @param checks array of checks - * @param file file to export checks - * @return number of lines - */ - public static int exportToFile (MPaySelectionCheck[] checks, File file) - { - if (checks == null || checks.length == 0) - return 0; - // Must be a file - if (file.isDirectory()) - { - s_log.log(Level.SEVERE, "exportToFile - file is directory - " + file.getAbsolutePath()); - return 0; - } - // delete if exists - try - { - if (file.exists()) - file.delete(); - } - catch (Exception e) - { - s_log.log(Level.SEVERE, "exportToFile - could not delete - " + file.getAbsolutePath(), e); - } - - char x = '"'; // ease - int noLines = 0; - StringBuffer line = null; - try - { - FileWriter fw = new FileWriter(file); - - // write header - line = new StringBuffer(); - line.append(x).append("Value").append(x).append(",") - .append(x).append("Name").append(x).append(",") - .append(x).append("Contact").append(x).append(",") - .append(x).append("Addr1").append(x).append(",") - .append(x).append("Addr2").append(x).append(",") - .append(x).append("City").append(x).append(",") - .append(x).append("State").append(x).append(",") - .append(x).append("ZIP").append(x).append(",") - .append(x).append("Country").append(x).append(",") - .append(x).append("ReferenceNo").append(x).append(",") - .append(x).append("DocumentNo").append(x).append(",") - .append(x).append("PayDate").append(x).append(",") - .append(x).append("Currency").append(x).append(",") - .append(x).append("PayAmount").append(x).append(",") - .append(x).append("Comment").append(x) - .append(Env.NL); - fw.write(line.toString()); - noLines++; - - // write lines - for (int i = 0; i < checks.length; i++) - { - MPaySelectionCheck mpp = checks[i]; - if (mpp == null) - continue; - // BPartner Info - String bp[] = getBPartnerInfo(mpp.getC_BPartner_ID()); - - // Comment - list of invoice document no - StringBuffer comment = new StringBuffer(); - MPaySelectionLine[] psls = mpp.getPaySelectionLines(false); - for (int l = 0; l < psls.length; l++) - { - if (l > 0) - comment.append(", "); - comment.append(psls[l].getInvoice().getDocumentNo()); - } - line = new StringBuffer(); - line.append(x).append(bp[BP_VALUE]).append(x).append(",") // Value - .append(x).append(bp[BP_NAME]).append(x).append(",") // Name - .append(x).append(bp[BP_CONTACT]).append(x).append(",") // Contact - .append(x).append(bp[BP_ADDR1]).append(x).append(",") // Addr1 - .append(x).append(bp[BP_ADDR2]).append(x).append(",") // Addr2 - .append(x).append(bp[BP_CITY]).append(x).append(",") // City - .append(x).append(bp[BP_REGION]).append(x).append(",") // State - .append(x).append(bp[BP_POSTAL]).append(x).append(",") // ZIP - .append(x).append(bp[BP_COUNTRY]).append(x).append(",") // Country - .append(x).append(bp[BP_REFNO]).append(x).append(",") // ReferenceNo - // Payment Info - .append(x).append(mpp.getDocumentNo()).append(x).append(",") // DocumentNo - .append(mpp.getParent().getPayDate()).append(",") // PayDate - .append(x).append(MCurrency.getISO_Code(Env.getCtx(), mpp.getParent().getC_Currency_ID())).append(x).append(",") // Currency - .append(mpp.getPayAmt()).append(",") // PayAmount - .append(x).append(comment.toString()).append(x) // Comment - .append(Env.NL); - fw.write(line.toString()); - noLines++; - } // write line - - fw.flush(); - fw.close(); - } - catch (Exception e) - { - s_log.log(Level.SEVERE, "", e); - } - - return noLines; - } // exportToFile - - - /** - * Get Customer/Vendor Info. - * Based on BP_ static variables - * @param C_BPartner_ID BPartner - * @return info array - */ - private static String[] getBPartnerInfo (int C_BPartner_ID) - { - String[] bp = new String[10]; - - String sql = "SELECT bp.Value, bp.Name, c.Name AS Contact, " - + "a.Address1, a.Address2, a.City, r.Name AS Region, a.Postal, " - + "cc.Name AS Country, bp.ReferenceNo " - + "FROM C_BPartner bp, AD_User c, C_BPartner_Location l, C_Location a, C_Region r, C_Country cc " - + "WHERE bp.C_BPartner_ID=?" // #1 - + " AND bp.C_BPartner_ID=c.C_BPartner_ID(+)" - + " AND bp.C_BPartner_ID=l.C_BPartner_ID" - + " AND l.C_Location_ID=a.C_Location_ID" - + " AND a.C_Region_ID=r.C_Region_ID(+)" - + " AND a.C_Country_ID=cc.C_Country_ID " - + "ORDER BY l.IsBillTo DESC"; - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, C_BPartner_ID); - ResultSet rs = pstmt.executeQuery(); - // - if (rs.next()) - { - bp[BP_VALUE] = rs.getString(1); - if (bp[BP_VALUE] == null) - bp[BP_VALUE] = ""; - bp[BP_NAME] = rs.getString(2); - if (bp[BP_NAME] == null) - bp[BP_NAME] = ""; - bp[BP_CONTACT] = rs.getString(3); - if (bp[BP_CONTACT] == null) - bp[BP_CONTACT] = ""; - bp[BP_ADDR1] = rs.getString(4); - if (bp[BP_ADDR1] == null) - bp[BP_ADDR1] = ""; - bp[BP_ADDR2] = rs.getString(5); - if (bp[BP_ADDR2] == null) - bp[BP_ADDR2] = ""; - bp[BP_CITY] = rs.getString(6); - if (bp[BP_CITY] == null) - bp[BP_CITY] = ""; - bp[BP_REGION] = rs.getString(7); - if (bp[BP_REGION] == null) - bp[BP_REGION] = ""; - bp[BP_POSTAL] = rs.getString(8); - if (bp[BP_POSTAL] == null) - bp[BP_POSTAL] = ""; - bp[BP_COUNTRY] = rs.getString(9); - if (bp[BP_COUNTRY] == null) - bp[BP_COUNTRY] = ""; - bp[BP_REFNO] = rs.getString(10); - if (bp[BP_REFNO] == null) - bp[BP_REFNO] = ""; - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - s_log.log(Level.SEVERE, "getBPartnerInfo", e); - } return bp; } // getBPartnerInfo - - - /************************************************************************** - * Confirm Print. - * Create Payments the first time - * @param checks checks - * @param batch batch - * @return last Document number or 0 if nothing printed - */ - public static int confirmPrint (MPaySelectionCheck[] checks, MPaymentBatch batch) - { - int lastDocumentNo = 0; - for (int i = 0; i < checks.length; i++) - { - MPaySelectionCheck check = checks[i]; - MPayment payment = new MPayment(check.getCtx(), check.getC_Payment_ID(), null); - // Existing Payment - if (check.getC_Payment_ID() != 0) - { - // Update check number - if (check.getPaymentRule().equals(PAYMENTRULE_Check)) - { - payment.setCheckNo(check.getDocumentNo()); - if (!payment.save()) - s_log.log(Level.SEVERE, "Payment not saved: " + payment); - } - } - else // New Payment - { - payment = new MPayment(check.getCtx(), 0, null); - payment.setAD_Org_ID(check.getAD_Org_ID()); - // - if (check.getPaymentRule().equals(PAYMENTRULE_Check)) - payment.setBankCheck (check.getParent().getC_BankAccount_ID(), false, check.getDocumentNo()); + + + /************************************************************************** + * Confirm Print. + * Create Payments the first time + * @param checks checks + * @param batch batch + * @return last Document number or 0 if nothing printed + */ + public static int confirmPrint (MPaySelectionCheck[] checks, MPaymentBatch batch) + { + int lastDocumentNo = 0; + for (int i = 0; i < checks.length; i++) + { + MPaySelectionCheck check = checks[i]; + MPayment payment = new MPayment(check.getCtx(), check.getC_Payment_ID(), null); + // Existing Payment + if (check.getC_Payment_ID() != 0) + { + // Update check number + if (check.getPaymentRule().equals(PAYMENTRULE_Check)) + { + payment.setCheckNo(check.getDocumentNo()); + if (!payment.save()) + s_log.log(Level.SEVERE, "Payment not saved: " + payment); + } + } + else // New Payment + { + payment = new MPayment(check.getCtx(), 0, null); + payment.setAD_Org_ID(check.getAD_Org_ID()); + // + if (check.getPaymentRule().equals(PAYMENTRULE_Check)) + payment.setBankCheck (check.getParent().getC_BankAccount_ID(), false, check.getDocumentNo()); else if (check.getPaymentRule().equals(PAYMENTRULE_CreditCard)) payment.setTenderType(X_C_Payment.TENDERTYPE_CreditCard); else if (check.getPaymentRule().equals(PAYMENTRULE_DirectDeposit) - || check.getPaymentRule().equals(PAYMENTRULE_DirectDeposit)) - payment.setBankACH(check.getParent().getC_BankAccount_ID(), false); + || check.getPaymentRule().equals(PAYMENTRULE_DirectDebit)) + payment.setBankACH(check); else { s_log.log(Level.SEVERE, "Unsupported Payment Rule=" + check.getPaymentRule()); - continue; - } - payment.setTrxType(X_C_Payment.TRXTYPE_CreditPayment); - payment.setAmount(check.getParent().getC_Currency_ID(), check.getPayAmt()); - payment.setDiscountAmt(check.getDiscountAmt()); - payment.setDateTrx(check.getParent().getPayDate()); - payment.setC_BPartner_ID(check.getC_BPartner_ID()); - // Link to Batch - if (batch != null) - { - if (batch.getC_PaymentBatch_ID() == 0) - batch.save(); // new - payment.setC_PaymentBatch_ID(batch.getC_PaymentBatch_ID()); - } - // Link to Invoice - MPaySelectionLine[] psls = check.getPaySelectionLines(false); - s_log.fine("confirmPrint - " + check + " (#SelectionLines=" + psls.length + ")"); - if (check.getQty() == 1 && psls != null && psls.length == 1) - { - MPaySelectionLine psl = psls[0]; - s_log.fine("Map to Invoice " + psl); - // - payment.setC_Invoice_ID (psl.getC_Invoice_ID()); - payment.setDiscountAmt (psl.getDiscountAmt()); - payment.setWriteOffAmt(psl.getDifferenceAmt()); - BigDecimal overUnder = psl.getOpenAmt().subtract(psl.getPayAmt()) - .subtract(psl.getDiscountAmt()).subtract(psl.getDifferenceAmt()); - payment.setOverUnderAmt(overUnder); - } - else - payment.setDiscountAmt(Env.ZERO); - payment.setWriteOffAmt(Env.ZERO); - if (!payment.save()) - s_log.log(Level.SEVERE, "Payment not saved: " + payment); - // - int C_Payment_ID = payment.get_ID(); - if (C_Payment_ID < 1) - s_log.log(Level.SEVERE, "Payment not created=" + check); - else - { - check.setC_Payment_ID (C_Payment_ID); - check.save(); // Payment process needs it - // Should start WF - payment.processIt(DocAction.ACTION_Complete); - if (!payment.save()) - s_log.log(Level.SEVERE, "Payment not saved: " + payment); - } - } // new Payment - - // Get Check Document No - try - { - int no = Integer.parseInt(check.getDocumentNo()); - if (lastDocumentNo < no) - lastDocumentNo = no; - } - catch (NumberFormatException ex) - { - s_log.log(Level.SEVERE, "DocumentNo=" + check.getDocumentNo(), ex); - } - check.setIsPrinted(true); - check.setProcessed(true); - if (!check.save ()) - s_log.log(Level.SEVERE, "Check not saved: " + check); - } // all checks - - s_log.fine("Last Document No = " + lastDocumentNo); - return lastDocumentNo; - } // confirmPrint - - /** Logger */ - static private CLogger s_log = CLogger.getCLogger (MPaySelectionCheck.class); - - /** BPartner Info Index for Value */ - private static final int BP_VALUE = 0; - /** BPartner Info Index for Name */ - private static final int BP_NAME = 1; - /** BPartner Info Index for Contact Name */ - private static final int BP_CONTACT = 2; - /** BPartner Info Index for Address 1 */ - private static final int BP_ADDR1 = 3; - /** BPartner Info Index for Address 2 */ - private static final int BP_ADDR2 = 4; - /** BPartner Info Index for City */ - private static final int BP_CITY = 5; - /** BPartner Info Index for Region */ - private static final int BP_REGION = 6; - /** BPartner Info Index for Postal Code */ - private static final int BP_POSTAL = 7; - /** BPartner Info Index for Country */ - private static final int BP_COUNTRY = 8; - /** BPartner Info Index for Reference No */ - private static final int BP_REFNO = 9; - - - /************************************************************************** - * Constructor - * @param ctx context - * @param C_PaySelectionCheck_ID C_PaySelectionCheck_ID - * @param trxName transaction - */ - public MPaySelectionCheck (Properties ctx, int C_PaySelectionCheck_ID, String trxName) - { - super(ctx, C_PaySelectionCheck_ID, trxName); - if (C_PaySelectionCheck_ID == 0) - { - // setC_PaySelection_ID (0); - // setC_BPartner_ID (0); - // setPaymentRule (null); - setPayAmt (Env.ZERO); - setDiscountAmt(Env.ZERO); - setIsPrinted (false); - setIsReceipt (false); - setQty (0); - } - } // MPaySelectionCheck - - /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MPaySelectionCheck(Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MPaySelectionCheck - - /** - * Create from Line - * @param line payment selection - * @param PaymentRule payment rule - */ - public MPaySelectionCheck (MPaySelectionLine line, String PaymentRule) - { + continue; + } + payment.setTrxType(X_C_Payment.TRXTYPE_CreditPayment); + payment.setAmount(check.getParent().getC_Currency_ID(), check.getPayAmt()); + payment.setDiscountAmt(check.getDiscountAmt()); + payment.setDateTrx(check.getParent().getPayDate()); + payment.setC_BPartner_ID(check.getC_BPartner_ID()); + // Link to Batch + if (batch != null) + { + if (batch.getC_PaymentBatch_ID() == 0) + batch.save(); // new + payment.setC_PaymentBatch_ID(batch.getC_PaymentBatch_ID()); + } + // Link to Invoice + MPaySelectionLine[] psls = check.getPaySelectionLines(false); + s_log.fine("confirmPrint - " + check + " (#SelectionLines=" + psls.length + ")"); + if (check.getQty() == 1 && psls != null && psls.length == 1) + { + MPaySelectionLine psl = psls[0]; + s_log.fine("Map to Invoice " + psl); + // + payment.setC_Invoice_ID (psl.getC_Invoice_ID()); + payment.setDiscountAmt (psl.getDiscountAmt()); + payment.setWriteOffAmt(psl.getDifferenceAmt()); + BigDecimal overUnder = psl.getOpenAmt().subtract(psl.getPayAmt()) + .subtract(psl.getDiscountAmt()).subtract(psl.getDifferenceAmt()); + payment.setOverUnderAmt(overUnder); + } + else + payment.setDiscountAmt(Env.ZERO); + payment.setWriteOffAmt(Env.ZERO); + if (!payment.save()) + s_log.log(Level.SEVERE, "Payment not saved: " + payment); + // + int C_Payment_ID = payment.get_ID(); + if (C_Payment_ID < 1) + s_log.log(Level.SEVERE, "Payment not created=" + check); + else + { + check.setC_Payment_ID (C_Payment_ID); + check.save(); // Payment process needs it + // Should start WF + payment.processIt(DocAction.ACTION_Complete); + if (!payment.save()) + s_log.log(Level.SEVERE, "Payment not saved: " + payment); + } + } // new Payment + + // Get Check Document No + try + { + int no = Integer.parseInt(check.getDocumentNo()); + if (lastDocumentNo < no) + lastDocumentNo = no; + } + catch (NumberFormatException ex) + { + s_log.log(Level.SEVERE, "DocumentNo=" + check.getDocumentNo(), ex); + } + check.setIsPrinted(true); + check.setProcessed(true); + if (!check.save ()) + s_log.log(Level.SEVERE, "Check not saved: " + check); + } // all checks + + s_log.fine("Last Document No = " + lastDocumentNo); + return lastDocumentNo; + } // confirmPrint + + /** Logger */ + static private CLogger s_log = CLogger.getCLogger (MPaySelectionCheck.class); + + /** BPartner Info Index for Value */ + private static final int BP_VALUE = 0; + /** BPartner Info Index for Name */ + private static final int BP_NAME = 1; + /** BPartner Info Index for Contact Name */ + private static final int BP_CONTACT = 2; + /** BPartner Info Index for Address 1 */ + private static final int BP_ADDR1 = 3; + /** BPartner Info Index for Address 2 */ + private static final int BP_ADDR2 = 4; + /** BPartner Info Index for City */ + private static final int BP_CITY = 5; + /** BPartner Info Index for Region */ + private static final int BP_REGION = 6; + /** BPartner Info Index for Postal Code */ + private static final int BP_POSTAL = 7; + /** BPartner Info Index for Country */ + private static final int BP_COUNTRY = 8; + /** BPartner Info Index for Reference No */ + private static final int BP_REFNO = 9; + + + /************************************************************************** + * Constructor + * @param ctx context + * @param C_PaySelectionCheck_ID C_PaySelectionCheck_ID + * @param trxName transaction + */ + public MPaySelectionCheck (Properties ctx, int C_PaySelectionCheck_ID, String trxName) + { + super(ctx, C_PaySelectionCheck_ID, trxName); + if (C_PaySelectionCheck_ID == 0) + { + // setC_PaySelection_ID (0); + // setC_BPartner_ID (0); + // setPaymentRule (null); + setPayAmt (Env.ZERO); + setDiscountAmt(Env.ZERO); + setIsPrinted (false); + setIsReceipt (false); + setQty (0); + } + } // MPaySelectionCheck + + /** + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MPaySelectionCheck(Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MPaySelectionCheck + + /** + * Create from Line + * @param line payment selection + * @param PaymentRule payment rule + */ + public MPaySelectionCheck (MPaySelectionLine line, String PaymentRule) + { this (line.getCtx(), 0, line.get_TrxName()); setClientOrg(line); setC_PaySelection_ID (line.getC_PaySelection_ID()); - setC_BPartner_ID (line.getInvoice().getC_BPartner_ID()); + int C_BPartner_ID = line.getInvoice().getC_BPartner_ID(); + setC_BPartner_ID (C_BPartner_ID); + // + if (X_C_Order.PAYMENTRULE_DirectDebit.equals(PaymentRule)) + { + MBPBankAccount[] bas = MBPBankAccount.getOfBPartner (line.getCtx(), C_BPartner_ID); + for (int i = 0; i < bas.length; i++) + { + MBPBankAccount account = bas[i]; + if (account.isDirectDebit()) + { + setC_BP_BankAccount_ID(account.getC_BP_BankAccount_ID()); + break; + } + } + } + else if (X_C_Order.PAYMENTRULE_DirectDeposit.equals(PaymentRule)) + { + MBPBankAccount[] bas = MBPBankAccount.getOfBPartner (line.getCtx(), C_BPartner_ID); + for (int i = 0; i < bas.length; i++) + { + MBPBankAccount account = bas[i]; + if (account.isDirectDeposit()) + { + setC_BP_BankAccount_ID(account.getC_BP_BankAccount_ID()); + break; + } + } + } setPaymentRule (PaymentRule); // setIsReceipt(line.isSOTrx()); - setPayAmt (line.getPayAmt()); - setDiscountAmt(line.getDiscountAmt()); - setQty (1); - } // MPaySelectionCheck - - /** - * Create from Pay Selection - * @param ps payment selection - * @param PaymentRule payment rule - */ - public MPaySelectionCheck (MPaySelection ps, String PaymentRule) - { - this (ps.getCtx(), 0, ps.get_TrxName()); - setClientOrg(ps); - setC_PaySelection_ID (ps.getC_PaySelection_ID()); - setPaymentRule (PaymentRule); - } // MPaySelectionCheck - - - /** Parent */ - private MPaySelection m_parent = null; - /** Payment Selection lines of this check */ - private MPaySelectionLine[] m_lines = null; - - - /** - * Add Payment Selection Line - * @param line line - */ - public void addLine (MPaySelectionLine line) - { - if (getC_BPartner_ID() != line.getInvoice().getC_BPartner_ID()) - throw new IllegalArgumentException("Line for fifferent BPartner"); - // - if (isReceipt() == line.isSOTrx()) - { - setPayAmt (getPayAmt().add(line.getPayAmt())); - setDiscountAmt(getDiscountAmt().add(line.getDiscountAmt())); - } - else - { - setPayAmt (getPayAmt().subtract(line.getPayAmt())); - setDiscountAmt(getDiscountAmt().subtract(line.getDiscountAmt())); - } - setQty (getQty()+1); - } // addLine - - /** - * Get Parent - * @return parent - */ - public MPaySelection getParent() - { - if (m_parent == null) - m_parent = new MPaySelection (getCtx(), getC_PaySelection_ID(), get_TrxName()); - return m_parent; + setPayAmt (line.getPayAmt()); + setDiscountAmt(line.getDiscountAmt()); + setQty (1); + } // MPaySelectionCheck + + /** + * Create from Pay Selection + * @param ps payment selection + * @param PaymentRule payment rule + */ + public MPaySelectionCheck (MPaySelection ps, String PaymentRule) + { + this (ps.getCtx(), 0, ps.get_TrxName()); + setClientOrg(ps); + setC_PaySelection_ID (ps.getC_PaySelection_ID()); + setPaymentRule (PaymentRule); + } // MPaySelectionCheck + + + /** Parent */ + private MPaySelection m_parent = null; + /** Payment Selection lines of this check */ + private MPaySelectionLine[] m_lines = null; + + + /** + * Add Payment Selection Line + * @param line line + */ + public void addLine (MPaySelectionLine line) + { + if (getC_BPartner_ID() != line.getInvoice().getC_BPartner_ID()) + throw new IllegalArgumentException("Line for fifferent BPartner"); + // + if (isReceipt() == line.isSOTrx()) + { + setPayAmt (getPayAmt().add(line.getPayAmt())); + setDiscountAmt(getDiscountAmt().add(line.getDiscountAmt())); + } + else + { + setPayAmt (getPayAmt().subtract(line.getPayAmt())); + setDiscountAmt(getDiscountAmt().subtract(line.getDiscountAmt())); + } + setQty (getQty()+1); + } // addLine + + /** + * Get Parent + * @return parent + */ + public MPaySelection getParent() + { + if (m_parent == null) + m_parent = new MPaySelection (getCtx(), getC_PaySelection_ID(), get_TrxName()); + return m_parent; } // getParent + /** + * Is this a valid Prepared Payment + * @return true if valid + */ + public boolean isValid() + { + if (getC_BP_BankAccount_ID() != 0) + return true; + return !isDirect(); + } // isValid + + /** + * Is this a direct Debit or Deposit + * @return true if direct + */ + public boolean isDirect() + { + return (X_C_Order.PAYMENTRULE_DirectDeposit.equals(getPaymentRule()) + || X_C_Order.PAYMENTRULE_DirectDebit.equals(getPaymentRule())); + } // isDirect + /** * String Representation * @return info */ - public String toString() - { - StringBuffer sb = new StringBuffer("MPaymentCheck["); - sb.append(get_ID()).append("-").append(getDocumentNo()) - .append("-").append(getPayAmt()) - .append(",PaymetRule=").append(getPaymentRule()) - .append(",Qty=").append(getQty()) - .append("]"); - return sb.toString(); - } // toString - - /** - * Get Payment Selection Lines of this check - * @param requery requery - * @return array of peyment selection lines - */ - public MPaySelectionLine[] getPaySelectionLines (boolean requery) - { - if (m_lines != null && !requery) - return m_lines; - ArrayList list = new ArrayList(); - String sql = "SELECT * FROM C_PaySelectionLine WHERE C_PaySelectionCheck_ID=? ORDER BY Line"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, get_TrxName()); - pstmt.setInt (1, getC_PaySelectionCheck_ID()); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - list.add (new MPaySelectionLine(getCtx(), rs, get_TrxName())); - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - // - m_lines = new MPaySelectionLine[list.size ()]; - list.toArray (m_lines); - return m_lines; - } // getPaySelectionLines - - -} // MPaySelectionCheck + public String toString() + { + StringBuffer sb = new StringBuffer("MPaymentCheck["); + sb.append(get_ID()).append("-").append(getDocumentNo()) + .append("-").append(getPayAmt()) + .append(",PaymetRule=").append(getPaymentRule()) + .append(",Qty=").append(getQty()) + .append("]"); + return sb.toString(); + } // toString + + /** + * Get Payment Selection Lines of this check + * @param requery requery + * @return array of peyment selection lines + */ + public MPaySelectionLine[] getPaySelectionLines (boolean requery) + { + if (m_lines != null && !requery) + return m_lines; + ArrayList list = new ArrayList(); + String sql = "SELECT * FROM C_PaySelectionLine WHERE C_PaySelectionCheck_ID=? ORDER BY Line"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, get_TrxName()); + pstmt.setInt (1, getC_PaySelectionCheck_ID()); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + list.add (new MPaySelectionLine(getCtx(), rs, get_TrxName())); + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // + m_lines = new MPaySelectionLine[list.size ()]; + list.toArray (m_lines); + return m_lines; + } // getPaySelectionLines + + +} // MPaySelectionCheck diff --git a/base/src/org/compiere/model/MPaySelectionLine.java b/base/src/org/compiere/model/MPaySelectionLine.java index 7e4a9eff15..22f6d82da8 100644 --- a/base/src/org/compiere/model/MPaySelectionLine.java +++ b/base/src/org/compiere/model/MPaySelectionLine.java @@ -3,176 +3,175 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.math.*; -import java.sql.*; -import java.util.*; -import org.compiere.util.*; - -/** - * Payment Selection Line Model - * - * @author Jorg Janke - * @version $Id: MPaySelectionLine.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ - */ -public class MPaySelectionLine extends X_C_PaySelectionLine -{ - /** - * Standard Constructor - * @param ctx context - * @param C_PaySelectionLine_ID id - * @param trxName transaction - */ - public MPaySelectionLine (Properties ctx, int C_PaySelectionLine_ID, String trxName) - { - super(ctx, C_PaySelectionLine_ID, trxName); - if (C_PaySelectionLine_ID == 0) - { - // setC_PaySelection_ID (0); - // setPaymentRule (null); // S - // setLine (0); // @SQL=SELECT NVL(MAX(Line),0)+10 AS DefaultValue FROM C_PaySelectionLine WHERE C_PaySelection_ID=@C_PaySelection_ID@ - // setC_Invoice_ID (0); - setIsSOTrx (false); - setOpenAmt(Env.ZERO); - setPayAmt (Env.ZERO); - setDiscountAmt(Env.ZERO); - setDifferenceAmt (Env.ZERO); - setIsManual (false); - } - } // MPaySelectionLine - - /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MPaySelectionLine(Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MPaySelectionLine - - /** - * Parent Constructor - * @param ps parent - * @param Line line - * @param PaymentRule payment rule - */ - public MPaySelectionLine (MPaySelection ps, int Line, String PaymentRule) - { - this (ps.getCtx(), 0, ps.get_TrxName()); - setClientOrg(ps); - setC_PaySelection_ID(ps.getC_PaySelection_ID()); - setLine(Line); - setPaymentRule(PaymentRule); - } // MPaySelectionLine - - /** Invoice */ - private MInvoice m_invoice = null; - - /** - * Set Invoice Info - * @param C_Invoice_ID invoice - * @param isSOTrx sales trx - * @param PayAmt payment - * @param OpenAmt open - * @param DiscountAmt discount - */ - public void setInvoice (int C_Invoice_ID, boolean isSOTrx, BigDecimal OpenAmt, - BigDecimal PayAmt, BigDecimal DiscountAmt) - { - setC_Invoice_ID (C_Invoice_ID); - setIsSOTrx(isSOTrx); - setOpenAmt(OpenAmt); - setPayAmt (PayAmt); - setDiscountAmt(DiscountAmt); - setDifferenceAmt(OpenAmt.subtract(PayAmt).subtract(DiscountAmt)); - } // setInvoive - - /** - * Get Invoice - * @return invoice - */ - public MInvoice getInvoice() - { - if (m_invoice == null) - m_invoice = new MInvoice (getCtx(), getC_Invoice_ID(), get_TrxName()); + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.math.*; +import java.sql.*; +import java.util.*; +import org.compiere.util.*; + +/** + * Payment Selection Line Model + * + * @author Jorg Janke + * @version $Id: MPaySelectionLine.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ + */ +public class MPaySelectionLine extends X_C_PaySelectionLine +{ + /** + * Standard Constructor + * @param ctx context + * @param C_PaySelectionLine_ID id + * @param trxName transaction + */ + public MPaySelectionLine (Properties ctx, int C_PaySelectionLine_ID, String trxName) + { + super(ctx, C_PaySelectionLine_ID, trxName); + if (C_PaySelectionLine_ID == 0) + { + // setC_PaySelection_ID (0); + // setPaymentRule (null); // S + // setLine (0); // @SQL=SELECT NVL(MAX(Line),0)+10 AS DefaultValue FROM C_PaySelectionLine WHERE C_PaySelection_ID=@C_PaySelection_ID@ + // setC_Invoice_ID (0); + setIsSOTrx (false); + setOpenAmt(Env.ZERO); + setPayAmt (Env.ZERO); + setDiscountAmt(Env.ZERO); + setDifferenceAmt (Env.ZERO); + setIsManual (false); + } + } // MPaySelectionLine + + /** + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MPaySelectionLine(Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MPaySelectionLine + + /** + * Parent Constructor + * @param ps parent + * @param Line line + * @param PaymentRule payment rule + */ + public MPaySelectionLine (MPaySelection ps, int Line, String PaymentRule) + { + this (ps.getCtx(), 0, ps.get_TrxName()); + setClientOrg(ps); + setC_PaySelection_ID(ps.getC_PaySelection_ID()); + setLine(Line); + setPaymentRule(PaymentRule); + } // MPaySelectionLine + + /** Invoice */ + private MInvoice m_invoice = null; + + /** + * Set Invoice Info + * @param C_Invoice_ID invoice + * @param isSOTrx sales trx + * @param PayAmt payment + * @param OpenAmt open + * @param DiscountAmt discount + */ + public void setInvoice (int C_Invoice_ID, boolean isSOTrx, BigDecimal OpenAmt, + BigDecimal PayAmt, BigDecimal DiscountAmt) + { + setC_Invoice_ID (C_Invoice_ID); + setIsSOTrx(isSOTrx); + setOpenAmt(OpenAmt); + setPayAmt (PayAmt); + setDiscountAmt(DiscountAmt); + setDifferenceAmt(OpenAmt.subtract(PayAmt).subtract(DiscountAmt)); + } // setInvoive + + /** + * Get Invoice + * @return invoice + */ + public MInvoice getInvoice() + { + if (m_invoice == null) + m_invoice = new MInvoice (getCtx(), getC_Invoice_ID(), get_TrxName()); return m_invoice; } // getInvoice - /** * Before Save * @param newRecord new - * @return true - */ - protected boolean beforeSave (boolean newRecord) - { - setDifferenceAmt(getOpenAmt().subtract(getPayAmt()).subtract(getDiscountAmt())); - return true; - } // beforeSave - - /** - * After Save - * @param newRecord new - * @param success success - * @return success - */ - protected boolean afterSave (boolean newRecord, boolean success) - { - setHeader(); - return success; - } // afterSave - - /** - * After Delete - * @param success success - * @return sucess - */ - protected boolean afterDelete (boolean success) - { - setHeader(); - return success; - } // afterDelete - - /** - * Recalculate Header Sum - */ - private void setHeader() - { - // Update Header - String sql = "UPDATE C_PaySelection ps " - + "SET TotalAmt = (SELECT COALESCE(SUM(psl.PayAmt),0) " - + "FROM C_PaySelectionLine psl " - + "WHERE ps.C_PaySelection_ID=psl.C_PaySelection_ID AND psl.IsActive='Y') " - + "WHERE C_PaySelection_ID=" + getC_PaySelection_ID(); - DB.executeUpdate(sql, get_TrxName()); - } // setHeader - - /** - * String Representation - * @return info - */ - public String toString() - { - StringBuffer sb = new StringBuffer("MPaySelectionLine["); - sb.append(get_ID()).append(",C_Invoice_ID=").append(getC_Invoice_ID()) - .append(",PayAmt=").append(getPayAmt()) - .append(",DifferenceAmt=").append(getDifferenceAmt()) - .append("]"); - return sb.toString(); - } // toString - -} // MPaySelectionLine + * @return true + */ + protected boolean beforeSave (boolean newRecord) + { + setDifferenceAmt(getOpenAmt().subtract(getPayAmt()).subtract(getDiscountAmt())); + return true; + } // beforeSave + + /** + * After Save + * @param newRecord new + * @param success success + * @return success + */ + protected boolean afterSave (boolean newRecord, boolean success) + { + setHeader(); + return success; + } // afterSave + + /** + * After Delete + * @param success success + * @return sucess + */ + protected boolean afterDelete (boolean success) + { + setHeader(); + return success; + } // afterDelete + + /** + * Recalculate Header Sum + */ + private void setHeader() + { + // Update Header + String sql = "UPDATE C_PaySelection ps " + + "SET TotalAmt = (SELECT COALESCE(SUM(psl.PayAmt),0) " + + "FROM C_PaySelectionLine psl " + + "WHERE ps.C_PaySelection_ID=psl.C_PaySelection_ID AND psl.IsActive='Y') " + + "WHERE C_PaySelection_ID=" + getC_PaySelection_ID(); + DB.executeUpdate(sql, get_TrxName()); + } // setHeader + + /** + * String Representation + * @return info + */ + public String toString() + { + StringBuffer sb = new StringBuffer("MPaySelectionLine["); + sb.append(get_ID()).append(",C_Invoice_ID=").append(getC_Invoice_ID()) + .append(",PayAmt=").append(getPayAmt()) + .append(",DifferenceAmt=").append(getDifferenceAmt()) + .append("]"); + return sb.toString(); + } // toString + +} // MPaySelectionLine diff --git a/base/src/org/compiere/model/MPayment.java b/base/src/org/compiere/model/MPayment.java index c1a4a79b98..ffa43a4456 100644 --- a/base/src/org/compiere/model/MPayment.java +++ b/base/src/org/compiere/model/MPayment.java @@ -3,2288 +3,2296 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.io.*; -import java.math.*; -import java.rmi.*; -import java.sql.*; -import java.util.*; -import java.util.logging.*; - -import org.compiere.db.*; -import org.compiere.interfaces.*; -import org.compiere.process.*; -import org.compiere.util.*; - -/** - * Payment Model. - * - retrieve and create payments for invoice - *

- *  Event chain
- *  - Payment inserted
- *      C_Payment_Trg fires
- *          update DocumentNo with payment summary
- *  - Payment posted (C_Payment_Post)
- *      create allocation line
- *          C_Allocation_Trg fires
- *              Update C_BPartner Open Item Amount
- *      update invoice (IsPaid)
- *      link invoice-payment if batch
- *
- *  Lifeline:
- *  -   Created by VPayment or directly
- *  -   When changed in VPayment
- *      - old payment is reversed
- *      - new payment created
- *
- *  When Payment is posed, the Allocation is made
- *  
- * @author Jorg Janke - * @version $Id: MPayment.java,v 1.4 2006/10/02 05:18:39 jjanke Exp $ - */ -public final class MPayment extends X_C_Payment - implements DocAction, ProcessCall -{ - /** - * Get Payments Of BPartner - * @param ctx context - * @param C_BPartner_ID id - * @param trxName transaction - * @return array - */ - public static MPayment[] getOfBPartner (Properties ctx, int C_BPartner_ID, String trxName) - { - ArrayList list = new ArrayList(); - String sql = "SELECT * FROM C_Payment WHERE C_BPartner_ID=?"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement(sql, trxName); - pstmt.setInt(1, C_BPartner_ID); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) - list.add(new MPayment(ctx,rs, trxName)); - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - s_log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - - // - MPayment[] retValue = new MPayment[list.size()]; - list.toArray(retValue); - return retValue; - } // getOfBPartner - - - /************************************************************************** - * Default Constructor - * @param ctx context - * @param C_Payment_ID payment to load, (0 create new payment) - * @param trxName trx name - */ - public MPayment (Properties ctx, int C_Payment_ID, String trxName) - { - super (ctx, C_Payment_ID, trxName); - // New - if (C_Payment_ID == 0) - { - setDocAction(DOCACTION_Complete); - setDocStatus(DOCSTATUS_Drafted); - setTrxType(TRXTYPE_Sales); - // - setR_AvsAddr (R_AVSZIP_Unavailable); - setR_AvsZip (R_AVSZIP_Unavailable); - // - setIsReceipt (true); - setIsApproved (false); - setIsReconciled (false); - setIsAllocated(false); - setIsOnline (false); - setIsSelfService(false); - setIsDelayedCapture (false); - setIsPrepayment(false); - setProcessed(false); - setProcessing(false); - setPosted (false); - // - setPayAmt(Env.ZERO); - setDiscountAmt(Env.ZERO); - setTaxAmt(Env.ZERO); - setWriteOffAmt(Env.ZERO); - setIsOverUnderPayment (false); - setOverUnderAmt(Env.ZERO); - // - setDateTrx (new Timestamp(System.currentTimeMillis())); - setDateAcct (getDateTrx()); - setTenderType(TENDERTYPE_Check); - } - } // MPayment - - /** - * Load Constructor - * @param ctx context - * @param rs result set record - * @param trxName transaction - */ - public MPayment (Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MPayment - - /** Temporary Payment Processors */ - private MPaymentProcessor[] m_mPaymentProcessors = null; - /** Temporary Payment Processor */ - private MPaymentProcessor m_mPaymentProcessor = null; - /** Logger */ - private static CLogger s_log = CLogger.getCLogger (MPayment.class); - /** Error Message */ - private String m_errorMessage = null; - - /** Reversal Indicator */ - public static String REVERSE_INDICATOR = "^"; - - /** - * Reset Payment to new status - */ - public void resetNew() - { - setC_Payment_ID(0); // forces new Record - set_ValueNoCheck ("DocumentNo", null); - setDocAction(DOCACTION_Prepare); - setDocStatus(DOCSTATUS_Drafted); - setProcessed(false); - setPosted (false); - setIsReconciled (false); - setIsAllocated(false); - setIsOnline(false); - setIsDelayedCapture (false); - // setC_BPartner_ID(0); - setC_Invoice_ID(0); - setC_Order_ID(0); - setC_Charge_ID(0); - setC_Project_ID(0); - setIsPrepayment(false); - } // resetNew - - /** - * Is Cashbook Transfer Trx - * @return true if Cash Trx - */ - public boolean isCashTrx() - { - return "X".equals(getTenderType()); - } // isCashTrx - - /************************************************************************** - * Set Credit Card. - * Need to set PatmentProcessor after Amount/Currency Set - * - * @param TrxType Transaction Type see TRX_ - * @param creditCardType CC type - * @param creditCardNumber CC number - * @param creditCardVV CC verification - * @param creditCardExpMM CC Exp MM - * @param creditCardExpYY CC Exp YY - * @return true if valid - */ - public boolean setCreditCard (String TrxType, String creditCardType, String creditCardNumber, - String creditCardVV, int creditCardExpMM, int creditCardExpYY) - { - setTenderType(TENDERTYPE_CreditCard); - setTrxType(TrxType); - // - setCreditCardType (creditCardType); - setCreditCardNumber (creditCardNumber); - setCreditCardVV (creditCardVV); - setCreditCardExpMM (creditCardExpMM); - setCreditCardExpYY (creditCardExpYY); - // - int check = MPaymentValidate.validateCreditCardNumber(creditCardNumber, creditCardType).length() - + MPaymentValidate.validateCreditCardExp(creditCardExpMM, creditCardExpYY).length(); - if (creditCardVV.length() > 0) - check += MPaymentValidate.validateCreditCardVV(creditCardVV, creditCardType).length(); - return check == 0; - } // setCreditCard - - /** - * Set Credit Card - Exp. - * Need to set PatmentProcessor after Amount/Currency Set - * - * @param TrxType Transaction Type see TRX_ - * @param creditCardType CC type - * @param creditCardNumber CC number - * @param creditCardVV CC verification - * @param creditCardExp CC Exp - * @return true if valid - */ - public boolean setCreditCard (String TrxType, String creditCardType, String creditCardNumber, - String creditCardVV, String creditCardExp) - { - return setCreditCard(TrxType, creditCardType, creditCardNumber, - creditCardVV, MPaymentValidate.getCreditCardExpMM(creditCardExp), - MPaymentValidate.getCreditCardExpYY(creditCardExp)); - } // setCreditCard - - /** - * Set ACH BankAccount Info - * - * @param C_BankAccount_ID bank account + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.io.*; +import java.math.*; +import java.rmi.*; +import java.sql.*; +import java.util.*; +import java.util.logging.*; + +import org.compiere.db.*; +import org.compiere.interfaces.*; +import org.compiere.process.*; +import org.compiere.util.*; + +/** + * Payment Model. + * - retrieve and create payments for invoice + *
+ *  Event chain
+ *  - Payment inserted
+ *      C_Payment_Trg fires
+ *          update DocumentNo with payment summary
+ *  - Payment posted (C_Payment_Post)
+ *      create allocation line
+ *          C_Allocation_Trg fires
+ *              Update C_BPartner Open Item Amount
+ *      update invoice (IsPaid)
+ *      link invoice-payment if batch
+ *
+ *  Lifeline:
+ *  -   Created by VPayment or directly
+ *  -   When changed in VPayment
+ *      - old payment is reversed
+ *      - new payment created
+ *
+ *  When Payment is posed, the Allocation is made
+ *  
+ * @author Jorg Janke + * @version $Id: MPayment.java,v 1.4 2006/10/02 05:18:39 jjanke Exp $ + */ +public final class MPayment extends X_C_Payment + implements DocAction, ProcessCall +{ + /** + * Get Payments Of BPartner + * @param ctx context + * @param C_BPartner_ID id + * @param trxName transaction + * @return array + */ + public static MPayment[] getOfBPartner (Properties ctx, int C_BPartner_ID, String trxName) + { + ArrayList list = new ArrayList(); + String sql = "SELECT * FROM C_Payment WHERE C_BPartner_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, trxName); + pstmt.setInt(1, C_BPartner_ID); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + list.add(new MPayment(ctx,rs, trxName)); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + + // + MPayment[] retValue = new MPayment[list.size()]; + list.toArray(retValue); + return retValue; + } // getOfBPartner + + + /************************************************************************** + * Default Constructor + * @param ctx context + * @param C_Payment_ID payment to load, (0 create new payment) + * @param trxName trx name + */ + public MPayment (Properties ctx, int C_Payment_ID, String trxName) + { + super (ctx, C_Payment_ID, trxName); + // New + if (C_Payment_ID == 0) + { + setDocAction(DOCACTION_Complete); + setDocStatus(DOCSTATUS_Drafted); + setTrxType(TRXTYPE_Sales); + // + setR_AvsAddr (R_AVSZIP_Unavailable); + setR_AvsZip (R_AVSZIP_Unavailable); + // + setIsReceipt (true); + setIsApproved (false); + setIsReconciled (false); + setIsAllocated(false); + setIsOnline (false); + setIsSelfService(false); + setIsDelayedCapture (false); + setIsPrepayment(false); + setProcessed(false); + setProcessing(false); + setPosted (false); + // + setPayAmt(Env.ZERO); + setDiscountAmt(Env.ZERO); + setTaxAmt(Env.ZERO); + setWriteOffAmt(Env.ZERO); + setIsOverUnderPayment (false); + setOverUnderAmt(Env.ZERO); + // + setDateTrx (new Timestamp(System.currentTimeMillis())); + setDateAcct (getDateTrx()); + setTenderType(TENDERTYPE_Check); + } + } // MPayment + + /** + * Load Constructor + * @param ctx context + * @param rs result set record + * @param trxName transaction + */ + public MPayment (Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MPayment + + /** Temporary Payment Processors */ + private MPaymentProcessor[] m_mPaymentProcessors = null; + /** Temporary Payment Processor */ + private MPaymentProcessor m_mPaymentProcessor = null; + /** Logger */ + private static CLogger s_log = CLogger.getCLogger (MPayment.class); + /** Error Message */ + private String m_errorMessage = null; + + /** Reversal Indicator */ + public static String REVERSE_INDICATOR = "^"; + + /** + * Reset Payment to new status + */ + public void resetNew() + { + setC_Payment_ID(0); // forces new Record + set_ValueNoCheck ("DocumentNo", null); + setDocAction(DOCACTION_Prepare); + setDocStatus(DOCSTATUS_Drafted); + setProcessed(false); + setPosted (false); + setIsReconciled (false); + setIsAllocated(false); + setIsOnline(false); + setIsDelayedCapture (false); + // setC_BPartner_ID(0); + setC_Invoice_ID(0); + setC_Order_ID(0); + setC_Charge_ID(0); + setC_Project_ID(0); + setIsPrepayment(false); + } // resetNew + + /** + * Is Cashbook Transfer Trx + * @return true if Cash Trx + */ + public boolean isCashTrx() + { + return "X".equals(getTenderType()); + } // isCashTrx + + /************************************************************************** + * Set Credit Card. + * Need to set PatmentProcessor after Amount/Currency Set + * + * @param TrxType Transaction Type see TRX_ + * @param creditCardType CC type + * @param creditCardNumber CC number + * @param creditCardVV CC verification + * @param creditCardExpMM CC Exp MM + * @param creditCardExpYY CC Exp YY + * @return true if valid + */ + public boolean setCreditCard (String TrxType, String creditCardType, String creditCardNumber, + String creditCardVV, int creditCardExpMM, int creditCardExpYY) + { + setTenderType(TENDERTYPE_CreditCard); + setTrxType(TrxType); + // + setCreditCardType (creditCardType); + setCreditCardNumber (creditCardNumber); + setCreditCardVV (creditCardVV); + setCreditCardExpMM (creditCardExpMM); + setCreditCardExpYY (creditCardExpYY); + // + int check = MPaymentValidate.validateCreditCardNumber(creditCardNumber, creditCardType).length() + + MPaymentValidate.validateCreditCardExp(creditCardExpMM, creditCardExpYY).length(); + if (creditCardVV.length() > 0) + check += MPaymentValidate.validateCreditCardVV(creditCardVV, creditCardType).length(); + return check == 0; + } // setCreditCard + + /** + * Set Credit Card - Exp. + * Need to set PatmentProcessor after Amount/Currency Set + * + * @param TrxType Transaction Type see TRX_ + * @param creditCardType CC type + * @param creditCardNumber CC number + * @param creditCardVV CC verification + * @param creditCardExp CC Exp + * @return true if valid + */ + public boolean setCreditCard (String TrxType, String creditCardType, String creditCardNumber, + String creditCardVV, String creditCardExp) + { + return setCreditCard(TrxType, creditCardType, creditCardNumber, + creditCardVV, MPaymentValidate.getCreditCardExpMM(creditCardExp), + MPaymentValidate.getCreditCardExpYY(creditCardExp)); + } // setCreditCard + + /** + * Set ACH BankAccount Info + * + * @param C_BankAccount_ID bank account * @param isReceipt true if receipt * @return true if valid */ - public boolean setBankACH (int C_BankAccount_ID, boolean isReceipt) + public boolean setBankACH (MPaySelectionCheck preparedPayment) { - setBankAccountDetails(C_BankAccount_ID); - setIsReceipt (isReceipt); + // Our Bank + setC_BankAccount_ID(preparedPayment.getParent().getC_BankAccount_ID()); + // Target Bank + int C_BP_BankAccount_ID = preparedPayment.getC_BP_BankAccount_ID(); + MBPBankAccount ba = new MBPBankAccount (preparedPayment.getCtx(), C_BP_BankAccount_ID, null); + setRoutingNo(ba.getRoutingNo()); + setAccountNo(ba.getAccountNo()); + setIsReceipt (X_C_Order.PAYMENTRULE_DirectDebit.equals // AR only + (preparedPayment.getPaymentRule())); // int check = MPaymentValidate.validateRoutingNo(getRoutingNo()).length() + MPaymentValidate.validateAccountNo(getAccountNo()).length(); - return check == 0; - } // setBankACH - - /** - * Set ACH BankAccount Info - * - * @param C_BankAccount_ID bank account - * @param isReceipt true if receipt - * @param tenderType - Direct Debit or Direct Deposit - * @param routingNo routing - * @param accountNo account - * @return true if valid - */ - public boolean setBankACH (int C_BankAccount_ID, boolean isReceipt, String tenderType, - String routingNo, String accountNo) - { - setTenderType (tenderType); - setIsReceipt (isReceipt); - // - if (C_BankAccount_ID > 0 - && (routingNo == null || routingNo.length() == 0 || accountNo == null || accountNo.length() == 0)) - setBankAccountDetails(C_BankAccount_ID); - else - { - setC_BankAccount_ID(C_BankAccount_ID); - setRoutingNo (routingNo); - setAccountNo (accountNo); - } - setCheckNo (""); - // - int check = MPaymentValidate.validateRoutingNo(routingNo).length() - + MPaymentValidate.validateAccountNo(accountNo).length(); - return check == 0; - } // setBankACH - - /** - * Set Check BankAccount Info - * - * @param C_BankAccount_ID bank account - * @param isReceipt true if receipt - * @param checkNo chack no - * @return true if valid - */ - public boolean setBankCheck (int C_BankAccount_ID, boolean isReceipt, String checkNo) - { - return setBankCheck (C_BankAccount_ID, isReceipt, null, null, checkNo); - } // setBankCheck - - /** - * Set Check BankAccount Info - * - * @param C_BankAccount_ID bank account - * @param isReceipt true if receipt - * @param routingNo routing no - * @param accountNo account no - * @param checkNo chack no - * @return true if valid - */ - public boolean setBankCheck (int C_BankAccount_ID, boolean isReceipt, - String routingNo, String accountNo, String checkNo) - { - setTenderType (TENDERTYPE_Check); - setIsReceipt (isReceipt); - // - if (C_BankAccount_ID > 0 - && (routingNo == null || routingNo.length() == 0 - || accountNo == null || accountNo.length() == 0)) - setBankAccountDetails(C_BankAccount_ID); - else - { - setC_BankAccount_ID(C_BankAccount_ID); - setRoutingNo (routingNo); - setAccountNo (accountNo); - } - setCheckNo (checkNo); - // - int check = MPaymentValidate.validateRoutingNo(routingNo).length() - + MPaymentValidate.validateAccountNo(accountNo).length() - + MPaymentValidate.validateCheckNo(checkNo).length(); - return check == 0; // no error message - } // setBankCheck - - /** - * Set Bank Account Details. - * Look up Routing No & Bank Acct No - * @param C_BankAccount_ID bank account - */ - public void setBankAccountDetails (int C_BankAccount_ID) - { - if (C_BankAccount_ID == 0) - return; - setC_BankAccount_ID(C_BankAccount_ID); - // - String sql = "SELECT b.RoutingNo, ba.AccountNo " - + "FROM C_BankAccount ba" - + " INNER JOIN C_Bank b ON (ba.C_Bank_ID=b.C_Bank_ID) " - + "WHERE C_BankAccount_ID=?"; - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, C_BankAccount_ID); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - { - setRoutingNo (rs.getString(1)); - setAccountNo (rs.getString(2)); - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - } - } // setBankAccountDetails - - /** - * Set Account Address - * - * @param name name - * @param street street - * @param city city - * @param state state - * @param zip zip - * @param country country - */ - public void setAccountAddress (String name, String street, - String city, String state, String zip, String country) - { - setA_Name (name); - setA_Street (street); - setA_City (city); - setA_State (state); - setA_Zip (zip); - setA_Country(country); - } // setAccountAddress - - - /************************************************************************** - * Process Payment - * @return true if approved - */ - public boolean processOnline() - { - log.info ("Amt=" + getPayAmt()); - // - setIsOnline(true); - setErrorMessage(null); - // prevent charging twice - if (isApproved()) - { - log.info("Already processed - " + getR_Result() + " - " + getR_RespMsg()); - setErrorMessage("Payment already Processed"); - return true; - } - - if (m_mPaymentProcessor == null) - setPaymentProcessor(); - if (m_mPaymentProcessor == null) - { - log.log(Level.WARNING, "No Payment Processor Model"); - setErrorMessage("No Payment Processor Model"); - return false; - } - - boolean approved = false; - /** Process Payment on Server */ - if (DB.isRemoteObjects()) - { - Server server = CConnection.get().getServer(); - try - { - if (server != null) - { // See ServerBean - String trxName = null; // unconditionally save - save(trxName); // server reads from disk - approved = server.paymentOnline (getCtx(), getC_Payment_ID(), - m_mPaymentProcessor.getC_PaymentProcessor_ID(), trxName); - if (CLogMgt.isLevelFinest()) - s_log.fine("server => " + approved); - load(trxName); // server saves to disk - setIsApproved(approved); - return approved; - } - log.log(Level.WARNING, "AppsServer not found"); - } - catch (RemoteException ex) - { - log.log(Level.SEVERE, "AppsServer error", ex); - } - } - /** **/ - - // Try locally - try - { - PaymentProcessor pp = PaymentProcessor.create(m_mPaymentProcessor, this); - if (pp == null) - setErrorMessage("No Payment Processor"); - else - { - approved = pp.processCC (); - if (approved) - setErrorMessage(null); - else - setErrorMessage("From " + getCreditCardName() + ": " + getR_RespMsg()); - } - } - catch (Exception e) - { - log.log(Level.SEVERE, "processOnline", e); - setErrorMessage("Payment Processor Error"); - } - setIsApproved(approved); - return approved; - } // processOnline - - /** - * Process Online Payment. - * implements ProcessCall after standard constructor - * Called when pressing the Process_Online button in C_Payment - * - * @param ctx Context - * @param pi Process Info - * @param trx transaction - * @return true if the next process should be performed - */ - public boolean startProcess (Properties ctx, ProcessInfo pi, Trx trx) - { - log.info("startProcess - " + pi.getRecord_ID()); - boolean retValue = false; - // - if (pi.getRecord_ID() != get_ID()) - { - log.log(Level.SEVERE, "startProcess - Not same Payment - " + pi.getRecord_ID()); - return false; - } - // Process it - retValue = processOnline(); - save(); - return retValue; // Payment processed - } // startProcess - - - /** - * Before Save - * @param newRecord new - * @return save - */ - protected boolean beforeSave (boolean newRecord) - { - // We have a charge - if (getC_Charge_ID() != 0) - { - if (newRecord || is_ValueChanged("C_Charge_ID")) - { - setC_Order_ID(0); - setC_Invoice_ID(0); - setWriteOffAmt(Env.ZERO); - setDiscountAmt(Env.ZERO); - setIsOverUnderPayment(false); - setOverUnderAmt(Env.ZERO); - setIsPrepayment(false); - } - } - // We need a BPartner - else if (getC_BPartner_ID() == 0 && !isCashTrx()) - { - if (getC_Invoice_ID() != 0) - ; - else if (getC_Order_ID() != 0) - ; - else - { - log.saveError("Error", Msg.parseTranslation(getCtx(), "@NotFound@: @C_BPartner_ID@")); - return false; - } - } - // Prepayment: No charge and order or project (not as acct dimension) - if (newRecord - || is_ValueChanged("C_Charge_ID") || is_ValueChanged("C_Invoice_ID") - || is_ValueChanged("C_Order_ID") || is_ValueChanged("C_Project_ID")) - setIsPrepayment (getC_Charge_ID() == 0 - && getC_BPartner_ID() != 0 - && (getC_Order_ID() != 0 - || (getC_Project_ID() != 0 && getC_Invoice_ID() == 0))); - if (isPrepayment()) - { - if (newRecord - || is_ValueChanged("C_Order_ID") || is_ValueChanged("C_Project_ID")) - { - setWriteOffAmt(Env.ZERO); - setDiscountAmt(Env.ZERO); - setIsOverUnderPayment(false); - setOverUnderAmt(Env.ZERO); - } - } - - // Document Type/Receipt - if (getC_DocType_ID() == 0) - setC_DocType_ID(); - else - { - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); - setIsReceipt(dt.isSOTrx()); - } - setDocumentNo(); - // - if (getDateAcct() == null) - setDateAcct(getDateTrx()); - // - if (!isOverUnderPayment()) - setOverUnderAmt(Env.ZERO); - - // Organization - if ((newRecord || is_ValueChanged("C_BankAccount_ID")) - && getC_Charge_ID() == 0) // allow different org for charge - { - MBankAccount ba = MBankAccount.get(getCtx(), getC_BankAccount_ID()); - if (ba.getAD_Org_ID() != 0) - setAD_Org_ID(ba.getAD_Org_ID()); - } - - return true; - } // beforeSave - - /** - * Get Allocated Amt in Payment Currency - * @return amount or null - */ - public BigDecimal getAllocatedAmt () - { - BigDecimal retValue = null; - if (getC_Charge_ID() != 0) - return getPayAmt(); - // - String sql = "SELECT SUM(currencyConvert(al.Amount," - + "ah.C_Currency_ID, p.C_Currency_ID,ah.DateTrx,p.C_ConversionType_ID, al.AD_Client_ID,al.AD_Org_ID)) " - + "FROM C_AllocationLine al" - + " INNER JOIN C_AllocationHdr ah ON (al.C_AllocationHdr_ID=ah.C_AllocationHdr_ID) " - + " INNER JOIN C_Payment p ON (al.C_Payment_ID=p.C_Payment_ID) " - + "WHERE al.C_Payment_ID=?" - + " AND ah.IsActive='Y' AND al.IsActive='Y'"; - // + " AND al.C_Invoice_ID IS NOT NULL"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, getC_Payment_ID()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - retValue = rs.getBigDecimal(1); - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, "getAllocatedAmt", e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - // log.fine("getAllocatedAmt - " + retValue); - // ? ROUND(NVL(v_AllocatedAmt,0), 2); - return retValue; - } // getAllocatedAmt - - /** - * Test Allocation (and set allocated flag) - * @return true if updated - */ - public boolean testAllocation() - { - // Cash Trx always allocated - if (isCashTrx()) - { - if (!isAllocated()) - { - setIsAllocated(true); - return true; - } - return false; - } - // - BigDecimal alloc = getAllocatedAmt(); - if (alloc == null) - alloc = Env.ZERO; - BigDecimal total = getPayAmt(); - if (!isReceipt()) - total = total.negate(); - boolean test = total.compareTo(alloc) == 0; - boolean change = test != isAllocated(); - if (change) - setIsAllocated(test); - log.fine("Allocated=" + test - + " (" + alloc + "=" + total + ")"); - return change; - } // testAllocation - - /** - * Set Allocated Flag for payments - * @param ctx context - * @param C_BPartner_ID if 0 all - * @param trxName trx - */ - public static void setIsAllocated (Properties ctx, int C_BPartner_ID, String trxName) - { - int counter = 0; - String sql = "SELECT * FROM C_Payment " - + "WHERE IsAllocated='N' AND DocStatus IN ('CO','CL')"; - if (C_BPartner_ID > 1) - sql += " AND C_BPartner_ID=?"; - else - sql += " AND AD_Client_ID=" + Env.getAD_Client_ID(ctx); - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, trxName); - if (C_BPartner_ID > 1) - pstmt.setInt (1, C_BPartner_ID); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - MPayment pay = new MPayment (ctx, rs, trxName); - if (pay.testAllocation()) - if (pay.save()) - counter++; - } - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - s_log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - s_log.config("#" + counter); - } // setIsAllocated - - /************************************************************************** - * Set Error Message - * @param errorMessage error message - */ - public void setErrorMessage(String errorMessage) - { - m_errorMessage = errorMessage; - } // setErrorMessage - - /** - * Get Error Message - * @return error message - */ - public String getErrorMessage() - { - return m_errorMessage; - } // getErrorMessage - - - /** - * Set Bank Account for Payment. - * @param C_BankAccount_ID C_BankAccount_ID - */ - public void setC_BankAccount_ID (int C_BankAccount_ID) - { - if (C_BankAccount_ID == 0) - { - setPaymentProcessor(); - if (getC_BankAccount_ID() == 0) - throw new IllegalArgumentException("Can't find Bank Account"); - } - else - super.setC_BankAccount_ID(C_BankAccount_ID); - } // setC_BankAccount_ID - - /** - * Set BankAccount and PaymentProcessor - * @return true if found - */ - public boolean setPaymentProcessor () - { - return setPaymentProcessor (getTenderType(), getCreditCardType()); - } // setPaymentProcessor - - /** - * Set BankAccount and PaymentProcessor - * @param tender TenderType see TENDER_ - * @param CCType CC Type see CC_ - * @return true if found - */ - public boolean setPaymentProcessor (String tender, String CCType) - { - m_mPaymentProcessor = null; - // Get Processor List - if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) - m_mPaymentProcessors = MPaymentProcessor.find (getCtx(), tender, CCType, getAD_Client_ID(), - getC_Currency_ID(), getPayAmt(), get_TrxName()); - // Relax Amount - if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) - m_mPaymentProcessors = MPaymentProcessor.find (getCtx(), tender, CCType, getAD_Client_ID(), - getC_Currency_ID(), Env.ZERO, get_TrxName()); - if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) - return false; - - // Find the first right one - for (int i = 0; i < m_mPaymentProcessors.length; i++) - { - if (m_mPaymentProcessors[i].accepts (tender, CCType)) - { - m_mPaymentProcessor = m_mPaymentProcessors[i]; - } - } - if (m_mPaymentProcessor != null) - setC_BankAccount_ID (m_mPaymentProcessor.getC_BankAccount_ID()); - // - return m_mPaymentProcessor != null; - } // setPaymentProcessor - - - /** - * Get Accepted Credit Cards for PayAmt (default 0) - * @return credit cards - */ - public ValueNamePair[] getCreditCards () - { - return getCreditCards(getPayAmt()); - } // getCreditCards - - - /** - * Get Accepted Credit Cards for amount - * @param amt trx amount - * @return credit cards - */ - public ValueNamePair[] getCreditCards (BigDecimal amt) - { - try - { - if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) - m_mPaymentProcessors = MPaymentProcessor.find (getCtx (), null, null, - getAD_Client_ID (), getC_Currency_ID (), amt, get_TrxName()); - // - HashMap map = new HashMap(); // to eliminate duplicates - for (int i = 0; i < m_mPaymentProcessors.length; i++) - { - if (m_mPaymentProcessors[i].isAcceptAMEX ()) - map.put (CREDITCARDTYPE_Amex, getCreditCardPair (CREDITCARDTYPE_Amex)); - if (m_mPaymentProcessors[i].isAcceptDiners ()) - map.put (CREDITCARDTYPE_Diners, getCreditCardPair (CREDITCARDTYPE_Diners)); - if (m_mPaymentProcessors[i].isAcceptDiscover ()) - map.put (CREDITCARDTYPE_Discover, getCreditCardPair (CREDITCARDTYPE_Discover)); - if (m_mPaymentProcessors[i].isAcceptMC ()) - map.put (CREDITCARDTYPE_MasterCard, getCreditCardPair (CREDITCARDTYPE_MasterCard)); - if (m_mPaymentProcessors[i].isAcceptCorporate ()) - map.put (CREDITCARDTYPE_PurchaseCard, getCreditCardPair (CREDITCARDTYPE_PurchaseCard)); - if (m_mPaymentProcessors[i].isAcceptVisa ()) - map.put (CREDITCARDTYPE_Visa, getCreditCardPair (CREDITCARDTYPE_Visa)); - } // for all payment processors - // - ValueNamePair[] retValue = new ValueNamePair[map.size ()]; - map.values ().toArray (retValue); - log.fine("getCreditCards - #" + retValue.length + " - Processors=" + m_mPaymentProcessors.length); - return retValue; - } - catch (Exception ex) - { - ex.printStackTrace(); - return null; - } - } // getCreditCards - - /** - * Get Type and name pair - * @param CreditCardType credit card Type - * @return pair - */ - private ValueNamePair getCreditCardPair (String CreditCardType) - { - return new ValueNamePair (CreditCardType, getCreditCardName(CreditCardType)); - } // getCreditCardPair - - - /************************************************************************** - * Credit Card Number - * @param CreditCardNumber CreditCard Number - */ - public void setCreditCardNumber (String CreditCardNumber) - { - super.setCreditCardNumber (MPaymentValidate.checkNumeric(CreditCardNumber)); - } // setCreditCardNumber - - /** - * Verification Code - * @param newCreditCardVV CC verification - */ - public void setCreditCardVV(String newCreditCardVV) - { - super.setCreditCardVV (MPaymentValidate.checkNumeric(newCreditCardVV)); - } // setCreditCardVV - - /** - * Two Digit CreditCard MM - * @param CreditCardExpMM Exp month - */ - public void setCreditCardExpMM (int CreditCardExpMM) - { - if (CreditCardExpMM < 1 || CreditCardExpMM > 12) - ; - else - super.setCreditCardExpMM (CreditCardExpMM); - } // setCreditCardExpMM - - /** - * Two digit CreditCard YY (til 2020) - * @param newCreditCardExpYY 2 or 4 digit year - */ - public void setCreditCardExpYY (int newCreditCardExpYY) - { - int CreditCardExpYY = newCreditCardExpYY; - if (newCreditCardExpYY > 1999) - CreditCardExpYY = newCreditCardExpYY-2000; - super.setCreditCardExpYY(CreditCardExpYY); - } // setCreditCardExpYY - - /** - * CreditCard Exp MMYY - * @param mmyy Exp in form of mmyy - * @return true if valid - */ - public boolean setCreditCardExp (String mmyy) - { - if (MPaymentValidate.validateCreditCardExp(mmyy).length() != 0) - return false; - // - String exp = MPaymentValidate.checkNumeric(mmyy); - String mmStr = exp.substring(0,2); - String yyStr = exp.substring(2,4); - setCreditCardExpMM (Integer.parseInt(mmStr)); - setCreditCardExpYY (Integer.parseInt(yyStr)); - return true; - } // setCreditCardExp - - - /** - * CreditCard Exp MMYY - * @param delimiter / - or null - * @return Exp - */ - public String getCreditCardExp(String delimiter) - { - String mm = String.valueOf(getCreditCardExpMM()); - String yy = String.valueOf(getCreditCardExpYY()); - - StringBuffer retValue = new StringBuffer(); - if (mm.length() == 1) - retValue.append("0"); - retValue.append(mm); - // - if (delimiter != null) - retValue.append(delimiter); - // - if (yy.length() == 1) - retValue.append("0"); - retValue.append(yy); - // - return (retValue.toString()); - } // getCreditCardExp - - /** - * MICR - * @param MICR MICR - */ - public void setMicr (String MICR) - { - super.setMicr (MPaymentValidate.checkNumeric(MICR)); - } // setBankMICR - - /** - * Routing No - * @param RoutingNo Routing No - */ - public void setRoutingNo(String RoutingNo) - { - super.setRoutingNo (MPaymentValidate.checkNumeric(RoutingNo)); - } // setBankRoutingNo - - - /** - * Bank Account No - * @param AccountNo AccountNo - */ - public void setAccountNo (String AccountNo) - { - super.setAccountNo (MPaymentValidate.checkNumeric(AccountNo)); - } // setBankAccountNo - - - /** - * Check No - * @param CheckNo Check No - */ - public void setCheckNo(String CheckNo) - { - super.setCheckNo(MPaymentValidate.checkNumeric(CheckNo)); - } // setBankCheckNo - - - /** - * Set DocumentNo to Payment info. - * If there is a R_PnRef that is set automatically - */ - private void setDocumentNo() - { - // Cash Transfer - if ("X".equals(getTenderType())) - return; - // Current Document No - String documentNo = getDocumentNo(); - // Existing reversal - if (documentNo != null - && documentNo.indexOf(REVERSE_INDICATOR) >= 0) - return; - - // If external number exists - enforce it - if (getR_PnRef() != null && getR_PnRef().length() > 0) - { - if (!getR_PnRef().equals(documentNo)) - setDocumentNo(getR_PnRef()); - return; - } - - documentNo = ""; - // Credit Card - if (TENDERTYPE_CreditCard.equals(getTenderType())) - { - documentNo = getCreditCardType() - + " " + Obscure.obscure(getCreditCardNumber()) - + " " + getCreditCardExpMM() - + "/" + getCreditCardExpYY(); - } - // Own Check No - else if (TENDERTYPE_Check.equals(getTenderType()) - && !isReceipt() - && getCheckNo() != null && getCheckNo().length() > 0) - { - documentNo = getCheckNo(); - } - // Customer Check: Routing: Account #Check - else if (TENDERTYPE_Check.equals(getTenderType()) - && isReceipt()) - { - if (getRoutingNo() != null) - documentNo = getRoutingNo() + ": "; - if (getAccountNo() != null) - documentNo += getAccountNo(); - if (getCheckNo() != null) - { - if (documentNo.length() > 0) - documentNo += " "; - documentNo += "#" + getCheckNo(); - } - } - - // Set Document No - documentNo = documentNo.trim(); - if (documentNo.length() > 0) - setDocumentNo(documentNo); - } // setDocumentNo - - /** - * Set Refernce No (and Document No) - * @param R_PnRef reference - */ - public void setR_PnRef (String R_PnRef) - { - super.setR_PnRef (R_PnRef); - if (R_PnRef != null) - setDocumentNo (R_PnRef); - } // setR_PnRef - - // --------------- - - /** - * Set Payment Amount - * @param PayAmt Pay Amt - */ - public void setPayAmt (BigDecimal PayAmt) - { - super.setPayAmt(PayAmt == null ? Env.ZERO : PayAmt); - } // setPayAmt - - /** - * Set Payment Amount - * - * @param C_Currency_ID currency - * @param payAmt amount - */ - public void setAmount (int C_Currency_ID, BigDecimal payAmt) - { - if (C_Currency_ID == 0) - C_Currency_ID = MClient.get(getCtx()).getC_Currency_ID(); - setC_Currency_ID(C_Currency_ID); - setPayAmt(payAmt); - } // setAmount - - /** - * Discount Amt - * @param DiscountAmt Discount - */ - public void setDiscountAmt (BigDecimal DiscountAmt) - { - super.setDiscountAmt (DiscountAmt == null ? Env.ZERO : DiscountAmt); - } // setDiscountAmt - - /** - * WriteOff Amt - * @param WriteOffAmt WriteOff - */ - public void setWriteOffAmt (BigDecimal WriteOffAmt) - { - super.setWriteOffAmt (WriteOffAmt == null ? Env.ZERO : WriteOffAmt); - } // setWriteOffAmt - - /** - * OverUnder Amt - * @param OverUnderAmt OverUnder - */ - public void setOverUnderAmt (BigDecimal OverUnderAmt) - { - super.setOverUnderAmt (OverUnderAmt == null ? Env.ZERO : OverUnderAmt); - setIsOverUnderPayment(getOverUnderAmt().compareTo(Env.ZERO) != 0); - } // setOverUnderAmt - - /** - * Tax Amt - * @param TaxAmt Tax - */ - public void setTaxAmt (BigDecimal TaxAmt) - { - super.setTaxAmt (TaxAmt == null ? Env.ZERO : TaxAmt); - } // setTaxAmt - - /** - * Set Info from BP Bank Account - * @param ba BP bank account - */ - public void setBP_BankAccount (MBPBankAccount ba) - { - log.fine("" + ba); - if (ba == null) - return; - setC_BPartner_ID(ba.getC_BPartner_ID()); - setAccountAddress(ba.getA_Name(), ba.getA_Street(), ba.getA_City(), - ba.getA_State(), ba.getA_Zip(), ba.getA_Country()); - setA_EMail(ba.getA_EMail()); - setA_Ident_DL(ba.getA_Ident_DL()); - setA_Ident_SSN(ba.getA_Ident_SSN()); - // CC - if (ba.getCreditCardType() != null) - setCreditCardType(ba.getCreditCardType()); - if (ba.getCreditCardNumber() != null) - setCreditCardNumber(ba.getCreditCardNumber()); - if (ba.getCreditCardExpMM() != 0) - setCreditCardExpMM(ba.getCreditCardExpMM()); - if (ba.getCreditCardExpYY() != 0) - setCreditCardExpYY(ba.getCreditCardExpYY()); - if (ba.getCreditCardVV() != null) - setCreditCardVV(ba.getCreditCardVV()); - // Bank - if (ba.getAccountNo() != null) - setAccountNo(ba.getAccountNo()); - if (ba.getRoutingNo() != null) - setRoutingNo(ba.getRoutingNo()); - } // setBP_BankAccount - - /** - * Save Info from BP Bank Account - * @param ba BP bank account - * @return true if saved - */ - public boolean saveToBP_BankAccount (MBPBankAccount ba) - { - if (ba == null) - return false; - ba.setA_Name(getA_Name()); - ba.setA_Street(getA_Street()); - ba.setA_City(getA_City()); - ba.setA_State(getA_State()); - ba.setA_Zip(getA_Zip()); - ba.setA_Country(getA_Country()); - ba.setA_EMail(getA_EMail()); - ba.setA_Ident_DL(getA_Ident_DL()); - ba.setA_Ident_SSN(getA_Ident_SSN()); - // CC - ba.setCreditCardType(getCreditCardType()); - ba.setCreditCardNumber(getCreditCardNumber()); - ba.setCreditCardExpMM(getCreditCardExpMM()); - ba.setCreditCardExpYY(getCreditCardExpYY()); - ba.setCreditCardVV(getCreditCardVV()); - // Bank - if (getAccountNo() != null) - ba.setAccountNo(getAccountNo()); - if (getRoutingNo() != null) - ba.setRoutingNo(getRoutingNo()); - // Trx - ba.setR_AvsAddr(getR_AvsAddr()); - ba.setR_AvsZip(getR_AvsZip()); - // - boolean ok = ba.save(get_TrxName()); - log.fine("saveToBP_BankAccount - " + ba); - return ok; - } // setBP_BankAccount - - /** - * Set Doc Type bases on IsReceipt - */ - private void setC_DocType_ID () - { - setC_DocType_ID(isReceipt()); - } // setC_DocType_ID - - /** - * Set Doc Type - * @param isReceipt is receipt - */ - public void setC_DocType_ID (boolean isReceipt) - { - setIsReceipt(isReceipt); - String sql = "SELECT C_DocType_ID FROM C_DocType WHERE AD_Client_ID=? AND DocBaseType=? ORDER BY IsDefault DESC"; - try - { + return check == 0; + } // setBankACH + + /** + * Set ACH BankAccount Info + * + * @param C_BankAccount_ID bank account + * @param isReceipt true if receipt + * @param tenderType - Direct Debit or Direct Deposit + * @param routingNo routing + * @param accountNo account + * @return true if valid + */ + public boolean setBankACH (int C_BankAccount_ID, boolean isReceipt, String tenderType, + String routingNo, String accountNo) + { + setTenderType (tenderType); + setIsReceipt (isReceipt); + // + if (C_BankAccount_ID > 0 + && (routingNo == null || routingNo.length() == 0 || accountNo == null || accountNo.length() == 0)) + setBankAccountDetails(C_BankAccount_ID); + else + { + setC_BankAccount_ID(C_BankAccount_ID); + setRoutingNo (routingNo); + setAccountNo (accountNo); + } + setCheckNo (""); + // + int check = MPaymentValidate.validateRoutingNo(routingNo).length() + + MPaymentValidate.validateAccountNo(accountNo).length(); + return check == 0; + } // setBankACH + + /** + * Set Check BankAccount Info + * + * @param C_BankAccount_ID bank account + * @param isReceipt true if receipt + * @param checkNo chack no + * @return true if valid + */ + public boolean setBankCheck (int C_BankAccount_ID, boolean isReceipt, String checkNo) + { + return setBankCheck (C_BankAccount_ID, isReceipt, null, null, checkNo); + } // setBankCheck + + /** + * Set Check BankAccount Info + * + * @param C_BankAccount_ID bank account + * @param isReceipt true if receipt + * @param routingNo routing no + * @param accountNo account no + * @param checkNo chack no + * @return true if valid + */ + public boolean setBankCheck (int C_BankAccount_ID, boolean isReceipt, + String routingNo, String accountNo, String checkNo) + { + setTenderType (TENDERTYPE_Check); + setIsReceipt (isReceipt); + // + if (C_BankAccount_ID > 0 + && (routingNo == null || routingNo.length() == 0 + || accountNo == null || accountNo.length() == 0)) + setBankAccountDetails(C_BankAccount_ID); + else + { + setC_BankAccount_ID(C_BankAccount_ID); + setRoutingNo (routingNo); + setAccountNo (accountNo); + } + setCheckNo (checkNo); + // + int check = MPaymentValidate.validateRoutingNo(routingNo).length() + + MPaymentValidate.validateAccountNo(accountNo).length() + + MPaymentValidate.validateCheckNo(checkNo).length(); + return check == 0; // no error message + } // setBankCheck + + /** + * Set Bank Account Details. + * Look up Routing No & Bank Acct No + * @param C_BankAccount_ID bank account + */ + public void setBankAccountDetails (int C_BankAccount_ID) + { + if (C_BankAccount_ID == 0) + return; + setC_BankAccount_ID(C_BankAccount_ID); + // + String sql = "SELECT b.RoutingNo, ba.AccountNo " + + "FROM C_BankAccount ba" + + " INNER JOIN C_Bank b ON (ba.C_Bank_ID=b.C_Bank_ID) " + + "WHERE C_BankAccount_ID=?"; + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, C_BankAccount_ID); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + { + setRoutingNo (rs.getString(1)); + setAccountNo (rs.getString(2)); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + } + } // setBankAccountDetails + + /** + * Set Account Address + * + * @param name name + * @param street street + * @param city city + * @param state state + * @param zip zip + * @param country country + */ + public void setAccountAddress (String name, String street, + String city, String state, String zip, String country) + { + setA_Name (name); + setA_Street (street); + setA_City (city); + setA_State (state); + setA_Zip (zip); + setA_Country(country); + } // setAccountAddress + + + /************************************************************************** + * Process Payment + * @return true if approved + */ + public boolean processOnline() + { + log.info ("Amt=" + getPayAmt()); + // + setIsOnline(true); + setErrorMessage(null); + // prevent charging twice + if (isApproved()) + { + log.info("Already processed - " + getR_Result() + " - " + getR_RespMsg()); + setErrorMessage("Payment already Processed"); + return true; + } + + if (m_mPaymentProcessor == null) + setPaymentProcessor(); + if (m_mPaymentProcessor == null) + { + log.log(Level.WARNING, "No Payment Processor Model"); + setErrorMessage("No Payment Processor Model"); + return false; + } + + boolean approved = false; + /** Process Payment on Server */ + if (DB.isRemoteObjects()) + { + Server server = CConnection.get().getServer(); + try + { + if (server != null) + { // See ServerBean + String trxName = null; // unconditionally save + save(trxName); // server reads from disk + approved = server.paymentOnline (getCtx(), getC_Payment_ID(), + m_mPaymentProcessor.getC_PaymentProcessor_ID(), trxName); + if (CLogMgt.isLevelFinest()) + s_log.fine("server => " + approved); + load(trxName); // server saves to disk + setIsApproved(approved); + return approved; + } + log.log(Level.WARNING, "AppsServer not found"); + } + catch (RemoteException ex) + { + log.log(Level.SEVERE, "AppsServer error", ex); + } + } + /** **/ + + // Try locally + try + { + PaymentProcessor pp = PaymentProcessor.create(m_mPaymentProcessor, this); + if (pp == null) + setErrorMessage("No Payment Processor"); + else + { + approved = pp.processCC (); + if (approved) + setErrorMessage(null); + else + setErrorMessage("From " + getCreditCardName() + ": " + getR_RespMsg()); + } + } + catch (Exception e) + { + log.log(Level.SEVERE, "processOnline", e); + setErrorMessage("Payment Processor Error"); + } + setIsApproved(approved); + return approved; + } // processOnline + + /** + * Process Online Payment. + * implements ProcessCall after standard constructor + * Called when pressing the Process_Online button in C_Payment + * + * @param ctx Context + * @param pi Process Info + * @param trx transaction + * @return true if the next process should be performed + */ + public boolean startProcess (Properties ctx, ProcessInfo pi, Trx trx) + { + log.info("startProcess - " + pi.getRecord_ID()); + boolean retValue = false; + // + if (pi.getRecord_ID() != get_ID()) + { + log.log(Level.SEVERE, "startProcess - Not same Payment - " + pi.getRecord_ID()); + return false; + } + // Process it + retValue = processOnline(); + save(); + return retValue; // Payment processed + } // startProcess + + + /** + * Before Save + * @param newRecord new + * @return save + */ + protected boolean beforeSave (boolean newRecord) + { + // We have a charge + if (getC_Charge_ID() != 0) + { + if (newRecord || is_ValueChanged("C_Charge_ID")) + { + setC_Order_ID(0); + setC_Invoice_ID(0); + setWriteOffAmt(Env.ZERO); + setDiscountAmt(Env.ZERO); + setIsOverUnderPayment(false); + setOverUnderAmt(Env.ZERO); + setIsPrepayment(false); + } + } + // We need a BPartner + else if (getC_BPartner_ID() == 0 && !isCashTrx()) + { + if (getC_Invoice_ID() != 0) + ; + else if (getC_Order_ID() != 0) + ; + else + { + log.saveError("Error", Msg.parseTranslation(getCtx(), "@NotFound@: @C_BPartner_ID@")); + return false; + } + } + // Prepayment: No charge and order or project (not as acct dimension) + if (newRecord + || is_ValueChanged("C_Charge_ID") || is_ValueChanged("C_Invoice_ID") + || is_ValueChanged("C_Order_ID") || is_ValueChanged("C_Project_ID")) + setIsPrepayment (getC_Charge_ID() == 0 + && getC_BPartner_ID() != 0 + && (getC_Order_ID() != 0 + || (getC_Project_ID() != 0 && getC_Invoice_ID() == 0))); + if (isPrepayment()) + { + if (newRecord + || is_ValueChanged("C_Order_ID") || is_ValueChanged("C_Project_ID")) + { + setWriteOffAmt(Env.ZERO); + setDiscountAmt(Env.ZERO); + setIsOverUnderPayment(false); + setOverUnderAmt(Env.ZERO); + } + } + + // Document Type/Receipt + if (getC_DocType_ID() == 0) + setC_DocType_ID(); + else + { + MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + setIsReceipt(dt.isSOTrx()); + } + setDocumentNo(); + // + if (getDateAcct() == null) + setDateAcct(getDateTrx()); + // + if (!isOverUnderPayment()) + setOverUnderAmt(Env.ZERO); + + // Organization + if ((newRecord || is_ValueChanged("C_BankAccount_ID")) + && getC_Charge_ID() == 0) // allow different org for charge + { + MBankAccount ba = MBankAccount.get(getCtx(), getC_BankAccount_ID()); + if (ba.getAD_Org_ID() != 0) + setAD_Org_ID(ba.getAD_Org_ID()); + } + + return true; + } // beforeSave + + /** + * Get Allocated Amt in Payment Currency + * @return amount or null + */ + public BigDecimal getAllocatedAmt () + { + BigDecimal retValue = null; + if (getC_Charge_ID() != 0) + return getPayAmt(); + // + String sql = "SELECT SUM(currencyConvert(al.Amount," + + "ah.C_Currency_ID, p.C_Currency_ID,ah.DateTrx,p.C_ConversionType_ID, al.AD_Client_ID,al.AD_Org_ID)) " + + "FROM C_AllocationLine al" + + " INNER JOIN C_AllocationHdr ah ON (al.C_AllocationHdr_ID=ah.C_AllocationHdr_ID) " + + " INNER JOIN C_Payment p ON (al.C_Payment_ID=p.C_Payment_ID) " + + "WHERE al.C_Payment_ID=?" + + " AND ah.IsActive='Y' AND al.IsActive='Y'"; + // + " AND al.C_Invoice_ID IS NOT NULL"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, getC_Payment_ID()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + retValue = rs.getBigDecimal(1); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, "getAllocatedAmt", e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // log.fine("getAllocatedAmt - " + retValue); + // ? ROUND(NVL(v_AllocatedAmt,0), 2); + return retValue; + } // getAllocatedAmt + + /** + * Test Allocation (and set allocated flag) + * @return true if updated + */ + public boolean testAllocation() + { + // Cash Trx always allocated + if (isCashTrx()) + { + if (!isAllocated()) + { + setIsAllocated(true); + return true; + } + return false; + } + // + BigDecimal alloc = getAllocatedAmt(); + if (alloc == null) + alloc = Env.ZERO; + BigDecimal total = getPayAmt(); + if (!isReceipt()) + total = total.negate(); + boolean test = total.compareTo(alloc) == 0; + boolean change = test != isAllocated(); + if (change) + setIsAllocated(test); + log.fine("Allocated=" + test + + " (" + alloc + "=" + total + ")"); + return change; + } // testAllocation + + /** + * Set Allocated Flag for payments + * @param ctx context + * @param C_BPartner_ID if 0 all + * @param trxName trx + */ + public static void setIsAllocated (Properties ctx, int C_BPartner_ID, String trxName) + { + int counter = 0; + String sql = "SELECT * FROM C_Payment " + + "WHERE IsAllocated='N' AND DocStatus IN ('CO','CL')"; + if (C_BPartner_ID > 1) + sql += " AND C_BPartner_ID=?"; + else + sql += " AND AD_Client_ID=" + Env.getAD_Client_ID(ctx); + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, trxName); + if (C_BPartner_ID > 1) + pstmt.setInt (1, C_BPartner_ID); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + MPayment pay = new MPayment (ctx, rs, trxName); + if (pay.testAllocation()) + if (pay.save()) + counter++; + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + s_log.config("#" + counter); + } // setIsAllocated + + /************************************************************************** + * Set Error Message + * @param errorMessage error message + */ + public void setErrorMessage(String errorMessage) + { + m_errorMessage = errorMessage; + } // setErrorMessage + + /** + * Get Error Message + * @return error message + */ + public String getErrorMessage() + { + return m_errorMessage; + } // getErrorMessage + + + /** + * Set Bank Account for Payment. + * @param C_BankAccount_ID C_BankAccount_ID + */ + public void setC_BankAccount_ID (int C_BankAccount_ID) + { + if (C_BankAccount_ID == 0) + { + setPaymentProcessor(); + if (getC_BankAccount_ID() == 0) + throw new IllegalArgumentException("Can't find Bank Account"); + } + else + super.setC_BankAccount_ID(C_BankAccount_ID); + } // setC_BankAccount_ID + + /** + * Set BankAccount and PaymentProcessor + * @return true if found + */ + public boolean setPaymentProcessor () + { + return setPaymentProcessor (getTenderType(), getCreditCardType()); + } // setPaymentProcessor + + /** + * Set BankAccount and PaymentProcessor + * @param tender TenderType see TENDER_ + * @param CCType CC Type see CC_ + * @return true if found + */ + public boolean setPaymentProcessor (String tender, String CCType) + { + m_mPaymentProcessor = null; + // Get Processor List + if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) + m_mPaymentProcessors = MPaymentProcessor.find (getCtx(), tender, CCType, getAD_Client_ID(), + getC_Currency_ID(), getPayAmt(), get_TrxName()); + // Relax Amount + if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) + m_mPaymentProcessors = MPaymentProcessor.find (getCtx(), tender, CCType, getAD_Client_ID(), + getC_Currency_ID(), Env.ZERO, get_TrxName()); + if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) + return false; + + // Find the first right one + for (int i = 0; i < m_mPaymentProcessors.length; i++) + { + if (m_mPaymentProcessors[i].accepts (tender, CCType)) + { + m_mPaymentProcessor = m_mPaymentProcessors[i]; + } + } + if (m_mPaymentProcessor != null) + setC_BankAccount_ID (m_mPaymentProcessor.getC_BankAccount_ID()); + // + return m_mPaymentProcessor != null; + } // setPaymentProcessor + + + /** + * Get Accepted Credit Cards for PayAmt (default 0) + * @return credit cards + */ + public ValueNamePair[] getCreditCards () + { + return getCreditCards(getPayAmt()); + } // getCreditCards + + + /** + * Get Accepted Credit Cards for amount + * @param amt trx amount + * @return credit cards + */ + public ValueNamePair[] getCreditCards (BigDecimal amt) + { + try + { + if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) + m_mPaymentProcessors = MPaymentProcessor.find (getCtx (), null, null, + getAD_Client_ID (), getC_Currency_ID (), amt, get_TrxName()); + // + HashMap map = new HashMap(); // to eliminate duplicates + for (int i = 0; i < m_mPaymentProcessors.length; i++) + { + if (m_mPaymentProcessors[i].isAcceptAMEX ()) + map.put (CREDITCARDTYPE_Amex, getCreditCardPair (CREDITCARDTYPE_Amex)); + if (m_mPaymentProcessors[i].isAcceptDiners ()) + map.put (CREDITCARDTYPE_Diners, getCreditCardPair (CREDITCARDTYPE_Diners)); + if (m_mPaymentProcessors[i].isAcceptDiscover ()) + map.put (CREDITCARDTYPE_Discover, getCreditCardPair (CREDITCARDTYPE_Discover)); + if (m_mPaymentProcessors[i].isAcceptMC ()) + map.put (CREDITCARDTYPE_MasterCard, getCreditCardPair (CREDITCARDTYPE_MasterCard)); + if (m_mPaymentProcessors[i].isAcceptCorporate ()) + map.put (CREDITCARDTYPE_PurchaseCard, getCreditCardPair (CREDITCARDTYPE_PurchaseCard)); + if (m_mPaymentProcessors[i].isAcceptVisa ()) + map.put (CREDITCARDTYPE_Visa, getCreditCardPair (CREDITCARDTYPE_Visa)); + } // for all payment processors + // + ValueNamePair[] retValue = new ValueNamePair[map.size ()]; + map.values ().toArray (retValue); + log.fine("getCreditCards - #" + retValue.length + " - Processors=" + m_mPaymentProcessors.length); + return retValue; + } + catch (Exception ex) + { + ex.printStackTrace(); + return null; + } + } // getCreditCards + + /** + * Get Type and name pair + * @param CreditCardType credit card Type + * @return pair + */ + private ValueNamePair getCreditCardPair (String CreditCardType) + { + return new ValueNamePair (CreditCardType, getCreditCardName(CreditCardType)); + } // getCreditCardPair + + + /************************************************************************** + * Credit Card Number + * @param CreditCardNumber CreditCard Number + */ + public void setCreditCardNumber (String CreditCardNumber) + { + super.setCreditCardNumber (MPaymentValidate.checkNumeric(CreditCardNumber)); + } // setCreditCardNumber + + /** + * Verification Code + * @param newCreditCardVV CC verification + */ + public void setCreditCardVV(String newCreditCardVV) + { + super.setCreditCardVV (MPaymentValidate.checkNumeric(newCreditCardVV)); + } // setCreditCardVV + + /** + * Two Digit CreditCard MM + * @param CreditCardExpMM Exp month + */ + public void setCreditCardExpMM (int CreditCardExpMM) + { + if (CreditCardExpMM < 1 || CreditCardExpMM > 12) + ; + else + super.setCreditCardExpMM (CreditCardExpMM); + } // setCreditCardExpMM + + /** + * Two digit CreditCard YY (til 2020) + * @param newCreditCardExpYY 2 or 4 digit year + */ + public void setCreditCardExpYY (int newCreditCardExpYY) + { + int CreditCardExpYY = newCreditCardExpYY; + if (newCreditCardExpYY > 1999) + CreditCardExpYY = newCreditCardExpYY-2000; + super.setCreditCardExpYY(CreditCardExpYY); + } // setCreditCardExpYY + + /** + * CreditCard Exp MMYY + * @param mmyy Exp in form of mmyy + * @return true if valid + */ + public boolean setCreditCardExp (String mmyy) + { + if (MPaymentValidate.validateCreditCardExp(mmyy).length() != 0) + return false; + // + String exp = MPaymentValidate.checkNumeric(mmyy); + String mmStr = exp.substring(0,2); + String yyStr = exp.substring(2,4); + setCreditCardExpMM (Integer.parseInt(mmStr)); + setCreditCardExpYY (Integer.parseInt(yyStr)); + return true; + } // setCreditCardExp + + + /** + * CreditCard Exp MMYY + * @param delimiter / - or null + * @return Exp + */ + public String getCreditCardExp(String delimiter) + { + String mm = String.valueOf(getCreditCardExpMM()); + String yy = String.valueOf(getCreditCardExpYY()); + + StringBuffer retValue = new StringBuffer(); + if (mm.length() == 1) + retValue.append("0"); + retValue.append(mm); + // + if (delimiter != null) + retValue.append(delimiter); + // + if (yy.length() == 1) + retValue.append("0"); + retValue.append(yy); + // + return (retValue.toString()); + } // getCreditCardExp + + /** + * MICR + * @param MICR MICR + */ + public void setMicr (String MICR) + { + super.setMicr (MPaymentValidate.checkNumeric(MICR)); + } // setBankMICR + + /** + * Routing No + * @param RoutingNo Routing No + */ + public void setRoutingNo(String RoutingNo) + { + super.setRoutingNo (MPaymentValidate.checkNumeric(RoutingNo)); + } // setBankRoutingNo + + + /** + * Bank Account No + * @param AccountNo AccountNo + */ + public void setAccountNo (String AccountNo) + { + super.setAccountNo (MPaymentValidate.checkNumeric(AccountNo)); + } // setBankAccountNo + + + /** + * Check No + * @param CheckNo Check No + */ + public void setCheckNo(String CheckNo) + { + super.setCheckNo(MPaymentValidate.checkNumeric(CheckNo)); + } // setBankCheckNo + + + /** + * Set DocumentNo to Payment info. + * If there is a R_PnRef that is set automatically + */ + private void setDocumentNo() + { + // Cash Transfer + if ("X".equals(getTenderType())) + return; + // Current Document No + String documentNo = getDocumentNo(); + // Existing reversal + if (documentNo != null + && documentNo.indexOf(REVERSE_INDICATOR) >= 0) + return; + + // If external number exists - enforce it + if (getR_PnRef() != null && getR_PnRef().length() > 0) + { + if (!getR_PnRef().equals(documentNo)) + setDocumentNo(getR_PnRef()); + return; + } + + documentNo = ""; + // Credit Card + if (TENDERTYPE_CreditCard.equals(getTenderType())) + { + documentNo = getCreditCardType() + + " " + Obscure.obscure(getCreditCardNumber()) + + " " + getCreditCardExpMM() + + "/" + getCreditCardExpYY(); + } + // Own Check No + else if (TENDERTYPE_Check.equals(getTenderType()) + && !isReceipt() + && getCheckNo() != null && getCheckNo().length() > 0) + { + documentNo = getCheckNo(); + } + // Customer Check: Routing: Account #Check + else if (TENDERTYPE_Check.equals(getTenderType()) + && isReceipt()) + { + if (getRoutingNo() != null) + documentNo = getRoutingNo() + ": "; + if (getAccountNo() != null) + documentNo += getAccountNo(); + if (getCheckNo() != null) + { + if (documentNo.length() > 0) + documentNo += " "; + documentNo += "#" + getCheckNo(); + } + } + + // Set Document No + documentNo = documentNo.trim(); + if (documentNo.length() > 0) + setDocumentNo(documentNo); + } // setDocumentNo + + /** + * Set Refernce No (and Document No) + * @param R_PnRef reference + */ + public void setR_PnRef (String R_PnRef) + { + super.setR_PnRef (R_PnRef); + if (R_PnRef != null) + setDocumentNo (R_PnRef); + } // setR_PnRef + + // --------------- + + /** + * Set Payment Amount + * @param PayAmt Pay Amt + */ + public void setPayAmt (BigDecimal PayAmt) + { + super.setPayAmt(PayAmt == null ? Env.ZERO : PayAmt); + } // setPayAmt + + /** + * Set Payment Amount + * + * @param C_Currency_ID currency + * @param payAmt amount + */ + public void setAmount (int C_Currency_ID, BigDecimal payAmt) + { + if (C_Currency_ID == 0) + C_Currency_ID = MClient.get(getCtx()).getC_Currency_ID(); + setC_Currency_ID(C_Currency_ID); + setPayAmt(payAmt); + } // setAmount + + /** + * Discount Amt + * @param DiscountAmt Discount + */ + public void setDiscountAmt (BigDecimal DiscountAmt) + { + super.setDiscountAmt (DiscountAmt == null ? Env.ZERO : DiscountAmt); + } // setDiscountAmt + + /** + * WriteOff Amt + * @param WriteOffAmt WriteOff + */ + public void setWriteOffAmt (BigDecimal WriteOffAmt) + { + super.setWriteOffAmt (WriteOffAmt == null ? Env.ZERO : WriteOffAmt); + } // setWriteOffAmt + + /** + * OverUnder Amt + * @param OverUnderAmt OverUnder + */ + public void setOverUnderAmt (BigDecimal OverUnderAmt) + { + super.setOverUnderAmt (OverUnderAmt == null ? Env.ZERO : OverUnderAmt); + setIsOverUnderPayment(getOverUnderAmt().compareTo(Env.ZERO) != 0); + } // setOverUnderAmt + + /** + * Tax Amt + * @param TaxAmt Tax + */ + public void setTaxAmt (BigDecimal TaxAmt) + { + super.setTaxAmt (TaxAmt == null ? Env.ZERO : TaxAmt); + } // setTaxAmt + + /** + * Set Info from BP Bank Account + * @param ba BP bank account + */ + public void setBP_BankAccount (MBPBankAccount ba) + { + log.fine("" + ba); + if (ba == null) + return; + setC_BPartner_ID(ba.getC_BPartner_ID()); + setAccountAddress(ba.getA_Name(), ba.getA_Street(), ba.getA_City(), + ba.getA_State(), ba.getA_Zip(), ba.getA_Country()); + setA_EMail(ba.getA_EMail()); + setA_Ident_DL(ba.getA_Ident_DL()); + setA_Ident_SSN(ba.getA_Ident_SSN()); + // CC + if (ba.getCreditCardType() != null) + setCreditCardType(ba.getCreditCardType()); + if (ba.getCreditCardNumber() != null) + setCreditCardNumber(ba.getCreditCardNumber()); + if (ba.getCreditCardExpMM() != 0) + setCreditCardExpMM(ba.getCreditCardExpMM()); + if (ba.getCreditCardExpYY() != 0) + setCreditCardExpYY(ba.getCreditCardExpYY()); + if (ba.getCreditCardVV() != null) + setCreditCardVV(ba.getCreditCardVV()); + // Bank + if (ba.getAccountNo() != null) + setAccountNo(ba.getAccountNo()); + if (ba.getRoutingNo() != null) + setRoutingNo(ba.getRoutingNo()); + } // setBP_BankAccount + + /** + * Save Info from BP Bank Account + * @param ba BP bank account + * @return true if saved + */ + public boolean saveToBP_BankAccount (MBPBankAccount ba) + { + if (ba == null) + return false; + ba.setA_Name(getA_Name()); + ba.setA_Street(getA_Street()); + ba.setA_City(getA_City()); + ba.setA_State(getA_State()); + ba.setA_Zip(getA_Zip()); + ba.setA_Country(getA_Country()); + ba.setA_EMail(getA_EMail()); + ba.setA_Ident_DL(getA_Ident_DL()); + ba.setA_Ident_SSN(getA_Ident_SSN()); + // CC + ba.setCreditCardType(getCreditCardType()); + ba.setCreditCardNumber(getCreditCardNumber()); + ba.setCreditCardExpMM(getCreditCardExpMM()); + ba.setCreditCardExpYY(getCreditCardExpYY()); + ba.setCreditCardVV(getCreditCardVV()); + // Bank + if (getAccountNo() != null) + ba.setAccountNo(getAccountNo()); + if (getRoutingNo() != null) + ba.setRoutingNo(getRoutingNo()); + // Trx + ba.setR_AvsAddr(getR_AvsAddr()); + ba.setR_AvsZip(getR_AvsZip()); + // + boolean ok = ba.save(get_TrxName()); + log.fine("saveToBP_BankAccount - " + ba); + return ok; + } // setBP_BankAccount + + /** + * Set Doc Type bases on IsReceipt + */ + private void setC_DocType_ID () + { + setC_DocType_ID(isReceipt()); + } // setC_DocType_ID + + /** + * Set Doc Type + * @param isReceipt is receipt + */ + public void setC_DocType_ID (boolean isReceipt) + { + setIsReceipt(isReceipt); + String sql = "SELECT C_DocType_ID FROM C_DocType WHERE AD_Client_ID=? AND DocBaseType=? ORDER BY IsDefault DESC"; + try + { PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName()); pstmt.setInt(1, getAD_Client_ID()); if (isReceipt) - pstmt.setString(2, MDocType.DOCBASETYPE_ARReceipt); + pstmt.setString(2, X_C_DocType.DOCBASETYPE_ARReceipt); else - pstmt.setString(2, MDocType.DOCBASETYPE_APPayment); + pstmt.setString(2, X_C_DocType.DOCBASETYPE_APPayment); ResultSet rs = pstmt.executeQuery(); if (rs.next()) setC_DocType_ID(rs.getInt(1)); - else - log.warning ("setDocType - NOT found - isReceipt=" + isReceipt); - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - } - } // setC_DocType_ID - - - /** - * Set Document Type - * @param C_DocType_ID doc type - */ - public void setC_DocType_ID (int C_DocType_ID) - { - // if (getDocumentNo() != null && getC_DocType_ID() != C_DocType_ID) - // setDocumentNo(null); - super.setC_DocType_ID(C_DocType_ID); - } // setC_DocType_ID - - /** - * Verify Document Type with Invoice - * @return true if ok - */ - private boolean verifyDocType() - { - if (getC_DocType_ID() == 0) - return false; - // - Boolean invoiceSO = null; - // Check Invoice First - if (getC_Invoice_ID() > 0) - { - String sql = "SELECT idt.IsSOTrx " - + "FROM C_Invoice i" - + " INNER JOIN C_DocType idt ON (i.C_DocType_ID=idt.C_DocType_ID) " - + "WHERE i.C_Invoice_ID=?"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, getC_Invoice_ID()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - invoiceSO = new Boolean ("Y".equals(rs.getString(1))); - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - } // Invoice - - // DocumentType - Boolean paymentSO = null; - PreparedStatement pstmt = null; - String sql = "SELECT IsSOTrx " - + "FROM C_DocType " - + "WHERE C_DocType_ID=?"; - try - { - pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, getC_DocType_ID()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - paymentSO = new Boolean ("Y".equals(rs.getString(1))); - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - // No Payment info - if (paymentSO == null) - return false; - setIsReceipt(paymentSO.booleanValue()); - - // We have an Invoice .. and it does not match - if (invoiceSO != null - && invoiceSO.booleanValue() != paymentSO.booleanValue()) - return false; - // OK - return true; - } // verifyDocType - - - /** - * Get ISO Code of Currency - * @return Currency ISO - */ - public String getCurrencyISO() - { - return MCurrency.getISO_Code (getCtx(), getC_Currency_ID()); - } // getCurrencyISO - - /** - * Get Document Status - * @return Document Status Clear Text - */ - public String getDocStatusName() - { - return MRefList.getListName(getCtx(), 131, getDocStatus()); - } // getDocStatusName - - /** - * Get Name of Credit Card - * @return Name - */ - public String getCreditCardName() - { - return getCreditCardName(getCreditCardType()); - } // getCreditCardName - - /** - * Get Name of Credit Card - * @param CreditCardType credit card type - * @return Name - */ - public String getCreditCardName(String CreditCardType) - { - if (CreditCardType == null) - return "--"; - else if (CREDITCARDTYPE_MasterCard.equals(CreditCardType)) - return "MasterCard"; - else if (CREDITCARDTYPE_Visa.equals(CreditCardType)) - return "Visa"; - else if (CREDITCARDTYPE_Amex.equals(CreditCardType)) - return "Amex"; - else if (CREDITCARDTYPE_ATM.equals(CreditCardType)) - return "ATM"; - else if (CREDITCARDTYPE_Diners.equals(CreditCardType)) - return "Diners"; - else if (CREDITCARDTYPE_Discover.equals(CreditCardType)) - return "Discover"; - else if (CREDITCARDTYPE_PurchaseCard.equals(CreditCardType)) - return "PurchaseCard"; - return "?" + CreditCardType + "?"; - } // getCreditCardName - - /** - * Add to Description - * @param description text - */ - public void addDescription (String description) - { - String desc = getDescription(); - if (desc == null) - setDescription(description); - else - setDescription(desc + " | " + description); - } // addDescription - - - /** - * Get Pay Amt - * @param absolute if true the absolute amount (i.e. negative if payment) - * @return amount - */ - public BigDecimal getPayAmt (boolean absolute) - { - if (isReceipt()) - return super.getPayAmt(); - return super.getPayAmt().negate(); - } // getPayAmt - - /** - * Get Pay Amt in cents - * @return amount in cents - */ - public int getPayAmtInCents () - { - BigDecimal bd = super.getPayAmt().multiply(Env.ONEHUNDRED); - return bd.intValue(); - } // getPayAmtInCents - - /************************************************************************** - * Process document - * @param processAction document action - * @return true if performed - */ - public boolean processIt (String processAction) - { - m_processMsg = null; - DocumentEngine engine = new DocumentEngine (this, getDocStatus()); - return engine.processIt (processAction, getDocAction()); - } // process - - /** Process Message */ - private String m_processMsg = null; - /** Just Prepared Flag */ - private boolean m_justPrepared = false; - - /** - * Unlock Document. - * @return true if success + else + log.warning ("setDocType - NOT found - isReceipt=" + isReceipt); + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + } + } // setC_DocType_ID + + + /** + * Set Document Type + * @param C_DocType_ID doc type + */ + public void setC_DocType_ID (int C_DocType_ID) + { + // if (getDocumentNo() != null && getC_DocType_ID() != C_DocType_ID) + // setDocumentNo(null); + super.setC_DocType_ID(C_DocType_ID); + } // setC_DocType_ID + + /** + * Verify Document Type with Invoice + * @return true if ok + */ + private boolean verifyDocType() + { + if (getC_DocType_ID() == 0) + return false; + // + Boolean invoiceSO = null; + // Check Invoice First + if (getC_Invoice_ID() > 0) + { + String sql = "SELECT idt.IsSOTrx " + + "FROM C_Invoice i" + + " INNER JOIN C_DocType idt ON (i.C_DocType_ID=idt.C_DocType_ID) " + + "WHERE i.C_Invoice_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, getC_Invoice_ID()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + invoiceSO = new Boolean ("Y".equals(rs.getString(1))); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + } // Invoice + + // DocumentType + Boolean paymentSO = null; + PreparedStatement pstmt = null; + String sql = "SELECT IsSOTrx " + + "FROM C_DocType " + + "WHERE C_DocType_ID=?"; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, getC_DocType_ID()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + paymentSO = new Boolean ("Y".equals(rs.getString(1))); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // No Payment info + if (paymentSO == null) + return false; + setIsReceipt(paymentSO.booleanValue()); + + // We have an Invoice .. and it does not match + if (invoiceSO != null + && invoiceSO.booleanValue() != paymentSO.booleanValue()) + return false; + // OK + return true; + } // verifyDocType + + + /** + * Get ISO Code of Currency + * @return Currency ISO + */ + public String getCurrencyISO() + { + return MCurrency.getISO_Code (getCtx(), getC_Currency_ID()); + } // getCurrencyISO + + /** + * Get Document Status + * @return Document Status Clear Text + */ + public String getDocStatusName() + { + return MRefList.getListName(getCtx(), 131, getDocStatus()); + } // getDocStatusName + + /** + * Get Name of Credit Card + * @return Name + */ + public String getCreditCardName() + { + return getCreditCardName(getCreditCardType()); + } // getCreditCardName + + /** + * Get Name of Credit Card + * @param CreditCardType credit card type + * @return Name + */ + public String getCreditCardName(String CreditCardType) + { + if (CreditCardType == null) + return "--"; + else if (CREDITCARDTYPE_MasterCard.equals(CreditCardType)) + return "MasterCard"; + else if (CREDITCARDTYPE_Visa.equals(CreditCardType)) + return "Visa"; + else if (CREDITCARDTYPE_Amex.equals(CreditCardType)) + return "Amex"; + else if (CREDITCARDTYPE_ATM.equals(CreditCardType)) + return "ATM"; + else if (CREDITCARDTYPE_Diners.equals(CreditCardType)) + return "Diners"; + else if (CREDITCARDTYPE_Discover.equals(CreditCardType)) + return "Discover"; + else if (CREDITCARDTYPE_PurchaseCard.equals(CreditCardType)) + return "PurchaseCard"; + return "?" + CreditCardType + "?"; + } // getCreditCardName + + /** + * Add to Description + * @param description text + */ + public void addDescription (String description) + { + String desc = getDescription(); + if (desc == null) + setDescription(description); + else + setDescription(desc + " | " + description); + } // addDescription + + + /** + * Get Pay Amt + * @param absolute if true the absolute amount (i.e. negative if payment) + * @return amount + */ + public BigDecimal getPayAmt (boolean absolute) + { + if (isReceipt()) + return super.getPayAmt(); + return super.getPayAmt().negate(); + } // getPayAmt + + /** + * Get Pay Amt in cents + * @return amount in cents + */ + public int getPayAmtInCents () + { + BigDecimal bd = super.getPayAmt().multiply(Env.ONEHUNDRED); + return bd.intValue(); + } // getPayAmtInCents + + /************************************************************************** + * Process document + * @param processAction document action + * @return true if performed + */ + public boolean processIt (String processAction) + { + m_processMsg = null; + DocumentEngine engine = new DocumentEngine (this, getDocStatus()); + return engine.processIt (processAction, getDocAction()); + } // process + + /** Process Message */ + private String m_processMsg = null; + /** Just Prepared Flag */ + private boolean m_justPrepared = false; + + /** + * Unlock Document. + * @return true if success */ public boolean unlockIt() { - log.info("unlockIt - " + toString()); + log.info(toString()); setProcessing(false); return true; } // unlockIt - - /** - * Invalidate Document - * @return true if success + + /** + * Invalidate Document + * @return true if success */ public boolean invalidateIt() { - log.info("invalidateIt - " + toString()); + log.info(toString()); setDocAction(DOCACTION_Prepare); return true; } // invalidateIt - - - /************************************************************************** - * Prepare Document - * @return new status (In Progress or Invalid) - */ - public String prepareIt() - { - log.info(toString()); - m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE); - if (m_processMsg != null) - return DocAction.STATUS_Invalid; + + + /************************************************************************** + * Prepare Document + * @return new status (In Progress or Invalid) + */ + public String prepareIt() + { + log.info(toString()); + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE); + if (m_processMsg != null) + return DocAction.STATUS_Invalid; // Std Period open? if (!MPeriod.isOpen(getCtx(), getDateAcct(), - isReceipt() ? MDocType.DOCBASETYPE_ARReceipt : MDocType.DOCBASETYPE_APPayment)) + isReceipt() ? X_C_DocType.DOCBASETYPE_ARReceipt : X_C_DocType.DOCBASETYPE_APPayment)) { m_processMsg = "@PeriodClosed@"; return DocAction.STATUS_Invalid; - } - - // Unsuccessful Online Payment - if (isOnline() && !isApproved()) - { - if (getR_Result() != null) - m_processMsg = "@OnlinePaymentFailed@"; - else - m_processMsg = "@PaymentNotProcessed@"; - return DocAction.STATUS_Invalid; - } - - // Waiting Payment - Need to create Invoice & Shipment - if (getC_Order_ID() != 0 && getC_Invoice_ID() == 0) - { // see WebOrder.process - MOrder order = new MOrder (getCtx(), getC_Order_ID(), get_TrxName()); + } + + // Unsuccessful Online Payment + if (isOnline() && !isApproved()) + { + if (getR_Result() != null) + m_processMsg = "@OnlinePaymentFailed@"; + else + m_processMsg = "@PaymentNotProcessed@"; + return DocAction.STATUS_Invalid; + } + + // Waiting Payment - Need to create Invoice & Shipment + if (getC_Order_ID() != 0 && getC_Invoice_ID() == 0) + { // see WebOrder.process + MOrder order = new MOrder (getCtx(), getC_Order_ID(), get_TrxName()); if (DOCSTATUS_WaitingPayment.equals(order.getDocStatus())) { order.setC_Payment_ID(getC_Payment_ID()); - order.setDocAction(MOrder.DOCACTION_WaitComplete); + order.setDocAction(X_C_Order.DOCACTION_WaitComplete); order.set_TrxName(get_TrxName()); - boolean ok = order.processIt (MOrder.DOCACTION_WaitComplete); + // boolean ok = + order.processIt (X_C_Order.DOCACTION_WaitComplete); m_processMsg = order.getProcessMsg(); order.save(get_TrxName()); // Set Invoice - MInvoice[] invoices = order.getInvoices(); - int length = invoices.length; - if (length > 0) // get last invoice - setC_Invoice_ID (invoices[length-1].getC_Invoice_ID()); - // - if (getC_Invoice_ID() == 0) - { - m_processMsg = "@NotFound@ @C_Invoice_ID@"; - return DocAction.STATUS_Invalid; - } - } // WaitingPayment - } - - // Consistency of Invoice / Document Type and IsReceipt - if (!verifyDocType()) - { - m_processMsg = "@PaymentDocTypeInvoiceInconsistent@"; - return DocAction.STATUS_Invalid; - } - - // Do not pay when Credit Stop/Hold + MInvoice[] invoices = order.getInvoices(); + int length = invoices.length; + if (length > 0) // get last invoice + setC_Invoice_ID (invoices[length-1].getC_Invoice_ID()); + // + if (getC_Invoice_ID() == 0) + { + m_processMsg = "@NotFound@ @C_Invoice_ID@"; + return DocAction.STATUS_Invalid; + } + } // WaitingPayment + } + + // Consistency of Invoice / Document Type and IsReceipt + if (!verifyDocType()) + { + m_processMsg = "@PaymentDocTypeInvoiceInconsistent@"; + return DocAction.STATUS_Invalid; + } + + // Do not pay when Credit Stop/Hold if (!isReceipt()) { MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); - if (MBPartner.SOCREDITSTATUS_CreditStop.equals(bp.getSOCreditStatus())) + if (X_C_BPartner.SOCREDITSTATUS_CreditStop.equals(bp.getSOCreditStatus())) { m_processMsg = "@BPartnerCreditStop@ - @TotalOpenBalance@=" + bp.getTotalOpenBalance() + ", @SO_CreditLimit@=" + bp.getSO_CreditLimit(); return DocAction.STATUS_Invalid; } - if (MBPartner.SOCREDITSTATUS_CreditHold.equals(bp.getSOCreditStatus())) + if (X_C_BPartner.SOCREDITSTATUS_CreditHold.equals(bp.getSOCreditStatus())) { m_processMsg = "@BPartnerCreditHold@ - @TotalOpenBalance@=" + bp.getTotalOpenBalance() - + ", @SO_CreditLimit@=" + bp.getSO_CreditLimit(); - return DocAction.STATUS_Invalid; - } - } - - m_justPrepared = true; - if (!DOCACTION_Complete.equals(getDocAction())) - setDocAction(DOCACTION_Complete); - return DocAction.STATUS_InProgress; - } // prepareIt - - /** - * Approve Document - * @return true if success - */ - public boolean approveIt() - { - log.info(toString()); - setIsApproved(true); - return true; - } // approveIt - - /** - * Reject Approval - * @return true if success - */ - public boolean rejectIt() - { - log.info(toString()); - setIsApproved(false); - return true; - } // rejectIt - - - /************************************************************************** - * Complete Document - * @return new status (Complete, In Progress, Invalid, Waiting ..) - */ - public String completeIt() - { - // Re-Check - if (!m_justPrepared) - { - String status = prepareIt(); - if (!DocAction.STATUS_InProgress.equals(status)) - return status; - } - // Implicit Approval - if (!isApproved()) - approveIt(); - log.info(toString()); - - // Charge Handling - if (getC_Charge_ID() != 0) - { - setIsAllocated(true); - } - else - { - allocateIt(); // Create Allocation Records - testAllocation(); - } - - // Project update - if (getC_Project_ID() != 0) - { - // MProject project = new MProject(getCtx(), getC_Project_ID()); - } - // Update BP for Prepayments - if (getC_BPartner_ID() != 0 && getC_Invoice_ID() == 0) - { - MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); - bp.setTotalOpenBalance(); - bp.save(); - } - - // Counter Doc - MPayment counter = createCounterDoc(); - if (counter != null) - m_processMsg += " @CounterDoc@: @C_Payment_ID@=" + counter.getDocumentNo(); - - // User Validation - String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE); - if (valid != null) - { - m_processMsg = valid; - return DocAction.STATUS_Invalid; - } - // - setProcessed(true); - setDocAction(DOCACTION_Close); - return DocAction.STATUS_Completed; - } // completeIt - - /** - * Create Counter Document - * @return payment - */ - private MPayment createCounterDoc() - { - // Is this a counter doc ? - if (getRef_Payment_ID() != 0) - return null; - - // Org Must be linked to BPartner - MOrg org = MOrg.get(getCtx(), getAD_Org_ID()); - int counterC_BPartner_ID = org.getLinkedC_BPartner_ID(); - if (counterC_BPartner_ID == 0) - return null; - // Business Partner needs to be linked to Org - MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), null); - int counterAD_Org_ID = bp.getAD_OrgBP_ID_Int(); - if (counterAD_Org_ID == 0) + + ", @SO_CreditLimit@=" + bp.getSO_CreditLimit(); + return DocAction.STATUS_Invalid; + } + } + + m_justPrepared = true; + if (!DOCACTION_Complete.equals(getDocAction())) + setDocAction(DOCACTION_Complete); + return DocAction.STATUS_InProgress; + } // prepareIt + + /** + * Approve Document + * @return true if success + */ + public boolean approveIt() + { + log.info(toString()); + setIsApproved(true); + return true; + } // approveIt + + /** + * Reject Approval + * @return true if success + */ + public boolean rejectIt() + { + log.info(toString()); + setIsApproved(false); + return true; + } // rejectIt + + + /************************************************************************** + * Complete Document + * @return new status (Complete, In Progress, Invalid, Waiting ..) + */ + public String completeIt() + { + // Re-Check + if (!m_justPrepared) + { + String status = prepareIt(); + if (!DocAction.STATUS_InProgress.equals(status)) + return status; + } + // Implicit Approval + if (!isApproved()) + approveIt(); + log.info(toString()); + + // Charge Handling + if (getC_Charge_ID() != 0) + { + setIsAllocated(true); + } + else + { + allocateIt(); // Create Allocation Records + testAllocation(); + } + + // Project update + if (getC_Project_ID() != 0) + { + // MProject project = new MProject(getCtx(), getC_Project_ID()); + } + // Update BP for Prepayments + if (getC_BPartner_ID() != 0 && getC_Invoice_ID() == 0) + { + MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); + bp.setTotalOpenBalance(); + bp.save(); + } + + // Counter Doc + MPayment counter = createCounterDoc(); + if (counter != null) + m_processMsg += " @CounterDoc@: @C_Payment_ID@=" + counter.getDocumentNo(); + + // User Validation + String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE); + if (valid != null) + { + m_processMsg = valid; + return DocAction.STATUS_Invalid; + } + // + setProcessed(true); + setDocAction(DOCACTION_Close); + return DocAction.STATUS_Completed; + } // completeIt + + /** + * Create Counter Document + * @return payment + */ + private MPayment createCounterDoc() + { + // Is this a counter doc ? + if (getRef_Payment_ID() != 0) + return null; + + // Org Must be linked to BPartner + MOrg org = MOrg.get(getCtx(), getAD_Org_ID()); + int counterC_BPartner_ID = org.getLinkedC_BPartner_ID(); + if (counterC_BPartner_ID == 0) + return null; + // Business Partner needs to be linked to Org + MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), null); + int counterAD_Org_ID = bp.getAD_OrgBP_ID_Int(); + if (counterAD_Org_ID == 0) return null; MBPartner counterBP = new MBPartner (getCtx(), counterC_BPartner_ID, null); - MOrgInfo counterOrgInfo = MOrgInfo.get(getCtx(), counterAD_Org_ID); + // MOrgInfo counterOrgInfo = MOrgInfo.get(getCtx(), counterAD_Org_ID); log.info("Counter BP=" + counterBP.getName()); // Document Type - int C_DocTypeTarget_ID = 0; - MDocTypeCounter counterDT = MDocTypeCounter.getCounterDocType(getCtx(), getC_DocType_ID()); - if (counterDT != null) - { - log.fine(counterDT.toString()); - if (!counterDT.isCreateCounter() || !counterDT.isValid()) - return null; - C_DocTypeTarget_ID = counterDT.getCounter_C_DocType_ID(); - } - else // indirect - { - C_DocTypeTarget_ID = MDocTypeCounter.getCounterDocType_ID(getCtx(), getC_DocType_ID()); - log.fine("Indirect C_DocTypeTarget_ID=" + C_DocTypeTarget_ID); - if (C_DocTypeTarget_ID <= 0) - return null; - } - - // Deep Copy - MPayment counter = new MPayment (getCtx(), 0, get_TrxName()); - counter.setAD_Org_ID(counterAD_Org_ID); - counter.setC_BPartner_ID(counterBP.getC_BPartner_ID()); - counter.setIsReceipt(!isReceipt()); - counter.setC_DocType_ID(C_DocTypeTarget_ID); - counter.setTrxType(getTrxType()); - counter.setTenderType(getTenderType()); - // - counter.setPayAmt(getPayAmt()); - counter.setDiscountAmt(getDiscountAmt()); - counter.setTaxAmt(getTaxAmt()); - counter.setWriteOffAmt(getWriteOffAmt()); - counter.setIsOverUnderPayment (isOverUnderPayment()); - counter.setOverUnderAmt(getOverUnderAmt()); - counter.setC_Currency_ID(getC_Currency_ID()); - counter.setC_ConversionType_ID(getC_ConversionType_ID()); - // - counter.setDateTrx (getDateTrx()); - counter.setDateAcct (getDateAcct()); - counter.setRef_Payment_ID(getC_Payment_ID()); - // - String sql = "SELECT C_BankAccount_ID FROM C_BankAccount " - + "WHERE C_Currency_ID=? AND AD_Org_ID IN (0,?) AND IsActive='Y' " - + "ORDER BY IsDefault DESC"; - int C_BankAccount_ID = DB.getSQLValue(get_TrxName(), sql, getC_Currency_ID(), counterAD_Org_ID); - counter.setC_BankAccount_ID(C_BankAccount_ID); - - // Refernces - counter.setC_Activity_ID(getC_Activity_ID()); - counter.setC_Campaign_ID(getC_Campaign_ID()); - counter.setC_Project_ID(getC_Project_ID()); - counter.setUser1_ID(getUser1_ID()); - counter.setUser2_ID(getUser2_ID()); - counter.save(get_TrxName()); - log.fine(counter.toString()); - setRef_Payment_ID(counter.getC_Payment_ID()); - - // Document Action - if (counterDT != null) - { - if (counterDT.getDocAction() != null) - { - counter.setDocAction(counterDT.getDocAction()); - counter.processIt(counterDT.getDocAction()); - counter.save(get_TrxName()); - } - } - return counter; - } // createCounterDoc - - /** - * Allocate It. - * Only call when there is NO allocation as it will create duplicates. - * If an invoice exists, it allocates that - * otherwise it allocates Payment Selection. - * @return true if allocated - */ - public boolean allocateIt() - { - // Create invoice Allocation - See also MCash.completeIt - if (getC_Invoice_ID() != 0) - return allocateInvoice(); - // Invoices of a AP Payment Selection - if (allocatePaySelection()) - return true; - - if (getC_Order_ID() != 0) - return false; - - // Allocate to multiple Payments based on entry - MPaymentAllocate[] pAllocs = MPaymentAllocate.get(this); - if (pAllocs.length == 0) - return false; - - MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, - getDateTrx(), getC_Currency_ID(), - Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo(), - get_TrxName()); - alloc.setAD_Org_ID(getAD_Org_ID()); - if (!alloc.save()) - { - log.severe("P.Allocations not created"); - return false; - } - // Lines - for (int i = 0; i < pAllocs.length; i++) - { - MPaymentAllocate pa = pAllocs[i]; - MAllocationLine aLine = null; - if (isReceipt()) - aLine = new MAllocationLine (alloc, pa.getAmount(), - pa.getDiscountAmt(), pa.getWriteOffAmt(), pa.getOverUnderAmt()); - else - aLine = new MAllocationLine (alloc, pa.getAmount().negate(), - pa.getDiscountAmt().negate(), pa.getWriteOffAmt().negate(), pa.getOverUnderAmt().negate()); - aLine.setDocInfo(pa.getC_BPartner_ID(), 0, pa.getC_Invoice_ID()); - aLine.setPaymentInfo(getC_Payment_ID(), 0); - if (!aLine.save(get_TrxName())) - log.warning("P.Allocations - line not saved"); - else - { - pa.setC_AllocationLine_ID(aLine.getC_AllocationLine_ID()); - pa.save(); - } - } - // Should start WF - alloc.processIt(DocAction.ACTION_Complete); - m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); - return alloc.save(get_TrxName()); - } // allocateIt - - /** - * Allocate single AP/AR Invoice - * @return true if allocated - */ - private boolean allocateInvoice() - { - // calculate actual allocation - BigDecimal allocationAmt = getPayAmt(); // underpayment - if (getOverUnderAmt().signum() < 0 && getPayAmt().signum() > 0) - allocationAmt = allocationAmt.add(getOverUnderAmt()); // overpayment (negative) - - MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, - getDateTrx(), getC_Currency_ID(), - Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo() + " [1]", get_TrxName()); - alloc.setAD_Org_ID(getAD_Org_ID()); - if (!alloc.save()) - { - log.log(Level.SEVERE, "Could not create Allocation Hdr"); - return false; - } - MAllocationLine aLine = null; - if (isReceipt()) - aLine = new MAllocationLine (alloc, allocationAmt, - getDiscountAmt(), getWriteOffAmt(), getOverUnderAmt()); - else - aLine = new MAllocationLine (alloc, allocationAmt.negate(), - getDiscountAmt().negate(), getWriteOffAmt().negate(), getOverUnderAmt().negate()); - aLine.setDocInfo(getC_BPartner_ID(), 0, getC_Invoice_ID()); - aLine.setC_Payment_ID(getC_Payment_ID()); - if (!aLine.save(get_TrxName())) - { - log.log(Level.SEVERE, "Could not create Allocation Line"); - return false; - } - // Should start WF - alloc.processIt(DocAction.ACTION_Complete); - alloc.save(get_TrxName()); - m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); - - // Get Project from Invoice - int C_Project_ID = DB.getSQLValue(get_TrxName(), - "SELECT MAX(C_Project_ID) FROM C_Invoice WHERE C_Invoice_ID=?", getC_Invoice_ID()); - if (C_Project_ID > 0 && getC_Project_ID() == 0) - setC_Project_ID(C_Project_ID); - else if (C_Project_ID > 0 && getC_Project_ID() > 0 && C_Project_ID != getC_Project_ID()) - log.warning("Invoice C_Project_ID=" + C_Project_ID - + " <> Payment C_Project_ID=" + getC_Project_ID()); - return true; - } // allocateInvoice - - /** - * Allocate Payment Selection - * @return true if allocated - */ - private boolean allocatePaySelection() - { - MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, - getDateTrx(), getC_Currency_ID(), - Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo() + " [n]", get_TrxName()); - alloc.setAD_Org_ID(getAD_Org_ID()); - - String sql = "SELECT psc.C_BPartner_ID, psl.C_Invoice_ID, psl.IsSOTrx, " // 1..3 - + " psl.PayAmt, psl.DiscountAmt, psl.DifferenceAmt, psl.OpenAmt " - + "FROM C_PaySelectionLine psl" - + " INNER JOIN C_PaySelectionCheck psc ON (psl.C_PaySelectionCheck_ID=psc.C_PaySelectionCheck_ID) " - + "WHERE psc.C_Payment_ID=?"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, getC_Payment_ID()); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) - { - int C_BPartner_ID = rs.getInt(1); - int C_Invoice_ID = rs.getInt(2); - if (C_BPartner_ID == 0 && C_Invoice_ID == 0) - continue; - boolean isSOTrx = "Y".equals(rs.getString(3)); - BigDecimal PayAmt = rs.getBigDecimal(4); - BigDecimal DiscountAmt = rs.getBigDecimal(5); - BigDecimal WriteOffAmt = rs.getBigDecimal(6); - BigDecimal OpenAmt = rs.getBigDecimal(7); - BigDecimal OverUnderAmt = OpenAmt.subtract(PayAmt) - .subtract(DiscountAmt).subtract(WriteOffAmt); - // - if (alloc.get_ID() == 0 && !alloc.save(get_TrxName())) - { - log.log(Level.SEVERE, "Could not create Allocation Hdr"); - rs.close(); - pstmt.close(); - return false; - } - MAllocationLine aLine = null; - if (isSOTrx) - aLine = new MAllocationLine (alloc, PayAmt, - DiscountAmt, WriteOffAmt, OverUnderAmt); - else - aLine = new MAllocationLine (alloc, PayAmt.negate(), - DiscountAmt.negate(), WriteOffAmt.negate(), OverUnderAmt.negate()); - aLine.setDocInfo(C_BPartner_ID, 0, C_Invoice_ID); - aLine.setC_Payment_ID(getC_Payment_ID()); - if (!aLine.save(get_TrxName())) - log.log(Level.SEVERE, "Could not create Allocation Line"); - } - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, "allocatePaySelection", e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - - // Should start WF - boolean ok = true; - if (alloc.get_ID() == 0) - { - log.fine("No Allocation created - C_Payment_ID=" - + getC_Payment_ID()); - ok = false; - } - else - { - alloc.processIt(DocAction.ACTION_Complete); - ok = alloc.save(get_TrxName()); - m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); - } - return ok; - } // allocatePaySelection - - /** - * De-allocate Payment. - * Unkink Invoices and Orders and delete Allocations - */ - private void deAllocate() - { - if (getC_Order_ID() != 0) - setC_Order_ID(0); - // if (getC_Invoice_ID() == 0) - // return; - // De-Allocate all - MAllocationHdr[] allocations = MAllocationHdr.getOfPayment(getCtx(), - getC_Payment_ID(), get_TrxName()); - log.fine("#" + allocations.length); - for (int i = 0; i < allocations.length; i++) - { - allocations[i].set_TrxName(get_TrxName()); - allocations[i].setDocAction(DocAction.ACTION_Reverse_Correct); - allocations[i].processIt(DocAction.ACTION_Reverse_Correct); - allocations[i].save(); - } - - // Unlink (in case allocation did not get it) - if (getC_Invoice_ID() != 0) - { - // Invoice - String sql = "UPDATE C_Invoice " - + "SET C_Payment_ID = NULL, IsPaid='N' " - + "WHERE C_Invoice_ID=" + getC_Invoice_ID() - + " AND C_Payment_ID=" + getC_Payment_ID(); - int no = DB.executeUpdate(sql, get_TrxName()); - if (no != 0) - log.fine("Unlink Invoice #" + no); - // Order - sql = "UPDATE C_Order o " - + "SET C_Payment_ID = NULL " - + "WHERE EXISTS (SELECT * FROM C_Invoice i " - + "WHERE o.C_Order_ID=i.C_Order_ID AND i.C_Invoice_ID=" + getC_Invoice_ID() + ")" - + " AND C_Payment_ID=" + getC_Payment_ID(); - no = DB.executeUpdate(sql, get_TrxName()); - if (no != 0) - log.fine("Unlink Order #" + no); - } - // - setC_Invoice_ID(0); - setIsAllocated(false); - } // deallocate - - /** - * Void Document. - * @return true if success - */ - public boolean voidIt() - { - log.info(toString()); - if (DOCSTATUS_Closed.equals(getDocStatus()) - || DOCSTATUS_Reversed.equals(getDocStatus()) - || DOCSTATUS_Voided.equals(getDocStatus())) - { - m_processMsg = "Document Closed: " + getDocStatus(); - setDocAction(DOCACTION_None); - return false; - } - // If on Bank Statement, don't void it - reverse it - if (getC_BankStatementLine_ID() > 0) - return reverseCorrectIt(); - - // Not Processed - if (DOCSTATUS_Drafted.equals(getDocStatus()) - || DOCSTATUS_Invalid.equals(getDocStatus()) - || DOCSTATUS_InProgress.equals(getDocStatus()) - || DOCSTATUS_Approved.equals(getDocStatus()) - || DOCSTATUS_NotApproved.equals(getDocStatus()) ) - { - addDescription(Msg.getMsg(getCtx(), "Voided") + " (" + getPayAmt() + ")"); - setPayAmt(Env.ZERO); - setDiscountAmt(Env.ZERO); - setWriteOffAmt(Env.ZERO); - setOverUnderAmt(Env.ZERO); - setIsAllocated(false); - // Unlink & De-Allocate - deAllocate(); - } - else - return reverseCorrectIt(); - - // - setProcessed(true); - setDocAction(DOCACTION_None); - return true; - } // voidIt - - /** - * Close Document. - * @return true if success - */ - public boolean closeIt() - { - log.info(toString()); - setDocAction(DOCACTION_None); - return true; - } // closeIt - - /** - * Reverse Correction - * @return true if success - */ - public boolean reverseCorrectIt() - { - log.info(toString()); - + int C_DocTypeTarget_ID = 0; + MDocTypeCounter counterDT = MDocTypeCounter.getCounterDocType(getCtx(), getC_DocType_ID()); + if (counterDT != null) + { + log.fine(counterDT.toString()); + if (!counterDT.isCreateCounter() || !counterDT.isValid()) + return null; + C_DocTypeTarget_ID = counterDT.getCounter_C_DocType_ID(); + } + else // indirect + { + C_DocTypeTarget_ID = MDocTypeCounter.getCounterDocType_ID(getCtx(), getC_DocType_ID()); + log.fine("Indirect C_DocTypeTarget_ID=" + C_DocTypeTarget_ID); + if (C_DocTypeTarget_ID <= 0) + return null; + } + + // Deep Copy + MPayment counter = new MPayment (getCtx(), 0, get_TrxName()); + counter.setAD_Org_ID(counterAD_Org_ID); + counter.setC_BPartner_ID(counterBP.getC_BPartner_ID()); + counter.setIsReceipt(!isReceipt()); + counter.setC_DocType_ID(C_DocTypeTarget_ID); + counter.setTrxType(getTrxType()); + counter.setTenderType(getTenderType()); + // + counter.setPayAmt(getPayAmt()); + counter.setDiscountAmt(getDiscountAmt()); + counter.setTaxAmt(getTaxAmt()); + counter.setWriteOffAmt(getWriteOffAmt()); + counter.setIsOverUnderPayment (isOverUnderPayment()); + counter.setOverUnderAmt(getOverUnderAmt()); + counter.setC_Currency_ID(getC_Currency_ID()); + counter.setC_ConversionType_ID(getC_ConversionType_ID()); + // + counter.setDateTrx (getDateTrx()); + counter.setDateAcct (getDateAcct()); + counter.setRef_Payment_ID(getC_Payment_ID()); + // + String sql = "SELECT C_BankAccount_ID FROM C_BankAccount " + + "WHERE C_Currency_ID=? AND AD_Org_ID IN (0,?) AND IsActive='Y' " + + "ORDER BY IsDefault DESC"; + int C_BankAccount_ID = DB.getSQLValue(get_TrxName(), sql, getC_Currency_ID(), counterAD_Org_ID); + counter.setC_BankAccount_ID(C_BankAccount_ID); + + // Refernces + counter.setC_Activity_ID(getC_Activity_ID()); + counter.setC_Campaign_ID(getC_Campaign_ID()); + counter.setC_Project_ID(getC_Project_ID()); + counter.setUser1_ID(getUser1_ID()); + counter.setUser2_ID(getUser2_ID()); + counter.save(get_TrxName()); + log.fine(counter.toString()); + setRef_Payment_ID(counter.getC_Payment_ID()); + + // Document Action + if (counterDT != null) + { + if (counterDT.getDocAction() != null) + { + counter.setDocAction(counterDT.getDocAction()); + counter.processIt(counterDT.getDocAction()); + counter.save(get_TrxName()); + } + } + return counter; + } // createCounterDoc + + /** + * Allocate It. + * Only call when there is NO allocation as it will create duplicates. + * If an invoice exists, it allocates that + * otherwise it allocates Payment Selection. + * @return true if allocated + */ + public boolean allocateIt() + { + // Create invoice Allocation - See also MCash.completeIt + if (getC_Invoice_ID() != 0) + return allocateInvoice(); + // Invoices of a AP Payment Selection + if (allocatePaySelection()) + return true; + + if (getC_Order_ID() != 0) + return false; + + // Allocate to multiple Payments based on entry + MPaymentAllocate[] pAllocs = MPaymentAllocate.get(this); + if (pAllocs.length == 0) + return false; + + MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, + getDateTrx(), getC_Currency_ID(), + Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo(), + get_TrxName()); + alloc.setAD_Org_ID(getAD_Org_ID()); + if (!alloc.save()) + { + log.severe("P.Allocations not created"); + return false; + } + // Lines + for (int i = 0; i < pAllocs.length; i++) + { + MPaymentAllocate pa = pAllocs[i]; + MAllocationLine aLine = null; + if (isReceipt()) + aLine = new MAllocationLine (alloc, pa.getAmount(), + pa.getDiscountAmt(), pa.getWriteOffAmt(), pa.getOverUnderAmt()); + else + aLine = new MAllocationLine (alloc, pa.getAmount().negate(), + pa.getDiscountAmt().negate(), pa.getWriteOffAmt().negate(), pa.getOverUnderAmt().negate()); + aLine.setDocInfo(pa.getC_BPartner_ID(), 0, pa.getC_Invoice_ID()); + aLine.setPaymentInfo(getC_Payment_ID(), 0); + if (!aLine.save(get_TrxName())) + log.warning("P.Allocations - line not saved"); + else + { + pa.setC_AllocationLine_ID(aLine.getC_AllocationLine_ID()); + pa.save(); + } + } + // Should start WF + alloc.processIt(DocAction.ACTION_Complete); + m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); + return alloc.save(get_TrxName()); + } // allocateIt + + /** + * Allocate single AP/AR Invoice + * @return true if allocated + */ + private boolean allocateInvoice() + { + // calculate actual allocation + BigDecimal allocationAmt = getPayAmt(); // underpayment + if (getOverUnderAmt().signum() < 0 && getPayAmt().signum() > 0) + allocationAmt = allocationAmt.add(getOverUnderAmt()); // overpayment (negative) + + MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, + getDateTrx(), getC_Currency_ID(), + Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo() + " [1]", get_TrxName()); + alloc.setAD_Org_ID(getAD_Org_ID()); + if (!alloc.save()) + { + log.log(Level.SEVERE, "Could not create Allocation Hdr"); + return false; + } + MAllocationLine aLine = null; + if (isReceipt()) + aLine = new MAllocationLine (alloc, allocationAmt, + getDiscountAmt(), getWriteOffAmt(), getOverUnderAmt()); + else + aLine = new MAllocationLine (alloc, allocationAmt.negate(), + getDiscountAmt().negate(), getWriteOffAmt().negate(), getOverUnderAmt().negate()); + aLine.setDocInfo(getC_BPartner_ID(), 0, getC_Invoice_ID()); + aLine.setC_Payment_ID(getC_Payment_ID()); + if (!aLine.save(get_TrxName())) + { + log.log(Level.SEVERE, "Could not create Allocation Line"); + return false; + } + // Should start WF + alloc.processIt(DocAction.ACTION_Complete); + alloc.save(get_TrxName()); + m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); + + // Get Project from Invoice + int C_Project_ID = DB.getSQLValue(get_TrxName(), + "SELECT MAX(C_Project_ID) FROM C_Invoice WHERE C_Invoice_ID=?", getC_Invoice_ID()); + if (C_Project_ID > 0 && getC_Project_ID() == 0) + setC_Project_ID(C_Project_ID); + else if (C_Project_ID > 0 && getC_Project_ID() > 0 && C_Project_ID != getC_Project_ID()) + log.warning("Invoice C_Project_ID=" + C_Project_ID + + " <> Payment C_Project_ID=" + getC_Project_ID()); + return true; + } // allocateInvoice + + /** + * Allocate Payment Selection + * @return true if allocated + */ + private boolean allocatePaySelection() + { + MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, + getDateTrx(), getC_Currency_ID(), + Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo() + " [n]", get_TrxName()); + alloc.setAD_Org_ID(getAD_Org_ID()); + + String sql = "SELECT psc.C_BPartner_ID, psl.C_Invoice_ID, psl.IsSOTrx, " // 1..3 + + " psl.PayAmt, psl.DiscountAmt, psl.DifferenceAmt, psl.OpenAmt " + + "FROM C_PaySelectionLine psl" + + " INNER JOIN C_PaySelectionCheck psc ON (psl.C_PaySelectionCheck_ID=psc.C_PaySelectionCheck_ID) " + + "WHERE psc.C_Payment_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, getC_Payment_ID()); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + int C_BPartner_ID = rs.getInt(1); + int C_Invoice_ID = rs.getInt(2); + if (C_BPartner_ID == 0 && C_Invoice_ID == 0) + continue; + boolean isSOTrx = "Y".equals(rs.getString(3)); + BigDecimal PayAmt = rs.getBigDecimal(4); + BigDecimal DiscountAmt = rs.getBigDecimal(5); + BigDecimal WriteOffAmt = rs.getBigDecimal(6); + BigDecimal OpenAmt = rs.getBigDecimal(7); + BigDecimal OverUnderAmt = OpenAmt.subtract(PayAmt) + .subtract(DiscountAmt).subtract(WriteOffAmt); + // + if (alloc.get_ID() == 0 && !alloc.save(get_TrxName())) + { + log.log(Level.SEVERE, "Could not create Allocation Hdr"); + rs.close(); + pstmt.close(); + return false; + } + MAllocationLine aLine = null; + if (isSOTrx) + aLine = new MAllocationLine (alloc, PayAmt, + DiscountAmt, WriteOffAmt, OverUnderAmt); + else + aLine = new MAllocationLine (alloc, PayAmt.negate(), + DiscountAmt.negate(), WriteOffAmt.negate(), OverUnderAmt.negate()); + aLine.setDocInfo(C_BPartner_ID, 0, C_Invoice_ID); + aLine.setC_Payment_ID(getC_Payment_ID()); + if (!aLine.save(get_TrxName())) + log.log(Level.SEVERE, "Could not create Allocation Line"); + } + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, "allocatePaySelection", e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + + // Should start WF + boolean ok = true; + if (alloc.get_ID() == 0) + { + log.fine("No Allocation created - C_Payment_ID=" + + getC_Payment_ID()); + ok = false; + } + else + { + alloc.processIt(DocAction.ACTION_Complete); + ok = alloc.save(get_TrxName()); + m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); + } + return ok; + } // allocatePaySelection + + /** + * De-allocate Payment. + * Unkink Invoices and Orders and delete Allocations + */ + private void deAllocate() + { + if (getC_Order_ID() != 0) + setC_Order_ID(0); + // if (getC_Invoice_ID() == 0) + // return; + // De-Allocate all + MAllocationHdr[] allocations = MAllocationHdr.getOfPayment(getCtx(), + getC_Payment_ID(), get_TrxName()); + log.fine("#" + allocations.length); + for (int i = 0; i < allocations.length; i++) + { + allocations[i].set_TrxName(get_TrxName()); + allocations[i].setDocAction(DocAction.ACTION_Reverse_Correct); + allocations[i].processIt(DocAction.ACTION_Reverse_Correct); + allocations[i].save(); + } + + // Unlink (in case allocation did not get it) + if (getC_Invoice_ID() != 0) + { + // Invoice + String sql = "UPDATE C_Invoice " + + "SET C_Payment_ID = NULL, IsPaid='N' " + + "WHERE C_Invoice_ID=" + getC_Invoice_ID() + + " AND C_Payment_ID=" + getC_Payment_ID(); + int no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Unlink Invoice #" + no); + // Order + sql = "UPDATE C_Order o " + + "SET C_Payment_ID = NULL " + + "WHERE EXISTS (SELECT * FROM C_Invoice i " + + "WHERE o.C_Order_ID=i.C_Order_ID AND i.C_Invoice_ID=" + getC_Invoice_ID() + ")" + + " AND C_Payment_ID=" + getC_Payment_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Unlink Order #" + no); + } + // + setC_Invoice_ID(0); + setIsAllocated(false); + } // deallocate + + /** + * Void Document. + * @return true if success + */ + public boolean voidIt() + { + log.info(toString()); + if (DOCSTATUS_Closed.equals(getDocStatus()) + || DOCSTATUS_Reversed.equals(getDocStatus()) + || DOCSTATUS_Voided.equals(getDocStatus())) + { + m_processMsg = "Document Closed: " + getDocStatus(); + setDocAction(DOCACTION_None); + return false; + } + // If on Bank Statement, don't void it - reverse it + if (getC_BankStatementLine_ID() > 0) + return reverseCorrectIt(); + + // Not Processed + if (DOCSTATUS_Drafted.equals(getDocStatus()) + || DOCSTATUS_Invalid.equals(getDocStatus()) + || DOCSTATUS_InProgress.equals(getDocStatus()) + || DOCSTATUS_Approved.equals(getDocStatus()) + || DOCSTATUS_NotApproved.equals(getDocStatus()) ) + { + addDescription(Msg.getMsg(getCtx(), "Voided") + " (" + getPayAmt() + ")"); + setPayAmt(Env.ZERO); + setDiscountAmt(Env.ZERO); + setWriteOffAmt(Env.ZERO); + setOverUnderAmt(Env.ZERO); + setIsAllocated(false); + // Unlink & De-Allocate + deAllocate(); + } + else + return reverseCorrectIt(); + + // + setProcessed(true); + setDocAction(DOCACTION_None); + return true; + } // voidIt + + /** + * Close Document. + * @return true if success + */ + public boolean closeIt() + { + log.info(toString()); + setDocAction(DOCACTION_None); + return true; + } // closeIt + + /** + * Reverse Correction + * @return true if success + */ + public boolean reverseCorrectIt() + { + log.info(toString()); + // Std Period open? Timestamp dateAcct = getDateAcct(); if (!MPeriod.isOpen(getCtx(), dateAcct, - isReceipt() ? MDocType.DOCBASETYPE_ARReceipt : MDocType.DOCBASETYPE_APPayment)) + isReceipt() ? X_C_DocType.DOCBASETYPE_ARReceipt : X_C_DocType.DOCBASETYPE_APPayment)) dateAcct = new Timestamp(System.currentTimeMillis()); // Auto Reconcile if not on Bank Statement - boolean reconciled = false; // getC_BankStatementLine_ID() == 0; - - // Create Reversal - MPayment reversal = new MPayment (getCtx(), 0, get_TrxName()); - copyValues(this, reversal); - reversal.setClientOrg(this); - reversal.setC_Order_ID(0); - reversal.setC_Invoice_ID(0); - reversal.setDateAcct(dateAcct); - // - reversal.setDocumentNo(getDocumentNo() + REVERSE_INDICATOR); // indicate reversals - reversal.setDocStatus(DOCSTATUS_Drafted); - reversal.setDocAction(DOCACTION_Complete); - // - reversal.setPayAmt(getPayAmt().negate()); - reversal.setDiscountAmt(getDiscountAmt().negate()); - reversal.setWriteOffAmt(getWriteOffAmt().negate()); - reversal.setOverUnderAmt(getOverUnderAmt().negate()); - // - reversal.setIsAllocated(true); - reversal.setIsReconciled(reconciled); // to put on bank statement - reversal.setIsOnline(false); - reversal.setIsApproved(true); - reversal.setR_PnRef(null); - reversal.setR_Result(null); - reversal.setR_RespMsg(null); - reversal.setR_AuthCode(null); - reversal.setR_Info(null); - reversal.setProcessing(false); - reversal.setOProcessing("N"); - reversal.setProcessed(false); - reversal.setPosted(false); - reversal.setDescription(getDescription()); - reversal.addDescription("{->" + getDocumentNo() + ")"); - reversal.save(get_TrxName()); - // Post Reversal - if (!reversal.processIt(DocAction.ACTION_Complete)) - { - m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); - return false; - } - reversal.closeIt(); - reversal.setDocStatus(DOCSTATUS_Reversed); - reversal.setDocAction(DOCACTION_None); - reversal.save(get_TrxName()); - - // Unlink & De-Allocate - deAllocate(); - setIsReconciled (reconciled); - setIsAllocated (true); // the allocation below is overwritten - // Set Status - addDescription("(" + reversal.getDocumentNo() + "<-)"); - setDocStatus(DOCSTATUS_Reversed); - setDocAction(DOCACTION_None); - setProcessed(true); - - // Create automatic Allocation - MAllocationHdr alloc = new MAllocationHdr (getCtx(), false, - getDateTrx(), getC_Currency_ID(), - Msg.translate(getCtx(), "C_Payment_ID") + ": " + reversal.getDocumentNo(), get_TrxName()); - alloc.setAD_Org_ID(getAD_Org_ID()); - if (!alloc.save()) - log.warning("Automatic allocation - hdr not saved"); - else - { - // Original Allocation - MAllocationLine aLine = new MAllocationLine (alloc, getPayAmt(true), - Env.ZERO, Env.ZERO, Env.ZERO); - aLine.setDocInfo(getC_BPartner_ID(), 0, 0); - aLine.setPaymentInfo(getC_Payment_ID(), 0); - if (!aLine.save(get_TrxName())) - log.warning("Automatic allocation - line not saved"); - // Reversal Allocation - aLine = new MAllocationLine (alloc, reversal.getPayAmt(true), - Env.ZERO, Env.ZERO, Env.ZERO); - aLine.setDocInfo(reversal.getC_BPartner_ID(), 0, 0); - aLine.setPaymentInfo(reversal.getC_Payment_ID(), 0); - if (!aLine.save(get_TrxName())) - log.warning("Automatic allocation - reversal line not saved"); - } - alloc.processIt(DocAction.ACTION_Complete); - alloc.save(get_TrxName()); - // - StringBuffer info = new StringBuffer (reversal.getDocumentNo()); - info.append(" - @C_AllocationHdr_ID@: ").append(alloc.getDocumentNo()); - - // Update BPartner - if (getC_BPartner_ID() != 0) - { - MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); - bp.setTotalOpenBalance(); - bp.save(get_TrxName()); - } - - m_processMsg = info.toString(); - return true; - } // reverseCorrectionIt - - /** - * Get Bank Statement Line of payment or 0 - * @return id or 0 - */ - private int getC_BankStatementLine_ID() - { - String sql = "SELECT C_BankStatementLine_ID FROM C_BankStatementLine WHERE C_Payment_ID=?"; - int id = DB.getSQLValue(get_TrxName(), sql, getC_Payment_ID()); - if (id < 0) - return 0; - return id; - } // getC_BankStatementLine_ID - - /** - * Reverse Accrual - none - * @return true if success - */ - public boolean reverseAccrualIt() - { - log.info(toString()); - return false; - } // reverseAccrualIt - - /** - * Re-activate - * @return true if success - */ - public boolean reActivateIt() - { - log.info(toString()); - if (reverseCorrectIt()) - return true; - return false; - } // reActivateIt - - /** - * String Representation - * @return info - */ - public String toString () - { - StringBuffer sb = new StringBuffer ("MPayment["); - sb.append(get_ID()).append("-").append(getDocumentNo()) - .append(",Receipt=").append(isReceipt()) - .append(",PayAmt=").append(getPayAmt()) - .append(",Discount=").append(getDiscountAmt()) - .append(",WriteOff=").append(getWriteOffAmt()) - .append(",OverUnder=").append(getOverUnderAmt()); - return sb.toString (); - } // toString - - /** - * Get Document Info - * @return document info (untranslated) - */ - public String getDocumentInfo() - { - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); - return dt.getName() + " " + getDocumentNo(); - } // getDocumentInfo - - /** - * Create PDF - * @return File or null - */ - public File createPDF () - { - try - { - File temp = File.createTempFile(get_TableName()+get_ID()+"_", ".pdf"); - return createPDF (temp); - } - catch (Exception e) - { - log.severe("Could not create PDF - " + e.getMessage()); - } - return null; - } // getPDF - - /** - * Create PDF file - * @param file output file - * @return file if success - */ - public File createPDF (File file) - { - // ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.PAYMENT, getC_Payment_ID()); - // if (re == null) - return null; - // return re.getPDF(file); - } // createPDF - - - /************************************************************************* - * Get Summary - * @return Summary of Document - */ - public String getSummary() - { - StringBuffer sb = new StringBuffer(); - sb.append(getDocumentNo()); - // : Total Lines = 123.00 (#1) - sb.append(": ") - .append(Msg.translate(getCtx(),"PayAmt")).append("=").append(getPayAmt()) - .append(",").append(Msg.translate(getCtx(),"WriteOffAmt")).append("=").append(getWriteOffAmt()); - // - Description - if (getDescription() != null && getDescription().length() > 0) - sb.append(" - ").append(getDescription()); - return sb.toString(); - } // getSummary - - /** - * Get Process Message - * @return clear text error message - */ - public String getProcessMsg() - { - return m_processMsg; - } // getProcessMsg - - /** - * Get Document Owner (Responsible) - * @return AD_User_ID - */ - public int getDoc_User_ID() - { - return getCreatedBy(); - } // getDoc_User_ID - - /** - * Get Document Approval Amount - * @return amount payment(AP) or write-off(AR) - */ - public BigDecimal getApprovalAmt() - { - if (isReceipt()) - return getWriteOffAmt(); - return getPayAmt(); - } // getApprovalAmt - -} // MPayment + boolean reconciled = false; // getC_BankStatementLine_ID() == 0; + + // Create Reversal + MPayment reversal = new MPayment (getCtx(), 0, get_TrxName()); + copyValues(this, reversal); + reversal.setClientOrg(this); + reversal.setC_Order_ID(0); + reversal.setC_Invoice_ID(0); + reversal.setDateAcct(dateAcct); + // + reversal.setDocumentNo(getDocumentNo() + REVERSE_INDICATOR); // indicate reversals + reversal.setDocStatus(DOCSTATUS_Drafted); + reversal.setDocAction(DOCACTION_Complete); + // + reversal.setPayAmt(getPayAmt().negate()); + reversal.setDiscountAmt(getDiscountAmt().negate()); + reversal.setWriteOffAmt(getWriteOffAmt().negate()); + reversal.setOverUnderAmt(getOverUnderAmt().negate()); + // + reversal.setIsAllocated(true); + reversal.setIsReconciled(reconciled); // to put on bank statement + reversal.setIsOnline(false); + reversal.setIsApproved(true); + reversal.setR_PnRef(null); + reversal.setR_Result(null); + reversal.setR_RespMsg(null); + reversal.setR_AuthCode(null); + reversal.setR_Info(null); + reversal.setProcessing(false); + reversal.setOProcessing("N"); + reversal.setProcessed(false); + reversal.setPosted(false); + reversal.setDescription(getDescription()); + reversal.addDescription("{->" + getDocumentNo() + ")"); + reversal.save(get_TrxName()); + // Post Reversal + if (!reversal.processIt(DocAction.ACTION_Complete)) + { + m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); + return false; + } + reversal.closeIt(); + reversal.setDocStatus(DOCSTATUS_Reversed); + reversal.setDocAction(DOCACTION_None); + reversal.save(get_TrxName()); + + // Unlink & De-Allocate + deAllocate(); + setIsReconciled (reconciled); + setIsAllocated (true); // the allocation below is overwritten + // Set Status + addDescription("(" + reversal.getDocumentNo() + "<-)"); + setDocStatus(DOCSTATUS_Reversed); + setDocAction(DOCACTION_None); + setProcessed(true); + + // Create automatic Allocation + MAllocationHdr alloc = new MAllocationHdr (getCtx(), false, + getDateTrx(), getC_Currency_ID(), + Msg.translate(getCtx(), "C_Payment_ID") + ": " + reversal.getDocumentNo(), get_TrxName()); + alloc.setAD_Org_ID(getAD_Org_ID()); + if (!alloc.save()) + log.warning("Automatic allocation - hdr not saved"); + else + { + // Original Allocation + MAllocationLine aLine = new MAllocationLine (alloc, getPayAmt(true), + Env.ZERO, Env.ZERO, Env.ZERO); + aLine.setDocInfo(getC_BPartner_ID(), 0, 0); + aLine.setPaymentInfo(getC_Payment_ID(), 0); + if (!aLine.save(get_TrxName())) + log.warning("Automatic allocation - line not saved"); + // Reversal Allocation + aLine = new MAllocationLine (alloc, reversal.getPayAmt(true), + Env.ZERO, Env.ZERO, Env.ZERO); + aLine.setDocInfo(reversal.getC_BPartner_ID(), 0, 0); + aLine.setPaymentInfo(reversal.getC_Payment_ID(), 0); + if (!aLine.save(get_TrxName())) + log.warning("Automatic allocation - reversal line not saved"); + } + alloc.processIt(DocAction.ACTION_Complete); + alloc.save(get_TrxName()); + // + StringBuffer info = new StringBuffer (reversal.getDocumentNo()); + info.append(" - @C_AllocationHdr_ID@: ").append(alloc.getDocumentNo()); + + // Update BPartner + if (getC_BPartner_ID() != 0) + { + MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); + bp.setTotalOpenBalance(); + bp.save(get_TrxName()); + } + + m_processMsg = info.toString(); + return true; + } // reverseCorrectionIt + + /** + * Get Bank Statement Line of payment or 0 + * @return id or 0 + */ + private int getC_BankStatementLine_ID() + { + String sql = "SELECT C_BankStatementLine_ID FROM C_BankStatementLine WHERE C_Payment_ID=?"; + int id = DB.getSQLValue(get_TrxName(), sql, getC_Payment_ID()); + if (id < 0) + return 0; + return id; + } // getC_BankStatementLine_ID + + /** + * Reverse Accrual - none + * @return true if success + */ + public boolean reverseAccrualIt() + { + log.info(toString()); + return false; + } // reverseAccrualIt + + /** + * Re-activate + * @return true if success + */ + public boolean reActivateIt() + { + log.info(toString()); + if (reverseCorrectIt()) + return true; + return false; + } // reActivateIt + + /** + * String Representation + * @return info + */ + public String toString () + { + StringBuffer sb = new StringBuffer ("MPayment["); + sb.append(get_ID()).append("-").append(getDocumentNo()) + .append(",Receipt=").append(isReceipt()) + .append(",PayAmt=").append(getPayAmt()) + .append(",Discount=").append(getDiscountAmt()) + .append(",WriteOff=").append(getWriteOffAmt()) + .append(",OverUnder=").append(getOverUnderAmt()); + return sb.toString (); + } // toString + + /** + * Get Document Info + * @return document info (untranslated) + */ + public String getDocumentInfo() + { + MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + return dt.getName() + " " + getDocumentNo(); + } // getDocumentInfo + + /** + * Create PDF + * @return File or null + */ + public File createPDF () + { + try + { + File temp = File.createTempFile(get_TableName()+get_ID()+"_", ".pdf"); + return createPDF (temp); + } + catch (Exception e) + { + log.severe("Could not create PDF - " + e.getMessage()); + } + return null; + } // getPDF + + /** + * Create PDF file + * @param file output file + * @return file if success + */ + public File createPDF (File file) + { + // ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.PAYMENT, getC_Payment_ID()); + // if (re == null) + return null; + // return re.getPDF(file); + } // createPDF + + + /************************************************************************* + * Get Summary + * @return Summary of Document + */ + public String getSummary() + { + StringBuffer sb = new StringBuffer(); + sb.append(getDocumentNo()); + // : Total Lines = 123.00 (#1) + sb.append(": ") + .append(Msg.translate(getCtx(),"PayAmt")).append("=").append(getPayAmt()) + .append(",").append(Msg.translate(getCtx(),"WriteOffAmt")).append("=").append(getWriteOffAmt()); + // - Description + if (getDescription() != null && getDescription().length() > 0) + sb.append(" - ").append(getDescription()); + return sb.toString(); + } // getSummary + + /** + * Get Process Message + * @return clear text error message + */ + public String getProcessMsg() + { + return m_processMsg; + } // getProcessMsg + + /** + * Get Document Owner (Responsible) + * @return AD_User_ID + */ + public int getDoc_User_ID() + { + return getCreatedBy(); + } // getDoc_User_ID + + /** + * Get Document Approval Amount + * @return amount payment(AP) or write-off(AR) + */ + public BigDecimal getApprovalAmt() + { + if (isReceipt()) + return getWriteOffAmt(); + return getPayAmt(); + } // getApprovalAmt + +} // MPayment diff --git a/base/src/org/compiere/model/MPaymentValidate.java b/base/src/org/compiere/model/MPaymentValidate.java index 4c37123f32..86e40998a6 100644 --- a/base/src/org/compiere/model/MPaymentValidate.java +++ b/base/src/org/compiere/model/MPaymentValidate.java @@ -3,436 +3,438 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.util.*; -import org.compiere.util.*; - - -/** - * Payment Validion Routines - * - * @author Jorg Janke - * @version $Id: MPaymentValidate.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ - */ -public class MPaymentValidate -{ - /** Static Logger */ - private static CLogger s_log = CLogger.getCLogger (MPaymentValidate.class); - - - /** - * Is this a valid Credit Card Exp Date? - * @param mmyy Exp in form of mmyy - * @return "" or Error AD_Message - */ - public static String validateCreditCardExp (String mmyy) - { - String exp = checkNumeric(mmyy); - if (exp.length() != 4) - return "CreditCardExpFormat"; - // - String mmStr = exp.substring(0,2); - String yyStr = exp.substring(2,4); - // - int mm = 0; - int yy = 0; - try - { - mm = Integer.parseInt(mmStr); - yy = Integer.parseInt(yyStr); - } - catch (Exception e) - { - return "CreditCardExpFormat"; - } - return validateCreditCardExp(mm,yy); - } // validateCreditCardExp - - /** - * Return Month of Exp - * @param mmyy Exp in form of mmyy - * @return month - */ - public static int getCreditCardExpMM (String mmyy) - { - String mmStr = mmyy.substring(0,2); - int mm = 0; - try - { - mm = Integer.parseInt(mmStr); - } - catch (Exception e) - { - } - return mm; - } // getCreditCardExpMM - - /** - * Return Year of Exp - * @param mmyy Exp in form of mmyy - * @return year - */ - public static int getCreditCardExpYY (String mmyy) - { - String yyStr = mmyy.substring(2); - int yy = 0; - try - { - yy = Integer.parseInt(yyStr); - } - catch (Exception e) - { - } - return yy; - } // getCreditCardExpYY - - /** - * Is this a valid Credit Card Exp Date? - * @param mm month - * @param yy year - * @return "" or Error AD_Message - */ - public static String validateCreditCardExp (int mm, int yy) - { - if (mm < 1 || mm > 12) - return "CreditCardExpMonth"; - // if (yy < 0 || yy > EXP_YEAR) - // return "CreditCardExpYear"; - - // Today's date - Calendar cal = Calendar.getInstance(); - int year = cal.get(Calendar.YEAR) - 2000; // two digits - int month = cal.get(Calendar.MONTH) + 1; // zero based - // - if (yy < year) - return "CreditCardExpired"; - else if (yy == year && mm < month) - return "CreditCardExpired"; - return ""; - } // validateCreditCardExp - - - /** - * Validate Credit Card Number. - * - Based on LUHN formula - * @param creditCardNumber credit card number - * @return "" or Error AD_Message - */ - public static String validateCreditCardNumber (String creditCardNumber) - { - if (creditCardNumber == null || creditCardNumber.length() == 0) - return "CreditCardNumberError"; - - /** - * 1: Double the value of alternate digits beginning with - * the first right-hand digit (low order). - * 2: Add the individual digits comprising the products - * obtained in step 1 to each of the unaffected digits - * in the original number. - * 3: Subtract the total obtained in step 2 from the next higher - * number ending in 0 [this in the equivalent of calculating - * the "tens complement" of the low order digit (unit digit) - * of the total]. - * If the total obtained in step 2 is a number ending in zero - * (30, 40 etc.), the check digit is 0. - * Example: - * Account number: 4992 73 9871 6 - * - * 4 9 9 2 7 3 9 8 7 1 6 - * x2 x2 x2 x2 x2 - * ------------------------------- - * 4 18 9 4 7 6 9 16 7 2 6 - * - * 4 + 1 + 8 + 9 + 4 + 7 + 6 + 9 + 1 + 6 + 7 + 2 + 6 = 70 - * 70 % 10 = 0 - */ - - // Clean up number - String ccNumber1 = checkNumeric(creditCardNumber); - int ccLength = ccNumber1.length(); - // Reverse string - StringBuffer buf = new StringBuffer(); - for (int i = ccLength; i != 0; i--) - buf.append(ccNumber1.charAt(i-1)); - String ccNumber = buf.toString(); - - int sum = 0; - for (int i = 0; i < ccLength; i++) - { - int digit = Character.getNumericValue(ccNumber.charAt(i)); - if (i % 2 == 1) - { - digit *= 2; - if (digit > 9) - digit -= 9; - } - sum += digit; - } - if (sum % 10 == 0) - return ""; - - s_log.fine("validateCreditCardNumber - " + creditCardNumber + " -> " - + ccNumber + ", Luhn=" + sum); - return "CreditCardNumberError"; - } // validateCreditCardNumber - - /** - * Validate Credit Card Number. - * - Check Card Type and Length - * @param creditCardNumber CC Number - * @param creditCardType CC Type - * @return "" or Error AD_Message - */ - public static String validateCreditCardNumber (String creditCardNumber, String creditCardType) - { - if (creditCardNumber == null || creditCardType == null) - return "CreditCardNumberError"; - - // http://www.beachnet.com/~hstiles/cardtype.html - // http://staff.semel.fi/~kribe/document/luhn.htm - + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.util.*; +import org.compiere.util.*; + + +/** + * Payment Validion Routines + * + * @author Jorg Janke + * @version $Id: MPaymentValidate.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ + */ +public class MPaymentValidate +{ + /** Static Logger */ + private static CLogger s_log = CLogger.getCLogger (MPaymentValidate.class); + + + /** + * Is this a valid Credit Card Exp Date? + * @param mmyy Exp in form of mmyy + * @return "" or Error AD_Message + */ + public static String validateCreditCardExp (String mmyy) + { + String exp = checkNumeric(mmyy); + if (exp.length() != 4) + return "CreditCardExpFormat"; + // + String mmStr = exp.substring(0,2); + String yyStr = exp.substring(2,4); + // + int mm = 0; + int yy = 0; + try + { + mm = Integer.parseInt(mmStr); + yy = Integer.parseInt(yyStr); + } + catch (Exception e) + { + return "CreditCardExpFormat"; + } + return validateCreditCardExp(mm,yy); + } // validateCreditCardExp + + /** + * Return Month of Exp + * @param mmyy Exp in form of mmyy + * @return month + */ + public static int getCreditCardExpMM (String mmyy) + { + String mmStr = mmyy.substring(0,2); + int mm = 0; + try + { + mm = Integer.parseInt(mmStr); + } + catch (Exception e) + { + } + return mm; + } // getCreditCardExpMM + + /** + * Return Year of Exp + * @param mmyy Exp in form of mmyy + * @return year + */ + public static int getCreditCardExpYY (String mmyy) + { + String yyStr = mmyy.substring(2); + int yy = 0; + try + { + yy = Integer.parseInt(yyStr); + } + catch (Exception e) + { + } + return yy; + } // getCreditCardExpYY + + /** + * Is this a valid Credit Card Exp Date? + * @param mm month + * @param yy year + * @return "" or Error AD_Message + */ + public static String validateCreditCardExp (int mm, int yy) + { + if (mm < 1 || mm > 12) + return "CreditCardExpMonth"; + // if (yy < 0 || yy > EXP_YEAR) + // return "CreditCardExpYear"; + + // Today's date + Calendar cal = Calendar.getInstance(); + int year = cal.get(Calendar.YEAR) - 2000; // two digits + int month = cal.get(Calendar.MONTH) + 1; // zero based + // + if (yy < year) + return "CreditCardExpired"; + else if (yy == year && mm < month) + return "CreditCardExpired"; + return ""; + } // validateCreditCardExp + + + /** + * Validate Credit Card Number. + * - Based on LUHN formula + * @param creditCardNumber credit card number + * @return "" or Error AD_Message + */ + public static String validateCreditCardNumber (String creditCardNumber) + { + if (creditCardNumber == null || creditCardNumber.length() == 0) + return "CreditCardNumberError"; + + /** + * 1: Double the value of alternate digits beginning with + * the first right-hand digit (low order). + * 2: Add the individual digits comprising the products + * obtained in step 1 to each of the unaffected digits + * in the original number. + * 3: Subtract the total obtained in step 2 from the next higher + * number ending in 0 [this in the equivalent of calculating + * the "tens complement" of the low order digit (unit digit) + * of the total]. + * If the total obtained in step 2 is a number ending in zero + * (30, 40 etc.), the check digit is 0. + * Example: + * Account number: 4992 73 9871 6 + * + * 4 9 9 2 7 3 9 8 7 1 6 + * x2 x2 x2 x2 x2 + * ------------------------------- + * 4 18 9 4 7 6 9 16 7 2 6 + * + * 4 + 1 + 8 + 9 + 4 + 7 + 6 + 9 + 1 + 6 + 7 + 2 + 6 = 70 + * 70 % 10 = 0 + */ + + // Clean up number + String ccNumber1 = checkNumeric(creditCardNumber); + int ccLength = ccNumber1.length(); + // Reverse string + StringBuffer buf = new StringBuffer(); + for (int i = ccLength; i != 0; i--) + buf.append(ccNumber1.charAt(i-1)); + String ccNumber = buf.toString(); + + int sum = 0; + for (int i = 0; i < ccLength; i++) + { + int digit = Character.getNumericValue(ccNumber.charAt(i)); + if (i % 2 == 1) + { + digit *= 2; + if (digit > 9) + digit -= 9; + } + sum += digit; + } + if (sum % 10 == 0) + return ""; + + s_log.fine("validateCreditCardNumber - " + creditCardNumber + " -> " + + ccNumber + ", Luhn=" + sum); + return "CreditCardNumberError"; + } // validateCreditCardNumber + + /** + * Validate Credit Card Number. + * - Check Card Type and Length + * @param creditCardNumber CC Number + * @param creditCardType CC Type + * @return "" or Error AD_Message + */ + public static String validateCreditCardNumber (String creditCardNumber, String creditCardType) + { + if (creditCardNumber == null || creditCardType == null) + return "CreditCardNumberError"; + + // http://www.beachnet.com/~hstiles/cardtype.html + // http://staff.semel.fi/~kribe/document/luhn.htm + String ccStartList = ""; // comma separated list of starting numbers String ccLengthList = ""; // comma separated list of lengths // - if (creditCardType.equals(MPayment.CREDITCARDTYPE_MasterCard)) + if (creditCardType.equals(X_C_Payment.CREDITCARDTYPE_MasterCard)) { ccStartList = "51,52,53,54,55"; ccLengthList = "16"; } - else if (creditCardType.equals(MPayment.CREDITCARDTYPE_Visa)) + else if (creditCardType.equals(X_C_Payment.CREDITCARDTYPE_Visa)) { ccStartList = "4"; ccLengthList = "13,16"; } - else if (creditCardType.equals(MPayment.CREDITCARDTYPE_Amex)) + else if (creditCardType.equals(X_C_Payment.CREDITCARDTYPE_Amex)) { ccStartList = "34,37"; ccLengthList = "15"; } - else if (creditCardType.equals(MPayment.CREDITCARDTYPE_Discover)) + else if (creditCardType.equals(X_C_Payment.CREDITCARDTYPE_Discover)) { ccStartList = "6011"; ccLengthList = "16"; } - else if (creditCardType.equals(MPayment.CREDITCARDTYPE_Diners)) + else if (creditCardType.equals(X_C_Payment.CREDITCARDTYPE_Diners)) { ccStartList = "300,301,302,303,304,305,36,38"; ccLengthList = "14"; - } - else - { - // enRouteCard - ccStartList = "2014,2149"; - ccLengthList = "15"; - // JCBCard - ccStartList += ",3088,3096,3112,3158,3337,3528"; - ccLengthList += ",16"; - // JCBCard - ccStartList += ",2131,1800"; - ccLengthList += ",15"; - } - - // Clean up number - String ccNumber = checkNumeric(creditCardNumber); - - /** - * Check Length - */ - int ccLength = ccNumber.length(); - boolean ccLengthOK = false; - StringTokenizer st = new StringTokenizer(ccLengthList, ",", false); - while (st.hasMoreTokens() && !ccLengthOK) - { - int l = Integer.parseInt(st.nextToken()); - if (ccLength == l) - ccLengthOK = true; - } - if (!ccLengthOK) - { - s_log.fine("validateCreditCardNumber Length=" - + ccLength + " <> " + ccLengthList); - return "CreditCardNumberError"; - } - - /** - * Check Start Digits - */ - boolean ccIdentified = false; - st = new StringTokenizer(ccStartList, ",", false); - while (st.hasMoreTokens() && !ccIdentified) - { - if (ccNumber.startsWith(st.nextToken())) - ccIdentified = true; - } - if (!ccIdentified) - s_log.fine("validateCreditCardNumber Type=" - + creditCardType + " <> " + ccStartList); - - // - String check = validateCreditCardNumber(ccNumber); - if (check.length() != 0) - return check; - if (!ccIdentified) - return "CreditCardNumberProblem?"; - return ""; - } // validateCreditCardNumber - - - /** - * Validate Validation Code - * @param creditCardVV CC Verification Code - * @return "" or Error AD_Message - */ - public static String validateCreditCardVV (String creditCardVV) - { - if (creditCardVV == null) - return ""; - int length = checkNumeric(creditCardVV).length(); - if (length == 3 || length == 4) - return ""; - try - { - Integer.parseInt (creditCardVV); - return ""; - } - catch (NumberFormatException ex) - { - s_log.fine("validateCreditCardVV - " + ex); - } - s_log.fine("validateCreditCardVV - length=" + length); - return "CreditCardVVError"; - } // validateCreditCardVV - - /** - * Validate Validation Code - * @param creditCardVV CC Verification Code - * @param creditCardType CC Type see CC_ - * @return "" or Error AD_Message - */ - public static String validateCreditCardVV (String creditCardVV, String creditCardType) - { - // no data - if (creditCardVV == null || creditCardVV.length() == 0 - || creditCardType == null || creditCardType.length() == 0) - return ""; - + } + else + { + // enRouteCard + ccStartList = "2014,2149"; + ccLengthList = "15"; + // JCBCard + ccStartList += ",3088,3096,3112,3158,3337,3528"; + ccLengthList += ",16"; + // JCBCard + ccStartList += ",2131,1800"; + ccLengthList += ",15"; + } + + // Clean up number + String ccNumber = checkNumeric(creditCardNumber); + + /** + * Check Length + */ + int ccLength = ccNumber.length(); + boolean ccLengthOK = false; + StringTokenizer st = new StringTokenizer(ccLengthList, ",", false); + while (st.hasMoreTokens() && !ccLengthOK) + { + int l = Integer.parseInt(st.nextToken()); + if (ccLength == l) + ccLengthOK = true; + } + if (!ccLengthOK) + { + s_log.fine("validateCreditCardNumber Length=" + + ccLength + " <> " + ccLengthList); + return "CreditCardNumberError"; + } + + /** + * Check Start Digits + */ + boolean ccIdentified = false; + st = new StringTokenizer(ccStartList, ",", false); + while (st.hasMoreTokens() && !ccIdentified) + { + if (ccNumber.startsWith(st.nextToken())) + ccIdentified = true; + } + if (!ccIdentified) + s_log.fine("validateCreditCardNumber Type=" + + creditCardType + " <> " + ccStartList); + + // + String check = validateCreditCardNumber(ccNumber); + if (check.length() != 0) + return check; + if (!ccIdentified) + return "CreditCardNumberProblem?"; + return ""; + } // validateCreditCardNumber + + + /** + * Validate Validation Code + * @param creditCardVV CC Verification Code + * @return "" or Error AD_Message + */ + public static String validateCreditCardVV (String creditCardVV) + { + if (creditCardVV == null) + return ""; + int length = checkNumeric(creditCardVV).length(); + if (length == 3 || length == 4) + return ""; + try + { + Integer.parseInt (creditCardVV); + return ""; + } + catch (NumberFormatException ex) + { + s_log.fine("validateCreditCardVV - " + ex); + } + s_log.fine("validateCreditCardVV - length=" + length); + return "CreditCardVVError"; + } // validateCreditCardVV + + /** + * Validate Validation Code + * @param creditCardVV CC Verification Code + * @param creditCardType CC Type see CC_ + * @return "" or Error AD_Message + */ + public static String validateCreditCardVV (String creditCardVV, String creditCardType) + { + // no data + if (creditCardVV == null || creditCardVV.length() == 0 + || creditCardType == null || creditCardType.length() == 0) + return ""; + int length = checkNumeric(creditCardVV).length(); // Amex = 4 digits - if (creditCardType.equals(MPayment.CREDITCARDTYPE_Amex)) + if (creditCardType.equals(X_C_Payment.CREDITCARDTYPE_Amex)) { if (length == 4) { - try - { - Integer.parseInt (creditCardVV); - return ""; - } - catch (NumberFormatException ex) - { - s_log.fine("validateCreditCardVV - " + ex); - } - } - s_log.fine("validateCreditCardVV(4) CC=" + creditCardType + ", length=" + length); + try + { + Integer.parseInt (creditCardVV); + return ""; + } + catch (NumberFormatException ex) + { + s_log.fine("validateCreditCardVV - " + ex); + } + } + s_log.fine("validateCreditCardVV(4) CC=" + creditCardType + ", length=" + length); return "CreditCardVVError"; } // Visa & MasterCard - 3 digits - if (creditCardType.equals(MPayment.CREDITCARDTYPE_Visa) - || creditCardType.equals(MPayment.CREDITCARDTYPE_MasterCard)) + if (creditCardType.equals(X_C_Payment.CREDITCARDTYPE_Visa) + || creditCardType.equals(X_C_Payment.CREDITCARDTYPE_MasterCard)) { if (length == 3) { - try - { - Integer.parseInt (creditCardVV); - return ""; - } - catch (NumberFormatException ex) - { - s_log.fine("validateCreditCardVV - " + ex); - } - } - s_log.fine("validateCreditCardVV(3) CC=" + creditCardType + ", length=" + length); - return "CreditCardVVError"; - } - - // Other - return ""; - } // validateCreditCardVV - - - /************************************************************************** - * Validate Routing Number - * @param routingNo Routing No - * @return "" or Error AD_Message - */ - public static String validateRoutingNo (String routingNo) - { - int length = checkNumeric(routingNo).length(); + try + { + Integer.parseInt (creditCardVV); + return ""; + } + catch (NumberFormatException ex) + { + s_log.fine("validateCreditCardVV - " + ex); + } + } + s_log.fine("validateCreditCardVV(3) CC=" + creditCardType + ", length=" + length); + return "CreditCardVVError"; + } + + // Other + return ""; + } // validateCreditCardVV + + + /************************************************************************** + * Validate Routing Number + * @param routingNo Routing No + * @return "" or Error AD_Message + */ + public static String validateRoutingNo (String routingNo) + { + int length = checkNumeric(routingNo).length(); // US - length 9 // Germany - length 8 // Japan - 7 - if (length == 7 || length == 8 || length == 9) + // CH - 5 + // Issue: Bank account country + if (length > 0) return ""; return "PaymentBankRoutingNotValid"; } // validateBankRoutingNo - - /** - * Validate Account No - * @param AccountNo AccountNo - * @return "" or Error AD_Message - */ - public static String validateAccountNo (String AccountNo) - { - int length = checkNumeric(AccountNo).length(); - if (length > 0) - return ""; - return "PaymentBankAccountNotValid"; - } // validateBankAccountNo - - /** - * Validate Check No - * @param CheckNo CheckNo - * @return "" or Error AD_Message - */ - public static String validateCheckNo (String CheckNo) - { - int length = checkNumeric(CheckNo).length(); - if (length > 0) - return ""; - return "PaymentBankCheckNotValid"; - } // validateBankCheckNo - - /** - * Check Numeric - * @param data input - * @return the digits of the data - ignore the rest - */ - public static String checkNumeric (String data) - { - if (data == null || data.length() == 0) - return ""; - // Remove all non Digits - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < data.length(); i++) - { - if (Character.isDigit(data.charAt(i))) - sb.append(data.charAt(i)); - } - return sb.toString(); - } // checkNumeric - - -} // MPaymentValidate + + /** + * Validate Account No + * @param AccountNo AccountNo + * @return "" or Error AD_Message + */ + public static String validateAccountNo (String AccountNo) + { + int length = checkNumeric(AccountNo).length(); + if (length > 0) + return ""; + return "PaymentBankAccountNotValid"; + } // validateBankAccountNo + + /** + * Validate Check No + * @param CheckNo CheckNo + * @return "" or Error AD_Message + */ + public static String validateCheckNo (String CheckNo) + { + int length = checkNumeric(CheckNo).length(); + if (length > 0) + return ""; + return "PaymentBankCheckNotValid"; + } // validateBankCheckNo + + /** + * Check Numeric + * @param data input + * @return the digits of the data - ignore the rest + */ + public static String checkNumeric (String data) + { + if (data == null || data.length() == 0) + return ""; + // Remove all non Digits + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < data.length(); i++) + { + if (Character.isDigit(data.charAt(i))) + sb.append(data.charAt(i)); + } + return sb.toString(); + } // checkNumeric + + +} // MPaymentValidate diff --git a/base/src/org/compiere/model/MProduct.java b/base/src/org/compiere/model/MProduct.java index b564b0bef3..fdd79a2289 100644 --- a/base/src/org/compiere/model/MProduct.java +++ b/base/src/org/compiere/model/MProduct.java @@ -3,686 +3,685 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.math.*; -import java.sql.*; -import java.util.*; -import java.util.logging.*; -import org.compiere.util.*; - -/** - * Product Model - * - * @author Jorg Janke - * @version $Id: MProduct.java,v 1.5 2006/07/30 00:51:05 jjanke Exp $ - */ -public class MProduct extends X_M_Product -{ - /** - * Get MProduct from Cache - * @param ctx context - * @param M_Product_ID id - * @return MProduct - */ - public static MProduct get (Properties ctx, int M_Product_ID) - { - Integer key = new Integer (M_Product_ID); - MProduct retValue = (MProduct) s_cache.get (key); - if (retValue != null) - return retValue; - retValue = new MProduct (ctx, M_Product_ID, null); - if (retValue.get_ID () != 0) - s_cache.put (key, retValue); - return retValue; - } // get - - /** - * Get MProduct from Cache - * @param ctx context - * @param whereClause sql where clause - * @param trxName trx - * @return MProduct - */ - public static MProduct[] get (Properties ctx, String whereClause, String trxName) - { - String sql = "SELECT * FROM M_Product"; - if (whereClause != null && whereClause.length() > 0) - sql += " WHERE AD_Client_ID=? AND " + whereClause; - ArrayList list = new ArrayList(); - int AD_Client_ID = Env.getAD_Client_ID(ctx); - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, trxName); - pstmt.setInt(1, AD_Client_ID); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - list.add (new MProduct (ctx, rs, trxName)); - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - s_log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - MProduct[] retValue = new MProduct[list.size ()]; - list.toArray (retValue); - return retValue; - } // get - - - /** - * Is Product Stocked - * @param ctx context - * @param M_Product_ID id - * @return true if found and stocked - false otherwise + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.math.*; +import java.sql.*; +import java.util.*; +import java.util.logging.*; +import org.compiere.util.*; + +/** + * Product Model + * + * @author Jorg Janke + * @version $Id: MProduct.java,v 1.5 2006/07/30 00:51:05 jjanke Exp $ + */ +public class MProduct extends X_M_Product +{ + /** + * Get MProduct from Cache + * @param ctx context + * @param M_Product_ID id + * @return MProduct + */ + public static MProduct get (Properties ctx, int M_Product_ID) + { + Integer key = new Integer (M_Product_ID); + MProduct retValue = (MProduct) s_cache.get (key); + if (retValue != null) + return retValue; + retValue = new MProduct (ctx, M_Product_ID, null); + if (retValue.get_ID () != 0) + s_cache.put (key, retValue); + return retValue; + } // get + + /** + * Get MProduct from Cache + * @param ctx context + * @param whereClause sql where clause + * @param trxName trx + * @return MProduct + */ + public static MProduct[] get (Properties ctx, String whereClause, String trxName) + { + String sql = "SELECT * FROM M_Product"; + if (whereClause != null && whereClause.length() > 0) + sql += " WHERE AD_Client_ID=? AND " + whereClause; + ArrayList list = new ArrayList(); + int AD_Client_ID = Env.getAD_Client_ID(ctx); + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, trxName); + pstmt.setInt(1, AD_Client_ID); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + list.add (new MProduct (ctx, rs, trxName)); + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + MProduct[] retValue = new MProduct[list.size ()]; + list.toArray (retValue); + return retValue; + } // get + + + /** + * Is Product Stocked + * @param ctx context + * @param M_Product_ID id + * @return true if found and stocked - false otherwise */ public static boolean isProductStocked (Properties ctx, int M_Product_ID) { - boolean retValue = false; MProduct product = get (ctx, M_Product_ID); return product.isStocked(); } // isProductStocked - - /** Cache */ - private static CCache s_cache = new CCache("M_Product", 40, 5); // 5 minutes - /** Static Logger */ - private static CLogger s_log = CLogger.getCLogger (MProduct.class); - - - /************************************************************************** - * Standard Constructor - * @param ctx context - * @param M_Product_ID id - * @param trxName transaction - */ - public MProduct (Properties ctx, int M_Product_ID, String trxName) - { - super (ctx, M_Product_ID, trxName); - if (M_Product_ID == 0) - { - // setValue (null); - // setName (null); - // setM_Product_Category_ID (0); - // setC_TaxCategory_ID (0); - // setC_UOM_ID (0); - // - setProductType (PRODUCTTYPE_Item); // I - setIsBOM (false); // N - setIsInvoicePrintDetails (false); - setIsPickListPrintDetails (false); - setIsPurchased (true); // Y - setIsSold (true); // Y - setIsStocked (true); // Y - setIsSummary (false); - setIsVerified (false); // N - setIsWebStoreFeatured (false); - setIsSelfService(true); - setIsExcludeAutoDelivery(false); - setProcessing (false); // N - } - } // MProduct - - /** - * Load constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MProduct (Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MProduct - - /** - * Parent Constructor - * @param et parent - */ + + /** Cache */ + private static CCache s_cache = new CCache("M_Product", 40, 5); // 5 minutes + /** Static Logger */ + private static CLogger s_log = CLogger.getCLogger (MProduct.class); + + + /************************************************************************** + * Standard Constructor + * @param ctx context + * @param M_Product_ID id + * @param trxName transaction + */ + public MProduct (Properties ctx, int M_Product_ID, String trxName) + { + super (ctx, M_Product_ID, trxName); + if (M_Product_ID == 0) + { + // setValue (null); + // setName (null); + // setM_Product_Category_ID (0); + // setC_TaxCategory_ID (0); + // setC_UOM_ID (0); + // + setProductType (PRODUCTTYPE_Item); // I + setIsBOM (false); // N + setIsInvoicePrintDetails (false); + setIsPickListPrintDetails (false); + setIsPurchased (true); // Y + setIsSold (true); // Y + setIsStocked (true); // Y + setIsSummary (false); + setIsVerified (false); // N + setIsWebStoreFeatured (false); + setIsSelfService(true); + setIsExcludeAutoDelivery(false); + setProcessing (false); // N + } + } // MProduct + + /** + * Load constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MProduct (Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MProduct + + /** + * Parent Constructor + * @param et parent + */ public MProduct (MExpenseType et) { this (et.getCtx(), 0, et.get_TrxName()); - setProductType(MProduct.PRODUCTTYPE_ExpenseType); + setProductType(X_M_Product.PRODUCTTYPE_ExpenseType); setExpenseType(et); } // MProduct - /** - * Parent Constructor - * @param resource parent - * @param resourceType resource type - */ + /** + * Parent Constructor + * @param resource parent + * @param resourceType resource type + */ public MProduct (MResource resource, MResourceType resourceType) { this (resource.getCtx(), 0, resource.get_TrxName()); - setProductType(MProduct.PRODUCTTYPE_Resource); + setProductType(X_M_Product.PRODUCTTYPE_Resource); setResource(resource); setResource(resourceType); } // MProduct - - /** - * Import Constructor - * @param impP import - */ - public MProduct (X_I_Product impP) - { - this (impP.getCtx(), 0, impP.get_TrxName()); - setClientOrg(impP); - setUpdatedBy(impP.getUpdatedBy()); - // - setValue(impP.getValue()); - setName(impP.getName()); - setDescription(impP.getDescription()); - setDocumentNote(impP.getDocumentNote()); - setHelp(impP.getHelp()); - setUPC(impP.getUPC()); - setSKU(impP.getSKU()); - setC_UOM_ID(impP.getC_UOM_ID()); - setM_Product_Category_ID(impP.getM_Product_Category_ID()); - setProductType(impP.getProductType()); - setImageURL(impP.getImageURL()); - setDescriptionURL(impP.getDescriptionURL()); - } // MProduct - - /** Additional Downloads */ - private MProductDownload[] m_downloads = null; - - /** - * Set Expense Type - * @param parent expense type - * @return true if changed - */ - public boolean setExpenseType (MExpenseType parent) - { - boolean changed = false; - if (!PRODUCTTYPE_ExpenseType.equals(getProductType())) - { - setProductType(PRODUCTTYPE_ExpenseType); - changed = true; - } - if (parent.getS_ExpenseType_ID() != getS_ExpenseType_ID()) - { - setS_ExpenseType_ID(parent.getS_ExpenseType_ID()); - changed = true; - } - if (parent.isActive() != isActive()) - { - setIsActive(parent.isActive()); - changed = true; - } - // - if (!parent.getValue().equals(getValue())) - { - setValue(parent.getValue()); - changed = true; - } - if (!parent.getName().equals(getName())) - { - setName(parent.getName()); - changed = true; - } - if ((parent.getDescription() == null && getDescription() != null) - || (parent.getDescription() != null && !parent.getDescription().equals(getDescription()))) - { - setDescription(parent.getDescription()); - changed = true; - } - if (parent.getC_UOM_ID() != getC_UOM_ID()) - { - setC_UOM_ID(parent.getC_UOM_ID()); - changed = true; - } - if (parent.getM_Product_Category_ID() != getM_Product_Category_ID()) - { - setM_Product_Category_ID(parent.getM_Product_Category_ID()); - changed = true; - } - if (parent.getC_TaxCategory_ID() != getC_TaxCategory_ID()) - { - setC_TaxCategory_ID(parent.getC_TaxCategory_ID()); - changed = true; - } - // - return changed; - } // setExpenseType - - /** - * Set Resource - * @param parent resource - * @return true if changed - */ - public boolean setResource (MResource parent) - { - boolean changed = false; - if (!PRODUCTTYPE_Resource.equals(getProductType())) - { - setProductType(PRODUCTTYPE_Resource); - changed = true; - } - if (parent.getS_Resource_ID() != getS_Resource_ID()) - { - setS_Resource_ID(parent.getS_Resource_ID()); - changed = true; - } - if (parent.isActive() != isActive()) - { - setIsActive(parent.isActive()); - changed = true; - } - // - if (!parent.getValue().equals(getValue())) - { - setValue(parent.getValue()); - changed = true; - } - if (!parent.getName().equals(getName())) - { - setName(parent.getName()); - changed = true; - } - if ((parent.getDescription() == null && getDescription() != null) - || (parent.getDescription() != null && !parent.getDescription().equals(getDescription()))) - { - setDescription(parent.getDescription()); - changed = true; - } - // - return changed; - } // setResource - - /** - * Set Resource Type - * @param parent resource type - * @return true if changed - */ - public boolean setResource (MResourceType parent) - { - boolean changed = false; - if (PRODUCTTYPE_Resource.equals(getProductType())) - { - setProductType(PRODUCTTYPE_Resource); - changed = true; - } - // - if (parent.getC_UOM_ID() != getC_UOM_ID()) - { - setC_UOM_ID(parent.getC_UOM_ID()); - changed = true; - } - if (parent.getM_Product_Category_ID() != getM_Product_Category_ID()) - { - setM_Product_Category_ID(parent.getM_Product_Category_ID()); - changed = true; - } - if (parent.getC_TaxCategory_ID() != getC_TaxCategory_ID()) - { - setC_TaxCategory_ID(parent.getC_TaxCategory_ID()); - changed = true; - } - // - return changed; - } // setResource - - - /** UOM Precision */ - private Integer m_precision = null; - - /** - * Get UOM Standard Precision - * @return UOM Standard Precision - */ - public int getUOMPrecision() - { - if (m_precision == null) - { - int C_UOM_ID = getC_UOM_ID(); - if (C_UOM_ID == 0) - return 0; // EA - m_precision = new Integer (MUOM.getPrecision(getCtx(), C_UOM_ID)); - } - return m_precision.intValue(); - } // getUOMPrecision - - - /** - * Create Asset Group for this product - * @return asset group id - */ - public int getA_Asset_Group_ID() - { - MProductCategory pc = MProductCategory.get(getCtx(), getM_Product_Category_ID()); - return pc.getA_Asset_Group_ID(); - } // getA_Asset_Group_ID - - /** - * Create Asset for this product - * @return true if asset is created - */ - public boolean isCreateAsset() - { - MProductCategory pc = MProductCategory.get(getCtx(), getM_Product_Category_ID()); - return pc.getA_Asset_Group_ID() != 0; - } // isCreated - - /** - * Get Attribute Set - * @return set or null - */ - public MAttributeSet getAttributeSet() - { - if (getM_AttributeSet_ID() != 0) - return MAttributeSet.get(getCtx(), getM_AttributeSet_ID()); - return null; - } // getAttributeSet - - /** - * Has the Product Instance Attribute - * @return true if instance attributes - */ - public boolean isInstanceAttribute() - { - if (getM_AttributeSet_ID() == 0) - return false; - MAttributeSet mas = MAttributeSet.get(getCtx(), getM_AttributeSet_ID()); - return mas.isInstanceAttribute(); - } // isInstanceAttribute - - /** - * Create One Asset Per UOM - * @return individual asset - */ - public boolean isOneAssetPerUOM() - { - MProductCategory pc = MProductCategory.get(getCtx(), getM_Product_Category_ID()); - if (pc.getA_Asset_Group_ID() == 0) - return false; - MAssetGroup ag = MAssetGroup.get(getCtx(), pc.getA_Asset_Group_ID()); - return ag.isOneAssetPerUOM(); - } // isOneAssetPerUOM - - /** - * Product is Item - * @return true if item - */ - public boolean isItem() - { - return PRODUCTTYPE_Item.equals(getProductType()); - } // isItem - - /** - * Product is an Item and Stocked - * @return true if stocked and item - */ - public boolean isStocked () - { - return super.isStocked() && isItem(); - } // isStocked - - /** - * Is Service - * @return true if service (resource, online) - */ - public boolean isService() - { - // PRODUCTTYPE_Service, PRODUCTTYPE_Resource, PRODUCTTYPE_Online - return !isItem(); // - } // isService - - /** - * Get UOM Symbol - * @return UOM Symbol - */ - public String getUOMSymbol() - { - int C_UOM_ID = getC_UOM_ID(); - if (C_UOM_ID == 0) - return ""; - return MUOM.get(getCtx(), C_UOM_ID).getUOMSymbol(); - } // getUOMSymbol - - /** - * Get Active(!) Product Downloads - * @param requery requery - * @return array of downloads - */ - public MProductDownload[] getProductDownloads (boolean requery) - { - if (m_downloads != null && !requery) - return m_downloads; - // - ArrayList list = new ArrayList(); - String sql = "SELECT * FROM M_ProductDownload " - + "WHERE M_Product_ID=? AND IsActive='Y' ORDER BY Name"; - // - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, get_TrxName()); - pstmt.setInt (1, getM_Product_ID()); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - list.add (new MProductDownload (getCtx(), rs, get_TrxName())); - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - log.log (Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - // - m_downloads = new MProductDownload[list.size ()]; - list.toArray (m_downloads); - return m_downloads; - } // getProductDownloads - - /** - * Does the product have downloads - * @return true if downloads exists - */ - public boolean hasDownloads() - { - getProductDownloads(false); - return m_downloads != null && m_downloads.length > 0; - } // hasDownloads - - /** - * String Representation - * @return info - */ - public String toString() - { - StringBuffer sb = new StringBuffer("MProduct["); - sb.append(get_ID()).append("-").append(getValue()) - .append("]"); - return sb.toString(); - } // toString - - - /** - * Before Save - * @param newRecord new - * @return true - */ - protected boolean beforeSave (boolean newRecord) - { - // Check Storage - if (!newRecord && // - ((is_ValueChanged("IsActive") && !isActive()) // now not active - || (is_ValueChanged("IsStocked") && !isStocked()) // now not stocked - || (is_ValueChanged("ProductType") // from Item - && PRODUCTTYPE_Item.equals(get_ValueOld("ProductType"))))) - { - MStorage[] storages = MStorage.getOfProduct(getCtx(), get_ID(), get_TrxName()); - BigDecimal OnHand = Env.ZERO; - BigDecimal Ordered = Env.ZERO; - BigDecimal Reserved = Env.ZERO; - for (int i = 0; i < storages.length; i++) - { - OnHand = OnHand.add(storages[i].getQtyOnHand()); - Ordered = OnHand.add(storages[i].getQtyOrdered()); - Reserved = OnHand.add(storages[i].getQtyReserved()); - } - String errMsg = ""; - if (OnHand.signum() != 0) - errMsg = "@QtyOnHand@ = " + OnHand; - if (Ordered.signum() != 0) - errMsg += " - @QtyOrdered@ = " + Ordered; - if (Reserved.signum() != 0) - errMsg += " - @QtyReserved@" + Reserved; - if (errMsg.length() > 0) - { - log.saveError("Error", Msg.parseTranslation(getCtx(), errMsg)); - return false; - } - } // storage - - // Reset Stocked if not Item - if (isStocked() && !PRODUCTTYPE_Item.equals(getProductType())) - setIsStocked(false); - - // UOM reset - if (m_precision != null && is_ValueChanged("C_UOM_ID")) - m_precision = null; - - return true; - } // beforeSave - - /** - * After Save - * @param newRecord new - * @param success success - * @return success - */ - protected boolean afterSave (boolean newRecord, boolean success) - { - if (!success) - return success; - - // Value/Name change in Account - if (!newRecord && (is_ValueChanged("Value") || is_ValueChanged("Name"))) - MAccount.updateValueDescription(getCtx(), "M_Product_ID=" + getM_Product_ID(), get_TrxName()); - - // Name/Description Change in Asset MAsset.setValueNameDescription - if (!newRecord && (is_ValueChanged("Name") || is_ValueChanged("Description"))) - { - String sql = "UPDATE A_Asset a " - + "SET (Name, Description)=" - + "(SELECT SUBSTR(bp.Name || ' - ' || p.Name,1,60), p.Description " - + "FROM M_Product p, C_BPartner bp " - + "WHERE p.M_Product_ID=a.M_Product_ID AND bp.C_BPartner_ID=a.C_BPartner_ID) " - + "WHERE IsActive='Y'" - // + " AND GuaranteeDate > SysDate" - + " AND M_Product_ID=" + getM_Product_ID(); - int no = DB.executeUpdate(sql, get_TrxName()); - log.fine("Asset Description updated #" + no); - } - - // New - Acct, Tree, Old Costing - if (newRecord) + + /** + * Import Constructor + * @param impP import + */ + public MProduct (X_I_Product impP) + { + this (impP.getCtx(), 0, impP.get_TrxName()); + setClientOrg(impP); + setUpdatedBy(impP.getUpdatedBy()); + // + setValue(impP.getValue()); + setName(impP.getName()); + setDescription(impP.getDescription()); + setDocumentNote(impP.getDocumentNote()); + setHelp(impP.getHelp()); + setUPC(impP.getUPC()); + setSKU(impP.getSKU()); + setC_UOM_ID(impP.getC_UOM_ID()); + setM_Product_Category_ID(impP.getM_Product_Category_ID()); + setProductType(impP.getProductType()); + setImageURL(impP.getImageURL()); + setDescriptionURL(impP.getDescriptionURL()); + } // MProduct + + /** Additional Downloads */ + private MProductDownload[] m_downloads = null; + + /** + * Set Expense Type + * @param parent expense type + * @return true if changed + */ + public boolean setExpenseType (MExpenseType parent) + { + boolean changed = false; + if (!PRODUCTTYPE_ExpenseType.equals(getProductType())) + { + setProductType(PRODUCTTYPE_ExpenseType); + changed = true; + } + if (parent.getS_ExpenseType_ID() != getS_ExpenseType_ID()) + { + setS_ExpenseType_ID(parent.getS_ExpenseType_ID()); + changed = true; + } + if (parent.isActive() != isActive()) + { + setIsActive(parent.isActive()); + changed = true; + } + // + if (!parent.getValue().equals(getValue())) + { + setValue(parent.getValue()); + changed = true; + } + if (!parent.getName().equals(getName())) + { + setName(parent.getName()); + changed = true; + } + if ((parent.getDescription() == null && getDescription() != null) + || (parent.getDescription() != null && !parent.getDescription().equals(getDescription()))) + { + setDescription(parent.getDescription()); + changed = true; + } + if (parent.getC_UOM_ID() != getC_UOM_ID()) + { + setC_UOM_ID(parent.getC_UOM_ID()); + changed = true; + } + if (parent.getM_Product_Category_ID() != getM_Product_Category_ID()) + { + setM_Product_Category_ID(parent.getM_Product_Category_ID()); + changed = true; + } + if (parent.getC_TaxCategory_ID() != getC_TaxCategory_ID()) + { + setC_TaxCategory_ID(parent.getC_TaxCategory_ID()); + changed = true; + } + // + return changed; + } // setExpenseType + + /** + * Set Resource + * @param parent resource + * @return true if changed + */ + public boolean setResource (MResource parent) + { + boolean changed = false; + if (!PRODUCTTYPE_Resource.equals(getProductType())) + { + setProductType(PRODUCTTYPE_Resource); + changed = true; + } + if (parent.getS_Resource_ID() != getS_Resource_ID()) + { + setS_Resource_ID(parent.getS_Resource_ID()); + changed = true; + } + if (parent.isActive() != isActive()) + { + setIsActive(parent.isActive()); + changed = true; + } + // + if (!parent.getValue().equals(getValue())) + { + setValue(parent.getValue()); + changed = true; + } + if (!parent.getName().equals(getName())) + { + setName(parent.getName()); + changed = true; + } + if ((parent.getDescription() == null && getDescription() != null) + || (parent.getDescription() != null && !parent.getDescription().equals(getDescription()))) + { + setDescription(parent.getDescription()); + changed = true; + } + // + return changed; + } // setResource + + /** + * Set Resource Type + * @param parent resource type + * @return true if changed + */ + public boolean setResource (MResourceType parent) + { + boolean changed = false; + if (PRODUCTTYPE_Resource.equals(getProductType())) + { + setProductType(PRODUCTTYPE_Resource); + changed = true; + } + // + if (parent.getC_UOM_ID() != getC_UOM_ID()) + { + setC_UOM_ID(parent.getC_UOM_ID()); + changed = true; + } + if (parent.getM_Product_Category_ID() != getM_Product_Category_ID()) + { + setM_Product_Category_ID(parent.getM_Product_Category_ID()); + changed = true; + } + if (parent.getC_TaxCategory_ID() != getC_TaxCategory_ID()) + { + setC_TaxCategory_ID(parent.getC_TaxCategory_ID()); + changed = true; + } + // + return changed; + } // setResource + + + /** UOM Precision */ + private Integer m_precision = null; + + /** + * Get UOM Standard Precision + * @return UOM Standard Precision + */ + public int getUOMPrecision() + { + if (m_precision == null) + { + int C_UOM_ID = getC_UOM_ID(); + if (C_UOM_ID == 0) + return 0; // EA + m_precision = new Integer (MUOM.getPrecision(getCtx(), C_UOM_ID)); + } + return m_precision.intValue(); + } // getUOMPrecision + + + /** + * Create Asset Group for this product + * @return asset group id + */ + public int getA_Asset_Group_ID() + { + MProductCategory pc = MProductCategory.get(getCtx(), getM_Product_Category_ID()); + return pc.getA_Asset_Group_ID(); + } // getA_Asset_Group_ID + + /** + * Create Asset for this product + * @return true if asset is created + */ + public boolean isCreateAsset() + { + MProductCategory pc = MProductCategory.get(getCtx(), getM_Product_Category_ID()); + return pc.getA_Asset_Group_ID() != 0; + } // isCreated + + /** + * Get Attribute Set + * @return set or null + */ + public MAttributeSet getAttributeSet() + { + if (getM_AttributeSet_ID() != 0) + return MAttributeSet.get(getCtx(), getM_AttributeSet_ID()); + return null; + } // getAttributeSet + + /** + * Has the Product Instance Attribute + * @return true if instance attributes + */ + public boolean isInstanceAttribute() + { + if (getM_AttributeSet_ID() == 0) + return false; + MAttributeSet mas = MAttributeSet.get(getCtx(), getM_AttributeSet_ID()); + return mas.isInstanceAttribute(); + } // isInstanceAttribute + + /** + * Create One Asset Per UOM + * @return individual asset + */ + public boolean isOneAssetPerUOM() + { + MProductCategory pc = MProductCategory.get(getCtx(), getM_Product_Category_ID()); + if (pc.getA_Asset_Group_ID() == 0) + return false; + MAssetGroup ag = MAssetGroup.get(getCtx(), pc.getA_Asset_Group_ID()); + return ag.isOneAssetPerUOM(); + } // isOneAssetPerUOM + + /** + * Product is Item + * @return true if item + */ + public boolean isItem() + { + return PRODUCTTYPE_Item.equals(getProductType()); + } // isItem + + /** + * Product is an Item and Stocked + * @return true if stocked and item + */ + public boolean isStocked () + { + return super.isStocked() && isItem(); + } // isStocked + + /** + * Is Service + * @return true if service (resource, online) + */ + public boolean isService() + { + // PRODUCTTYPE_Service, PRODUCTTYPE_Resource, PRODUCTTYPE_Online + return !isItem(); // + } // isService + + /** + * Get UOM Symbol + * @return UOM Symbol + */ + public String getUOMSymbol() + { + int C_UOM_ID = getC_UOM_ID(); + if (C_UOM_ID == 0) + return ""; + return MUOM.get(getCtx(), C_UOM_ID).getUOMSymbol(); + } // getUOMSymbol + + /** + * Get Active(!) Product Downloads + * @param requery requery + * @return array of downloads + */ + public MProductDownload[] getProductDownloads (boolean requery) + { + if (m_downloads != null && !requery) + return m_downloads; + // + ArrayList list = new ArrayList(); + String sql = "SELECT * FROM M_ProductDownload " + + "WHERE M_Product_ID=? AND IsActive='Y' ORDER BY Name"; + // + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, get_TrxName()); + pstmt.setInt (1, getM_Product_ID()); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + list.add (new MProductDownload (getCtx(), rs, get_TrxName())); + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // + m_downloads = new MProductDownload[list.size ()]; + list.toArray (m_downloads); + return m_downloads; + } // getProductDownloads + + /** + * Does the product have downloads + * @return true if downloads exists + */ + public boolean hasDownloads() + { + getProductDownloads(false); + return m_downloads != null && m_downloads.length > 0; + } // hasDownloads + + /** + * String Representation + * @return info + */ + public String toString() + { + StringBuffer sb = new StringBuffer("MProduct["); + sb.append(get_ID()).append("-").append(getValue()) + .append("]"); + return sb.toString(); + } // toString + + + /** + * Before Save + * @param newRecord new + * @return true + */ + protected boolean beforeSave (boolean newRecord) + { + // Check Storage + if (!newRecord && // + ((is_ValueChanged("IsActive") && !isActive()) // now not active + || (is_ValueChanged("IsStocked") && !isStocked()) // now not stocked + || (is_ValueChanged("ProductType") // from Item + && PRODUCTTYPE_Item.equals(get_ValueOld("ProductType"))))) + { + MStorage[] storages = MStorage.getOfProduct(getCtx(), get_ID(), get_TrxName()); + BigDecimal OnHand = Env.ZERO; + BigDecimal Ordered = Env.ZERO; + BigDecimal Reserved = Env.ZERO; + for (int i = 0; i < storages.length; i++) + { + OnHand = OnHand.add(storages[i].getQtyOnHand()); + Ordered = OnHand.add(storages[i].getQtyOrdered()); + Reserved = OnHand.add(storages[i].getQtyReserved()); + } + String errMsg = ""; + if (OnHand.signum() != 0) + errMsg = "@QtyOnHand@ = " + OnHand; + if (Ordered.signum() != 0) + errMsg += " - @QtyOrdered@ = " + Ordered; + if (Reserved.signum() != 0) + errMsg += " - @QtyReserved@" + Reserved; + if (errMsg.length() > 0) + { + log.saveError("Error", Msg.parseTranslation(getCtx(), errMsg)); + return false; + } + } // storage + + // Reset Stocked if not Item + if (isStocked() && !PRODUCTTYPE_Item.equals(getProductType())) + setIsStocked(false); + + // UOM reset + if (m_precision != null && is_ValueChanged("C_UOM_ID")) + m_precision = null; + + return true; + } // beforeSave + + /** + * After Save + * @param newRecord new + * @param success success + * @return success + */ + protected boolean afterSave (boolean newRecord, boolean success) + { + if (!success) + return success; + + // Value/Name change in Account + if (!newRecord && (is_ValueChanged("Value") || is_ValueChanged("Name"))) + MAccount.updateValueDescription(getCtx(), "M_Product_ID=" + getM_Product_ID(), get_TrxName()); + + // Name/Description Change in Asset MAsset.setValueNameDescription + if (!newRecord && (is_ValueChanged("Name") || is_ValueChanged("Description"))) + { + String sql = "UPDATE A_Asset a " + + "SET (Name, Description)=" + + "(SELECT SUBSTR(bp.Name || ' - ' || p.Name,1,60), p.Description " + + "FROM M_Product p, C_BPartner bp " + + "WHERE p.M_Product_ID=a.M_Product_ID AND bp.C_BPartner_ID=a.C_BPartner_ID) " + + "WHERE IsActive='Y'" + // + " AND GuaranteeDate > SysDate" + + " AND M_Product_ID=" + getM_Product_ID(); + int no = DB.executeUpdate(sql, get_TrxName()); + log.fine("Asset Description updated #" + no); + } + + // New - Acct, Tree, Old Costing + if (newRecord) { insert_Accounting("M_Product_Acct", "M_Product_Category_Acct", "p.M_Product_Category_ID=" + getM_Product_Category_ID()); - insert_Tree(MTree_Base.TREETYPE_Product); + insert_Tree(X_AD_Tree.TREETYPE_Product); // MAcctSchema[] mass = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID(), get_TrxName()); for (int i = 0; i < mass.length; i++) - { - // Old - MProductCosting pcOld = new MProductCosting(this, mass[i].getC_AcctSchema_ID()); - pcOld.save(); - } + { + // Old + MProductCosting pcOld = new MProductCosting(this, mass[i].getC_AcctSchema_ID()); + pcOld.save(); + } } // New Costing - if (newRecord || is_ValueChanged("M_Product_Category")) + if (newRecord || is_ValueChanged("M_Product_Category_ID")) MCost.create(this); return success; - } // afterSave - - /** - * Before Delete - * @return true if it can be deleted - */ - protected boolean beforeDelete () - { - // Check Storage - if (isStocked() || PRODUCTTYPE_Item.equals(getProductType())) - { - MStorage[] storages = MStorage.getOfProduct(getCtx(), get_ID(), get_TrxName()); - BigDecimal OnHand = Env.ZERO; - BigDecimal Ordered = Env.ZERO; - BigDecimal Reserved = Env.ZERO; - for (int i = 0; i < storages.length; i++) - { - OnHand = OnHand.add(storages[i].getQtyOnHand()); - Ordered = OnHand.add(storages[i].getQtyOrdered()); - Reserved = OnHand.add(storages[i].getQtyReserved()); - } - String errMsg = ""; - if (OnHand.signum() != 0) - errMsg = "@QtyOnHand@ = " + OnHand; - if (Ordered.signum() != 0) - errMsg += " - @QtyOrdered@ = " + Ordered; - if (Reserved.signum() != 0) - errMsg += " - @QtyReserved@" + Reserved; - if (errMsg.length() > 0) - { - log.saveError("Error", Msg.parseTranslation(getCtx(), errMsg)); - return false; - } - - } - // delete costing - MProductCosting[] costings = MProductCosting.getOfProduct(getCtx(), get_ID(), get_TrxName()); - for (int i = 0; i < costings.length; i++) - costings[i].delete(true, get_TrxName()); - // - return delete_Accounting("M_Product_Acct"); - } // beforeDelete - - /** - * After Delete - * @param success - * @return deleted - */ + } // afterSave + + /** + * Before Delete + * @return true if it can be deleted + */ + protected boolean beforeDelete () + { + // Check Storage + if (isStocked() || PRODUCTTYPE_Item.equals(getProductType())) + { + MStorage[] storages = MStorage.getOfProduct(getCtx(), get_ID(), get_TrxName()); + BigDecimal OnHand = Env.ZERO; + BigDecimal Ordered = Env.ZERO; + BigDecimal Reserved = Env.ZERO; + for (int i = 0; i < storages.length; i++) + { + OnHand = OnHand.add(storages[i].getQtyOnHand()); + Ordered = OnHand.add(storages[i].getQtyOrdered()); + Reserved = OnHand.add(storages[i].getQtyReserved()); + } + String errMsg = ""; + if (OnHand.signum() != 0) + errMsg = "@QtyOnHand@ = " + OnHand; + if (Ordered.signum() != 0) + errMsg += " - @QtyOrdered@ = " + Ordered; + if (Reserved.signum() != 0) + errMsg += " - @QtyReserved@" + Reserved; + if (errMsg.length() > 0) + { + log.saveError("Error", Msg.parseTranslation(getCtx(), errMsg)); + return false; + } + + } + // delete costing + MProductCosting[] costings = MProductCosting.getOfProduct(getCtx(), get_ID(), get_TrxName()); + for (int i = 0; i < costings.length; i++) + costings[i].delete(true, get_TrxName()); + // + return delete_Accounting("M_Product_Acct"); + } // beforeDelete + + /** + * After Delete + * @param success + * @return deleted + */ protected boolean afterDelete (boolean success) { if (success) - delete_Tree(MTree_Base.TREETYPE_Product); + delete_Tree(X_AD_Tree.TREETYPE_Product); return success; } // afterDelete -} // MProduct +} // MProduct diff --git a/base/src/org/compiere/model/MSchedulerLog.java b/base/src/org/compiere/model/MSchedulerLog.java index 784ffc11f5..bf35df39cc 100644 --- a/base/src/org/compiere/model/MSchedulerLog.java +++ b/base/src/org/compiere/model/MSchedulerLog.java @@ -3,27 +3,27 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.sql.*; -import java.util.*; - - -/** - * Scheduler Log - * - * @author Jorg Janke + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.sql.*; +import java.util.*; + + +/** + * Scheduler Log + * + * @author Jorg Janke * @version $Id: MSchedulerLog.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $ */ public class MSchedulerLog extends X_AD_SchedulerLog @@ -31,37 +31,39 @@ public class MSchedulerLog extends X_AD_SchedulerLog { /** * Standard Constructor - * @param ctx context - * @param AD_SchedulerLog_ID id - * @param trxName transaction - */ + * @param ctx context + * @param AD_SchedulerLog_ID id + * @param trxName transaction + */ public MSchedulerLog (Properties ctx, int AD_SchedulerLog_ID, String trxName) { super (ctx, AD_SchedulerLog_ID, trxName); + if (AD_SchedulerLog_ID == 0) + setIsError(false); } // MSchedulerLog /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MSchedulerLog (Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MSchedulerLog - - /** - * Parent Constructor - * @param parent parent - * @param summary summary - */ - public MSchedulerLog (MScheduler parent, String summary) - { - this (parent.getCtx(), 0, parent.get_TrxName()); - setClientOrg(parent); - setAD_Scheduler_ID(parent.getAD_Scheduler_ID()); - setSummary(summary); - } // MSchedulerLog - -} // MSchedulerLog + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MSchedulerLog (Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MSchedulerLog + + /** + * Parent Constructor + * @param parent parent + * @param summary summary + */ + public MSchedulerLog (MScheduler parent, String summary) + { + this (parent.getCtx(), 0, parent.get_TrxName()); + setClientOrg(parent); + setAD_Scheduler_ID(parent.getAD_Scheduler_ID()); + setSummary(summary); + } // MSchedulerLog + +} // MSchedulerLog diff --git a/base/src/org/compiere/model/MWebProjectDomain.java b/base/src/org/compiere/model/MWebProjectDomain.java index 8c56db29bb..38474bb0bc 100644 --- a/base/src/org/compiere/model/MWebProjectDomain.java +++ b/base/src/org/compiere/model/MWebProjectDomain.java @@ -3,50 +3,99 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; import java.sql.*; import java.util.*; +import java.util.logging.Level; +import org.compiere.util.CLogger; +import org.compiere.util.DB; /** * Web Project Domain - * - * @author Jorg Janke - * @version $Id: MWebProjectDomain.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ + * + * @author Jorg Janke + * @version $Id: MWebProjectDomain.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ */ public class MWebProjectDomain extends X_CM_WebProject_Domain { + /** serialVersionUID */ + private static final long serialVersionUID = 5134789895039452551L; + + /** Logger */ + private static CLogger s_log = CLogger.getCLogger (MContainer.class); + /** * Web Project Domain Constructor * @param ctx context - * @param CM_WebProject_Domain_ID id - * @param trxName transaction - */ - public MWebProjectDomain (Properties ctx, int CM_WebProject_Domain_ID, String trxName) - { - super (ctx, CM_WebProject_Domain_ID, trxName); - } // MWebProjectDomain - - /** - * Load Constructor - * @param ctx context - * @param rs result set - * @param trxName transaction - */ - public MWebProjectDomain (Properties ctx, ResultSet rs, String trxName) + * @param CM_WebProject_Domain_ID id + * @param trxName transaction + */ + public MWebProjectDomain (Properties ctx, int CM_WebProject_Domain_ID, String trxName) + { + super (ctx, CM_WebProject_Domain_ID, trxName); + } // MWebProjectDomain + + /** + * Load Constructor + * @param ctx context + * @param rs result set + * @param trxName transaction + */ + public MWebProjectDomain (Properties ctx, ResultSet rs, String trxName) { super (ctx, rs, trxName); } // MWebProjectDomain + + /** + * get WebProjectDomain by Name + * @param ctx + * @param ServerName + * @param trxName + * @return ContainerElement + */ + public static MWebProjectDomain get(Properties ctx, String ServerName, String trxName) { + MWebProjectDomain thisWebProjectDomain = null; + String sql = "SELECT * FROM CM_WebProject_Domain WHERE lower(FQDN) LIKE ? ORDER by CM_WebProject_Domain_ID DESC"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, trxName); + pstmt.setString(1, ServerName); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + thisWebProjectDomain = (new MWebProjectDomain(ctx, rs, trxName)); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + return thisWebProjectDomain; + } + } // MWebProjectDomain diff --git a/base/src/org/compiere/process/DunningPrint.java b/base/src/org/compiere/process/DunningPrint.java index ad7d405e60..8106836e78 100644 --- a/base/src/org/compiere/process/DunningPrint.java +++ b/base/src/org/compiere/process/DunningPrint.java @@ -3,78 +3,78 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.process; - -import java.io.*; -import java.util.logging.*; -import org.compiere.model.*; -import org.compiere.print.*; -import org.compiere.util.*; - - - -/** - * Dunning Letter Print - * - * @author Jorg Janke - * @version $Id: DunningPrint.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ - */ -public class DunningPrint extends SvrProcess -{ - /** Mail PDF */ - private boolean p_EMailPDF = false; - /** Mail Template */ - private int p_R_MailText_ID = 0; - /** Dunning Run */ - private int p_C_DunningRun_ID = 0; - /** Print only Outstanding */ - private boolean p_IsOnlyIfBPBalance = true; - - - /** - * Prepare - e.g., get Parameters. - */ - protected void prepare() - { - ProcessInfoParameter[] para = getParameter(); - for (int i = 0; i < para.length; i++) - { - String name = para[i].getParameterName(); - if (para[i].getParameter() == null) - ; - else if (name.equals("EMailPDF")) - p_EMailPDF = "Y".equals(para[i].getParameter()); - else if (name.equals("R_MailText_ID")) - p_R_MailText_ID = para[i].getParameterAsInt(); - else if (name.equals("C_DunningRun_ID")) - p_C_DunningRun_ID = para[i].getParameterAsInt(); - else if (name.equals("IsOnlyIfBPBalance")) - p_IsOnlyIfBPBalance = "Y".equals(para[i].getParameter()); - else - log.log(Level.SEVERE, "Unknown Parameter: " + name); - } - } // prepare - - /** - * Pocess - * @return info - * @throws Exception - */ - protected String doIt () throws Exception - { - log.info("C_DunningRun_ID=" + p_C_DunningRun_ID + ",R_MailText_ID=" + p_R_MailText_ID - + ", EmailPDF=" + p_EMailPDF + ",IsOnlyIfBPBalance=" + p_IsOnlyIfBPBalance); + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.process; + +import java.io.*; +import java.util.logging.*; +import org.compiere.model.*; +import org.compiere.print.*; +import org.compiere.util.*; + + + +/** + * Dunning Letter Print + * + * @author Jorg Janke + * @version $Id: DunningPrint.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ + */ +public class DunningPrint extends SvrProcess +{ + /** Mail PDF */ + private boolean p_EMailPDF = false; + /** Mail Template */ + private int p_R_MailText_ID = 0; + /** Dunning Run */ + private int p_C_DunningRun_ID = 0; + /** Print only Outstanding */ + private boolean p_IsOnlyIfBPBalance = true; + + + /** + * Prepare - e.g., get Parameters. + */ + protected void prepare() + { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (para[i].getParameter() == null) + ; + else if (name.equals("EMailPDF")) + p_EMailPDF = "Y".equals(para[i].getParameter()); + else if (name.equals("R_MailText_ID")) + p_R_MailText_ID = para[i].getParameterAsInt(); + else if (name.equals("C_DunningRun_ID")) + p_C_DunningRun_ID = para[i].getParameterAsInt(); + else if (name.equals("IsOnlyIfBPBalance")) + p_IsOnlyIfBPBalance = "Y".equals(para[i].getParameter()); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + } // prepare + + /** + * Pocess + * @return info + * @throws Exception + */ + protected String doIt () throws Exception + { + log.info("C_DunningRun_ID=" + p_C_DunningRun_ID + ",R_MailText_ID=" + p_R_MailText_ID + + ", EmailPDF=" + p_EMailPDF + ",IsOnlyIfBPBalance=" + p_IsOnlyIfBPBalance); // Need to have Template if (p_EMailPDF && p_R_MailText_ID == 0) @@ -95,122 +95,127 @@ public class DunningPrint extends SvrProcess // Print Format on Dunning Level MDunningLevel level = new MDunningLevel (getCtx(), run.getC_DunningLevel_ID(), get_TrxName()); MPrintFormat format = MPrintFormat.get (getCtx(), level.getDunning_PrintFormat_ID(), false); - - MClient client = MClient.get(getCtx()); - - int count = 0; - int errors = 0; - MDunningRunEntry[] entries = run.getEntries(false); - for (int i = 0; i < entries.length; i++) - { - MDunningRunEntry entry = entries[i]; - if (p_IsOnlyIfBPBalance && entry.getAmt().signum() <= 0) - continue; - // To BPartner - MBPartner bp = new MBPartner (getCtx(), entry.getC_BPartner_ID(), get_TrxName()); - if (bp.get_ID() == 0) - { - addLog (entry.get_ID(), null, null, "@NotFound@: @C_BPartner_ID@ " + entry.getC_BPartner_ID()); - errors++; - continue; - } - // To User - MUser to = new MUser (getCtx(), entry.getAD_User_ID(), get_TrxName()); - if (p_EMailPDF) - { - if (to.get_ID() == 0) - { - addLog (entry.get_ID(), null, null, "@NotFound@: @AD_User_ID@ - " + bp.getName()); - errors++; - continue; - } - else if (to.getEMail() == null || to.getEMail().length() == 0) - { - addLog (entry.get_ID(), null, null, "@NotFound@: @EMail@ - " + to.getName()); - errors++; - continue; - } - } - // BP Language - Language language = Language.getLoginLanguage(); // Base Language - String tableName = "C_Dunning_Header_v"; - if (client.isMultiLingualDocument()) - { - tableName += "t"; - String AD_Language = bp.getAD_Language(); - if (AD_Language != null) - language = Language.getLanguage(AD_Language); - } - format.setLanguage(language); - format.setTranslationLanguage(language); - // query - MQuery query = new MQuery(tableName); - query.addRestriction("C_DunningRunEntry_ID", MQuery.EQUAL, - new Integer(entry.getC_DunningRunEntry_ID())); - - // Engine - PrintInfo info = new PrintInfo( - bp.getName(), - X_C_DunningRunEntry.Table_ID, - entry.getC_DunningRunEntry_ID(), - entry.getC_BPartner_ID()); - info.setDescription(bp.getName() + ", Amt=" + entry.getAmt()); - ReportEngine re = new ReportEngine(getCtx(), format, query, info); - boolean printed = false; - if (p_EMailPDF) - { - EMail email = client.createEMail(to.getEMail(), null, null); - if (!email.isValid()) - { - addLog (entry.get_ID(), null, null, - "@RequestActionEMailError@ Invalid EMail: " + to); - errors++; - continue; - } - mText.setUser(to); // variable context - mText.setBPartner(bp); - mText.setPO(entry); - String message = mText.getMailText(true); - if (mText.isHtml()) - email.setMessageHTML(mText.getMailHeader(), message); - else - { - email.setSubject (mText.getMailHeader()); - email.setMessageText (message); - } - // - File attachment = re.getPDF(File.createTempFile("Dunning", ".pdf")); - log.fine(to + " - " + attachment); - email.addAttachment(attachment); - // - String msg = email.send(); - MUserMail um = new MUserMail(mText, entry.getAD_User_ID(), email); - um.save(); - if (msg.equals(EMail.SENT_OK)) - { - addLog (entry.get_ID(), null, null, - bp.getName() + " @RequestActionEMailOK@"); - count++; - printed = true; - } - else - { - addLog (entry.get_ID(), null, null, - bp.getName() + " @RequestActionEMailError@ " + msg); - errors++; - } - } - else - { - re.print (); + + MClient client = MClient.get(getCtx()); + + int count = 0; + int errors = 0; + MDunningRunEntry[] entries = run.getEntries(false); + for (int i = 0; i < entries.length; i++) + { + MDunningRunEntry entry = entries[i]; + if (p_IsOnlyIfBPBalance && entry.getAmt().signum() <= 0) + continue; + // To BPartner + MBPartner bp = new MBPartner (getCtx(), entry.getC_BPartner_ID(), get_TrxName()); + if (bp.get_ID() == 0) + { + addLog (entry.get_ID(), null, null, "@NotFound@: @C_BPartner_ID@ " + entry.getC_BPartner_ID()); + errors++; + continue; + } + // To User + MUser to = new MUser (getCtx(), entry.getAD_User_ID(), get_TrxName()); + if (p_EMailPDF) + { + if (to.get_ID() == 0) + { + addLog (entry.get_ID(), null, null, "@NotFound@: @AD_User_ID@ - " + bp.getName()); + errors++; + continue; + } + else if (to.getEMail() == null || to.getEMail().length() == 0) + { + addLog (entry.get_ID(), null, null, "@NotFound@: @EMail@ - " + to.getName()); + errors++; + continue; + } + } + // BP Language + Language language = Language.getLoginLanguage(); // Base Language + String tableName = "C_Dunning_Header_v"; + if (client.isMultiLingualDocument()) + { + tableName += "t"; + String AD_Language = bp.getAD_Language(); + if (AD_Language != null) + language = Language.getLanguage(AD_Language); + } + format.setLanguage(language); + format.setTranslationLanguage(language); + // query + MQuery query = new MQuery(tableName); + query.addRestriction("C_DunningRunEntry_ID", MQuery.EQUAL, + new Integer(entry.getC_DunningRunEntry_ID())); + + // Engine + PrintInfo info = new PrintInfo( + bp.getName(), + X_C_DunningRunEntry.Table_ID, + entry.getC_DunningRunEntry_ID(), + entry.getC_BPartner_ID()); + info.setDescription(bp.getName() + ", Amt=" + entry.getAmt()); + ReportEngine re = new ReportEngine(getCtx(), format, query, info); + boolean printed = false; + if (p_EMailPDF) + { + EMail email = client.createEMail(to.getEMail(), null, null); + if (!email.isValid()) + { + addLog (entry.get_ID(), null, null, + "@RequestActionEMailError@ Invalid EMail: " + to); + errors++; + continue; + } + mText.setUser(to); // variable context + mText.setBPartner(bp); + mText.setPO(entry); + String message = mText.getMailText(true); + if (mText.isHtml()) + email.setMessageHTML(mText.getMailHeader(), message); + else + { + email.setSubject (mText.getMailHeader()); + email.setMessageText (message); + } + // + File attachment = re.getPDF(File.createTempFile("Dunning", ".pdf")); + log.fine(to + " - " + attachment); + email.addAttachment(attachment); + // + String msg = email.send(); + MUserMail um = new MUserMail(mText, entry.getAD_User_ID(), email); + um.save(); + if (msg.equals(EMail.SENT_OK)) + { + addLog (entry.get_ID(), null, null, + bp.getName() + " @RequestActionEMailOK@"); + count++; + printed = true; + } + else + { + addLog (entry.get_ID(), null, null, + bp.getName() + " @RequestActionEMailError@ " + msg); + errors++; + } + } + else + { + re.print (); count++; printed = true; } + if (printed) + { + entry.setProcessed (true); + entry.save (); + } } // for all dunning letters if (p_EMailPDF) - return "@Sent@=" + count + " - @Errors@=" + errors; - return "@Printed@=" + count; - } // doIt - -} // DunningPrint + return "@Sent@=" + count + " - @Errors@=" + errors; + return "@Printed@=" + count; + } // doIt + +} // DunningPrint diff --git a/base/src/org/compiere/process/DunningRunCreate.java b/base/src/org/compiere/process/DunningRunCreate.java index 8ba2b57c1b..9d92653bed 100644 --- a/base/src/org/compiere/process/DunningRunCreate.java +++ b/base/src/org/compiere/process/DunningRunCreate.java @@ -3,350 +3,395 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.process; - -import java.math.*; -import java.sql.*; -import java.util.logging.*; -import org.compiere.model.*; -import org.compiere.util.*; - - -/** - * Create Dunning Run Entries/Lines - * - * @author Jorg Janke - * @version $Id: DunningRunCreate.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ - */ -public class DunningRunCreate extends SvrProcess + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.process; + +import java.math.*; +import java.sql.*; +import java.util.logging.*; +import org.compiere.model.*; +import org.compiere.util.*; + + +/** + * Create Dunning Run Entries/Lines + * + * @author Jorg Janke + * @version $Id: DunningRunCreate.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ + */ +public class DunningRunCreate extends SvrProcess { private boolean p_IncludeInDispute = false; private boolean p_OnlySOTrx = false; + private boolean p_IsAllCurrencies = false; private int p_SalesRep_ID = 0; private int p_C_Currency_ID = 0; private int p_C_BPartner_ID = 0; - private int p_C_BP_Group_ID = 0; + private int p_C_BP_Group_ID = 0; private int p_C_DunningRun_ID = 0; private MDunningRun m_run = null; + private MDunningLevel m_level = null; /** * Prepare - e.g., get Parameters. - */ - protected void prepare() - { - ProcessInfoParameter[] para = getParameter(); - for (int i = 0; i < para.length; i++) - { - String name = para[i].getParameterName(); - if (para[i].getParameter() == null) - ; - else if (name.equals("IncludeInDispute")) + */ + protected void prepare() + { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (para[i].getParameter() == null) + ; + else if (name.equals("IncludeInDispute")) p_IncludeInDispute = "Y".equals(para[i].getParameter()); else if (name.equals("OnlySOTrx")) p_OnlySOTrx = "Y".equals(para[i].getParameter()); + else if (name.equals("IsAllCurrencies")) + p_IsAllCurrencies = "Y".equals(para[i].getParameter()); else if (name.equals("SalesRep_ID")) p_SalesRep_ID = para[i].getParameterAsInt(); else if (name.equals("C_Currency_ID")) - p_C_Currency_ID = para[i].getParameterAsInt(); - else if (name.equals("C_BPartner_ID")) - p_C_BPartner_ID = para[i].getParameterAsInt(); - else if (name.equals("C_BP_Group_ID")) - p_C_BP_Group_ID = para[i].getParameterAsInt(); - else - log.log(Level.SEVERE, "Unknown Parameter: " + name); - } - p_C_DunningRun_ID = getRecord_ID(); - } // prepare - - /** - * Process - * @return message - * @throws Exception - */ - protected String doIt () throws Exception - { - log.info("C_DunningRun_ID=" + p_C_DunningRun_ID - + ", Dispute=" + p_IncludeInDispute - + ", C_BP_Group_ID=" + p_C_BP_Group_ID - + ", C_BPartner_ID=" + p_C_BPartner_ID); - m_run = new MDunningRun (getCtx(),p_C_DunningRun_ID, get_TrxName()); - if (m_run.get_ID() == 0) - throw new IllegalArgumentException ("Not found MDunningRun"); - if (!m_run.deleteEntries(true)) - throw new IllegalArgumentException ("Cannot delete existing entries"); - if (p_SalesRep_ID == 0) - throw new IllegalArgumentException ("No SalesRep"); + p_C_Currency_ID = para[i].getParameterAsInt(); + else if (name.equals("C_BPartner_ID")) + p_C_BPartner_ID = para[i].getParameterAsInt(); + else if (name.equals("C_BP_Group_ID")) + p_C_BP_Group_ID = para[i].getParameterAsInt(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + p_C_DunningRun_ID = getRecord_ID(); + } // prepare + + /** + * Process + * @return message + * @throws Exception + */ + protected String doIt () throws Exception + { + log.info("C_DunningRun_ID=" + p_C_DunningRun_ID + + ", Dispute=" + p_IncludeInDispute + + ", C_BP_Group_ID=" + p_C_BP_Group_ID + + ", C_BPartner_ID=" + p_C_BPartner_ID); + m_run = new MDunningRun (getCtx(),p_C_DunningRun_ID, get_TrxName()); + if (m_run.get_ID() == 0) + throw new IllegalArgumentException ("Not found MDunningRun"); + if (!m_run.deleteEntries(true)) + throw new IllegalArgumentException ("Cannot delete existing entries"); + if (p_SalesRep_ID == 0) + throw new IllegalArgumentException ("No SalesRep"); if (p_C_Currency_ID == 0) throw new IllegalArgumentException ("No Currency"); // + m_level = m_run.getLevel (); + int inv = addInvoices(); int pay = addPayments(); + if (m_level.isChargeFee ()) + addFees(); + return "@C_Invoice_ID@ #" + inv + " - @C_Payment_ID@=" + pay; } // doIt - - /************************************************************************** - * Add Invoices to Run - * @return no of invoices - */ - private int addInvoices() - { - int count = 0; - String sql = "SELECT i.C_Invoice_ID, i.C_Currency_ID," - + " i.GrandTotal*i.MultiplierAP," - + " invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID)*MultiplierAP," - + " COALESCE(daysBetween(?,ips.DueDate),paymentTermDueDays(i.C_PaymentTerm_ID,i.DateInvoiced,?))," // ##1/2 - + " i.IsInDispute, i.C_BPartner_ID " - + "FROM C_Invoice_v i " - + " LEFT OUTER JOIN C_InvoicePaySchedule ips ON (i.C_InvoicePaySchedule_ID=ips.C_InvoicePaySchedule_ID) " - + "WHERE i.IsPaid='N' AND i.AD_Client_ID=?" // ##3 - + " AND i.DocStatus IN ('CO','CL')" - // Only BP(Group) with Dunning defined - + " AND EXISTS (SELECT * FROM C_DunningLevel dl " - + "WHERE dl.C_DunningLevel_ID=?" // // ##4 - + " AND dl.C_Dunning_ID IN " - + "(SELECT COALESCE(bp.C_Dunning_ID, bpg.C_Dunning_ID) " - + "FROM C_BPartner bp" - + " INNER JOIN C_BP_Group bpg ON (bp.C_BP_Group_ID=bpg.C_BP_Group_ID) " - + "WHERE i.C_BPartner_ID=bp.C_BPartner_ID))"; - if (p_C_BPartner_ID != 0) - sql += " AND i.C_BPartner_ID=?"; // ##5 - else if (p_C_BP_Group_ID != 0) - sql += " AND EXISTS (SELECT * FROM C_BPartner bp " + + /************************************************************************** + * Add Invoices to Run + * @return no of invoices + */ + private int addInvoices() + { + int count = 0; + String sql = "SELECT i.C_Invoice_ID, i.C_Currency_ID," + + " i.GrandTotal*i.MultiplierAP," + + " invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID)*MultiplierAP," + + " COALESCE(daysBetween(?,ips.DueDate),paymentTermDueDays(i.C_PaymentTerm_ID,i.DateInvoiced,?))," // ##1/2 + + " i.IsInDispute, i.C_BPartner_ID " + + "FROM C_Invoice_v i " + + " LEFT OUTER JOIN C_InvoicePaySchedule ips ON (i.C_InvoicePaySchedule_ID=ips.C_InvoicePaySchedule_ID) " + + "WHERE i.IsPaid='N' AND i.AD_Client_ID=?" // ##3 + + " AND i.DocStatus IN ('CO','CL')" + // Only BP(Group) with Dunning defined + + " AND EXISTS (SELECT * FROM C_DunningLevel dl " + + "WHERE dl.C_DunningLevel_ID=?" // // ##4 + + " AND dl.C_Dunning_ID IN " + + "(SELECT COALESCE(bp.C_Dunning_ID, bpg.C_Dunning_ID) " + + "FROM C_BPartner bp" + + " INNER JOIN C_BP_Group bpg ON (bp.C_BP_Group_ID=bpg.C_BP_Group_ID) " + + "WHERE i.C_BPartner_ID=bp.C_BPartner_ID))"; + if (p_C_BPartner_ID != 0) + sql += " AND i.C_BPartner_ID=?"; // ##5 + else if (p_C_BP_Group_ID != 0) + sql += " AND EXISTS (SELECT * FROM C_BPartner bp " + "WHERE i.C_BPartner_ID=bp.C_BPartner_ID AND bp.C_BP_Group_ID=?)"; // ##5 if (p_OnlySOTrx) sql += " AND i.IsSOTrx='Y'"; + if (!p_IsAllCurrencies) + sql += " AND i.C_Currency_ID=" + p_C_Currency_ID; // log.info(sql); - - // Sub Query - String sql2 = "SELECT COUNT(*), COALESCE(TRUNC(SysDate-MAX(dr.DunningDate)),0) " + + String sql2=null; + + // if sequentially we must check for other levels with smaller days for + // which this invoice is not yet included! + if (m_level.getParent ().isCreateLevelsSequentially ()) { + // Build a list of all topmost Dunning Levels + MDunningLevel[] previousLevels = m_level.getPreviousLevels(); + if (previousLevels!=null && previousLevels.length>0) { + String sqlAppend = ""; + for (int i=0; i'N')"; + } + sql += sqlAppend; + } + } + sql2 = "SELECT COUNT(*), COALESCE(TRUNC(SysDate-MAX(dr.DunningDate)),0) " + "FROM C_DunningRun dr" + " INNER JOIN C_DunningRunEntry dre ON (dr.C_DunningRun_ID=dre.C_DunningRun_ID)" + " INNER JOIN C_DunningRunLine drl ON (dre.C_DunningRunEntry_ID=drl.C_DunningRunEntry_ID) " + "WHERE drl.Processed='Y' AND drl.C_Invoice_ID=?"; + BigDecimal DaysAfterDue = m_run.getLevel().getDaysAfterDue(); int DaysBetweenDunning = m_run.getLevel().getDaysBetweenDunning(); - - PreparedStatement pstmt = null; - PreparedStatement pstmt2 = null; - try - { - pstmt = DB.prepareStatement (sql, get_TrxName()); - pstmt.setTimestamp(1, m_run.getDunningDate()); - pstmt.setTimestamp(2, m_run.getDunningDate()); - pstmt.setInt (3, m_run.getAD_Client_ID()); - pstmt.setInt(4, m_run.getC_DunningLevel_ID()); - if (p_C_BPartner_ID != 0) - pstmt.setInt (5, p_C_BPartner_ID); - else if (p_C_BP_Group_ID != 0) - pstmt.setInt (5, p_C_BP_Group_ID); - // - pstmt2 = DB.prepareStatement (sql2, get_TrxName()); - // - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - int C_Invoice_ID = rs.getInt(1); - int C_Currency_ID = rs.getInt(2); - BigDecimal GrandTotal = rs.getBigDecimal(3); - BigDecimal Open = rs.getBigDecimal(4); - int DaysDue = rs.getInt(5); - boolean IsInDispute = "Y".equals(rs.getString(6)); - int C_BPartner_ID = rs.getInt(7); + + PreparedStatement pstmt = null; + PreparedStatement pstmt2 = null; + try + { + pstmt = DB.prepareStatement (sql, get_TrxName()); + pstmt.setTimestamp(1, m_run.getDunningDate()); + pstmt.setTimestamp(2, m_run.getDunningDate()); + pstmt.setInt (3, m_run.getAD_Client_ID()); + pstmt.setInt(4, m_run.getC_DunningLevel_ID()); + if (p_C_BPartner_ID != 0) + pstmt.setInt (5, p_C_BPartner_ID); + else if (p_C_BP_Group_ID != 0) + pstmt.setInt (5, p_C_BP_Group_ID); + // + pstmt2 = DB.prepareStatement (sql2, get_TrxName()); + // + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + int C_Invoice_ID = rs.getInt(1); + int C_Currency_ID = rs.getInt(2); + BigDecimal GrandTotal = rs.getBigDecimal(3); + BigDecimal Open = rs.getBigDecimal(4); + int DaysDue = rs.getInt(5); + boolean IsInDispute = "Y".equals(rs.getString(6)); + int C_BPartner_ID = rs.getInt(7); // if (!p_IncludeInDispute && IsInDispute) continue; - if (DaysDue < DaysAfterDue.intValue()) + if (DaysDue < DaysAfterDue.intValue() && !m_level.isShowAllDue ()) continue; if (Env.ZERO.compareTo(Open) == 0) continue; - // - int TimesDunned = 0; - int DaysAfterLast = 0; - // SubQuery - pstmt2.setInt (1, C_Invoice_ID); - ResultSet rs2 = pstmt2.executeQuery (); - if (rs2.next()) - { - TimesDunned = rs2.getInt(1); - DaysAfterLast = rs2.getInt(2); + // + int TimesDunned = 0; + int DaysAfterLast = 0; + // SubQuery + pstmt2.setInt (1, C_Invoice_ID); + ResultSet rs2 = pstmt2.executeQuery (); + if (rs2.next()) + { + TimesDunned = rs2.getInt(1); + DaysAfterLast = rs2.getInt(2); } rs2.close(); // SubQuery - if (DaysBetweenDunning != 0 && DaysAfterLast < DaysBetweenDunning) + + if (DaysBetweenDunning != 0 && DaysAfterLast < DaysBetweenDunning && !m_level.isShowAllDue () && !m_level.isShowNotDue ()) continue; // createInvoiceLine (C_Invoice_ID, C_Currency_ID, GrandTotal, Open, - DaysDue, IsInDispute, C_BPartner_ID, - TimesDunned, DaysAfterLast); - count++; - } - rs.close (); - pstmt.close (); - pstmt = null; - pstmt2.close(); - pstmt2 = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, "addInvoices", e); - } - try - { - if (pstmt != null) - pstmt.close (); - if (pstmt2 != null) - pstmt2.close (); - pstmt = null; - pstmt2 = null; - } - catch (Exception e) - { - pstmt = null; - pstmt2 = null; - } - return count; - } // addInvoices - - /** - * Create Invoice Line - * @param C_Invoice_ID - * @param C_Currency_ID - * @param GrandTotal - * @param Open - * @param DaysDue - * @param IsInDispute - * @param C_BPartner_ID - * @param TimesDunned - * @param DaysAfterLast - */ - private void createInvoiceLine (int C_Invoice_ID, int C_Currency_ID, - BigDecimal GrandTotal, BigDecimal Open, - int DaysDue, boolean IsInDispute, - int C_BPartner_ID, int TimesDunned, int DaysAfterLast) - { - MDunningRunEntry entry = m_run.getEntry (C_BPartner_ID, p_C_Currency_ID, p_SalesRep_ID); - if (entry.get_ID() == 0) - if (!entry.save()) - throw new IllegalStateException("Cannot save MDunningRunEntry"); + DaysDue, IsInDispute, C_BPartner_ID, + TimesDunned, DaysAfterLast); + count++; + } + rs.close (); + pstmt.close (); + pstmt = null; + pstmt2.close(); + pstmt2 = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, "addInvoices", e); + } + try + { + if (pstmt != null) + pstmt.close (); + if (pstmt2 != null) + pstmt2.close (); + pstmt = null; + pstmt2 = null; + } + catch (Exception e) + { + pstmt = null; + pstmt2 = null; + } + return count; + } // addInvoices + + /** + * Create Invoice Line + * @param C_Invoice_ID + * @param C_Currency_ID + * @param GrandTotal + * @param Open + * @param DaysDue + * @param IsInDispute + * @param C_BPartner_ID + * @param TimesDunned + * @param DaysAfterLast + */ + private void createInvoiceLine (int C_Invoice_ID, int C_Currency_ID, + BigDecimal GrandTotal, BigDecimal Open, + int DaysDue, boolean IsInDispute, + int C_BPartner_ID, int TimesDunned, int DaysAfterLast) + { + MDunningRunEntry entry = m_run.getEntry (C_BPartner_ID, p_C_Currency_ID, p_SalesRep_ID); + if (entry.get_ID() == 0) + if (!entry.save()) + throw new IllegalStateException("Cannot save MDunningRunEntry"); // MDunningRunLine line = new MDunningRunLine (entry); line.setInvoice(C_Invoice_ID, C_Currency_ID, GrandTotal, Open, - DaysDue, IsInDispute, TimesDunned, DaysAfterLast); + new BigDecimal(0), DaysDue, IsInDispute, TimesDunned, + DaysAfterLast); if (!line.save()) throw new IllegalStateException("Cannot save MDunningRunLine"); } // createInvoiceLine - - - /************************************************************************** - * Add Payments to Run - * @return no of payments - */ - private int addPayments() - { - String sql = "SELECT C_Payment_ID, C_Currency_ID, PayAmt," - + " paymentAvailable(C_Payment_ID), C_BPartner_ID " - + "FROM C_Payment_v p " - + "WHERE AD_Client_ID=?" // ##1 - + " AND IsAllocated='N' AND C_BPartner_ID IS NOT NULL" - + " AND C_Charge_ID IS NULL" - + " AND DocStatus IN ('CO','CL')" - // Only BP with Dunning defined - + " AND EXISTS (SELECT * FROM C_BPartner bp " - + "WHERE p.C_BPartner_ID=bp.C_BPartner_ID" - + " AND bp.C_Dunning_ID=(SELECT C_Dunning_ID FROM C_DunningLevel WHERE C_DunningLevel_ID=?))"; // ##2 - if (p_C_BPartner_ID != 0) - sql += " AND C_BPartner_ID=?"; // ##3 - else if (p_C_BP_Group_ID != 0) - sql += " AND EXISTS (SELECT * FROM C_BPartner bp " - + "WHERE p.C_BPartner_ID=bp.C_BPartner_ID AND bp.C_BP_Group_ID=?)"; // ##3 - if (p_OnlySOTrx) - sql += " AND IsReceipt='Y'"; - - int count = 0; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, get_TrxName()); - pstmt.setInt (1, getAD_Client_ID()); - pstmt.setInt (2, m_run.getC_DunningLevel_ID()); - if (p_C_BPartner_ID != 0) - pstmt.setInt (3, p_C_BPartner_ID); - else if (p_C_BP_Group_ID != 0) - pstmt.setInt (3, p_C_BP_Group_ID); - - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - int C_Payment_ID = rs.getInt(1); - int C_Currency_ID = rs.getInt(2); - BigDecimal PayAmt = rs.getBigDecimal(3).negate(); - BigDecimal OpenAmt = rs.getBigDecimal(4).negate(); - int C_BPartner_ID = rs.getInt(5); - // - if (Env.ZERO.compareTo(OpenAmt) == 0) - continue; - // - createPaymentLine (C_Payment_ID, C_Currency_ID, PayAmt, OpenAmt, - C_BPartner_ID); - count++; - } - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - return count; - } // addPayments - - /** - * Create Payment Line - * @param C_Payment_ID - * @param C_Currency_ID - * @param PayAmt - * @param OpenAmt - * @param C_BPartner_ID - */ - private void createPaymentLine (int C_Payment_ID, int C_Currency_ID, - BigDecimal PayAmt, BigDecimal OpenAmt, int C_BPartner_ID) - { - MDunningRunEntry entry = m_run.getEntry (C_BPartner_ID, p_C_Currency_ID, p_SalesRep_ID); - if (entry.get_ID() == 0) - if (!entry.save()) - throw new IllegalStateException("Cannot save MDunningRunEntry"); - // - MDunningRunLine line = new MDunningRunLine (entry); - line.setPayment(C_Payment_ID, C_Currency_ID, PayAmt, OpenAmt); - if (!line.save()) + + + /************************************************************************** + * Add Payments to Run + * @return no of payments + */ + private int addPayments() + { + String sql = "SELECT C_Payment_ID, C_Currency_ID, PayAmt," + + " paymentAvailable(C_Payment_ID), C_BPartner_ID " + + "FROM C_Payment_v p " + + "WHERE AD_Client_ID=?" // ##1 + + " AND IsAllocated='N' AND C_BPartner_ID IS NOT NULL" + + " AND C_Charge_ID IS NULL" + + " AND DocStatus IN ('CO','CL')" + // Only BP with Dunning defined + + " AND EXISTS (SELECT * FROM C_BPartner bp " + + "WHERE p.C_BPartner_ID=bp.C_BPartner_ID" + + " AND bp.C_Dunning_ID=(SELECT C_Dunning_ID FROM C_DunningLevel WHERE C_DunningLevel_ID=?))"; // ##2 + if (p_C_BPartner_ID != 0) + sql += " AND C_BPartner_ID=?"; // ##3 + else if (p_C_BP_Group_ID != 0) + sql += " AND EXISTS (SELECT * FROM C_BPartner bp " + + "WHERE p.C_BPartner_ID=bp.C_BPartner_ID AND bp.C_BP_Group_ID=?)"; // ##3 + if (p_OnlySOTrx) + sql += " AND IsReceipt='Y'"; + + int count = 0; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, get_TrxName()); + pstmt.setInt (1, getAD_Client_ID()); + pstmt.setInt (2, m_run.getC_DunningLevel_ID()); + if (p_C_BPartner_ID != 0) + pstmt.setInt (3, p_C_BPartner_ID); + else if (p_C_BP_Group_ID != 0) + pstmt.setInt (3, p_C_BP_Group_ID); + + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + int C_Payment_ID = rs.getInt(1); + int C_Currency_ID = rs.getInt(2); + BigDecimal PayAmt = rs.getBigDecimal(3).negate(); + BigDecimal OpenAmt = rs.getBigDecimal(4).negate(); + int C_BPartner_ID = rs.getInt(5); + // + if (Env.ZERO.compareTo(OpenAmt) == 0) + continue; + // + createPaymentLine (C_Payment_ID, C_Currency_ID, PayAmt, OpenAmt, + C_BPartner_ID); + count++; + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + return count; + } // addPayments + + /** + * Create Payment Line + * @param C_Payment_ID + * @param C_Currency_ID + * @param PayAmt + * @param OpenAmt + * @param C_BPartner_ID + */ + private void createPaymentLine (int C_Payment_ID, int C_Currency_ID, + BigDecimal PayAmt, BigDecimal OpenAmt, int C_BPartner_ID) + { + MDunningRunEntry entry = m_run.getEntry (C_BPartner_ID, p_C_Currency_ID, p_SalesRep_ID); + if (entry.get_ID() == 0) + if (!entry.save()) + throw new IllegalStateException("Cannot save MDunningRunEntry"); + // + MDunningRunLine line = new MDunningRunLine (entry); + line.setPayment(C_Payment_ID, C_Currency_ID, PayAmt, OpenAmt); + if (!line.save()) throw new IllegalStateException("Cannot save MDunningRunLine"); } // createPaymentLine + private void addFees() + { + MDunningRunEntry [] entries = m_run.getEntries (true); + if (entries!=null && entries.length>0) { + for (int i=0;i'Y' OR I_IsImported IS NULL"); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Reset=" + no); - - // Set BP_Group - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET GroupValue=(SELECT Value FROM C_BP_Group g WHERE g.IsDefault='Y'" - + " AND g.AD_Client_ID=i.AD_Client_ID AND ROWNUM=1) " - + "WHERE GroupValue IS NULL AND C_BP_Group_ID IS NULL" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Set Group Default=" + no); - // - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET C_BP_Group_ID=(SELECT C_BP_Group_ID FROM C_BP_Group g" - + " WHERE i.GroupValue=g.Value AND g.AD_Client_ID=i.AD_Client_ID) " - + "WHERE C_BP_Group_ID IS NULL" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Set Group=" + no); - // - sql = new StringBuffer ("UPDATE I_BPartner " - + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||'ERR=Invalid Group, ' " - + "WHERE C_BP_Group_ID IS NULL" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.config("Invalid Group=" + no); - - // Set Country - /** - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET CountryCode=(SELECT CountryCode FROM C_Country c WHERE c.IsDefault='Y'" - + " AND c.AD_Client_ID IN (0, i.AD_Client_ID) AND ROWNUM=1) " - + "WHERE CountryCode IS NULL AND C_Country_ID IS NULL" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Set Country Default=" + no); - **/ - // - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET C_Country_ID=(SELECT C_Country_ID FROM C_Country c" - + " WHERE i.CountryCode=c.CountryCode AND c.AD_Client_ID IN (0, i.AD_Client_ID)) " - + "WHERE C_Country_ID IS NULL" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Set Country=" + no); - // - sql = new StringBuffer ("UPDATE I_BPartner " - + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||'ERR=Invalid Country, ' " - + "WHERE C_Country_ID IS NULL AND (City IS NOT NULL OR Address1 IS NOT NULL)" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.config("Invalid Country=" + no); - - // Set Region - sql = new StringBuffer ("UPDATE I_BPartner i " - + "Set RegionName=(SELECT Name FROM C_Region r" - + " WHERE r.IsDefault='Y' AND r.C_Country_ID=i.C_Country_ID" - + " AND r.AD_Client_ID IN (0, i.AD_Client_ID) AND ROWNUM=1) " - + "WHERE RegionName IS NULL AND C_Region_ID IS NULL" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Set Region Default=" + no); - // - sql = new StringBuffer ("UPDATE I_BPartner i " - + "Set C_Region_ID=(SELECT C_Region_ID FROM C_Region r" - + " WHERE r.Name=i.RegionName AND r.C_Country_ID=i.C_Country_ID" - + " AND r.AD_Client_ID IN (0, i.AD_Client_ID)) " - + "WHERE C_Region_ID IS NULL" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Set Region=" + no); - // - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||'ERR=Invalid Region, ' " - + "WHERE C_Region_ID IS NULL " - + " AND EXISTS (SELECT * FROM C_Country c" - + " WHERE c.C_Country_ID=i.C_Country_ID AND c.HasRegion='Y')" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.config("Invalid Region=" + no); - - // Set Greeting - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET C_Greeting_ID=(SELECT C_Greeting_ID FROM C_Greeting g" - + " WHERE i.BPContactGreeting=g.Name AND g.AD_Client_ID IN (0, i.AD_Client_ID)) " - + "WHERE C_Greeting_ID IS NULL AND BPContactGreeting IS NOT NULL" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Set Greeting=" + no); - // - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||'ERR=Invalid Greeting, ' " - + "WHERE C_Greeting_ID IS NULL AND BPContactGreeting IS NOT NULL" - + " AND I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.config("Invalid Greeting=" + no); - - // Existing User ? - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET (C_BPartner_ID,AD_User_ID)=" - + "(SELECT C_BPartner_ID,AD_User_ID FROM AD_User u " - + "WHERE i.EMail=u.EMail AND u.AD_Client_ID=i.AD_Client_ID) " - + "WHERE i.EMail IS NOT NULL AND I_IsImported='N'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Found EMail User=" + no); - - // Existing BPartner ? Match Value - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET C_BPartner_ID=(SELECT C_BPartner_ID FROM C_BPartner p" - + " WHERE i.Value=p.Value AND p.AD_Client_ID=i.AD_Client_ID) " - + "WHERE C_BPartner_ID IS NULL AND Value IS NOT NULL" - + " AND I_IsImported='N'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Found BPartner=" + no); - - // Existing Contact ? Match Name - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET AD_User_ID=(SELECT AD_User_ID FROM AD_User c" - + " WHERE i.ContactName=c.Name AND i.C_BPartner_ID=c.C_BPartner_ID AND c.AD_Client_ID=i.AD_Client_ID) " - + "WHERE C_BPartner_ID IS NOT NULL AND AD_User_ID IS NULL AND ContactName IS NOT NULL" - + " AND I_IsImported='N'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Found Contact=" + no); - - // Existing Location ? Exact Match - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET C_BPartner_Location_ID=(SELECT C_BPartner_Location_ID" - + " FROM C_BPartner_Location bpl INNER JOIN C_Location l ON (bpl.C_Location_ID=l.C_Location_ID)" - + " WHERE i.C_BPartner_ID=bpl.C_BPartner_ID AND bpl.AD_Client_ID=i.AD_Client_ID" - + " AND DUMP(i.Address1)=DUMP(l.Address1) AND DUMP(i.Address2)=DUMP(l.Address2)" - + " AND DUMP(i.City)=DUMP(l.City) AND DUMP(i.Postal)=DUMP(l.Postal) AND DUMP(i.Postal_Add)=DUMP(l.Postal_Add)" - + " AND DUMP(i.C_Region_ID)=DUMP(l.C_Region_ID) AND DUMP(i.C_Country_ID)=DUMP(l.C_Country_ID)) " - + "WHERE C_BPartner_ID IS NOT NULL AND C_BPartner_Location_ID IS NULL" - + " AND I_IsImported='N'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Found Location=" + no); - - // Interest Area - sql = new StringBuffer ("UPDATE I_BPartner i " - + "SET R_InterestArea_ID=(SELECT R_InterestArea_ID FROM R_InterestArea ia " - + "WHERE i.InterestAreaName=ia.Name AND ia.AD_Client_ID=i.AD_Client_ID) " - + "WHERE R_InterestArea_ID IS NULL AND InterestAreaName IS NOT NULL" - + " AND I_IsImported='N'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - log.fine("Set Interest Area=" + no); - - - commit(); - // ------------------------------------------------------------------- - int noInsert = 0; - int noUpdate = 0; - - // Go through Records - sql = new StringBuffer ("SELECT * FROM I_BPartner " - + "WHERE I_IsImported='N'").append(clientCheck); - try - { - PreparedStatement pstmt = DB.prepareStatement(sql.toString(), get_TrxName()); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) - { - X_I_BPartner impBP = new X_I_BPartner (getCtx(), rs, get_TrxName()); - log.fine("I_BPartner_ID=" + impBP.getI_BPartner_ID() - + ", C_BPartner_ID=" + impBP.getC_BPartner_ID() - + ", C_BPartner_Location_ID=" + impBP.getC_BPartner_Location_ID() - + ", AD_User_ID=" + impBP.getAD_User_ID()); - - - // **** Create/Update BPartner **** - MBPartner bp = null; - if (impBP.getC_BPartner_ID() == 0) // Insert new BPartner - { - bp = new MBPartner(impBP); - if (bp.save()) - { - impBP.setC_BPartner_ID(bp.getC_BPartner_ID()); - log.finest("Insert BPartner - " + bp.getC_BPartner_ID()); - noInsert++; - } - else +import java.math.*; +import java.sql.*; +import java.util.logging.*; +import org.compiere.model.*; +import org.compiere.util.*; + +/** + * Import BPartners from I_BPartner + * + * @author Jorg Janke + * @version $Id: ImportBPartner.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ + */ +public class ImportBPartner extends SvrProcess +{ + /** Client to be imported to */ + private int m_AD_Client_ID = 0; + /** Delete old Imported */ + private boolean m_deleteOldImported = false; + + /** Organization to be imported to */ + private int m_AD_Org_ID = 0; + /** Effective */ + private Timestamp m_DateValue = null; + + /** + * Prepare - e.g., get Parameters. + */ + protected void prepare() + { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (name.equals("AD_Client_ID")) + m_AD_Client_ID = ((BigDecimal)para[i].getParameter()).intValue(); + else if (name.equals("DeleteOldImported")) + m_deleteOldImported = "Y".equals(para[i].getParameter()); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + if (m_DateValue == null) + m_DateValue = new Timestamp (System.currentTimeMillis()); + } // prepare + + + /** + * Perrform process. + * @return Message + * @throws Exception + */ + protected String doIt() throws java.lang.Exception + { + StringBuffer sql = null; + int no = 0; + String clientCheck = " AND AD_Client_ID=" + m_AD_Client_ID; + + // **** Prepare **** + + // Delete Old Imported + if (m_deleteOldImported) + { + sql = new StringBuffer ("DELETE I_BPartner " + + "WHERE I_IsImported='Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Delete Old Impored =" + no); + } + + // Set Client, Org, IsActive, Created/Updated + sql = new StringBuffer ("UPDATE I_BPartner " + + "SET AD_Client_ID = COALESCE (AD_Client_ID, ").append(m_AD_Client_ID).append(")," + + " AD_Org_ID = COALESCE (AD_Org_ID, 0)," + + " IsActive = COALESCE (IsActive, 'Y')," + + " Created = COALESCE (Created, SysDate)," + + " CreatedBy = COALESCE (CreatedBy, 0)," + + " Updated = COALESCE (Updated, SysDate)," + + " UpdatedBy = COALESCE (UpdatedBy, 0)," + + " I_ErrorMsg = NULL," + + " I_IsImported = 'N' " + + "WHERE I_IsImported<>'Y' OR I_IsImported IS NULL"); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Reset=" + no); + + // Set BP_Group + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET GroupValue=(SELECT Value FROM C_BP_Group g WHERE g.IsDefault='Y'" + + " AND g.AD_Client_ID=i.AD_Client_ID AND ROWNUM=1) " + + "WHERE GroupValue IS NULL AND C_BP_Group_ID IS NULL" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Set Group Default=" + no); + // + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET C_BP_Group_ID=(SELECT C_BP_Group_ID FROM C_BP_Group g" + + " WHERE i.GroupValue=g.Value AND g.AD_Client_ID=i.AD_Client_ID) " + + "WHERE C_BP_Group_ID IS NULL" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Set Group=" + no); + // + sql = new StringBuffer ("UPDATE I_BPartner " + + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||'ERR=Invalid Group, ' " + + "WHERE C_BP_Group_ID IS NULL" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.config("Invalid Group=" + no); + + // Set Country + /** + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET CountryCode=(SELECT CountryCode FROM C_Country c WHERE c.IsDefault='Y'" + + " AND c.AD_Client_ID IN (0, i.AD_Client_ID) AND ROWNUM=1) " + + "WHERE CountryCode IS NULL AND C_Country_ID IS NULL" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Set Country Default=" + no); + **/ + // + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET C_Country_ID=(SELECT C_Country_ID FROM C_Country c" + + " WHERE i.CountryCode=c.CountryCode AND c.AD_Client_ID IN (0, i.AD_Client_ID)) " + + "WHERE C_Country_ID IS NULL" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Set Country=" + no); + // + sql = new StringBuffer ("UPDATE I_BPartner " + + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||'ERR=Invalid Country, ' " + + "WHERE C_Country_ID IS NULL AND (City IS NOT NULL OR Address1 IS NOT NULL)" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.config("Invalid Country=" + no); + + // Set Region + sql = new StringBuffer ("UPDATE I_BPartner i " + + "Set RegionName=(SELECT Name FROM C_Region r" + + " WHERE r.IsDefault='Y' AND r.C_Country_ID=i.C_Country_ID" + + " AND r.AD_Client_ID IN (0, i.AD_Client_ID) AND ROWNUM=1) " + + "WHERE RegionName IS NULL AND C_Region_ID IS NULL" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Set Region Default=" + no); + // + sql = new StringBuffer ("UPDATE I_BPartner i " + + "Set C_Region_ID=(SELECT C_Region_ID FROM C_Region r" + + " WHERE r.Name=i.RegionName AND r.C_Country_ID=i.C_Country_ID" + + " AND r.AD_Client_ID IN (0, i.AD_Client_ID)) " + + "WHERE C_Region_ID IS NULL" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Set Region=" + no); + // + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||'ERR=Invalid Region, ' " + + "WHERE C_Region_ID IS NULL " + + " AND EXISTS (SELECT * FROM C_Country c" + + " WHERE c.C_Country_ID=i.C_Country_ID AND c.HasRegion='Y')" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.config("Invalid Region=" + no); + + // Set Greeting + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET C_Greeting_ID=(SELECT C_Greeting_ID FROM C_Greeting g" + + " WHERE i.BPContactGreeting=g.Name AND g.AD_Client_ID IN (0, i.AD_Client_ID)) " + + "WHERE C_Greeting_ID IS NULL AND BPContactGreeting IS NOT NULL" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Set Greeting=" + no); + // + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||'ERR=Invalid Greeting, ' " + + "WHERE C_Greeting_ID IS NULL AND BPContactGreeting IS NOT NULL" + + " AND I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.config("Invalid Greeting=" + no); + + // Existing User ? + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET (C_BPartner_ID,AD_User_ID)=" + + "(SELECT C_BPartner_ID,AD_User_ID FROM AD_User u " + + "WHERE i.EMail=u.EMail AND u.AD_Client_ID=i.AD_Client_ID) " + + "WHERE i.EMail IS NOT NULL AND I_IsImported='N'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Found EMail User=" + no); + + // Existing BPartner ? Match Value + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET C_BPartner_ID=(SELECT C_BPartner_ID FROM C_BPartner p" + + " WHERE i.Value=p.Value AND p.AD_Client_ID=i.AD_Client_ID) " + + "WHERE C_BPartner_ID IS NULL AND Value IS NOT NULL" + + " AND I_IsImported='N'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Found BPartner=" + no); + + // Existing Contact ? Match Name + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET AD_User_ID=(SELECT AD_User_ID FROM AD_User c" + + " WHERE i.ContactName=c.Name AND i.C_BPartner_ID=c.C_BPartner_ID AND c.AD_Client_ID=i.AD_Client_ID) " + + "WHERE C_BPartner_ID IS NOT NULL AND AD_User_ID IS NULL AND ContactName IS NOT NULL" + + " AND I_IsImported='N'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Found Contact=" + no); + + // Existing Location ? Exact Match + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET C_BPartner_Location_ID=(SELECT C_BPartner_Location_ID" + + " FROM C_BPartner_Location bpl INNER JOIN C_Location l ON (bpl.C_Location_ID=l.C_Location_ID)" + + " WHERE i.C_BPartner_ID=bpl.C_BPartner_ID AND bpl.AD_Client_ID=i.AD_Client_ID" + + " AND DUMP(i.Address1)=DUMP(l.Address1) AND DUMP(i.Address2)=DUMP(l.Address2)" + + " AND DUMP(i.City)=DUMP(l.City) AND DUMP(i.Postal)=DUMP(l.Postal) AND DUMP(i.Postal_Add)=DUMP(l.Postal_Add)" + + " AND DUMP(i.C_Region_ID)=DUMP(l.C_Region_ID) AND DUMP(i.C_Country_ID)=DUMP(l.C_Country_ID)) " + + "WHERE C_BPartner_ID IS NOT NULL AND C_BPartner_Location_ID IS NULL" + + " AND I_IsImported='N'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Found Location=" + no); + + // Interest Area + sql = new StringBuffer ("UPDATE I_BPartner i " + + "SET R_InterestArea_ID=(SELECT R_InterestArea_ID FROM R_InterestArea ia " + + "WHERE i.InterestAreaName=ia.Name AND ia.AD_Client_ID=i.AD_Client_ID) " + + "WHERE R_InterestArea_ID IS NULL AND InterestAreaName IS NOT NULL" + + " AND I_IsImported='N'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + log.fine("Set Interest Area=" + no); + + + commit(); + // ------------------------------------------------------------------- + int noInsert = 0; + int noUpdate = 0; + + // Go through Records + sql = new StringBuffer ("SELECT * FROM I_BPartner " + + "WHERE I_IsImported='N'").append(clientCheck); + try + { + PreparedStatement pstmt = DB.prepareStatement(sql.toString(), get_TrxName()); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + X_I_BPartner impBP = new X_I_BPartner (getCtx(), rs, get_TrxName()); + log.fine("I_BPartner_ID=" + impBP.getI_BPartner_ID() + + ", C_BPartner_ID=" + impBP.getC_BPartner_ID() + + ", C_BPartner_Location_ID=" + impBP.getC_BPartner_Location_ID() + + ", AD_User_ID=" + impBP.getAD_User_ID()); + + + // **** Create/Update BPartner **** + MBPartner bp = null; + if (impBP.getC_BPartner_ID() == 0) // Insert new BPartner + { + bp = new MBPartner(impBP); + if (bp.save()) + { + impBP.setC_BPartner_ID(bp.getC_BPartner_ID()); + log.finest("Insert BPartner - " + bp.getC_BPartner_ID()); + noInsert++; + } + else { sql = new StringBuffer ("UPDATE I_BPartner i " + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||") - .append("'Cannot Insert BPartner, ' ") + .append("Cannot Insert BPartner") .append("WHERE I_BPartner_ID=").append(impBP.getI_BPartner_ID()); DB.executeUpdate(sql.toString(), get_TrxName()); continue; - } - } - else // Update existing BPartner - { - bp = new MBPartner(getCtx(), impBP.getC_BPartner_ID(), get_TrxName()); - // if (impBP.getValue() != null) // not to overwite - // bp.setValue(impBP.getValue()); - if (impBP.getName() != null) - { - bp.setName(impBP.getName()); - bp.setName2(impBP.getName2()); - } - if (impBP.getDUNS() != null) - bp.setDUNS(impBP.getDUNS()); - if (impBP.getTaxID() != null) - bp.setTaxID(impBP.getTaxID()); - if (impBP.getNAICS() != null) - bp.setNAICS(impBP.getNAICS()); - if (impBP.getC_BP_Group_ID() != 0) - bp.setC_BP_Group_ID(impBP.getC_BP_Group_ID()); - // - if (bp.save()) - { - log.finest("Update BPartner - " + bp.getC_BPartner_ID()); - noUpdate++; - } - else + } + } + else // Update existing BPartner + { + bp = new MBPartner(getCtx(), impBP.getC_BPartner_ID(), get_TrxName()); + // if (impBP.getValue() != null) // not to overwite + // bp.setValue(impBP.getValue()); + if (impBP.getName() != null) + { + bp.setName(impBP.getName()); + bp.setName2(impBP.getName2()); + } + if (impBP.getDUNS() != null) + bp.setDUNS(impBP.getDUNS()); + if (impBP.getTaxID() != null) + bp.setTaxID(impBP.getTaxID()); + if (impBP.getNAICS() != null) + bp.setNAICS(impBP.getNAICS()); + if (impBP.getC_BP_Group_ID() != 0) + bp.setC_BP_Group_ID(impBP.getC_BP_Group_ID()); + // + if (bp.save()) + { + log.finest("Update BPartner - " + bp.getC_BPartner_ID()); + noUpdate++; + } + else { sql = new StringBuffer ("UPDATE I_BPartner i " + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||") - .append("'Cannot Update BPartner, ' ") + .append("Cannot Update BPartner") .append("WHERE I_BPartner_ID=").append(impBP.getI_BPartner_ID()); DB.executeUpdate(sql.toString(), get_TrxName()); continue; - } - } - - // **** Create/Update BPartner Location **** - MBPartnerLocation bpl = null; - if (impBP.getC_BPartner_Location_ID() != 0) // Update Location - { - bpl = new MBPartnerLocation(getCtx(), impBP.getC_BPartner_Location_ID(), get_TrxName()); - MLocation location = new MLocation(getCtx(), bpl.getC_Location_ID(), get_TrxName()); - location.setC_Country_ID(impBP.getC_Country_ID()); - location.setC_Region_ID(impBP.getC_Region_ID()); - location.setCity(impBP.getCity()); - location.setAddress1(impBP.getAddress1()); - location.setAddress2(impBP.getAddress2()); - location.setPostal(impBP.getPostal()); - location.setPostal_Add(impBP.getPostal_Add()); - if (!location.save()) - log.warning("Location not updated"); - else - bpl.setC_Location_ID(location.getC_Location_ID()); - if (impBP.getPhone() != null) - bpl.setPhone(impBP.getPhone()); - if (impBP.getPhone2() != null) - bpl.setPhone2(impBP.getPhone2()); - if (impBP.getFax() != null) - bpl.setFax(impBP.getFax()); - bpl.save(); - } - else // New Location - if (impBP.getC_Country_ID() != 0 - && impBP.getAddress1() != null - && impBP.getCity() != null) - { - MLocation location = new MLocation(getCtx(), impBP.getC_Country_ID(), - impBP.getC_Region_ID(), impBP.getCity(), get_TrxName()); - location.setAddress1(impBP.getAddress1()); - location.setAddress2(impBP.getAddress2()); - location.setPostal(impBP.getPostal()); - location.setPostal_Add(impBP.getPostal_Add()); - if (location.save()) - log.finest("Insert Location - " + location.getC_Location_ID()); - else - { - rollback(); + } + } + + // **** Create/Update BPartner Location **** + MBPartnerLocation bpl = null; + if (impBP.getC_BPartner_Location_ID() != 0) // Update Location + { + bpl = new MBPartnerLocation(getCtx(), impBP.getC_BPartner_Location_ID(), get_TrxName()); + MLocation location = new MLocation(getCtx(), bpl.getC_Location_ID(), get_TrxName()); + location.setC_Country_ID(impBP.getC_Country_ID()); + location.setC_Region_ID(impBP.getC_Region_ID()); + location.setCity(impBP.getCity()); + location.setAddress1(impBP.getAddress1()); + location.setAddress2(impBP.getAddress2()); + location.setPostal(impBP.getPostal()); + location.setPostal_Add(impBP.getPostal_Add()); + if (!location.save()) + log.warning("Location not updated"); + else + bpl.setC_Location_ID(location.getC_Location_ID()); + if (impBP.getPhone() != null) + bpl.setPhone(impBP.getPhone()); + if (impBP.getPhone2() != null) + bpl.setPhone2(impBP.getPhone2()); + if (impBP.getFax() != null) + bpl.setFax(impBP.getFax()); + bpl.save(); + } + else // New Location + if (impBP.getC_Country_ID() != 0 + && impBP.getAddress1() != null + && impBP.getCity() != null) + { + MLocation location = new MLocation(getCtx(), impBP.getC_Country_ID(), + impBP.getC_Region_ID(), impBP.getCity(), get_TrxName()); + location.setAddress1(impBP.getAddress1()); + location.setAddress2(impBP.getAddress2()); + location.setPostal(impBP.getPostal()); + location.setPostal_Add(impBP.getPostal_Add()); + if (location.save()) + log.finest("Insert Location - " + location.getC_Location_ID()); + else + { + rollback(); noInsert--; sql = new StringBuffer ("UPDATE I_BPartner i " + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||") - .append("'Cannot Insert Location, ' ") + .append("Cannot Insert Location") .append("WHERE I_BPartner_ID=").append(impBP.getI_BPartner_ID()); DB.executeUpdate(sql.toString(), get_TrxName()); continue; - } - // - bpl = new MBPartnerLocation (bp); - bpl.setC_Location_ID(location.getC_Location_ID()); - bpl.setPhone(impBP.getPhone()); - bpl.setPhone2(impBP.getPhone2()); - bpl.setFax(impBP.getFax()); - if (bpl.save()) - { - log.finest("Insert BP Location - " + bpl.getC_BPartner_Location_ID()); - impBP.setC_BPartner_Location_ID(bpl.getC_BPartner_Location_ID()); - } - else - { - rollback(); + } + // + bpl = new MBPartnerLocation (bp); + bpl.setC_Location_ID(location.getC_Location_ID()); + bpl.setPhone(impBP.getPhone()); + bpl.setPhone2(impBP.getPhone2()); + bpl.setFax(impBP.getFax()); + if (bpl.save()) + { + log.finest("Insert BP Location - " + bpl.getC_BPartner_Location_ID()); + impBP.setC_BPartner_Location_ID(bpl.getC_BPartner_Location_ID()); + } + else + { + rollback(); noInsert--; sql = new StringBuffer ("UPDATE I_BPartner i " + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||") - .append("'Cannot Insert BPLocation, ' ") + .append("Cannot Insert BPLocation") .append("WHERE I_BPartner_ID=").append(impBP.getI_BPartner_ID()); DB.executeUpdate(sql.toString(), get_TrxName()); continue; - } - } - - // **** Create/Update Contact **** - MUser user = null; - if (impBP.getAD_User_ID() != 0) - { - user = new MUser (getCtx(), impBP.getAD_User_ID(), get_TrxName()); - if (user.getC_BPartner_ID() == 0) - user.setC_BPartner_ID(bp.getC_BPartner_ID()); - else if (user.getC_BPartner_ID() != bp.getC_BPartner_ID()) - { - rollback(); + } + } + + // **** Create/Update Contact **** + MUser user = null; + if (impBP.getAD_User_ID() != 0) + { + user = new MUser (getCtx(), impBP.getAD_User_ID(), get_TrxName()); + if (user.getC_BPartner_ID() == 0) + user.setC_BPartner_ID(bp.getC_BPartner_ID()); + else if (user.getC_BPartner_ID() != bp.getC_BPartner_ID()) + { + rollback(); noInsert--; sql = new StringBuffer ("UPDATE I_BPartner i " + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||") - .append("'BP of User <> BP, ' ") + .append("BP of User <> BP") .append("WHERE I_BPartner_ID=").append(impBP.getI_BPartner_ID()); DB.executeUpdate(sql.toString(), get_TrxName()); continue; - } - if (impBP.getC_Greeting_ID() != 0) - user.setC_Greeting_ID(impBP.getC_Greeting_ID()); - String name = impBP.getContactName(); - if (name == null || name.length() == 0) - name = impBP.getEMail(); - user.setName(name); - if (impBP.getTitle() != null) - user.setTitle(impBP.getTitle()); - if (impBP.getContactDescription() != null) - user.setDescription(impBP.getContactDescription()); - if (impBP.getComments() != null) - user.setComments(impBP.getComments()); - if (impBP.getPhone() != null) - user.setPhone(impBP.getPhone()); - if (impBP.getPhone2() != null) - user.setPhone(impBP.getPhone2()); - if (impBP.getFax() != null) - user.setFax(impBP.getFax()); - if (impBP.getEMail() != null) - user.setEMail(impBP.getEMail()); - if (impBP.getBirthday() != null) - user.setBirthday(impBP.getBirthday()); - if (bpl != null) - user.setC_BPartner_Location_ID(bpl.getC_BPartner_Location_ID()); - if (user.save()) - { - log.finest("Update BP Contact - " + user.getAD_User_ID()); - } - else - { - rollback(); + } + if (impBP.getC_Greeting_ID() != 0) + user.setC_Greeting_ID(impBP.getC_Greeting_ID()); + String name = impBP.getContactName(); + if (name == null || name.length() == 0) + name = impBP.getEMail(); + user.setName(name); + if (impBP.getTitle() != null) + user.setTitle(impBP.getTitle()); + if (impBP.getContactDescription() != null) + user.setDescription(impBP.getContactDescription()); + if (impBP.getComments() != null) + user.setComments(impBP.getComments()); + if (impBP.getPhone() != null) + user.setPhone(impBP.getPhone()); + if (impBP.getPhone2() != null) + user.setPhone(impBP.getPhone2()); + if (impBP.getFax() != null) + user.setFax(impBP.getFax()); + if (impBP.getEMail() != null) + user.setEMail(impBP.getEMail()); + if (impBP.getBirthday() != null) + user.setBirthday(impBP.getBirthday()); + if (bpl != null) + user.setC_BPartner_Location_ID(bpl.getC_BPartner_Location_ID()); + if (user.save()) + { + log.finest("Update BP Contact - " + user.getAD_User_ID()); + } + else + { + rollback(); noInsert--; sql = new StringBuffer ("UPDATE I_BPartner i " + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||") - .append("'Cannot Update BP Contact, ' ") + .append("Cannot Update BP Contact") .append("WHERE I_BPartner_ID=").append(impBP.getI_BPartner_ID()); DB.executeUpdate(sql.toString(), get_TrxName()); continue; - } - } - else // New Contact - if (impBP.getContactName() != null || impBP.getEMail() != null) - { - user = new MUser (bp); - if (impBP.getC_Greeting_ID() != 0) - user.setC_Greeting_ID(impBP.getC_Greeting_ID()); - String name = impBP.getContactName(); - if (name == null || name.length() == 0) - name = impBP.getEMail(); - user.setName(name); - user.setTitle(impBP.getTitle()); - user.setDescription(impBP.getContactDescription()); - user.setComments(impBP.getComments()); - user.setPhone(impBP.getPhone()); - user.setPhone(impBP.getPhone2()); - user.setFax(impBP.getFax()); - user.setEMail(impBP.getEMail()); - user.setBirthday(impBP.getBirthday()); - if (bpl != null) - user.setC_BPartner_Location_ID(bpl.getC_BPartner_Location_ID()); - if (user.save()) - { - log.finest("Insert BP Contact - " + user.getAD_User_ID()); - impBP.setAD_User_ID(user.getAD_User_ID()); - } - else - { - rollback(); + } + } + else // New Contact + if (impBP.getContactName() != null || impBP.getEMail() != null) + { + user = new MUser (bp); + if (impBP.getC_Greeting_ID() != 0) + user.setC_Greeting_ID(impBP.getC_Greeting_ID()); + String name = impBP.getContactName(); + if (name == null || name.length() == 0) + name = impBP.getEMail(); + user.setName(name); + user.setTitle(impBP.getTitle()); + user.setDescription(impBP.getContactDescription()); + user.setComments(impBP.getComments()); + user.setPhone(impBP.getPhone()); + user.setPhone(impBP.getPhone2()); + user.setFax(impBP.getFax()); + user.setEMail(impBP.getEMail()); + user.setBirthday(impBP.getBirthday()); + if (bpl != null) + user.setC_BPartner_Location_ID(bpl.getC_BPartner_Location_ID()); + if (user.save()) + { + log.finest("Insert BP Contact - " + user.getAD_User_ID()); + impBP.setAD_User_ID(user.getAD_User_ID()); + } + else + { + rollback(); noInsert--; sql = new StringBuffer ("UPDATE I_BPartner i " + "SET I_IsImported='E', I_ErrorMsg=I_ErrorMsg||") - .append("'Cannot Insert BPContact, ' ") + .append("Cannot Insert BPContact") .append("WHERE I_BPartner_ID=").append(impBP.getI_BPartner_ID()); DB.executeUpdate(sql.toString(), get_TrxName()); continue; - } - } - - // Interest Area - if (impBP.getR_InterestArea_ID() != 0 && user != null) - { - MContactInterest ci = MContactInterest.get(getCtx(), - impBP.getR_InterestArea_ID(), user.getAD_User_ID(), - true, get_TrxName()); - ci.save(); // don't subscribe or re-activate - } - // - impBP.setI_IsImported(true); - impBP.setProcessed(true); - impBP.setProcessing(false); - impBP.save(); - commit(); - } // for all I_Product - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, "", e); - rollback(); - } - - // Set Error to indicator to not imported - sql = new StringBuffer ("UPDATE I_BPartner " - + "SET I_IsImported='N', Updated=SysDate " - + "WHERE I_IsImported<>'Y'").append(clientCheck); - no = DB.executeUpdate(sql.toString(), get_TrxName()); - addLog (0, null, new BigDecimal (no), "@Errors@"); - addLog (0, null, new BigDecimal (noInsert), "@C_BPartner_ID@: @Inserted@"); - addLog (0, null, new BigDecimal (noUpdate), "@C_BPartner_ID@: @Updated@"); - return ""; - } // doIt - -} // ImportBPartner + } + } + + // Interest Area + if (impBP.getR_InterestArea_ID() != 0 && user != null) + { + MContactInterest ci = MContactInterest.get(getCtx(), + impBP.getR_InterestArea_ID(), user.getAD_User_ID(), + true, get_TrxName()); + ci.save(); // don't subscribe or re-activate + } + // + impBP.setI_IsImported(true); + impBP.setProcessed(true); + impBP.setProcessing(false); + impBP.save(); + commit(); + } // for all I_Product + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, "", e); + rollback(); + } + + // Set Error to indicator to not imported + sql = new StringBuffer ("UPDATE I_BPartner " + + "SET I_IsImported='N', Updated=SysDate " + + "WHERE I_IsImported<>'Y'").append(clientCheck); + no = DB.executeUpdate(sql.toString(), get_TrxName()); + addLog (0, null, new BigDecimal (no), "@Errors@"); + addLog (0, null, new BigDecimal (noInsert), "@C_BPartner_ID@: @Inserted@"); + addLog (0, null, new BigDecimal (noUpdate), "@C_BPartner_ID@: @Updated@"); + return ""; + } // doIt + +} // ImportBPartner diff --git a/base/src/org/compiere/process/InvoiceNGL.java b/base/src/org/compiere/process/InvoiceNGL.java index 05a436e2ff..1eb1d12848 100644 --- a/base/src/org/compiere/process/InvoiceNGL.java +++ b/base/src/org/compiere/process/InvoiceNGL.java @@ -3,366 +3,366 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.process; - -import java.sql.*; -import java.util.*; -import java.util.logging.*; -import java.math.*; - -import org.compiere.model.*; -import org.compiere.util.*; - -/** - * Invoice Not realized Gain & Loss. - * The actual data shown is T_InvoiceGL_v - * @author Jorg Janke - * @version $Id: InvoiceNGL.java,v 1.3 2006/08/04 03:53:59 jjanke Exp $ - */ -public class InvoiceNGL extends SvrProcess -{ - /** Mandatory Acct Schema */ - private int p_C_AcctSchema_ID = 0; - /** Mandatory Conversion Type */ - private int p_C_ConversionTypeReval_ID = 0; - /** Revaluation Date */ - private Timestamp p_DateReval = null; - /** Only AP/AR Transactions */ - private String p_APAR = "A"; - private static String ONLY_AP = "P"; - private static String ONLY_AR = "R"; - /** Report all Currencies */ - private boolean p_IsAllCurrencies = false; - /** Optional Invoice Currency */ - private int p_C_Currency_ID = 0; - /** GL Document Type */ - private int p_C_DocTypeReval_ID = 0; - - /** - * Prepare - e.g., get Parameters. - */ - protected void prepare() - { - ProcessInfoParameter[] para = getParameter(); - for (int i = 0; i < para.length; i++) - { - String name = para[i].getParameterName(); - if (para[i].getParameter() == null) - ; - else if (name.equals("C_AcctSchema_ID")) - p_C_AcctSchema_ID = para[i].getParameterAsInt(); - else if (name.equals("C_ConversionTypeReval_ID")) - p_C_ConversionTypeReval_ID = para[i].getParameterAsInt(); - else if (name.equals("DateReval")) - p_DateReval = (Timestamp)para[i].getParameter(); - else if (name.equals("APAR")) - p_APAR = (String)para[i].getParameter(); - else if (name.equals("IsAllCurrencies")) - p_IsAllCurrencies = "Y".equals((String)para[i].getParameter()); - else if (name.equals("C_Currency_ID")) - p_C_Currency_ID = para[i].getParameterAsInt(); - else if (name.equals("C_DocTypeReval_ID")) - p_C_DocTypeReval_ID = para[i].getParameterAsInt(); - else - log.log(Level.SEVERE, "Unknown Parameter: " + name); - } - } // prepare - - /** - * Process - * @return info - * @throws Exception - */ - protected String doIt () throws Exception - { - if (p_IsAllCurrencies) - p_C_Currency_ID = 0; - log.info("C_AcctSchema_ID=" + p_C_AcctSchema_ID - + ",C_ConversionTypeReval_ID=" + p_C_ConversionTypeReval_ID - + ",DateReval=" + p_DateReval - + ", APAR=" + p_APAR - + ", IsAllCurrencies=" + p_IsAllCurrencies - + ",C_Currency_ID=" + p_C_Currency_ID - + ", C_DocType_ID=" + p_C_DocTypeReval_ID); - - // Parameter - if (p_DateReval == null) - p_DateReval = new Timestamp(System.currentTimeMillis()); - - // Delete - just to be sure - String sql = "DELETE T_InvoiceGL WHERE AD_PInstance_ID=" + getAD_PInstance_ID(); - int no = DB.executeUpdate(sql, get_TrxName()); - if (no > 0) - log.info("Deleted #" + no); - - // Insert Trx - String dateStr = DB.TO_DATE(p_DateReval, true); - sql = "INSERT INTO T_InvoiceGL (AD_Client_ID, AD_Org_ID, IsActive, Created,CreatedBy, Updated,UpdatedBy," - + " AD_PInstance_ID, C_Invoice_ID, GrandTotal, OpenAmt, " - + " Fact_Acct_ID, AmtSourceBalance, AmtAcctBalance, " - + " AmtRevalDr, AmtRevalCr, C_DocTypeReval_ID, IsAllCurrencies, " - + " DateReval, C_ConversionTypeReval_ID, AmtRevalDrDiff, AmtRevalCrDiff, APAR) " - // -- - + "SELECT i.AD_Client_ID, i.AD_Org_ID, i.IsActive, i.Created,i.CreatedBy, i.Updated,i.UpdatedBy," - + getAD_PInstance_ID() + ", i.C_Invoice_ID, i.GrandTotal, invoiceOpen(i.C_Invoice_ID, 0), " - + " fa.Fact_Acct_ID, fa.AmtSourceDr-fa.AmtSourceCr, fa.AmtAcctDr-fa.AmtAcctCr, " - // AmtRevalDr, AmtRevalCr, - + " currencyConvert(fa.AmtSourceDr, i.C_Currency_ID, a.C_Currency_ID, " + dateStr + ", " + p_C_ConversionTypeReval_ID + ", i.AD_Client_ID, i.AD_Org_ID)," - + " currencyConvert(fa.AmtSourceCr, i.C_Currency_ID, a.C_Currency_ID, " + dateStr + ", " + p_C_ConversionTypeReval_ID + ", i.AD_Client_ID, i.AD_Org_ID)," - + (p_C_DocTypeReval_ID==0 ? "NULL" : String.valueOf(p_C_DocTypeReval_ID)) + ", " - + (p_IsAllCurrencies ? "'Y'," : "'N',") - + dateStr + ", " + p_C_ConversionTypeReval_ID + ", 0, 0, '" + p_APAR + "' " - // - + "FROM C_Invoice_v i" - + " INNER JOIN Fact_Acct fa ON (fa.AD_Table_ID=318 AND fa.Record_ID=i.C_Invoice_ID" - + " AND (i.GrandTotal=fa.AmtSourceDr OR i.GrandTotal=fa.AmtSourceCr))" - + " INNER JOIN C_AcctSchema a ON (fa.C_AcctSchema_ID=a.C_AcctSchema_ID) " - + "WHERE i.IsPaid='N'" - + " AND EXISTS (SELECT * FROM C_ElementValue ev " - + "WHERE ev.C_ElementValue_ID=fa.Account_ID AND (ev.AccountType='A' OR ev.AccountType='L'))" - + " AND fa.C_AcctSchema_ID=" + p_C_AcctSchema_ID; - if (!p_IsAllCurrencies) - sql += " AND i.C_Currency_ID<>a.C_Currency_ID"; - if (ONLY_AR.equals(p_APAR)) - sql += " AND i.IsSOTrx='Y'"; - else if (ONLY_AP.equals(p_APAR)) - sql += " AND i.IsSOTrx='N'"; - if (!p_IsAllCurrencies && p_C_Currency_ID != 0) - sql += " AND i.C_Currency_ID=" + p_C_Currency_ID; - - no = DB.executeUpdate(sql, get_TrxName()); - if (no != 0) - log.info("Inserted #" + no); - else if (CLogMgt.isLevelFiner()) - log.warning("Inserted #" + no + " - " + sql); - else - log.warning("Inserted #" + no); - - // Calculate Difference - sql = "UPDATE T_InvoiceGL gl " - + "SET (AmtRevalDrDiff,AmtRevalCrDiff)=" - + "(SELECT gl.AmtRevalDr-fa.AmtAcctDr, gl.AmtRevalCr-fa.AmtAcctCr " - + "FROM Fact_Acct fa " - + "WHERE gl.Fact_Acct_ID=fa.Fact_Acct_ID) " - + "WHERE AD_PInstance_ID=" + getAD_PInstance_ID(); - int noT = DB.executeUpdate(sql, get_TrxName()); - if (noT > 0) - log.config("Difference #" + noT); - - // Percentage - sql = "UPDATE T_InvoiceGL SET Percent = 100 " - + "WHERE GrandTotal=OpenAmt AND AD_PInstance_ID=" + getAD_PInstance_ID(); - no = DB.executeUpdate(sql, get_TrxName()); + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.process; + +import java.sql.*; +import java.util.*; +import java.util.logging.*; +import java.math.*; + +import org.compiere.model.*; +import org.compiere.util.*; + +/** + * Invoice Not realized Gain & Loss. + * The actual data shown is T_InvoiceGL_v + * @author Jorg Janke + * @version $Id: InvoiceNGL.java,v 1.3 2006/08/04 03:53:59 jjanke Exp $ + */ +public class InvoiceNGL extends SvrProcess +{ + /** Mandatory Acct Schema */ + private int p_C_AcctSchema_ID = 0; + /** Mandatory Conversion Type */ + private int p_C_ConversionTypeReval_ID = 0; + /** Revaluation Date */ + private Timestamp p_DateReval = null; + /** Only AP/AR Transactions */ + private String p_APAR = "A"; + private static String ONLY_AP = "P"; + private static String ONLY_AR = "R"; + /** Report all Currencies */ + private boolean p_IsAllCurrencies = false; + /** Optional Invoice Currency */ + private int p_C_Currency_ID = 0; + /** GL Document Type */ + private int p_C_DocTypeReval_ID = 0; + + /** + * Prepare - e.g., get Parameters. + */ + protected void prepare() + { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (para[i].getParameter() == null) + ; + else if (name.equals("C_AcctSchema_ID")) + p_C_AcctSchema_ID = para[i].getParameterAsInt(); + else if (name.equals("C_ConversionTypeReval_ID")) + p_C_ConversionTypeReval_ID = para[i].getParameterAsInt(); + else if (name.equals("DateReval")) + p_DateReval = (Timestamp)para[i].getParameter(); + else if (name.equals("APAR")) + p_APAR = (String)para[i].getParameter(); + else if (name.equals("IsAllCurrencies")) + p_IsAllCurrencies = "Y".equals((String)para[i].getParameter()); + else if (name.equals("C_Currency_ID")) + p_C_Currency_ID = para[i].getParameterAsInt(); + else if (name.equals("C_DocTypeReval_ID")) + p_C_DocTypeReval_ID = para[i].getParameterAsInt(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + } // prepare + + /** + * Process + * @return info + * @throws Exception + */ + protected String doIt () throws Exception + { + if (p_IsAllCurrencies) + p_C_Currency_ID = 0; + log.info("C_AcctSchema_ID=" + p_C_AcctSchema_ID + + ",C_ConversionTypeReval_ID=" + p_C_ConversionTypeReval_ID + + ",DateReval=" + p_DateReval + + ", APAR=" + p_APAR + + ", IsAllCurrencies=" + p_IsAllCurrencies + + ",C_Currency_ID=" + p_C_Currency_ID + + ", C_DocType_ID=" + p_C_DocTypeReval_ID); + + // Parameter + if (p_DateReval == null) + p_DateReval = new Timestamp(System.currentTimeMillis()); + + // Delete - just to be sure + String sql = "DELETE T_InvoiceGL WHERE AD_PInstance_ID=" + getAD_PInstance_ID(); + int no = DB.executeUpdate(sql, get_TrxName()); + if (no > 0) + log.info("Deleted #" + no); + + // Insert Trx + String dateStr = DB.TO_DATE(p_DateReval, true); + sql = "INSERT INTO T_InvoiceGL (AD_Client_ID, AD_Org_ID, IsActive, Created,CreatedBy, Updated,UpdatedBy," + + " AD_PInstance_ID, C_Invoice_ID, GrandTotal, OpenAmt, " + + " Fact_Acct_ID, AmtSourceBalance, AmtAcctBalance, " + + " AmtRevalDr, AmtRevalCr, C_DocTypeReval_ID, IsAllCurrencies, " + + " DateReval, C_ConversionTypeReval_ID, AmtRevalDrDiff, AmtRevalCrDiff, APAR) " + // -- + + "SELECT i.AD_Client_ID, i.AD_Org_ID, i.IsActive, i.Created,i.CreatedBy, i.Updated,i.UpdatedBy," + + getAD_PInstance_ID() + ", i.C_Invoice_ID, i.GrandTotal, invoiceOpen(i.C_Invoice_ID, 0), " + + " fa.Fact_Acct_ID, fa.AmtSourceDr-fa.AmtSourceCr, fa.AmtAcctDr-fa.AmtAcctCr, " + // AmtRevalDr, AmtRevalCr, + + " currencyConvert(fa.AmtSourceDr, i.C_Currency_ID, a.C_Currency_ID, " + dateStr + ", " + p_C_ConversionTypeReval_ID + ", i.AD_Client_ID, i.AD_Org_ID)," + + " currencyConvert(fa.AmtSourceCr, i.C_Currency_ID, a.C_Currency_ID, " + dateStr + ", " + p_C_ConversionTypeReval_ID + ", i.AD_Client_ID, i.AD_Org_ID)," + + (p_C_DocTypeReval_ID==0 ? "NULL" : String.valueOf(p_C_DocTypeReval_ID)) + ", " + + (p_IsAllCurrencies ? "'Y'," : "'N',") + + dateStr + ", " + p_C_ConversionTypeReval_ID + ", 0, 0, '" + p_APAR + "' " + // + + "FROM C_Invoice_v i" + + " INNER JOIN Fact_Acct fa ON (fa.AD_Table_ID=318 AND fa.Record_ID=i.C_Invoice_ID" + + " AND (i.GrandTotal=fa.AmtSourceDr OR i.GrandTotal=fa.AmtSourceCr))" + + " INNER JOIN C_AcctSchema a ON (fa.C_AcctSchema_ID=a.C_AcctSchema_ID) " + + "WHERE i.IsPaid='N'" + + " AND EXISTS (SELECT * FROM C_ElementValue ev " + + "WHERE ev.C_ElementValue_ID=fa.Account_ID AND (ev.AccountType='A' OR ev.AccountType='L'))" + + " AND fa.C_AcctSchema_ID=" + p_C_AcctSchema_ID; + if (!p_IsAllCurrencies) + sql += " AND i.C_Currency_ID<>a.C_Currency_ID"; + if (ONLY_AR.equals(p_APAR)) + sql += " AND i.IsSOTrx='Y'"; + else if (ONLY_AP.equals(p_APAR)) + sql += " AND i.IsSOTrx='N'"; + if (!p_IsAllCurrencies && p_C_Currency_ID != 0) + sql += " AND i.C_Currency_ID=" + p_C_Currency_ID; + + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.info("Inserted #" + no); + else if (CLogMgt.isLevelFiner()) + log.warning("Inserted #" + no + " - " + sql); + else + log.warning("Inserted #" + no); + + // Calculate Difference + sql = "UPDATE T_InvoiceGL gl " + + "SET (AmtRevalDrDiff,AmtRevalCrDiff)=" + + "(SELECT gl.AmtRevalDr-fa.AmtAcctDr, gl.AmtRevalCr-fa.AmtAcctCr " + + "FROM Fact_Acct fa " + + "WHERE gl.Fact_Acct_ID=fa.Fact_Acct_ID) " + + "WHERE AD_PInstance_ID=" + getAD_PInstance_ID(); + int noT = DB.executeUpdate(sql, get_TrxName()); + if (noT > 0) + log.config("Difference #" + noT); + + // Percentage + sql = "UPDATE T_InvoiceGL SET Percent = 100 " + + "WHERE GrandTotal=OpenAmt AND AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); if (no > 0) log.info("Not Paid #" + no); - sql = "UPDATE T_InvoiceGL SET Percent = ROUND(OpenAmt*100/GrandTotal,4) " + sql = "UPDATE T_InvoiceGL SET Percent = ROUND(OpenAmt*100/GrandTotal,6) " + "WHERE GrandTotal<>OpenAmt AND GrandTotal <> 0 AND AD_PInstance_ID=" + getAD_PInstance_ID(); no = DB.executeUpdate(sql, get_TrxName()); if (no > 0) - log.info("Partial Paid #" + no); - - sql = "UPDATE T_InvoiceGL SET AmtRevalDr = AmtRevalDr * Percent/100," - + " AmtRevalCr = AmtRevalCr * Percent/100," - + " AmtRevalDrDiff = AmtRevalDrDiff * Percent/100," - + " AmtRevalCrDiff = AmtRevalCrDiff * Percent/100 " - + "WHERE Percent <> 100 AND AD_PInstance_ID=" + getAD_PInstance_ID(); - no = DB.executeUpdate(sql, get_TrxName()); - if (no > 0) - log.config("Partial Calc #" + no); - - // Create Document - String info = ""; - if (p_C_DocTypeReval_ID != 0) - { - if (p_C_Currency_ID != 0) - log.warning("Can create Journal only for all currencies"); - else - info = createGLJournal(); - } - return "#" + noT + info; - } // doIt - - /** - * Create GL Journal - * @return document info - */ - private String createGLJournal() - { - ArrayList list = new ArrayList(); - String sql = "SELECT * FROM T_InvoiceGL " - + "WHERE AD_PInstance_ID=" + getAD_PInstance_ID() - + " ORDER BY AD_Org_ID"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, get_TrxName()); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - list.add (new X_T_InvoiceGL (getCtx(), rs, get_TrxName())); - } - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - log.log (Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - if (list.size() == 0) - return " - No Records found"; - - // - MAcctSchema as = MAcctSchema.get(getCtx(), p_C_AcctSchema_ID); - MAcctSchemaDefault asDefaultAccts = MAcctSchemaDefault.get(getCtx(), p_C_AcctSchema_ID); - MGLCategory cat = MGLCategory.getDefaultSystem(getCtx()); - if (cat == null) - { - MDocType docType = MDocType.get(getCtx(), p_C_DocTypeReval_ID); - cat = MGLCategory.get(getCtx(), docType.getGL_Category_ID()); - } - // - MJournalBatch batch = new MJournalBatch(getCtx(), 0, get_TrxName()); - batch.setDescription (getName()); - batch.setC_DocType_ID(p_C_DocTypeReval_ID); - batch.setDateDoc(new Timestamp(System.currentTimeMillis())); - batch.setDateAcct(p_DateReval); - batch.setC_Currency_ID(as.getC_Currency_ID()); - if (!batch.save()) - return " - Could not create Batch"; - // - MJournal journal = null; - BigDecimal drTotal = Env.ZERO; - BigDecimal crTotal = Env.ZERO; - int AD_Org_ID = 0; - for (int i = 0; i < list.size(); i++) - { - X_T_InvoiceGL gl = list.get(i); - if (gl.getAmtRevalDrDiff().signum() == 0 && gl.getAmtRevalCrDiff().signum() == 0) - continue; - MInvoice invoice = new MInvoice(getCtx(), gl.getC_Invoice_ID(), null); - if (invoice.getC_Currency_ID() == as.getC_Currency_ID()) - continue; - // - if (journal == null) - { - journal = new MJournal (batch); - journal.setC_AcctSchema_ID (as.getC_AcctSchema_ID()); - journal.setC_Currency_ID(as.getC_Currency_ID()); - journal.setC_ConversionType_ID(p_C_ConversionTypeReval_ID); - MOrg org = MOrg.get(getCtx(), gl.getAD_Org_ID()); - journal.setDescription (getName() + " - " + org.getName()); - journal.setGL_Category_ID (cat.getGL_Category_ID()); - if (!journal.save()) - return " - Could not create Journal"; - } - // - MJournalLine line = new MJournalLine(journal); - line.setLine((i+1) * 10); - line.setDescription(invoice.getSummary()); - // - MFactAcct fa = new MFactAcct (getCtx(), gl.getFact_Acct_ID(), null); - line.setC_ValidCombination_ID(MAccount.get(fa)); - BigDecimal dr = gl.getAmtRevalDrDiff(); - BigDecimal cr = gl.getAmtRevalCrDiff(); - drTotal = drTotal.add(dr); - crTotal = crTotal.add(cr); - line.setAmtSourceDr (dr); - line.setAmtAcctDr (dr); - line.setAmtSourceCr (cr); - line.setAmtAcctCr (cr); - line.save(); - // - if (AD_Org_ID == 0) // invoice org id - AD_Org_ID = gl.getAD_Org_ID(); - // Change in Org - if (AD_Org_ID != gl.getAD_Org_ID()) - { - createBalancing (asDefaultAccts, journal, drTotal, crTotal, AD_Org_ID, (i+1) * 10); - // - AD_Org_ID = gl.getAD_Org_ID(); - drTotal = Env.ZERO; - crTotal = Env.ZERO; - journal = null; - } - } - createBalancing (asDefaultAccts, journal, drTotal, crTotal, AD_Org_ID, (list.size()+1) * 10); - - return " - " + batch.getDocumentNo() + " #" + list.size(); - } // createGLJournal - - /** - * Create Balancing Entry - * @param asDefaultAccts acct schema default accounts - * @param journal journal - * @param drTotal dr - * @param crTotal cr - * @param AD_Org_ID org - * @param lineNo base line no - */ - private void createBalancing (MAcctSchemaDefault asDefaultAccts, MJournal journal, - BigDecimal drTotal, BigDecimal crTotal, int AD_Org_ID, int lineNo) - { - if (journal == null) - throw new IllegalArgumentException("Jornal is null"); - // CR Entry = Gain - if (drTotal.signum() != 0) - { - MJournalLine line = new MJournalLine(journal); - line.setLine(lineNo+1); - MAccount base = MAccount.get(getCtx(), asDefaultAccts.getUnrealizedGain_Acct()); - MAccount acct = MAccount.get(getCtx(), asDefaultAccts.getAD_Client_ID(), AD_Org_ID, - asDefaultAccts.getC_AcctSchema_ID(), base.getAccount_ID(), base.getC_SubAcct_ID(), - base.getM_Product_ID(), base.getC_BPartner_ID(), base.getAD_OrgTrx_ID(), - base.getC_LocFrom_ID(), base.getC_LocTo_ID(), base.getC_SalesRegion_ID(), - base.getC_Project_ID(), base.getC_Campaign_ID(), base.getC_Activity_ID(), - base.getUser1_ID(), base.getUser2_ID(), base.getUserElement1_ID(), base.getUserElement2_ID()); - line.setDescription(Msg.getElement(getCtx(), "UnrealizedGain_Acct")); - line.setC_ValidCombination_ID(acct.getC_ValidCombination_ID()); - line.setAmtSourceCr (drTotal); - line.setAmtAcctCr (drTotal); - line.save(); - } - // DR Entry = Loss - if (crTotal.signum() != 0) - { - MJournalLine line = new MJournalLine(journal); - line.setLine(lineNo+2); - MAccount base = MAccount.get(getCtx(), asDefaultAccts.getUnrealizedLoss_Acct()); - MAccount acct = MAccount.get(getCtx(), asDefaultAccts.getAD_Client_ID(), AD_Org_ID, - asDefaultAccts.getC_AcctSchema_ID(), base.getAccount_ID(), base.getC_SubAcct_ID(), - base.getM_Product_ID(), base.getC_BPartner_ID(), base.getAD_OrgTrx_ID(), - base.getC_LocFrom_ID(), base.getC_LocTo_ID(), base.getC_SalesRegion_ID(), - base.getC_Project_ID(), base.getC_Campaign_ID(), base.getC_Activity_ID(), - base.getUser1_ID(), base.getUser2_ID(), base.getUserElement1_ID(), base.getUserElement2_ID()); - line.setDescription(Msg.getElement(getCtx(), "UnrealizedLoss_Acct")); - line.setC_ValidCombination_ID(acct.getC_ValidCombination_ID()); - line.setAmtSourceDr (crTotal); - line.setAmtAcctDr (crTotal); - line.save(); - } - } // createBalancing - -} // InvoiceNGL + log.info("Partial Paid #" + no); + + sql = "UPDATE T_InvoiceGL SET AmtRevalDr = AmtRevalDr * Percent/100," + + " AmtRevalCr = AmtRevalCr * Percent/100," + + " AmtRevalDrDiff = AmtRevalDrDiff * Percent/100," + + " AmtRevalCrDiff = AmtRevalCrDiff * Percent/100 " + + "WHERE Percent <> 100 AND AD_PInstance_ID=" + getAD_PInstance_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no > 0) + log.config("Partial Calc #" + no); + + // Create Document + String info = ""; + if (p_C_DocTypeReval_ID != 0) + { + if (p_C_Currency_ID != 0) + log.warning("Can create Journal only for all currencies"); + else + info = createGLJournal(); + } + return "#" + noT + info; + } // doIt + + /** + * Create GL Journal + * @return document info + */ + private String createGLJournal() + { + ArrayList list = new ArrayList(); + String sql = "SELECT * FROM T_InvoiceGL " + + "WHERE AD_PInstance_ID=" + getAD_PInstance_ID() + + " ORDER BY AD_Org_ID"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, get_TrxName()); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + list.add (new X_T_InvoiceGL (getCtx(), rs, get_TrxName())); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + if (list.size() == 0) + return " - No Records found"; + + // + MAcctSchema as = MAcctSchema.get(getCtx(), p_C_AcctSchema_ID); + MAcctSchemaDefault asDefaultAccts = MAcctSchemaDefault.get(getCtx(), p_C_AcctSchema_ID); + MGLCategory cat = MGLCategory.getDefaultSystem(getCtx()); + if (cat == null) + { + MDocType docType = MDocType.get(getCtx(), p_C_DocTypeReval_ID); + cat = MGLCategory.get(getCtx(), docType.getGL_Category_ID()); + } + // + MJournalBatch batch = new MJournalBatch(getCtx(), 0, get_TrxName()); + batch.setDescription (getName()); + batch.setC_DocType_ID(p_C_DocTypeReval_ID); + batch.setDateDoc(new Timestamp(System.currentTimeMillis())); + batch.setDateAcct(p_DateReval); + batch.setC_Currency_ID(as.getC_Currency_ID()); + if (!batch.save()) + return " - Could not create Batch"; + // + MJournal journal = null; + BigDecimal drTotal = Env.ZERO; + BigDecimal crTotal = Env.ZERO; + int AD_Org_ID = 0; + for (int i = 0; i < list.size(); i++) + { + X_T_InvoiceGL gl = list.get(i); + if (gl.getAmtRevalDrDiff().signum() == 0 && gl.getAmtRevalCrDiff().signum() == 0) + continue; + MInvoice invoice = new MInvoice(getCtx(), gl.getC_Invoice_ID(), null); + if (invoice.getC_Currency_ID() == as.getC_Currency_ID()) + continue; + // + if (journal == null) + { + journal = new MJournal (batch); + journal.setC_AcctSchema_ID (as.getC_AcctSchema_ID()); + journal.setC_Currency_ID(as.getC_Currency_ID()); + journal.setC_ConversionType_ID(p_C_ConversionTypeReval_ID); + MOrg org = MOrg.get(getCtx(), gl.getAD_Org_ID()); + journal.setDescription (getName() + " - " + org.getName()); + journal.setGL_Category_ID (cat.getGL_Category_ID()); + if (!journal.save()) + return " - Could not create Journal"; + } + // + MJournalLine line = new MJournalLine(journal); + line.setLine((i+1) * 10); + line.setDescription(invoice.getSummary()); + // + MFactAcct fa = new MFactAcct (getCtx(), gl.getFact_Acct_ID(), null); + line.setC_ValidCombination_ID(MAccount.get(fa)); + BigDecimal dr = gl.getAmtRevalDrDiff(); + BigDecimal cr = gl.getAmtRevalCrDiff(); + drTotal = drTotal.add(dr); + crTotal = crTotal.add(cr); + line.setAmtSourceDr (dr); + line.setAmtAcctDr (dr); + line.setAmtSourceCr (cr); + line.setAmtAcctCr (cr); + line.save(); + // + if (AD_Org_ID == 0) // invoice org id + AD_Org_ID = gl.getAD_Org_ID(); + // Change in Org + if (AD_Org_ID != gl.getAD_Org_ID()) + { + createBalancing (asDefaultAccts, journal, drTotal, crTotal, AD_Org_ID, (i+1) * 10); + // + AD_Org_ID = gl.getAD_Org_ID(); + drTotal = Env.ZERO; + crTotal = Env.ZERO; + journal = null; + } + } + createBalancing (asDefaultAccts, journal, drTotal, crTotal, AD_Org_ID, (list.size()+1) * 10); + + return " - " + batch.getDocumentNo() + " #" + list.size(); + } // createGLJournal + + /** + * Create Balancing Entry + * @param asDefaultAccts acct schema default accounts + * @param journal journal + * @param drTotal dr + * @param crTotal cr + * @param AD_Org_ID org + * @param lineNo base line no + */ + private void createBalancing (MAcctSchemaDefault asDefaultAccts, MJournal journal, + BigDecimal drTotal, BigDecimal crTotal, int AD_Org_ID, int lineNo) + { + if (journal == null) + throw new IllegalArgumentException("Jornal is null"); + // CR Entry = Gain + if (drTotal.signum() != 0) + { + MJournalLine line = new MJournalLine(journal); + line.setLine(lineNo+1); + MAccount base = MAccount.get(getCtx(), asDefaultAccts.getUnrealizedGain_Acct()); + MAccount acct = MAccount.get(getCtx(), asDefaultAccts.getAD_Client_ID(), AD_Org_ID, + asDefaultAccts.getC_AcctSchema_ID(), base.getAccount_ID(), base.getC_SubAcct_ID(), + base.getM_Product_ID(), base.getC_BPartner_ID(), base.getAD_OrgTrx_ID(), + base.getC_LocFrom_ID(), base.getC_LocTo_ID(), base.getC_SalesRegion_ID(), + base.getC_Project_ID(), base.getC_Campaign_ID(), base.getC_Activity_ID(), + base.getUser1_ID(), base.getUser2_ID(), base.getUserElement1_ID(), base.getUserElement2_ID()); + line.setDescription(Msg.getElement(getCtx(), "UnrealizedGain_Acct")); + line.setC_ValidCombination_ID(acct.getC_ValidCombination_ID()); + line.setAmtSourceCr (drTotal); + line.setAmtAcctCr (drTotal); + line.save(); + } + // DR Entry = Loss + if (crTotal.signum() != 0) + { + MJournalLine line = new MJournalLine(journal); + line.setLine(lineNo+2); + MAccount base = MAccount.get(getCtx(), asDefaultAccts.getUnrealizedLoss_Acct()); + MAccount acct = MAccount.get(getCtx(), asDefaultAccts.getAD_Client_ID(), AD_Org_ID, + asDefaultAccts.getC_AcctSchema_ID(), base.getAccount_ID(), base.getC_SubAcct_ID(), + base.getM_Product_ID(), base.getC_BPartner_ID(), base.getAD_OrgTrx_ID(), + base.getC_LocFrom_ID(), base.getC_LocTo_ID(), base.getC_SalesRegion_ID(), + base.getC_Project_ID(), base.getC_Campaign_ID(), base.getC_Activity_ID(), + base.getUser1_ID(), base.getUser2_ID(), base.getUserElement1_ID(), base.getUserElement2_ID()); + line.setDescription(Msg.getElement(getCtx(), "UnrealizedLoss_Acct")); + line.setC_ValidCombination_ID(acct.getC_ValidCombination_ID()); + line.setAmtSourceDr (crTotal); + line.setAmtAcctDr (crTotal); + line.save(); + } + } // createBalancing + +} // InvoiceNGL diff --git a/base/src/org/compiere/process/PaySelectionCreateCheck.java b/base/src/org/compiere/process/PaySelectionCreateCheck.java index fe3fd8866e..b2c1307e58 100644 --- a/base/src/org/compiere/process/PaySelectionCreateCheck.java +++ b/base/src/org/compiere/process/PaySelectionCreateCheck.java @@ -19,6 +19,7 @@ package org.compiere.process; import java.util.*; import java.util.logging.*; import org.compiere.model.*; +import org.compiere.util.AdempiereUserError; /** @@ -50,9 +51,11 @@ public class PaySelectionCreateCheck extends SvrProcess else if (name.equals("PaymentRule")) p_PaymentRule = (String)para[i].getParameter(); else - log.log(Level.SEVERE, "prepare - Unknown Parameter: " + name); + log.log(Level.SEVERE, "Unknown Parameter: " + name); } p_C_PaySelection_ID = getRecord_ID(); + if (p_PaymentRule != null & p_PaymentRule.equals(X_C_Order.PAYMENTRULE_DirectDebit)) + p_PaymentRule = null; } // prepare /** @@ -62,7 +65,7 @@ public class PaySelectionCreateCheck extends SvrProcess */ protected String doIt () throws Exception { - log.info ("doIt - C_PaySelection_ID=" + p_C_PaySelection_ID + log.info ("C_PaySelection_ID=" + p_C_PaySelection_ID + ", PaymentRule=" + p_PaymentRule); MPaySelection psel = new MPaySelection (getCtx(), p_C_PaySelection_ID, get_TrxName()); @@ -70,8 +73,6 @@ public class PaySelectionCreateCheck extends SvrProcess throw new IllegalArgumentException("Not found C_PaySelection_ID=" + p_C_PaySelection_ID); if (psel.isProcessed()) throw new IllegalArgumentException("@Processed@"); - if (p_PaymentRule == null) - throw new IllegalArgumentException("No PaymentRule"); // MPaySelectionLine[] lines = psel.getLines(false); for (int i = 0; i < lines.length; i++) @@ -91,8 +92,9 @@ public class PaySelectionCreateCheck extends SvrProcess /** * Create Check from line * @param line + * @throws Exception for invalid bank accounts */ - private void createCheck (MPaySelectionLine line) + private void createCheck (MPaySelectionLine line) throws Exception { // Try to find one for (int i = 0; i < m_list.size(); i++) @@ -103,22 +105,35 @@ public class PaySelectionCreateCheck extends SvrProcess { check.addLine(line); if (!check.save()) - throw new IllegalStateException("Cannot Save MPaySelectionCheck"); + throw new IllegalStateException("Cannot save MPaySelectionCheck"); line.setC_PaySelectionCheck_ID(check.getC_PaySelectionCheck_ID()); line.setProcessed(true); if (!line.save()) - throw new IllegalStateException("Cannot Save MPaySelectionLine"); + throw new IllegalStateException("Cannot save MPaySelectionLine"); return; } } // Create new - MPaySelectionCheck check = new MPaySelectionCheck(line, p_PaymentRule); + String PaymentRule = line.getPaymentRule(); + if (p_PaymentRule != null) + { + if (!X_C_Order.PAYMENTRULE_DirectDebit.equals(PaymentRule)) + PaymentRule = p_PaymentRule; + } + MPaySelectionCheck check = new MPaySelectionCheck(line, PaymentRule); + if (!check.isValid()) + { + int C_BPartner_ID = check.getC_BPartner_ID(); + MBPartner bp = MBPartner.get(getCtx(), C_BPartner_ID); + String msg = "@NotFound@ @C_BP_BankAccount@: " + bp.getName(); + throw new AdempiereUserError(msg); + } if (!check.save()) - throw new IllegalStateException("Cannot Save MPaySelectionCheck"); + throw new IllegalStateException("Cannot save MPaySelectionCheck"); line.setC_PaySelectionCheck_ID(check.getC_PaySelectionCheck_ID()); line.setProcessed(true); if (!line.save()) - throw new IllegalStateException("Cannot Save MPaySelectionLine"); + throw new IllegalStateException("Cannot save MPaySelectionLine"); m_list.add(check); } // createCheck diff --git a/base/src/org/compiere/process/PaySelectionCreateFrom.java b/base/src/org/compiere/process/PaySelectionCreateFrom.java index b20ce3bd25..5e6dfc00ec 100644 --- a/base/src/org/compiere/process/PaySelectionCreateFrom.java +++ b/base/src/org/compiere/process/PaySelectionCreateFrom.java @@ -3,236 +3,236 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.process; - -import java.math.*; -import java.sql.*; -import java.util.logging.*; -import org.compiere.model.*; -import org.compiere.util.*; - - -/** - * Create Payment Selection Lines from AP Invoices - * - * @author Jorg Janke - * @version $Id: PaySelectionCreateFrom.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ - */ -public class PaySelectionCreateFrom extends SvrProcess -{ - /** Only When Discount */ - private boolean p_OnlyDiscount = false; - /** Only when Due */ - private boolean p_OnlyDue = false; - /** Include Disputed */ - private boolean p_IncludeInDispute = false; - /** Match Requirement */ - private String p_MatchRequirement = "N"; - /** Payment Rule */ - private String p_PaymentRule = null; - /** BPartner */ - private int p_C_BPartner_ID = 0; - /** BPartner Group */ - private int p_C_BP_Group_ID = 0; - /** Payment Selection */ - private int p_C_PaySelection_ID = 0; - - /** - * Prepare - e.g., get Parameters. - */ - protected void prepare() - { - ProcessInfoParameter[] para = getParameter(); - for (int i = 0; i < para.length; i++) - { - String name = para[i].getParameterName(); - if (para[i].getParameter() == null) - ; - else if (name.equals("OnlyDiscount")) - p_OnlyDiscount = "Y".equals(para[i].getParameter()); - else if (name.equals("OnlyDue")) - p_OnlyDue = "Y".equals(para[i].getParameter()); - else if (name.equals("IncludeInDispute")) - p_IncludeInDispute = "Y".equals(para[i].getParameter()); - else if (name.equals("MatchRequirement")) - p_MatchRequirement = (String)para[i].getParameter(); - else if (name.equals("PaymentRule")) - p_PaymentRule = (String)para[i].getParameter(); - else if (name.equals("C_BPartner_ID")) - p_C_BPartner_ID = para[i].getParameterAsInt(); - else if (name.equals("C_BP_Group_ID")) - p_C_BP_Group_ID = para[i].getParameterAsInt(); - else - log.log(Level.SEVERE, "Unknown Parameter: " + name); - } - p_C_PaySelection_ID = getRecord_ID(); - } // prepare - - /** - * Perrform process. - * @return Message - * @throws Exception if not successful - */ - protected String doIt() throws Exception - { - log.info ("C_PaySelection_ID=" + p_C_PaySelection_ID - + ", OnlyDiscount=" + p_OnlyDiscount + ", OnlyDue=" + p_OnlyDue - + ", IncludeInDispute=" + p_IncludeInDispute - + ", MatchRequirement=" + p_MatchRequirement - + ", PaymentRule=" + p_PaymentRule - + ", C_BP_Group_ID=" + p_C_BP_Group_ID + ", C_BPartner_ID=" + p_C_BPartner_ID); - - MPaySelection psel = new MPaySelection (getCtx(), p_C_PaySelection_ID, get_TrxName()); - if (psel.get_ID() == 0) - throw new IllegalArgumentException("Not found C_PaySelection_ID=" + p_C_PaySelection_ID); - if (psel.isProcessed()) - throw new IllegalArgumentException("@Processed@"); - // psel.getPayDate(); - - String sql = "SELECT C_Invoice_ID," - // Open - + " currencyConvert(invoiceOpen(i.C_Invoice_ID, 0)" - + ",i.C_Currency_ID, ?,?, i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID)," // ##1/2 Currency_To,PayDate + * by the Free Software Foundation. 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.process; + +import java.math.*; +import java.sql.*; +import java.util.logging.*; +import org.compiere.model.*; +import org.compiere.util.*; + + +/** + * Create Payment Selection Lines from AP Invoices + * + * @author Jorg Janke + * @version $Id: PaySelectionCreateFrom.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $ + */ +public class PaySelectionCreateFrom extends SvrProcess +{ + /** Only When Discount */ + private boolean p_OnlyDiscount = false; + /** Only when Due */ + private boolean p_OnlyDue = false; + /** Include Disputed */ + private boolean p_IncludeInDispute = false; + /** Match Requirement */ + private String p_MatchRequirement = "N"; + /** Payment Rule */ + private String p_PaymentRule = null; + /** BPartner */ + private int p_C_BPartner_ID = 0; + /** BPartner Group */ + private int p_C_BP_Group_ID = 0; + /** Payment Selection */ + private int p_C_PaySelection_ID = 0; + + /** + * Prepare - e.g., get Parameters. + */ + protected void prepare() + { + ProcessInfoParameter[] para = getParameter(); + for (int i = 0; i < para.length; i++) + { + String name = para[i].getParameterName(); + if (para[i].getParameter() == null) + ; + else if (name.equals("OnlyDiscount")) + p_OnlyDiscount = "Y".equals(para[i].getParameter()); + else if (name.equals("OnlyDue")) + p_OnlyDue = "Y".equals(para[i].getParameter()); + else if (name.equals("IncludeInDispute")) + p_IncludeInDispute = "Y".equals(para[i].getParameter()); + else if (name.equals("MatchRequirement")) + p_MatchRequirement = (String)para[i].getParameter(); + else if (name.equals("PaymentRule")) + p_PaymentRule = (String)para[i].getParameter(); + else if (name.equals("C_BPartner_ID")) + p_C_BPartner_ID = para[i].getParameterAsInt(); + else if (name.equals("C_BP_Group_ID")) + p_C_BP_Group_ID = para[i].getParameterAsInt(); + else + log.log(Level.SEVERE, "Unknown Parameter: " + name); + } + p_C_PaySelection_ID = getRecord_ID(); + } // prepare + + /** + * Perrform process. + * @return Message + * @throws Exception if not successful + */ + protected String doIt() throws Exception + { + log.info ("C_PaySelection_ID=" + p_C_PaySelection_ID + + ", OnlyDiscount=" + p_OnlyDiscount + ", OnlyDue=" + p_OnlyDue + + ", IncludeInDispute=" + p_IncludeInDispute + + ", MatchRequirement=" + p_MatchRequirement + + ", PaymentRule=" + p_PaymentRule + + ", C_BP_Group_ID=" + p_C_BP_Group_ID + ", C_BPartner_ID=" + p_C_BPartner_ID); + + MPaySelection psel = new MPaySelection (getCtx(), p_C_PaySelection_ID, get_TrxName()); + if (psel.get_ID() == 0) + throw new IllegalArgumentException("Not found C_PaySelection_ID=" + p_C_PaySelection_ID); + if (psel.isProcessed()) + throw new IllegalArgumentException("@Processed@"); + // psel.getPayDate(); + + String sql = "SELECT C_Invoice_ID," + // Open + + " currencyConvert(invoiceOpen(i.C_Invoice_ID, 0)" + + ",i.C_Currency_ID, ?,?, i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID)," // ##1/2 Currency_To,PayDate // Discount + " currencyConvert(paymentTermDiscount(i.GrandTotal,i.C_Currency_ID,i.C_PaymentTerm_ID,i.DateInvoiced, ?)" // ##3 PayDate + ",i.C_Currency_ID, ?,?,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID)," // ##4/5 Currency_To,PayDate - + " PaymentRule, IsSOTrx " + + " PaymentRule, IsSOTrx " // 4..6 + "FROM C_Invoice i " + "WHERE IsSOTrx='N' AND IsPaid='N' AND DocStatus IN ('CO','CL')" + " AND AD_Client_ID=?" // ##6 - // Existing Payments - Will reselect Invoice if prepared but not paid - + " AND NOT EXISTS (SELECT * FROM C_PaySelectionLine psl " - + "WHERE i.C_Invoice_ID=psl.C_Invoice_ID AND psl.IsActive='Y'" - + " AND psl.C_PaySelectionCheck_ID IS NOT NULL)"; - // Disputed - if (!p_IncludeInDispute) - sql += " AND i.IsInDispute='N'"; - // PaymentRule (optional) - if (p_PaymentRule != null) - sql += " AND PaymentRule=?"; // ## - // OnlyDiscount - if (p_OnlyDiscount) - { - if (p_OnlyDue) - sql += " AND ("; - else - sql += " AND "; - sql += "paymentTermDiscount(invoiceOpen(C_Invoice_ID, 0), C_Currency_ID, C_PaymentTerm_ID, DateInvoiced, ?) > 0"; // ## - } - // OnlyDue - if (p_OnlyDue) - { - if (p_OnlyDiscount) - sql += " OR "; - else - sql += " AND "; - sql += "paymentTermDueDays(C_PaymentTerm_ID, DateInvoiced, ?) >= 0"; // ## - if (p_OnlyDiscount) - sql += ")"; - } - // Business Partner - if (p_C_BPartner_ID != 0) - sql += " AND C_BPartner_ID=?"; // ## - // Business Partner Group - else if (p_C_BP_Group_ID != 0) - sql += " AND EXISTS (SELECT * FROM C_BPartner bp " - + "WHERE bp.C_BPartner_ID=i.C_BPartner_ID AND bp.C_BP_Group_ID=?)"; // ## - // PO Matching Requiremnent - if (p_MatchRequirement.equals("P") || p_MatchRequirement.equals("B")) - { - sql += " AND EXISTS (SELECT * FROM C_InvoiceLine il " - + "WHERE i.C_Invoice_ID=il.C_Invoice_ID" - + " AND QtyInvoiced=(SELECT SUM(Qty) FROM M_MatchPO m " - + "WHERE il.C_InvoiceLine_ID=m.C_InvoiceLine_ID))"; - } - // Receipt Matching Requiremnent - if (p_MatchRequirement.equals("R") || p_MatchRequirement.equals("B")) - { - sql += " AND EXISTS (SELECT * FROM C_InvoiceLine il " - + "WHERE i.C_Invoice_ID=il.C_Invoice_ID" - + " AND QtyInvoiced=(SELECT SUM(Qty) FROM M_MatchInv m " - + "WHERE il.C_InvoiceLine_ID=m.C_InvoiceLine_ID))"; - } - - // - int lines = 0; - int C_CurrencyTo_ID = psel.getC_Currency_ID(); - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, get_TrxName()); - int index = 1; - pstmt.setInt (index++, C_CurrencyTo_ID); - pstmt.setTimestamp(index++, psel.getPayDate()); - // - pstmt.setTimestamp(index++, psel.getPayDate()); - pstmt.setInt (index++, C_CurrencyTo_ID); - pstmt.setTimestamp(index++, psel.getPayDate()); - // - pstmt.setInt(index++, psel.getAD_Client_ID()); - if (p_PaymentRule != null) - pstmt.setString(index++, p_PaymentRule); - if (p_OnlyDiscount) - pstmt.setTimestamp(index++, psel.getPayDate()); - if (p_OnlyDue) - pstmt.setTimestamp(index++, psel.getPayDate()); - if (p_C_BPartner_ID != 0) - pstmt.setInt (index++, p_C_BPartner_ID); - else if (p_C_BP_Group_ID != 0) - pstmt.setInt (index++, p_C_BP_Group_ID); - // - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - int C_Invoice_ID = rs.getInt(1); - BigDecimal PayAmt = rs.getBigDecimal(2); - if (C_Invoice_ID == 0 || Env.ZERO.compareTo(PayAmt) == 0) - continue; - BigDecimal DiscountAmt = rs.getBigDecimal(3); - String PaymentRule = rs.getString(4); - boolean isSOTrx = "Y".equals(rs.getString(5)); - // - lines++; - MPaySelectionLine pselLine = new MPaySelectionLine (psel, lines*10, PaymentRule); - pselLine.setInvoice (C_Invoice_ID, isSOTrx, - PayAmt, PayAmt.subtract(DiscountAmt), DiscountAmt); - if (!pselLine.save()) - { - pstmt.close(); - throw new IllegalStateException ("Cannot save MPaySelectionLine"); - } - } - rs.close (); - pstmt.close (); - pstmt = null; + // Existing Payments - Will reselect Invoice if prepared but not paid + + " AND NOT EXISTS (SELECT * FROM C_PaySelectionLine psl " + + "WHERE i.C_Invoice_ID=psl.C_Invoice_ID AND psl.IsActive='Y'" + + " AND psl.C_PaySelectionCheck_ID IS NOT NULL)"; + // Disputed + if (!p_IncludeInDispute) + sql += " AND i.IsInDispute='N'"; + // PaymentRule (optional) + if (p_PaymentRule != null) + sql += " AND PaymentRule=?"; // ## + // OnlyDiscount + if (p_OnlyDiscount) + { + if (p_OnlyDue) + sql += " AND ("; + else + sql += " AND "; + sql += "paymentTermDiscount(invoiceOpen(C_Invoice_ID, 0), C_Currency_ID, C_PaymentTerm_ID, DateInvoiced, ?) > 0"; // ## + } + // OnlyDue + if (p_OnlyDue) + { + if (p_OnlyDiscount) + sql += " OR "; + else + sql += " AND "; + sql += "paymentTermDueDays(C_PaymentTerm_ID, DateInvoiced, ?) >= 0"; // ## + if (p_OnlyDiscount) + sql += ")"; + } + // Business Partner + if (p_C_BPartner_ID != 0) + sql += " AND C_BPartner_ID=?"; // ## + // Business Partner Group + else if (p_C_BP_Group_ID != 0) + sql += " AND EXISTS (SELECT * FROM C_BPartner bp " + + "WHERE bp.C_BPartner_ID=i.C_BPartner_ID AND bp.C_BP_Group_ID=?)"; // ## + // PO Matching Requiremnent + if (p_MatchRequirement.equals("P") || p_MatchRequirement.equals("B")) + { + sql += " AND EXISTS (SELECT * FROM C_InvoiceLine il " + + "WHERE i.C_Invoice_ID=il.C_Invoice_ID" + + " AND QtyInvoiced=(SELECT SUM(Qty) FROM M_MatchPO m " + + "WHERE il.C_InvoiceLine_ID=m.C_InvoiceLine_ID))"; + } + // Receipt Matching Requiremnent + if (p_MatchRequirement.equals("R") || p_MatchRequirement.equals("B")) + { + sql += " AND EXISTS (SELECT * FROM C_InvoiceLine il " + + "WHERE i.C_Invoice_ID=il.C_Invoice_ID" + + " AND QtyInvoiced=(SELECT SUM(Qty) FROM M_MatchInv m " + + "WHERE il.C_InvoiceLine_ID=m.C_InvoiceLine_ID))"; + } + + // + int lines = 0; + int C_CurrencyTo_ID = psel.getC_Currency_ID(); + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, get_TrxName()); + int index = 1; + pstmt.setInt (index++, C_CurrencyTo_ID); + pstmt.setTimestamp(index++, psel.getPayDate()); + // + pstmt.setTimestamp(index++, psel.getPayDate()); + pstmt.setInt (index++, C_CurrencyTo_ID); + pstmt.setTimestamp(index++, psel.getPayDate()); + // + pstmt.setInt(index++, psel.getAD_Client_ID()); + if (p_PaymentRule != null) + pstmt.setString(index++, p_PaymentRule); + if (p_OnlyDiscount) + pstmt.setTimestamp(index++, psel.getPayDate()); + if (p_OnlyDue) + pstmt.setTimestamp(index++, psel.getPayDate()); + if (p_C_BPartner_ID != 0) + pstmt.setInt (index++, p_C_BPartner_ID); + else if (p_C_BP_Group_ID != 0) + pstmt.setInt (index++, p_C_BP_Group_ID); + // + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + int C_Invoice_ID = rs.getInt(1); + BigDecimal PayAmt = rs.getBigDecimal(2); + if (C_Invoice_ID == 0 || Env.ZERO.compareTo(PayAmt) == 0) + continue; + BigDecimal DiscountAmt = rs.getBigDecimal(3); + String PaymentRule = rs.getString(4); + boolean isSOTrx = "Y".equals(rs.getString(5)); + // + lines++; + MPaySelectionLine pselLine = new MPaySelectionLine (psel, lines*10, PaymentRule); + pselLine.setInvoice (C_Invoice_ID, isSOTrx, + PayAmt, PayAmt.subtract(DiscountAmt), DiscountAmt); + if (!pselLine.save()) + { + pstmt.close(); + throw new IllegalStateException ("Cannot save MPaySelectionLine"); + } + } + rs.close (); + pstmt.close (); + pstmt = null; } catch (Exception e) { - log.log(Level.SEVERE, "doIt - " + sql, e); + log.log(Level.SEVERE, sql, e); } try { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - - return "@C_PaySelectionLine_ID@ - #" + lines; - } // doIt - -} // PaySelectionCreateFrom + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + + return "@C_PaySelectionLine_ID@ - #" + lines; + } // doIt + +} // PaySelectionCreateFrom