private void processCostDetail(I_M_CostDetail cd) { if (!cd.isProcessed()) { final Properties ctx = InterfaceWrapperHelper.getCtx(cd); final I_C_AcctSchema as = MAcctSchema.get(ctx, cd.getC_AcctSchema_ID()); final I_AD_Client client = MClient.get(ctx, as.getAD_Client_ID()); if (client.isCostImmediate()) { final MCostDetail cdPO = LegacyAdapters.convertToPO(cd); cdPO.process(); } } }
/** * 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
/** * Get Total Product Costs from Cost Detail or from Current Cost * * @param as accounting schema * @param AD_Org_ID trx org * @param zeroCostsOK zero/no costs are OK * @param whereClause null are OK * @return costs */ public BigDecimal getProductCosts( MAcctSchema as, int AD_Org_ID, boolean zeroCostsOK, String whereClause) { if (whereClause != null && !as.getCostingMethod().equals(MAcctSchema.COSTINGMETHOD_StandardCosting)) { MCostDetail cd = MCostDetail.get( Env.getCtx(), whereClause, get_ID(), getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), p_po.get_TrxName()); if (cd != null) return cd.getAmt(); } return getProductCosts(as, AD_Org_ID, zeroCostsOK); } // getProductCosts
public void createRateVariances(MPPCostCollector cc) { final I_M_Product product; if (cc.isCostCollectorType(X_PP_Cost_Collector.COSTCOLLECTORTYPE_ActivityControl)) { final I_AD_WF_Node node = cc.getPP_Order_Node().getAD_WF_Node(); product = MProduct.forS_Resource_ID(cc.getCtx(), node.getS_Resource_ID(), null); } else if (cc.isCostCollectorType(X_PP_Cost_Collector.COSTCOLLECTORTYPE_ComponentIssue)) { final I_PP_Order_BOMLine bomLine = cc.getPP_Order_BOMLine(); product = MProduct.get(cc.getCtx(), bomLine.getM_Product_ID()); } else { return; } I_PP_Cost_Collector ccrv = null; // Cost Collector - Rate Variance for (MAcctSchema as : getAcctSchema(cc)) { for (I_M_CostElement element : getCostElements(cc.getCtx())) { final MCostDetail cd = getCostDetail(cc, element.getM_CostElement_ID()); if (cd == null) { continue; } // final BigDecimal qty = cd.getQty(); final BigDecimal priceStd = getProductStandardCostPrice(cc, product, as, element); final BigDecimal priceActual = getProductActualCostPriceOrZero(cc, product, as, element, cc.get_TrxName()); final BigDecimal amtStd = roundCost(priceStd.multiply(qty), as.getC_AcctSchema_ID()); final BigDecimal amtActual = roundCost(priceActual.multiply(qty), as.getC_AcctSchema_ID()); if (amtStd.compareTo(amtActual) == 0) { continue; } // if (ccrv == null) { ccrv = createVarianceCostCollector(cc, X_PP_Cost_Collector.COSTCOLLECTORTYPE_RateVariance); } // createVarianceCostDetail(ccrv, amtActual.negate(), qty.negate(), cd, null, as, element); createVarianceCostDetail(ccrv, amtStd, qty, cd, null, as, element); } } // if (ccrv != null) { Services.get(IDocActionBL.class) .processEx(ccrv, DocAction.ACTION_Complete, DocAction.STATUS_Completed); } }
public void createActivityControl(MPPCostCollector cc) { if (!cc.isCostCollectorType(X_PP_Cost_Collector.COSTCOLLECTORTYPE_ActivityControl)) return; // final I_M_Product product = MProduct.forS_Resource_ID(cc.getCtx(), cc.getS_Resource_ID(), null); final RoutingService routingService = RoutingServiceFactory.get().getRoutingService(cc.getAD_Client_ID()); final BigDecimal qty = routingService.getResourceBaseValue(cc.getS_Resource_ID(), cc); for (MAcctSchema as : getAcctSchema(cc)) { for (I_M_CostElement element : getCostElements(cc.getCtx())) { if (!isActivityControlElement(element)) { continue; } final CostDimension d = new CostDimension( product, as, as.getM_CostType_ID(), 0, // AD_Org_ID, 0, // M_ASI_ID element.getM_CostElement_ID()); final BigDecimal price = getResourceActualCostRate(cc, cc.getS_Resource_ID(), d, cc.get_TrxName()); BigDecimal costs = price.multiply(qty); if (costs.scale() > as.getCostingPrecision()) costs = costs.setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); // MCostDetail cd = new MCostDetail( as, 0, // AD_Org_ID, d.getM_Product_ID(), 0, // M_AttributeSetInstance_ID, element.getM_CostElement_ID(), costs.negate(), qty.negate(), "", // Description, cc.get_TrxName()); cd.setPP_Cost_Collector_ID(cc.getPP_Cost_Collector_ID()); cd.saveEx(); processCostDetail(cd); } } }
/** * Perform process. * * @return Message (text with variables) * @throws Exception if not successful */ protected String doIt() throws Exception { if (log.isLoggable(Level.INFO)) log.info("M_Product_ID=" + p_M_Product_ID); if (p_M_Product_ID == 0) throw new AdempiereUserError("@NotFound@: @M_Product_ID@ = " + p_M_Product_ID); MProduct product = MProduct.get(getCtx(), p_M_Product_ID); if (product.get_ID() != p_M_Product_ID) throw new AdempiereUserError("@NotFound@: @M_Product_ID@ = " + p_M_Product_ID); // if (MCostDetail.processProduct(product, get_TrxName())) return "@OK@"; return "@Error@"; } // doIt
/** * Create & Proce Cost Detail for Variances * * @param ccv * @param amt * @param qty * @param cd (optional) * @param product * @param as * @param element * @return */ private MCostDetail createVarianceCostDetail( I_PP_Cost_Collector ccv, BigDecimal amt, BigDecimal qty, MCostDetail cd, I_M_Product product, I_C_AcctSchema as, I_M_CostElement element) { final Properties ctx = InterfaceWrapperHelper.getCtx(ccv); final String trxName = InterfaceWrapperHelper.getTrxName(ccv); final MCostDetail cdv = new MCostDetail(ctx, 0, trxName); if (cd != null) { MCostDetail.copyValues(cd, cdv); cdv.setProcessed(false); } if (product != null) { cdv.setM_Product_ID(product.getM_Product_ID()); cdv.setM_AttributeSetInstance_ID(0); } if (as != null) { cdv.setC_AcctSchema_ID(as.getC_AcctSchema_ID()); } if (element != null) { cdv.setM_CostElement_ID(element.getM_CostElement_ID()); } // cdv.setPP_Cost_Collector_ID(ccv.getPP_Cost_Collector_ID()); cdv.setAmt(amt); cdv.setQty(qty); cdv.saveEx(); processCostDetail(cdv); return cdv; }
/** * Create Cost Detail (Material Issue, Material Receipt) * * @param model * @param mtrx Material Transaction */ public void createCostDetail(IDocumentLine model, MTransaction mtrx) { final I_PP_Cost_Collector cc = (model instanceof MPPCostCollector ? (MPPCostCollector) model : null); final Properties ctx = mtrx.getCtx(); for (I_C_AcctSchema as : getAcctSchema(mtrx)) { // Cost Detail final I_M_Product product = MProduct.get(ctx, mtrx.getM_Product_ID()); final String costingMethod = Services.get(IProductBL.class).getCostingMethod(product, as); // Check costing method if (!getCostingMethod().equals(costingMethod)) { throw new LiberoException("Costing method not supported - " + costingMethod); } // for (I_M_CostElement element : getCostElements(ctx)) { // // Delete Unprocessed zero Differences deleteCostDetail( model, as, element.getM_CostElement_ID(), mtrx.getM_AttributeSetInstance_ID()); // // Get Costs final BigDecimal qty = mtrx.getMovementQty(); final BigDecimal price = getProductActualCostPriceOrZero(cc, product, as, element, mtrx.get_TrxName()); final BigDecimal amt = roundCost(price.multiply(qty), as.getC_AcctSchema_ID()); // // Create / Update Cost Detail MCostDetail cd = getCostDetail(model, mtrx, as, element.getM_CostElement_ID()); if (cd == null) // createNew { cd = new MCostDetail( as, mtrx.getAD_Org_ID(), mtrx.getM_Product_ID(), mtrx.getM_AttributeSetInstance_ID(), element.getM_CostElement_ID(), amt, qty, model.getDescription(), mtrx.get_TrxName()); // cd.setMovementDate(mtrx.getMovementDate()); // if (cost != null) // { // cd.setCurrentCostPrice(cost.getCurrentCostPrice()); // cd.setCurrentCostPriceLL(cost.getCurrentCostPriceLL()); // } // else // { // cd.setCurrentCostPrice(Env.ZERO); // cd.setCurrentCostPriceLL(Env.ZERO); // } // cd.setM_CostType_ID(as.getM_CostType_ID()); // //cd.setCostingMethod(element.getCostingMethod()); // cd.setM_Transaction_ID(mtrx.get_ID()); if (cc != null) { cd.setPP_Cost_Collector_ID(cc.getPP_Cost_Collector_ID()); } } else { cd.setDeltaAmt(amt.subtract(cd.getAmt())); cd.setDeltaQty(mtrx.getMovementQty().subtract(cd.getQty())); if (cd.isDelta()) { cd.setProcessed(false); cd.setAmt(amt); cd.setQty(mtrx.getMovementQty()); } } cd.saveEx(); processCostDetail(cd); log.info("" + cd); } // for ELements } // Account Schema }
/** * 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