Exemplo n.º 1
0
        public dynamic GenerateGLHeader(ICollection <PurchaseInvoiceLine> InvoiceLines, PurchaseInvoiceHeader purchaseIvoice)
        {
            var glHeader = _financialService.CreateGeneralLedgerHeader(DocumentTypes.PurchaseInvoice, purchaseIvoice.Date, purchaseIvoice.Description);

            decimal totalTaxAmount = 0, totalAmount = 0, totalDiscount = 0;
            var     taxes = new List <KeyValuePair <int, decimal> >();

            foreach (var line in InvoiceLines)
            {
                var lineTaxes = _financialService.ComputeInputTax(purchaseIvoice.VendorId.Value, line.ItemId, line.Quantity, line.Cost.Value, decimal.Zero);

                var lineAmount = line.Quantity * line.Cost;

                var totalLineAmount = lineAmount + lineTaxes.Sum(t => t.Value);

                totalAmount += (decimal)totalLineAmount;

                foreach (var t in lineTaxes)
                {
                    taxes.Add(t);
                }
            }

            if (taxes != null && taxes.Count > 0)
            {
                var groupedTaxes = from t in taxes
                                   group t by t.Key into grouped
                                   select new
                {
                    Key   = grouped.Key,
                    Value = grouped.Sum(t => t.Value)
                };

                totalTaxAmount = taxes.Sum(t => t.Value);

                foreach (var tax in groupedTaxes)
                {
                    var tx = _financialService.GetTaxes().Where(t => t.Id == tax.Key).FirstOrDefault();
                    var debitPurchaseTaxAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Dr, tx.PurchasingAccountId.Value, tax.Value);
                    glHeader.GeneralLedgerLines.Add(debitPurchaseTaxAccount);
                }
            }

            if (totalDiscount > 0)
            {
            }

            Vendor vendor = _vendorRepo.GetById(purchaseIvoice.VendorId.Value);
            var    creditVendorAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Cr, vendor.AccountsPayableAccountId.Value, totalAmount);

            glHeader.GeneralLedgerLines.Add(creditVendorAccount);

            var debitGRNClearingAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Dr, GetGeneralLedgerSetting().GoodsReceiptNoteClearingAccountId.Value, totalAmount - totalTaxAmount);

            glHeader.GeneralLedgerLines.Add(debitGRNClearingAccount);

            return(glHeader);
        }
