/// <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); }
private void btnCalculate_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(errorProvider1.GetError(txtSharedSold)) && string.IsNullOrEmpty(errorProvider1.GetError(txtSalePrice)) // text fields validations ) { #region Read Input and Create Order Order order = new Order(); order.NumberOfShares = Convert.ToInt32(txtSharedSold.Text); order.Price = Convert.ToDecimal(txtSalePrice.Text); order.SellDate = dtDateOfSale.Value; CostingMethod costingMethod; Enum.TryParse <CostingMethod>(cmbCostingMethod.SelectedValue.ToString(), out costingMethod); #endregion try { // Proess input OrderInvoice orderInvoice = _inventoryService.FulfillOrder(order, costingMethod); #region Show Order Invoice on Form txtCostPriceOfRemainingShares.Text = orderInvoice.CostPriceOfRemainingShares.ToString(); txtCostPriceOfSharesSold.Text = orderInvoice.CostPriceOfSoldShares.ToString(); txtSharesRemaining.Text = orderInvoice.RemainingShares.ToString(); txtProfitLoss.Text = orderInvoice.ProfitLoss.ToString(); #endregion } catch (InventoryException ex) { MessageBox.Show(ex.Message, "Inventory Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception ex) { MessageBox.Show(ex.Message, "Unhandled Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); throw; } } }