/// <summary> /// Processes the order and updates the inventory. /// </summary> /// <param name="order">order object to be fulfilled.</param> /// <param name="costingMethod">Costing Method</param> /// <returns>OrderInvoice object containing details of invoice of order</returns> public OrderInvoice FulfillOrder(Order order, CostingMethod costingMethod) { int sharesToBeSold = order.NumberOfShares; decimal totalCostPrice = 0m; decimal inventoryCostPrice; OrderInvoice orderInvoice = new OrderInvoice(); // throw error if there is not enough inventory to fulfill order if (GetSharesCount() < order.NumberOfShares) { throw new InventoryException(String.Format("Cannot process order for {0} shares, only {1} shares left in Inventory!", order.NumberOfShares, GetSharesCount())); } // Get costing class object based on the costing method selected, default is FIFO costingService = CostingFactory.GetCostingService(costingMethod); #region ProcessOrder var inventoryItem = costingService.GetInventory(inventory, out inventoryCostPrice); while (costingService.GetInventory(inventory, out inventoryCostPrice).SharesCount < sharesToBeSold) { totalCostPrice += inventoryItem.SharesCount * inventoryCostPrice; sharesToBeSold -= inventoryItem.SharesCount; inventory.RemoveAt(0); } inventoryItem = costingService.GetInventory(inventory, out inventoryCostPrice); inventoryItem.SharesCount -= sharesToBeSold; totalCostPrice += sharesToBeSold * inventoryCostPrice; if (inventoryItem.SharesCount == 0) { inventory.RemoveAt(0); } #endregion #region Create OrderInvoice orderInvoice.CostPriceOfSoldShares = totalCostPrice / order.NumberOfShares; orderInvoice.ProfitLoss = (order.Price * order.NumberOfShares) - totalCostPrice; orderInvoice.RemainingShares = GetSharesCount(); orderInvoice.CostPriceOfRemainingShares = GetCostPrice(); #endregion return(orderInvoice); }
public static ICosting GetCostingService(CostingMethod costingMethod) { switch (costingMethod) { case CostingMethod.FIFO: return(new FIFOCosting()); case CostingMethod.LIFO: return(new LIFOCosting()); case CostingMethod.HighestCost: return(new HighestCostCosting()); case CostingMethod.LowestCost: return(new LowestCostCosting()); case CostingMethod.WeightedAverage: return(new WeightedAverageCosting()); default: return(new LIFOCosting()); } }