private async Task <IActionResult> SendInvoice()
        {
            if (Order != null && Order.Invoice != null)
            {
                var Invoice = InvoiceFunction.GetInvoiceByOrderId(OrderId);
                BotMessage = new InvoiceViewMessage(Invoice, OrderId);
                await EditMessage(BotMessage.BuildMsg());

                return(OkResult);
            }

            return(OkResult);
        }
        /// <summary>
        /// отправить сообщение со счетом на оплату
        /// </summary>
        /// <returns></returns>
        private async Task <IActionResult> SendViewInvoice()
        {
            var Invoice = InvoiceFunction.GetInvoiceByOrderId(OrderId);

            BotMessage = new AdminViewInvoice(Invoice);

            var mess = BotMessage.BuildMsg();

            if (mess != null)
            {
                await EditMessage(mess);
            }

            else
            {
                await AnswerCallback("Счет на оплату отсутствует", true);
            }

            return(OkResult);
        }
Exemple #3
0
        public override BotMessage BuildMsg()
        {
            string IsPaid = "Нет";

            if (Invoice == null && OrderId > 0)
            {
                Invoice = InvoiceFunction.GetInvoiceByOrderId(OrderId);
            }

            if (Invoice != null)
            {
                if (Invoice.Paid && Invoice.Payment.Count > 0)
                {
                    IsPaid = "Да (" + Invoice.Payment.LastOrDefault().TimestampDataAdd.ToString() + ")";
                }

                base.TextMessage = Bold("Счет на оплату №") + Invoice.InvoiceNumber.ToString() + NewLine() +
                                   Bold("Адрес счета получателя:") + Invoice.AccountNumber + NewLine() +
                                   Bold("Комментарий к платежу:") + Invoice.Comment + NewLine() +
                                   Bold("Сумма: ") + Invoice.Value.ToString() + " " + Invoice.PaymentType.Code + NewLine() +
                                   Bold("Время создания: ") + Invoice.CreateTimestamp.ToString() + NewLine() +
                                   Bold("Способ оплаты: ") + Invoice.PaymentType.Name + NewLine() +
                                   Bold("Оплачено:") + IsPaid;

                BackToOrderBtn = BuildInlineBtn("Детали заказа", BuildCallData(OrderProccesingBot.CmdBackToOrder, OrderProccesingBot.ModuleName, Invoice.Orders.LastOrDefault().Id));

                ViewPaymentBtn = BuildInlineBtn("Платеж", BuildCallData(OrderProccesingBot.ViewPaymentCmd, OrderProccesingBot.ModuleName, Invoice.Orders.LastOrDefault().Id, Invoice.Payment.LastOrDefault().Id));

                if (Invoice.PaymentType != null && Invoice.PaymentType.Id == ConstantVariable.PaymentTypeVariable.Litecoin ||
                    Invoice.PaymentType != null && Invoice.PaymentType.Id == ConstantVariable.PaymentTypeVariable.Bitcoin ||
                    Invoice.PaymentType != null && Invoice.PaymentType.Id == ConstantVariable.PaymentTypeVariable.Doge)
                {
                    base.TextMessage += NewLine() + NewLine() +
                                        HrefUrl("https://live.blockcypher.com/" + Invoice.PaymentType.Code + "/address/" + Invoice.AccountNumber, "Посмотреть счет");
                }


                if (Invoice.PaymentType != null && Invoice.PaymentType.Id == ConstantVariable.PaymentTypeVariable.BitcoinCash)
                {
                    base.TextMessage += NewLine() + NewLine() +
                                        HrefUrl("https://blockchair.com/bitcoin-cash/address/" + Invoice.AccountNumber, "Посмотреть счет");
                }

                if (Invoice.PaymentType != null && Invoice.PaymentType.Id == ConstantVariable.PaymentTypeVariable.Dash)
                {
                    base.TextMessage += NewLine() + NewLine() +
                                        HrefUrl("https://explorer.dash.org/address/" + Invoice.AccountNumber, "Посмотреть счет");
                }

                if (Invoice.PaymentType != null && Invoice.PaymentType.Id == ConstantVariable.PaymentTypeVariable.Zcash)
                {
                    base.TextMessage += NewLine() + NewLine() +
                                        HrefUrl("https://explorer.zcha.in/accounts/" + Invoice.AccountNumber, "Посмотреть счет");
                }


                SetButtons();

                return(this);
            }

            else
            {
                return(null);
            }
        }
