Search in sources :

Example 6 with MMatchPO

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;
    }
}
Also used : MLandedCostAllocation(org.compiere.model.MLandedCostAllocation) MMatchPO(org.compiere.model.MMatchPO) MCostDetail(org.compiere.model.MCostDetail)

Example 7 with MMatchPO

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);
}
Also used : MCostElement(org.compiere.model.MCostElement) MAcctSchema(org.compiere.model.MAcctSchema) MLandedCostAllocation(org.compiere.model.MLandedCostAllocation) MInOutLine(org.compiere.model.MInOutLine) MMatchPO(org.compiere.model.MMatchPO) MTransaction(org.compiere.model.MTransaction) List(java.util.List) MCostType(org.compiere.model.MCostType) Properties(java.util.Properties)

Example 8 with MMatchPO

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);
        });
    }
}
Also used : MInOutLine(org.compiere.model.MInOutLine) MMatchPO(org.compiere.model.MMatchPO) MMatchInv(org.compiere.model.MMatchInv)

Example 9 with MMatchPO

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();
}
Also used : MLandedCostAllocation(org.compiere.model.MLandedCostAllocation) MMatchPO(org.compiere.model.MMatchPO) MCostDetail(org.compiere.model.MCostDetail) BigDecimal(java.math.BigDecimal)

Example 10 with MMatchPO

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);
}
Also used : MCostElement(org.compiere.model.MCostElement) MLandedCostAllocation(org.compiere.model.MLandedCostAllocation) MInOutLine(org.compiere.model.MInOutLine) MMatchPO(org.compiere.model.MMatchPO) MTransaction(org.compiere.model.MTransaction) MCostType(org.compiere.model.MCostType) Properties(java.util.Properties) MAcctSchema(org.compiere.model.MAcctSchema) MMatchInv(org.compiere.model.MMatchInv) List(java.util.List)

Aggregations

MMatchPO (org.compiere.model.MMatchPO)14 MInOutLine (org.compiere.model.MInOutLine)9 MMatchInv (org.compiere.model.MMatchInv)8 MLandedCostAllocation (org.compiere.model.MLandedCostAllocation)7 MCostDetail (org.compiere.model.MCostDetail)3 MInventoryLine (org.compiere.model.MInventoryLine)3 MMovementLine (org.compiere.model.MMovementLine)3 MOrderLine (org.compiere.model.MOrderLine)3 MTransaction (org.compiere.model.MTransaction)3 BigDecimal (java.math.BigDecimal)2 List (java.util.List)2 Properties (java.util.Properties)2 MAcctSchema (org.compiere.model.MAcctSchema)2 MCostElement (org.compiere.model.MCostElement)2 MCostType (org.compiere.model.MCostType)2 MProduction (org.compiere.model.MProduction)2 MProductionLine (org.compiere.model.MProductionLine)2 MPPCostCollector (org.eevolution.model.MPPCostCollector)2 ArrayList (java.util.ArrayList)1 AdempiereException (org.adempiere.exceptions.AdempiereException)1