Example #1
0
        //public OrderItemBalance(OrderItem orderItem, long invoiceItemId, long fuelReportDetailId, decimal amount, string unitCode)
        //{
        //    OrderItemId = orderItem.Id;
        //    OrderId = orderItem.OrderId;
        //    InvoiceItemId = invoiceItemId;
        //    FuelReportDetailId = fuelReportDetailId;
        //    this.setQuantity(amount, unitCode);
        //}
        public OrderItemBalance(OrderItem orderItem, InvoiceItem invoiceItem, FuelReportDetail fuelReportDetail, decimal amount, string unitCode)
        {
            OrderItem = orderItem;
            OrderId = orderItem.OrderId;
            InvoiceItem = invoiceItem;
            FuelReportDetail = fuelReportDetail;
            InvoiceItemId = invoiceItem.Id;
            FuelReportDetailId = fuelReportDetail.Id;

            this.setQuantity(amount, unitCode);
        }
        //<A.H> This method is required for unifying the InvoiceItem with relevant OrderItem Unit of Measurement.
        private decimal updateInvoiceItemWithHeterogeneousOderItem(InvoiceItem invoiceItem, OrderItem orderItem, decimal availableForInvoice)
        {
            var currentValueInMainUnit = goodUnitConvertorDomainService.GetUnitValueInMainUnit
                (invoiceItem.GoodId, invoiceItem.MeasuringUnitId, invoiceItem.Quantity);
            invoiceItem.UpdateUnitAndQuantity(currentValueInMainUnit.Id, currentValueInMainUnit.Value);
            var newValueInMainUnit = goodUnitConvertorDomainService.GetUnitValueInMainUnit
                (invoiceItem.GoodId, orderItem.MeasuringUnitId, availableForInvoice);

            return newValueInMainUnit.Value;
        }
        private List<OrderItemBalance> balanceInvoiceItemInMainUnit(InvoiceItem invoiceItem, IEnumerable<OrderItem> orderItems)
        {
            List<OrderItemBalance> generatedOrderItemBalances = new List<OrderItemBalance>();

            var fuelReportDetialListFetchStrategy = new ListFetchStrategy<FuelReportDetail>()
                            .OrderBy(frd => frd.FuelReport.EventDate);

            var orderIds = orderItems.Select(oi => oi.OrderId).ToList();

            var fuelReportDetailsOfOrderItems = fuelReportDetailRepository.Find(
                                            frd =>
                                                frd.GoodId == invoiceItem.GoodId &&
                                                frd.ReceiveReference.ReferenceType == ReferenceType.Order &&
                                                orderIds.Contains(frd.ReceiveReference.ReferenceId.Value),
                                            fuelReportDetialListFetchStrategy);

            var unassignedInvoiceItemQuantity = goodUnitConvertorDomainService.ConvertUnitValueToMainUnitValue(invoiceItem.MeasuringUnit, invoiceItem.Quantity);

            for (int index = 0; index < fuelReportDetailsOfOrderItems.Count; index++)
            {
                var checkingFuelReportDetail = fuelReportDetailsOfOrderItems[index];

                var fuelReportDetailInvoicedQuantityInMainUnit = balanceRepository.Find(b => b.FuelReportDetailId == checkingFuelReportDetail.Id).Sum(found => found.QuantityAmountInMainUnit);

                var fuelReportDetailReceivedInMainUnit = goodUnitConvertorDomainService.ConvertUnitValueToMainUnitValue(checkingFuelReportDetail.MeasuringUnit, (decimal)checkingFuelReportDetail.Receive.Value);

                var fuelReportDetailNotInvoicedQuantity = fuelReportDetailReceivedInMainUnit - fuelReportDetailInvoicedQuantityInMainUnit;

                if (fuelReportDetailNotInvoicedQuantity <= 0)
                    continue;

                var availableQuantityForBalancing = Math.Min(fuelReportDetailNotInvoicedQuantity, unassignedInvoiceItemQuantity);

                var relevantOrderItem = orderItems.Single(
                        oi =>
                            oi.OrderId == checkingFuelReportDetail.ReceiveReference.ReferenceId.Value &&
                            oi.GoodId == checkingFuelReportDetail.GoodId);

                var orderItemBalanceToAdd = new OrderItemBalance(
                    relevantOrderItem, invoiceItem, checkingFuelReportDetail,
                    availableQuantityForBalancing, checkingFuelReportDetail.Good.SharedGood.MainUnit.Abbreviation);

                balanceRepository.Add(orderItemBalanceToAdd);

                generatedOrderItemBalances.Add(orderItemBalanceToAdd);

                relevantOrderItem.UpdateInvoiced(availableQuantityForBalancing);

                unassignedInvoiceItemQuantity -= availableQuantityForBalancing;

                if (unassignedInvoiceItemQuantity <= 0)
                    break;
            }

            if (unassignedInvoiceItemQuantity != 0)
            {
                throw new BusinessRuleException("", string.Format("Invoiced Quantity for Good '{0}' has deficiencies with selected Orders.", invoiceItem.Good.Name));
            }

            return generatedOrderItemBalances;
        }
        public IEnumerable<InvoiceItem> GenerateInvoiceItemFromOrders(List<long> orderList)
        {
            var orderRefrences = orderRepository.Find(c => orderList.Contains(c.Id) && c.State == States.Submitted);
            var invoiceItems = new List<InvoiceItem>();
            var orderItemsForInvoicing = orderRefrences.SelectMany(c => c.OrderItems.Where(d => d.GetAvailableForInvoiceInMainUnit() > 0)).ToList();

            foreach (var orderItem in orderItemsForInvoicing)
            {
                var invoiceItem = invoiceItems.SingleOrDefault(c => c.GoodId == orderItem.GoodId);
                var availableForInvoiceInMainUnit = orderItem.GetAvailableForInvoiceInMainUnit();
                if (invoiceItem == null)
                {
                    invoiceItem = new InvoiceItem(availableForInvoiceInMainUnit, 0, orderItem.Good, orderItem.MeasuringUnit.MainGoodUnit, 0, "");
                    invoiceItems.Add(invoiceItem);
                }
                else
                {
                    //<A.H> Commented to be refactored to reflect the unit conversions and support for different unit of measure by Invoice items.
                    //if (orderItem.MeasuringUnitId != invoiceItem.MeasuringUnitId)
                    //    availableForInvoiceInMainUnit = updateInvoiceItemWithHeterogeneousOderItem(invoiceItem, orderItem, availableForInvoiceInMainUnit);

                    invoiceItem.UpdateQuantity(availableForInvoiceInMainUnit);
                }
            }
            return invoiceItems;
        }
        /*
        public void CreateBalanceRecordForInvoiceItem(InvoiceItem invoiceItem, List<Order> orderRefrences)
        {
            var orderItemsForGood =
                orderRefrences.SelectMany(c => c.OrderItems.Where(d => d.GoodId == invoiceItem.GoodId && d.GetAvailableForInvoice() > 0)).ToList();

            if (orderItemsForGood.GroupBy(c => c.MeasuringUnitId == invoiceItem.MeasuringUnitId).Count() > 1)
                balanceInvoiceItemInMainUnit(invoiceItem, orderItemsForGood);
            else
                balanceInvoiceItem(invoiceItem, orderItemsForGood);
        }

        private void balanceInvoiceItemInMainUnit(InvoiceItem invoiceItem, IEnumerable<OrderItem> orderItems)
        {
            var requestQuantity = goodUnitConvertorDomainService.ConvertUnitValueToMainUnitValue(invoiceItem.MeasuringUnit, invoiceItem.Quantity);
            foreach (OrderItem orderItem in orderItems)
            {
                var availbleQuantity = goodUnitConvertorDomainService.ConvertUnitValueToMainUnitValue
                    (orderItem.MeasuringUnit, orderItem.GetAvailableForInvoice());

                decimal quantity = requestQuantity >= availbleQuantity ? availbleQuantity : requestQuantity;
                orderItem.UpdateInvoiced(quantity);
                balanceRepository.Add(new OrderItemBalance(orderItem, invoiceItem.Id,  quantity, orderItem.MeasuringUnit.Abbreviation));
                requestQuantity -= quantity;
                if (requestQuantity == 0)
                    break;
            }

            if (requestQuantity > 0)
                throw new BusinessRuleException("", "Not enough Quantity In Refrenced Orders");
        }

        private void balanceInvoiceItem(InvoiceItem invoiceItem, IEnumerable<OrderItem> orderItems)
        {
            var requestQuantity = invoiceItem.Quantity;

            foreach (OrderItem orderItem in orderItems)
            {
                decimal quantity = requestQuantity >= orderItem.GetAvailableForInvoice() ? orderItem.GetAvailableForInvoice() : requestQuantity;
                orderItem.UpdateInvoiced(quantity);
                balanceRepository.Add(new OrderItemBalance(orderItem, invoiceItem, quantity, "Ton"));
                requestQuantity -= quantity;
                if (requestQuantity == 0)
                    break;
            }
            if (requestQuantity > 0)
                throw new BusinessRuleException("", "Not enough Quantity In Refrenced Orders");
        }

        private decimal updateInvoiceItemWithHeterogeneousOderItem(InvoiceItem invoiceItem, OrderItem orderItem, decimal availableForInvoice)
        {
            var currentValueInMainUnit = goodUnitConvertorDomainService.GetUnitValueInMainUnit
                (invoiceItem.GoodId, invoiceItem.MeasuringUnitId, invoiceItem.Quantity);
            invoiceItem.UpdateUnitAndQuantity(currentValueInMainUnit.Id, currentValueInMainUnit.Value);
            var newValueInMainUnit = goodUnitConvertorDomainService.GetUnitValueInMainUnit
                (invoiceItem.GoodId, orderItem.MeasuringUnitId, availableForInvoice);

            return newValueInMainUnit.Value;
        }
        */
        public List<OrderItemBalance> CreateBalanceRecordForInvoiceItem(InvoiceItem invoiceItem, List<Order> orderRefrences)
        {
            var relatedOrderItemsToInvoiceItem =
                orderRefrences.SelectMany(c => c.OrderItems.Where(d => d.GoodId == invoiceItem.GoodId /*&& d.GetAvailableForInvoice() > 0*/)).ToList();

            return balanceInvoiceItemInMainUnit(invoiceItem, relatedOrderItemsToInvoiceItem);
            //if (relatedOrderItemsToInvoiceItem.GroupBy(c => c.MeasuringUnitId == invoiceItem.MeasuringUnitId).Count() > 1)
            //else
            //    balanceInvoiceItem(invoiceItem, relatedOrderItemsToInvoiceItem);
        }