/**
   * Create Facts (the accounting logic) for PJI
   *
   * <pre>
   *  Issue
   *      ProjectWIP      DR
   *      Inventory               CR
   *  </pre>
   *
   * Project Account is either Asset or WIP depending on Project Type
   *
   * @param as accounting schema
   * @return Fact
   */
  public ArrayList<Fact> createFacts(MAcctSchema as) {
    //  create Fact Header
    Fact fact = new Fact(this, as, Fact.POST_Actual);
    setC_Currency_ID(as.getC_Currency_ID());

    MProject project = new MProject(getCtx(), m_issue.getC_Project_ID(), getTrxName());
    String ProjectCategory = project.getProjectCategory();
    MProduct product = MProduct.get(getCtx(), m_issue.getM_Product_ID());

    //  Line pointers
    FactLine dr = null;
    FactLine cr = null;

    //  Issue Cost
    BigDecimal costs = null;
    BigDecimal total = Env.ZERO;
    if (m_issue.getM_InOutLine_ID() != 0) costs = getPOCost(as);
    else if (m_issue.getS_TimeExpenseLine_ID() != 0) costs = getLaborCost(as);
    if (costs == null) // 	standard Product Costs
    {
      for (MCostDetail cost : m_line.getCostDetail(as)) {
        if (!MCostDetail.existsCost(cost)) continue;

        costs = MCostDetail.getTotalCost(cost, as);
        total = total.add(costs);
      }
    }

    if (total == null || total.signum() == 0) {
      p_Error = "Resubmit - No Costs for " + product.getName();
      log.log(Level.WARNING, p_Error);
      return null;
    }

    //  Project         DR
    int acctType = ACCTTYPE_ProjectWIP;
    if (MProject.PROJECTCATEGORY_AssetProject.equals(ProjectCategory))
      acctType = ACCTTYPE_ProjectAsset;
    dr = fact.createLine(m_line, getAccount(acctType, as), as.getC_Currency_ID(), costs, null);
    dr.setQty(m_line.getQty().negate());

    //  Inventory               CR
    acctType = ProductCost.ACCTTYPE_P_Asset;
    if (product.isService()) acctType = ProductCost.ACCTTYPE_P_Expense;
    cr =
        fact.createLine(
            m_line, m_line.getAccount(acctType, as), as.getC_Currency_ID(), null, costs);
    cr.setM_Locator_ID(m_line.getM_Locator_ID());
    cr.setLocationFromLocator(m_line.getM_Locator_ID(), true); // from Loc
    //
    ArrayList<Fact> facts = new ArrayList<Fact>();
    facts.add(fact);
    return facts;
  } //  createFact
Ejemplo n.º 2
0
  /**
   * Create Facts (the accounting logic) for MMP.
   *
   * <pre>
   *  Production
   *      Inventory       DR      CR
   *  </pre>
   *
   * @param as account schema
   * @return Fact
   */
  public ArrayList<Fact> createFacts(MAcctSchema as) {
    //  create Fact Header
    Fact fact = new Fact(this, as, Fact.POST_Actual);
    setC_Currency_ID(as.getC_Currency_ID());

    //  Line pointer
    FactLine fl = null;
    X_M_Production prod = (X_M_Production) getPO();
    for (int i = 0; i < p_lines.length; i++) {
      DocLine line = p_lines[i];
      //	Calculate Costs
      BigDecimal costs = null;

      // MZ Goodwill
      // if Production CostDetail exist then get Cost from Cost Detail
      MCostDetail cd =
          MCostDetail.get(
              as.getCtx(),
              "M_ProductionLine_ID=?",
              line.get_ID(),
              line.getM_AttributeSetInstance_ID(),
              as.getC_AcctSchema_ID(),
              getTrxName());
      if (cd != null) {
        costs = cd.getAmt();
      } else {
        costs = line.getProductCosts(as, line.getAD_Org_ID(), false);
      }
      if (line.isProductionBOM()) {
        X_M_ProductionLine endProLine = (X_M_ProductionLine) line.getPO();
        Object parentEndPro =
            prod.isUseProductionPlan()
                ? endProLine.getM_ProductionPlan_ID()
                : endProLine.getM_Production_ID();

        //	Get BOM Cost - Sum of individual lines
        BigDecimal bomCost = Env.ZERO;
        for (int ii = 0; ii < p_lines.length; ii++) {
          DocLine line0 = p_lines[ii];
          X_M_ProductionLine bomProLine = (X_M_ProductionLine) line0.getPO();
          Object parentBomPro =
              prod.isUseProductionPlan()
                  ? bomProLine.getM_ProductionPlan_ID()
                  : bomProLine.getM_Production_ID();

          if (!parentBomPro.equals(parentEndPro)) continue;
          if (!line0.isProductionBOM()) {
            // get cost of children
            MCostDetail cd0 =
                MCostDetail.get(
                    as.getCtx(),
                    "M_ProductionLine_ID=?",
                    line0.get_ID(),
                    line0.getM_AttributeSetInstance_ID(),
                    as.getC_AcctSchema_ID(),
                    getTrxName());
            BigDecimal costs0;
            if (cd0 != null) {
              costs0 = cd0.getAmt();
            } else {
              costs0 = line0.getProductCosts(as, line0.getAD_Org_ID(), false);
            }
            bomCost = bomCost.add(costs0.setScale(2, BigDecimal.ROUND_HALF_UP));
          }
        }

        BigDecimal qtyProduced =
            manipulateQtyProduced(mQtyProduced, endProLine, prod.isUseProductionPlan(), null);
        if (line.getQty().compareTo(qtyProduced) != 0) {
          BigDecimal factor = line.getQty().divide(qtyProduced, 12, BigDecimal.ROUND_HALF_UP);
          bomCost = bomCost.multiply(factor).setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        int precision = as.getStdPrecision();
        BigDecimal variance =
            (costs.setScale(precision, BigDecimal.ROUND_HALF_UP)).subtract(bomCost.negate());
        // only post variance if it's not zero
        if (variance.signum() != 0) {
          // post variance
          fl =
              fact.createLine(
                  line,
                  line.getAccount(ProductCost.ACCTTYPE_P_RateVariance, as),
                  as.getC_Currency_ID(),
                  variance.negate());
          if (fl == null) {
            p_Error = "Couldn't post variance " + line.getLine() + " - " + line;
            return null;
          }
          fl.setQty(Env.ZERO);
        }
        // costs = bomCost.negate();
      }
      // end MZ

      //  Inventory       DR      CR
      fl =
          fact.createLine(
              line,
              line.getAccount(ProductCost.ACCTTYPE_P_Asset, as),
              as.getC_Currency_ID(),
              costs);
      if (fl == null) {
        p_Error = "No Costs for Line " + line.getLine() + " - " + line;
        return null;
      }
      fl.setM_Locator_ID(line.getM_Locator_ID());
      fl.setQty(line.getQty());

      //	Cost Detail
      String description = line.getDescription();
      if (description == null) description = "";
      if (line.isProductionBOM()) description += "(*)";
      if (!MCostDetail.createProduction(
          as,
          line.getAD_Org_ID(),
          line.getM_Product_ID(),
          line.getM_AttributeSetInstance_ID(),
          line.get_ID(),
          0,
          costs,
          line.getQty(),
          description,
          getTrxName())) {
        p_Error = "Failed to create cost detail record";
        return null;
      }
    }
    //
    ArrayList<Fact> facts = new ArrayList<Fact>();
    facts.add(fact);
    return facts;
  } //  createFact