public Account getAcctByBusinessPartner(
      String AcctType, String bpId, AcctSchema as, ConnectionProvider conn) {
    AcctServerData[] data = null;
    try {
      if (AcctType.equals(ACCTTYPE_NotInvoicedReceipts)) {
        data = AcctServerData.selectNotInvoicedReceiptsAcct(conn, bpId, as.getC_AcctSchema_ID());
      }

    } catch (ServletException e) {
      log4j.warn("SelectNotInvoicedReceiptsAcct" + e);
    }

    // Get Acct
    String Account_ID = "";
    if (data != null && data.length != 0) {
      Account_ID = data[0].accountId;
    } else return null;
    // No account
    if (Account_ID.equals("")) {
      log4j.warn("AcctServer - getAccount - NO account Type=" + AcctType + ", Record=" + Record_ID);
      return null;
    }

    Account acct = null;
    try {
      acct = Account.getAccount(conn, Account_ID);
    } catch (ServletException e) {
      log4j.warn("Get Account" + e);
    }
    return acct;
  }
  /**
   * Get the account for Accounting Schema
   *
   * @param AcctType see ACCTTYPE_*
   * @param as accounting schema
   * @return Account
   */
  public final Account getAccountByWarehouse(
      String AcctType, AcctSchema as, String WarehouseId, ConnectionProvider conn) {
    AcctServerData[] data = null;

    try {
      /** Account Type - Invoice */
      if (AcctType.equals(ACCTTYPE_InvDifferences)) {
        /** Inventory Accounts */
        data = AcctServerData.selectWDifferencesAcct(conn, WarehouseId, as.getC_AcctSchema_ID());
      } else {
        log4jDocCostAdjustment.warn("AcctServer - getAccount - Not found AcctType=" + AcctType);
        return null;
      }
    } catch (ServletException e) {
      log4jDocCostAdjustment.warn(e);
      e.printStackTrace();
    }
    // Get Acct
    String Account_ID = "";
    if (data != null && data.length != 0) {
      Account_ID = data[0].accountId;
    } else return null;
    // No account
    if (Account_ID.equals("")) {
      log4jDocCostAdjustment.warn(
          "AcctServer - getAccount - NO account Type=" + AcctType + ", Record=" + Record_ID);
      return null;
    }
    Account acct = null;
    try {
      acct = Account.getAccount(conn, Account_ID);
    } catch (ServletException e) {
      log4jDocCostAdjustment.warn(e);
      e.printStackTrace();
    }
    return acct;
  } // getAccount
  /**
   * Create Facts (the accounting logic) for MMS, MMR.
   *
   * <pre>
   *  Shipment
   *      CoGS            DR
   *      Inventory               CR
   *  Shipment of Project Issue
   *      CoGS            DR
   *      Project                 CR
   *  Receipt
   *      Inventory       DR
   *      NotInvoicedReceipt      CR
   * </pre>
   *
   * @param as accounting schema
   * @return Fact
   */
  public Fact createFact(
      AcctSchema as, ConnectionProvider conn, Connection con, VariablesSecureApp vars)
      throws ServletException {
    // Select specific definition
    String strClassname =
        AcctServerData.selectTemplateDoc(conn, as.m_C_AcctSchema_ID, DocumentType);
    if (StringUtils.isEmpty(strClassname)) {
      strClassname = AcctServerData.selectTemplate(conn, as.m_C_AcctSchema_ID, AD_Table_ID);
    } else {
      try {
        DocCostAdjustmentTemplate newTemplate =
            (DocCostAdjustmentTemplate) Class.forName(strClassname).newInstance();
        return newTemplate.createFact(this, as, conn, con, vars);
      } catch (Exception e) {
        log4j.error("Error while creating new instance for DocCostAdjustmentTemplate - ", e);
      }
    }
    C_Currency_ID = as.getC_Currency_ID();
    // create Fact Header
    Fact fact = new Fact(this, as, Fact.POST_Actual);
    String Fact_Acct_Group_ID = SequenceIdData.getUUID();
    String amtDebit = "0";
    String amtCredit = "0";

    // Lines
    for (int i = 0; p_lines != null && i < p_lines.length; i++) {
      DocLine_CostAdjustment line = (DocLine_CostAdjustment) p_lines[i];
      String transactionType = line.getTransactionType();

      BigDecimal amount = new BigDecimal(line.getAmount());
      ProductInfo p = new ProductInfo(line.m_M_Product_ID, conn);

      log4jDocCostAdjustment.debug(
          "antes del creteline, line.getAmount(): "
              + line.getAmount()
              + " - TransactionType: "
              + transactionType);
      if (transactionType.equals(DocLine_CostAdjustment.TRXTYPE_SHIPMENT)) {
        // Cogs DR
        // Inventory Asset CR
        log4jDocCostAdjustment.debug(
            "********** DocCostAdjustment - factAcct - account - "
                + p.getAccount(ProductInfo.ACCTTYPE_P_Cogs, as, conn).C_ValidCombination_ID);

        if (line.isTransactionNegative()) {
          amtDebit = "";
          amtCredit = amount.toPlainString();
        } else {
          amtDebit = amount.toPlainString();
          amtCredit = "";
        }
        fact.createLine(
            line,
            p.getAccount(ProductInfo.ACCTTYPE_P_Cogs, as, conn),
            line.m_C_Currency_ID,
            amtDebit,
            amtCredit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
        fact.createLine(
            line,
            p.getAccount(ProductInfo.ACCTTYPE_P_Asset, as, conn),
            line.m_C_Currency_ID,
            amtCredit,
            amtDebit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
      } else if (transactionType.equals(DocLine_CostAdjustment.TRXTYPE_RECEIPT)) {
        Account acct = null;
        // Inventory Asset DR
        if (line.getIsSource() && ("PDC").equals(line.getSourceProcess())) { // Price Diff
          // Correction
          // Invoice Price Variance CR
          acct = p.getAccount(ProductInfo.ACCTTYPE_P_IPV, as, conn);
        } else if (line.getIsSource() && ("LC").equals(line.getSourceProcess())) {
          throw new IllegalStateException(OBMessageUtils.messageBD("LCNotAccounting"));
        } else {
          // Product Exp CR
          acct =
              getAccountByWarehouse(
                  AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn);
        }
        log4jDocCostAdjustment.debug(
            "********** DocCostAdjustment - factAcct - account - "
                + p.getAccount(ProductInfo.ACCTTYPE_P_Expense, as, conn).C_ValidCombination_ID);
        if (line.isTransactionNegative()) {
          amtDebit = amount.toPlainString();
          amtCredit = "";
        } else {
          amtDebit = "";
          amtCredit = amount.toPlainString();
        }
        fact.createLine(
            line,
            acct,
            line.m_C_Currency_ID,
            amtDebit,
            amtCredit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
        fact.createLine(
            line,
            p.getAccount(ProductInfo.ACCTTYPE_P_Asset, as, conn),
            line.m_C_Currency_ID,
            amtCredit,
            amtDebit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
      } else if (transactionType.equals(DocLine_CostAdjustment.TRXTYPE_INVENTORY)) {
        // Inventory Asset DR
        // Inventory Adjustment CR
        log4jDocCostAdjustment.debug(
            "********** DocCostAdjustment - factAcct - account - "
                + getAccountByWarehouse(
                        AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn)
                    .C_ValidCombination_ID);
        if (line.isTransactionNegative()) {
          amtDebit = amount.toPlainString();
          amtCredit = "";
        } else {
          amtDebit = "";
          amtCredit = amount.toPlainString();
        }
        fact.createLine(
            line,
            getAccountByWarehouse(
                AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn),
            line.m_C_Currency_ID,
            amtDebit,
            amtCredit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
        fact.createLine(
            line,
            p.getAccount(ProductInfo.ACCTTYPE_P_Asset, as, conn),
            line.m_C_Currency_ID,
            amtCredit,
            amtDebit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
      } else if (transactionType.equals(DocLine_CostAdjustment.TRXTYPE_INTERNALMOVEMENTFROM)) {
        // Inventory Asset DR
        // Inventory Adjustment CR
        M_Warehouse_ID = line.getWarehouseId();
        log4jDocCostAdjustment.debug(
            "********** DocCostAdjustment - factAcct - account - "
                + getAccountByWarehouse(
                        AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn)
                    .C_ValidCombination_ID);
        if (line.isTransactionNegative()) {
          amtDebit = amount.negate().toPlainString();
          amtCredit = "";
        } else {
          amtDebit = "";
          amtCredit = amount.negate().toPlainString();
        }
        fact.createLine(
            line,
            p.getAccount(ProductInfo.ACCTTYPE_P_Asset, as, conn),
            line.m_C_Currency_ID,
            amtDebit,
            amtCredit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);

        fact.createLine(
            line,
            getAccountByWarehouse(
                AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn),
            line.m_C_Currency_ID,
            amtCredit,
            amtDebit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
      } else if (transactionType.equals(DocLine_CostAdjustment.TRXTYPE_INTERNALMOVEMENTTO)) {
        // Inventory Asset DR
        // Inventory Adjustment CR
        M_Warehouse_ID = line.getWarehouseId();
        log4jDocCostAdjustment.debug(
            "********** DocCostAdjustment - factAcct - account - "
                + getAccountByWarehouse(
                        AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn)
                    .C_ValidCombination_ID);
        if (line.isTransactionNegative()) {
          amtDebit = amount.toPlainString();
          amtCredit = "";
        } else {
          amtDebit = "";
          amtCredit = amount.toPlainString();
        }
        fact.createLine(
            line,
            getAccountByWarehouse(
                AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn),
            line.m_C_Currency_ID,
            amtDebit,
            amtCredit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
        fact.createLine(
            line,
            p.getAccount(ProductInfo.ACCTTYPE_P_Asset, as, conn),
            line.m_C_Currency_ID,
            amtCredit,
            amtDebit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
      } else if (transactionType.equals(DocLine_CostAdjustment.TRXTYPE_INTERNALCONSUMPTION)) {
        // Inventory Asset DR
        // Inventory Adjustment CR
        M_Warehouse_ID = line.getWarehouseId();
        log4jDocCostAdjustment.debug(
            "********** DocCostAdjustment - factAcct - account - "
                + getAccountByWarehouse(
                        AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn)
                    .C_ValidCombination_ID);
        if (line.isTransactionNegative()) {
          amtDebit = amount.toPlainString();
          amtCredit = "";
        } else {
          amtDebit = "";
          amtCredit = amount.toPlainString();
        }
        fact.createLine(
            line,
            p.getAccount(ProductInfo.ACCTTYPE_P_Asset, as, conn),
            line.m_C_Currency_ID,
            amtDebit,
            amtCredit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);

        fact.createLine(
            line,
            getAccountByWarehouse(
                AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn),
            line.m_C_Currency_ID,
            amtCredit,
            amtDebit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
      } else if (transactionType.equals(DocLine_CostAdjustment.TRXTYPE_BOM)) {
        // Inventory Asset DR
        // Inventory Adjustment CR
        M_Warehouse_ID = line.getWarehouseId();
        log4jDocCostAdjustment.debug(
            "********** DocCostAdjustment - factAcct - account - "
                + getAccountByWarehouse(
                        AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn)
                    .C_ValidCombination_ID);
        if (line.isTransactionNegative()) {
          amtDebit = amount.toPlainString();
          amtCredit = "";
        } else {
          amtDebit = "";
          amtCredit = amount.toPlainString();
        }
        fact.createLine(
            line,
            getAccountByWarehouse(
                AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn),
            line.m_C_Currency_ID,
            amtDebit,
            amtCredit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);

        fact.createLine(
            line,
            p.getAccount(ProductInfo.ACCTTYPE_P_Asset, as, conn),
            line.m_C_Currency_ID,
            amtCredit,
            amtDebit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
      } else if (transactionType.equals(DocLine_CostAdjustment.TRXTYPE_MANUFACTURING)) {
        // Inventory Asset DR
        // Inventory Adjustment CR
        M_Warehouse_ID = line.getWarehouseId();
        log4jDocCostAdjustment.debug(
            "********** DocCostAdjustment - factAcct - account - "
                + getAccountByWarehouse(
                        AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn)
                    .C_ValidCombination_ID);
        if (line.isTransactionNegative()) {
          amtDebit = amount.toPlainString();
          amtCredit = "";
        } else {
          amtDebit = "";
          amtCredit = amount.toPlainString();
        }
        fact.createLine(
            line,
            getAccountByWarehouse(
                AcctServer.ACCTTYPE_InvDifferences, as, line.getWarehouseId(), conn),
            line.m_C_Currency_ID,
            amtDebit,
            amtCredit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);

        fact.createLine(
            line,
            p.getAccount(ProductInfo.ACCTTYPE_P_Asset, as, conn),
            line.m_C_Currency_ID,
            amtCredit,
            amtDebit,
            Fact_Acct_Group_ID,
            nextSeqNo(SeqNo),
            DocumentType,
            line.m_DateAcct,
            null,
            conn);
      }
    } // lines

    SeqNo = "0";
    return fact;
  } // createFact