Exemple #4
0
        private async Task <AccountingDocumentLine> CreateAccountingDocumentLineForInvoice(
            AccountingDocumentLineType accountingDocumentLineType, InvoiceInformationDto invoiceInformation,
            IEnumerable <SectionsInformationDto> sectionsInformation, IEnumerable <Vat> vats, Company company,
            AccountingSetupDto accountingSetup, FxRateInformation fxRates, int postingLineId, int index = 0,
            List <AccountingDocumentLine> accountingDocumentLines = null)
        {
            string          whiteSpace      = " ";
            InvoiceFunction invoiceFunction = CommonRules.CheckInvoiceType(invoiceInformation.InvoiceType);

            AccountingDocumentLine accountingDocumentLine = new AccountingDocumentLine();

            SectionsInformationDto latestSectionsInformation = sectionsInformation.OrderByDescending(x => x.BLDate).FirstOrDefault();

            accountingDocumentLine.AssociatedAccountCode = invoiceInformation.CounterpartyCode;
            accountingDocumentLine.ClientReference       = invoiceInformation.ExternalReference;
            accountingDocumentLine.PaymentTermCode       = invoiceInformation.PaymentTerms;
            if (invoiceFunction == InvoiceFunction.Commercial)
            {
                if (invoiceInformation.CostTypeCode != null)
                {
                    accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode;
                }
                else
                {
                    accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? accountingSetup.PurchaseInvoice : accountingSetup.SalesInvoice;
                }

                accountingDocumentLine.Narrative = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode);
            }
            else if (invoiceFunction == InvoiceFunction.GoodsAndCost)
            {
                if (invoiceInformation.CostTypeCode != null)
                {
                    accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode;
                }
                else
                {
                    accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.GoodsCostPurchase ? accountingSetup.PurchaseInvoice : accountingSetup.SalesInvoice;
                }

                accountingDocumentLine.Narrative = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode);
            }
            else if (invoiceFunction == InvoiceFunction.Cost)
            {
                accountingDocumentLine.Narrative    = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, invoiceInformation.InvoiceLines.ToList()[index].CostType);
                accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceLines.ToList()[index].CostType;
            }
            else if (invoiceFunction == InvoiceFunction.Washout)
            {
                if (invoiceInformation.InvoiceLines.ToList()[index].CostDirectionId != null)
                {
                    accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceLines.ToList()[index].CostType;
                }
                else
                {
                    int purchaseIndex = index % 2 == 0 ? index + 1 : index - 1;
                    var saleLines     = invoiceInformation.InvoiceLines.ToList()[index];
                    var purchaseLines = invoiceInformation.InvoiceLines.ToList()[purchaseIndex];
                    accountingDocumentLine.CostTypeCode = saleLines.InvoiceLineAmount > purchaseLines.InvoiceLineAmount ? accountingSetup.WashoutInvoiceGains : accountingSetup.WashoutInvoiceLoss;
                }

                accountingDocumentLine.Narrative = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode);
            }
            else if (invoiceFunction == InvoiceFunction.Cancelled)
            {
                accountingDocumentLine.CostTypeCode = invoiceInformation.TransactionDocumentTypeId == (int)MasterDocumentType.CN ? accountingSetup.CancellationLoss : accountingSetup.CancellationGain;

                accountingDocumentLine.Narrative = invoiceInformation.ExternalReference;
            }

            switch (accountingDocumentLineType)
            {
            case AccountingDocumentLineType.Client:
                accountingDocumentLine.PostingLineId        = postingLineId;
                accountingDocumentLine.ContractSectionCode  = latestSectionsInformation.ContractSectionCode;
                accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.C;
                accountingDocumentLine.VATTurnover          = null;
                accountingDocumentLine.VATCode                    = null;
                accountingDocumentLine.AccountReference           = (invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase || invoiceInformation.InvoiceType == (int)Entities.InvoiceType.GoodsCostPurchase) ? accountingSetup.PurchaseLedgerControlClientCreditors : accountingSetup.SalesLedgerControlClientDebtors;
                accountingDocumentLine.CommodityId                = latestSectionsInformation.CommodityId;
                accountingDocumentLine.CharterId                  = latestSectionsInformation.CharterId;
                accountingDocumentLine.DepartmentId               = latestSectionsInformation.DepartmentId;
                accountingDocumentLine.SectionId                  = latestSectionsInformation.SectionId;
                accountingDocumentLine.SecondaryDocumentReference = null;
                accountingDocumentLine.ClientAccount              = invoiceInformation.CounterpartyCode;
                if (invoiceFunction == InvoiceFunction.Commercial)
                {
                    // The quantity of the client line should be the Sum of quantities of Nominal Legs
                    accountingDocumentLine.Quantity          = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(x => x.Quantity).Sum();
                    accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? (int)AccountLineType.V : (int)AccountLineType.C;
                    decimal totalTaxAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum();
                    accountingDocumentLine.Amount = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? -(invoiceInformation.SumOfInvoiceTotalAmount + totalTaxAmount) : invoiceInformation.SumOfInvoiceTotalAmount - totalTaxAmount;

                    // Binding the cost type associated with business sector if business sector posting is configured
                    if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null)
                    {
                        accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode;
                    }
                }
                else if (invoiceFunction == InvoiceFunction.Cost)
                {
                    decimal totalNominalAmount = 0;
                    foreach (InvoiceLinesDto invoiceLineNominalClient in invoiceInformation.InvoiceLines)
                    {
                        totalNominalAmount += invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CostCredit || invoiceLineNominalClient.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineNominalClient.InvoiceLineAmount : -invoiceLineNominalClient.InvoiceLineAmount;
                    }
                    decimal totalTaxAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum();
                    accountingDocumentLine.Amount            = totalNominalAmount >= 0 ? -invoiceInformation.SumOfInvoiceTotalAmount : invoiceInformation.SumOfInvoiceTotalAmount;
                    accountingDocumentLine.Amount            = accountingDocumentLine.Amount - totalTaxAmount;
                    accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.External ? (int)AccountLineType.V : (int)AccountLineType.C;
                    accountingDocumentLine.CostTypeCode      = invoiceInformation.InvoiceLines.FirstOrDefault(line => line.InvoiceLineAmount == invoiceInformation.InvoiceLines.Max(max => max.InvoiceLineAmount)).CostType;
                    accountingDocumentLine.Narrative         = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode);
                    accountingDocumentLine.AccountReference  = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.External ? accountingSetup.PurchaseLedgerControlClientCreditors : accountingSetup.SalesLedgerControlClientDebtors;
                    accountingDocumentLine.Quantity          = 0;
                }
                else if (invoiceFunction == InvoiceFunction.Washout)
                {
                    // [WASHOUT_E6] Well, this works only if the washout has only one match (ie only one purchase invoice, one sales invoice...), which is the case
                    // for E6 but which is not true for after e6...
                    InvoiceLinesDto invoiceLinePurchase = invoiceInformation.InvoiceLines.OrderBy(x => Math.Abs(x.InvoiceLineAmount)).FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialPurchase);
                    InvoiceLinesDto invoiceLineSale     = invoiceInformation.InvoiceLines.FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialSale);
                    decimal         totalNominalAmount  = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum();
                    decimal         totalTaxAmount      = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum();
                    accountingDocumentLine.ContractSectionCode = invoiceLinePurchase.PhysicalContractCode;
                    accountingDocumentLine.Quantity            = invoiceInformation.InvoiceLines.Where(x => x.Type == (int)Entities.ContractType.CommercialPurchase).Select(x => x.Quantity).Sum();
                    accountingDocumentLine.Amount = -(totalNominalAmount + totalTaxAmount);
                    //--change done as part of PBI-22258
                    accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.Inhouse ? (int)AccountLineType.C : (int)AccountLineType.V;
                    accountingDocumentLine.AccountReference  = accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.C ? accountingSetup.SalesLedgerControlClientDebtors : accountingSetup.PurchaseLedgerControlClientCreditors;
                    accountingDocumentLine.SectionId         = invoiceLinePurchase.SectionId;
                    accountingDocumentLine.CostTypeCode      = totalNominalAmount < 0 ? accountingSetup.WashoutInvoiceGains : accountingSetup.WashoutInvoiceLoss;
                }
                else if (invoiceFunction == InvoiceFunction.Cancelled)
                {
                    InvoiceLinesDto invoiceLine = invoiceInformation.InvoiceLines.FirstOrDefault();

                    decimal totalNominalAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum();
                    decimal totalTaxAmount     = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum();
                    accountingDocumentLine.ContractSectionCode = invoiceLine.PhysicalContractCode;
                    accountingDocumentLine.Quantity            = invoiceLine.Quantity;
                    accountingDocumentLine.Amount            = -(totalNominalAmount + totalTaxAmount);
                    accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.Inhouse ? (int)AccountLineType.C : (int)AccountLineType.V;
                    accountingDocumentLine.AccountReference  = accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.C ? accountingSetup.SalesLedgerControlClientDebtors : accountingSetup.PurchaseLedgerControlClientCreditors;
                    accountingDocumentLine.SectionId         = invoiceLine.SectionId;
                }
                else if (invoiceFunction == InvoiceFunction.GoodsAndCost)
                {
                    var     invoiceLinesGoods  = invoiceInformation.InvoiceLines.FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialPurchase || x.Type == (int)Entities.ContractType.CommercialSale);
                    var     invoiceLineCosts   = invoiceInformation.InvoiceLines.Where(x => x.CostDirectionId == (int)Entities.CostDirectionType.Pay || x.CostDirectionId == (int)Entities.CostDirectionType.Receive);
                    decimal totalNominalAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum();
                    decimal totalTaxAmount     = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum();
                    accountingDocumentLine.Quantity            = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(x => x.Quantity).Sum();
                    accountingDocumentLine.Amount              = -(totalNominalAmount + totalTaxAmount);
                    accountingDocumentLine.ContractSectionCode = latestSectionsInformation.ContractSectionCode;
                    accountingDocumentLine.SectionId           = latestSectionsInformation.SectionId;

                    if (invoiceLinesGoods != null)
                    {
                        accountingDocumentLine.AccountLineTypeId = invoiceLinesGoods.Type == (int)Entities.ContractType.CommercialPurchase ? (int)AccountLineType.V : (int)AccountLineType.C;
                        if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null)
                        {
                            accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode;
                        }
                    }
                    else if (invoiceLineCosts != null)
                    {
                        accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.External ? (int)AccountLineType.V : (int)AccountLineType.C;
                        if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null)
                        {
                            accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode;
                        }
                        else
                        {
                            accountingDocumentLine.CostTypeCode = invoiceLineCosts.FirstOrDefault(line => line.InvoiceLineAmount == invoiceLineCosts.Max(max => max.InvoiceLineAmount)).CostType;
                        }
                    }
                }

                break;

            case AccountingDocumentLineType.Tax:
                Vat     vat = vats.ToList()[index];
                decimal totalInvoiceAmount = invoiceInformation.InvoiceLines.Where(invoiceLine => invoiceLine.VATCode == vat.VatCode).Select(x => x.InvoiceTotalAmount).Sum();
                decimal totalQuantity      = invoiceInformation.InvoiceLines.Where(invoiceLine => invoiceLine.VATCode == vat.VatCode).Select(x => x.Quantity).Sum();
                accountingDocumentLine.PostingLineId        = postingLineId;
                accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.T;
                accountingDocumentLine.VATTurnover          = Math.Abs(accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum());
                accountingDocumentLine.AccountReference     = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? vat.InputAccount.Trim() : vat.OutputAccount.Trim();
                accountingDocumentLine.VATCode                    = vat.VatCode;
                accountingDocumentLine.CommodityId                = latestSectionsInformation.CommodityId;
                accountingDocumentLine.CharterId                  = latestSectionsInformation.CharterId;
                accountingDocumentLine.DepartmentId               = latestSectionsInformation.DepartmentId;
                accountingDocumentLine.ContractSectionCode        = latestSectionsInformation.ContractSectionCode;
                accountingDocumentLine.SectionId                  = latestSectionsInformation.SectionId;
                accountingDocumentLine.SecondaryDocumentReference = null;
                accountingDocumentLine.ClientAccount              = null;
                if (invoiceFunction == InvoiceFunction.Commercial)
                {
                    accountingDocumentLine.Quantity          = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? totalQuantity : -totalQuantity;
                    accountingDocumentLine.Amount            = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? totalInvoiceAmount : -totalInvoiceAmount;
                    accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L;
                    if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null)
                    {
                        accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode;
                    }
                }
                else if (invoiceFunction == InvoiceFunction.Cost)
                {
                    accountingDocumentLine.Quantity          = 0;
                    accountingDocumentLine.AccountReference  = totalInvoiceAmount >= 0 ? vat.InputAccount.Trim() : vat.OutputAccount.Trim();
                    accountingDocumentLine.Amount            = totalInvoiceAmount;
                    accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L;
                    accountingDocumentLine.CostTypeCode      = invoiceInformation.InvoiceLines.FirstOrDefault(line => line.InvoiceLineAmount == invoiceInformation.InvoiceLines.Max(max => max.InvoiceLineAmount)).CostType;
                    accountingDocumentLine.Narrative         = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode);
                }
                else if (invoiceFunction == InvoiceFunction.Washout)
                {
                    InvoiceLinesDto invoiceLinePurchase = invoiceInformation.InvoiceLines.OrderBy(x => Math.Abs(x.InvoiceLineAmount)).FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialPurchase);
                    InvoiceLinesDto invoiceLineSale     = invoiceInformation.InvoiceLines.FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialSale);

                    accountingDocumentLine.AccountReference    = totalInvoiceAmount >= 0 ? vat.InputAccount.Trim() : vat.OutputAccount.Trim();
                    accountingDocumentLine.ContractSectionCode = invoiceLinePurchase.PhysicalContractCode;
                    accountingDocumentLine.Quantity            = invoiceInformation.InvoiceLines.Where(x => x.Type == (int)Entities.ContractType.CommercialPurchase).Select(x => x.Quantity).Sum();
                    accountingDocumentLine.Amount            = totalInvoiceAmount;
                    accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L;
                    accountingDocumentLine.SectionId         = invoiceLinePurchase.SectionId;
                    accountingDocumentLine.SectionId         = invoiceLinePurchase.SectionId;
                    decimal totalNominalAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum();
                    decimal totalTaxAmount     = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum();
                    accountingDocumentLine.CostTypeCode = totalNominalAmount < 0 ? accountingSetup.WashoutInvoiceGains : accountingSetup.WashoutInvoiceLoss;
                }
                else if (invoiceFunction == InvoiceFunction.Cancelled)
                {
                    InvoiceLinesDto invoiceLine = invoiceInformation.InvoiceLines.FirstOrDefault();

                    accountingDocumentLine.AccountReference    = totalInvoiceAmount >= 0 ? vat.InputAccount.Trim() : vat.OutputAccount.Trim();
                    accountingDocumentLine.ContractSectionCode = invoiceLine.PhysicalContractCode;
                    accountingDocumentLine.Quantity            = invoiceLine.Quantity;
                    accountingDocumentLine.Amount            = 0;
                    accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L;
                    accountingDocumentLine.SectionId         = invoiceLine.SectionId;
                }
                else if (invoiceFunction == InvoiceFunction.GoodsAndCost)
                {
                    accountingDocumentLine.Quantity = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(x => x.Quantity).Sum();
                    accountingDocumentLine.Amount   = totalInvoiceAmount;
                    if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null)
                    {
                        accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode;
                    }

                    accountingDocumentLine.AccountReference    = totalInvoiceAmount >= 0 ? vat.InputAccount.Trim() : vat.OutputAccount.Trim();
                    accountingDocumentLine.AccountLineTypeId   = (int)AccountLineType.L;
                    accountingDocumentLine.ContractSectionCode = latestSectionsInformation.ContractSectionCode;
                    accountingDocumentLine.SectionId           = latestSectionsInformation.SectionId;
                }

                break;

            case AccountingDocumentLineType.Nominal:
                long                   sectionId          = invoiceInformation.InvoiceLines.ToList()[index].SectionId;
                InvoiceLinesDto        invoiceLineNominal = invoiceInformation.InvoiceLines.ToList()[index];
                SectionsInformationDto sectionInfo        = sectionsInformation.FirstOrDefault(section => section.SectionId == sectionId);
                decimal                invoiceLineAmount  = invoiceInformation.InvoiceLines.ToList()[index].InvoiceLineAmount;
                accountingDocumentLine.PostingLineId        = postingLineId;
                accountingDocumentLine.ContractSectionCode  = sectionInfo.ContractSectionCode;
                accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.N;
                accountingDocumentLine.VATTurnover          = null;
                accountingDocumentLine.CommodityId          = sectionInfo.CommodityId;
                accountingDocumentLine.VATCode             = invoiceInformation.InvoiceLines.ToList()[index].VATCode;
                accountingDocumentLine.AccountLineTypeId   = (int)AccountLineType.L;
                accountingDocumentLine.CharterId           = sectionInfo.CharterId;
                accountingDocumentLine.DepartmentId        = sectionInfo.DepartmentId;
                accountingDocumentLine.SectionId           = sectionInfo.SectionId;
                accountingDocumentLine.ClientAccount       = null;
                accountingDocumentLine.SourceInvoiceLineId = invoiceLineNominal.InvoiceLineId;
                if (invoiceFunction == InvoiceFunction.Commercial)
                {
                    if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.AccountReference != null && invoiceInformation.CostTypeCode != null)
                    {
                        accountingDocumentLine.AccountReference = invoiceInformation.AccountReference;
                        accountingDocumentLine.CostTypeCode     = invoiceInformation.CostTypeCode;
                    }
                    else
                    {
                        accountingDocumentLine.AccountReference = accountingSetup.NominalCostTypeInfo.Where(x => x.CostTypeCode == accountingDocumentLine.CostTypeCode).FirstOrDefault().NominalAccountCode;
                    }

                    accountingDocumentLine.Quantity = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? invoiceInformation.InvoiceLines.ToList()[index].Quantity : -invoiceInformation.InvoiceLines.ToList()[index].Quantity;
                    accountingDocumentLine.Amount   = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? invoiceLineAmount : -invoiceLineAmount;
                    if (invoiceLineNominal.CostDirectionId != null)
                    {
                        accountingDocumentLine.Amount = invoiceLineNominal.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineAmount : -invoiceLineAmount;
                    }
                    accountingDocumentLine.Narrative = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode);
                }
                else if (invoiceFunction == InvoiceFunction.Cost)
                {
                    accountingDocumentLine.AccountReference = invoiceInformation.InvoiceLines.ToList()[index].NominalAccount;
                    accountingDocumentLine.Quantity         = 0;
                    accountingDocumentLine.Amount           = invoiceLineNominal.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineAmount : -invoiceLineAmount;
                    accountingDocumentLine.Narrative        = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode);
                }
                else if (invoiceFunction == InvoiceFunction.Washout)
                {
                    if (invoiceInformation.InvoiceLines.ToList()[index].CostDirectionId != null)
                    {
                        accountingDocumentLine.AccountReference = invoiceInformation.InvoiceLines.ToList()[index].NominalAccount;
                    }
                    else
                    {
                        accountingDocumentLine.AccountReference = accountingSetup.NominalCostTypeInfo.Where(x => x.CostTypeCode == accountingDocumentLine.CostTypeCode).FirstOrDefault().NominalAccountCode;
                    }

                    accountingDocumentLine.Narrative = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode);

                    accountingDocumentLine.Quantity = invoiceLineNominal.Quantity;

                    if (invoiceLineNominal.CostDirectionId != null)
                    {
                        accountingDocumentLine.Amount = invoiceLineNominal.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineAmount : -invoiceLineAmount;
                    }
                    else
                    {
                        int             purchaseIndex       = index % 2 == 0 ? index + 1 : index - 1;
                        InvoiceLinesDto invoiceLinePurchase = invoiceInformation.InvoiceLines.ToList()[purchaseIndex];
                        InvoiceLinesDto invoiceLineSale     = invoiceInformation.InvoiceLines.ToList()[index];
                        accountingDocumentLine.Amount = invoiceLinePurchase.InvoiceLineAmount - invoiceLineSale.InvoiceLineAmount;
                    }
                }
                else if (invoiceFunction == InvoiceFunction.Cancelled)
                {
                    if (invoiceInformation.InvoiceLines.ToList()[index].CostDirectionId != null)
                    {
                        accountingDocumentLine.AccountReference = invoiceInformation.InvoiceLines.ToList()[index].NominalAccount;
                    }
                    else
                    {
                        accountingDocumentLine.AccountReference = accountingSetup.NominalCostTypeInfo.Where(x => x.CostTypeCode == accountingDocumentLine.CostTypeCode).FirstOrDefault().NominalAccountCode;
                    }

                    accountingDocumentLine.Narrative = invoiceInformation.ExternalReference;

                    accountingDocumentLine.Quantity = invoiceLineNominal.Quantity;
                    accountingDocumentLine.Amount   = invoiceInformation.TransactionDocumentTypeId == (int)DocumentType.CN ? invoiceInformation.SumOfInvoiceTotalAmount : -invoiceInformation.SumOfInvoiceTotalAmount;
                }
                else if (invoiceFunction == InvoiceFunction.GoodsAndCost)
                {
                    var invoiceLinesGoods = invoiceInformation.InvoiceLines.FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialPurchase || x.Type == (int)Entities.ContractType.CommercialSale);
                    var invoiceLineCosts  = invoiceInformation.InvoiceLines.Where(x => x.CostDirectionId == (int)Entities.CostDirectionType.Pay || x.CostDirectionId == (int)Entities.CostDirectionType.Receive);
                    if (invoiceLineNominal.CostDirectionId != null)
                    {
                        accountingDocumentLine.Amount   = invoiceLineNominal.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineAmount : -invoiceLineAmount;
                        accountingDocumentLine.Quantity = 0;
                        if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.AccountReference != null && invoiceInformation.CostTypeCode != null)
                        {
                            accountingDocumentLine.AccountReference = invoiceInformation.AccountReference;
                            accountingDocumentLine.CostTypeCode     = invoiceInformation.CostTypeCode;
                        }
                        else
                        {
                            accountingDocumentLine.AccountReference = invoiceLineNominal.NominalAccount;
                            accountingDocumentLine.CostTypeCode     = invoiceLineNominal.CostType;
                        }

                        accountingDocumentLine.Narrative = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, invoiceLineNominal.CostType);
                    }
                    else
                    {
                        // Binding the Account Reference associated with business sector if business sector posting is configured
                        if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.AccountReference != null && invoiceInformation.CostTypeCode != null)
                        {
                            accountingDocumentLine.AccountReference = invoiceInformation.AccountReference;
                            accountingDocumentLine.CostTypeCode     = invoiceInformation.CostTypeCode;
                        }
                        else
                        {
                            accountingDocumentLine.AccountReference = accountingSetup.NominalCostTypeInfo.Where(x => x.CostTypeCode == accountingDocumentLine.CostTypeCode).FirstOrDefault().NominalAccountCode;
                        }

                        accountingDocumentLine.Amount    = invoiceLineNominal.Type == (int)Entities.ContractType.CommercialPurchase ? invoiceLineAmount : -invoiceLineAmount;
                        accountingDocumentLine.Quantity  = invoiceLineNominal.Type == (int)Entities.ContractType.CommercialPurchase ? invoiceLineNominal.Quantity : -invoiceLineNominal.Quantity;
                        accountingDocumentLine.Narrative = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode);
                    }
                }

                break;

            default:
                throw new Exception("Unable to create document header and lines.");
            }

            accountingDocumentLine.Amount = Math.Round(accountingDocumentLine.Amount, CommonRules.RoundDecimals);

            decimal?amountInUSD = accountingDocumentLine.Amount;

            if (invoiceInformation.Currency != null && invoiceInformation.Currency.ToUpperInvariant() != "USD")
            {
                amountInUSD = (await _foreignExchangeRateService.Convert(fxRates.FxRateInvoiceCurrency.FxCurrency, CommonRules.BaseCurrency, accountingDocumentLine.Amount, fxRates.FxRateInvoiceCurrency.FxDate)).ConvertedValue;
            }

            await CommonRules.CalculateFunctionalAndStatutoryCurrency(_foreignExchangeRateService, accountingDocumentLine, amountInUSD, fxRates, company, CommonRules.BaseCurrency, CommonRules.RoundDecimals);

            return(accountingDocumentLine);
        }
        private async Task <IEnumerable <AccountingDocumentLine> > CreateAccountingDocumentLines(
            int docTypeId, Company company, AccountingSetupDto accountingSetup, FxRateInformation fxRates,
            IEnumerable <Vat> vats = null, InvoiceInformationDto invoiceInformation = null,
            IEnumerable <SectionsInformationDto> sectionsInformation = null, CashInformationDto cashInformation = null,
            ManualJournalDocumentDto manualJournal       = null, RevaluationInformationDto revalInformation     = null,
            MonthEndTADocumentDto monthEndTADocument     = null,
            FxSettlementDocumentDto fxSettlementDocument = null)
        {
            List <AccountingDocumentLine> accountingDocumentLines = new List <AccountingDocumentLine>();

            AccountingDocumentLine accountingDocumentLine;

            int postingLineId = 1;

            switch (docTypeId)
            {
            case (int)DocumentType.PI:
            case (int)DocumentType.SI:
            case (int)DocumentType.CN:
            case (int)DocumentType.DN:

                // Nominal
                InvoiceFunction invoiceFunction = CommonRules.CheckInvoiceType(invoiceInformation.InvoiceType);
                for (int index = 0; index < invoiceInformation.InvoiceLines.Count(); index++)
                {
                    if (invoiceFunction == InvoiceFunction.Washout)
                    {
                        if (invoiceInformation.InvoiceLines.ToList()[index].Type == (int)Entities.ContractType.CommercialSale)
                        {
                            // [WASHOUT_E6] For washout E6, we expect to have only one 1 to 1 washout (ie we must have only one line for a purchase
                            // contract, and one line for a sales contract)
                            // This rule is also implemented in UpdateAccountingDocumentStatusToPostedCommandHandler.CalculateAmountUpdatesForWashoutInvoice
                            accountingDocumentLine = await CreateAccountingDocumentLineForInvoice(AccountingDocumentLineType.Nominal, invoiceInformation, sectionsInformation, vats, company, accountingSetup, fxRates, postingLineId, index, null);

                            accountingDocumentLines.Add(accountingDocumentLine);
                            postingLineId++;
                        }
                    }
                    else if (invoiceFunction == InvoiceFunction.Cancelled)
                    {
                        accountingDocumentLine = await CreateAccountingDocumentLineForInvoice(AccountingDocumentLineType.Nominal, invoiceInformation, sectionsInformation, vats, company, accountingSetup, fxRates, postingLineId, index, null);

                        accountingDocumentLines.Add(accountingDocumentLine);
                        postingLineId++;
                    }
                    else
                    {
                        accountingDocumentLine = await CreateAccountingDocumentLineForInvoice(AccountingDocumentLineType.Nominal, invoiceInformation, sectionsInformation, vats, company, accountingSetup, fxRates, postingLineId, index, null);

                        accountingDocumentLines.Add(accountingDocumentLine);
                        postingLineId++;
                    }
                }

                // Tax
                for (int index = 0; index < vats.Count(); index++)
                {
                    accountingDocumentLine = await CreateAccountingDocumentLineForInvoice(AccountingDocumentLineType.Tax, invoiceInformation, sectionsInformation, vats, company, accountingSetup, fxRates, postingLineId, index, accountingDocumentLines);

                    accountingDocumentLines.Add(accountingDocumentLine);
                    postingLineId++;
                }

                // Client
                accountingDocumentLine = await CreateAccountingDocumentLineForInvoice(AccountingDocumentLineType.Client, invoiceInformation, sectionsInformation, vats, company, accountingSetup, fxRates, postingLineId, 0, accountingDocumentLines);

                accountingDocumentLine.SourceInvoiceId = invoiceInformation.InvoiceId;
                accountingDocumentLines.Add(accountingDocumentLine);

                break;

            case (int)DocumentType.CP:
            case (int)DocumentType.CI:

                AccountingDocumentLine accountingDocumentLineForDocumentReference = new AccountingDocumentLine();

                accountingDocumentLine = await CreateAccountingDocumentLineForSimpleCash(AccountingDocumentLineType.Client, docTypeId, cashInformation, company, fxRates, postingLineId, accountingSetup);

                // Note: this is here for simple cash. There is no secondary reference, as at that time, the cash is no matched...
                accountingDocumentLines.Add(accountingDocumentLine);

                // Nominal
                postingLineId++;
                accountingDocumentLine = await CreateAccountingDocumentLineForSimpleCash(AccountingDocumentLineType.Nominal, docTypeId, cashInformation, company, fxRates, postingLineId, accountingSetup);

                accountingDocumentLines.Add(accountingDocumentLine);

                if (cashInformation.AdditionalCosts != null && cashInformation.AdditionalCosts.Any())
                {
                    for (int index = 0; index < cashInformation.AdditionalCosts.Count(); index++)
                    {
                        postingLineId++;
                        AccountingDocumentLine accountingDocumentLineForAdditionalCosts = new AccountingDocumentLine();
                        AdditionalCostsDto     additionalCostsDto = cashInformation.AdditionalCosts.ToList()[index];
                        accountingDocumentLineForAdditionalCosts.PostingLineId         = postingLineId;
                        accountingDocumentLineForAdditionalCosts.AccountLineTypeId     = (int)AccountLineType.L;
                        accountingDocumentLineForAdditionalCosts.Amount                = additionalCostsDto.CostDirectionId == (int)Entities.CostDirectionType.Pay ? cashInformation.AdditionalCosts.ToList()[index].Amount : -cashInformation.AdditionalCosts.ToList()[index].Amount;
                        accountingDocumentLineForAdditionalCosts.AccountReference      = additionalCostsDto.AccountReference;
                        accountingDocumentLineForAdditionalCosts.CostTypeCode          = additionalCostsDto.CostTypeCode;
                        accountingDocumentLineForAdditionalCosts.AssociatedAccountCode = accountingDocumentLine.AssociatedAccountCode;
                        accountingDocumentLineForAdditionalCosts.DepartmentId          = accountingDocumentLine.DepartmentId;
                        accountingDocumentLineForAdditionalCosts.Narrative             = additionalCostsDto.Narrative;
                        accountingDocumentLineForAdditionalCosts.AccountingCategoryId  = (int)AccountingCategory.N;
                        accountingDocumentLineForAdditionalCosts.Amount                = Math.Round(accountingDocumentLineForAdditionalCosts.Amount, CommonRules.RoundDecimals);
                        accountingDocumentLineForAdditionalCosts.ClientAccount         = null;
                        accountingDocumentLineForAdditionalCosts.SourceCostLineId      = cashInformation.AdditionalCosts.ToList()[index].CashAdditionalCostId;
                        decimal?amountInUSD = accountingDocumentLineForAdditionalCosts.Amount;

                        if (additionalCostsDto.CurrencyCode != null && additionalCostsDto.CurrencyCode.ToUpperInvariant() != CommonRules.BaseCurrency)
                        {
                            amountInUSD = (await _foreignExchangeRateService.Convert(additionalCostsDto.CurrencyCode, CommonRules.BaseCurrency, accountingDocumentLineForAdditionalCosts.Amount, cashInformation.DocumentDate)).ConvertedValue;
                        }

                        accountingDocumentLineForAdditionalCosts = await CommonRules.CalculateFunctionalAndStatutoryCurrency(_foreignExchangeRateService, accountingDocumentLineForAdditionalCosts, amountInUSD, fxRates, company, CommonRules.BaseCurrency, CommonRules.RoundDecimals);

                        accountingDocumentLines.Add(accountingDocumentLineForAdditionalCosts);
                    }
                }

                break;

            case (int)DocumentType.MJL:
                foreach (ManualJournalLineDto manualJournalLine in manualJournal.ManualJournalLines)
                {
                    accountingDocumentLine = await CreateAccountingDocumentLineForManualJournal(docTypeId, company, manualJournal, fxRates, manualJournalLine, postingLineId, accountingSetup);

                    accountingDocumentLines.Add(accountingDocumentLine);
                    postingLineId++;
                }

                break;

            case (int)DocumentType.MTA:

                if (manualJournal != null && (manualJournal.TATypeId == (int)TAType.ManualTemporaryAdjustment || manualJournal.TATypeId == (int)TAType.ManualMarkToMarket))
                {
                    IEnumerable <ManualJournalLineDto> manualJournalLines = manualJournal.ManualJournalLines.OrderBy(x => x.AccrualNumber);

                    int?previousAccuralNumber = manualJournal.ManualJournalLines.FirstOrDefault().AccrualNumber;

                    foreach (ManualJournalLineDto manualJournalLine in manualJournalLines)
                    {
                        if (previousAccuralNumber != manualJournalLine.AccrualNumber)
                        {
                            postingLineId         = 1;
                            previousAccuralNumber = manualJournalLine.AccrualNumber;
                        }

                        accountingDocumentLine = await CreateAccountingDocumentLineForManualJournal(docTypeId, company, manualJournal, fxRates, manualJournalLine, postingLineId, accountingSetup);

                        accountingDocumentLines.Add(accountingDocumentLine);

                        if (previousAccuralNumber == manualJournalLine.AccrualNumber)
                        {
                            postingLineId++;
                        }

                        previousAccuralNumber = manualJournalLine.AccrualNumber;
                    }
                }

                else if (monthEndTADocument != null && (monthEndTADocument.TATypeId == (int)TAType.MonthEndTemporaryAdjustment || monthEndTADocument.TATypeId == (int)TAType.FxDealMonthTemporaryAdjustment))
                {
                    IEnumerable <MonthEndTALineDto> monthEndLines = monthEndTADocument.MonthEndTALines.OrderBy(x => x.AccrualNumber);

                    foreach (MonthEndTALineDto monthEndLine in monthEndLines)
                    {
                        accountingDocumentLine = await CreateAccountingDocumentLineForMonthEndTA(docTypeId, company, monthEndTADocument, fxRates, monthEndLine, postingLineId);

                        if (monthEndTADocument.TATypeId == (int)TAType.FxDealMonthTemporaryAdjustment)
                        {
                            postingLineId++;
                            accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.N;
                            accountingDocumentLine.AccountLineTypeId    = (int)AccountLineType.L;
                        }

                        accountingDocumentLines.Add(accountingDocumentLine);
                    }
                }

                break;

            case (int)DocumentType.FJ:
                accountingDocumentLine = await CreateAccountingDocumentLineForFJDocument(docTypeId, postingLineId, accountingSetup, AccountLineType.B, company, fxRates, fxSettlementDocument);

                accountingDocumentLines.Add(accountingDocumentLine);
                postingLineId++;

                accountingDocumentLine = await CreateAccountingDocumentLineForFJDocument(docTypeId, postingLineId, accountingSetup, AccountLineType.L, company, fxRates, fxSettlementDocument);

                accountingDocumentLines.Add(accountingDocumentLine);
                break;
            }

            return(accountingDocumentLines);
        }