Exemplo n.º 2
0
        public void AddSalesInvoice(SalesInvoiceHeader salesInvoice, int?salesDeliveryId)
        {
            decimal totalAmount = 0, totalDiscount = 0;

            var taxes = new List <KeyValuePair <int, decimal> >();
            var sales = new List <KeyValuePair <int, decimal> >();

            var glHeader = _financialService.CreateGeneralLedgerHeader(DocumentTypes.SalesInvoice, salesInvoice.Date, string.Empty);
            var customer = _customerRepo.GetById(salesInvoice.CustomerId);

            foreach (var lineItem in salesInvoice.SalesInvoiceLines)
            {
                var item = _itemRepo.GetById(lineItem.ItemId);

                var lineAmount = lineItem.Quantity * lineItem.Amount;

                if (!item.GLAccountsValidated())
                {
                    throw new Exception("Item is not correctly setup for financial transaction. Please check if GL accounts are all set.");
                }

                var lineDiscountAmount = (lineItem.Discount / 100) * lineAmount;
                totalDiscount += lineDiscountAmount;

                var totalLineAmount = lineAmount - lineDiscountAmount;

                totalAmount += totalLineAmount;

                var lineTaxes = _financialService.ComputeOutputTax(salesInvoice.CustomerId, item.Id, lineItem.Quantity, lineItem.Amount, lineItem.Discount);

                foreach (var t in lineTaxes)
                {
                    taxes.Add(t);
                }

                var lineTaxAmount = lineTaxes != null && lineTaxes.Count > 0 ? lineTaxes.Sum(t => t.Value) : 0;
                totalLineAmount = totalLineAmount - lineTaxAmount;

                sales.Add(new KeyValuePair <int, decimal>(item.SalesAccountId.Value, totalLineAmount));

                if (item.ItemCategory.ItemType == ItemTypes.Purchased)
                {
                    lineItem.InventoryControlJournal = _inventoryService.CreateInventoryControlJournal(lineItem.ItemId,
                                                                                                       lineItem.MeasurementId,
                                                                                                       DocumentTypes.SalesInvoice,
                                                                                                       null,
                                                                                                       lineItem.Quantity,
                                                                                                       lineItem.Quantity * item.Cost,
                                                                                                       lineItem.Quantity * item.Price);
                }
            }

            totalAmount += salesInvoice.ShippingHandlingCharge;
            var debitCustomerAR = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Dr, customer.AccountsReceivableAccount.Id, Math.Round(totalAmount, 2, MidpointRounding.ToEven));

            glHeader.GeneralLedgerLines.Add(debitCustomerAR);

            var groupedSalesAccount = from s in sales
                                      group s by s.Key into grouped
                                      select new
            {
                Key   = grouped.Key,
                Value = grouped.Sum(s => s.Value)
            };

            foreach (var salesAccount in groupedSalesAccount)
            {
                var salesAmount        = salesAccount.Value;
                var creditSalesAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Cr, salesAccount.Key, Math.Round(salesAmount, 2, MidpointRounding.ToEven));
                glHeader.GeneralLedgerLines.Add(creditSalesAccount);
            }

            if (taxes != null && taxes.Count > 0)
            {
                var groupedTaxes = from t in taxes
                                   group t by t.Key into grouped
                                   select new
                {
                    Key   = grouped.Key,
                    Value = grouped.Sum(t => t.Value)
                };

                foreach (var tax in groupedTaxes)
                {
                    var tx = _financialService.GetTaxes().Where(t => t.Id == tax.Key).FirstOrDefault();
                    var creditSalesTaxAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Cr, tx.SalesAccountId.Value, Math.Round(tax.Value, 2, MidpointRounding.ToEven));
                    glHeader.GeneralLedgerLines.Add(creditSalesTaxAccount);
                }
            }

            if (totalDiscount > 0)
            {
                var salesDiscountAccount       = base.GetGeneralLedgerSetting().SalesDiscountAccount;
                var creditSalesDiscountAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Dr, salesDiscountAccount.Id, Math.Round(totalDiscount, 2, MidpointRounding.ToEven));
                glHeader.GeneralLedgerLines.Add(creditSalesDiscountAccount);
            }

            if (salesInvoice.ShippingHandlingCharge > 0)
            {
                var shippingHandlingAccount       = base.GetGeneralLedgerSetting().ShippingChargeAccount;
                var creditShippingHandlingAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Cr, shippingHandlingAccount.Id, Math.Round(salesInvoice.ShippingHandlingCharge, 2, MidpointRounding.ToEven));
                glHeader.GeneralLedgerLines.Add(creditShippingHandlingAccount);
            }

            if (_financialService.ValidateGeneralLedgerEntry(glHeader))
            {
                salesInvoice.GeneralLedgerHeader = glHeader;

                salesInvoice.No = GetNextNumber(SequenceNumberTypes.SalesInvoice).ToString();

                if (!salesDeliveryId.HasValue)
                {
                    var salesDelivery = new SalesDeliveryHeader()
                    {
                        CustomerId = salesInvoice.CustomerId,
                        Date       = salesInvoice.Date,
                    };
                    foreach (var line in salesInvoice.SalesInvoiceLines)
                    {
                        var item = _itemRepo.GetById(line.ItemId);
                        salesDelivery.SalesDeliveryLines.Add(new SalesDeliveryLine()
                        {
                            ItemId        = line.ItemId,
                            MeasurementId = line.MeasurementId,
                            Quantity      = line.Quantity,
                            Discount      = line.Discount,
                            Price         = item.Cost.Value,
                        });
                    }
                    AddSalesDelivery(salesDelivery, false);
                    salesInvoice.SalesDeliveryHeader = salesDelivery;
                }
                _salesInvoiceRepo.Insert(salesInvoice);
            }
        }
