/**
   * 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
  /**
   * Load Document Details
   *
   * @return error message or null
   */
  protected String loadDocumentDetails() {
    setC_Currency_ID(NO_CURRENCY);
    m_issue = (MProjectIssue) getPO();
    setDateDoc(m_issue.getMovementDate());
    setDateAcct(m_issue.getMovementDate());

    //	Pseudo Line
    m_line = new DocLine(m_issue, this);
    m_line.setQty(m_issue.getMovementQty(), true); //  sets Trx and Storage Qty

    //	Pseudo Line Check
    if (m_line.getM_Product_ID() == 0) log.warning(m_line.toString() + " - No Product");
    log.fine(m_line.toString());
    return null;
  } //  loadDocumentDetails
예제 #3
0
  /**
   * Load Invoice Line
   *
   * @param prod production
   * @return DoaLine Array
   */
  private DocLine[] loadLines(X_M_Production prod) {
    ArrayList<DocLine> list = new ArrayList<DocLine>();
    mQtyProduced = new HashMap<>();
    String sqlPL = null;
    if (prod.isUseProductionPlan()) {
      //			Production
      //	-- ProductionLine	- the real level
      sqlPL =
          "SELECT * FROM "
              + " M_ProductionLine pro_line INNER JOIN M_ProductionPlan plan ON pro_line.M_ProductionPlan_id = plan.M_ProductionPlan_id "
              + " INNER JOIN M_Production pro ON pro.M_Production_id = plan.M_Production_id "
              + " WHERE pro.M_Production_ID=? "
              + " ORDER BY plan.M_ProductionPlan_id, pro_line.Line";
    } else {
      //			Production
      //	-- ProductionLine	- the real level
      sqlPL =
          "SELECT * FROM M_ProductionLine pl " + "WHERE pl.M_Production_ID=? " + "ORDER BY pl.Line";
    }

    PreparedStatement pstmtPL = null;
    ResultSet rsPL = null;
    try {
      pstmtPL = DB.prepareStatement(sqlPL, getTrxName());
      pstmtPL.setInt(1, get_ID());
      rsPL = pstmtPL.executeQuery();
      while (rsPL.next()) {
        X_M_ProductionLine line = new X_M_ProductionLine(getCtx(), rsPL, getTrxName());
        if (line.getMovementQty().signum() == 0) {
          if (log.isLoggable(Level.INFO)) log.info("LineQty=0 - " + line);
          continue;
        }
        DocLine docLine = new DocLine(line, this);
        docLine.setQty(line.getMovementQty(), false);
        //	Identify finished BOM Product
        if (prod.isUseProductionPlan())
          docLine.setProductionBOM(
              line.getM_Product_ID() == line.getM_ProductionPlan().getM_Product_ID());
        else docLine.setProductionBOM(line.getM_Product_ID() == prod.getM_Product_ID());

        if (docLine.isProductionBOM()) {
          manipulateQtyProduced(
              mQtyProduced, line, prod.isUseProductionPlan(), line.getMovementQty());
        }
        //
        if (log.isLoggable(Level.FINE)) log.fine(docLine.toString());
        list.add(docLine);
      }
    } catch (Exception ee) {
      log.log(Level.SEVERE, sqlPL, ee);
    } finally {
      DB.close(rsPL, pstmtPL);
      rsPL = null;
      pstmtPL = null;
    }

    DocLine[] dl = new DocLine[list.size()];
    list.toArray(dl);
    return dl;
  } //	loadLines
예제 #4
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