private void AddLineItem(OrderLineItem oli)
        {
            using (var container = NestedContainer)
            {
                IOtherUtilities _otherUtilities = Using<IOtherUtilities>(container);

                ApproveSalesmanOrderItem li = null;
                int sequenceNo = 1;
                if (LineItems.Count > 0)
                {
                    sequenceNo = LineItems.Max(n => n.SequenceNo) + 1;
                }
                if (LineItems.Any(n => n.ProductId == oli.Product.Id))
                {
                    li = LineItems.First(n => n.ProductId == oli.Product.Id);
                    li.Qty += oli.Qty;
                    li.TotalLineItemVatAmount += oli.LineItemVatTotal;
                    li.LineItemVatValue = oli.LineItemVatValue;
                    li.TotalPrice += oli.LineItemTotal;
                }
                else
                {
                    li = new ApproveSalesmanOrderItem(_otherUtilities)
                             {
                                 SequenceNo = sequenceNo,
                                 ProductId = oli.Product.Id,
                                 Product = oli.Product.Description,
                                 UnitPrice = oli.Value,
                                 LineItemVatValue = oli.LineItemVatValue,
                                 TotalLineItemVatAmount = oli.LineItemVatTotal,
                                 Qty = oli.Qty,
                                 TotalPrice = oli.LineItemTotal,
                                 IsEditable = false,
                                 LineItemId = oli.Id,
                                 CanEdit = false,
                                 CanRemove = false,
                                 ProductType = oli.Product.GetType().ToString().Split('.').Last(),
                                 HlnkDeleteContent =
                                     GetLocalText("sl.approveOrder.lineItemsGrid.deleteLineItem"),
                             };
                    LineItems.Add(li);
                }
                CalcTotals();
            }
        }
        public void LoadBackOrderlineItem(Guid productId, string productDesc, decimal unitPrice, decimal vatValue, decimal vatAmount, decimal vat, decimal qty, decimal totalPrice, bool isEditable, Guid? lineItemID, string liProdType)
        {
            using (var container = NestedContainer)
            {
               
                var _inventoryService = Using<IInventoryRepository>(container);
               
                IOtherUtilities _otherUtilities = Using<IOtherUtilities>(container);
                IConfigService _configService = Using<IConfigService>(container);

                ApproveSalesmanOrderItem li = null;
                //Inventory availableInv = _inventoryService.GetByProductId(productId, OutletId);
                Inventory availableInv = _inventoryService.GetByProductIdAndWarehouseId(productId, _configService.Load().CostCentreId);
                if (liProdType == "ReturnableProduct") //#$@$%#^!!
                    if (availableInv != null)
                        if (availableInv.Balance < 0)
                            availableInv.Balance = 0;

                decimal totalProcessedBackOrderQty = 0;
                try
                {
                    totalProcessedBackOrderQty =
                        _order.LineItems.Where(
                            n => n.Product.Id == productId && n.LineItemType == OrderLineItemType.ProcessedBackOrder)
                            .Sum(s => s.Qty);
                }
                catch
                {
                }

                int sequenceNo = 1;
                if (LineItems.Count > 0)
                {
                    sequenceNo = LineItems.Max(n => n.SequenceNo) + 1;
                }
                li = new ApproveSalesmanOrderItem(_otherUtilities)
                         {
                             SequenceNo = sequenceNo,
                             ProductId = productId,
                             Product = productDesc,
                             UnitPrice = unitPrice,
                             LineItemVatValue = vatValue,
                             TotalLineItemVatAmount = vatAmount,
                             Qty = qty - totalProcessedBackOrderQty,
                             //less the processed qty
                             TotalPrice = totalPrice,
                             IsEditable = isEditable,
                             LineItemId = (Guid) lineItemID,
                             ProcessedQty = 0,
                             //item.LineItemId   = oli.Id;
                             AvailableProductInv = availableInv == null ? 0 : availableInv.Balance,
                             CanEdit = true,
                             CanRemove = true,
                             HlnkDeleteContent = GetLocalText("sl.approveBackOrder.lineItemsGrid.rejectBackOrderItem"),
                             ProductType = liProdType
                         };
                if (liProdType == "ReturnableProduct") li.CanEdit = false;
                if (liProdType == "ReturnableProduct") li.CanRemove = false;

                if (LoadForViewing)
                {
                    li.CanEdit = false;
                    li.CanRemove = false;
                }
                LineItems.Add(li);
                //}
                CalcTotals();
            }
        }
        OrderLineItem CreateNewLineItem(Guid lineItemId, ApproveSalesmanOrderItem item, OrderLineItemType orderLineItemType = OrderLineItemType.PostConfirmation)
        {
            using (var container = NestedContainer)
            {
                IProductRepository _productService = Using<IProductRepository>(container);
               

                lineItemId = lineItemId == Guid.Empty ? Guid.NewGuid() : lineItemId;
                var oli = new OrderLineItem(lineItemId)
                              {
                                  Description = item.Product,
                                  Product = _productService.GetById(item.ProductId),
                                  Qty = item.Qty,
                                  IsNew = true,
                                  LineItemSequenceNo = item.SequenceNo
                              };
                oli.Value = item.UnitPrice;
                oli.LineItemVatValue = item.LineItemVatValue;
                oli.LineItemType = orderLineItemType;
                oli.ProductDiscount = item.ProductDiscount;
                oli.LineItemType = orderLineItemType;
                oli.DiscountType = item.LineItemDiscountType;

                return oli;
            }
        }
        public void UpdateLineItem(int sequenceNo, decimal qty, decimal lineItemVatValue, decimal vatAmount, decimal totalPrice, decimal backOrder, decimal lostSale, bool updatedLI = false)
        {
            using (var container = NestedContainer)
            {
                
                IOtherUtilities _otherUtilities = Using<IOtherUtilities>(container);

                if (childLineItems == null)
                    childLineItems = new List<OrderLineItem>();
                ApproveSalesmanOrderItem lineItem = LineItems.FirstOrDefault(n => n.SequenceNo == sequenceNo);
                OrderLineItem oli = _order.LineItems.FirstOrDefault(n => n.Id == lineItem.LineItemId);
                //BackOrder, LostSales
                lineItem.Qty = qty;
                //item.Approved = approve;
                lineItem.BackOrder = backOrder;
                lineItem.LostSale = lostSale;
                lineItem.LineItemVatValue = lineItemVatValue;
                lineItem.TotalLineItemVatAmount = vatAmount;
                lineItem.LineItemVatValue = vatAmount;
                lineItem.TotalPrice = totalPrice;
                lineItem.ProcessedQty = lineItem.Qty - lineItem.BackOrder;
                lineItem.ProcessedQty = lineItem.ProcessedQty < 0 ? 0 : lineItem.ProcessedQty;

                if (oli != null)
                {
                    OrderLineItem originalOLi =
                        _order._allLineItems().FirstOrDefault(n => n.Id.ToString() == oli.Description);
                    if (originalOLi == null)
                    {
                        if (oli.LineItemType != OrderLineItemType.PostConfirmation)
                            originalOLi = oli;
                    }

                    if (childLineItems.Any(n => n.Description == oli.Id.ToString())) //same as updating existing
                    {
                        var toRemove = childLineItems.Where(n => n.Description == oli.Id.ToString());
                        toRemove.ToList().ForEach(n => childLineItems.Remove(n));
                    }

                    if (backOrder > 0) //Create or update Back Orders
                    {
                        childLineItems.Add(new OrderLineItem(Guid.NewGuid())
                                               {
                                                   Description = originalOLi.Id.ToString(),
                                                   LineItemSequenceNo = _order.LineItems.Count() + 1,
                                                   LineItemVatValue = oli.LineItemVatValue,
                                                   Qty = lineItem.BackOrder,
                                                   Product = oli.Product,
                                                   IsNew = true,
                                                   LineItemType = OrderLineItemType.BackOrder,
                                                   Value = oli.Value
                                               });
                    }
                    if (lostSale > 0) //Lost Sale : create or update
                    {
                        childLineItems.Add(new OrderLineItem(Guid.NewGuid())
                                               {
                                                   Description = originalOLi.Id.ToString(),
                                                   LineItemSequenceNo = _order.LineItems.Count() + 1,
                                                   LineItemVatValue = oli.LineItemVatValue,
                                                   Qty = lineItem.LostSale,
                                                   Product = oli.Product,
                                                   IsNew = true,
                                                   LineItemType = OrderLineItemType.LostSale,
                                                   Value = oli.Value
                                               });
                    }
                }
                else //line item was added during approval
                {
                    var updatingLi = LineItems.First(n => n.SequenceNo == sequenceNo);
                    if (updatingLi.LineItemId == Guid.Empty)
                        updatingLi.LineItemId = Guid.NewGuid();

                    if (childLineItems.Any(n => n.Description == updatingLi.LineItemId.ToString())) //add/update
                    {
                        var toRemove = childLineItems.Where(n => n.Description == oli.Id.ToString());
                        toRemove.ToList().ForEach(n => childLineItems.Remove(n));
                    }
                    if (backOrder > 0) //Create or update Back Orders
                    {
                        var newLineItem = new ApproveSalesmanOrderItem(_otherUtilities)
                                              {
                                                  AvailableProductInv = updatingLi.AvailableProductInv,
                                                  BackOrder = updatingLi.BackOrder,
                                                  LineItemVatValue = updatingLi.LineItemVatValue,
                                                  LostSale = updatingLi.LostSale,
                                                  Product = updatingLi.Product,
                                                  ProcessedQty = updatingLi.ProcessedQty,
                                                  ProductId = updatingLi.ProductId,
                                                  Qty = updatingLi.BackOrder,
                                                  SequenceNo = LineItems.Count + 1,
                                                  TotalPrice = updatingLi.TotalPrice,
                                                  UnitPrice = updatingLi.UnitPrice,
                                                  TotalLineItemVatAmount = updatingLi.TotalLineItemVatAmount,
                                                  HlnkDeleteContent =
                                                      GetLocalText("sl.approveOrder.lineItemsGrid.deleteLineItem"),
                                              };
                        newLineItem.LineItemId = Guid.NewGuid();
                        var newOrderLineItem = CreateNewLineItem(newLineItem.LineItemId, newLineItem,
                                                                 OrderLineItemType.BackOrder);
                        newOrderLineItem.Description = updatingLi.LineItemId.ToString();

                        childLineItems.Add(newOrderLineItem);
                    }
                    if (lostSale > 0) //Lost Sale : create or update
                    {
                        var newLineItem = new ApproveSalesmanOrderItem(_otherUtilities)
                                              {
                                                  AvailableProductInv = updatingLi.AvailableProductInv,
                                                  BackOrder = updatingLi.BackOrder,
                                                  LineItemVatValue = updatingLi.LineItemVatValue,
                                                  LostSale = updatingLi.LostSale,
                                                  Product = updatingLi.Product,
                                                  ProcessedQty = updatingLi.ProcessedQty,
                                                  ProductId = updatingLi.ProductId,
                                                  Qty = updatingLi.LostSale,
                                                  SequenceNo = LineItems.Count + 1,
                                                  TotalPrice = updatingLi.TotalPrice,
                                                  UnitPrice = updatingLi.UnitPrice,
                                                  TotalLineItemVatAmount = updatingLi.TotalLineItemVatAmount,
                                                  HlnkDeleteContent =
                                                      GetLocalText("sl.approveOrder.lineItemsGrid.deleteLineItem"),
                                              };
                        newLineItem.LineItemId = Guid.NewGuid();
                        var newOrderLineItem = CreateNewLineItem(newLineItem.LineItemId, newLineItem,
                                                                 OrderLineItemType.LostSale);
                        newOrderLineItem.Description = updatingLi.LineItemId.ToString();
                        childLineItems.Add(newOrderLineItem);
                    }
                }
                CalcTotals();
            }
        }
        private void AddOrUpdateLineItemFromDiscount(ProductAsDiscount productAsDiscount, Product product)
        {
            List<Product> discountProducts = new List<Product>();
            discountProducts.Add(product);
            discProdReturnables = new List<ReturnableProduct>();
            discProdReturnables = _productPackagingSummaryService.GetProductReturnables(product,
                                                                                        productAsDiscount.Quantity);
            if (discProdReturnables != null && discProdReturnables.Count > 0)
            {
                discProdReturnables.ForEach(discountProducts.Add);
            }
            _productPackagingSummaryService.ClearProductReturnables();

            foreach (Product prod in discountProducts)
            {
                decimal unitPrice = 0m;
                decimal vatValue = 0m;
                decimal totalVatAmount = 0m;
                decimal totalPrice = 0m;
                decimal productDiscount = 0m;
                decimal totalProductDiscount = 0m;
                decimal qty = productAsDiscount.Quantity;

                if (prod.Id != product.Id)
                {
                    if ((prod as ReturnableProduct).Capacity > 1) //returnable bulk container
                        qty = (int) (productAsDiscount.Quantity/(prod as ReturnableProduct).Capacity);
                }
                if (prod.Id != product.Id)
                {
                    LineItemPricingInfo pi = GetLineItemPricing(new PackagingSummary
                                                                    {
                                                                        Product = prod,
                                                                        Quantity = qty
                                                                    },
                                                                OutletId);
                    unitPrice = pi.UnitPrice;
                    vatValue = pi.VatValue;
                    totalVatAmount = pi.TotalVatAmount;
                    totalPrice = pi.TotalPrice;
                    productDiscount = pi.ProductDiscount;
                    totalProductDiscount = pi.TotalProductDiscount;
                }

                ApproveSalesmanOrderItem existingItem = null;
                if (prod.Id == product.Id) //is the discount product
                {
                    existingItem = discountLineItems.FirstOrDefault(n =>
                                                                    n.OrderLineItemType ==
                                                                    OrderLineItemType.Discount &&
                                                                    n.ProductId == prod.Id &&
                                                                    n.LineItemDiscountType ==
                                                                    productAsDiscount.DiscountType);
                }
                else
                {
                    existingItem =
                        LineItems.FirstOrDefault(
                            n => n.ProductId == prod.Id && n.OrderLineItemType != OrderLineItemType.Discount);
                }
                if (existingItem != null)
                {
                    if (prod.Id != product.Id)
                    {
                        if ((prod as ReturnableProduct).Capacity > 1) //returnable bulk container
                            existingItem.Qty += qty;
                        else //sale product returnable
                            existingItem.Qty += qty;
                    }
                    else //sale product
                        existingItem.Qty += qty;
                    existingItem.TotalLineItemVatAmount += totalVatAmount;
                    existingItem.TotalPrice += totalPrice;
                    existingItem.LineItemTotalProductDiscount += totalProductDiscount;
                }
                else
                {
                    using (var container = NestedContainer)
                    {
                        IOtherUtilities _otherUtilities = Using<IOtherUtilities>(container);
                        existingItem = new ApproveSalesmanOrderItem(_otherUtilities)
                                           {
                                               SequenceNo = LineItems.Count() + 1,
                                               ProductDiscount = productDiscount,
                                               LineItemTotalProductDiscount = totalProductDiscount,
                                               IsEditable = false,
                                               LineItemId = Guid.Empty,
                                               ProductId = prod.Id,
                                               Product = prod.Description,
                                               //ParentProductId            = product.Id,
                                               Qty = qty,
                                               UnitPrice = unitPrice,
                                               TotalLineItemVatAmount = totalVatAmount,
                                               LineItemVatValue = vatValue,
                                               TotalPrice = totalPrice,
                                               ProductType = prod.GetType().ToString().Split('.').Last(),
                                               CanEdit = false,
                                               CanRemove = false,
                                               HlnkDeleteContent =
                                                   GetLocalText("sl.approveOrder.lineItemsGrid.deleteLineItem"),
                                           };
                        if (prod.Id == product.Id) //is the discount product
                        {
                            existingItem.LineItemDiscountType = productAsDiscount.DiscountType;
                            existingItem.OrderLineItemType = OrderLineItemType.Discount;
                        }
                        if (existingItem.OrderLineItemType == OrderLineItemType.Discount)
                        {
                            discountLineItems.Add(existingItem);
                        }
                        else
                        {
                            LineItems.Add(existingItem);
                        }
                    }
                }
            }
        }
        private void AddCertainProductQuantityCertainProductDiscount(ApproveSalesmanOrderItem lineItem)
        {
            using (var container = NestedContainer)
            {
                IDiscountProWorkflow _discountProService = Using<IDiscountProWorkflow>(container);


                List<ProductAsDiscount> productAsDiscounts = _discountProService.GetFOCCertainProduct(
                    lineItem.ProductId, lineItem.Qty);

                foreach (ProductAsDiscount productAsDiscount in productAsDiscounts)
                {
                    if (productAsDiscount != null)
                        DisplayProductAsDiscountAndAddToDiscountLineItems(productAsDiscount);
                }
            }
        }
        public void AddReceivedReturnables(Guid productId, string productDesc, decimal unitPrice, decimal vatValue,
                                           decimal vatAmount, decimal qty, decimal totalPrice, bool isEditable,
                                           string liProdType, Guid lineItemID)
        {
            using (var container = NestedContainer)
            {
                IOtherUtilities _otherUtilities = Using<IOtherUtilities>(container);
                var _inventoryService = Using<IInventoryRepository>(container);
                IConfigService _configService = Using<IConfigService>(container);
                ApproveSalesmanOrderItem li = null;
                int sequenceNo = 0;
                Inventory availableInv = _inventoryService.GetByProductIdAndWarehouseId(productId, _configService.Load().CostCentreId);

                if (liProdType == "ReturnableProduct") //#$@$%#^!!
                    if (availableInv != null)
                        if (availableInv.Balance < 0)
                            availableInv.Balance = 0;

                if (_order.Status == DocumentStatus.Confirmed || _order.Status == DocumentStatus.OrderPendingDispatch)
                    // editing at confirm order and at process back order
                {
                    li.Qty += qty;
                    li.TotalLineItemVatAmount += vatAmount;
                    li.LineItemVatValue = vatValue;
                    li.TotalPrice += totalPrice;
                    li.ProcessedQty = (li.Qty - li.BackOrder);
                    li.ProcessedQty = li.ProcessedQty < 0 ? 0 : li.ProcessedQty;
                }
                else
                {
                    li = new ApproveSalesmanOrderItem(_otherUtilities)
                             {
                                 SequenceNo =
                                     LineItems.Count > 0 ? (LineItems.Max(n => n.SequenceNo) + 1) : (sequenceNo + 1),
                                 ProductId = productId,
                                 Product = productDesc,
                                 UnitPrice = unitPrice,
                                 LineItemVatValue = vatValue,
                                 TotalLineItemVatAmount = vatAmount,
                                 Qty = qty,
                                 TotalPrice = totalPrice,
                                 IsEditable = isEditable,
                                 LineItemId = (Guid) lineItemID,
                                 AvailableProductInv = availableInv == null ? 0 : availableInv.Balance,
                                 LiProductType = liProdType,
                                 CanEdit = isEditable,
                                 CanRemove = isEditable,
                                 ProductType = liProdType,
                                 HlnkDeleteContent =
                                     GetLocalText("sl.approveOrder.lineItemsGrid.deleteLineItem"),
                             };
                }
                LineItems.Add(li);
                CalcTotals();
            }
        }
        public void AddLineItem(Guid productId, string productDesc, decimal unitPrice, decimal vatValue,
                                decimal vatAmount, decimal qty, decimal totalPrice, bool isEditable, string liProdType,
                                Guid lineItemID, decimal productDiscount, OrderLineItemType orderLineItemType,
                                DiscountType discountType)
        {
            using (var container = NestedContainer)
            {
                IConfigService _configService = Using<IConfigService>(container);
                var _inventoryService = Using<IInventoryRepository>(container);
                IProductRepository _productService = Using<IProductRepository>(container);
                IOtherUtilities _otherUtilities = Using<IOtherUtilities>(container);

                ApproveSalesmanOrderItem li = null;
                Inventory availableInv = _inventoryService.GetByProductIdAndWarehouseId(productId, _configService.Load().CostCentreId);
                Product product = null;

                if (liProdType == "ReturnableProduct") //#$@$%#^!!
                {
                    if (availableInv != null)
                        if (availableInv.Balance < 0)
                            availableInv.Balance = 0;
                    product = _productService.GetById(productId);
                }


                int sequenceNo = 1;
                if (LineItems.Count > 0)
                {
                    sequenceNo = LineItems.Max(n => n.SequenceNo) + 1;
                }
                if (!LoadForProcessing)
                    isEditable = false;
                //Check the line item exists by productId and update it ..
                if (LineItems.Any(n => n.ProductId == productId && n.OrderLineItemType == orderLineItemType)) //
                {
                    li = LineItems.FirstOrDefault(n => n.ProductId == productId); //lineItem to update ..
                    if (_order.Status == DocumentStatus.Confirmed ||
                        (_order.Status == DocumentStatus.OrderPendingDispatch && ProcessingBackOrder))
                        // editing at confirm order and at process back order
                    {
                        if (!LoadForViewing)
                        {
                            li.Qty += qty;
                            li.TotalLineItemVatAmount += vatAmount;
                            li.LineItemVatValue = vatValue;
                            li.TotalPrice += totalPrice;
                            li.LineItemTotalProductDiscount += (productDiscount*qty);
                            li.ProcessedQty = (li.Qty - li.BackOrder);
                            li.ProcessedQty = li.ProcessedQty < 0 ? 0 : li.ProcessedQty;
                        }
                    }
                    else if (_order.Status == DocumentStatus.OrderPendingDispatch ||
                             _order.Status == DocumentStatus.OrderDispatchedToPhone ||
                             _order.Status == DocumentStatus.Closed ||
                             _order.Status == DocumentStatus.Cancelled ||
                             _order.Status == DocumentStatus.Rejected)
                        //load awaiting stock etc ...
                    {
                        if (!ProcessingBackOrder)
                        {
                            var item = _order.LineItems.FirstOrDefault(n => n.Id == lineItemID);
                            try
                            {
                                switch (item.LineItemType)
                                {
                                    case OrderLineItemType.BackOrder:
                                        li.BackOrder += qty;
                                        li.ProcessedQty = li.Qty - li.BackOrder;
                                        break;
                                    case OrderLineItemType.LostSale:
                                        li.LostSale = qty;
                                        break;
                                    case OrderLineItemType.ProcessedBackOrder:
                                        li.BackOrder -= qty;
                                        li.ProcessedQty = li.Qty - li.BackOrder;
                                        break;
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                }
                else
                {
                    #region New LineItem

                    li = new ApproveSalesmanOrderItem(_otherUtilities)
                             {
                                 SequenceNo = sequenceNo,
                                 ProductId = productId,
                                 Product = productDesc,
                                 UnitPrice = unitPrice,
                                 LineItemVatValue = vatValue,
                                 TotalLineItemVatAmount = vatAmount,
                                 Qty = qty,
                                 TotalPrice = totalPrice,
                                 IsEditable = isEditable,
                                 LineItemId = (Guid) lineItemID,
                                 AvailableProductInv = availableInv == null ? 0 : availableInv.Balance,
                                 LiProductType = liProdType,
                                 CanEdit = isEditable,
                                 CanRemove = isEditable,
                                 ProductType = liProdType,
                                 OrderLineItemType = orderLineItemType,
                                 ProductDiscount = productDiscount,
                                 LineItemTotalProductDiscount = productDiscount*qty,
                                 LineItemDiscountType = discountType,
                                 HlnkDeleteContent = GetLocalText("sl.approveOrder.lineItemsGrid.deleteLineItem"),
                             };

                    if (liProdType == "ReturnableProduct") li.CanEdit = false;
                    if (liProdType == "ReturnableProduct") li.CanRemove = false;

                    if (liProdType == "ReturnableProduct" && ((ReturnableProduct) product).Capacity > 1)
                        //cn: containers to be edited independently
                    {
                        li.CanEdit = true;
                        li.CanRemove = true;
                    }

                    //overriding editing determiners!!
                    if (li.OrderLineItemType == OrderLineItemType.Discount)
                    {
                        li.CanEdit = false;
                        li.CanRemove = false;
                    }

                    if (Status != "New" && Status != "Confirmed")
                    {
                        li.CanEdit = false;
                        li.CanRemove = false;
                    }

                    if (LoadForViewing)
                    {
                        li.CanEdit = false;
                        li.CanRemove = false;
                    }
                    LineItems.Add(li);

                    #endregion
                }
                CanProcessBackOrder = li.BackOrder > 0;
                CalcTotals();
            }
        }