Exemplo n.º 3
0
        public void AddPurchaseInvoice(PurchaseInvoiceHeader purchaseIvoice, int?purchaseOrderId)
        {
            #region Auto create purchase order
            if (!purchaseOrderId.HasValue)
            {
                var po = new PurchaseOrderHeader()
                {
                    Date        = purchaseIvoice.Date,
                    No          = GetNextNumber(SequenceNumberTypes.PurchaseOrder).ToString(),
                    Vendor      = purchaseIvoice.Vendor,
                    VendorId    = purchaseIvoice.VendorId.Value,
                    Description = purchaseIvoice.Description,
                };
                foreach (var line in purchaseIvoice.PurchaseInvoiceLines)
                {
                    var item = _inventoryService.GetItemById(line.ItemId);

                    po.PurchaseOrderLines.Add(new PurchaseOrderLine()
                    {
                        ItemId        = item.Id,
                        MeasurementId = line.MeasurementId,
                        Quantity      = line.Quantity,
                        Cost          = item.Cost.Value,
                        Discount      = line.Discount.HasValue ? line.Discount.Value : 0,
                        Amount        = line.Amount * line.Quantity,
                    });
                }
                purchaseIvoice.PurchaseOrders.Add(po);
                //var poReceipt = new PurchaseReceiptHeader()
                //{
                //    Date = DateTime.Now,
                //    VendorId = po.VendorId.Value,
                //    PurchaseOrderHeaderId = po.Id,
                //};

                //foreach (var line in purchaseIvoice.PurchaseInvoiceLines)
                //{
                //    poReceipt.PurchaseReceiptLines.Add(new PurchaseReceiptLine()
                //    {
                //        ItemId = line.ItemId,
                //        MeasurementId = line.MeasurementId,
                //        Quantity = line.Quantity,
                //        ReceivedQuantity = (line.ReceivedQuantity.HasValue ? line.ReceivedQuantity.Value : 0),
                //        Cost = line.Cost.Value,
                //        Amount = line.Cost.Value * (line.ReceivedQuantity.HasValue ? line.ReceivedQuantity.Value : 0),
                //    });
                //}

                //po.PurchaseReceipts.Add(poReceipt);

                //AddPurchaseOrderReceipt(poReceipt);
            }
            #endregion

            var glHeader = _financialService.CreateGeneralLedgerHeader(DocumentTypes.PurchaseInvoice, purchaseIvoice.Date, purchaseIvoice.Description);

            decimal totalTaxAmount = 0, totalAmount = 0, totalDiscount = 0;
            var     taxes = new List <KeyValuePair <int, decimal> >();

            foreach (var line in purchaseIvoice.PurchaseInvoiceLines)
            {
                var lineTaxes = _financialService.ComputeInputTax(purchaseIvoice.VendorId.GetValueOrDefault(), line.ItemId, line.Quantity, line.Amount, line.Discount.GetValueOrDefault());

                var lineAmount = line.Quantity * line.Amount;

                var totalLineAmount = lineAmount + lineTaxes.Sum(t => t.Value);

                totalAmount += (decimal)totalLineAmount;

                foreach (var t in lineTaxes)
                {
                    taxes.Add(t);
                }

                var     item = _inventoryService.GetItemById(line.ItemId);
                decimal lineItemTotalAmountAfterTax = line.Amount - lineTaxes.Sum(t => t.Value);

                GeneralLedgerLine debitInventory = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Dr, item.InventoryAccount.Id, lineItemTotalAmountAfterTax);
                glHeader.GeneralLedgerLines.Add(debitInventory);

                GeneralLedgerLine creditGRNClearingAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Cr, GetGeneralLedgerSetting().GoodsReceiptNoteClearingAccountId.Value, lineItemTotalAmountAfterTax);
                glHeader.GeneralLedgerLines.Add(creditGRNClearingAccount);

                line.InventoryControlJournal = _inventoryService.CreateInventoryControlJournal(line.ItemId,
                                                                                               line.MeasurementId,
                                                                                               DocumentTypes.PurchaseReceipt,
                                                                                               line.Quantity,
                                                                                               null,
                                                                                               line.Quantity * item.Cost,
                                                                                               null);
            }

            if (taxes != null && taxes.Count > 0)
            {
                var groupedTaxes = from t in taxes
                                   group t by t.Key into grouped
                                   select new
                {
                    Key   = grouped.Key,
                    Value = grouped.Sum(t => t.Value)
                };

                totalTaxAmount = taxes.Sum(t => t.Value);

                foreach (var tax in groupedTaxes)
                {
                    var tx = _financialService.GetTaxes().Where(t => t.Id == tax.Key).FirstOrDefault();
                    var debitPurchaseTaxAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Dr, tx.PurchasingAccountId.Value, tax.Value);
                    glHeader.GeneralLedgerLines.Add(debitPurchaseTaxAccount);
                }
            }

            if (totalDiscount > 0)
            {
            }

            Vendor vendor = GetVendorById(purchaseIvoice.VendorId.Value);
            var    creditVendorAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Cr, vendor.AccountsPayableAccountId.Value, totalAmount);
            glHeader.GeneralLedgerLines.Add(creditVendorAccount);

            var debitGRNClearingAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Dr, GetGeneralLedgerSetting().GoodsReceiptNoteClearingAccountId.Value, totalAmount - totalTaxAmount);
            glHeader.GeneralLedgerLines.Add(debitGRNClearingAccount);

            if (_financialService.ValidateGeneralLedgerEntry(glHeader))
            {
                purchaseIvoice.GeneralLedgerHeader = glHeader;

                purchaseIvoice.No = GetNextNumber(SequenceNumberTypes.PurchaseInvoice).ToString();
                _purchaseInvoiceRepo.Insert(purchaseIvoice);

                if (purchaseOrderId.HasValue)
                {
                    // TODO: Look for other way to update the purchase order's invoice header id field so that it shall be in a single transaction along with purchase invoice saving
                    var purchOrder = GetPurchaseOrderById(purchaseOrderId.GetValueOrDefault());
                    //purchOrder.PurchaseInvoiceHeaderId = purchaseIvoice.Id;
                    _purchaseOrderRepo.Update(purchOrder);
                }
            }
        }
