How to create a new document with specific accounting

From ADempiere
Revision as of 13:51, 29 March 2007 by Rvergara (Talk)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
This Wiki is read-only for reference purposes to avoid broken links.

In order to generate a new document within ADempiere that has a specific accounting to be generated upon completion of the document, it is necessary to follow these 3 steps. For this example it is assumed that the new document behaves similarly to an invoice but generates different accounting transactions:


1. Create a new Base Document using the system/system login. In C_DocType DocBaseType we need a 3 capital letter code that identifies our new document base. In this example we will use PTK, then:

search key:PTK name:DOCTYPE_PTCheck


2. In the java class Doc.java, ADempiere defines the documents supported by the application. We need to add the following statement:

public static final String DOCTYPE_NInvoice = "PTK";


3. Every document table has a class that defines how the accounting transactions are generated. For instance the tables C_Order and C_Invoice have the corresponding and related classes Doc_Order.java and DocInvoice.java. Within these classes you will find a method named "createFacts". This method contains the logic for the document accounting generation.

In reviewing the method you will find the following structure for each document:

if (getDocumentType().equals("A_Type_of_Document") {

} else if (getDocumentType().equals("Another_Type_Of_Document") ) {

}

In order to add accounting for our newly added document (PTCheck) we need to add the following:


else if (getDocumentType().equals(DOCTYPE_PTCheck)) //PTK {

  BigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);
  BigDecimal serviceAmt = Env.ZERO;
  
  //  Header Charge           CR
  BigDecimal amt = getAmount(Doc.AMTTYPE_Charge);
  if (amt != null && amt.signum() != 0)
   fact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as),
    getC_Currency_ID(), null, amt);
  //  TaxDue                  CR
  for (int i = 0; i < m_taxes.length; i++)
  {
   amt = m_taxes[i].getAmount();
   if (amt != null && amt.signum() != 0)
   {
    FactLine tl = fact.createLine(null, m_taxes[i].getAccount(DocTax.ACCTTYPE_TaxDue, as),
     getC_Currency_ID(), null, amt);
    if (tl != null)
     tl.setC_Tax_ID(m_taxes[i].getC_Tax_ID());
   }
  }
  //  Revenue                 CR
  for (int i = 0; i < p_lines.length; i++)
  {
   amt = p_lines[i].getAmtSource();
   BigDecimal dAmt = null;
   if (as.isTradeDiscountPosted())
   {
    BigDecimal discount = p_lines[i].getDiscount();
    if (discount != null && discount.signum() != 0)
    {
     amt = amt.add(discount);
     dAmt = discount;
    }
   }
   fact.createLine (p_lines[i],
    p_lines[i].getAccount(ProductCost.ACCTTYPE_P_Revenue, as),
    getC_Currency_ID(), dAmt, amt);
   if (!p_lines[i].isItem())
   {
    grossAmt = grossAmt.subtract(amt);
    serviceAmt = serviceAmt.add(amt);
   }
  }
  //  Set Locations
  FactLine[] fLines = fact.getLines();
  for (int i = 0; i < fLines.length ; i++)
  {
   if (fLines[i] != null)
   {
    fLines[i].setLocationFromOrg(fLines[i].getAD_Org_ID(), true);      //  from Loc
    fLines[i].setLocationFromBPartner(getC_BPartner_Location_ID(), false);  //  to Loc
   }
  }
  
  //  Receivables     DR
  int receivables_ID = getValidCombination_ID(Doc.ACCTTYPE_BankAsset, as);
  int receivablesServices_ID = getValidCombination_ID (Doc.ACCTTYPE_BankAsset, as);
  if (m_allLinesItem || !as.isPostServices()
   || receivables_ID == receivablesServices_ID)
  {
   grossAmt = getAmount(Doc.AMTTYPE_Gross);
   serviceAmt = Env.ZERO;
  }
  else if (m_allLinesService)
  {
   serviceAmt = getAmount(Doc.AMTTYPE_Gross);
   grossAmt = Env.ZERO;
  }
  if (grossAmt.signum() != 0)
   fact.createLine(null, MAccount.get(getCtx(), receivables_ID),
    getC_Currency_ID(), grossAmt, null);
  if (serviceAmt.signum() != 0)
   fact.createLine(null, MAccount.get(getCtx(), receivablesServices_ID),
    getC_Currency_ID(), serviceAmt, null);

}

la fraccion de codigo que comienza con el comentario de CR, busca la cuenta especifica linea a linea para el credito, la fraccion que comienda con DR lo hace para el debito

si nos fijamos bien en el codigo, el posteo de cada cuenta se realiza con una linea muy similar a esta

fact.createLine (p_lines[i],p_lines[i].getAccount(ProductCost.ACCTTYPE_P_Revenue, as),getC_Currency_ID(), dAmt, amt);

aqui lo que nos interesa es lo sgte p_lines[i].getAccount(ProductCost.ACCTTYPE_P_Revenue, as) ese metodo va a buscar la cuenta correspondiente que se necesita para el posteo que se esta ejecutando este metodo finalmente hace alucion al metodo getValidCombination_ID encontrado en la clase doc.java.

este medoto posee sqls simples que buscan en cada tabla por tipo de documento, la cuenta que le indiquemos, es muy facil de modificar y agregar nuevas cuentas por documentos, en el caso de que las necesitemos.