use of org.compiere.model.MMatchInv 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.MMatchInv in project adempiere by adempiere.
the class CostEngine method clearAccounting.
/**
* clear Accounting
* @param accountSchema
* @param transaction
*/
public void clearAccounting(MAcctSchema accountSchema, MTransaction transaction) {
if (transaction.getM_InOutLine_ID() > 0) {
MInOutLine line = (MInOutLine) transaction.getM_InOutLine();
if (!clearAccounting(accountSchema, accountSchema.getM_CostType(), line.getParent(), transaction.getM_Product_ID(), line.getDateAcct()))
return;
// get Purchase matches
List<MMatchPO> orderMatches = MMatchPO.getInOutLine(line);
for (MMatchPO match : orderMatches) {
if (!clearAccounting(accountSchema, accountSchema.getM_CostType(), match, transaction.getM_Product_ID(), line.getDateAcct()))
return;
}
// get invoice matches
List<MMatchInv> invoiceMatches = MMatchInv.getInOutLine(line);
for (MMatchInv match : invoiceMatches) {
if (!clearAccounting(accountSchema, accountSchema.getM_CostType(), match, transaction.getM_Product_ID(), line.getDateAcct()))
return;
}
} else if (transaction.getC_ProjectIssue_ID() > 0) {
MProjectIssue line = (MProjectIssue) transaction.getC_ProjectIssue();
if (!clearAccounting(accountSchema, accountSchema.getM_CostType(), line.getParent(), transaction.getM_Product_ID(), line.getMovementDate()))
return;
} else if (transaction.getM_InventoryLine_ID() > 0) {
MInventoryLine line = (MInventoryLine) transaction.getM_InventoryLine();
if (!clearAccounting(accountSchema, accountSchema.getM_CostType(), line.getParent(), transaction.getM_Product_ID(), line.getDateAcct()))
return;
} else if (transaction.getM_MovementLine_ID() > 0) {
MMovementLine line = (MMovementLine) transaction.getM_MovementLine();
if (!clearAccounting(accountSchema, accountSchema.getM_CostType(), line.getParent(), transaction.getM_Product_ID(), line.getDateAcct()))
return;
} else if (transaction.getM_ProductionLine_ID() > 0) {
MProductionLine line = (MProductionLine) transaction.getM_ProductionLine();
MProduction production = (MProduction) line.getM_ProductionPlan().getM_Production();
if (!clearAccounting(accountSchema, accountSchema.getM_CostType(), production, transaction.getM_Product_ID(), production.getMovementDate()))
return;
} else if (transaction.getPP_Cost_Collector_ID() > 0) {
MPPCostCollector costCollector = (MPPCostCollector) transaction.getPP_Cost_Collector();
if (!clearAccounting(accountSchema, accountSchema.getM_CostType(), costCollector, costCollector.getM_Product_ID(), costCollector.getDateAcct()))
;
return;
} else {
log.info("Document does not exist :" + transaction);
}
}
use of org.compiere.model.MMatchInv in project adempiere by adempiere.
the class A_Asset_CreateFromMatchInv method doIt.
// prepare
protected String doIt() throws Exception {
MMatchInv match = new MMatchInv(getCtx(), p_M_MatchInv_ID, get_TrxName());
if (match == null || match.get_ID() <= 0) {
throw new AssetException("@NotFound@ @M_MatchInv_ID@=" + match + "(ID=" + p_M_MatchInv_ID + ")");
}
MAssetAddition assetAdd = MAssetAddition.createAsset(match);
return "@A_Asset_Addition_ID@ - " + assetAdd;
}
use of org.compiere.model.MMatchInv in project adempiere by adempiere.
the class Match method createMatchRecord.
// tableLoad
/**
* Create Matching Record
* @param invoice true if matching invoice false if matching PO
* @param M_InOutLine_ID shipment line
* @param Line_ID C_InvoiceLine_ID or C_OrderLine_ID
* @param qty quantity
* @param trxName
* @return true if created
*/
protected boolean createMatchRecord(boolean invoice, int M_InOutLine_ID, int Line_ID, BigDecimal qty, String trxName) {
if (qty.compareTo(Env.ZERO) == 0)
return true;
log.fine("IsInvoice=" + invoice + ", M_InOutLine_ID=" + M_InOutLine_ID + ", Line_ID=" + Line_ID + ", Qty=" + qty);
//
boolean success = false;
MInOutLine sLine = new MInOutLine(Env.getCtx(), M_InOutLine_ID, trxName);
if (// Shipment - Invoice
invoice) {
// Update Invoice Line
MInvoiceLine iLine = new MInvoiceLine(Env.getCtx(), Line_ID, trxName);
iLine.setM_InOutLine_ID(M_InOutLine_ID);
if (sLine.getC_OrderLine_ID() != 0)
iLine.setC_OrderLine_ID(sLine.getC_OrderLine_ID());
iLine.saveEx();
// Create Shipment - Invoice Link
if (iLine.getM_Product_ID() != 0) {
MMatchInv match = new MMatchInv(iLine, null, qty);
match.setM_InOutLine_ID(M_InOutLine_ID);
if (match.save()) {
success = true;
if (MClient.isClientAccountingImmediate()) {
String ignoreError = DocumentEngine.postImmediate(match.getCtx(), match.getAD_Client_ID(), match.get_Table_ID(), match.get_ID(), true, match.get_TrxName());
}
} else
log.log(Level.SEVERE, "Inv Match not created: " + match);
} else
success = true;
// Create PO - Invoice Link = corrects PO
if (iLine.getC_OrderLine_ID() != 0 && iLine.getM_Product_ID() != 0) {
MMatchPO matchPO = MMatchPO.create(iLine, sLine, null, qty);
matchPO.setC_InvoiceLine_ID(iLine);
matchPO.setM_InOutLine_ID(M_InOutLine_ID);
if (!matchPO.save())
log.log(Level.SEVERE, "PO(Inv) Match not created: " + matchPO);
if (MClient.isClientAccountingImmediate()) {
String ignoreError = DocumentEngine.postImmediate(matchPO.getCtx(), matchPO.getAD_Client_ID(), matchPO.get_Table_ID(), matchPO.get_ID(), true, matchPO.get_TrxName());
}
}
} else // Shipment - Order
{
// Update Shipment Line
sLine.setC_OrderLine_ID(Line_ID);
sLine.saveEx();
// Update Order Line
MOrderLine oLine = new MOrderLine(Env.getCtx(), Line_ID, trxName);
if (// other in MInOut.completeIt
oLine.get_ID() != 0) {
oLine.setQtyReserved(oLine.getQtyReserved().subtract(qty));
if (!oLine.save())
log.severe("QtyReserved not updated - C_OrderLine_ID=" + Line_ID);
}
// Create PO - Shipment Link
if (sLine.getM_Product_ID() != 0) {
MMatchPO match = new MMatchPO(sLine, null, qty);
if (!match.save())
log.log(Level.SEVERE, "PO Match not created: " + match);
else {
success = true;
// Correct Ordered Qty for Stocked Products (see MOrder.reserveStock / MInOut.processIt)
if (sLine.getProduct() != null && sLine.getProduct().isStocked())
success = MStorage.add(Env.getCtx(), sLine.getM_Warehouse_ID(), sLine.getM_Locator_ID(), sLine.getM_Product_ID(), sLine.getM_AttributeSetInstance_ID(), oLine.getM_AttributeSetInstance_ID(), null, null, qty.negate(), trxName);
}
} else
success = true;
}
return success;
}
Aggregations