Esempio n. 1
0
        /// <summary>
        /// Calculate Cost based on Qty based on in Lifo/Fifo order
        /// </summary>
        /// <param name="product">product</param>
        /// <param name="M_ASI_ID">costing level ASI</param>
        /// <param name="mas">accounting schema</param>
        /// <param name="Org_ID">costing level org</param>
        /// <param name="ce">Cost Element</param>
        /// <param name="Qty">quantity to be reduced</param>
        /// <param name="trxName">transaction</param>
        /// <returns>cost for qty or null of error</returns>
        public static Decimal?GetCosts(MProduct product, int M_ASI_ID, MAcctSchema mas,
                                       int Org_ID, MCostElement ce, Decimal Qty, Trx trxName)
        {
            if (Env.Signum(Qty) == 0)
            {
                return(Env.ZERO);
            }
            MCostQueue[] costQ = GetQueue(product, M_ASI_ID,
                                          mas, Org_ID, ce, trxName);
            //
            Decimal cost         = Env.ZERO;
            Decimal remainingQty = Qty;
            Decimal?firstPrice   = null;
            Decimal?lastPrice    = null;

            //
            for (int i = 0; i < costQ.Length; i++)
            {
                MCostQueue queue = costQ[i];
                //	Negative Qty i.e. add
                if (Env.Signum(remainingQty) <= 0)
                {
                    Decimal oldQty = queue.GetCurrentQty();
                    lastPrice = queue.GetCurrentCostPrice();
                    Decimal costBatch = Decimal.Multiply((Decimal)lastPrice, remainingQty);
                    cost = Decimal.Add(cost, costBatch);
                    _log.Config("ASI=" + queue.GetM_AttributeSetInstance_ID()
                                + " - Cost=" + lastPrice + " * Qty=" + remainingQty + "(!) = " + costBatch);
                    return(cost);
                }

                //	Positive queue
                if (Env.Signum(queue.GetCurrentQty()) > 0)
                {
                    Decimal reduction = remainingQty;
                    if (reduction.CompareTo(queue.GetCurrentQty()) > 0)
                    {
                        reduction = queue.GetCurrentQty();
                    }
                    Decimal oldQty = queue.GetCurrentQty();
                    lastPrice = queue.GetCurrentCostPrice();
                    Decimal costBatch = Decimal.Multiply((Decimal)lastPrice, reduction);
                    cost = Decimal.Add(cost, costBatch);
                    _log.Fine("ASI=" + queue.GetM_AttributeSetInstance_ID()
                              + " - Cost=" + lastPrice + " * Qty=" + reduction + " = " + costBatch);
                    remainingQty = Decimal.Subtract(remainingQty, reduction);
                    //	Done
                    if (Env.Signum(remainingQty) == 0)
                    {
                        _log.Config("Cost=" + cost);
                        return(cost);
                    }
                    if (firstPrice == null)
                    {
                        firstPrice = lastPrice;
                    }
                }
            }           //	for queue

            if (lastPrice == null)
            {
                lastPrice = MCost.GetSeedCosts(product, M_ASI_ID, mas, Org_ID,
                                               ce.GetCostingMethod(), 0);
                if (lastPrice == null)
                {
                    _log.Info("No Price found");
                    return(null);
                }
                _log.Info("No Cost Queue");
            }
            Decimal costBatch1 = Decimal.Multiply((Decimal)lastPrice, remainingQty);

            _log.Fine("RemainingQty=" + remainingQty + " * LastPrice=" + lastPrice + " = " + costBatch1);
            cost = Decimal.Add(cost, costBatch1);
            _log.Config("Cost=" + cost);
            return(cost);
        }