();
+ // For all fact lines
+ for (int i = 0; i < m_lines.size(); i++)
+ {
+ FactLine dLine = (FactLine)m_lines.get(i);
+ MDistribution[] distributions = MDistribution.get (dLine.getAccount(),
+ m_postingType, m_doc.getC_DocType_ID());
+ // No Distribution for this line
+ if (distributions == null || distributions.length == 0)
+ continue;
+ // Just the first
+ if (distributions.length > 1)
+ log.warning("More then one Distributiion for " + dLine.getAccount());
+ MDistribution distribution = distributions[0];
+ // Add Reversal
+ FactLine reversal = dLine.reverse(distribution.getName());
+ log.info("Reversal=" + reversal);
+ newLines.add(reversal); // saved in postCommit
+ // Prepare
+ distribution.distribute(dLine.getAccount(), dLine.getSourceBalance(), dLine.getC_Currency_ID());
+ MDistributionLine[] lines = distribution.getLines(false);
+ for (int j = 0; j < lines.length; j++)
+ {
+ MDistributionLine dl = lines[j];
+ if (!dl.isActive() || dl.getAmt().signum() == 0)
+ continue;
+ FactLine factLine = new FactLine (m_doc.getCtx(), m_doc.get_Table_ID(),
+ m_doc.get_ID(), 0, m_trxName);
+ // Set Info & Account
+ factLine.setDocumentInfo(m_doc, dLine.getDocLine());
+ factLine.setAccount(m_acctSchema, dl.getAccount());
+ factLine.setPostingType(m_postingType);
+ if (dl.isOverwriteOrg()) // set Org explicitly
+ factLine.setAD_Org_ID(dl.getOrg_ID());
+ //
+ if (dl.getAmt().signum() < 0)
+ factLine.setAmtSource(dLine.getC_Currency_ID(), null, dl.getAmt().abs());
+ else
+ factLine.setAmtSource(dLine.getC_Currency_ID(), dl.getAmt(), null);
+ // Convert
+ factLine.convert();
+ //
+ String description = distribution.getName() + " #" + dl.getLine();
+ if (dl.getDescription() != null)
+ description += " - " + dl.getDescription();
+ factLine.addDescription(description);
+ //
+ log.info(factLine.toString());
+ newLines.add(factLine);
+ }
+ } // for all lines
+
+ // Add Lines
+ for (int i = 0; i < newLines.size(); i++)
+ m_lines.add(newLines.get(i));
+
+ return true;
+ } // distribute
+
+
+ /**************************************************************************
+ * String representation
+ * @return String
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer("Fact[");
+ sb.append(m_doc.toString());
+ sb.append(",").append(m_acctSchema.toString());
+ sb.append(",PostType=").append(m_postingType);
+ sb.append("]");
+ return sb.toString();
+ } // toString
+
+ /**
+ * Get Lines
+ * @return FactLine Array
+ */
+ public FactLine[] getLines()
+ {
+ FactLine[] temp = new FactLine[m_lines.size()];
+ m_lines.toArray(temp);
+ return temp;
+ } // getLines
+
+ /**
+ * Save Fact
+ * @param trxName transaction
+ * @return true if all lines were saved
+ */
+ public boolean save (String trxName)
+ {
+ // save Lines
+ for (int i = 0; i < m_lines.size(); i++)
+ {
+ FactLine fl = (FactLine)m_lines.get(i);
+ // log.fine("save - " + fl);
+ if (!fl.save(trxName)) // abort on first error
+ return false;
+ }
+ return true;
+ } // commit
+
+ /**
+ * Get Transaction
+ * @return trx
+ */
+ public String get_TrxName()
+ {
+ return m_trxName;
+ } // getTrxName
+
+ /**
* Set Transaction name
* @param trxName
*/
+ @SuppressWarnings("unused")
private void set_TrxName(String trxName)
{
m_trxName = trxName;
- } // set_TrxName
-
- /**
- * Fact Balance Utility
- *
- * @author Jorg Janke
- * @version $Id: Fact.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
- */
- public class Balance
- {
- /**
- * New Balance
- * @param dr DR
- * @param cr CR
- */
- public Balance (BigDecimal dr, BigDecimal cr)
- {
- DR = dr;
- CR = cr;
- }
-
- /** DR Amount */
- public BigDecimal DR = Env.ZERO;
- /** CR Amount */
- public BigDecimal CR = Env.ZERO;
-
- /**
- * Add
- * @param dr DR
- * @param cr CR
- */
- public void add (BigDecimal dr, BigDecimal cr)
- {
- DR = DR.add(dr);
- CR = CR.add(cr);
- }
-
- /**
- * Get Balance
- * @return balance
- */
- public BigDecimal getBalance()
- {
- return DR.subtract(CR);
- } // getBalance
-
- /**
- * Get Post Balance
- * @return absolute balance - negative if reversal
- */
- public BigDecimal getPostBalance()
- {
- BigDecimal bd = getBalance().abs();
- if (isReversal())
- return bd.negate();
- return bd;
- } // getPostBalance
-
- /**
- * Zero Balance
- * @return true if 0
- */
- public boolean isZeroBalance()
- {
- return getBalance().signum() == 0;
- } // isZeroBalance
-
- /**
- * Reversal
- * @return true if both DR/CR are negative or zero
- */
- public boolean isReversal()
- {
- return DR.signum() <= 0 && CR.signum() <= 0;
- } // isReversal
-
- /**
- * String Representation
- * @return info
- */
- public String toString ()
- {
- StringBuffer sb = new StringBuffer ("Balance[");
- sb.append ("DR=").append(DR)
- .append ("-CR=").append(CR)
- .append(" = ").append(getBalance())
- .append ("]");
- return sb.toString ();
- } // toString
-
- } // Balance
-
-} // Fact
+ } // set_TrxName
+
+ /**
+ * Fact Balance Utility
+ *
+ * @author Jorg Janke
+ * @version $Id: Fact.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
+ */
+ public class Balance
+ {
+ /**
+ * New Balance
+ * @param dr DR
+ * @param cr CR
+ */
+ public Balance (BigDecimal dr, BigDecimal cr)
+ {
+ DR = dr;
+ CR = cr;
+ }
+
+ /** DR Amount */
+ public BigDecimal DR = Env.ZERO;
+ /** CR Amount */
+ public BigDecimal CR = Env.ZERO;
+
+ /**
+ * Add
+ * @param dr DR
+ * @param cr CR
+ */
+ public void add (BigDecimal dr, BigDecimal cr)
+ {
+ DR = DR.add(dr);
+ CR = CR.add(cr);
+ }
+
+ /**
+ * Get Balance
+ * @return balance
+ */
+ public BigDecimal getBalance()
+ {
+ return DR.subtract(CR);
+ } // getBalance
+
+ /**
+ * Get Post Balance
+ * @return absolute balance - negative if reversal
+ */
+ public BigDecimal getPostBalance()
+ {
+ BigDecimal bd = getBalance().abs();
+ if (isReversal())
+ return bd.negate();
+ return bd;
+ } // getPostBalance
+
+ /**
+ * Zero Balance
+ * @return true if 0
+ */
+ public boolean isZeroBalance()
+ {
+ return getBalance().signum() == 0;
+ } // isZeroBalance
+
+ /**
+ * Reversal
+ * @return true if both DR/CR are negative or zero
+ */
+ public boolean isReversal()
+ {
+ return DR.signum() <= 0 && CR.signum() <= 0;
+ } // isReversal
+
+ /**
+ * String Representation
+ * @return info
+ */
+ public String toString ()
+ {
+ StringBuffer sb = new StringBuffer ("Balance[");
+ sb.append ("DR=").append(DR)
+ .append ("-CR=").append(CR)
+ .append(" = ").append(getBalance())
+ .append ("]");
+ return sb.toString ();
+ } // toString
+
+ } // Balance
+
+} // Fact
diff --git a/serverRoot/src/main/server/org/compiere/acct/FactLine.java b/serverRoot/src/main/server/org/compiere/acct/FactLine.java
index 343364b561..f009b4366e 100644
--- a/serverRoot/src/main/server/org/compiere/acct/FactLine.java
+++ b/serverRoot/src/main/server/org/compiere/acct/FactLine.java
@@ -3,947 +3,988 @@
* 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.acct;
-
-import java.math.*;
-import java.sql.*;
-import java.util.*;
-import java.util.logging.*;
-import org.compiere.model.*;
-import org.compiere.util.*;
-
-/**
- * Accounting Fact Entry.
- *
- * @author Jorg Janke
- * @version $Id: FactLine.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
- */
-public final class FactLine extends X_Fact_Acct
-{
- /**
- * Constructor
- * @param ctx context
- * @param AD_Table_ID - Table of Document Source
- * @param Record_ID - Record of document
- * @param Line_ID - Optional line id
- * @param trxName transaction
- */
- public FactLine (Properties ctx, int AD_Table_ID, int Record_ID, int Line_ID, String trxName)
- {
- super(ctx, 0, trxName);
- setAD_Client_ID(0); // do not derive
- setAD_Org_ID(0); // do not derive
- //
- setAmtAcctCr (Env.ZERO);
- setAmtAcctDr (Env.ZERO);
- setAmtSourceCr (Env.ZERO);
- setAmtSourceDr (Env.ZERO);
- // Log.trace(this,Log.l1_User, "FactLine " + AD_Table_ID + ":" + Record_ID);
- setAD_Table_ID (AD_Table_ID);
- setRecord_ID (Record_ID);
- setLine_ID (Line_ID);
- } // FactLine
-
- /** Account */
- private MAccount m_acct = null;
- /** Accounting Schema */
- private MAcctSchema m_acctSchema = null;
- /** Document Header */
- private Doc m_doc = null;
- /** Document Line */
- private DocLine m_docLine = null;
-
- /**
- * Create Reversal (negate DR/CR) of the line
- * @param description new description
- * @return reversal line
- */
- public FactLine reverse (String description)
- {
- FactLine reversal = new FactLine (getCtx(), getAD_Table_ID(), getRecord_ID(), getLine_ID(), get_TrxName());
- reversal.setClientOrg(this); // needs to be set explicitly
- reversal.setDocumentInfo(m_doc, m_docLine);
- reversal.setAccount(m_acctSchema, m_acct);
- reversal.setPostingType(getPostingType());
- //
- reversal.setAmtSource(getC_Currency_ID(), getAmtSourceDr().negate(), getAmtSourceCr().negate());
- reversal.convert();
- reversal.setDescription(description);
- return reversal;
- } // reverse
-
- /**
- * Create Accrual (flip CR/DR) of the line
- * @param description new description
- * @return accrual line
- */
- public FactLine accrue (String description)
- {
- FactLine accrual = new FactLine (getCtx(), getAD_Table_ID(), getRecord_ID(), getLine_ID(), get_TrxName());
- accrual.setClientOrg(this); // needs to be set explicitly
- accrual.setDocumentInfo(m_doc, m_docLine);
- accrual.setAccount(m_acctSchema, m_acct);
- accrual.setPostingType(getPostingType());
- //
- accrual.setAmtSource(getC_Currency_ID(), getAmtSourceCr(), getAmtSourceDr());
- accrual.convert();
- accrual.setDescription(description);
- return accrual;
- } // reverse
-
- /**
- * Set Account Info
- * @param acctSchema account schema
- * @param acct account
- */
- public void setAccount (MAcctSchema acctSchema, MAccount acct)
- {
- m_acctSchema = acctSchema;
- setC_AcctSchema_ID (acctSchema.getC_AcctSchema_ID());
- //
- m_acct = acct;
- if (getAD_Client_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.acct;
+
+import java.math.*;
+import java.sql.*;
+import java.util.*;
+import java.util.logging.*;
+import org.compiere.model.*;
+import org.compiere.util.*;
+
+/**
+ * Accounting Fact Entry.
+ *
+ * @author Jorg Janke
+ * @version $Id: FactLine.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
+ */
+public final class FactLine extends X_Fact_Acct
+{
+ /**
+ * Constructor
+ * @param ctx context
+ * @param AD_Table_ID - Table of Document Source
+ * @param Record_ID - Record of document
+ * @param Line_ID - Optional line id
+ * @param trxName transaction
+ */
+ public FactLine (Properties ctx, int AD_Table_ID, int Record_ID, int Line_ID, String trxName)
+ {
+ super(ctx, 0, trxName);
+ setAD_Client_ID(0); // do not derive
+ setAD_Org_ID(0); // do not derive
+ //
+ setAmtAcctCr (Env.ZERO);
+ setAmtAcctDr (Env.ZERO);
+ setAmtSourceCr (Env.ZERO);
+ setAmtSourceDr (Env.ZERO);
+ // Log.trace(this,Log.l1_User, "FactLine " + AD_Table_ID + ":" + Record_ID);
+ setAD_Table_ID (AD_Table_ID);
+ setRecord_ID (Record_ID);
+ setLine_ID (Line_ID);
+ } // FactLine
+
+ /** Account */
+ private MAccount m_acct = null;
+ /** Accounting Schema */
+ private MAcctSchema m_acctSchema = null;
+ /** Document Header */
+ private Doc m_doc = null;
+ /** Document Line */
+ private DocLine m_docLine = null;
+
+ /**
+ * Create Reversal (negate DR/CR) of the line
+ * @param description new description
+ * @return reversal line
+ */
+ public FactLine reverse (String description)
+ {
+ FactLine reversal = new FactLine (getCtx(), getAD_Table_ID(), getRecord_ID(), getLine_ID(), get_TrxName());
+ reversal.setClientOrg(this); // needs to be set explicitly
+ reversal.setDocumentInfo(m_doc, m_docLine);
+ reversal.setAccount(m_acctSchema, m_acct);
+ reversal.setPostingType(getPostingType());
+ //
+ reversal.setAmtSource(getC_Currency_ID(), getAmtSourceDr().negate(), getAmtSourceCr().negate());
+ reversal.convert();
+ reversal.setDescription(description);
+ return reversal;
+ } // reverse
+
+ /**
+ * Create Accrual (flip CR/DR) of the line
+ * @param description new description
+ * @return accrual line
+ */
+ public FactLine accrue (String description)
+ {
+ FactLine accrual = new FactLine (getCtx(), getAD_Table_ID(), getRecord_ID(), getLine_ID(), get_TrxName());
+ accrual.setClientOrg(this); // needs to be set explicitly
+ accrual.setDocumentInfo(m_doc, m_docLine);
+ accrual.setAccount(m_acctSchema, m_acct);
+ accrual.setPostingType(getPostingType());
+ //
+ accrual.setAmtSource(getC_Currency_ID(), getAmtSourceCr(), getAmtSourceDr());
+ accrual.convert();
+ accrual.setDescription(description);
+ return accrual;
+ } // reverse
+
+ /**
+ * Set Account Info
+ * @param acctSchema account schema
+ * @param acct account
+ */
+ public void setAccount (MAcctSchema acctSchema, MAccount acct)
+ {
+ m_acctSchema = acctSchema;
+ setC_AcctSchema_ID (acctSchema.getC_AcctSchema_ID());
+ //
+ m_acct = acct;
+ if (getAD_Client_ID() == 0)
setAD_Client_ID(m_acct.getAD_Client_ID());
setAccount_ID (m_acct.getAccount_ID());
setC_SubAcct_ID(m_acct.getC_SubAcct_ID());
+
+ // User Defined References
+ MAcctSchemaElement ud1 = m_acctSchema.getAcctSchemaElement(
+ X_C_AcctSchema_Element.ELEMENTTYPE_UserElement1);
+ if (ud1 != null)
+ {
+ String ColumnName1 = ud1.getDisplayColumnName();
+ if (ColumnName1 != null)
+ {
+ int ID1 = 0;
+ if (m_docLine != null)
+ ID1 = m_docLine.getValue(ColumnName1);
+ if (ID1 == 0)
+ {
+ if (m_doc == null)
+ throw new IllegalArgumentException("Document not set yet");
+ ID1 = m_doc.getValue(ColumnName1);
+ }
+ if (ID1 != 0)
+ setUserElement1_ID(ID1);
+ }
+ }
+ MAcctSchemaElement ud2 = m_acctSchema.getAcctSchemaElement(
+ X_C_AcctSchema_Element.ELEMENTTYPE_UserElement2);
+ if (ud2 != null)
+ {
+ String ColumnName2 = ud2.getDisplayColumnName();
+ if (ColumnName2 != null)
+ {
+ int ID2 = 0;
+ if (m_docLine != null)
+ ID2 = m_docLine.getValue(ColumnName2);
+ if (ID2 == 0)
+ {
+ if (m_doc == null)
+ throw new IllegalArgumentException("Document not set yet");
+ ID2 = m_doc.getValue(ColumnName2);
+ }
+ if (ID2 != 0)
+ setUserElement2_ID(ID2);
+ }
+ }
} // setAccount
/**
- * Set Source Amounts
- * @param C_Currency_ID currency
- * @param AmtSourceDr source amount dr
- * @param AmtSourceCr source amount cr
- * @return true, if any if the amount is not zero
- */
- public boolean setAmtSource (int C_Currency_ID, BigDecimal AmtSourceDr, BigDecimal AmtSourceCr)
- {
- setC_Currency_ID (C_Currency_ID);
- if (AmtSourceDr != null)
- setAmtSourceDr (AmtSourceDr);
- if (AmtSourceCr != null)
- setAmtSourceCr (AmtSourceCr);
- // one needs to be non zero
- if (getAmtSourceDr().equals(Env.ZERO) && getAmtSourceCr().equals(Env.ZERO))
- return false;
- // Currency Precision
- int precision = MCurrency.getStdPrecision(getCtx(), C_Currency_ID);
- if (AmtSourceDr != null && AmtSourceDr.scale() > precision)
- {
- BigDecimal AmtSourceDr1 = AmtSourceDr.setScale(precision, BigDecimal.ROUND_HALF_UP);
- log.warning("Source DR Precision " + AmtSourceDr + " -> " + AmtSourceDr1);
- setAmtSourceDr(AmtSourceDr1);
- }
- if (AmtSourceCr != null && AmtSourceCr.scale() > precision)
- {
- BigDecimal AmtSourceCr1 = AmtSourceCr.setScale(precision, BigDecimal.ROUND_HALF_UP);
- log.warning("Source CR Precision " + AmtSourceCr + " -> " + AmtSourceCr1);
- setAmtSourceCr(AmtSourceCr1);
- }
- return true;
- } // setAmtSource
-
- /**
- * Set Accounted Amounts (alternative: call convert)
- * @param AmtAcctDr acct amount dr
- * @param AmtAcctCr acct amount cr
- */
- public void setAmtAcct(BigDecimal AmtAcctDr, BigDecimal AmtAcctCr)
- {
- setAmtAcctDr (AmtAcctDr);
- setAmtAcctCr (AmtAcctCr);
- } // setAmtAcct
-
- /**
- * Set Document Info
- * @param doc document
- * @param docLine doc line
- */
- public void setDocumentInfo(Doc doc, DocLine docLine)
- {
- m_doc = doc;
- m_docLine = docLine;
- // reset
- setAD_Org_ID(0);
- setC_SalesRegion_ID(0);
- // Client
- if (getAD_Client_ID() == 0)
- setAD_Client_ID (m_doc.getAD_Client_ID());
- // Date Trx
- setDateTrx (m_doc.getDateDoc());
- if (m_docLine != null && m_docLine.getDateDoc() != null)
- setDateTrx (m_docLine.getDateDoc());
- // Date Acct
- setDateAcct (m_doc.getDateAcct());
- if (m_docLine != null && m_docLine.getDateAcct() != null)
- setDateAcct (m_docLine.getDateAcct());
- // Period, Tax
- if (m_docLine != null && m_docLine.getC_Period_ID() != 0)
- setC_Period_ID(m_docLine.getC_Period_ID());
- else
- setC_Period_ID (m_doc.getC_Period_ID());
- if (m_docLine != null)
- setC_Tax_ID (m_docLine.getC_Tax_ID());
- // Description
- StringBuffer description = new StringBuffer(m_doc.getDocumentNo());
- if (m_docLine != null)
- {
- description.append(" #").append(m_docLine.getLine());
- if (m_docLine.getDescription() != null)
- description.append(" (").append(m_docLine.getDescription()).append(")");
- else if (m_doc.getDescription() != null && m_doc.getDescription().length() > 0)
- description.append(" (").append(m_doc.getDescription()).append(")");
- }
- else if (m_doc.getDescription() != null && m_doc.getDescription().length() > 0)
- description.append(" (").append(m_doc.getDescription()).append(")");
- setDescription(description.toString());
- // Journal Info
- setGL_Budget_ID (m_doc.getGL_Budget_ID());
- setGL_Category_ID (m_doc.getGL_Category_ID());
-
- // Product
- if (m_docLine != null)
- setM_Product_ID (m_docLine.getM_Product_ID());
- if (getM_Product_ID() == 0)
- setM_Product_ID (m_doc.getM_Product_ID());
- // UOM
- if (m_docLine != null)
- setC_UOM_ID (m_docLine.getC_UOM_ID());
- // Qty
- if (get_Value("Qty") == null) // not previously set
- {
- setQty (m_doc.getQty()); // neg = outgoing
- if (m_docLine != null)
- setQty (m_docLine.getQty());
- }
-
- // Loc From (maybe set earlier)
- if (getC_LocFrom_ID() == 0 && m_docLine != null)
- setC_LocFrom_ID (m_docLine.getC_LocFrom_ID());
- if (getC_LocFrom_ID() == 0)
- setC_LocFrom_ID (m_doc.getC_LocFrom_ID());
- // Loc To (maybe set earlier)
- if (getC_LocTo_ID() == 0 && m_docLine != null)
- setC_LocTo_ID (m_docLine.getC_LocTo_ID());
- if (getC_LocTo_ID() == 0)
- setC_LocTo_ID (m_doc.getC_LocTo_ID());
- // BPartner
- if (m_docLine != null)
- setC_BPartner_ID (m_docLine.getC_BPartner_ID());
- if (getC_BPartner_ID() == 0)
- setC_BPartner_ID (m_doc.getC_BPartner_ID());
- // Sales Region from BPLocation/Sales Rep
- // Trx Org
- if (m_docLine != null)
- setAD_OrgTrx_ID (m_docLine.getAD_OrgTrx_ID());
- if (getAD_OrgTrx_ID() == 0)
- setAD_OrgTrx_ID (m_doc.getAD_OrgTrx_ID());
- // Project
- if (m_docLine != null)
- setC_Project_ID (m_docLine.getC_Project_ID());
- if (getC_Project_ID() == 0)
- setC_Project_ID (m_doc.getC_Project_ID());
- // Campaign
- if (m_docLine != null)
- setC_Campaign_ID (m_docLine.getC_Campaign_ID());
- if (getC_Campaign_ID() == 0)
- setC_Campaign_ID (m_doc.getC_Campaign_ID());
- // Activity
- if (m_docLine != null)
- setC_Activity_ID (m_docLine.getC_Activity_ID());
- if (getC_Activity_ID() == 0)
- setC_Activity_ID (m_doc.getC_Activity_ID());
- // User List 1
- if (m_docLine != null)
- setUser1_ID (m_docLine.getUser1_ID());
- if (getUser1_ID() == 0)
- setUser1_ID (m_doc.getUser1_ID());
- // User List 2
- if (m_docLine != null)
+ * Set Source Amounts
+ * @param C_Currency_ID currency
+ * @param AmtSourceDr source amount dr
+ * @param AmtSourceCr source amount cr
+ * @return true, if any if the amount is not zero
+ */
+ public boolean setAmtSource (int C_Currency_ID, BigDecimal AmtSourceDr, BigDecimal AmtSourceCr)
+ {
+ setC_Currency_ID (C_Currency_ID);
+ if (AmtSourceDr != null)
+ setAmtSourceDr (AmtSourceDr);
+ if (AmtSourceCr != null)
+ setAmtSourceCr (AmtSourceCr);
+ // one needs to be non zero
+ if (getAmtSourceDr().equals(Env.ZERO) && getAmtSourceCr().equals(Env.ZERO))
+ return false;
+ // Currency Precision
+ int precision = MCurrency.getStdPrecision(getCtx(), C_Currency_ID);
+ if (AmtSourceDr != null && AmtSourceDr.scale() > precision)
+ {
+ BigDecimal AmtSourceDr1 = AmtSourceDr.setScale(precision, BigDecimal.ROUND_HALF_UP);
+ log.warning("Source DR Precision " + AmtSourceDr + " -> " + AmtSourceDr1);
+ setAmtSourceDr(AmtSourceDr1);
+ }
+ if (AmtSourceCr != null && AmtSourceCr.scale() > precision)
+ {
+ BigDecimal AmtSourceCr1 = AmtSourceCr.setScale(precision, BigDecimal.ROUND_HALF_UP);
+ log.warning("Source CR Precision " + AmtSourceCr + " -> " + AmtSourceCr1);
+ setAmtSourceCr(AmtSourceCr1);
+ }
+ return true;
+ } // setAmtSource
+
+ /**
+ * Set Accounted Amounts (alternative: call convert)
+ * @param AmtAcctDr acct amount dr
+ * @param AmtAcctCr acct amount cr
+ */
+ public void setAmtAcct(BigDecimal AmtAcctDr, BigDecimal AmtAcctCr)
+ {
+ setAmtAcctDr (AmtAcctDr);
+ setAmtAcctCr (AmtAcctCr);
+ } // setAmtAcct
+
+ /**
+ * Set Document Info
+ * @param doc document
+ * @param docLine doc line
+ */
+ public void setDocumentInfo(Doc doc, DocLine docLine)
+ {
+ m_doc = doc;
+ m_docLine = docLine;
+ // reset
+ setAD_Org_ID(0);
+ setC_SalesRegion_ID(0);
+ // Client
+ if (getAD_Client_ID() == 0)
+ setAD_Client_ID (m_doc.getAD_Client_ID());
+ // Date Trx
+ setDateTrx (m_doc.getDateDoc());
+ if (m_docLine != null && m_docLine.getDateDoc() != null)
+ setDateTrx (m_docLine.getDateDoc());
+ // Date Acct
+ setDateAcct (m_doc.getDateAcct());
+ if (m_docLine != null && m_docLine.getDateAcct() != null)
+ setDateAcct (m_docLine.getDateAcct());
+ // Period, Tax
+ if (m_docLine != null && m_docLine.getC_Period_ID() != 0)
+ setC_Period_ID(m_docLine.getC_Period_ID());
+ else
+ setC_Period_ID (m_doc.getC_Period_ID());
+ if (m_docLine != null)
+ setC_Tax_ID (m_docLine.getC_Tax_ID());
+ // Description
+ StringBuffer description = new StringBuffer(m_doc.getDocumentNo());
+ if (m_docLine != null)
+ {
+ description.append(" #").append(m_docLine.getLine());
+ if (m_docLine.getDescription() != null)
+ description.append(" (").append(m_docLine.getDescription()).append(")");
+ else if (m_doc.getDescription() != null && m_doc.getDescription().length() > 0)
+ description.append(" (").append(m_doc.getDescription()).append(")");
+ }
+ else if (m_doc.getDescription() != null && m_doc.getDescription().length() > 0)
+ description.append(" (").append(m_doc.getDescription()).append(")");
+ setDescription(description.toString());
+ // Journal Info
+ setGL_Budget_ID (m_doc.getGL_Budget_ID());
+ setGL_Category_ID (m_doc.getGL_Category_ID());
+
+ // Product
+ if (m_docLine != null)
+ setM_Product_ID (m_docLine.getM_Product_ID());
+ if (getM_Product_ID() == 0)
+ setM_Product_ID (m_doc.getM_Product_ID());
+ // UOM
+ if (m_docLine != null)
+ setC_UOM_ID (m_docLine.getC_UOM_ID());
+ // Qty
+ if (get_Value("Qty") == null) // not previously set
+ {
+ setQty (m_doc.getQty()); // neg = outgoing
+ if (m_docLine != null)
+ setQty (m_docLine.getQty());
+ }
+
+ // Loc From (maybe set earlier)
+ if (getC_LocFrom_ID() == 0 && m_docLine != null)
+ setC_LocFrom_ID (m_docLine.getC_LocFrom_ID());
+ if (getC_LocFrom_ID() == 0)
+ setC_LocFrom_ID (m_doc.getC_LocFrom_ID());
+ // Loc To (maybe set earlier)
+ if (getC_LocTo_ID() == 0 && m_docLine != null)
+ setC_LocTo_ID (m_docLine.getC_LocTo_ID());
+ if (getC_LocTo_ID() == 0)
+ setC_LocTo_ID (m_doc.getC_LocTo_ID());
+ // BPartner
+ if (m_docLine != null)
+ setC_BPartner_ID (m_docLine.getC_BPartner_ID());
+ if (getC_BPartner_ID() == 0)
+ setC_BPartner_ID (m_doc.getC_BPartner_ID());
+ // Sales Region from BPLocation/Sales Rep
+ // Trx Org
+ if (m_docLine != null)
+ setAD_OrgTrx_ID (m_docLine.getAD_OrgTrx_ID());
+ if (getAD_OrgTrx_ID() == 0)
+ setAD_OrgTrx_ID (m_doc.getAD_OrgTrx_ID());
+ // Project
+ if (m_docLine != null)
+ setC_Project_ID (m_docLine.getC_Project_ID());
+ if (getC_Project_ID() == 0)
+ setC_Project_ID (m_doc.getC_Project_ID());
+ // Campaign
+ if (m_docLine != null)
+ setC_Campaign_ID (m_docLine.getC_Campaign_ID());
+ if (getC_Campaign_ID() == 0)
+ setC_Campaign_ID (m_doc.getC_Campaign_ID());
+ // Activity
+ if (m_docLine != null)
+ setC_Activity_ID (m_docLine.getC_Activity_ID());
+ if (getC_Activity_ID() == 0)
+ setC_Activity_ID (m_doc.getC_Activity_ID());
+ // User List 1
+ if (m_docLine != null)
+ setUser1_ID (m_docLine.getUser1_ID());
+ if (getUser1_ID() == 0)
+ setUser1_ID (m_doc.getUser1_ID());
+ // User List 2
+ if (m_docLine != null)
setUser2_ID (m_docLine.getUser2_ID());
if (getUser2_ID() == 0)
setUser2_ID (m_doc.getUser2_ID());
- // User Defined
-
+ // References in setAccount
} // setDocumentInfo
/**
- * Get Document Line
- * @return doc line
- */
- protected DocLine getDocLine()
- {
- return m_docLine;
- } // getDocLine
-
- /**
- * Set Description
- * @param description description
- */
- public void addDescription (String description)
- {
- String original = getDescription();
- if (original == null || original.trim().length() == 0)
- super.setDescription(description);
- else
- super.setDescription(original + " - " + description);
- } // addDescription
-
- /**
- * Set Warehouse Locator.
- * - will overwrite Organization -
- * @param M_Locator_ID locator
- */
- public void setM_Locator_ID (int M_Locator_ID)
- {
- super.setM_Locator_ID (M_Locator_ID);
- setAD_Org_ID(0); // reset
- } // setM_Locator_ID
-
-
- /**************************************************************************
- * Set Location
- * @param C_Location_ID location
- * @param isFrom from
- */
- public void setLocation (int C_Location_ID, boolean isFrom)
- {
- if (isFrom)
- setC_LocFrom_ID (C_Location_ID);
- else
- setC_LocTo_ID (C_Location_ID);
- } // setLocator
-
- /**
- * Set Location from Locator
- * @param M_Locator_ID locator
- * @param isFrom from
- */
- public void setLocationFromLocator (int M_Locator_ID, boolean isFrom)
- {
- if (M_Locator_ID == 0)
- return;
- int C_Location_ID = 0;
- String sql = "SELECT w.C_Location_ID FROM M_Warehouse w, M_Locator l "
- + "WHERE w.M_Warehouse_ID=l.M_Warehouse_ID AND l.M_Locator_ID=?";
- try
- {
- PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
- pstmt.setInt(1, M_Locator_ID);
- ResultSet rs = pstmt.executeQuery();
- if (rs.next())
- C_Location_ID = rs.getInt(1);
- rs.close();
- pstmt.close();
- }
- catch (SQLException e)
- {
- log.log(Level.SEVERE, sql, e);
- return;
- }
- if (C_Location_ID != 0)
- setLocation (C_Location_ID, isFrom);
- } // setLocationFromLocator
-
- /**
- * Set Location from Busoness Partner Location
- * @param C_BPartner_Location_ID bp location
- * @param isFrom from
- */
- public void setLocationFromBPartner (int C_BPartner_Location_ID, boolean isFrom)
- {
- if (C_BPartner_Location_ID == 0)
- return;
- int C_Location_ID = 0;
- String sql = "SELECT C_Location_ID FROM C_BPartner_Location WHERE C_BPartner_Location_ID=?";
- try
- {
- PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
- pstmt.setInt(1, C_BPartner_Location_ID);
- ResultSet rs = pstmt.executeQuery();
- if (rs.next())
- C_Location_ID = rs.getInt(1);
- rs.close();
- pstmt.close();
- }
- catch (SQLException e)
- {
- log.log(Level.SEVERE, sql, e);
- return;
- }
- if (C_Location_ID != 0)
- setLocation (C_Location_ID, isFrom);
- } // setLocationFromBPartner
-
- /**
- * Set Location from Organization
- * @param AD_Org_ID org
- * @param isFrom from
- */
- public void setLocationFromOrg (int AD_Org_ID, boolean isFrom)
- {
- if (AD_Org_ID == 0)
- return;
- int C_Location_ID = 0;
- String sql = "SELECT C_Location_ID FROM AD_OrgInfo WHERE AD_Org_ID=?";
- try
- {
- PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
- pstmt.setInt(1, AD_Org_ID);
- ResultSet rs = pstmt.executeQuery();
- if (rs.next())
- C_Location_ID = rs.getInt(1);
- rs.close();
- pstmt.close();
- }
- catch (SQLException e)
- {
- log.log(Level.SEVERE, sql, e);
- return;
- }
- if (C_Location_ID != 0)
- setLocation (C_Location_ID, isFrom);
- } // setLocationFromOrg
-
-
- /**************************************************************************
- * Returns Source Balance of line
- * @return source balance
- */
- public BigDecimal getSourceBalance()
- {
- if (getAmtSourceDr() == null)
- setAmtSourceDr (Env.ZERO);
- if (getAmtSourceCr() == null)
- setAmtSourceCr (Env.ZERO);
- //
- return getAmtSourceDr().subtract(getAmtSourceCr());
- } // getSourceBalance
-
- /**
- * Is Debit Source Balance
- * @return true if DR source balance
- */
- public boolean isDrSourceBalance()
- {
- return getSourceBalance().signum() != -1;
- } // isDrSourceBalance
-
- /**
- * Get Accounted Balance
- * @return accounting balance
- */
- public BigDecimal getAcctBalance()
- {
- if (getAmtAcctDr() == null)
- setAmtAcctDr (Env.ZERO);
- if (getAmtAcctCr() == null)
- setAmtAcctCr (Env.ZERO);
- return getAmtAcctDr().subtract(getAmtAcctCr());
- } // getAcctBalance
-
- /**
- * Is Account on Balance Sheet
- * @return true if account is a balance sheet account
- */
- public boolean isBalanceSheet()
- {
- return m_acct.isBalanceSheet();
- } // isBalanceSheet
-
- /**
- * Currect Accounting Amount.
- *
- * Example: 1 -1 1 -1
- * Old 100/0 100/0 0/100 0/100
- * New 99/0 101/0 0/99 0/101
- *
- * @param deltaAmount delta amount
- */
- public void currencyCorrect (BigDecimal deltaAmount)
- {
- boolean negative = deltaAmount.compareTo(Env.ZERO) < 0;
- boolean adjustDr = getAmtAcctDr().abs().compareTo(getAmtAcctCr().abs()) > 0;
-
- log.fine(deltaAmount.toString()
- + "; Old-AcctDr=" + getAmtAcctDr() + ",AcctCr=" + getAmtAcctCr()
- + "; Negative=" + negative + "; AdjustDr=" + adjustDr);
-
- if (adjustDr)
- if (negative)
- setAmtAcctDr (getAmtAcctDr().subtract(deltaAmount));
- else
- setAmtAcctDr (getAmtAcctDr().subtract(deltaAmount));
- else
- if (negative)
- setAmtAcctCr (getAmtAcctCr().add(deltaAmount));
- else
- setAmtAcctCr (getAmtAcctCr().add(deltaAmount));
-
- log.fine("New-AcctDr=" + getAmtAcctDr() + ",AcctCr=" + getAmtAcctCr());
- } // currencyCorrect
-
- /**
- * Convert to Accounted Currency
- * @return true if converted
- */
- public boolean convert ()
- {
- // Document has no currency
- if (getC_Currency_ID() == Doc.NO_CURRENCY)
- setC_Currency_ID (m_acctSchema.getC_Currency_ID());
-
- if (m_acctSchema.getC_Currency_ID() == getC_Currency_ID())
- {
- setAmtAcctDr (getAmtSourceDr());
- setAmtAcctCr (getAmtSourceCr());
- return true;
- }
- // Get Conversion Type from Line or Header
- int C_ConversionType_ID = 0;
- int AD_Org_ID = 0;
- if (m_docLine != null) // get from line
- {
- C_ConversionType_ID = m_docLine.getC_ConversionType_ID();
- AD_Org_ID = m_docLine.getAD_Org_ID();
- }
- if (C_ConversionType_ID == 0) // get from header
- {
- if (m_doc == null)
- {
- log.severe ("No Document VO");
- return false;
- }
- C_ConversionType_ID = m_doc.getC_ConversionType_ID();
- if (AD_Org_ID == 0)
- AD_Org_ID = m_doc.getAD_Org_ID();
- }
- setAmtAcctDr (MConversionRate.convert (getCtx(),
- getAmtSourceDr(), getC_Currency_ID(), m_acctSchema.getC_Currency_ID(),
- getDateAcct(), C_ConversionType_ID, m_doc.getAD_Client_ID(), AD_Org_ID));
- if (getAmtAcctDr() == null)
- return false;
- setAmtAcctCr (MConversionRate.convert (getCtx(),
- getAmtSourceCr(), getC_Currency_ID(), m_acctSchema.getC_Currency_ID(),
- getDateAcct(), C_ConversionType_ID, m_doc.getAD_Client_ID(), AD_Org_ID));
- return true;
- } // convert
-
- /**
- * Get Account
- * @return account
- */
- public MAccount getAccount()
- {
- return m_acct;
- } // getAccount
-
- /**
- * To String
- * @return String
- */
- public String toString()
- {
- StringBuffer sb = new StringBuffer("FactLine=[");
- sb.append(getAD_Table_ID()).append(":").append(getRecord_ID())
- .append(",").append(m_acct)
- .append(",Cur=").append(getC_Currency_ID())
- .append(", DR=").append(getAmtSourceDr()).append("|").append(getAmtAcctDr())
- .append(", CR=").append(getAmtSourceCr()).append("|").append(getAmtAcctCr())
- .append("]");
- return sb.toString();
- } // toString
-
-
- /**
- * Get AD_Org_ID (balancing segment).
- * (if not set directly - from document line, document, account, locator)
- *
- * Note that Locator needs to be set before - otherwise
- * segment balancing might produce the wrong results
- * @return AD_Org_ID
- */
- public int getAD_Org_ID()
- {
- if (super.getAD_Org_ID() != 0) // set earlier
- return super.getAD_Org_ID();
- // Prio 1 - get from locator - if exist
- if (getM_Locator_ID() != 0)
- {
- String sql = "SELECT AD_Org_ID FROM M_Locator WHERE M_Locator_ID=? AND AD_Client_ID=?";
- try
- {
- PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
- pstmt.setInt(1, getM_Locator_ID());
- pstmt.setInt(2, getAD_Client_ID());
- ResultSet rs = pstmt.executeQuery();
- if (rs.next())
- {
- setAD_Org_ID (rs.getInt(1));
- log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (1 from M_Locator_ID=" + getM_Locator_ID() + ")");
- }
- else
- log.log(Level.SEVERE, "AD_Org_ID - Did not find M_Locator_ID=" + getM_Locator_ID());
- rs.close();
- pstmt.close();
- }
- catch (SQLException e)
- {
- log.log(Level.SEVERE, sql, e);
- }
- } // M_Locator_ID != 0
-
- // Prio 2 - get from doc line - if exists (document context overwrites)
- if (m_docLine != null && super.getAD_Org_ID() == 0)
- {
- setAD_Org_ID (m_docLine.getAD_Org_ID());
- log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (2 from DocumentLine)");
- }
- // Prio 3 - get from doc - if not GL
- if (m_doc != null && super.getAD_Org_ID() == 0)
- {
- if (Doc.DOCTYPE_GLJournal.equals (m_doc.getDocumentType()))
- {
- setAD_Org_ID (m_acct.getAD_Org_ID()); // inter-company GL
- log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (3 from Acct)");
- }
- else
- {
- setAD_Org_ID (m_doc.getAD_Org_ID());
- log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (3 from Document)");
- }
- }
- // Prio 4 - get from account - if not GL
- if (m_doc != null && super.getAD_Org_ID() == 0)
- {
- if (Doc.DOCTYPE_GLJournal.equals (m_doc.getDocumentType()))
- {
- setAD_Org_ID (m_doc.getAD_Org_ID());
- log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (4 from Document)");
- }
- else
- {
- setAD_Org_ID (m_acct.getAD_Org_ID());
- log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (4 from Acct)");
- }
- }
- return super.getAD_Org_ID();
- } // setAD_Org_ID
-
-
- /**
- * Get/derive Sales Region
- * @return Sales Region
- */
- public int getC_SalesRegion_ID ()
- {
- if (super.getC_SalesRegion_ID() != 0)
- return super.getC_SalesRegion_ID();
- //
- if (m_docLine != null)
- setC_SalesRegion_ID (m_docLine.getC_SalesRegion_ID());
- if (m_doc != null)
- {
- if (super.getC_SalesRegion_ID() == 0)
- setC_SalesRegion_ID (m_doc.getC_SalesRegion_ID());
- if (super.getC_SalesRegion_ID() == 0 && m_doc.getBP_C_SalesRegion_ID() > 0)
- setC_SalesRegion_ID (m_doc.getBP_C_SalesRegion_ID());
- // derive SalesRegion if AcctSegment
- if (super.getC_SalesRegion_ID() == 0
- && m_doc.getC_BPartner_Location_ID() != 0
- && m_doc.getBP_C_SalesRegion_ID() == -1) // never tried
- // && m_acctSchema.isAcctSchemaElement(MAcctSchemaElement.ELEMENTTYPE_SalesRegion))
- {
- String sql = "SELECT COALESCE(C_SalesRegion_ID,0) FROM C_BPartner_Location WHERE C_BPartner_Location_ID=?";
- setC_SalesRegion_ID (DB.getSQLValue(null,
- sql, m_doc.getC_BPartner_Location_ID()));
- if (super.getC_SalesRegion_ID() != 0) // save in VO
- {
- m_doc.setBP_C_SalesRegion_ID(super.getC_SalesRegion_ID());
- log.fine("C_SalesRegion_ID=" + super.getC_SalesRegion_ID() + " (from BPL)" );
- }
- else // From Sales Rep of Document -> Sales Region
- {
- sql = "SELECT COALESCE(MAX(C_SalesRegion_ID),0) FROM C_SalesRegion WHERE SalesRep_ID=?";
- setC_SalesRegion_ID (DB.getSQLValue(null,
- sql, m_doc.getSalesRep_ID()));
- if (super.getC_SalesRegion_ID() != 0) // save in VO
- {
- m_doc.setBP_C_SalesRegion_ID(super.getC_SalesRegion_ID());
- log.fine("C_SalesRegion_ID=" + super.getC_SalesRegion_ID() + " (from SR)" );
- }
- else
- m_doc.setBP_C_SalesRegion_ID(-2); // don't try again
- }
- }
- if (m_acct != null && super.getC_SalesRegion_ID() == 0)
- setC_SalesRegion_ID (m_acct.getC_SalesRegion_ID());
- }
- //
- // log.fine("C_SalesRegion_ID=" + super.getC_SalesRegion_ID()
- // + ", C_BPartner_Location_ID=" + m_docVO.C_BPartner_Location_ID
- // + ", BP_C_SalesRegion_ID=" + m_docVO.BP_C_SalesRegion_ID
- // + ", SR=" + m_acctSchema.isAcctSchemaElement(MAcctSchemaElement.ELEMENTTYPE_SalesRegion));
- return super.getC_SalesRegion_ID();
- } // getC_SalesRegion_ID
-
-
- /**
- * Before Save
- * @param newRecord new
- * @return true
- */
- protected boolean beforeSave (boolean newRecord)
- {
- if (newRecord)
- {
- log.fine(toString());
- //
- getAD_Org_ID();
- getC_SalesRegion_ID();
- // Set Default Account Info
- if (getM_Product_ID() == 0)
- setM_Product_ID (m_acct.getM_Product_ID());
- if (getC_LocFrom_ID() == 0)
- setC_LocFrom_ID (m_acct.getC_LocFrom_ID());
- if (getC_LocTo_ID() == 0)
- setC_LocTo_ID (m_acct.getC_LocTo_ID());
- if (getC_BPartner_ID() == 0)
- setC_BPartner_ID (m_acct.getC_BPartner_ID());
- if (getAD_OrgTrx_ID() == 0)
- setAD_OrgTrx_ID (m_acct.getAD_OrgTrx_ID());
- if (getC_Project_ID() == 0)
- setC_Project_ID (m_acct.getC_Project_ID());
- if (getC_Campaign_ID() == 0)
- setC_Campaign_ID (m_acct.getC_Campaign_ID());
- if (getC_Activity_ID() == 0)
- setC_Activity_ID (m_acct.getC_Activity_ID());
- if (getUser1_ID() == 0)
- setUser1_ID (m_acct.getUser1_ID());
- if (getUser2_ID() == 0)
- setUser2_ID (m_acct.getUser2_ID());
-
- // Revenue Recognition for AR Invoices
- if (m_doc.getDocumentType().equals(Doc.DOCTYPE_ARInvoice)
- && m_docLine != null
- && m_docLine.getC_RevenueRecognition_ID() != 0)
- {
- int AD_User_ID = 0;
- setAccount_ID (
- createRevenueRecognition (
- m_docLine.getC_RevenueRecognition_ID(), m_docLine.get_ID(),
- getAD_Client_ID(), getAD_Org_ID(), AD_User_ID,
- getAccount_ID(), getC_SubAcct_ID(),
- getM_Product_ID(), getC_BPartner_ID(), getAD_OrgTrx_ID(),
- getC_LocFrom_ID(), getC_LocTo_ID(),
- getC_SalesRegion_ID(), getC_Project_ID(),
- getC_Campaign_ID(), getC_Activity_ID(),
- getUser1_ID(), getUser2_ID(),
- getUserElement1_ID(), getUserElement2_ID())
- );
- }
- }
- return true;
- } // beforeSave
-
-
- /**************************************************************************
- * Revenue Recognition.
- * Called from FactLine.save
- *
- * Create Revenue recognition plan and return Unearned Revenue account
- * to be used instead of Revenue Account. If not found, it returns
- * the revenue account.
- *
- * @param C_RevenueRecognition_ID revenue recognition
- * @param C_InvoiceLine_ID invoice line
- * @param AD_Client_ID client
- * @param AD_Org_ID org
- * @param AD_User_ID user
- * @param Account_ID of Revenue Account
- * @param C_SubAcct_ID sub account
- * @param M_Product_ID product
- * @param C_BPartner_ID bpartner
- * @param AD_OrgTrx_ID trx org
- * @param C_LocFrom_ID loc from
- * @param C_LocTo_ID loc to
- * @param C_SRegion_ID sales region
- * @param C_Project_ID project
- * @param C_Campaign_ID campaign
- * @param C_Activity_ID activity
- * @param User1_ID user1
- * @param User2_ID user2
- * @param UserElement1_ID user element 1
- * @param UserElement2_ID user element 2
- * @return Account_ID for Unearned Revenue or Revenue Account if not found
- */
- private int createRevenueRecognition (
- int C_RevenueRecognition_ID, int C_InvoiceLine_ID,
- int AD_Client_ID, int AD_Org_ID, int AD_User_ID,
- int Account_ID, int C_SubAcct_ID,
- int M_Product_ID, int C_BPartner_ID, int AD_OrgTrx_ID,
- int C_LocFrom_ID, int C_LocTo_ID, int C_SRegion_ID, int C_Project_ID,
- int C_Campaign_ID, int C_Activity_ID,
- int User1_ID, int User2_ID, int UserElement1_ID, int UserElement2_ID)
- {
- log.fine("From Accout_ID=" + Account_ID);
- // get VC for P_Revenue (from Product)
- MAccount revenue = MAccount.get(getCtx(),
- AD_Client_ID, AD_Org_ID, getC_AcctSchema_ID(), Account_ID, C_SubAcct_ID,
- M_Product_ID, C_BPartner_ID, AD_OrgTrx_ID, C_LocFrom_ID, C_LocTo_ID, C_SRegion_ID,
- C_Project_ID, C_Campaign_ID, C_Activity_ID,
- User1_ID, User2_ID, UserElement1_ID, UserElement2_ID);
- if (revenue != null && revenue.get_ID() == 0)
- revenue.save();
- if (revenue == null || revenue.get_ID() == 0)
- {
- log.severe ("Revenue_Acct not found");
- return Account_ID;
- }
- int P_Revenue_Acct = revenue.get_ID();
-
- // get Unearned Revenue Acct from BPartner Group
- int UnearnedRevenue_Acct = 0;
- int new_Account_ID = 0;
- String sql = "SELECT ga.UnearnedRevenue_Acct, vc.Account_ID "
- + "FROM C_BP_Group_Acct ga, C_BPartner p, C_ValidCombination vc "
- + "WHERE ga.C_BP_Group_ID=p.C_BP_Group_ID"
- + " AND ga.UnearnedRevenue_Acct=vc.C_ValidCombination_ID"
- + " AND ga.C_AcctSchema_ID=? AND p.C_BPartner_ID=?";
- try
- {
- PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
- pstmt.setInt(1, getC_AcctSchema_ID());
- pstmt.setInt(2, C_BPartner_ID);
- ResultSet rs = pstmt.executeQuery();
- if (rs.next())
- {
- UnearnedRevenue_Acct = rs.getInt(1);
- new_Account_ID = rs.getInt(2);
- }
- rs.close();
- pstmt.close();
- }
- catch (SQLException e)
- {
- log.log(Level.SEVERE, sql, e);
- }
- if (new_Account_ID == 0)
- {
- log.severe ("UnearnedRevenue_Acct not found");
- return Account_ID;
- }
-
- MRevenueRecognitionPlan plan = new MRevenueRecognitionPlan(getCtx(), 0, null);
- plan.setC_RevenueRecognition_ID (C_RevenueRecognition_ID);
- plan.setC_AcctSchema_ID (getC_AcctSchema_ID());
- plan.setC_InvoiceLine_ID (C_InvoiceLine_ID);
- plan.setUnEarnedRevenue_Acct (UnearnedRevenue_Acct);
- plan.setP_Revenue_Acct (P_Revenue_Acct);
- plan.setC_Currency_ID (getC_Currency_ID());
- plan.setTotalAmt (getAcctBalance());
- if (!plan.save(get_TrxName()))
- {
- log.severe ("Plan NOT created");
- return Account_ID;
- }
- log.fine("From Acctount_ID=" + Account_ID + " to " + new_Account_ID
- + " - Plan from UnearnedRevenue_Acct=" + UnearnedRevenue_Acct + " to Revenue_Acct=" + P_Revenue_Acct);
- return new_Account_ID;
- } // createRevenueRecognition
-
-
- /**************************************************************************
- * Update Line with reversed Original Amount in Accounting Currency.
- * Also copies original dimensions like Project, etc.
- * Called from Doc_MatchInv
- * @param AD_Table_ID table
- * @param Record_ID record
- * @param Line_ID line
- * @param multiplier targetQty/documentQty
- * @return true if success
- */
- public boolean updateReverseLine (int AD_Table_ID, int Record_ID, int Line_ID,
- BigDecimal multiplier)
- {
- boolean success = false;
-
- String sql = "SELECT * "
- + "FROM Fact_Acct "
- + "WHERE C_AcctSchema_ID=? AND AD_Table_ID=? AND Record_ID=?"
- + " AND Line_ID=? AND Account_ID=?";
- try
- {
- PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
- pstmt.setInt(1, getC_AcctSchema_ID());
- pstmt.setInt(2, AD_Table_ID);
- pstmt.setInt(3, Record_ID);
- pstmt.setInt(4, Line_ID);
- pstmt.setInt(5, m_acct.getAccount_ID());
- ResultSet rs = pstmt.executeQuery();
- if (rs.next())
- {
- MFactAcct fact = new MFactAcct(getCtx(), rs, get_TrxName());
- // Accounted Amounts - reverse
- BigDecimal dr = fact.getAmtAcctDr();
- BigDecimal cr = fact.getAmtAcctCr();
- setAmtAcctDr (cr.multiply(multiplier));
- setAmtAcctCr (dr.multiply(multiplier));
- // Source Amounts
- setAmtSourceDr (getAmtAcctDr());
- setAmtSourceCr (getAmtAcctCr());
- //
- success = true;
- log.fine(new StringBuffer("(Table=").append(AD_Table_ID)
- .append(",Record_ID=").append(Record_ID)
- .append(",Line=").append(Record_ID)
- .append(", Account=").append(m_acct)
- .append(",dr=").append(dr).append(",cr=").append(cr)
- .append(") - DR=").append(getAmtSourceDr()).append("|").append(getAmtAcctDr())
- .append(", CR=").append(getAmtSourceCr()).append("|").append(getAmtAcctCr())
- .toString());
- // Dimensions
- setAD_OrgTrx_ID(fact.getAD_OrgTrx_ID());
- setC_Project_ID (fact.getC_Project_ID());
- setC_Activity_ID(fact.getC_Activity_ID());
- setC_Campaign_ID(fact.getC_Campaign_ID());
- setC_SalesRegion_ID(fact.getC_SalesRegion_ID());
- setC_LocFrom_ID(fact.getC_LocFrom_ID());
- setC_LocTo_ID(fact.getC_LocTo_ID());
- setM_Product_ID(fact.getM_Product_ID());
- setM_Locator_ID(fact.getM_Locator_ID());
- setUser1_ID(fact.getUser1_ID());
- setUser2_ID(fact.getUser2_ID());
- setC_UOM_ID(fact.getC_UOM_ID());
- setC_Tax_ID(fact.getC_Tax_ID());
- // Org for cross charge
- setAD_Org_ID (fact.getAD_Org_ID());
- }
- else
- log.warning(new StringBuffer("Not Found (try later) ")
- .append(",C_AcctSchema_ID=").append(getC_AcctSchema_ID())
- .append(", AD_Table_ID=").append(AD_Table_ID)
- .append(",Record_ID=").append(Record_ID)
- .append(",Line_ID=").append(Line_ID)
- .append(", Account_ID=").append(m_acct.getAccount_ID()).toString());
- rs.close();
- pstmt.close();
- }
- catch (SQLException e)
- {
- log.log(Level.SEVERE, sql, e);
- }
- return success;
- } // updateReverseLine
-
-} // FactLine
+ * Get Document Line
+ * @return doc line
+ */
+ protected DocLine getDocLine()
+ {
+ return m_docLine;
+ } // getDocLine
+
+ /**
+ * Set Description
+ * @param description description
+ */
+ public void addDescription (String description)
+ {
+ String original = getDescription();
+ if (original == null || original.trim().length() == 0)
+ super.setDescription(description);
+ else
+ super.setDescription(original + " - " + description);
+ } // addDescription
+
+ /**
+ * Set Warehouse Locator.
+ * - will overwrite Organization -
+ * @param M_Locator_ID locator
+ */
+ public void setM_Locator_ID (int M_Locator_ID)
+ {
+ super.setM_Locator_ID (M_Locator_ID);
+ setAD_Org_ID(0); // reset
+ } // setM_Locator_ID
+
+
+ /**************************************************************************
+ * Set Location
+ * @param C_Location_ID location
+ * @param isFrom from
+ */
+ public void setLocation (int C_Location_ID, boolean isFrom)
+ {
+ if (isFrom)
+ setC_LocFrom_ID (C_Location_ID);
+ else
+ setC_LocTo_ID (C_Location_ID);
+ } // setLocator
+
+ /**
+ * Set Location from Locator
+ * @param M_Locator_ID locator
+ * @param isFrom from
+ */
+ public void setLocationFromLocator (int M_Locator_ID, boolean isFrom)
+ {
+ if (M_Locator_ID == 0)
+ return;
+ int C_Location_ID = 0;
+ String sql = "SELECT w.C_Location_ID FROM M_Warehouse w, M_Locator l "
+ + "WHERE w.M_Warehouse_ID=l.M_Warehouse_ID AND l.M_Locator_ID=?";
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
+ pstmt.setInt(1, M_Locator_ID);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ C_Location_ID = rs.getInt(1);
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ return;
+ }
+ if (C_Location_ID != 0)
+ setLocation (C_Location_ID, isFrom);
+ } // setLocationFromLocator
+
+ /**
+ * Set Location from Busoness Partner Location
+ * @param C_BPartner_Location_ID bp location
+ * @param isFrom from
+ */
+ public void setLocationFromBPartner (int C_BPartner_Location_ID, boolean isFrom)
+ {
+ if (C_BPartner_Location_ID == 0)
+ return;
+ int C_Location_ID = 0;
+ String sql = "SELECT C_Location_ID FROM C_BPartner_Location WHERE C_BPartner_Location_ID=?";
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
+ pstmt.setInt(1, C_BPartner_Location_ID);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ C_Location_ID = rs.getInt(1);
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ return;
+ }
+ if (C_Location_ID != 0)
+ setLocation (C_Location_ID, isFrom);
+ } // setLocationFromBPartner
+
+ /**
+ * Set Location from Organization
+ * @param AD_Org_ID org
+ * @param isFrom from
+ */
+ public void setLocationFromOrg (int AD_Org_ID, boolean isFrom)
+ {
+ if (AD_Org_ID == 0)
+ return;
+ int C_Location_ID = 0;
+ String sql = "SELECT C_Location_ID FROM AD_OrgInfo WHERE AD_Org_ID=?";
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
+ pstmt.setInt(1, AD_Org_ID);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ C_Location_ID = rs.getInt(1);
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ return;
+ }
+ if (C_Location_ID != 0)
+ setLocation (C_Location_ID, isFrom);
+ } // setLocationFromOrg
+
+
+ /**************************************************************************
+ * Returns Source Balance of line
+ * @return source balance
+ */
+ public BigDecimal getSourceBalance()
+ {
+ if (getAmtSourceDr() == null)
+ setAmtSourceDr (Env.ZERO);
+ if (getAmtSourceCr() == null)
+ setAmtSourceCr (Env.ZERO);
+ //
+ return getAmtSourceDr().subtract(getAmtSourceCr());
+ } // getSourceBalance
+
+ /**
+ * Is Debit Source Balance
+ * @return true if DR source balance
+ */
+ public boolean isDrSourceBalance()
+ {
+ return getSourceBalance().signum() != -1;
+ } // isDrSourceBalance
+
+ /**
+ * Get Accounted Balance
+ * @return accounting balance
+ */
+ public BigDecimal getAcctBalance()
+ {
+ if (getAmtAcctDr() == null)
+ setAmtAcctDr (Env.ZERO);
+ if (getAmtAcctCr() == null)
+ setAmtAcctCr (Env.ZERO);
+ return getAmtAcctDr().subtract(getAmtAcctCr());
+ } // getAcctBalance
+
+ /**
+ * Is Account on Balance Sheet
+ * @return true if account is a balance sheet account
+ */
+ public boolean isBalanceSheet()
+ {
+ return m_acct.isBalanceSheet();
+ } // isBalanceSheet
+
+ /**
+ * Currect Accounting Amount.
+ *
+ * Example: 1 -1 1 -1
+ * Old 100/0 100/0 0/100 0/100
+ * New 99/0 101/0 0/99 0/101
+ *
+ * @param deltaAmount delta amount
+ */
+ public void currencyCorrect (BigDecimal deltaAmount)
+ {
+ boolean negative = deltaAmount.compareTo(Env.ZERO) < 0;
+ boolean adjustDr = getAmtAcctDr().abs().compareTo(getAmtAcctCr().abs()) > 0;
+
+ log.fine(deltaAmount.toString()
+ + "; Old-AcctDr=" + getAmtAcctDr() + ",AcctCr=" + getAmtAcctCr()
+ + "; Negative=" + negative + "; AdjustDr=" + adjustDr);
+
+ if (adjustDr)
+ if (negative)
+ setAmtAcctDr (getAmtAcctDr().subtract(deltaAmount));
+ else
+ setAmtAcctDr (getAmtAcctDr().subtract(deltaAmount));
+ else
+ if (negative)
+ setAmtAcctCr (getAmtAcctCr().add(deltaAmount));
+ else
+ setAmtAcctCr (getAmtAcctCr().add(deltaAmount));
+
+ log.fine("New-AcctDr=" + getAmtAcctDr() + ",AcctCr=" + getAmtAcctCr());
+ } // currencyCorrect
+
+ /**
+ * Convert to Accounted Currency
+ * @return true if converted
+ */
+ public boolean convert ()
+ {
+ // Document has no currency
+ if (getC_Currency_ID() == Doc.NO_CURRENCY)
+ setC_Currency_ID (m_acctSchema.getC_Currency_ID());
+
+ if (m_acctSchema.getC_Currency_ID() == getC_Currency_ID())
+ {
+ setAmtAcctDr (getAmtSourceDr());
+ setAmtAcctCr (getAmtSourceCr());
+ return true;
+ }
+ // Get Conversion Type from Line or Header
+ int C_ConversionType_ID = 0;
+ int AD_Org_ID = 0;
+ if (m_docLine != null) // get from line
+ {
+ C_ConversionType_ID = m_docLine.getC_ConversionType_ID();
+ AD_Org_ID = m_docLine.getAD_Org_ID();
+ }
+ if (C_ConversionType_ID == 0) // get from header
+ {
+ if (m_doc == null)
+ {
+ log.severe ("No Document VO");
+ return false;
+ }
+ C_ConversionType_ID = m_doc.getC_ConversionType_ID();
+ if (AD_Org_ID == 0)
+ AD_Org_ID = m_doc.getAD_Org_ID();
+ }
+ setAmtAcctDr (MConversionRate.convert (getCtx(),
+ getAmtSourceDr(), getC_Currency_ID(), m_acctSchema.getC_Currency_ID(),
+ getDateAcct(), C_ConversionType_ID, m_doc.getAD_Client_ID(), AD_Org_ID));
+ if (getAmtAcctDr() == null)
+ return false;
+ setAmtAcctCr (MConversionRate.convert (getCtx(),
+ getAmtSourceCr(), getC_Currency_ID(), m_acctSchema.getC_Currency_ID(),
+ getDateAcct(), C_ConversionType_ID, m_doc.getAD_Client_ID(), AD_Org_ID));
+ return true;
+ } // convert
+
+ /**
+ * Get Account
+ * @return account
+ */
+ public MAccount getAccount()
+ {
+ return m_acct;
+ } // getAccount
+
+ /**
+ * To String
+ * @return String
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer("FactLine=[");
+ sb.append(getAD_Table_ID()).append(":").append(getRecord_ID())
+ .append(",").append(m_acct)
+ .append(",Cur=").append(getC_Currency_ID())
+ .append(", DR=").append(getAmtSourceDr()).append("|").append(getAmtAcctDr())
+ .append(", CR=").append(getAmtSourceCr()).append("|").append(getAmtAcctCr())
+ .append("]");
+ return sb.toString();
+ } // toString
+
+
+ /**
+ * Get AD_Org_ID (balancing segment).
+ * (if not set directly - from document line, document, account, locator)
+ *
+ * Note that Locator needs to be set before - otherwise
+ * segment balancing might produce the wrong results
+ * @return AD_Org_ID
+ */
+ public int getAD_Org_ID()
+ {
+ if (super.getAD_Org_ID() != 0) // set earlier
+ return super.getAD_Org_ID();
+ // Prio 1 - get from locator - if exist
+ if (getM_Locator_ID() != 0)
+ {
+ String sql = "SELECT AD_Org_ID FROM M_Locator WHERE M_Locator_ID=? AND AD_Client_ID=?";
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
+ pstmt.setInt(1, getM_Locator_ID());
+ pstmt.setInt(2, getAD_Client_ID());
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ {
+ setAD_Org_ID (rs.getInt(1));
+ log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (1 from M_Locator_ID=" + getM_Locator_ID() + ")");
+ }
+ else
+ log.log(Level.SEVERE, "AD_Org_ID - Did not find M_Locator_ID=" + getM_Locator_ID());
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+ } // M_Locator_ID != 0
+
+ // Prio 2 - get from doc line - if exists (document context overwrites)
+ if (m_docLine != null && super.getAD_Org_ID() == 0)
+ {
+ setAD_Org_ID (m_docLine.getAD_Org_ID());
+ log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (2 from DocumentLine)");
+ }
+ // Prio 3 - get from doc - if not GL
+ if (m_doc != null && super.getAD_Org_ID() == 0)
+ {
+ if (Doc.DOCTYPE_GLJournal.equals (m_doc.getDocumentType()))
+ {
+ setAD_Org_ID (m_acct.getAD_Org_ID()); // inter-company GL
+ log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (3 from Acct)");
+ }
+ else
+ {
+ setAD_Org_ID (m_doc.getAD_Org_ID());
+ log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (3 from Document)");
+ }
+ }
+ // Prio 4 - get from account - if not GL
+ if (m_doc != null && super.getAD_Org_ID() == 0)
+ {
+ if (Doc.DOCTYPE_GLJournal.equals (m_doc.getDocumentType()))
+ {
+ setAD_Org_ID (m_doc.getAD_Org_ID());
+ log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (4 from Document)");
+ }
+ else
+ {
+ setAD_Org_ID (m_acct.getAD_Org_ID());
+ log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (4 from Acct)");
+ }
+ }
+ return super.getAD_Org_ID();
+ } // setAD_Org_ID
+
+
+ /**
+ * Get/derive Sales Region
+ * @return Sales Region
+ */
+ public int getC_SalesRegion_ID ()
+ {
+ if (super.getC_SalesRegion_ID() != 0)
+ return super.getC_SalesRegion_ID();
+ //
+ if (m_docLine != null)
+ setC_SalesRegion_ID (m_docLine.getC_SalesRegion_ID());
+ if (m_doc != null)
+ {
+ if (super.getC_SalesRegion_ID() == 0)
+ setC_SalesRegion_ID (m_doc.getC_SalesRegion_ID());
+ if (super.getC_SalesRegion_ID() == 0 && m_doc.getBP_C_SalesRegion_ID() > 0)
+ setC_SalesRegion_ID (m_doc.getBP_C_SalesRegion_ID());
+ // derive SalesRegion if AcctSegment
+ if (super.getC_SalesRegion_ID() == 0
+ && m_doc.getC_BPartner_Location_ID() != 0
+ && m_doc.getBP_C_SalesRegion_ID() == -1) // never tried
+ // && m_acctSchema.isAcctSchemaElement(MAcctSchemaElement.ELEMENTTYPE_SalesRegion))
+ {
+ String sql = "SELECT COALESCE(C_SalesRegion_ID,0) FROM C_BPartner_Location WHERE C_BPartner_Location_ID=?";
+ setC_SalesRegion_ID (DB.getSQLValue(null,
+ sql, m_doc.getC_BPartner_Location_ID()));
+ if (super.getC_SalesRegion_ID() != 0) // save in VO
+ {
+ m_doc.setBP_C_SalesRegion_ID(super.getC_SalesRegion_ID());
+ log.fine("C_SalesRegion_ID=" + super.getC_SalesRegion_ID() + " (from BPL)" );
+ }
+ else // From Sales Rep of Document -> Sales Region
+ {
+ sql = "SELECT COALESCE(MAX(C_SalesRegion_ID),0) FROM C_SalesRegion WHERE SalesRep_ID=?";
+ setC_SalesRegion_ID (DB.getSQLValue(null,
+ sql, m_doc.getSalesRep_ID()));
+ if (super.getC_SalesRegion_ID() != 0) // save in VO
+ {
+ m_doc.setBP_C_SalesRegion_ID(super.getC_SalesRegion_ID());
+ log.fine("C_SalesRegion_ID=" + super.getC_SalesRegion_ID() + " (from SR)" );
+ }
+ else
+ m_doc.setBP_C_SalesRegion_ID(-2); // don't try again
+ }
+ }
+ if (m_acct != null && super.getC_SalesRegion_ID() == 0)
+ setC_SalesRegion_ID (m_acct.getC_SalesRegion_ID());
+ }
+ //
+ // log.fine("C_SalesRegion_ID=" + super.getC_SalesRegion_ID()
+ // + ", C_BPartner_Location_ID=" + m_docVO.C_BPartner_Location_ID
+ // + ", BP_C_SalesRegion_ID=" + m_docVO.BP_C_SalesRegion_ID
+ // + ", SR=" + m_acctSchema.isAcctSchemaElement(MAcctSchemaElement.ELEMENTTYPE_SalesRegion));
+ return super.getC_SalesRegion_ID();
+ } // getC_SalesRegion_ID
+
+
+ /**
+ * Before Save
+ * @param newRecord new
+ * @return true
+ */
+ protected boolean beforeSave (boolean newRecord)
+ {
+ if (newRecord)
+ {
+ log.fine(toString());
+ //
+ getAD_Org_ID();
+ getC_SalesRegion_ID();
+ // Set Default Account Info
+ if (getM_Product_ID() == 0)
+ setM_Product_ID (m_acct.getM_Product_ID());
+ if (getC_LocFrom_ID() == 0)
+ setC_LocFrom_ID (m_acct.getC_LocFrom_ID());
+ if (getC_LocTo_ID() == 0)
+ setC_LocTo_ID (m_acct.getC_LocTo_ID());
+ if (getC_BPartner_ID() == 0)
+ setC_BPartner_ID (m_acct.getC_BPartner_ID());
+ if (getAD_OrgTrx_ID() == 0)
+ setAD_OrgTrx_ID (m_acct.getAD_OrgTrx_ID());
+ if (getC_Project_ID() == 0)
+ setC_Project_ID (m_acct.getC_Project_ID());
+ if (getC_Campaign_ID() == 0)
+ setC_Campaign_ID (m_acct.getC_Campaign_ID());
+ if (getC_Activity_ID() == 0)
+ setC_Activity_ID (m_acct.getC_Activity_ID());
+ if (getUser1_ID() == 0)
+ setUser1_ID (m_acct.getUser1_ID());
+ if (getUser2_ID() == 0)
+ setUser2_ID (m_acct.getUser2_ID());
+
+ // Revenue Recognition for AR Invoices
+ if (m_doc.getDocumentType().equals(Doc.DOCTYPE_ARInvoice)
+ && m_docLine != null
+ && m_docLine.getC_RevenueRecognition_ID() != 0)
+ {
+ int AD_User_ID = 0;
+ setAccount_ID (
+ createRevenueRecognition (
+ m_docLine.getC_RevenueRecognition_ID(), m_docLine.get_ID(),
+ getAD_Client_ID(), getAD_Org_ID(), AD_User_ID,
+ getAccount_ID(), getC_SubAcct_ID(),
+ getM_Product_ID(), getC_BPartner_ID(), getAD_OrgTrx_ID(),
+ getC_LocFrom_ID(), getC_LocTo_ID(),
+ getC_SalesRegion_ID(), getC_Project_ID(),
+ getC_Campaign_ID(), getC_Activity_ID(),
+ getUser1_ID(), getUser2_ID(),
+ getUserElement1_ID(), getUserElement2_ID())
+ );
+ }
+ }
+ return true;
+ } // beforeSave
+
+
+ /**************************************************************************
+ * Revenue Recognition.
+ * Called from FactLine.save
+ *
+ * Create Revenue recognition plan and return Unearned Revenue account
+ * to be used instead of Revenue Account. If not found, it returns
+ * the revenue account.
+ *
+ * @param C_RevenueRecognition_ID revenue recognition
+ * @param C_InvoiceLine_ID invoice line
+ * @param AD_Client_ID client
+ * @param AD_Org_ID org
+ * @param AD_User_ID user
+ * @param Account_ID of Revenue Account
+ * @param C_SubAcct_ID sub account
+ * @param M_Product_ID product
+ * @param C_BPartner_ID bpartner
+ * @param AD_OrgTrx_ID trx org
+ * @param C_LocFrom_ID loc from
+ * @param C_LocTo_ID loc to
+ * @param C_SRegion_ID sales region
+ * @param C_Project_ID project
+ * @param C_Campaign_ID campaign
+ * @param C_Activity_ID activity
+ * @param User1_ID user1
+ * @param User2_ID user2
+ * @param UserElement1_ID user element 1
+ * @param UserElement2_ID user element 2
+ * @return Account_ID for Unearned Revenue or Revenue Account if not found
+ */
+ private int createRevenueRecognition (
+ int C_RevenueRecognition_ID, int C_InvoiceLine_ID,
+ int AD_Client_ID, int AD_Org_ID, int AD_User_ID,
+ int Account_ID, int C_SubAcct_ID,
+ int M_Product_ID, int C_BPartner_ID, int AD_OrgTrx_ID,
+ int C_LocFrom_ID, int C_LocTo_ID, int C_SRegion_ID, int C_Project_ID,
+ int C_Campaign_ID, int C_Activity_ID,
+ int User1_ID, int User2_ID, int UserElement1_ID, int UserElement2_ID)
+ {
+ log.fine("From Accout_ID=" + Account_ID);
+ // get VC for P_Revenue (from Product)
+ MAccount revenue = MAccount.get(getCtx(),
+ AD_Client_ID, AD_Org_ID, getC_AcctSchema_ID(), Account_ID, C_SubAcct_ID,
+ M_Product_ID, C_BPartner_ID, AD_OrgTrx_ID, C_LocFrom_ID, C_LocTo_ID, C_SRegion_ID,
+ C_Project_ID, C_Campaign_ID, C_Activity_ID,
+ User1_ID, User2_ID, UserElement1_ID, UserElement2_ID);
+ if (revenue != null && revenue.get_ID() == 0)
+ revenue.save();
+ if (revenue == null || revenue.get_ID() == 0)
+ {
+ log.severe ("Revenue_Acct not found");
+ return Account_ID;
+ }
+ int P_Revenue_Acct = revenue.get_ID();
+
+ // get Unearned Revenue Acct from BPartner Group
+ int UnearnedRevenue_Acct = 0;
+ int new_Account_ID = 0;
+ String sql = "SELECT ga.UnearnedRevenue_Acct, vc.Account_ID "
+ + "FROM C_BP_Group_Acct ga, C_BPartner p, C_ValidCombination vc "
+ + "WHERE ga.C_BP_Group_ID=p.C_BP_Group_ID"
+ + " AND ga.UnearnedRevenue_Acct=vc.C_ValidCombination_ID"
+ + " AND ga.C_AcctSchema_ID=? AND p.C_BPartner_ID=?";
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
+ pstmt.setInt(1, getC_AcctSchema_ID());
+ pstmt.setInt(2, C_BPartner_ID);
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ {
+ UnearnedRevenue_Acct = rs.getInt(1);
+ new_Account_ID = rs.getInt(2);
+ }
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+ if (new_Account_ID == 0)
+ {
+ log.severe ("UnearnedRevenue_Acct not found");
+ return Account_ID;
+ }
+
+ MRevenueRecognitionPlan plan = new MRevenueRecognitionPlan(getCtx(), 0, null);
+ plan.setC_RevenueRecognition_ID (C_RevenueRecognition_ID);
+ plan.setC_AcctSchema_ID (getC_AcctSchema_ID());
+ plan.setC_InvoiceLine_ID (C_InvoiceLine_ID);
+ plan.setUnEarnedRevenue_Acct (UnearnedRevenue_Acct);
+ plan.setP_Revenue_Acct (P_Revenue_Acct);
+ plan.setC_Currency_ID (getC_Currency_ID());
+ plan.setTotalAmt (getAcctBalance());
+ if (!plan.save(get_TrxName()))
+ {
+ log.severe ("Plan NOT created");
+ return Account_ID;
+ }
+ log.fine("From Acctount_ID=" + Account_ID + " to " + new_Account_ID
+ + " - Plan from UnearnedRevenue_Acct=" + UnearnedRevenue_Acct + " to Revenue_Acct=" + P_Revenue_Acct);
+ return new_Account_ID;
+ } // createRevenueRecognition
+
+
+ /**************************************************************************
+ * Update Line with reversed Original Amount in Accounting Currency.
+ * Also copies original dimensions like Project, etc.
+ * Called from Doc_MatchInv
+ * @param AD_Table_ID table
+ * @param Record_ID record
+ * @param Line_ID line
+ * @param multiplier targetQty/documentQty
+ * @return true if success
+ */
+ public boolean updateReverseLine (int AD_Table_ID, int Record_ID, int Line_ID,
+ BigDecimal multiplier)
+ {
+ boolean success = false;
+
+ String sql = "SELECT * "
+ + "FROM Fact_Acct "
+ + "WHERE C_AcctSchema_ID=? AND AD_Table_ID=? AND Record_ID=?"
+ + " AND Line_ID=? AND Account_ID=?";
+ try
+ {
+ PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
+ pstmt.setInt(1, getC_AcctSchema_ID());
+ pstmt.setInt(2, AD_Table_ID);
+ pstmt.setInt(3, Record_ID);
+ pstmt.setInt(4, Line_ID);
+ pstmt.setInt(5, m_acct.getAccount_ID());
+ ResultSet rs = pstmt.executeQuery();
+ if (rs.next())
+ {
+ MFactAcct fact = new MFactAcct(getCtx(), rs, get_TrxName());
+ // Accounted Amounts - reverse
+ BigDecimal dr = fact.getAmtAcctDr();
+ BigDecimal cr = fact.getAmtAcctCr();
+ setAmtAcctDr (cr.multiply(multiplier));
+ setAmtAcctCr (dr.multiply(multiplier));
+ // Source Amounts
+ setAmtSourceDr (getAmtAcctDr());
+ setAmtSourceCr (getAmtAcctCr());
+ //
+ success = true;
+ log.fine(new StringBuffer("(Table=").append(AD_Table_ID)
+ .append(",Record_ID=").append(Record_ID)
+ .append(",Line=").append(Record_ID)
+ .append(", Account=").append(m_acct)
+ .append(",dr=").append(dr).append(",cr=").append(cr)
+ .append(") - DR=").append(getAmtSourceDr()).append("|").append(getAmtAcctDr())
+ .append(", CR=").append(getAmtSourceCr()).append("|").append(getAmtAcctCr())
+ .toString());
+ // Dimensions
+ setAD_OrgTrx_ID(fact.getAD_OrgTrx_ID());
+ setC_Project_ID (fact.getC_Project_ID());
+ setC_Activity_ID(fact.getC_Activity_ID());
+ setC_Campaign_ID(fact.getC_Campaign_ID());
+ setC_SalesRegion_ID(fact.getC_SalesRegion_ID());
+ setC_LocFrom_ID(fact.getC_LocFrom_ID());
+ setC_LocTo_ID(fact.getC_LocTo_ID());
+ setM_Product_ID(fact.getM_Product_ID());
+ setM_Locator_ID(fact.getM_Locator_ID());
+ setUser1_ID(fact.getUser1_ID());
+ setUser2_ID(fact.getUser2_ID());
+ setC_UOM_ID(fact.getC_UOM_ID());
+ setC_Tax_ID(fact.getC_Tax_ID());
+ // Org for cross charge
+ setAD_Org_ID (fact.getAD_Org_ID());
+ }
+ else
+ log.warning(new StringBuffer("Not Found (try later) ")
+ .append(",C_AcctSchema_ID=").append(getC_AcctSchema_ID())
+ .append(", AD_Table_ID=").append(AD_Table_ID)
+ .append(",Record_ID=").append(Record_ID)
+ .append(",Line_ID=").append(Line_ID)
+ .append(", Account_ID=").append(m_acct.getAccount_ID()).toString());
+ rs.close();
+ pstmt.close();
+ }
+ catch (SQLException e)
+ {
+ log.log(Level.SEVERE, sql, e);
+ }
+ return success;
+ } // updateReverseLine
+
+} // FactLine
diff --git a/serverRoot/src/main/server/org/compiere/ldap/LdapConnectionHandler.java b/serverRoot/src/main/server/org/compiere/ldap/LdapConnectionHandler.java
index 532c7062da..94525a0aa8 100644
--- a/serverRoot/src/main/server/org/compiere/ldap/LdapConnectionHandler.java
+++ b/serverRoot/src/main/server/org/compiere/ldap/LdapConnectionHandler.java
@@ -10,21 +10,50 @@
* 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.adempiere.org/license.html
- * 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
+ * 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.ldap;
-import java.io.*;
-import java.net.*;
-import java.util.logging.*;
-import org.compiere.ldap.*;
-import org.compiere.util.*;
-import com.sun.jndi.ldap.*;
-
-/**
- * LDAP Connection Handler
- *
+import java.io.*;
+import java.net.*;
+import java.util.Hashtable;
+import java.util.logging.*;
+
+import javax.naming.AuthenticationException;
+import javax.naming.Context;
+import javax.naming.ldap.InitialLdapContext;
+
+import org.compiere.model.*;
+import org.compiere.util.*;
+
+/**
+ * LDAP Connection Handler
+ *
+ * Only "simple" authentication and the following protocol are supported:
+ * bind
+ * unbind
+ * search
+ * The following distinguished name are supported:
+ * o - organization
+ * ou - organization unit
+ * cn - common name
+ * Due to some of the ldap client might not unbind and close the connection,
+ * whenever error occurs and authenticate done, we will close the connection.
+ *
+ * Basically, tested with two type of ldap authentication, java client and
+ * apache ldap support.
+ * For the apache support, here's the tested definition:
+ * AuthType Basic
+ * AuthLDAPAuthoritative on
+ * AuthLDAPEnabled on
+ * AuthLDAPURL ldap://:/o=,ou=?uid?sub
+ * The protocol for the apache ldap:
+ * - bind to server
+ * - search for the object name with user input userid
+ * - bind again with returned object name and password
+ * The protocol for the java client, please refer to the sample code in main().
+ *
* @author Jorg Janke
* @version $Id: LdapConnectionHandler.java,v 1.1 2006/10/09 00:23:16 jjanke Exp $
*/
@@ -33,13 +62,15 @@ public class LdapConnectionHandler extends Thread
/**
* Ldap Connection Handler
* @param socket server socket
- */
- public LdapConnectionHandler(Socket socket)
- {
- try
- {
- m_socket = socket;
- m_socket.setTcpNoDelay(true); // should not be required
+ * @param model model
+ */
+ public LdapConnectionHandler(Socket socket, MLdapProcessor model)
+ {
+ try
+ {
+ m_socket = socket;
+ m_socket.setTcpNoDelay(true); // should not be required
+ m_model = model;
}
catch (Exception e)
{
@@ -49,6 +80,8 @@ public class LdapConnectionHandler extends Thread
/** Socket */
private Socket m_socket = null;
+ /** Ldap Model */
+ private MLdapProcessor m_model = null;
/** Logger */
private static CLogger log = CLogger.getCLogger (LdapConnectionHandler.class);
@@ -63,6 +96,9 @@ public class LdapConnectionHandler extends Thread
if (m_socket == null || m_socket.isClosed())
return;
+ LdapMessage msg = new LdapMessage();
+ MLdapUser ldapUser = new MLdapUser();
+ LdapResult result = new LdapResult();
boolean activeSession = true;
while (activeSession)
{
@@ -72,21 +108,31 @@ public class LdapConnectionHandler extends Thread
byte[] buffer = new byte[512];
int length = in.read(buffer, 0, 512);
- LdapMessage msg = new LdapMessage (buffer, length);
- if (msg.getOperation() == LdapMessage.UNBIND_REQUEST)
- {
- activeSession = false;
- out.close();
- }
- else
- {
- LdapResult result = new LdapResult ();
- byte[] bytes = result.bindResponse();
- //
- out.write(bytes);
- out.flush();
- }
- }
+ // Decode the input message buffer
+ result.reset(msg, ldapUser);
+ msg.reset(result);
+ msg.decode(buffer, length);
+ if (msg.getOperation() == LdapMessage.UNBIND_REQUEST)
+ {
+ out.close();
+ break;
+ }
+
+ // Not unbind, so we can create a response
+ byte[] bytes = result.getResult(m_model);
+
+ // Send the response back
+ out.write(bytes);
+ out.flush();
+
+ // If there's error or successfully authenticated the user,
+ // close the connection to avoid too many open connection
+ if (result.getDone())
+ {
+ out.close();
+ break;
+ }
+ } // while(activeSession)
}
catch (IOException e)
{
@@ -115,4 +161,42 @@ public class LdapConnectionHandler extends Thread
return sb.toString ();
} // toString
-} // LdapConnectionHandler
+ /**
+ * Test using the java client.
+ * Ldap v3 won't need to do any bind, search, bind anymore.
+ * When new InitialLdapContext() is called, it will bind with the
+ * dn and password, the ldap server should be authenticate with it.
+ *
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ // ldap://dc.compiere.org
+ env.put(Context.PROVIDER_URL, "ldap://10.104.139.160:389");
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ // Compiere server only support cn/o/ou, and cn should be the user id.
+ // Only one entry for cn.
+ env.put(Context.SECURITY_PRINCIPAL, "cn=cboss@compiere.org,o=GardenWorld,ou=LawnCare");
+ env.put(Context.SECURITY_CREDENTIALS, "carlboss");
+
+ try
+ {
+ // Create the initial context
+ new InitialLdapContext(env, null);
+ // If not successfully authenticated, exception should be thrown
+ System.out.println("Successfully authenticated ...");
+ }
+ catch (AuthenticationException e)
+ {
+ e.printStackTrace();
+ return;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ return;
+ }
+ } // main()
+} // LdapConnectionHandler
diff --git a/serverRoot/src/main/server/org/compiere/ldap/LdapMessage.java b/serverRoot/src/main/server/org/compiere/ldap/LdapMessage.java
index e3e0c26e0f..c2003a0715 100644
--- a/serverRoot/src/main/server/org/compiere/ldap/LdapMessage.java
+++ b/serverRoot/src/main/server/org/compiere/ldap/LdapMessage.java
@@ -10,12 +10,13 @@
* 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.adempiere.org/license.html
- * 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
+ * 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.ldap;
-import java.util.logging.*;
+import java.util.logging.*;
+
import org.compiere.util.*;
import com.sun.jndi.ldap.*;
@@ -27,138 +28,235 @@ import com.sun.jndi.ldap.*;
*/
public class LdapMessage
{
- /**
- * Ldap Message
- * @param data BER data
- * @param length Ber data length
- */
- public LdapMessage (byte[] data, int length)
- {
- try
- {
- decode(data, length);
- }
- catch (Exception e)
- {
- log.log(Level.SEVERE, data.toString(), e);
- }
- } // LdapMessage
-
- /**
- LDAPMessage ::= SEQUENCE {
- messageID MessageID,
- protocolOp CHOICE {
- bindRequest BindRequest,
- bindResponse BindResponse,
- unbindRequest UnbindRequest,
- searchRequest SearchRequest,
- searchResEntry SearchResultEntry,
- searchResDone SearchResultDone,
- searchResRef SearchResultReference,
- modifyRequest ModifyRequest,
- modifyResponse ModifyResponse,
- addRequest AddRequest,
- addResponse AddResponse,
- delRequest DelRequest,
- delResponse DelResponse,
- modDNRequest ModifyDNRequest,
- modDNResponse ModifyDNResponse,
- compareRequest CompareRequest,
- compareResponse CompareResponse,
- abandonRequest AbandonRequest,
- extendedReq ExtendedRequest,
- extendedResp ExtendedResponse },
- controls [0] Controls OPTIONAL }
- **/
-
- static public final int BIND_REQUEST = 0;
- static public final int BIND_RESPONSE = 1;
- static public final int UNBIND_REQUEST = 2;
- static public final int SEARCH_REQUEST = 3;
- static public final int SEARCH_RESENTRY = 4;
- static public final int SEARCH_RESDONE = 5;
- static public final int MODIFY_REQUEST = 6;
- static public final int MODIFY_RESPONSE = 7;
- static public final int ADD_REQUEST = 8;
- static public final int ADD_RESPONSE = 9;
- static public final int DEL_REQUEST = 10;
- static public final int DEL_RESPONSE = 11;
- static public final int MODDN_REQUEST = 12;
- static public final int MODDN_RESPONSE = 13;
- static public final int COMPARE_REQUEST = 14;
- static public final int COMPARE_RESPONSE = 15;
- static public final int ABANDON_REQUEST = 16;
- static public final int EXTENDED_REQUEST = 17;
- static public final int EXTENDED_RESPONSE = 18;
-
- static public final int[] PROTOCOL_OP = {
- BIND_REQUEST, BIND_RESPONSE, UNBIND_REQUEST,
- SEARCH_REQUEST, SEARCH_RESENTRY, SEARCH_RESDONE,
- MODIFY_REQUEST, MODIFY_RESPONSE, ADD_REQUEST, ADD_RESPONSE,
- DEL_REQUEST, DEL_RESPONSE, MODDN_REQUEST, MODDN_RESPONSE,
- COMPARE_REQUEST, COMPARE_RESPONSE, ABANDON_REQUEST,
- EXTENDED_REQUEST, EXTENDED_RESPONSE};
-
-
- /** Logger */
- private static CLogger log = CLogger.getCLogger (LdapMessage.class);
- /** Protocol Operation */
- private int m_protocolOp = -1;
-
-
- /**
- * Decode Message
- * @param data data
- * @param length length
- * @throws Exception
- */
- private void decode (byte[] data, int length) throws Exception
- {
- BerDecoder decoder = new BerDecoder(data, 0, length);
- int left = decoder.bytesLeft();
- int pos = decoder.getParsePosition();
- //
- int seq = decoder.parseSeq(null);
- left = decoder.bytesLeft();
- pos = decoder.getParsePosition();
- //
- int messageID = decoder.parseInt();
- left = decoder.bytesLeft();
- pos = decoder.getParsePosition();
- //
- int peek = decoder.peekByte();
- m_protocolOp = decoder.parseSeq(PROTOCOL_OP);
- m_protocolOp -= Ber.ASN_APPLICATION;
- if (m_protocolOp - Ber.ASN_CONSTRUCTOR >= 0)
- m_protocolOp -= Ber.ASN_CONSTRUCTOR;
- left = decoder.bytesLeft();
- pos = decoder.getParsePosition();
- //
- // Payload
- if (m_protocolOp == BIND_REQUEST)
- {
- int version = decoder.parseInt();
- left = decoder.bytesLeft();
- pos = decoder.getParsePosition();
- //
- byte[] dn = decoder.parseOctetString(Ber.ASN_OCTET_STR, null);
- left = decoder.bytesLeft();
- pos = decoder.getParsePosition();
- //
- byte[] authentification = decoder.parseOctetString(Ber.ASN_CONTEXT, null);
- left = decoder.bytesLeft();
- pos = decoder.getParsePosition();
- //
- log.info("#" + messageID + ": bind - version=" + version + ", dn=" + new String(dn)
- + ", auth=" + new String (authentification));
- }
- else if (m_protocolOp == UNBIND_REQUEST)
- log.info("#" + messageID + ": unbind");
- else
- {
- log.warning("#" + messageID + ": Unknown Op + " + m_protocolOp);
- }
- } // decode
+ static public final int BIND_REQUEST = 96;
+ static public final int BIND_RESPONSE = 97;
+ static public final int UNBIND_REQUEST = 98;
+ static public final int SEARCH_REQUEST = 99;
+ static public final int SEARCH_REP_ENTRY = 100;
+ static public final int SEARCH_RES_RESULT = 101;
+
+ static public final int SIMPLE_AUTHENTICATION = 128;
+
+ static public final int FILTER_AND = 160;
+ static public final int FILTER_OR = 161;
+ static public final int FILTER_NOT = 162;
+ static public final int FILTER_EQUALITYMATCH = 163;
+
+ static public final int SEQUENCE = 48;
+
+ /** Decoder */
+ private BerDecoder decoder = null;
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger (LdapMessage.class);
+ /** Protocol Operation */
+ private int m_protocolOp = -1;
+ /** Message Id needed for the reply message */
+ private int msgId;
+ /** Distinguished name */
+ private String dn = null;
+ /** Organization */
+ private String org = null;
+ /** Organization unit */
+ private String orgUnit = null;
+ /** User Id */
+ private String userId = null;
+ /** Password */
+ private String passwd = null;
+ /** base Object */
+ private String baseObj = null;
+ /** LdapResult object to hold if there's any error during parsing */
+ private LdapResult result = null;
+
+ /**
+ * Ldap Message
+ */
+ public LdapMessage()
+ {
+ } // LdapMessage
+
+ /*
+ * Reset all the attributes
+ */
+ public void reset(LdapResult result)
+ {
+ this.result = result;
+ decoder = null;
+ m_protocolOp = -1;
+ msgId = -1;
+ dn = null;
+ org = null;
+ orgUnit = null;
+ userId = null;
+ passwd = null;
+ baseObj = null;
+
+ } // reset()
+
+ /**
+ * Decode Message
+ * @param data input buffer
+ * @param length buffer size
+ */
+ public void decode(byte[] data, int length)
+ {
+ try
+ {
+ // Create the decoder
+ decoder = new BerDecoder(data, 0, length);
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, data.toString(), e);
+ return;
+ }
+
+ try
+ {
+ // Parse the message envelope
+ decoder.parseSeq(null);
+
+ // Parse message Id
+ msgId = decoder.parseInt();
+
+ // Parse the operation protocol
+ m_protocolOp = decoder.parseSeq(null);
+
+ //
+ // Payload
+ if (m_protocolOp == BIND_REQUEST)
+ handleBind();
+ else if (m_protocolOp == UNBIND_REQUEST)
+ log.info("#" + msgId + ": unbind");
+ else if (m_protocolOp == SEARCH_REQUEST)
+ handleSearch();
+ else // Only supoort BIND, UNBIND and SEARCH
+ {
+ result.setErrorNo(LdapResult.LDAP_PROTOCOL_ERROR);
+ result.setErrorString(": Unsupported Request");
+ log.warning("#" + msgId + ": Unknown Op + " + m_protocolOp);
+ }
+ }
+ catch (Exception ex)
+ {
+ result.setErrorNo(LdapResult.LDAP_PROTOCOL_ERROR);
+ log.log(Level.SEVERE, "", ex);
+ }
+ } // decode
+
+ /*
+ * Encode the search request message
+ */
+ private void handleSearch()
+ {
+ try
+ {
+ // Parse the base Object
+ baseObj = decoder.parseString(true);
+ parseDN(baseObj);
+
+ decoder.parseEnumeration(); // scope
+ decoder.parseEnumeration(); // derefAliases
+ decoder.parseInt(); // sizeLimit
+ decoder.parseInt(); // timeLimit
+ decoder.parseBoolean(); // typeOnly
+
+ boolean equalityFilter = false;
+ while (true)
+ {
+ int filter = decoder.parseSeq(null); //Filter
+ if (filter == FILTER_EQUALITYMATCH)
+ {
+ decoder.parseString(true);
+ userId = decoder.parseString(true);
+ equalityFilter = true;
+ break;
+ }
+ else if (filter == FILTER_AND)
+ decoder.parseStringWithTag(135, true, null);
+ else if (filter == SEQUENCE)
+ break;
+ } // while true
+
+ if (!equalityFilter) // Didn't find the it
+ {
+ result.setErrorNo(LdapResult.LDAP_PROTOCOL_ERROR);
+ result.setErrorString("Can't can't Filter - EqualityMatch");
+ }
+ }
+ catch (Exception ex)
+ {
+ log.log(Level.SEVERE, "", ex);
+ }
+ } // handleSearch()
+
+ /*
+ * Encode the bind request message
+ */
+ private void handleBind()
+ {
+ try
+ {
+ // Parse LDAP version; only support v3
+ int version = decoder.parseInt();
+ if (version != 3)
+ {
+ result.setErrorNo(LdapResult.LDAP_PROTOCOL_ERROR);
+ result.setErrorString("Unsupported LDAP version");
+ log.info("#" + msgId + ": unsupported LDAP version - " + version);
+ return;
+ }
+
+ // Parse DN
+ dn = decoder.parseString(true);
+
+ // Peek on AuthenticationChoice; only support simple authentication
+ int auth = decoder.peekByte();
+ if (auth != SIMPLE_AUTHENTICATION) // 0x80 - simple authentication
+ {
+ result.setErrorNo(LdapResult.LDAP_AUTH_METHOD_NOT_SUPPORTED);
+ log.info("#" + msgId + ": unsupported authentication method - " + auth);
+ return;
+ }
+
+ // It is simple authentication, get the authentication string
+ passwd = decoder.parseStringWithTag(SIMPLE_AUTHENTICATION, true, null);
+ if (passwd != null && passwd.length() > 0)
+ {
+ parseDN(dn);
+ if (userId == null || userId.length() <= 0)
+ {
+ result.setErrorNo(LdapResult.LDAP_NO_SUCH_OBJECT);
+ result.setErrorString(": \"cn\" not defined");
+ log.info("#" + msgId + ": \"cn\" not defined");
+ return;
+ }
+ }
+
+ // Log the information
+ log.info("#" + msgId + ": bind - version=" + version + ", userId=" + userId);
+ }
+ catch (Exception ex)
+ {
+ log.log(Level.SEVERE, "", ex);
+ }
+ } // handleBind()
+
+ /*
+ * Parse the DN to find user id, organization and organization unit
+ */
+ private void parseDN(String dName)
+ {
+ String[] dnArray = dName.split(",");
+ for (int i = 0; i < dnArray.length; i++)
+ {
+ if (dnArray[i].startsWith("cn="))
+ userId = dnArray[i].split("=")[1];
+ else if (dnArray[i].startsWith("o="))
+ org = dnArray[i].split("=")[1];
+ else if (dnArray[i].startsWith("ou="))
+ orgUnit = dnArray[i].split("=")[1];
+ }
+ } // parseDN()
/**
* Get Operation Code
@@ -169,4 +267,66 @@ public class LdapMessage
return m_protocolOp;
} // getOperation
-} // LdapMessage
+ /**
+ * Get message id
+ * @return msgId
+ */
+ public int getMsgId()
+ {
+ return msgId;
+ } // getMsgId()
+
+ /**
+ * Get DN
+ * @return dn
+ */
+ public String getDN()
+ {
+ return dn;
+ } // getDN()
+
+ /**
+ * Get User Id
+ * @return userId
+ */
+ public String getUserId()
+ {
+ return userId;
+ } // getUserId()
+
+ /**
+ * Get User passwod
+ * @return passwd
+ */
+ public String getUserPasswd()
+ {
+ return passwd;
+ } // getUserPasswd()
+
+ /**
+ * Get base object
+ * @return baseObj
+ */
+ public String getBaseObj()
+ {
+ return baseObj;
+ } // getBaseObj()
+
+ /**
+ * Get organization
+ * @return org
+ */
+ public String getOrg()
+ {
+ return org;
+ } // getOrg()
+
+ /**
+ * Get organization unit
+ * @return orgUnit
+ */
+ public String getOrgUnit()
+ {
+ return orgUnit;
+ } // getOrgUnit()
+} // LdapMessage
diff --git a/serverRoot/src/main/server/org/compiere/ldap/LdapProcessor.java b/serverRoot/src/main/server/org/compiere/ldap/LdapProcessor.java
index 13a181595a..8906c45976 100644
--- a/serverRoot/src/main/server/org/compiere/ldap/LdapProcessor.java
+++ b/serverRoot/src/main/server/org/compiere/ldap/LdapProcessor.java
@@ -10,8 +10,8 @@
* 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.adempiere.org/license.html
- * 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
+ * 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.ldap;
@@ -19,9 +19,7 @@ import java.net.*;
import java.sql.*;
import java.util.*;
import java.util.logging.*;
-import javax.naming.ldap.*;
import org.compiere.*;
-import org.compiere.ldap.*;
import org.compiere.model.*;
import org.compiere.server.*;
import org.compiere.util.*;
@@ -38,19 +36,16 @@ public class LdapProcessor extends AdempiereServer
* Ldap Processor (Server)
* @param model Ldap Model
*/
- public LdapProcessor (LdapProcessorModel model)
+ public LdapProcessor (MLdapProcessor model)
{
super (model, 300);
m_model = model;
- init();
} // LdapProcessor
/** The Concrete Model */
- private LdapProcessorModel m_model = null;
+ private MLdapProcessor m_model = null;
/** Last Summary */
private StringBuffer m_summary = new StringBuffer();
- /** Client info */
- private MClient m_client = null;
/** Server Socket */
private ServerSocket m_serverSocket = null;
/** Counter */
@@ -87,7 +82,8 @@ public class LdapProcessor extends AdempiereServer
{
Socket socket = m_serverSocket.accept(); // waits for connection
log.log(Level.FINE, "Connection on Port=" + m_model.getLdapPort());
- LdapConnectionHandler handler = new LdapConnectionHandler (socket);
+ LdapConnectionHandler handler =
+ new LdapConnectionHandler (socket, m_model);
handler.start();
m_counter++;
}
@@ -98,24 +94,19 @@ public class LdapProcessor extends AdempiereServer
m_summary.append(e.toString());
}
+ m_summary.append ("; ")
+ .append (m_model.getInfo());
+
+ int no = m_model.deleteLog();
+ m_summary.append("; Logs deleted=").append(no);
+ //
+ MLdapProcessorLog pLog = new MLdapProcessorLog(m_model, m_summary.toString());
+ pLog.setReference("#" + String.valueOf(p_runCount)
+ + " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork)));
+ pLog.save();
+
} // doWork
- /**
- * Initialize
- */
- private void init()
- {
- try
- {
- InitialLdapContext lctx = new InitialLdapContext();
- // lctx.setRequestControls(critModCtls);
- // lctx.modifyAttributes(name, mods);
- Control[] respCtls = lctx.getResponseControls();
- }
- catch (Exception e)
- {
- }
- } //
/**
* Get Server Info
@@ -124,7 +115,8 @@ public class LdapProcessor extends AdempiereServer
public String getServerInfo()
{
return "#" + p_runCount + " - Last=" + m_summary.toString()
- + "; Counter=" + m_counter;
+ + "; Counter=" + m_counter
+ + "; " + m_model.getInfo();
} // getServerInfo
/**
@@ -134,7 +126,7 @@ public class LdapProcessor extends AdempiereServer
public static void main(String[] args)
{
Adempiere.startup(true);
- new LdapProcessor(new LdapProcessorModel(new Properties())).doWork();
+ new LdapProcessor(new MLdapProcessor(new Properties(), 0, null)).doWork();
} // main
} // LdapProcessor
diff --git a/serverRoot/src/main/server/org/compiere/ldap/LdapProcessorModel.java b/serverRoot/src/main/server/org/compiere/ldap/LdapProcessorModel.java
deleted file mode 100644
index b2b04e7a4a..0000000000
--- a/serverRoot/src/main/server/org/compiere/ldap/LdapProcessorModel.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/******************************************************************************
- * 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.adempiere.org/license.html
- * 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
- *****************************************************************************/
-package org.compiere.ldap;
-
-import java.sql.*;
-import java.util.*;
-import org.compiere.model.*;
-
-/**
- * Interim LDAP Server Model
- *
- * @author Jorg Janke
- * @version $Id: LdapProcessorModel.java,v 1.1 2006/10/09 00:23:16 jjanke Exp $
- */
-public class LdapProcessorModel implements AdempiereProcessor
-{
- /**
- * Ldap Processor Model
- * @param ctx context
- */
- public LdapProcessorModel (Properties ctx)
- {
- m_ctx = ctx;
- }
- // Properties
- private Properties m_ctx = null;
-
- private Timestamp m_dateNextRun;
- private Timestamp m_dateLastRun;
-
-
- public int getLdapPort()
- {
- return 389;
- }
-
-
-
- /**
- * String Representation
- * @return info
- */
- public String toString()
- {
- StringBuffer sb = new StringBuffer (getName());
- sb.append (";Port=").append (getLdapPort());
- return sb.toString ();
- } // toString
-
-
-
-
- /**************************************************************************
- * getAD_Client_ID
- * @see org.compiere.model.AdempiereProcessor#getAD_Client_ID()
- * @return 0
- */
- public int getAD_Client_ID()
- {
- return 0;
- }
- /**
- * getName
- * @see org.compiere.model.AdempiereProcessor#getName()
- * @return name
- */
- public String getName()
- {
- return "Adempiere LDAP Server";
- }
- /**
- * getDescription
- * @see org.compiere.model.AdempiereProcessor#getDescription()
- * @return -
- */
- public String getDescription()
- {
- return "-";
- }
- /**
- * Get Ctx
- * @return context
- */
- public Properties getCtx()
- {
- return m_ctx;
- }
- /**
- * GetFrequencyType
- * @see org.compiere.model.AdempiereProcessor#getFrequencyType()
- * @return min
- */
- public String getFrequencyType()
- {
- return MRequestProcessor.FREQUENCYTYPE_Minute;
- }
- /**
- * getFrequency
- * @see org.compiere.model.AdempiereProcessor#getFrequency()
- * @return 1
- */
- public int getFrequency()
- {
- return 1;
- }
-
- /**
- * Get Unique Server ID
- * @return id
- */
- public String getServerID()
- {
- return "Ldap";
- }
-
- public Timestamp getDateNextRun(boolean requery)
- {
- return m_dateNextRun;
- }
-
- public void setDateNextRun(Timestamp dateNextWork)
- {
- m_dateNextRun = dateNextWork;
- }
-
- public Timestamp getDateLastRun()
- {
- return m_dateLastRun;
- }
-
- public void setDateLastRun(Timestamp dateLastRun)
- {
- m_dateLastRun = dateLastRun;
- }
-
- public boolean save()
- {
- return true;
- }
-
- public AdempiereProcessorLog[] getLogs()
- {
- return new AdempiereProcessorLog[0];
- }
-}
diff --git a/serverRoot/src/main/server/org/compiere/ldap/LdapResult.java b/serverRoot/src/main/server/org/compiere/ldap/LdapResult.java
index 7c459ed878..00b3be5000 100644
--- a/serverRoot/src/main/server/org/compiere/ldap/LdapResult.java
+++ b/serverRoot/src/main/server/org/compiere/ldap/LdapResult.java
@@ -10,15 +10,15 @@
* 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.adempiere.org/license.html
- * 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
+ * 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.ldap;
-import java.io.*;
import java.util.logging.*;
+import org.compiere.model.*;
import org.compiere.util.*;
-import com.sun.jndi.ldap.*;
+import com.sun.jndi.ldap.BerEncoder;
/**
* Ldap Wire Response
@@ -28,120 +28,278 @@ import com.sun.jndi.ldap.*;
*/
public class LdapResult
{
-
- public LdapResult()
- {
- super ();
- } // LdapResult
-
- /**
- LDAPResult ::= SEQUENCE {
- resultCode ENUMERATED {
- success (0),
- operationsError (1),
- protocolError (2),
- timeLimitExceeded (3),
- sizeLimitExceeded (4),
- compareFalse (5),
- compareTrue (6),
-
- authMethodNotSupported (7),
- strongAuthRequired (8),
- -- 9 reserved --
- referral (10), -- new
- adminLimitExceeded (11), -- new
- unavailableCriticalExtension (12), -- new
- confidentialityRequired (13), -- new
- saslBindInProgress (14), -- new
- noSuchAttribute (16),
- undefinedAttributeType (17),
- inappropriateMatching (18),
- constraintViolation (19),
- attributeOrValueExists (20),
- invalidAttributeSyntax (21),
- noSuchObject (32),
- aliasProblem (33),
- invalidDNSyntax (34),
- -- 35 reserved for undefined isLeaf --
- aliasDereferencingProblem (36),
- -- 37-47 unused --
- inappropriateAuthentication (48),
- invalidCredentials (49),
- insufficientAccessRights (50),
- busy (51),
- unavailable (52),
- unwillingToPerform (53),
- loopDetect (54),
- -- 55-63 unused --
- namingViolation (64),
- objectClassViolation (65),
- notAllowedOnNonLeaf (66),
- notAllowedOnRDN (67),
- entryAlreadyExists (68),
- objectClassModsProhibited (69),
- -- 70 reserved for CLDAP --
- affectsMultipleDSAs (71), -- new
- -- 72-79 unused --
- other (80) },
- -- 81-90 reserved for APIs --
- matchedDN LDAPDN,
- errorMessage LDAPString,
- referral [3] Referral OPTIONAL }
- **/
-
- /** Encoder */
- private BerEncoder m_encoder = new BerEncoder();
- /** Logger */
- private static CLogger log = CLogger.getCLogger (LdapResult.class);
-
- /**
- * Bind Response
- * @return reponse
- */
- public byte[] bindResponse()
- {
- try
- {
-/**
- m_encoder.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
- for (int i = 0; i < sortKeys.length; i++) {
- ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
- ber.encodeString(sortKeys[i].getAttributeID(), true); // v3
- if ((matchingRule = sortKeys[i].getMatchingRuleID()) != null) {
- ber.encodeString(matchingRule, (Ber.ASN_CONTEXT | 0), true);
- }
- if (! sortKeys[i].isAscending()) {
- ber.encodeBoolean(true, (Ber.ASN_CONTEXT | 1));
- }
- ber.endSeq();
- }
-*/
- // payload
- m_encoder.beginSeq(Ber.ASN_APPLICATION | LdapMessage.BIND_RESPONSE);
- // Response
- m_encoder.encodeInt(0); // success
- m_encoder.encodeOctetString("cn=testCN".getBytes(), 0); // matched DN
- m_encoder.encodeOctetString("".getBytes(), 0); // error mag
- // referral
- // sasl
- //
- m_encoder.endSeq();
- log.info("Success");
- }
- catch (Exception e)
- {
- log.log(Level.SEVERE, "", e);
- }
- return getResult();
- } // bindResponse
-
- /**
- * Get BER Result as byte array
- * @return byte array
- */
- public byte[] getResult()
- {
- return m_encoder.getTrimmedBuf();
- } // getResult
-
-} // LdapResult
+ /** LdapMesssage */
+ private LdapMessage ldapMsg = null;
+ /** Encoder */
+ private BerEncoder m_encoder = null;
+ /** Logger */
+ private static CLogger log = CLogger.getCLogger (LdapResult.class);
+ /** Error number */
+ private int errNo = LDAP_SUCCESS;
+ /** Error String */
+ private String errStr = "";
+ /** LdapUser */
+ private MLdapUser ldapUser = null;
+ /** disconnect to client */
+ private boolean disconnect = false;
+
+ public LdapResult ()
+ {
+ } // LdapResult
+
+ /*
+ * Reset the attributes
+ */
+ public void reset(LdapMessage ldapMsg, MLdapUser ldapUser)
+ {
+ this.ldapMsg = ldapMsg;
+ m_encoder = new BerEncoder();
+ errNo = LDAP_SUCCESS;
+ errStr = "";
+ this.ldapUser = ldapUser;
+ } // reset()
+
+ /**
+ * Get the response according to the request message
+ * @param model model
+ * @return reponse
+ */
+ public byte[] getResult(MLdapProcessor model)
+ {
+ if (errNo != LDAP_SUCCESS)
+ {
+ generateResult("",
+ ((ldapMsg.getOperation()==LdapMessage.BIND_REQUEST)?
+ LdapMessage.BIND_RESPONSE:LdapMessage.SEARCH_RES_RESULT),
+ errNo, ldapErrorMessage[errNo] + errStr);
+ m_encoder.getTrimmedBuf();
+ }
+
+ try
+ {
+ String usrId = ldapMsg.getUserId();
+ String o = ldapMsg.getOrg();
+ String ou = ldapMsg.getOrgUnit();
+
+ // Adding the Application 1 Sequence
+ if (ldapMsg.getOperation() == LdapMessage.BIND_REQUEST)
+ {
+ String pwd = ldapMsg.getUserPasswd();
+ if (pwd == null || pwd.length() <= 0)
+ {
+ // 1st anonymous bind
+ generateResult(ldapMsg.getDN(), LdapMessage.BIND_RESPONSE,
+ LDAP_SUCCESS, null);
+ log.info("Success");
+ return m_encoder.getTrimmedBuf();
+ }
+
+ // Authenticate with Compiere data
+ if (ldapUser.getUserId() == null)
+ { // Try to authenticate on the 1st bind, must be java client
+ ldapUser.reset();
+ model.authenticate(ldapUser, usrId, o, ou);
+ if (ldapUser.getErrorMsg() != null)
+ { // Failed to authenticated with compiere
+ errNo = LDAP_NO_SUCH_OBJECT;
+ generateResult(ldapMsg.getBaseObj(), LdapMessage.SEARCH_RES_RESULT,
+ LDAP_NO_SUCH_OBJECT,
+ ldapErrorMessage[LDAP_NO_SUCH_OBJECT] + ldapUser.getErrorMsg());
+ log.info("Failed");
+ return m_encoder.getTrimmedBuf();
+ }
+ }
+
+ // Check to see if the input passwd is match to the one
+ // in compiere database
+ if (usrId.compareTo(ldapUser.getUserId()) == 0 &&
+ pwd.compareTo(ldapUser.getPassword()) == 0)
+ { // Successfully authenticated
+ generateResult("", LdapMessage.BIND_RESPONSE,
+ LDAP_SUCCESS, null);
+ // Close the connection to client since most of the client
+ // application might cache the connection but we can't afford
+ // to have too many such client connection
+ disconnect = true;
+ log.info("Success");
+ }
+ else
+ { // Unsuccessfully authenticated
+ errNo = LDAP_INAPPROPRIATE_AUTHENTICATION;
+ generateResult("", LdapMessage.BIND_RESPONSE,
+ LDAP_INAPPROPRIATE_AUTHENTICATION,
+ ldapErrorMessage[LDAP_INAPPROPRIATE_AUTHENTICATION]);
+ log.info("Failed : " + ldapErrorMessage[LDAP_INAPPROPRIATE_AUTHENTICATION]);
+ }
+ }
+ else if (ldapMsg.getOperation() == LdapMessage.SEARCH_REQUEST)
+ {
+ // Authenticate with compiere database
+ ldapUser.reset();
+ model.authenticate(ldapUser, usrId, o, ou);
+ if (ldapUser.getErrorMsg() != null)
+ {
+ errNo = LDAP_NO_SUCH_OBJECT;
+ generateResult(ldapMsg.getBaseObj(), LdapMessage.SEARCH_RES_RESULT,
+ LDAP_NO_SUCH_OBJECT,
+ ldapErrorMessage[LDAP_NO_SUCH_OBJECT] + ldapUser.getErrorMsg());
+ log.info("Failed");
+ return m_encoder.getTrimmedBuf();
+ }
+
+ m_encoder.beginSeq(48); // Hard coded here for Envelope header
+ m_encoder.encodeInt(ldapMsg.getMsgId());
+ m_encoder.beginSeq(LdapMessage.SEARCH_REP_ENTRY); // Application 4
+ m_encoder.encodeString("cn="+ldapMsg.getUserId(), true); // this should be object name
+ // not going to put in any attributes for this
+ m_encoder.beginSeq(48);
+ m_encoder.endSeq();
+ m_encoder.endSeq();
+ m_encoder.endSeq();
+
+ // SearchResultDone Application 5 for bind
+ // Result 0 = success
+ // No error message
+ generateResult(ldapMsg.getBaseObj(), LdapMessage.SEARCH_RES_RESULT,
+ LDAP_SUCCESS, null);
+ log.info("Success");
+ }
+
+ return m_encoder.getTrimmedBuf();
+ }
+ catch (Exception e)
+ {
+ log.log(Level.SEVERE, "", e);
+ }
+
+ return m_encoder.getTrimmedBuf();
+ } // bindResponse
+
+ /**
+ * Generate LDAPResult
+ * @param dn Distinguished Name
+ * @param resultProtocol Result protocol/operation code
+ * @param resultCode Result code
+ * @param errMsg Error Message
+ * @return reponse
+ */
+ private void generateResult(String dn, int resultProtocol,
+ int resultCode, String errMsg)
+ {
+ try
+ {
+ m_encoder.beginSeq(48); // Hard coded here for Envelope header
+ m_encoder.encodeInt(ldapMsg.getMsgId());
+ m_encoder.beginSeq(resultProtocol);
+ m_encoder.encodeInt(resultCode, 10); // Enumeration - 10
+ // Adding LDAPDN
+ m_encoder.encodeString(dn, true);
+ // Adding error message
+ m_encoder.encodeString((errMsg == null)?"":errMsg, true);
+ m_encoder.endSeq();
+ m_encoder.endSeq();
+ }
+ catch (Exception ex)
+ {
+ log.log(Level.SEVERE, "", ex);
+ }
+ } // generateResult()
+
+ /*
+ * Should it be close the connection with client
+ */
+ public boolean getDone()
+ {
+ if (errNo != LDAP_SUCCESS)
+ return true;
+ return disconnect;
+ } // getDone()
+
+ /**
+ * Set the error No
+ * @param errNo Error Number
+ */
+ public void setErrorNo(int errNo)
+ {
+ this.errNo = errNo;
+ } // setErrorNo()
+
+ /**
+ * Get the error No
+ * @return errNo Error Number
+ */
+ public int getErrorNo()
+ {
+ return errNo;
+ } // getErrorNo()
+
+ /**
+ * Set the error String
+ * @param errStr Error String
+ */
+ public void setErrorString(String errStr)
+ {
+ this.errStr = errStr;
+ } // setErrorStr()
+
+ static final int LDAP_SUCCESS = 0;
+ static final int LDAP_OPERATIONS_ERROR = 1;
+ static final int LDAP_PROTOCOL_ERROR = 2;
+ static final int LDAP_TIME_LIMIT_EXCEEDED = 3;
+ static final int LDAP_SIZE_LIMIT_EXCEEDED = 4;
+ static final int LDAP_COMPARE_FALSE = 5;
+ static final int LDAP_COMPARE_TRUE = 6;
+ static final int LDAP_AUTH_METHOD_NOT_SUPPORTED = 7;
+ static final int LDAP_STRONG_AUTH_REQUIRED = 8;
+ static final int LDAP_PARTIAL_RESULTS = 9;
+ static final int LDAP_REFERRAL = 10;
+ static final int LDAP_ADMIN_LIMIT_EXCEEDED = 11;
+ static final int LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12;
+ static final int LDAP_CONFIDENTIALITY_REQUIRED = 13;
+ static final int LDAP_SASL_BIND_IN_PROGRESS = 14;
+ static final int LDAP_NO_SUCH_ATTRIBUTE = 16;
+ static final int LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17;
+ static final int LDAP_INAPPROPRIATE_MATCHING = 18;
+ static final int LDAP_CONSTRAINT_VIOLATION = 19;
+ static final int LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20;
+ static final int LDAP_INVALID_ATTRIBUTE_SYNTAX = 21;
+ static final int LDAP_NO_SUCH_OBJECT = 32;
+ static final int LDAP_ALIAS_PROBLEM = 33;
+ static final int LDAP_INVALID_DN_SYNTAX = 34;
+ static final int LDAP_IS_LEAF = 35;
+ static final int LDAP_ALIAS_DEREFERENCING_PROBLEM = 36;
+ static final int LDAP_INAPPROPRIATE_AUTHENTICATION = 48;
+ static final int LDAP_INVALID_CREDENTIALS = 49;
+ static final int LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50;
+ static final int LDAP_BUSY = 51;
+ static final int LDAP_UNAVAILABLE = 52;
+ static final int LDAP_UNWILLING_TO_PERFORM = 53;
+ static final int LDAP_LOOP_DETECT = 54;
+ static final int LDAP_NAMING_VIOLATION = 64;
+ static final int LDAP_OBJECT_CLASS_VIOLATION = 65;
+ static final int LDAP_NOT_ALLOWED_ON_NON_LEAF = 66;
+ static final int LDAP_NOT_ALLOWED_ON_RDN = 67;
+ static final int LDAP_ENTRY_ALREADY_EXISTS = 68;
+ static final int LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69;
+ static final int LDAP_AFFECTS_MULTIPLE_DSAS = 71;
+ static final int LDAP_OTHER = 80;
+ static final String ldapErrorMessage[] = {
+ "Success", "Operations Error", "Protocol Error", "Timelimit Exceeded",
+ "Sizelimit Exceeded", "Compare False", "Compare True",
+ "Authentication Method Not Supported", "Strong Authentication Required", null,
+ "Referral", "Administrative Limit Exceeded", "Unavailable Critical Extension",
+ "Confidentiality Required", "SASL Bind In Progress", null, "No Such Attribute",
+ "Undefined Attribute Type", "Inappropriate Matching", "Constraint Violation",
+ "Attribute Or Value Exists", "Invalid Attribute Syntax", null, null, null,
+ null, null, null, null, null,null, null, "No Such Object", "Alias Problem",
+ "Invalid DN Syntax", null, "Alias Dereferencing Problem", null, null, null,
+ null, null, null, null, null, null, null, null, "Inappropriate Authentication",
+ "Invalid Credentials", "Insufficient Access Rights", "Busy", "Unavailable",
+ "Unwilling To Perform", "Loop Detect", null, null, null, null, null,
+ null, null, null, null, "Naming Violation", "Object Class Violation",
+ "Not Allowed On Non-leaf", "Not Allowed On RDN", "Entry Already Exists",
+ "Object Class Modifications Prohibited", null, "Affects Multiple DSAs", null,
+ null, null, null, null, null, null, null,"Other", null, null, null, null,
+ null, null, null, null, null,null
+ };
+} // LdapResult
diff --git a/serverRoot/src/main/server/org/compiere/server/AdempiereServer.java b/serverRoot/src/main/server/org/compiere/server/AdempiereServer.java
index 4dde40ed9c..0472f50efb 100644
--- a/serverRoot/src/main/server/org/compiere/server/AdempiereServer.java
+++ b/serverRoot/src/main/server/org/compiere/server/AdempiereServer.java
@@ -3,25 +3,25 @@
* 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.server;
-
-import java.sql.*;
-import java.util.*;
-import java.util.logging.*;
-import org.compiere.ldap.*;
-import org.compiere.model.*;
-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.server;
+
+import java.sql.*;
+import java.util.*;
+import java.util.logging.*;
+import org.compiere.ldap.*;
+import org.compiere.model.*;
+import org.compiere.util.*;
import org.compiere.wf.*;
/**
@@ -41,23 +41,23 @@ public abstract class AdempiereServer extends Thread
{
if (model instanceof MRequestProcessor)
return new RequestProcessor ((MRequestProcessor)model);
- if (model instanceof MWorkflowProcessor)
- return new WorkflowProcessor ((MWorkflowProcessor)model);
- if (model instanceof MAcctProcessor)
- return new AcctProcessor ((MAcctProcessor)model);
- if (model instanceof MAlertProcessor)
+ if (model instanceof MWorkflowProcessor)
+ return new WorkflowProcessor ((MWorkflowProcessor)model);
+ if (model instanceof MAcctProcessor)
+ return new AcctProcessor ((MAcctProcessor)model);
+ if (model instanceof MAlertProcessor)
return new AlertProcessor ((MAlertProcessor)model);
if (model instanceof MScheduler)
return new Scheduler ((MScheduler)model);
- if (model instanceof LdapProcessorModel)
- return new LdapProcessor((LdapProcessorModel)model);
+ if (model instanceof MLdapProcessor)
+ return new LdapProcessor((MLdapProcessor)model);
//
throw new IllegalArgumentException("Unknown Processor");
} // create
-
-
- /**************************************************************************
- * Server Base Class
+
+
+ /**************************************************************************
+ * Server Base Class
* @param model model
* @param initialNap delay time running in sec
*/
@@ -67,11 +67,11 @@ public abstract class AdempiereServer extends Thread
p_model = model;
m_ctx = new Properties(model.getCtx());
if (p_system == null)
- p_system = MSystem.get(m_ctx);
- p_client = MClient.get(m_ctx);
- Env.setContext(m_ctx, "#AD_Client_ID", p_client.getAD_Client_ID());
- m_initialNap = initialNap;
- // log.info(model.getName() + " - " + getThreadGroup());
+ p_system = MSystem.get(m_ctx);
+ p_client = MClient.get(m_ctx);
+ Env.setContext(m_ctx, "#AD_Client_ID", p_client.getAD_Client_ID());
+ m_initialNap = initialNap;
+ // log.info(model.getName() + " - " + getThreadGroup());
} // ServerBase
/** The Processor Model */
@@ -79,221 +79,221 @@ public abstract class AdempiereServer extends Thread
/** Initial nap is seconds */
private int m_initialNap = 0;
- /** Miliseconds to sleep - 10 Min default */
- private long m_sleepMS = 600000;
- /** Sleeping */
- private volatile boolean m_sleeping = false;
- /** Server start time */
- private long m_start = 0;
- /** Number of Work executions */
- protected int p_runCount = 0;
- /** Tine start of work */
- protected long p_startWork = 0;
- /** Number MS of last Run */
- private long m_runLastMS = 0;
- /** Number of MS total */
- private long m_runTotalMS = 0;
- /** When to run next */
- private long m_nextWork = 0;
-
- /** Logger */
- protected CLogger log = CLogger.getCLogger(getClass());
- /** Context */
- private Properties m_ctx = null;
- /** System */
- protected static MSystem p_system = null;
- /** Client */
- protected MClient p_client = null;
-
- /**
- * Get Server Context
- * @return context
- */
- public Properties getCtx()
- {
- return m_ctx;
- } // getCtx
-
- /**
- * @return Returns the sleepMS.
- */
- public long getSleepMS ()
- {
- return m_sleepMS;
- } // getSleepMS
-
-
- /**
- * Sleep for set time
- * @return true if not interrupted
- */
- public boolean sleep()
- {
- if (isInterrupted())
- {
- log.info (getName() + ": interrupted");
- return false;
- }
- log.fine(getName() + ": sleeping " + TimeUtil.formatElapsed(m_sleepMS));
- m_sleeping = true;
- try
- {
- sleep (m_sleepMS);
- }
- catch (InterruptedException e)
- {
- log.info (getName() + ": interrupted");
- m_sleeping = false;
- return false;
- }
- m_sleeping = false;
- return true;
- } // sleep
-
- /**
- * Run Now
- */
- public void runNow()
- {
- log.info(getName());
- p_startWork = System.currentTimeMillis();
- doWork();
- long now = System.currentTimeMillis();
- // ---------------
-
- p_runCount++;
- m_runLastMS = now - p_startWork;
- m_runTotalMS += m_runLastMS;
- //
- p_model.setDateLastRun(new Timestamp(now));
- p_model.save();
- //
- log.fine(getName() + ": " + getStatistics());
- } // runNow
-
- /**************************************************************************
- * Run async
- */
- public void run ()
- {
- try
- {
- log.fine(getName() + ": pre-nap - " + m_initialNap);
- sleep (m_initialNap * 1000);
- }
- catch (InterruptedException e)
- {
- log.log(Level.SEVERE, getName() + ": pre-nap interrupted", e);
- return;
- }
-
- m_start = System.currentTimeMillis();
- while (true)
- {
- if (m_nextWork == 0)
- {
- Timestamp dateNextRun = getDateNextRun(true);
- if (dateNextRun != null)
- m_nextWork = dateNextRun.getTime();
- }
- long now = System.currentTimeMillis();
- if (m_nextWork > now)
- {
- m_sleepMS = m_nextWork - now;
- if (!sleep ())
- break;
- }
- if (isInterrupted())
- {
- log.info (getName() + ": interrupted");
- break;
- }
-
- // ---------------
- p_startWork = System.currentTimeMillis();
- doWork();
- now = System.currentTimeMillis();
- // ---------------
-
- p_runCount++;
- m_runLastMS = now - p_startWork;
- m_runTotalMS += m_runLastMS;
- //
- m_sleepMS = calculateSleep();
- m_nextWork = now + m_sleepMS;
- //
- p_model.setDateLastRun(new Timestamp(now));
- p_model.setDateNextRun(new Timestamp(m_nextWork));
- p_model.save();
- //
- log.fine(getName() + ": " + getStatistics());
- if (!sleep())
- break;
- }
- m_start = 0;
- } // run
-
- /**
- * Get Run Statistics
- * @return Statistic info
- */
- public String getStatistics()
- {
- return "Run #" + p_runCount
- + " - Last=" + TimeUtil.formatElapsed(m_runLastMS)
- + " - Total=" + TimeUtil.formatElapsed(m_runTotalMS)
- + " - Next " + TimeUtil.formatElapsed(m_nextWork - System.currentTimeMillis());
- } // getStatistics
-
- /**
- * Do the actual Work
- */
- protected abstract void doWork();
-
- /**
- * Get Server Info
- * @return info
- */
- public abstract String getServerInfo();
-
- /**
- * Get Unique ID
- * @return Unique ID
- */
- public String getServerID()
- {
- return p_model.getServerID();
- } // getServerID
-
- /**
- * Get the date Next run
- * @param requery requery database
- * @return date next run
- */
- public Timestamp getDateNextRun (boolean requery)
- {
- return p_model.getDateNextRun(requery);
- } // getDateNextRun
-
- /**
- * Get the date Last run
- * @return date lext run
- */
- public Timestamp getDateLastRun ()
- {
- return p_model.getDateLastRun();
- } // getDateLastRun
-
- /**
- * Get Description
- * @return Description
- */
- public String getDescription()
- {
- return p_model.getDescription();
- } // getDescription
-
- /**
+ /** Miliseconds to sleep - 10 Min default */
+ private long m_sleepMS = 600000;
+ /** Sleeping */
+ private volatile boolean m_sleeping = false;
+ /** Server start time */
+ private long m_start = 0;
+ /** Number of Work executions */
+ protected int p_runCount = 0;
+ /** Tine start of work */
+ protected long p_startWork = 0;
+ /** Number MS of last Run */
+ private long m_runLastMS = 0;
+ /** Number of MS total */
+ private long m_runTotalMS = 0;
+ /** When to run next */
+ private long m_nextWork = 0;
+
+ /** Logger */
+ protected CLogger log = CLogger.getCLogger(getClass());
+ /** Context */
+ private Properties m_ctx = null;
+ /** System */
+ protected static MSystem p_system = null;
+ /** Client */
+ protected MClient p_client = null;
+
+ /**
+ * Get Server Context
+ * @return context
+ */
+ public Properties getCtx()
+ {
+ return m_ctx;
+ } // getCtx
+
+ /**
+ * @return Returns the sleepMS.
+ */
+ public long getSleepMS ()
+ {
+ return m_sleepMS;
+ } // getSleepMS
+
+
+ /**
+ * Sleep for set time
+ * @return true if not interrupted
+ */
+ public boolean sleep()
+ {
+ if (isInterrupted())
+ {
+ log.info (getName() + ": interrupted");
+ return false;
+ }
+ log.fine(getName() + ": sleeping " + TimeUtil.formatElapsed(m_sleepMS));
+ m_sleeping = true;
+ try
+ {
+ sleep (m_sleepMS);
+ }
+ catch (InterruptedException e)
+ {
+ log.info (getName() + ": interrupted");
+ m_sleeping = false;
+ return false;
+ }
+ m_sleeping = false;
+ return true;
+ } // sleep
+
+ /**
+ * Run Now
+ */
+ public void runNow()
+ {
+ log.info(getName());
+ p_startWork = System.currentTimeMillis();
+ doWork();
+ long now = System.currentTimeMillis();
+ // ---------------
+
+ p_runCount++;
+ m_runLastMS = now - p_startWork;
+ m_runTotalMS += m_runLastMS;
+ //
+ p_model.setDateLastRun(new Timestamp(now));
+ p_model.save();
+ //
+ log.fine(getName() + ": " + getStatistics());
+ } // runNow
+
+ /**************************************************************************
+ * Run async
+ */
+ public void run ()
+ {
+ try
+ {
+ log.fine(getName() + ": pre-nap - " + m_initialNap);
+ sleep (m_initialNap * 1000);
+ }
+ catch (InterruptedException e)
+ {
+ log.log(Level.SEVERE, getName() + ": pre-nap interrupted", e);
+ return;
+ }
+
+ m_start = System.currentTimeMillis();
+ while (true)
+ {
+ if (m_nextWork == 0)
+ {
+ Timestamp dateNextRun = getDateNextRun(true);
+ if (dateNextRun != null)
+ m_nextWork = dateNextRun.getTime();
+ }
+ long now = System.currentTimeMillis();
+ if (m_nextWork > now)
+ {
+ m_sleepMS = m_nextWork - now;
+ if (!sleep ())
+ break;
+ }
+ if (isInterrupted())
+ {
+ log.info (getName() + ": interrupted");
+ break;
+ }
+
+ // ---------------
+ p_startWork = System.currentTimeMillis();
+ doWork();
+ now = System.currentTimeMillis();
+ // ---------------
+
+ p_runCount++;
+ m_runLastMS = now - p_startWork;
+ m_runTotalMS += m_runLastMS;
+ //
+ m_sleepMS = calculateSleep();
+ m_nextWork = now + m_sleepMS;
+ //
+ p_model.setDateLastRun(new Timestamp(now));
+ p_model.setDateNextRun(new Timestamp(m_nextWork));
+ p_model.save();
+ //
+ log.fine(getName() + ": " + getStatistics());
+ if (!sleep())
+ break;
+ }
+ m_start = 0;
+ } // run
+
+ /**
+ * Get Run Statistics
+ * @return Statistic info
+ */
+ public String getStatistics()
+ {
+ return "Run #" + p_runCount
+ + " - Last=" + TimeUtil.formatElapsed(m_runLastMS)
+ + " - Total=" + TimeUtil.formatElapsed(m_runTotalMS)
+ + " - Next " + TimeUtil.formatElapsed(m_nextWork - System.currentTimeMillis());
+ } // getStatistics
+
+ /**
+ * Do the actual Work
+ */
+ protected abstract void doWork();
+
+ /**
+ * Get Server Info
+ * @return info
+ */
+ public abstract String getServerInfo();
+
+ /**
+ * Get Unique ID
+ * @return Unique ID
+ */
+ public String getServerID()
+ {
+ return p_model.getServerID();
+ } // getServerID
+
+ /**
+ * Get the date Next run
+ * @param requery requery database
+ * @return date next run
+ */
+ public Timestamp getDateNextRun (boolean requery)
+ {
+ return p_model.getDateNextRun(requery);
+ } // getDateNextRun
+
+ /**
+ * Get the date Last run
+ * @return date lext run
+ */
+ public Timestamp getDateLastRun ()
+ {
+ return p_model.getDateLastRun();
+ } // getDateLastRun
+
+ /**
+ * Get Description
+ * @return Description
+ */
+ public String getDescription()
+ {
+ return p_model.getDescription();
+ } // getDescription
+
+ /**
* Get Model
* @return Model
*/
@@ -301,82 +301,82 @@ public abstract class AdempiereServer extends Thread
{
return p_model;
} // getModel
-
- /**
- * Calculate Sleep ms
- * @return miliseconds
- */
- private long calculateSleep ()
- {
- String frequencyType = p_model.getFrequencyType();
- int frequency = p_model.getFrequency();
- if (frequency < 1)
- frequency = 1;
- //
- long typeSec = 600; // 10 minutes
- if (frequencyType == null)
- typeSec = 300; // 5 minutes
- else if (X_R_RequestProcessor.FREQUENCYTYPE_Minute.equals(frequencyType))
- typeSec = 60;
- else if (X_R_RequestProcessor.FREQUENCYTYPE_Hour.equals(frequencyType))
- typeSec = 3600;
- else if (X_R_RequestProcessor.FREQUENCYTYPE_Day.equals(frequencyType))
- typeSec = 86400;
- //
- return typeSec * 1000 * frequency; // ms
- } // calculateSleep
-
- /**
- * Is Sleeping
- * @return sleeping
- */
- public boolean isSleeping()
- {
- return m_sleeping;
- } // isSleeping
-
- /**
- * String Representation
- * @return info
- */
- public String toString ()
- {
- StringBuffer sb = new StringBuffer (getName())
- .append (",Prio=").append(getPriority())
- .append (",").append (getThreadGroup())
- .append (",Alive=").append(isAlive())
- .append (",Sleeping=").append(m_sleeping)
- .append (",Last=").append(getDateLastRun());
- if (m_sleeping)
- sb.append (",Next=").append(getDateNextRun(false));
- return sb.toString ();
- } // toString
-
- /**
- * Get Seconds Alive
- * @return seconds alive
- */
- public int getSecondsAlive()
- {
- if (m_start == 0)
- return 0;
- long now = System.currentTimeMillis();
- long ms = (now-m_start) / 1000;
- return (int)ms;
- } // getSecondsAlive
-
- /**
- * Get Start Time
- * @return start time
- */
- public Timestamp getStartTime()
- {
- if (m_start == 0)
- return null;
- return new Timestamp (m_start);
- } // getStartTime
-
- /**
+
+ /**
+ * Calculate Sleep ms
+ * @return miliseconds
+ */
+ private long calculateSleep ()
+ {
+ String frequencyType = p_model.getFrequencyType();
+ int frequency = p_model.getFrequency();
+ if (frequency < 1)
+ frequency = 1;
+ //
+ long typeSec = 600; // 10 minutes
+ if (frequencyType == null)
+ typeSec = 300; // 5 minutes
+ else if (X_R_RequestProcessor.FREQUENCYTYPE_Minute.equals(frequencyType))
+ typeSec = 60;
+ else if (X_R_RequestProcessor.FREQUENCYTYPE_Hour.equals(frequencyType))
+ typeSec = 3600;
+ else if (X_R_RequestProcessor.FREQUENCYTYPE_Day.equals(frequencyType))
+ typeSec = 86400;
+ //
+ return typeSec * 1000 * frequency; // ms
+ } // calculateSleep
+
+ /**
+ * Is Sleeping
+ * @return sleeping
+ */
+ public boolean isSleeping()
+ {
+ return m_sleeping;
+ } // isSleeping
+
+ /**
+ * String Representation
+ * @return info
+ */
+ public String toString ()
+ {
+ StringBuffer sb = new StringBuffer (getName())
+ .append (",Prio=").append(getPriority())
+ .append (",").append (getThreadGroup())
+ .append (",Alive=").append(isAlive())
+ .append (",Sleeping=").append(m_sleeping)
+ .append (",Last=").append(getDateLastRun());
+ if (m_sleeping)
+ sb.append (",Next=").append(getDateNextRun(false));
+ return sb.toString ();
+ } // toString
+
+ /**
+ * Get Seconds Alive
+ * @return seconds alive
+ */
+ public int getSecondsAlive()
+ {
+ if (m_start == 0)
+ return 0;
+ long now = System.currentTimeMillis();
+ long ms = (now-m_start) / 1000;
+ return (int)ms;
+ } // getSecondsAlive
+
+ /**
+ * Get Start Time
+ * @return start time
+ */
+ public Timestamp getStartTime()
+ {
+ if (m_start == 0)
+ return null;
+ return new Timestamp (m_start);
+ } // getStartTime
+
+ /**
* Get Processor Logs
* @return logs
*/
diff --git a/serverRoot/src/main/server/org/compiere/server/AdempiereServerMgr.java b/serverRoot/src/main/server/org/compiere/server/AdempiereServerMgr.java
index 5285c1cdd6..d79098a82d 100644
--- a/serverRoot/src/main/server/org/compiere/server/AdempiereServerMgr.java
+++ b/serverRoot/src/main/server/org/compiere/server/AdempiereServerMgr.java
@@ -20,7 +20,6 @@ import java.sql.*;
import java.util.*;
import java.util.logging.*;
import org.compiere.*;
-import org.compiere.ldap.*;
import org.compiere.model.*;
import org.compiere.util.*;
import org.compiere.wf.*;
@@ -148,12 +147,15 @@ public class AdempiereServerMgr
m_servers.add(server);
}
// LDAP
- LdapProcessorModel lp = new LdapProcessorModel(m_ctx);
- AdempiereServer server = AdempiereServer.create(lp);
- server.start();
- server.setPriority(Thread.NORM_PRIORITY-2);
- m_servers.add(server);
-
+ MLdapProcessor[] ldapModels = MLdapProcessor.getActive(m_ctx);
+ for (int i = 0; i < ldapModels.length; i++)
+ {
+ MLdapProcessor lp = ldapModels[i];
+ AdempiereServer server = AdempiereServer.create(lp);
+ server.start();
+ server.setPriority(Thread.NORM_PRIORITY-1);
+ m_servers.add(server);
+ }
log.fine("#" + noServers);
return startAll();
diff --git a/serverRoot/src/web/adempiere.jnlp b/serverRoot/src/web/adempiere.jnlp
index 858d1e54d3..053593f80e 100644
--- a/serverRoot/src/web/adempiere.jnlp
+++ b/serverRoot/src/web/adempiere.jnlp
@@ -3,7 +3,7 @@
codebase = "$$context/adempiereHome"
href = "$$context/adempiere.jnlp">
- Adempiere Client 3.1.1 $$context
+ Adempiere Client 3.1.2 $$context
ComPiere, Inc.