use of org.compiere.model.MCostType in project adempiere by adempiere.
the class RollupWorkflow method doIt.
// prepare
protected String doIt() throws Exception {
//Get account schema
MAcctSchema accountSchema = MAcctSchema.get(getCtx(), getAccountingSchemaId());
//Get cost type
MCostType costType = MCostType.get(getCtx(), getCostTypeId());
//Get cost element to process
final List<MCostElement> costElements = getCostElementId() > 0 ? Arrays.asList(MCostElement.get(getCtx(), getCostElementId())) : MCostElement.getCostElement(getCtx(), get_TrxName());
routingService = RoutingServiceFactory.get().getRoutingService(getAD_Client_ID());
//Iterate product ids based on parameters
Arrays.stream(getProductIds()).filter(productId -> productId > 0).forEach(productId -> {
MProduct product = MProduct.get(getCtx(), productId);
log.info("Product: " + product);
int workflowId = 0;
MPPProductPlanning productPlanning = null;
if (workflowId <= 0)
workflowId = MWorkflow.getWorkflowSearchKey(product);
if (workflowId <= 0) {
productPlanning = MPPProductPlanning.find(getCtx(), getOrganizationId(), getWarehouseId(), getResourcePlantId(), product.get_ID(), get_TrxName());
if (productPlanning != null)
workflowId = productPlanning.getAD_Workflow_ID();
else
createNotice(product, "@NotFound@ @PP_Product_Planning_ID@");
}
if (workflowId <= 0)
createNotice(product, "@NotFound@ @AD_Workflow_ID@");
else {
Trx.run(new TrxRunnable() {
MAcctSchema accountSchema;
MCostType costType;
MProduct product;
MPPProductPlanning productPlanning;
int workflowId;
public TrxRunnable setParameters(MAcctSchema accountSchema, MCostType costType, MProduct product, MPPProductPlanning productPlanning, int workflowId) {
this.accountSchema = accountSchema;
this.costType = costType;
this.product = product;
this.productPlanning = productPlanning;
this.workflowId = workflowId;
return this;
}
public void run(String trxName) {
MWorkflow workflow = new MWorkflow(getCtx(), workflowId, trxName);
costElements.stream().filter(costElement -> costElement != null && CostEngine.isActivityControlElement(costElement)).forEach(costElement -> {
rollup(accountSchema, costType, costElement, product, workflow, trxName);
});
if (productPlanning != null) {
productPlanning.load(trxName);
productPlanning.setYield(workflow.getYield());
productPlanning.saveEx();
}
}
}.setParameters(accountSchema, costType, product, productPlanning, workflowId));
}
});
return "@OK@";
}
use of org.compiere.model.MCostType in project adempiere by adempiere.
the class RollupWorkflow method rollup.
/**
* Execute rollup process
* @param accountSchema
* @param costType
* @param costElement
* @param product
* @param workflow
* @param trxName
*/
protected void rollup(MAcctSchema accountSchema, MCostType costType, MCostElement costElement, MProduct product, MWorkflow workflow, String trxName) {
log.info("Workflow: " + workflow);
workflow.setCost(Env.ZERO);
double yield = 1;
int queuingTime = 0;
int setupTime = 0;
int duration = 0;
int waitingTime = 0;
int movingTime = 0;
int workingTime = 0;
MWFNode[] nodes = workflow.getNodes(false, getAD_Client_ID());
for (MWFNode node : nodes) {
node.setCost(Env.ZERO);
if (node.getYield() != 0) {
yield = yield * ((double) node.getYield() / 100);
}
// We use node.getDuration() instead of m_routingService.estimateWorkingTime(node) because
// this will be the minimum duration of this node. So even if the node have defined units/cycle
// we consider entire duration of the node.
long nodeDuration = node.getDuration();
queuingTime += node.getQueuingTime();
setupTime += node.getSetupTime();
duration += nodeDuration;
waitingTime += node.getWaitingTime();
movingTime += node.getMovingTime();
workingTime += node.getWorkingTime();
}
workflow.setCost(Env.ZERO);
workflow.setYield((int) (yield * 100));
workflow.setQueuingTime(queuingTime);
workflow.setSetupTime(setupTime);
workflow.setDuration(duration);
workflow.setWaitingTime(waitingTime);
workflow.setMovingTime(movingTime);
workflow.setWorkingTime(workingTime);
final CostDimension costDimension = new CostDimension(product, accountSchema, costType.getM_CostType_ID(), getOrganizationId(), getWarehouseId(), 0, costElement.get_ID());
MCost cost = MCost.getOrCreate(product, 0, accountSchema, getOrganizationId(), getWarehouseId(), costType.getM_CostType_ID(), costElement.getM_CostElement_ID());
cost.setFutureCostPrice(BigDecimal.ZERO);
if (!cost.isCostFrozen())
cost.setCurrentCostPrice(BigDecimal.ZERO);
AtomicReference<BigDecimal> segmentCost = new AtomicReference<>(Env.ZERO);
Arrays.stream(nodes).filter(node -> node != null).forEach(node -> {
final CostEngine costEngine = CostEngineFactory.getCostEngine(node.getAD_Client_ID());
final BigDecimal rate = StandardCostingMethod.getResourceActualCostRate(node.getS_Resource_ID(), costDimension, trxName);
final BigDecimal baseValue = routingService.getResourceBaseValue(node.getS_Resource_ID(), node);
BigDecimal nodeCostPrecision = baseValue.multiply(rate);
BigDecimal nodeCost;
if (nodeCostPrecision.scale() > accountSchema.getCostingPrecision())
nodeCost = nodeCostPrecision.setScale(accountSchema.getCostingPrecision(), RoundingMode.HALF_UP);
else
nodeCost = nodeCostPrecision;
segmentCost.updateAndGet(costAmt -> costAmt.add(nodeCost));
log.info(Msg.parseTranslation(getCtx(), " @M_CostElement_ID@ : ") + costElement.getName() + ", Node=" + node + ", BaseValue=" + baseValue + ", rate=" + rate + ", nodeCost=" + nodeCost + " => Cost=" + segmentCost);
node.setCost(node.getCost().add(nodeCost));
});
cost.setFutureCostPrice(segmentCost.get());
if (!cost.isCostFrozen())
cost.setCurrentCostPrice(segmentCost.get());
cost.saveEx();
// Update Workflow cost
workflow.setCost(workflow.getCost().add(segmentCost.get()));
// Save Workflow & Nodes
Arrays.stream(nodes).filter(node -> node != null).forEach(node -> node.saveEx());
workflow.saveEx();
log.info("Product: " + product.getName() + " WFCost: " + workflow.getCost());
}
use of org.compiere.model.MCostType in project adempiere by adempiere.
the class RollupBillOfMaterial method doIt.
// prepare
/**
* Generate Calculate Cost
* @return info
* @throws Exception
*/
protected String doIt() throws Exception {
//Get account schema
MAcctSchema acctSchema = MAcctSchema.get(getCtx(), getAccountingSchemaId());
//Get cost type
MCostType costType = MCostType.get(getCtx(), getCostTypeId());
final List<MCostElement> costElements = getCostElementId() > 0 ? Arrays.asList(MCostElement.get(getCtx(), getCostElementId())) : MCostElement.getCostElement(getCtx(), get_TrxName());
//Get max low level
int maxLowLevel = MPPMRP.getMaxLowLevel(getCtx(), get_TrxName());
// Cost Roll-up for all levels
for (int lowLevel = maxLowLevel; lowLevel >= 0; lowLevel--) {
//Iterate product based in parameters
Arrays.stream(getProductIds(lowLevel)).filter(productId -> productId > 0).forEach(productId -> {
MProduct product = MProduct.get(getCtx(), productId);
I_PP_Product_Planning productPlanning = MPPProductPlanning.find(getCtx(), getOrganizationId(), getWarehouseId(), getResourcePlantId(), productId, get_TrxName());
int bomId = 0;
if (productPlanning != null)
bomId = productPlanning.getPP_Product_BOM_ID();
else
createNotice(product, Msg.parseTranslation(getCtx(), "@NotFound@ @PP_Product_Planning_ID@"));
if (bomId <= 0)
bomId = MPPProductBOM.getBOMSearchKey(product);
MPPProductBOM bom = MPPProductBOM.get(getCtx(), bomId);
if (bom == null)
createNotice(product, Msg.parseTranslation(getCtx(), "@NotFound@ @PP_Product_BOM_ID@"));
Trx.run(new TrxRunnable() {
MAcctSchema acctSchema;
MCostType costType;
MProduct product;
MPPProductBOM bom;
public TrxRunnable setParameters(MAcctSchema acctSchema, MCostType costType, MProduct product, MPPProductBOM bom) {
this.acctSchema = acctSchema;
this.costType = costType;
this.product = product;
this.bom = bom;
return this;
}
public void run(String trxName) {
costElements.stream().filter(costElement -> costElement != null).forEach(costElement -> {
rollup(acctSchema, costType, costElement, product, bom, trxName);
});
}
}.setParameters(acctSchema, costType, product, bom));
});
// Products List
}
// for Low Lever
return "@OK@";
}
use of org.compiere.model.MCostType in project adempiere by adempiere.
the class Doc_Invoice method landedCost.
// createFactCash
/**
* Create Landed Cost accounting & Cost lines
* @param as accounting schema
* @param fact fact
* @param line document line
* @param isDebit DR entry (normal api)
* @return true if landed costs were created
*/
private boolean landedCost(MAcctSchema as, Fact fact, DocLine line, boolean isDebit) {
int invoiceLineId = line.get_ID();
MLandedCostAllocation[] landedCostAllocations = MLandedCostAllocation.getOfInvoiceLine(getCtx(), invoiceLineId, getTrxName());
if (landedCostAllocations.length == 0)
return false;
BigDecimal totalBase = Arrays.stream(landedCostAllocations).map(MLandedCostAllocation::getBase).reduce(BigDecimal.ZERO, BigDecimal::add);
// Create New
MInvoiceLine invoiceLine = new MInvoiceLine(getCtx(), invoiceLineId, getTrxName());
Arrays.stream(landedCostAllocations).filter(// only cost allocation with base > 0
landedCostAllocation -> landedCostAllocation.getBase().signum() != 0).forEach(landedCostAllocation -> {
BigDecimal percent = landedCostAllocation.getBase().divide(totalBase, BigDecimal.ROUND_HALF_UP);
String desc = invoiceLine.getDescription();
if (desc == null)
desc = percent + "%";
else
desc += " - " + percent + "%";
if (line.getDescription() != null)
desc += " - " + line.getDescription();
ProductCost productCost = new ProductCost(Env.getCtx(), landedCostAllocation.getM_Product_ID(), landedCostAllocation.getM_AttributeSetInstance_ID(), getTrxName());
BigDecimal debitAmount = BigDecimal.ZERO;
BigDecimal creditAmount = BigDecimal.ZERO;
;
FactLine factLine = null;
MCostType costType = MCostType.get(as, landedCostAllocation.getM_Product_ID(), landedCostAllocation.getAD_Org_ID());
if (MCostType.COSTINGMETHOD_AverageInvoice.equals(costType.getCostingMethod())) {
BigDecimal assetAmount = Optional.ofNullable(MCostDetail.getByDocLineLandedCost(landedCostAllocation, as.getC_AcctSchema_ID(), costType.get_ID())).orElse(BigDecimal.ZERO);
BigDecimal costAdjustment = landedCostAllocation.getAmt().subtract(assetAmount);
if (assetAmount.signum() != 0) {
if (isDebit)
debitAmount = assetAmount;
else
creditAmount = assetAmount;
factLine = fact.createLine(line, productCost.getAccount(ProductCost.ACCTTYPE_P_Asset, as), as.getC_Currency_ID(), debitAmount, creditAmount);
factLine.setDescription(desc + " " + landedCostAllocation.getM_CostElement().getName());
factLine.setM_Product_ID(landedCostAllocation.getM_Product_ID());
}
if (costAdjustment.signum() != 0) {
if (isDebit)
debitAmount = costAdjustment;
else
creditAmount = costAdjustment;
factLine = fact.createLine(line, productCost.getAccount(ProductCost.ACCTTYPE_P_CostAdjustment, as), getC_Currency_ID(), debitAmount, creditAmount);
}
} else {
factLine = fact.createLine(line, productCost.getAccount(ProductCost.ACCTTYPE_P_CostAdjustment, as), getC_Currency_ID(), debitAmount, creditAmount);
}
factLine.setDescription(desc + " " + landedCostAllocation.getM_CostElement().getName());
factLine.setM_Product_ID(landedCostAllocation.getM_Product_ID());
});
log.config("Created #" + landedCostAllocations.length);
return true;
}
use of org.compiere.model.MCostType in project adempiere by adempiere.
the class Doc_Production method createFacts.
// getBalance
/**
* 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 factLine = null;
BigDecimal total = Env.ZERO;
DocLine parentProductionLine = null;
for (DocLine line : p_lines) {
MProduct product = line.getProduct();
if (line.isProductionBOM())
parentProductionLine = line;
if (X_M_Product.PRODUCTTYPE_Item.equals(product.getProductType())) {
BigDecimal totalCosts = Env.ZERO;
BigDecimal qty = line.getQty();
BigDecimal costTransaction = Env.ZERO;
for (MCostDetail cost : line.getCostDetail(as, false)) {
if (!MCostDetail.existsCost(cost))
continue;
costTransaction = MCostDetail.getTotalCost(cost, as);
totalCosts = totalCosts.add(costTransaction);
}
if (qty.signum() < 0)
totalCosts = totalCosts.negate();
total = total.add(totalCosts);
factLine = fact.createLine(line, line.getAccount(ProductCost.ACCTTYPE_P_Asset, as), line.getAccount(ProductCost.ACCTTYPE_P_Asset, as), as.getC_Currency_ID(), totalCosts);
factLine.setM_Product_ID(line.getM_Product_ID());
factLine.setM_Locator_ID(line.getM_LocatorTo_ID());
factLine.setDescription("");
factLine.saveEx();
} else if (!X_M_Product.PRODUCTTYPE_Item.equals(product.getProductType())) {
BigDecimal totalCosts = Env.ZERO;
MAccount acct = null;
for (MCostElement costElement : MCostElement.getCostElement(line.getCtx(), line.getTrxName())) {
if (MCostElement.COSTELEMENTTYPE_BurdenMOverhead.equals(costElement.getCostElementType()))
acct = line.getAccount(ProductCost.ACCTTYPE_P_Burden, as);
else if (MCostElement.COSTELEMENTTYPE_OutsideProcessing.equals(costElement.getCostElementType()))
acct = line.getAccount(ProductCost.ACCTTYPE_P_OutsideProcessing, as);
else if (MCostElement.COSTELEMENTTYPE_Overhead.equals(costElement.getCostElementType()))
acct = line.getAccount(ProductCost.ACCTTYPE_P_Overhead, as);
else if (MCostElement.COSTELEMENTTYPE_Resource.equals(costElement.getCostElementType()))
acct = line.getAccount(ProductCost.ACCTTYPE_P_Labor, as);
else
acct = line.getAccount(ProductCost.ACCTTYPE_P_OutsideProcessing, as);
int warehouseId = DB.getSQLValue(line.getTrxName(), "SELECT M_Warehouse_ID from M_Locator WHERE M_Locator_ID=?", line.getM_Locator_ID());
BigDecimal costTransaction = Env.ZERO;
MCost costDimension = MCost.validateCostForCostType(as, (MCostType) as.getM_CostType(), costElement, product.getM_Product_ID(), line.getAD_Org_ID(), warehouseId, line.getM_AttributeSetInstance_ID(), line.getTrxName());
if (costDimension != null)
costTransaction = costDimension.getCurrentCostPrice().add(costDimension.getCurrentCostPriceLL());
totalCosts = totalCosts.add(costTransaction.multiply(line.getQty()));
}
factLine = fact.createLine(line, acct, acct, as.getC_Currency_ID(), totalCosts);
factLine.setM_Product_ID(line.getM_Product_ID());
factLine.setM_Locator_ID(line.getM_LocatorTo_ID());
if (m_DocStatus.equals(MProduction.DOCSTATUS_Reversed) && m_Reversal_ID != 0 && line.getReversalLine_ID() != 0) {
// Set AmtAcctDr from Original Phys.Inventory
if (!factLine.updateReverseLine(MProduction.Table_ID, m_Reversal_ID, line.getReversalLine_ID(), line.getQty(), Env.ONE)) {
p_Error = "Original Physical Inventory not posted yet";
return null;
}
}
factLine.setDescription("");
factLine.saveEx();
total = total.add(totalCosts);
}
}
// When total no is zero then create an adjustment cost , can happen when of resource rate was changes from original cost finish good
if (total.signum() != 0) {
factLine = fact.createLine(parentProductionLine, parentProductionLine.getAccount(ProductCost.ACCTTYPE_P_CostAdjustment, as), as.getC_Currency_ID(), total);
factLine.setM_Product_ID(parentProductionLine.getM_Product_ID());
factLine.setM_Locator_ID(parentProductionLine.getM_LocatorTo_ID());
factLine.setDescription(" Adjustment Cost");
factLine.saveEx();
}
ArrayList<Fact> facts = new ArrayList<Fact>();
facts.add(fact);
return facts;
}
Aggregations