Exemplo n.º 4
0
        public void AddPurchaseInvoice(PurchaseInvoiceHeader purchaseIvoice, int?purchaseOrderId)
        {
            #region Auto create purchase order
            if (!purchaseOrderId.HasValue)
            {
                var po = new PurchaseOrderHeader()
                {
                    Date        = purchaseIvoice.Date,
                    No          = GetNextNumber(SequenceNumberTypes.PurchaseOrder).ToString(),
                    Vendor      = purchaseIvoice.Vendor,
                    VendorId    = purchaseIvoice.VendorId.Value,
                    Description = purchaseIvoice.Description,
                    CreatedBy   = purchaseIvoice.CreatedBy,
                    CreatedOn   = purchaseIvoice.CreatedOn,
                    ModifiedBy  = purchaseIvoice.ModifiedBy,
                    ModifiedOn  = purchaseIvoice.ModifiedOn
                };
                foreach (var line in purchaseIvoice.PurchaseInvoiceLines)
                {
                    var item = _itemRepo.GetById(line.ItemId);

                    po.PurchaseOrderLines.Add(new PurchaseOrderLine()
                    {
                        ItemId        = item.Id,
                        MeasurementId = line.MeasurementId,
                        Quantity      = line.Quantity,
                        Cost          = item.Cost.Value,
                        Discount      = line.Discount.HasValue ? line.Discount.Value : 0,
                        Amount        = item.Cost.Value * line.Quantity,
                        CreatedBy     = line.CreatedBy,
                        CreatedOn     = line.CreatedOn,
                        ModifiedBy    = line.ModifiedBy,
                        ModifiedOn    = line.ModifiedOn
                    });
                }
                purchaseIvoice.PurchaseOrders.Add(po);

                var poReceipt = new PurchaseReceiptHeader()
                {
                    Date     = DateTime.Now,
                    Vendor   = po.Vendor,
                    VendorId = po.VendorId,
                    PurchaseOrderHeaderId = po.Id,
                    CreatedBy             = po.CreatedBy,
                    CreatedOn             = DateTime.Now,
                    ModifiedBy            = po.ModifiedBy,
                    ModifiedOn            = DateTime.Now
                };

                foreach (var line in purchaseIvoice.PurchaseInvoiceLines)
                {
                    poReceipt.PurchaseReceiptLines.Add(new PurchaseReceiptLine()
                    {
                        ItemId           = line.ItemId,
                        MeasurementId    = line.MeasurementId,
                        Quantity         = line.Quantity,
                        ReceivedQuantity = (line.ReceivedQuantity.HasValue ? line.ReceivedQuantity.Value : 0),
                        Cost             = line.Cost.Value,
                        Amount           = line.Cost.Value * (line.ReceivedQuantity.HasValue ? line.ReceivedQuantity.Value : 0),
                        CreatedBy        = po.CreatedBy,
                        CreatedOn        = DateTime.Now,
                        ModifiedBy       = po.ModifiedBy,
                        ModifiedOn       = DateTime.Now
                    });
                }

                po.PurchaseReceipts.Add(poReceipt);

                AddPurchaseOrderReceipt(poReceipt);
            }
            #endregion

            var glHeader = _financialService.CreateGeneralLedgerHeader(DocumentTypes.PurchaseInvoice, purchaseIvoice.Date, purchaseIvoice.Description);

            decimal taxAmount = 0;
            var     taxes     = new List <KeyValuePair <int, decimal> >();
            foreach (var line in purchaseIvoice.PurchaseInvoiceLines)
            {
                var lineAmount = line.Quantity * line.Cost;
                //var item = _inventoryService.GetItemById(line.ItemId);
                //foreach (var tax in item.ItemTaxGroup.ItemTaxGroupTax)
                //{
                //    if(!tax.IsExempt)
                //    {
                //        var lineTaxAmount = (tax.Tax.Rate / 100) * lineAmount;
                //        taxAmount += lineTaxAmount.Value;
                //        taxes.Add(new KeyValuePair<int, decimal>(tax.Tax.PurchasingAccountId.Value, lineTaxAmount.Value));
                //    }
                //}
                var lineTaxes = _financialService.ComputeInputTax(line.ItemId, line.Quantity, line.Cost.Value);
                foreach (var t in lineTaxes)
                {
                    taxes.Add(t);
                }
            }

            decimal totalAmount   = purchaseIvoice.PurchaseInvoiceLines.Sum(d => d.Amount);
            decimal totalDiscount = 0;

            Vendor vendor = _vendorRepo.GetById(purchaseIvoice.VendorId.Value);
            var    creditVendorAccount = _financialService.CreateGeneralLedgerLine(TransactionTypes.Cr, vendor.AccountsPayableAccountId.Value, totalAmount + taxAmount);
            glHeader.GeneralLedgerLines.Add(creditVendorAccount);

            var creditGRNClearingAccount = _financialService.CreateGeneralLedgerLine(TransactionTypes.Dr, GetGeneralLedgerSetting().GoodsReceiptNoteClearingAccountId.Value, totalAmount);
            glHeader.GeneralLedgerLines.Add(creditGRNClearingAccount);

            if (taxAmount > 0)
            {
                var groupedTaxes = from t in taxes
                                   group t by t.Key into grouped
                                   select new
                {
                    Key   = grouped.Key,
                    Value = grouped.Sum(t => t.Value)
                };

                foreach (var tax in groupedTaxes)
                {
                    var tx = _financialService.GetTaxes().Where(t => t.Id == tax.Key).FirstOrDefault();
                    var debitPurchaseTaxAccount = _financialService.CreateGeneralLedgerLine(TransactionTypes.Dr, tx.SalesAccountId.Value, tax.Value);
                    glHeader.GeneralLedgerLines.Add(debitPurchaseTaxAccount);
                }
            }

            if (totalDiscount > 0)
            {
            }

            if (_financialService.ValidateGeneralLedgerEntry(glHeader))
            {
                purchaseIvoice.GeneralLedgerHeader = glHeader;

                purchaseIvoice.No = GetNextNumber(SequenceNumberTypes.PurchaseInvoice).ToString();
                _purchaseInvoiceRepo.Insert(purchaseIvoice);

                // TODO: Look for another way to update the purchase order's invoice header id field so that it shall be in a single transaction along with purchase invoice saving
                var purchOrder = _purchaseOrderRepo.GetById(purchaseOrderId.Value);
                purchOrder.PurchaseInvoiceHeaderId = purchaseIvoice.Id;
                purchOrder.ModifiedBy = purchaseIvoice.ModifiedBy;
                purchOrder.ModifiedOn = purchaseIvoice.ModifiedOn;
                _purchaseOrderRepo.Update(purchOrder);
            }
        }
