use of org.compiere.model.MMatchPO in project adempiere by adempiere.
the class AveragePOCostingMethod 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 MMatchPO))
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)
costDetail.setIsSOTrx(isSalesTransaction);
else
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 + " Adjust Cost:" + 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 + " Adjust Cost LL:" + adjustCost);
}
}
updateAmountCost();
return;
}
}
use of org.compiere.model.MMatchPO in project adempiere by adempiere.
the class AveragePOCostingMethod method adjustCostDetail.
/**
* Recalculate Cost Detail
* @param costDetail
*/
public void adjustCostDetail(MCostDetail costDetail) {
Properties ctx = costDetail.getCtx();
String trxName = costDetail.get_TrxName();
int transactionId = costDetail.getM_Transaction_ID();
int clientId = costDetail.getAD_Client_ID();
MTransaction transaction = new MTransaction(ctx, transactionId, trxName);
MCostType costType = (MCostType) costDetail.getM_CostType();
MCostElement costElement = (MCostElement) costDetail.getM_CostElement();
MAcctSchema accountSchema = (MAcctSchema) costDetail.getC_AcctSchema();
CostEngineFactory.getCostEngine(accountSchema.getAD_Client_ID()).clearAccounting(accountSchema, transaction);
if (MTransaction.MOVEMENTTYPE_VendorReceipts.equals(transaction.getMovementType())) {
MInOutLine line = (MInOutLine) transaction.getDocumentLine();
if (MCostElement.COSTELEMENTTYPE_Material.equals(costElement.getCostElementType())) {
if (costDetail.getM_InOutLine_ID() > 0 && costDetail.getQty().signum() != 0) {
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, line, true);
} else if (costDetail.getM_InOutLine_ID() > 0 && costDetail.getQty().signum() != 0 && costDetail.getC_OrderLine_ID() > 0) {
List<MMatchPO> orderMatches = MMatchPO.getInOutLine(line);
for (MMatchPO match : orderMatches) {
if (match.getM_InOutLine_ID() == line.getM_InOutLine_ID() && match.getM_Product_ID() == transaction.getM_Product_ID()) {
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, match, true);
}
}
} else if (costDetail.getM_InOutLine_ID() > 0 && costDetail.getQty().signum() == 0 && costDetail.getC_OrderLine_ID() > 0) {
List<MMatchPO> poMatches = MMatchPO.getInOutLine(line);
for (MMatchPO match : poMatches) {
if (match.getM_Product_ID() == transaction.getM_Product_ID()) {
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, match, true);
}
}
}
}
for (MLandedCostAllocation allocation : MLandedCostAllocation.getOfInOutline(line, costElement.getM_CostElement_ID())) {
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, allocation, true);
}
} else
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, transaction.getDocumentLine(), true);
}
use of org.compiere.model.MMatchPO in project adempiere by adempiere.
the class GenerateCostDetail method generateCostDetail.
public void generateCostDetail(MAcctSchema accountSchema, MCostType costType, MCostElement costElement, MTransaction transaction) {
//Create Cost Detail for this Transaction
CostEngineFactory.getCostEngine(accountSchema.getAD_Client_ID()).createCostDetail(accountSchema, costType, costElement, transaction, transaction.getDocumentLine(), true);
CostEngineFactory.getCostEngine(accountSchema.getAD_Client_ID()).clearAccounting(accountSchema, transaction);
// invoices
if (MTransaction.MOVEMENTTYPE_VendorReceipts.equals(transaction.getMovementType())) {
MInOutLine line = (MInOutLine) transaction.getDocumentLine();
if (MCostElement.COSTELEMENTTYPE_Material.equals(costElement.getCostElementType())) {
//get purchase matches
List<MMatchPO> orderMatches = MMatchPO.getInOutLine(line);
orderMatches.stream().forEach(match -> {
if (match.getM_Product_ID() == transaction.getM_Product_ID() && match.getDateAcct().after(getAccountDate()) && match.getDateAcct().before(getAccountDateTo())) {
CostEngineFactory.getCostEngine(accountSchema.getAD_Client_ID()).createCostDetail(accountSchema, costType, costElement, transaction, match, true);
}
});
//get invoice matches
List<MMatchInv> invoiceMatches = MMatchInv.getInOutLine(line);
invoiceMatches.forEach(match -> {
if (match.getM_Product_ID() == transaction.getM_Product_ID() && match.getDateAcct().after(getAccountDate()) && match.getDateAcct().before(getAccountDateTo())) {
CostEngineFactory.getCostEngine(accountSchema.getAD_Client_ID()).createCostDetail(accountSchema, costType, costElement, transaction, match, true);
}
});
}
//get landed allocation cost
MLandedCostAllocation.getOfInOutline(line, costElement.getM_CostElement_ID()).stream().forEach(allocation -> {
if (allocation.getDateAcct().after(getAccountDate()) && allocation.getDateAcct().before(getAccountDateTo()))
CostEngineFactory.getCostEngine(accountSchema.getAD_Client_ID()).createCostDetail(accountSchema, costType, costElement, transaction, allocation, true);
});
}
}
use of org.compiere.model.MMatchPO in project adempiere by adempiere.
the class AveragePOCostingMethod 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()) {
//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 MMatchPO) {
provisionOfPurchaseCost = lastCostDetail.getCostAmt();
provisionOfPurchaseCostLL = lastCostDetail.getCostAmtLL();
MMatchPO iMatch = (MMatchPO) 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 MMatchPO) {
if (!isOpenPeriod) {
int attributeSetInstanceId = 0;
if (model instanceof MLandedCostAllocation) {
MLandedCostAllocation costAllocation = (MLandedCostAllocation) this.model;
attributeSetInstanceId = costAllocation.getM_AttributeSetInstance_ID();
}
if (model instanceof MMatchPO) {
MMatchPO matchPO = (MMatchPO) this.model;
attributeSetInstanceId = matchPO.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.MMatchPO in project adempiere by adempiere.
the class AverageInvoiceCostingMethod method adjustCostDetail.
/**
* Recalculate Cost Detail
* @param cost
*/
public void adjustCostDetail(MCostDetail cost) {
Properties ctx = cost.getCtx();
String trxName = cost.get_TrxName();
int transactionId = cost.getM_Transaction_ID();
int clientId = cost.getAD_Client_ID();
MTransaction transaction = new MTransaction(ctx, transactionId, trxName);
MCostType costType = (MCostType) cost.getM_CostType();
MCostElement costElement = (MCostElement) cost.getM_CostElement();
MAcctSchema accountSchema = (MAcctSchema) cost.getC_AcctSchema();
CostEngineFactory.getCostEngine(accountSchema.getAD_Client_ID()).clearAccounting(accountSchema, transaction);
if (MTransaction.MOVEMENTTYPE_VendorReceipts.equals(transaction.getMovementType())) {
MInOutLine line = (MInOutLine) transaction.getDocumentLine();
if (MCostElement.COSTELEMENTTYPE_Material.equals(costElement.getCostElementType())) {
if (cost.getM_InOutLine_ID() > 0 && cost.getQty().signum() != 0) {
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, line, true);
} else if (cost.getM_InOutLine_ID() > 0 && cost.getQty().signum() != 0 && cost.getC_OrderLine_ID() > 0) {
List<MMatchPO> orderMatches = MMatchPO.getInOutLine(line);
for (MMatchPO match : orderMatches) {
if (match.getM_InOutLine_ID() == line.getM_InOutLine_ID() && match.getM_Product_ID() == transaction.getM_Product_ID()) {
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, match, true);
}
}
} else if (cost.getM_InOutLine_ID() > 0 && cost.getQty().signum() == 0 && cost.getC_InvoiceLine_ID() > 0 && cost.getC_LandedCostAllocation_ID() == 0) {
List<MMatchInv> invoiceMatches = MMatchInv.getInOutLine(line);
for (MMatchInv match : invoiceMatches) {
if (match.getM_Product_ID() == transaction.getM_Product_ID()) {
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, match, true);
}
}
}
}
// only own allocation
if (cost.getC_LandedCostAllocation_ID() != 0) {
MLandedCostAllocation allocation = (MLandedCostAllocation) cost.getC_LandedCostAllocation();
{
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, allocation, true);
}
}
} else
CostEngineFactory.getCostEngine(clientId).createCostDetail(accountSchema, costType, costElement, transaction, transaction.getDocumentLine(), true);
}
Aggregations