public IHttpActionResult SaveSupplierPayment(SPOPaymentAC supplierPOPayment)
 {
     try
     {
         if (HttpContext.Current.User.Identity.IsAuthenticated)
         {
             var user   = MerchantContext.UserDetails;
             var status = _spoPaymentContext.SaveSupplierPayment(supplierPOPayment, user.RoleName, user.UserName);
             return(Ok(new { status = status }));
         }
         else
         {
             return(BadRequest());
         }
     }
     catch (Exception ex)
     {
         _errorLog.LogException(ex);
         throw;
     }
 }
        /// <summary>
        /// This method is used to save SPO Payment. - JJ
        /// </summary>
        /// <param name="supplierPOPayment"> object of SPOPaymentAC</param>
        /// <param name="RoleName">rolename of the logged in user</param>
        /// <param name="userName">username of the logged in user</param>
        /// <returns>status</returns>
        public string SaveSupplierPayment(SPOPaymentAC supplierPOPayment, string RoleName, string userName)
        {
            decimal creditNoteAmount;
            string  poNumber = string.Empty;
            SupplierPaymentDetail spDetail = new SupplierPaymentDetail
            {
                Amount          = supplierPOPayment.Amount,
                CreatedDateTime = DateTime.UtcNow,
                IsPOBillPayment = true
            };

            _supplierPaymentDetailContext.Add(spDetail);
            _supplierPaymentDetailContext.SaveChanges();
            foreach (var bill in supplierPOPayment.SPOBill)
            {
                var poSupplierBill = _poSupplierBillContext.FirstOrDefault(x => x.BillNumber == bill.BillNumber && x.SupplierPurchaseOrder.PurchaseOrderNumber == bill.PurchaseOrderNo);
                if (poSupplierBill != null)
                {
                    poNumber = bill.PurchaseOrderNo;
                    poSupplierBill.IsPaid           = true;
                    poSupplierBill.ModifiedDateTime = DateTime.UtcNow;
                    _poSupplierBillContext.Update(poSupplierBill);
                    _poSupplierBillContext.SaveChanges();
                    POBillPayment poBill = new POBillPayment
                    {
                        CreatedDateTime   = DateTime.UtcNow,
                        VoucherNo         = supplierPOPayment.VoucherNo,
                        POSupplierBillId  = poSupplierBill.Id,
                        SupplierPaymentId = spDetail.Id
                    };
                    _poBillPaymentContext.Add(poBill);
                    _poBillPaymentContext.SaveChanges();
                }
            }

            var paymentTypeList = _paramTypeContext.Fetch(x => x.Param.Value.Equals(StringConstants.POSPaymentType)).ToList();

            if (supplierPOPayment.Cash != 0)
            {
                PaymentType type = new PaymentType
                {
                    Amount            = supplierPOPayment.Cash,
                    CreatedDateTime   = DateTime.UtcNow,
                    SupplierPaymentId = spDetail.Id,
                    TypeId            = paymentTypeList.FirstOrDefault(x => x.ValueEn.Equals(StringConstants.Cash)).Id
                };
                _paymentTypeContext.Add(type);
                _paymentTypeContext.SaveChanges();
            }
            if (supplierPOPayment.Cheque != 0)
            {
                PaymentType type = new PaymentType
                {
                    Amount            = supplierPOPayment.Cheque,
                    ChequeNo          = supplierPOPayment.ChequeNo,
                    CreatedDateTime   = DateTime.UtcNow,
                    SupplierPaymentId = spDetail.Id,
                    TypeId            = paymentTypeList.FirstOrDefault(x => x.ValueEn.Equals(StringConstants.Cheque)).Id
                };
                _paymentTypeContext.Add(type);
                _paymentTypeContext.SaveChanges();
            }

            creditNoteAmount = supplierPOPayment.Credit;

            if (supplierPOPayment.Credit != 0)
            {
                PaymentType type = new PaymentType
                {
                    Amount            = supplierPOPayment.Credit,
                    CreatedDateTime   = DateTime.UtcNow,
                    SupplierPaymentId = spDetail.Id,
                    TypeId            = _paramTypeContext.FirstOrDefault(x => x.ValueEn.Equals(StringConstants.CreditNote)).Id
                };
                _paymentTypeContext.Add(type);
                _paymentTypeContext.SaveChanges();

                if (supplierPOPayment.CreditNoteDetail != null && supplierPOPayment.CreditNoteDetail.Count > 0)
                {
                    foreach (var note in supplierPOPayment.CreditNoteDetail)
                    {
                        var creditNote = _creditNoteDetailContext.Find(note.Id);
                        if (creditNote != null)
                        {
                            if (creditNote.IsCollected)
                            {
                                if (creditNote.RemainigAmount >= creditNoteAmount)
                                {
                                    creditNote.RemainigAmount = creditNote.RemainigAmount - creditNoteAmount;
                                    creditNoteAmount          = 0;
                                }
                                else
                                {
                                    creditNoteAmount          = creditNoteAmount - creditNote.RemainigAmount;
                                    creditNote.RemainigAmount = 0;
                                }
                            }
                            else
                            {
                                creditNote.IsCollected = true;
                                if (creditNote.Amount >= creditNoteAmount)
                                {
                                    creditNote.RemainigAmount = creditNote.Amount - creditNoteAmount;
                                    creditNoteAmount          = 0;
                                }
                                else
                                {
                                    creditNoteAmount          = creditNoteAmount - creditNote.Amount;
                                    creditNote.RemainigAmount = 0;
                                }
                            }
                            creditNote.ModifiedDateTime = DateTime.UtcNow;
                            _creditNoteDetailContext.Update(creditNote);
                            _creditNoteDetailContext.SaveChanges();

                            PaymentTypeCreditNote notePaymentType = new PaymentTypeCreditNote
                            {
                                CreatedDateTime = DateTime.UtcNow,
                                CreditNoteId    = note.Id,
                                // insert as needed
                                PaymentTypeId = type.Id
                            };
                            _paymentTypeCreditNoteContext.Add(notePaymentType);
                            _paymentTypeCreditNoteContext.SaveChanges();

                            CreditNotePayment notePayment = new CreditNotePayment
                            {
                                CreatedDateTime   = DateTime.UtcNow,
                                SupplierPaymentId = spDetail.Id,
                                CreditNoteId      = note.Id
                            };
                            _creditNotePaymentContext.Add(notePayment);
                            _creditNotePaymentContext.SaveChanges();

                            if (creditNoteAmount <= 0)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            var poSupplierBillList = _poSupplierBillContext.Fetch(x => x.SupplierPurchaseOrder.PurchaseOrderNumber == poNumber).ToList();
            var ispaid             = true;

            foreach (var bill in poSupplierBillList)
            {
                if (!bill.IsPaid)
                {
                    ispaid = false;
                }
            }
            var spo = _supplierPurchaseOrderContext.FirstOrDefault(x => x.PurchaseOrderNumber == poNumber);

            if (ispaid)
            {
                spo.IsPaid           = true;
                spo.ModifiedDateTime = DateTime.UtcNow;
                _supplierPurchaseOrderContext.Update(spo);
                _supplierPurchaseOrderContext.SaveChanges();

                if (supplierPOPayment.Comment == ".")
                {
                    supplierPOPayment.Comment = "";
                }

                _supplierPOWorkListRepository.SaveSupplierPurchaseOrderLog("Paid", supplierPOPayment.Comment, spo.Id, spo.RecordId, RoleName, "" + RoleName + " " + StringConstants.PaySPO, userName);
            }
            else
            {
                _supplierPOWorkListRepository.SaveSupplierPurchaseOrderLog("Partially Paid", supplierPOPayment.Comment, spo.Id, spo.RecordId, RoleName, "" + RoleName + " " + StringConstants.PaySPO, userName);
            }

            var discount = CalculateDiscount(spo.Id);

            InsertIntoAccountEntries(spo, supplierPOPayment, discount);
            return("ok");
        }
        /// <summary>
        /// This method used for insert into account entroes table.- JJ
        /// </summary>
        /// <param name="destruction"></param>
        /// <param name="totalCostPrice"></param>
        private void InsertIntoAccountEntries(SupplierPurchaseOrder supplierPO, SPOPaymentAC supplierPOPayment, decimal?discount)
        {
            try
            {
                List <DoubleEntry> listOfDoubleEntry = new List <DoubleEntry>();
                var spoBranches = _purchaseOrderBranchContext.Fetch(x => x.PurchaseOrderId == supplierPO.Id).ToList();
                foreach (var branch in spoBranches)
                {
                    if (supplierPO.SupplierProfile.SupplierType.ValueEn == StringConstants.Cash)//check whether cash po.
                    {
                        var ledgersForCash        = _iAccountingRepository.GetAccountLedgerByName(StringConstants.CashInHand, Convert.ToInt32(branch.BranchId));
                        var ledgersForStockInHand = _iAccountingRepository.GetAccountLedgerByName(StringConstants.StockInHand, Convert.ToInt32(branch.BranchId));
                        var cash = 0M;
                        cash = supplierPOPayment.Cash;
                        if (discount > 0)
                        {
                            cash += (decimal)discount;
                        }
                        if (ledgersForCash != null && ledgersForStockInHand != null)
                        {
                            listOfDoubleEntry.Add(new DoubleEntry {
                                LedgerId = ledgersForCash.Id, TransactionDate = DateTime.UtcNow, Credit = cash, Debit = 0, ActivityName = StringConstants.SPOPayment, CreatedDateTime = DateTime.UtcNow, Description = "Entry for SPO no. " + supplierPO.PurchaseOrderNumber
                            });
                            listOfDoubleEntry.Add(new DoubleEntry {
                                LedgerId = ledgersForStockInHand.Id, TransactionDate = DateTime.UtcNow, Credit = 0, Debit = cash, ActivityName = StringConstants.SPOPayment, CreatedDateTime = DateTime.UtcNow, Description = "Entry for SPO no. " + supplierPO.PurchaseOrderNumber
                            });
                        }
                    }
                    else
                    {
                        var ledgersForSupplier    = _iAccountingRepository.GetAccountLedgerBySupplier(supplierPO.SupplierId);
                        var ledgersForStockInHand = _iAccountingRepository.GetAccountLedgerByName(StringConstants.StockInHand, Convert.ToInt32(branch.BranchId));
                        var cheque = 0M;
                        cheque = supplierPOPayment.Cheque;
                        if (discount > 0)
                        {
                            cheque += (decimal)discount;
                        }
                        if (ledgersForSupplier != null && ledgersForStockInHand != null)
                        {
                            listOfDoubleEntry.Add(new DoubleEntry {
                                LedgerId = ledgersForSupplier.Id, TransactionDate = DateTime.UtcNow, Credit = cheque, Debit = 0, ActivityName = StringConstants.SPOPayment, CreatedDateTime = DateTime.UtcNow, Description = "Entry for SPO no. " + supplierPO.PurchaseOrderNumber
                            });
                            listOfDoubleEntry.Add(new DoubleEntry {
                                LedgerId = ledgersForStockInHand.Id, TransactionDate = DateTime.UtcNow, Credit = 0, Debit = cheque, ActivityName = StringConstants.SPOPayment, CreatedDateTime = DateTime.UtcNow, Description = "Entry for SPO no. " + supplierPO.PurchaseOrderNumber
                            });
                        }
                    }

                    if (discount > 0)
                    {
                        var ledgersForIncome = _iAccountingRepository.GetAccountLedgerByName(StringConstants.Income, Convert.ToInt32(branch.BranchId));
                        if (ledgersForIncome != null)
                        {
                            listOfDoubleEntry.Add(new DoubleEntry {
                                LedgerId = ledgersForIncome.Id, TransactionDate = DateTime.UtcNow, Credit = (decimal)discount, Debit = 0, ActivityName = StringConstants.SPOPayment, CreatedDateTime = DateTime.UtcNow, Description = "Entry for SPO no. " + supplierPO.PurchaseOrderNumber
                            });
                        }
                    }

                    if (supplierPOPayment.Credit > 0)
                    {
                        var ledgersForSupplier   = _iAccountingRepository.GetAccountLedgerBySupplier(supplierPO.SupplierId);
                        var ledgersForCreditNote = _iAccountingRepository.GetAccountLedgerByName(StringConstants.CRNote, Convert.ToInt32(branch.BranchId));
                        if (ledgersForSupplier != null && ledgersForCreditNote != null)
                        {
                            listOfDoubleEntry.Add(new DoubleEntry {
                                LedgerId = ledgersForCreditNote.Id, TransactionDate = DateTime.UtcNow, Credit = supplierPOPayment.Credit, Debit = 0, ActivityName = StringConstants.SPOPayment, CreatedDateTime = DateTime.UtcNow, Description = "Entry for SPO no. " + supplierPO.PurchaseOrderNumber
                            });
                            listOfDoubleEntry.Add(new DoubleEntry {
                                LedgerId = ledgersForSupplier.Id, TransactionDate = DateTime.UtcNow, Credit = 0, Debit = supplierPOPayment.Credit, ActivityName = StringConstants.SPOPayment, CreatedDateTime = DateTime.UtcNow, Description = "Entry for SPO no. " + supplierPO.PurchaseOrderNumber
                            });
                        }
                    }
                }
                if (listOfDoubleEntry.Any())
                {
                    _iAccountingRepository.AddAccountingEntries(listOfDoubleEntry);
                }
            }
            catch (Exception ex)
            {
                _errorLog.LogException(ex);
                throw;
            }
        }