Exemplo n.º 5
0
        //public SalesInvoiceHeader GetSalesInvoiceByNo(string no)
        //{
        //    var query = from invoice in _salesInvoiceRepo.Table
        //                where invoice.No == no
        //                select invoice;
        //    return query.FirstOrDefault();
        //}
        public SalesInvoiceHeader SaveSaleInvoice(SalesInvoiceHeader salesInvoice)
        {
            decimal totalAmount = 0, totalDiscount = 0;
            var     taxes    = new List <KeyValuePair <int, decimal> >();
            var     sales    = new List <KeyValuePair <int, decimal> >();
            var     glHeader = _financialService.CreateGeneralLedgerHeader(DocumentTypes.SalesInvoice, salesInvoice.Date, salesInvoice.Description);
            var     customer = _customerRepo.GetById(salesInvoice.CustomerId);

            foreach (var lineItem in salesInvoice.SalesInvoiceLines)
            {
                var item = _inventoryService.GetItemDetailById(lineItem.ItemId);

                var lineAmount = lineItem.Quantity * lineItem.Amount;

                //var itemCatagory = _itemCatagoryRepo.GetById(lineItem.ItemId);
                item.CostOfGoodsSoldAccountId     = item.CostOfGoodsSoldAccountId;
                item.InventoryAccountId           = item.InventoryAccountId;
                item.SalesAccountId               = item.SalesAccountId;
                item.InventoryAdjustmentAccountId = item.InventoryAdjustmentAccountId;
                //item.ItemCategory=new ItemCategory { ItemType=itemCatagory.ItemType};

                if (!item.GLAccountsValidated())
                {
                    throw new Exception("Item is not correctly setup for financial transaction. Please check if GL accounts are all set.");
                }

                lineItem.DiscountAmount = (lineItem.Discount / 100) * lineAmount;
                totalDiscount          += lineItem.DiscountAmount;

                var totalLineAmount = lineAmount - lineItem.DiscountAmount;

                totalAmount += totalLineAmount;

                //TODO: Sarfraz has to build Taxes list
                var itemTaxesToAdd = lineItem.Taxes.Select(t => new Tax()
                {
                    Id = t.TaxId, Rate = t.Rate
                }).ToList();
                var lineTaxes = _financialService.ComputeOutputTax(item.Id, lineItem.Quantity, lineItem.Amount, lineItem.Discount, itemTaxesToAdd);

                foreach (var t in lineTaxes)
                {
                    taxes.Add(t);
                }

                //lineItem.TaxAmount = lineTaxes != null && lineTaxes.Count > 0 ? lineTaxes.Sum(t => t.Value) : 0;
                //totalLineAmount = totalLineAmount - lineItem.TaxAmount;

                sales.Add(new KeyValuePair <int, decimal>(item.SalesAccountId.Value, totalLineAmount));

                if (item.ItemCategory.ItemType == ItemTypes.Purchased)
                {
                    lineItem.InventoryControlJournal = _inventoryService.CreateInventoryControlJournal(lineItem.ItemId,
                                                                                                       lineItem.MeasurementId,
                                                                                                       DocumentTypes.SalesInvoice,
                                                                                                       null,
                                                                                                       lineItem.Quantity,
                                                                                                       lineItem.Quantity * item.Cost,
                                                                                                       lineItem.Quantity * item.Price);
                }
            }
            decimal totalTax = 0;

            foreach (var tax in taxes)
            {
                totalTax += tax.Value;
            }
            totalAmount += salesInvoice.ShippingHandlingCharge + totalTax;

            var debitCustomerAR = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Dr, customer.AccountsReceivableAccount.Id, Math.Round(totalAmount, 2, MidpointRounding.ToEven));

            glHeader.GeneralLedgerLines.Add(debitCustomerAR);

            var groupedSalesAccount = from s in sales
                                      group s by s.Key into grouped
                                      select new
            {
                Key   = grouped.Key,
                Value = grouped.Sum(s => s.Value)
            };

            foreach (var salesAccount in groupedSalesAccount)
            {
                var salesAmount        = salesAccount.Value;
                var creditSalesAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Cr, salesAccount.Key, Math.Round(salesAmount, 2, MidpointRounding.ToEven));
                glHeader.GeneralLedgerLines.Add(creditSalesAccount);
            }

            if (taxes != null && taxes.Count > 0)
            {
                var groupedTaxes = from t in taxes
                                   group t by t.Key into grouped
                                   select new
                {
                    Key   = grouped.Key,
                    Value = grouped.Sum(t => t.Value)
                };

                foreach (var tax in groupedTaxes)
                {
                    var tx = _financialService.GetTaxes().Where(t => t.Id == tax.Key).FirstOrDefault();
                    var creditSalesTaxAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Cr, tx.SalesAccountId.Value, Math.Round(tax.Value, 2, MidpointRounding.ToEven));
                    glHeader.GeneralLedgerLines.Add(creditSalesTaxAccount);
                }
            }

            if (totalDiscount > 0)
            {
                var salesDiscountAccount       = base.GetGeneralLedgerSetting().SalesDiscountAccount;
                var creditSalesDiscountAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Dr, salesDiscountAccount.Id, Math.Round(totalDiscount, 2, MidpointRounding.ToEven));
                glHeader.GeneralLedgerLines.Add(creditSalesDiscountAccount);
            }

            if (salesInvoice.ShippingHandlingCharge > 0)
            {
                var shippingHandlingAccount       = base.GetGeneralLedgerSetting().ShippingChargeAccount;
                var creditShippingHandlingAccount = _financialService.CreateGeneralLedgerLine(DrOrCrSide.Cr, shippingHandlingAccount.Id, Math.Round(salesInvoice.ShippingHandlingCharge, 2, MidpointRounding.ToEven));
                glHeader.GeneralLedgerLines.Add(creditShippingHandlingAccount);
            }

            if (_financialService.ValidateGeneralLedgerEntry(glHeader))
            {
                salesInvoice.GeneralLedgerHeader = glHeader;

                var dbObject = _salesInvoiceRepo.Table
                               .Include(p => p.GeneralLedgerHeader)
                               .ThenInclude(p => p.GeneralLedgerLines)
                               .Include(p => p.SalesInvoiceLines)
                               .ThenInclude(p2 => p2.InventoryControlJournal)
                               .Where(o => o.Id == salesInvoice.Id).FirstOrDefault();

                #region UPDATE
                if (dbObject != null)
                {
                    dbObject.No                     = salesInvoice.No;
                    dbObject.Description            = salesInvoice.Description;
                    dbObject.Date                   = salesInvoice.Date;
                    dbObject.CustomerId             = salesInvoice.CustomerId;
                    dbObject.ShippingHandlingCharge = salesInvoice.ShippingHandlingCharge;
                    dbObject.IsActive               = salesInvoice.IsActive;

                    dbObject.GeneralLedgerHeader.Date        = salesInvoice.Date;
                    dbObject.GeneralLedgerHeader.Description = salesInvoice.Description;
                    var GLLinesToUpdateIds = dbObject.GeneralLedgerHeader.GeneralLedgerLines.Select(c => c.Id).ToList();
                    foreach (var generalLedgerLine in salesInvoice.GeneralLedgerHeader.GeneralLedgerLines)
                    {
                        var existinggeneralLedgerLine = dbObject.GeneralLedgerHeader.GeneralLedgerLines.FirstOrDefault(c => c.AccountId == generalLedgerLine.AccountId);
                        if (existinggeneralLedgerLine != null)
                        {
                            existinggeneralLedgerLine.AccountId = generalLedgerLine.AccountId;
                            existinggeneralLedgerLine.Amount    = generalLedgerLine.Amount;
                            existinggeneralLedgerLine.DrCr      = generalLedgerLine.DrCr;
                            existinggeneralLedgerLine.IsActive  = generalLedgerLine.IsActive;
                            GLLinesToUpdateIds.Remove(existinggeneralLedgerLine.Id);
                        }
                        else
                        {
                            dbObject.GeneralLedgerHeader.GeneralLedgerLines.Add(new GeneralLedgerLine()
                            {
                                DrCr      = generalLedgerLine.DrCr,
                                AccountId = generalLedgerLine.AccountId,
                                Amount    = generalLedgerLine.Amount
                            });
                        }
                    }
                    foreach (var generalLedgerLine in dbObject.GeneralLedgerHeader.GeneralLedgerLines.Where(c => GLLinesToUpdateIds.Contains(c.Id)))
                    {
                        generalLedgerLine.Deleted = true;
                    }
                    var salesInvoiceLinesToUpdateIds = dbObject.SalesInvoiceLines.Select(c => c.Id).ToList();
                    foreach (var salesInvoiceLine in salesInvoice.SalesInvoiceLines)
                    {
                        var existingSalesInvoiceLine = dbObject.SalesInvoiceLines.FirstOrDefault(c => c.Id == salesInvoiceLine.Id);
                        if (existingSalesInvoiceLine != null)
                        {
                            existingSalesInvoiceLine.ItemId        = salesInvoiceLine.ItemId;
                            existingSalesInvoiceLine.MeasurementId = salesInvoiceLine.MeasurementId;
                            // existingSalesInvoiceLine.TaxId = salesInvoiceLine.TaxId;
                            existingSalesInvoiceLine.Quantity = salesInvoiceLine.Quantity;
                            existingSalesInvoiceLine.Discount = salesInvoiceLine.Discount;
                            existingSalesInvoiceLine.Amount   = salesInvoiceLine.Amount;
                            //existingSalesInvoiceLine.TaxAmount = salesInvoiceLine.TaxAmount;
                            existingSalesInvoiceLine.DiscountAmount = salesInvoiceLine.DiscountAmount;
                            existingSalesInvoiceLine.IsActive       = salesInvoiceLine.IsActive;
                            if (salesInvoiceLine.InventoryControlJournal != null)
                            {
                                if (existingSalesInvoiceLine.InventoryControlJournal != null)
                                {
                                    existingSalesInvoiceLine.InventoryControlJournal.MeasurementId = salesInvoiceLine.InventoryControlJournal.MeasurementId;
                                    existingSalesInvoiceLine.InventoryControlJournal.OUTQty        = salesInvoiceLine.InventoryControlJournal.OUTQty;
                                    existingSalesInvoiceLine.InventoryControlJournal.TotalCost     = salesInvoiceLine.InventoryControlJournal.TotalCost;
                                    existingSalesInvoiceLine.InventoryControlJournal.TotalAmount   = salesInvoiceLine.InventoryControlJournal.TotalAmount;
                                }
                                else
                                {
                                    existingSalesInvoiceLine.InventoryControlJournal = salesInvoiceLine.InventoryControlJournal;
                                }
                            }
                            else
                            {
                                if (existingSalesInvoiceLine.InventoryControlJournal != null)
                                {
                                    existingSalesInvoiceLine.InventoryControlJournal.Deleted = true;
                                    existingSalesInvoiceLine.InventoryControlJournalId       = -1;
                                }
                            }
                            salesInvoiceLinesToUpdateIds.Remove(existingSalesInvoiceLine.Id);
                        }
                        else
                        {
                            dbObject.SalesInvoiceLines.Add(salesInvoiceLine);
                        }

                        //TODO: Apply Line Tax update
                    }
                    foreach (var salesInvoiceLine in dbObject.SalesInvoiceLines.Where(c => salesInvoiceLinesToUpdateIds.Contains(c.Id)))
                    {
                        salesInvoiceLine.Deleted = true;
                    }
                    salesInvoice = dbObject;
                    _salesInvoiceRepo.Update(salesInvoice);
                }
                #endregion
                #region INSERT
                else
                {
                    salesInvoice.No = GetNextNumber(SequenceNumberTypes.SalesInvoice).ToString();
                    _salesInvoiceRepo.Insert(salesInvoice);
                }
                #endregion
            }
            return(salesInvoice);
        }