use of org.compiere.model.MCostDetail in project adempiere by adempiere.
the class AverageInvoiceCostingMethod method createCostDetail.
private void createCostDetail() {
//Validate if model have a reverses and processing of reverse
if (model.getReversalLine_ID() > 0 && costDetail == null) {
createReversalCostDetail();
return;
} else if (model.getReversalLine_ID() > 0)
return;
int seqNo = lastCostDetail.getSeqNo() + 10;
// adjustment
if (transaction.getM_Transaction_ID() != lastCostDetail.getM_Transaction_ID() && costDetail == null || adjustCost.add(adjustCostLowerLevel).signum() != 0 && costDetail == null) {
// if exist adjustment cost for Landed Cost Allocation or Match Inv then set the movement qty to zero
if ((adjustCost.add(adjustCostLowerLevel).signum() != 0 && costDetail != null) || (model instanceof MLandedCostAllocation || model instanceof MMatchInv))
movementQuantity = Env.ZERO;
// create new cost detail
costDetail = new MCostDetail(transaction, accountSchema.getC_AcctSchema_ID(), dimension.getM_CostType_ID(), dimension.getM_CostElement_ID(), currentCostPrice.multiply(movementQuantity).abs(), currentCostPriceLowerLevel.multiply(movementQuantity).abs(), movementQuantity, transaction.get_TrxName());
// set account date for this cost detail
costDetail.setDateAcct(dateAccounting);
costDetail.setSeqNo(seqNo);
// set transaction id
if (transaction != null)
costDetail.setM_Transaction_ID(transaction.getM_Transaction_ID());
// set if transaction is sales order type or not
if (isSalesTransaction != null && isSalesTransaction)
costDetail.setIsSOTrx(isSalesTransaction);
else if (isSalesTransaction != null && !isSalesTransaction)
costDetail.setIsSOTrx(model.isSOTrx());
if (adjustCost.signum() != 0 || adjustCostLowerLevel.signum() != 0) {
String description = costDetail.getDescription() != null ? costDetail.getDescription() : "";
// update adjustment cost this level
if (adjustCost.signum() != 0) {
costDetail.setCostAdjustmentDate(model.getDateAcct());
costDetail.setCostAdjustment(adjustCost);
costDetail.setCostAmt(BigDecimal.ZERO);
costDetail.setAmt(costDetail.getAmt().add(costDetail.getCostAdjustment()));
costDetail.setDescription(description + Msg.parseTranslation(Env.getCtx(), "@CostAdjustment@ ") + adjustCost);
}
// update adjustment cost lower level
if (adjustCostLowerLevel.signum() != 0) {
description = costDetail.getDescription() != null ? costDetail.getDescription() : "";
costDetail.setCostAdjustmentDateLL(model.getDateAcct());
costDetail.setCostAdjustmentLL(adjustCostLowerLevel);
costDetail.setCostAmtLL(BigDecimal.ZERO);
costDetail.setAmt(costDetail.getCostAmtLL().add(costDetail.getCostAdjustmentLL()));
costDetail.setDescription(description + Msg.parseTranslation(Env.getCtx(), "@CostAdjustmentLL@ ") + adjustCost);
}
}
updateAmountCost();
return;
}
}
use of org.compiere.model.MCostDetail in project adempiere by adempiere.
the class AverageInvoiceCostingMethod method calculate.
public void calculate() {
// try find the last cost detail transaction
lastCostDetail = MCostDetail.getLastTransaction(model, transaction, accountSchema.getC_AcctSchema_ID(), dimension.getM_CostType_ID(), dimension.getM_CostElement_ID(), dateAccounting, costingLevel);
//Validate if model have a reverses and processing of reverse
if (model.getReversalLine_ID() > 0 && costDetail == null)
return;
else if (costDetail != null && costDetail.isReversal() && model.getReversalLine_ID() > 0) {
setReversalCostDetail();
return;
}
// created a new instance cost detail to process calculated cost
if (lastCostDetail == null) {
lastCostDetail = new MCostDetail(transaction, accountSchema.getC_AcctSchema_ID(), dimension.getM_CostType_ID(), dimension.getM_CostElement_ID(), Env.ZERO, Env.ZERO, Env.ZERO, transaction.get_TrxName());
lastCostDetail.setDateAcct(dateAccounting);
}
BigDecimal quantityOnHand = getNewAccumulatedQuantity(lastCostDetail);
// generate adjustment
if (transaction.getM_Transaction_ID() == lastCostDetail.getM_Transaction_ID()) {
//SHW
movementQuantity = Env.ZERO;
//Processing provision of purchase cost
//Provision is calculated when the last cost detail is a material receipt and not exist of invoice line
//if an invoice line exist for this cost detail then an invoice line was processed for this material receipt
//and not exist different between purchase cost and invoice cost, this logic was implemented to prevent
//that a provision of purchase cost decreases more than one times in a cost adjustment
BigDecimal provisionOfPurchaseCost = BigDecimal.ZERO;
BigDecimal provisionOfPurchaseCostLL = BigDecimal.ZERO;
// Quantity accumulated from last cost transaction
accumulatedQuantity = getNewAccumulatedQuantity(lastCostDetail).add(movementQuantity);
if (model instanceof MMatchInv && lastCostDetail.getC_InvoiceLine_ID() == 0) {
provisionOfPurchaseCost = lastCostDetail.getCostAmt();
provisionOfPurchaseCostLL = lastCostDetail.getCostAmtLL();
MMatchInv iMatch = (MMatchInv) model;
lastCostDetail.setC_InvoiceLine_ID(iMatch.getC_InvoiceLine_ID());
lastCostDetail.saveEx();
// reset the accumulated quantity with last cost detail
if (lastCostDetail != null && lastCostDetail.getM_CostDetail_ID() > 0)
accumulatedQuantity = getNewAccumulatedQuantity(lastCostDetail);
}
adjustCost = model.getMovementQty().multiply(costThisLevel).subtract(provisionOfPurchaseCost);
adjustCostLowerLevel = model.getMovementQty().multiply(costLowLevel).subtract(provisionOfPurchaseCostLL);
accumulatedAmount = getNewAccumulatedAmount(lastCostDetail);
accumulatedAmount = accumulatedQuantity.signum() > 0 ? accumulatedAmount.add(adjustCost) : accumulatedAmount.add(adjustCost.negate());
accumulatedAmountLowerLevel = getNewAccumulatedAmountLowerLevel(lastCostDetail);
accumulatedAmountLowerLevel = accumulatedQuantity.signum() > 0 ? accumulatedAmountLowerLevel.add(adjustCostLowerLevel) : accumulatedAmountLowerLevel.add(adjustCostLowerLevel.negate());
currentCostPrice = accumulatedAmount.divide(accumulatedQuantity.signum() != 0 ? accumulatedQuantity : BigDecimal.ONE, accountSchema.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
currentCostPriceLowerLevel = accumulatedAmountLowerLevel.divide(accumulatedQuantity.signum() != 0 ? accumulatedQuantity : BigDecimal.ONE, accountSchema.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
if (adjustCost.add(adjustCostLowerLevel).signum() == 0)
return;
// validation when the cost detail is reprocess
if (costDetail == null)
return;
// reset with the current values
costDetail.setCostAdjustment(adjustCost);
costDetail.setAmt(costDetail.getCostAmt().add(costDetail.getCostAdjustment()));
costDetail.setCostAdjustmentLL(adjustCostLowerLevel);
costDetail.setAmtLL(costDetail.getCostAmtLL().add(costDetail.getCostAdjustmentLL()));
updateAmountCost();
return;
}
// calculated costing
if (transaction.getMovementType().endsWith("+")) {
//the On hand is different zero and inventory values is zero then
if (quantityOnHand.signum() != 0 && getNewAccumulatedAmount(lastCostDetail).signum() == 0 && costThisLevel.signum() != 0) {
adjustCost = quantityOnHand.add(movementQuantity).multiply(costThisLevel).subtract(costThisLevel.multiply(movementQuantity));
} else // Logic to calculate adjustment when inventory is negative
if (quantityOnHand.add(movementQuantity).signum() < 0 && getNewCurrentCostPrice(lastCostDetail, accountSchema.getCostingPrecision(), BigDecimal.ROUND_HALF_UP).signum() != 0 && costThisLevel.signum() == 0) {
currentCostPrice = getNewCurrentCostPrice(lastCostDetail, accountSchema.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
adjustCost = currentCostPrice.multiply(movementQuantity).abs();
}
// proportionally
if (model instanceof MLandedCostAllocation || model instanceof MMatchInv) {
if (!isOpenPeriod) {
int attributeSetInstanceId = 0;
if (model instanceof MLandedCostAllocation) {
MLandedCostAllocation costAllocation = (MLandedCostAllocation) this.model;
attributeSetInstanceId = costAllocation.getM_AttributeSetInstance_ID();
}
if (model instanceof MMatchInv) {
MMatchInv matchInv = (MMatchInv) this.model;
attributeSetInstanceId = matchInv.getM_AttributeSetInstance_ID();
}
this.movementQuantity = MCostDetail.getQtyOnHandByASIAndSeqNo(transaction.getCtx(), transaction.getM_Product_ID(), dimension.getM_CostType_ID(), dimension.getM_CostElement_ID(), attributeSetInstanceId, lastCostDetail.getSeqNo(), transaction.get_TrxName());
accumulatedQuantity = getNewAccumulatedQuantity(lastCostDetail);
currentCostPrice = movementQuantity.multiply(costThisLevel);
currentCostPriceLowerLevel = movementQuantity.multiply(costLowLevel);
adjustCost = currentCostPrice;
adjustCostLowerLevel = currentCostPriceLowerLevel;
}
} else {
accumulatedQuantity = getNewAccumulatedQuantity(lastCostDetail).add(movementQuantity);
currentCostPrice = costThisLevel;
currentCostPriceLowerLevel = costLowLevel;
}
amount = movementQuantity.multiply(costThisLevel);
amountLowerLevel = movementQuantity.multiply(costLowLevel);
accumulatedAmount = getNewAccumulatedAmount(lastCostDetail);
accumulatedAmount = accumulatedQuantity.signum() > 0 ? accumulatedAmount.add(amount) : accumulatedAmount.add(amount.negate());
accumulatedAmountLowerLevel = getNewAccumulatedAmountLowerLevel(lastCostDetail);
accumulatedAmountLowerLevel = accumulatedQuantity.signum() > 0 ? accumulatedAmountLowerLevel.add(amountLowerLevel) : accumulatedAmountLowerLevel.add(amountLowerLevel.negate());
} else if (transaction.getMovementType().endsWith("-")) {
// Use the last current cost price for out transaction
if (quantityOnHand.add(movementQuantity).signum() >= 0) {
currentCostPrice = getNewCurrentCostPrice(lastCostDetail, accountSchema.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
currentCostPriceLowerLevel = getNewCurrentCostPriceLowerLevel(lastCostDetail, accountSchema.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
} else {
currentCostPrice = CostEngine.getCostThisLevel(accountSchema, dimension.getM_CostType(), dimension.getM_CostElement(), transaction, model, costingLevel);
}
amount = transaction.getMovementQty().multiply(currentCostPrice);
amountLowerLevel = movementQuantity.multiply(currentCostPriceLowerLevel);
accumulatedQuantity = getNewAccumulatedQuantity(lastCostDetail).add(movementQuantity);
accumulatedAmount = getNewAccumulatedAmount(lastCostDetail);
accumulatedAmount = accumulatedQuantity.signum() > 0 ? accumulatedAmount.add(amount) : accumulatedAmount.add(amount.negate());
accumulatedAmountLowerLevel = getNewAccumulatedAmountLowerLevel(lastCostDetail);
accumulatedAmountLowerLevel = accumulatedQuantity.signum() > 0 ? accumulatedAmountLowerLevel.add(amountLowerLevel) : accumulatedAmountLowerLevel.add(amountLowerLevel.negate());
if (costDetail != null) {
costDetail.setAmt(currentCostPrice.multiply(movementQuantity.abs()));
costDetail.setAmtLL(currentCostPriceLowerLevel.multiply(movementQuantity).abs());
}
}
//create new cost
if (costDetail == null)
return;
updateAmountCost();
}
use of org.compiere.model.MCostDetail in project adempiere by adempiere.
the class CostEngine method getCostThisLevel.
/**
* get cost this level
* @param accountSchema
* @param costType
* @param costElement
* @param transaction
* @param model
* @param costingLevel
* @return
*/
public static BigDecimal getCostThisLevel(MAcctSchema accountSchema, I_M_CostType costType, I_M_CostElement costElement, MTransaction transaction, IDocumentLine model, String costingLevel) {
BigDecimal costThisLevel = Env.ZERO;
MCostDetail lastCostDetail = MCostDetail.getLastTransaction(model, transaction, accountSchema.getC_AcctSchema_ID(), costType.getM_CostType_ID(), costElement.getM_CostElement_ID(), model.getDateAcct(), costingLevel);
if (lastCostDetail != null) {
// (Total Cost transaction + cost adjustments) divide by transaction quantity
if (lastCostDetail.getQty().signum() != 0) {
costThisLevel = lastCostDetail.getCostAmt().add(lastCostDetail.getCostAdjustment()).divide(lastCostDetail.getQty(), accountSchema.getCostingPrecision(), BigDecimal.ROUND_HALF_UP).abs();
} else // (Total Cost Transaction + cost adjustments + accumulate cost) divide between on hand quantity
if (lastCostDetail.getCumulatedQty().add(lastCostDetail.getQty()).signum() != 0) {
costThisLevel = lastCostDetail.getCostAmt().add(lastCostDetail.getCostAdjustment()).add(lastCostDetail.getCumulatedAmt()).divide(lastCostDetail.getCumulatedQty().add(lastCostDetail.getQty()), accountSchema.getCostingPrecision(), BigDecimal.ROUND_HALF_UP).abs();
return costThisLevel;
} else // (Total Cost transaction + cost adjustments + Cumulated amount) divide by On hand Quantity
if (lastCostDetail.getCumulatedQty().signum() != 0) {
costThisLevel = lastCostDetail.getCumulatedAmt().divide(lastCostDetail.getCumulatedQty(), accountSchema.getCostingPrecision(), BigDecimal.ROUND_HALF_UP).abs();
return costThisLevel;
}
}
return costThisLevel;
}
use of org.compiere.model.MCostDetail in project adempiere by adempiere.
the class InventoryTestException method dumpStatus.
private void dumpStatus(MMDocument doc, String trxName) {
MProduct product = InventoryUtil.getCreateProduct(doc);
MStorage[] storage = MStorage.getOfProduct(getCtx(), product.get_ID(), trxName);
System.err.println("" + product.toString());
System.err.println("STORAGE____________________________________________________");
System.err.println(" " + doc);
for (MStorage s : storage) {
System.err.println("" + s);
}
//
//
System.err.println("COST QUEUE ________________________________________________");
List<MCostQueue> queue = new Query(getCtx(), MCostQueue.Table_Name, "M_Product_ID=?", trxName).setParameters(new Object[] { product.get_ID() }).setOrderBy(MCostQueue.COLUMNNAME_M_CostQueue_ID).list();
for (MCostQueue q : queue) {
System.err.println("" + q);
}
//
//
System.err.println("COST Detail ________________________________________________");
List<MCostDetail> details = new Query(getCtx(), MCostDetail.Table_Name, "M_Product_ID=?", trxName).setParameters(new Object[] { product.get_ID() }).setOrderBy(MCostDetail.COLUMNNAME_M_CostDetail_ID).list();
for (MCostDetail cd : details) {
System.err.println("" + cd.toString());
}
//
//
System.err.println(doc.scenario.toString());
//
System.err.println("___________________________________________________________");
System.err.flush();
System.err.flush();
}
use of org.compiere.model.MCostDetail in project adempiere by adempiere.
the class CostResult method assertCostDetail.
public void assertCostDetail(CostResult costResult, String whereClause, ArrayList<Object> parameters) {
MCostDetail cd = getCostDetail(whereClause, parameters);
System.out.println("Result" + costResult.toString());
System.out.println("Cost Detail " + cd.toString());
assertEquals("Cost Detail Amt ", costResult.cdAmt, cd.getAmt());
assertEquals("Cost Detail Adjutment ", costResult.cdAdjutment, cd.getCostAdjustment());
assertEquals("Cost Detail Qty", costResult.cdQty, cd.getQty());
assertEquals("Cost Detail Current Price Cost ", costResult.cdCurrentCostPrice, cd.getCurrentCostPrice());
assertEquals("Cost Detail Cumulate Qty ", costResult.cdCumulateQty, cd.getCumulatedQty());
assertEquals("Cost Detail Cumulate Amt ", costResult.cdCumulateAmt, cd.getCumulatedAmt());
assertEquals("Account Date", new Date(costResult.cdDateAcct.getTime()).toString(), new Date(cd.getDateAcct().getTime()).toString());
}
Aggregations