private async Task <AccountingDocument> CreateAccountingDocumentForFxDeal(bool postOpClosedPolicy, long docId, int docTypeId, AccountingSetupDto accountingSetup, Company company, string companyId, DateTime companyDate)
        {
            AccountingDocument      accountingDocument   = new AccountingDocument();
            FxSettlementDocumentDto fxSettlementDocument = null;
            FxRateInformation       fxRates = null;

            fxSettlementDocument = await _accountingQueries.GetFxSettlementbyTransactionDocumentId(docId, company.CompanyId);

            if (fxSettlementDocument.FxSettlementDocumentTypeId == FxSettlementDocumentType.FxDeal)
            {
                fxRates = CommonRules.GetFxRateInformation(fxSettlementDocument.DocumentDate, fxSettlementDocument.CurrencyCode, company);
            }
            else
            {
                fxRates = CommonRules.GetFxRateInformation(fxSettlementDocument.DocumentDate, fxSettlementDocument.SettlementCurrencyCode, company);
            }

            if (fxSettlementDocument != null && fxRates.AreAllFilled())
            {
                accountingDocument = await CommonRules.CreateAccountingDocument(_masterDataService, _identityService.GetUserAtlasId(), postOpClosedPolicy, docId, docTypeId, CommonRules.BaseCurrency, fxRates.FxRateInvoiceCurrency, accountingSetup, null, null, null, null, null, null, null, null, fxSettlementDocument);

                accountingDocument.AccountingPeriod = CommonRules.CalculateAccountPeriod(accountingSetup, fxSettlementDocument.DocumentDate, postOpClosedPolicy);
                accountingDocument.AccrualNumber    = CommonRules.IsLastMonthForOperationOpen(accountingSetup.LastMonthClosedForOperation, fxSettlementDocument.DocumentDate) ?
                                                      fxSettlementDocument.AccrualNumber :
                                                      null;
                accountingDocument.AccountingDate = accountingDocument.DocumentDate.Year == accountingDocument.AccountingPeriod.Year &&
                                                    accountingDocument.DocumentDate.Month == accountingDocument.AccountingPeriod.Month ?
                                                    accountingDocument.DocumentDate :
                                                    new DateTime(accountingDocument.AccountingPeriod.Year, accountingDocument.AccountingPeriod.Month, 1);

                if (accountingDocument != null)
                {
                    accountingDocument.AccountingDocumentLines = await CreateAccountingDocumentLines(docTypeId, company, accountingSetup, fxRates, null, null, null, null, null, null, null, fxSettlementDocument);

                    accountingDocument.StatusId = await CommonRules.GetAccountingDocumentStatus(accountingSetup, _accountingQueries, accountingDocument, company.CompanyId, companyDate, null, null);
                }
            }

            return(accountingDocument);
        }
Example #2
0
        internal static FxRateInformation GetFxRateInformation(DateTime blDate, string currency, Company company)
        {
            var fxRateInvoiceCurrencyCode = new FxRateConversion
            {
                FxDate     = blDate,
                FxCurrency = currency
            };

            var fxRateStatutoryCurrencyCode = new FxRateConversion
            {
                FxDate     = blDate,
                FxCurrency = company.StatutoryCurrencyCode
            };

            var fxRateFunctionalCurrencyCode = new FxRateConversion
            {
                FxDate     = blDate,
                FxCurrency = company.FunctionalCurrencyCode
            };

            FxRateInformation fxRateInformation = new FxRateInformation(fxRateInvoiceCurrencyCode, fxRateStatutoryCurrencyCode, fxRateFunctionalCurrencyCode);

            return(fxRateInformation);
        }
        private async Task <AccountingDocumentLine> CreateAccountingDocumentLineForSimpleCash(
            AccountingDocumentLineType accountingDocumentLineType, int docTypeId, CashInformationDto cashInformation,
            Company company, FxRateInformation fxRates, int postingLineId, AccountingSetupDto accountingSetup)
        {
            AccountingDocumentLine accountingDocumentLine = new AccountingDocumentLine();

            accountingDocumentLine.SecondaryDocumentReference = cashInformation.CounterpartyDocumentReference;
            accountingDocumentLine.CostTypeCode          = cashInformation.CostTypeCode;
            accountingDocumentLine.AssociatedAccountCode = cashInformation.CounterpartyCode;
            accountingDocumentLine.ClientReference       = null;
            accountingDocumentLine.PaymentTermCode       = null;
            accountingDocumentLine.ContractSectionCode   = null;
            accountingDocumentLine.VATTurnover           = null;
            accountingDocumentLine.CommodityId           = null;
            accountingDocumentLine.VATCode      = null;
            accountingDocumentLine.CharterId    = cashInformation.CharterId;
            accountingDocumentLine.DepartmentId = cashInformation.DepartmentId;
            accountingDocumentLine.Quantity     = 0;
            accountingDocumentLine.SectionId    = null;

            decimal totalCostAmountForClient = 0;

            if (cashInformation.AdditionalCosts != null && cashInformation.AdditionalCosts.Any())
            {
                foreach (var additionalCostsDto in cashInformation.AdditionalCosts.ToList())
                {
                    totalCostAmountForClient += additionalCostsDto.CostDirectionId == (int)CostDirectionType.Pay ? additionalCostsDto.Amount : -additionalCostsDto.Amount;
                }
            }

            switch (accountingDocumentLineType)
            {
            case AccountingDocumentLineType.Client:
                // in the case of a simple cash, the cash contains one unique line
                // with the amount corresponding to the amount exchanged with the customer
                // Note that this amount is different from the value of Cash.Amount in the case of a
                // Cash receipt (CI), as the costs are included in the client amount
                //
                // The calculation below duplicates the rule written in
                // CreateCashCommandHandler.GenerateCashLineForSimpleCash for the calculation of the cash line
                if (docTypeId == (int)DocumentType.CP)
                {
                    accountingDocumentLine.Amount = cashInformation.Amount;
                }
                else
                {
                    accountingDocumentLine.Amount = -(cashInformation.Amount + totalCostAmountForClient);
                }

                accountingDocumentLine.PostingLineId        = postingLineId;
                accountingDocumentLine.Narrative            = cashInformation.Narrative;
                accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.C;
                accountingDocumentLine.AccountLineTypeId    = docTypeId == (int)DocumentType.CP ? (int)AccountLineType.V : (int)AccountLineType.C;
                accountingDocumentLine.AccountReference     = accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.V ? accountingSetup.PurchaseLedgerControlClientCreditors : accountingSetup.SalesLedgerControlClientDebtors;
                accountingDocumentLine.ClientAccount        = cashInformation.CounterpartyCode;
                break;

            case AccountingDocumentLineType.Nominal:
                // Creation of the Bank accounting line
                if (docTypeId == (int)DocumentType.CP)
                {
                    accountingDocumentLine.Amount = -(cashInformation.Amount + totalCostAmountForClient);
                }
                else
                {
                    // In the case of a CI (cash receipt), the costs are integrated in the client line
                    // => not to be integrated in the bank line
                    accountingDocumentLine.Amount = cashInformation.Amount;
                }

                accountingDocumentLine.PostingLineId        = postingLineId;
                accountingDocumentLine.Narrative            = cashInformation.Payee;
                accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.N;
                accountingDocumentLine.AccountReference     = cashInformation.NominalAccount;
                accountingDocumentLine.AccountLineTypeId    = (int)AccountLineType.B;
                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 (cashInformation.Currency != null && cashInformation.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> > CreateAccountingDocumentLineForCashPaidCashInAnotherCcy(int docTypeId, Company company, FxRateInformation fxRates, AccountingSetupDto accountingSetup, CashInformationDto cashInformation, CashInformationDto paidCashInformation)
        {
            List <AccountingDocumentLine> accountingDocumentLines = new List <AccountingDocumentLine>();

            int postingLineId = 1;

            // To make the accounting lines' sum equal to 0
            int directionFactor = CommonRules.CalculateDirectionFactorForClientLines(cashInformation);

            // Create the ledger line representing the payment in the cash effective currency
            AccountingDocumentLine accountingDocumentLineForPayment = new AccountingDocumentLine();

            accountingDocumentLineForPayment.AssociatedAccountCode = cashInformation.CounterpartyCode;
            accountingDocumentLineForPayment.ClientAccount         = cashInformation.CounterpartyCode;
            accountingDocumentLineForPayment.ClientReference       = null;
            accountingDocumentLineForPayment.PaymentTermCode       = null;
            accountingDocumentLineForPayment.ContractSectionCode   = null;
            accountingDocumentLineForPayment.VATTurnover           = null;
            accountingDocumentLineForPayment.VATCode      = null;
            accountingDocumentLineForPayment.CharterId    = cashInformation.CharterId;
            accountingDocumentLineForPayment.DepartmentId = cashInformation.DepartmentId;

            accountingDocumentLineForPayment.CommodityId          = null;
            accountingDocumentLineForPayment.Quantity             = 0;
            accountingDocumentLineForPayment.SectionId            = null;
            accountingDocumentLineForPayment.PostingLineId        = postingLineId;
            accountingDocumentLineForPayment.Narrative            = cashInformation.Payee;
            accountingDocumentLineForPayment.AccountingCategoryId = (int)AccountingCategory.N;
            accountingDocumentLineForPayment.AccountLineTypeId    = (int)AccountLineType.L;
            accountingDocumentLineForPayment.ClientAccount        = cashInformation.CounterpartyCode;

            // all the lines of this cash must have the reference of the "matching cash"
            accountingDocumentLineForPayment.SecondaryDocumentReference = paidCashInformation.CashDocRef;

            accountingDocumentLineForPayment.Amount = directionFactor * paidCashInformation.Amount;

            // Use the nominal account & cost type configured for the company
            accountingDocumentLineForPayment.AccountReference = accountingSetup.FXRevalaccount;
            accountingDocumentLineForPayment.CostTypeCode     = accountingSetup.FXReval;

            var cashMatchingTotal = accountingDocumentLineForPayment.Amount;

            await CommonRules.CalculateFunctionalAndStatutoryCurrency(_foreignExchangeRateService, accountingDocumentLineForPayment, cashMatchingTotal, fxRates, company, CommonRules.BaseCurrency, CommonRules.RoundDecimals);

            postingLineId++;

            accountingDocumentLines.Add(accountingDocumentLineForPayment);

            decimal totalCostAmountForClient = 0;

            // The cost, on a « L » line (one line per CostType) => sum (per costType) in cash currency
            if (paidCashInformation.AdditionalCosts != null && paidCashInformation.AdditionalCosts.Any())
            {
                foreach (var additionalCostsDto in paidCashInformation.AdditionalCosts.ToList())
                {
                    totalCostAmountForClient += additionalCostsDto.CostDirectionId == (int)CostDirectionType.Pay ? additionalCostsDto.Amount : -additionalCostsDto.Amount;

                    AccountingDocumentLine accountingDocumentLineForAdditionalCosts = new AccountingDocumentLine();

                    accountingDocumentLineForAdditionalCosts.PostingLineId         = postingLineId;
                    accountingDocumentLineForAdditionalCosts.AccountLineTypeId     = (int)AccountLineType.L;
                    accountingDocumentLineForAdditionalCosts.AccountReference      = additionalCostsDto.AccountReference;
                    accountingDocumentLineForAdditionalCosts.CostTypeCode          = additionalCostsDto.CostTypeCode;
                    accountingDocumentLineForAdditionalCosts.AssociatedAccountCode = null;
                    accountingDocumentLineForAdditionalCosts.DepartmentId          = paidCashInformation.DepartmentId;
                    accountingDocumentLineForAdditionalCosts.Narrative             = additionalCostsDto.Narrative;
                    accountingDocumentLineForAdditionalCosts.AccountingCategoryId  = (int)AccountingCategory.N;
                    accountingDocumentLineForAdditionalCosts.ClientAccount         = additionalCostsDto.ClientAccountCode;
                    accountingDocumentLineForAdditionalCosts.ClientAccountId       = additionalCostsDto.ClientAccountId;
                    accountingDocumentLineForAdditionalCosts.CommodityId           = null;
                    accountingDocumentLineForAdditionalCosts.ClientReference       = null;
                    accountingDocumentLineForAdditionalCosts.CharterId             = paidCashInformation.CharterId;
                    accountingDocumentLineForAdditionalCosts.SourceCostLineId      = additionalCostsDto.CashAdditionalCostId;

                    // the sign of the accounting line representing the cost depends on the cost type (payable / receivable)
                    accountingDocumentLineForAdditionalCosts.Amount = Math.Round(
                        additionalCostsDto.CostDirectionId == (int)CostDirectionType.Pay
                        ? additionalCostsDto.Amount
                        : -additionalCostsDto.Amount, CommonRules.RoundDecimals);

                    // all the lines of this cash must have the reference of the "matching cash"
                    accountingDocumentLineForAdditionalCosts.SecondaryDocumentReference = paidCashInformation.CashDocRef;

                    decimal?additionalCostAmount = accountingDocumentLineForAdditionalCosts.Amount;

                    if (additionalCostsDto.CurrencyCode != null && additionalCostsDto.CurrencyCode.ToUpperInvariant() != CommonRules.BaseCurrency)
                    {
                        additionalCostAmount = (await _foreignExchangeRateService.Convert(fxRates.FxRateInvoiceCurrency.FxCurrency, CommonRules.BaseCurrency, (decimal)additionalCostAmount, fxRates.FxRateInvoiceCurrency.FxDate)).ConvertedValue;
                    }

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

                    postingLineId++;

                    accountingDocumentLines.Add(accountingDocumentLineForAdditionalCosts);
                }
            }

            // Bank Line for Cash Document
            AccountingDocumentLine accountingDocumentLineForBank = new AccountingDocumentLine();

            accountingDocumentLineForBank.CostTypeCode          = cashInformation.CostTypeCode;
            accountingDocumentLineForBank.AssociatedAccountCode = cashInformation.CounterpartyCode;
            accountingDocumentLineForBank.ClientAccount         = cashInformation.CounterpartyCode;
            accountingDocumentLineForBank.ClientReference       = null;
            accountingDocumentLineForBank.PaymentTermCode       = null;
            accountingDocumentLineForBank.ContractSectionCode   = null;
            accountingDocumentLineForBank.VATTurnover           = null;
            accountingDocumentLineForBank.VATCode      = null;
            accountingDocumentLineForBank.CharterId    = cashInformation.CharterId;
            accountingDocumentLineForBank.DepartmentId = cashInformation.DepartmentId;

            // all the lines of this cash must have the reference of the "matching cash"
            accountingDocumentLineForBank.SecondaryDocumentReference = paidCashInformation.CashDocRef;

            accountingDocumentLineForBank.CommodityId          = null;
            accountingDocumentLineForBank.Quantity             = 0;
            accountingDocumentLineForBank.SectionId            = null;
            accountingDocumentLineForBank.PostingLineId        = postingLineId;
            accountingDocumentLineForBank.Narrative            = cashInformation.Payee;
            accountingDocumentLineForBank.AccountingCategoryId = (int)AccountingCategory.N;
            accountingDocumentLineForBank.AccountReference     = cashInformation.NominalAccount;
            accountingDocumentLineForBank.AccountLineTypeId    = (int)AccountLineType.B;

            accountingDocumentLineForBank.Amount = (-1) * (cashMatchingTotal + totalCostAmountForClient);
            decimal?bankLineAmount = accountingDocumentLineForBank.Amount;

            if (cashInformation.Currency != null && cashInformation.Currency.ToUpperInvariant() != CommonRules.BaseCurrency)
            {
                bankLineAmount = (await _foreignExchangeRateService.Convert(cashInformation.Currency, CommonRules.BaseCurrency, (decimal)bankLineAmount, fxRates.FxRateInvoiceCurrency.FxDate)).ConvertedValue;
            }

            accountingDocumentLineForBank = await CommonRules.CalculateFunctionalAndStatutoryCurrency(_foreignExchangeRateService, accountingDocumentLineForBank, bankLineAmount, fxRates, company, CommonRules.BaseCurrency, CommonRules.RoundDecimals);

            postingLineId++;
            accountingDocumentLines.Add(accountingDocumentLineForBank);

            return(accountingDocumentLines);
        }
        private async Task <IEnumerable <AccountingDocumentLine> > CreateAccountingDocumentLinesForCashPickingTransaction(int docTypeId, Company company, FxRateInformation fxRates, AccountingSetupDto accountingSetup, CashInformationDto cashInformation)
        {
            List <AccountingDocumentLine> accountingDocumentLines = new List <AccountingDocumentLine>();

            int postingLineId = 1;

            // To make the accounting lines' sum equal to 0
            int directionFactor = CommonRules.CalculateDirectionFactorForClientLines(cashInformation);

            // Create one client line per cash line
            foreach (var cashline in cashInformation.CashLines)
            {
                var documentMatchingForSourceDocument = cashInformation.DocumentMatchingsForCashByPicking.Where(d => d.MatchedCashLineId == cashline.CashLineId).FirstOrDefault();

                // ClientLine For cash document
                AccountingDocumentLine accountingDocumentLineForClient = new AccountingDocumentLine();
                accountingDocumentLineForClient.CostTypeCode          = cashInformation.CostTypeCode;
                accountingDocumentLineForClient.AssociatedAccountCode = cashInformation.PaymentCounterpartyCode == null ? cashInformation.CounterpartyCode : cashInformation.PaymentCounterpartyCode;
                accountingDocumentLineForClient.ClientReference       = null;
                accountingDocumentLineForClient.PaymentTermCode       = null;
                accountingDocumentLineForClient.ContractSectionCode   = null;
                accountingDocumentLineForClient.VATTurnover           = null;
                accountingDocumentLineForClient.VATCode              = null;
                accountingDocumentLineForClient.CharterId            = cashInformation.CharterId;
                accountingDocumentLineForClient.DepartmentId         = cashline.DepartmentId;
                accountingDocumentLineForClient.CommodityId          = null;
                accountingDocumentLineForClient.Quantity             = 0;
                accountingDocumentLineForClient.SectionId            = null;
                accountingDocumentLineForClient.PostingLineId        = postingLineId;
                accountingDocumentLineForClient.Narrative            = cashInformation.Narrative;
                accountingDocumentLineForClient.AccountingCategoryId = (int)AccountingCategory.C;
                accountingDocumentLineForClient.AccountLineTypeId    = (int)cashline.TransactionDirectionId;
                accountingDocumentLineForClient.AccountReference     = accountingDocumentLineForClient.AccountLineTypeId == (int)AccountLineType.V ? accountingSetup.PurchaseLedgerControlClientCreditors : accountingSetup.SalesLedgerControlClientDebtors;
                accountingDocumentLineForClient.Amount = directionFactor * cashline.Amount.Value;

                // In case of diff Client, the accounting line should have the payee as Client Account
                if (cashInformation.CashTypeId == (int)CashSelectionType.PaymentDifferentClient)
                {
                    if (cashInformation.SecondaryReferencesForCashByPicking != null && cashInformation.SecondaryReferencesForCashByPicking.Any())
                    {
                        accountingDocumentLineForClient.SecondaryDocumentReference = cashInformation.SecondaryReferencesForCashByPicking.First().DocumentReference;
                    }
                    else
                    {
                        accountingDocumentLineForClient.SecondaryDocumentReference = documentMatchingForSourceDocument == null ? null : documentMatchingForSourceDocument.DocumentReference;
                    }

                    accountingDocumentLineForClient.ClientAccount = cashInformation.PaymentCounterpartyCode;
                }
                else if (cashInformation.CashTypeId == (int)CashSelectionType.PaymentDifferentCurrency || cashInformation.CashTypeId == (int)CashSelectionType.ReceiptDifferentCurrency)
                {
                    var matchedDocument = cashInformation.DocumentMatchingsForCashByPicking.FirstOrDefault(dm => dm.MatchedCashLineId.HasValue && dm.MatchedCashLineId.Value == cashline.CashLineId);
                    accountingDocumentLineForClient.SecondaryDocumentReference = matchedDocument?.DocumentReference;
                    accountingDocumentLineForClient.ClientAccount = cashInformation.CounterpartyCode;
                }
                else
                {
                    accountingDocumentLineForClient.SecondaryDocumentReference = documentMatchingForSourceDocument == null ? null : documentMatchingForSourceDocument.DocumentReference;
                    accountingDocumentLineForClient.ClientAccount = cashInformation.CounterpartyCode;
                }

                // Updating the referenced IDs
                accountingDocumentLineForClient.SourceCashLineId    = cashline.CashLineId;
                accountingDocumentLineForClient.SourceJournalLineId = null;
                accountingDocumentLineForClient.SourceInvoiceId     = null;

                decimal?amountInUSD = accountingDocumentLineForClient.Amount;
                if (cashInformation.Currency != null && cashInformation.Currency.ToUpperInvariant() != CommonRules.BaseCurrency)
                {
                    amountInUSD = (await _foreignExchangeRateService.Convert(fxRates.FxRateInvoiceCurrency.FxCurrency, CommonRules.BaseCurrency, (decimal)amountInUSD, fxRates.FxRateInvoiceCurrency.FxDate)).ConvertedValue;
                }

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

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

            var cashMatchingTotal = cashInformation.CashLines.Sum(s => s.Amount);

            // Nominal Line for Cash Document
            decimal totalCostAmountForClient = 0;

            if (cashInformation.AdditionalCosts != null && cashInformation.AdditionalCosts.Any())
            {
                foreach (var additionalCostsDto in cashInformation.AdditionalCosts.ToList())
                {
                    totalCostAmountForClient += additionalCostsDto.CostDirectionId == (int)CostDirectionType.Pay ? additionalCostsDto.Amount : -additionalCostsDto.Amount;

                    AccountingDocumentLine accountingDocumentLineForAdditionalCosts = new AccountingDocumentLine();

                    accountingDocumentLineForAdditionalCosts.PostingLineId         = postingLineId;
                    accountingDocumentLineForAdditionalCosts.AccountLineTypeId     = additionalCostsDto.AccountLineTypeId ?? (int)AccountLineType.L;
                    accountingDocumentLineForAdditionalCosts.AccountReference      = additionalCostsDto.AccountReference;
                    accountingDocumentLineForAdditionalCosts.CostTypeCode          = additionalCostsDto.CostTypeCode;
                    accountingDocumentLineForAdditionalCosts.AssociatedAccountCode = additionalCostsDto.ClientAccountCode;
                    accountingDocumentLineForAdditionalCosts.DepartmentId          = cashInformation.DepartmentId;
                    accountingDocumentLineForAdditionalCosts.Narrative             = additionalCostsDto.Narrative;
                    accountingDocumentLineForAdditionalCosts.AccountingCategoryId  = (int)AccountingCategory.N;
                    accountingDocumentLineForAdditionalCosts.ClientAccount         = additionalCostsDto.ClientAccountCode;
                    accountingDocumentLineForAdditionalCosts.ClientAccountId       = additionalCostsDto.ClientAccountId;
                    accountingDocumentLineForAdditionalCosts.CommodityId           = null;
                    accountingDocumentLineForAdditionalCosts.ClientReference       = null;
                    accountingDocumentLineForAdditionalCosts.CharterId             = cashInformation.CharterId;
                    accountingDocumentLineForAdditionalCosts.SourceCostLineId      = additionalCostsDto.CashAdditionalCostId;

                    // the sign of the accounting line representing the cost depends on the cost type (payable / receivable )
                    accountingDocumentLineForAdditionalCosts.Amount = Math.Round(
                        additionalCostsDto.CostDirectionId == (int)CostDirectionType.Pay
                        ? additionalCostsDto.Amount
                        : -additionalCostsDto.Amount, CommonRules.RoundDecimals);

                    if (cashInformation.SecondaryReferencesForCashByPicking != null && cashInformation.SecondaryReferencesForCashByPicking.Any())
                    {
                        var docreference = cashInformation.SecondaryReferencesForCashByPicking.FirstOrDefault();
                        accountingDocumentLineForAdditionalCosts.SecondaryDocumentReference = docreference.DocumentReference;
                    }

                    decimal?additionalCostAmount = accountingDocumentLineForAdditionalCosts.Amount;

                    if (additionalCostsDto.CurrencyCode != null && additionalCostsDto.CurrencyCode.ToUpperInvariant() != CommonRules.BaseCurrency)
                    {
                        additionalCostAmount = (await _foreignExchangeRateService.Convert(fxRates.FxRateInvoiceCurrency.FxCurrency, CommonRules.BaseCurrency, (decimal)additionalCostAmount, fxRates.FxRateInvoiceCurrency.FxDate)).ConvertedValue;
                    }

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

                    postingLineId++;

                    accountingDocumentLines.Add(accountingDocumentLineForAdditionalCosts);
                }
            }

            // Bank Line for Cash Document
            AccountingDocumentLine accountingDocumentLineForBank = new AccountingDocumentLine();

            accountingDocumentLineForBank.AssociatedAccountCode = cashInformation.PaymentCounterpartyCode == null ? cashInformation.CounterpartyCode : cashInformation.PaymentCounterpartyCode;
            accountingDocumentLineForBank.ClientAccount         = cashInformation.PaymentCounterpartyCode == null ? cashInformation.CounterpartyCode : cashInformation.PaymentCounterpartyCode;
            accountingDocumentLineForBank.ClientReference       = null;
            accountingDocumentLineForBank.PaymentTermCode       = null;
            accountingDocumentLineForBank.ContractSectionCode   = null;
            accountingDocumentLineForBank.VATTurnover           = null;
            accountingDocumentLineForBank.VATCode      = null;
            accountingDocumentLineForBank.CharterId    = cashInformation.CharterId;
            accountingDocumentLineForBank.DepartmentId = cashInformation.DepartmentId;
            if (cashInformation.SecondaryReferencesForCashByPicking != null && cashInformation.SecondaryReferencesForCashByPicking.Any())
            {
                accountingDocumentLineForBank.SecondaryDocumentReference = cashInformation.SecondaryReferencesForCashByPicking.First().DocumentReference;
            }

            accountingDocumentLineForBank.CommodityId          = null;
            accountingDocumentLineForBank.Quantity             = 0;
            accountingDocumentLineForBank.SectionId            = null;
            accountingDocumentLineForBank.PostingLineId        = postingLineId;
            accountingDocumentLineForBank.Narrative            = cashInformation.Payee;
            accountingDocumentLineForBank.AccountingCategoryId = (int)AccountingCategory.N;

            if (cashInformation.MatchingCCY == null && (cashInformation.CashTypeId == (int)CashSelectionType.PaymentDifferentCurrency || cashInformation.CashTypeId == (int)CashSelectionType.ReceiptDifferentCurrency))
            {
                // Use type Ledger in case of DifferentCurrency for the accounting document not in the cash currency
                accountingDocumentLineForBank.AccountLineTypeId = (int)AccountLineType.L;
                // And use the nominal account & cost type configured for the company
                accountingDocumentLineForBank.AccountReference = accountingSetup.FXRevalaccount;
                accountingDocumentLineForBank.CostTypeCode     = accountingSetup.FXReval;
            }
            else
            {
                accountingDocumentLineForBank.AccountLineTypeId = (int)AccountLineType.B;
                accountingDocumentLineForBank.AccountReference  = cashInformation.NominalAccount;
                accountingDocumentLineForBank.CostTypeCode      = cashInformation.CostTypeCode;
            }

            decimal totalAmount = cashMatchingTotal.Value + (directionFactor * totalCostAmountForClient);

            accountingDocumentLineForBank.Amount = directionFactor * (-1) * totalAmount;
            decimal?bankLineAmount = accountingDocumentLineForBank.Amount;

            if (cashInformation.Currency != null && cashInformation.Currency.ToUpperInvariant() != CommonRules.BaseCurrency)
            {
                bankLineAmount = (await _foreignExchangeRateService.Convert(fxRates.FxRateInvoiceCurrency.FxCurrency, CommonRules.BaseCurrency, (decimal)bankLineAmount, fxRates.FxRateInvoiceCurrency.FxDate)).ConvertedValue;
            }

            accountingDocumentLineForBank = await CommonRules.CalculateFunctionalAndStatutoryCurrency(_foreignExchangeRateService, accountingDocumentLineForBank, bankLineAmount, fxRates, company, CommonRules.BaseCurrency, CommonRules.RoundDecimals);

            postingLineId++;
            accountingDocumentLines.Add(accountingDocumentLineForBank);

            return(accountingDocumentLines);
        }
        private async Task <AccountingDocumentLine> CreateAccountingDocumentLineForFJDocument(int docTypeId, int postingLineId, AccountingSetupDto accountingSetup, AccountLineType lineType, Company company, FxRateInformation fxRates, FxSettlementDocumentDto fxSettlementDocument)
        {
            AccountingDocumentLine accountingDocumentLine = new AccountingDocumentLine();

            accountingDocumentLine.PostingLineId       = postingLineId;
            accountingDocumentLine.AssociatedAccountId = fxSettlementDocument.CounterpartyId;
            accountingDocumentLine.DepartmentId        = fxSettlementDocument.DepartmentId;
            if (fxSettlementDocument.IsNdf)
            {
                accountingDocumentLine.Narrative = string.Concat(
                    Convert.ToString(fxSettlementDocument.Reference),
                    " ",
                    fxSettlementDocument.Memorandum,
                    " NDF ", ((DateTime)fxSettlementDocument.NdfAgreedDate).ToString("dd MMM yyyy"));
            }
            else
            {
                accountingDocumentLine.Narrative = string.Concat(
                    Convert.ToString(fxSettlementDocument.Reference),
                    " ",
                    fxSettlementDocument.Memorandum);
            }
            accountingDocumentLine.AccountLineTypeId          = (int)lineType;
            accountingDocumentLine.DepartmentId               = fxSettlementDocument.DepartmentId;
            accountingDocumentLine.AccountingCategoryId       = (int)AccountingCategory.N;
            accountingDocumentLine.TransactionDocumentId      = (int)DocumentType.FJ;
            accountingDocumentLine.CostTypeCode               = accountingSetup.FXReval;
            accountingDocumentLine.SecondaryDocumentReference = fxSettlementDocument.DocumentReference;
            accountingDocumentLine.AssociatedAccountId        = fxSettlementDocument.BrokerId;

            if (fxSettlementDocument.FxSettlementDocumentTypeId != FxSettlementDocumentType.FxDeal)
            {
                accountingDocumentLine.Amount = Math.Round(
                    CalculateFxDealAmountForSettlementCurrency(
                        fxSettlementDocument.Amount,
                        fxSettlementDocument.SpotRate,
                        fxSettlementDocument.FwPoints,
                        fxSettlementDocument.SpotRateType),
                    CommonRules.RoundDecimals);

                if (fxSettlementDocument.IsNdf)
                {
                    accountingDocumentLine.SecondaryDocumentReference = null;

                    decimal dealtAmount = fxSettlementDocument.Amount;

                    decimal settledAmount = accountingDocumentLine.Amount;

                    switch (lineType)
                    {
                    case AccountLineType.B:
                        if (fxSettlementDocument.DealDirectionId == (int)FxDealDirection.Buy)
                        {
                            settledAmount = -1 * settledAmount;
                        }
                        else
                        {
                            dealtAmount = -1 * dealtAmount;
                        }
                        break;

                    case AccountLineType.L:
                        if (fxSettlementDocument.DealDirectionId == (int)FxDealDirection.Buy)
                        {
                            dealtAmount = -1 * dealtAmount;
                        }
                        else
                        {
                            settledAmount = -1 * settledAmount;
                        }
                        break;

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

                    if (fxSettlementDocument.CurrencyCode == "USD" && fxSettlementDocument.SettlementCurrencyCode != "USD")
                    {
                        FxRate fxRateUSD = await _masterDataService.GetFxRateAsync((DateTime)fxSettlementDocument.NdfAgreedDate, fxSettlementDocument.SettlementCurrencyCode);

                        if (fxRateUSD.CurrencyRoeType == "M")
                        {
                            accountingDocumentLine.Amount = fxSettlementDocument.NdfAgreedRate == null?Math.Round((dealtAmount / (decimal)fxRateUSD.Rate) + settledAmount, CommonRules.RoundDecimals) : Math.Round((dealtAmount / (decimal)fxSettlementDocument.NdfAgreedRate) + settledAmount, CommonRules.RoundDecimals);
                        }
                        else
                        {
                            accountingDocumentLine.Amount = fxSettlementDocument.NdfAgreedRate == null?Math.Round((dealtAmount * (decimal)fxRateUSD.Rate) + settledAmount, CommonRules.RoundDecimals) : Math.Round((dealtAmount * (decimal)fxSettlementDocument.NdfAgreedRate) + settledAmount, CommonRules.RoundDecimals);
                        }
                    }
                    else if (fxSettlementDocument.CurrencyCode != "USD" && fxSettlementDocument.SettlementCurrencyCode == "USD")
                    {
                        FxRate fxRateUSD = await _masterDataService.GetFxRateAsync((DateTime)fxSettlementDocument.NdfAgreedDate, fxSettlementDocument.CurrencyCode);

                        if (fxRateUSD.CurrencyRoeType == "D")
                        {
                            accountingDocumentLine.Amount = fxSettlementDocument.NdfAgreedRate == null?Math.Round((dealtAmount / (decimal)fxRateUSD.Rate) + settledAmount, CommonRules.RoundDecimals) : Math.Round((dealtAmount / (decimal)fxSettlementDocument.NdfAgreedRate) + settledAmount, CommonRules.RoundDecimals);
                        }
                        else
                        {
                            accountingDocumentLine.Amount = fxSettlementDocument.NdfAgreedRate == null?Math.Round((dealtAmount * (decimal)fxRateUSD.Rate) + settledAmount, CommonRules.RoundDecimals) : Math.Round((dealtAmount * (decimal)fxSettlementDocument.NdfAgreedRate) + settledAmount, CommonRules.RoundDecimals);
                        }
                    }
                    else if (fxSettlementDocument.CurrencyCode != "USD" && fxSettlementDocument.SettlementCurrencyCode != "USD")
                    {
                        FxRate fxRateUSD1 = await _masterDataService.GetFxRateAsync((DateTime)fxSettlementDocument.NdfAgreedDate, fxSettlementDocument.CurrencyCode);

                        FxRate fxRateUSD2 = await _masterDataService.GetFxRateAsync((DateTime)fxSettlementDocument.NdfAgreedDate, fxSettlementDocument.SettlementCurrencyCode);

                        decimal crossSettlementROESettCcy = 1;

                        if (fxSettlementDocument.NdfAgreedRate == null)
                        {
                            if (fxRateUSD1.CurrencyRoeType == "M" && fxRateUSD2.CurrencyRoeType == "M")
                            {
                                crossSettlementROESettCcy = (decimal)fxRateUSD1.Rate / (decimal)fxRateUSD2.Rate;
                            }
                            else if (fxRateUSD1.CurrencyRoeType == "M" && fxRateUSD2.CurrencyRoeType == "D")
                            {
                                crossSettlementROESettCcy = (decimal)fxRateUSD1.Rate * (decimal)fxRateUSD2.Rate;
                            }
                            else if (fxRateUSD1.CurrencyRoeType == "D" && fxRateUSD2.CurrencyRoeType == "M")
                            {
                                crossSettlementROESettCcy = (1 / (decimal)fxRateUSD1.Rate) / (decimal)fxRateUSD2.Rate;
                            }
                            else
                            {
                                crossSettlementROESettCcy = (decimal)fxRateUSD2.Rate / (decimal)fxRateUSD1.Rate;
                            }
                        }
                        else
                        {
                            crossSettlementROESettCcy = (decimal)fxSettlementDocument.NdfAgreedRate;
                        }

                        accountingDocumentLine.Amount = Math.Round((dealtAmount * crossSettlementROESettCcy) - settledAmount, CommonRules.RoundDecimals);
                    }
                    else
                    {
                        accountingDocumentLine.Amount = Math.Round(dealtAmount + settledAmount, CommonRules.RoundDecimals);
                    }
                }
            }
            else
            {
                accountingDocumentLine.Amount = Math.Round(fxSettlementDocument.Amount, CommonRules.RoundDecimals);
            }

            // Amount conversion for StaturoyCurrency and FunctionalCurrency
            decimal?amountInUSD = accountingDocumentLine.Amount;

            if (fxSettlementDocument.CurrencyCode != null && fxSettlementDocument.CurrencyCode.ToUpperInvariant() != CommonRules.BaseCurrency)
            {
                amountInUSD = (await _foreignExchangeRateService.Convert(fxSettlementDocument.CurrencyCode, CommonRules.BaseCurrency, accountingDocumentLine.Amount, fxSettlementDocument.DocumentDate)).ConvertedValue;
                if (amountInUSD != null)
                {
                    amountInUSD = Math.Round((decimal)amountInUSD, CommonRules.RoundDecimals);
                }
            }

            accountingDocumentLine.StatutoryCurrency  = amountInUSD;
            accountingDocumentLine.FunctionalCurrency = amountInUSD;

            if (company.StatutoryCurrencyCode != null && amountInUSD != null && company.StatutoryCurrencyCode.ToUpperInvariant() != CommonRules.BaseCurrency)
            {
                accountingDocumentLine.StatutoryCurrency = (await _foreignExchangeRateService.Convert(CommonRules.BaseCurrency, company.StatutoryCurrencyCode, (decimal)amountInUSD, fxSettlementDocument.DocumentDate)).ConvertedValue;
            }

            if (company.FunctionalCurrencyCode != null && amountInUSD != null && company.FunctionalCurrencyCode.ToUpperInvariant() != CommonRules.BaseCurrency)
            {
                accountingDocumentLine.FunctionalCurrency = (await _foreignExchangeRateService.Convert(CommonRules.BaseCurrency, company.FunctionalCurrencyCode, (decimal)amountInUSD, fxSettlementDocument.DocumentDate)).ConvertedValue;
            }

            // the default rounding option for .NET is MidPointRounding.ToEven, but that this option does not produce the desired result for some of values: -1119.965 was getting rounded to -1119.96 instead of -1119.97
            if (accountingDocumentLine.StatutoryCurrency != null)
            {
                accountingDocumentLine.StatutoryCurrency = Math.Round((decimal)accountingDocumentLine.StatutoryCurrency, CommonRules.RoundDecimals, MidpointRounding.AwayFromZero);
            }

            if (accountingDocumentLine.FunctionalCurrency != null)
            {
                accountingDocumentLine.FunctionalCurrency = Math.Round((decimal)accountingDocumentLine.FunctionalCurrency, CommonRules.RoundDecimals, MidpointRounding.AwayFromZero);
            }

            accountingDocumentLine.AccountReference = await GetAccountReferenceForFJDocument(
                lineType,
                company,
                fxSettlementDocument);

            if (!fxSettlementDocument.IsNdf)
            {
                switch (lineType)
                {
                case AccountLineType.B:
                    if (fxSettlementDocument.DealDirectionId == (int)FxDealDirection.Buy)
                    {
                        if (fxSettlementDocument.FxSettlementDocumentTypeId == FxSettlementDocumentType.FxDeal)
                        {
                            accountingDocumentLine.Amount = accountingDocumentLine.Amount;
                        }
                        else
                        {
                            accountingDocumentLine.Amount = (-1) * accountingDocumentLine.Amount;
                        }
                    }
                    else
                    {
                        if (fxSettlementDocument.FxSettlementDocumentTypeId == FxSettlementDocumentType.FxDeal)
                        {
                            accountingDocumentLine.Amount = (-1) * accountingDocumentLine.Amount;
                        }
                        else
                        {
                            accountingDocumentLine.Amount = accountingDocumentLine.Amount;
                        }
                    }

                    break;

                case AccountLineType.L:
                    if (fxSettlementDocument.DealDirectionId == (int)FxDealDirection.Buy)
                    {
                        if (fxSettlementDocument.FxSettlementDocumentTypeId == FxSettlementDocumentType.FxDeal)
                        {
                            accountingDocumentLine.Amount = (-1) * accountingDocumentLine.Amount;
                        }
                        else
                        {
                            accountingDocumentLine.Amount = accountingDocumentLine.Amount;
                        }
                    }
                    else
                    {
                        if (fxSettlementDocument.FxSettlementDocumentTypeId == FxSettlementDocumentType.FxDeal)
                        {
                            accountingDocumentLine.Amount = accountingDocumentLine.Amount;
                        }
                        else
                        {
                            accountingDocumentLine.Amount = (-1) * accountingDocumentLine.Amount;
                        }
                    }

                    break;

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

            return(accountingDocumentLine);
        }
Example #7
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);
        }
Example #8
0
        internal static async Task <AccountingDocumentLine> CalculateFunctionalAndStatutoryCurrency(IForeignExchangeRateService foreignExchangeRateService, AccountingDocumentLine accountingDocumentLine, decimal?amountInUSD, FxRateInformation fxRates, Company company, string baseCurrency, int decimals)
        {
            if (amountInUSD != null)
            {
                amountInUSD = Math.Round((decimal)amountInUSD, decimals);

                accountingDocumentLine.StatutoryCurrency = amountInUSD;
                if (company.StatutoryCurrencyCode != null && amountInUSD != null && company.StatutoryCurrencyCode.ToUpperInvariant() != baseCurrency)
                {
                    accountingDocumentLine.StatutoryCurrency = (await foreignExchangeRateService.Convert(baseCurrency, fxRates.FxRateStatutoryCurrency.FxCurrency, (decimal)amountInUSD, fxRates.FxRateStatutoryCurrency.FxDate)).ConvertedValue;
                }

                accountingDocumentLine.FunctionalCurrency = amountInUSD;
                if (company.FunctionalCurrencyCode != null && amountInUSD != null && company.FunctionalCurrencyCode.ToUpperInvariant() != baseCurrency)
                {
                    accountingDocumentLine.FunctionalCurrency = (await foreignExchangeRateService.Convert(baseCurrency, fxRates.FxRateFunctionalCurrency.FxCurrency, (decimal)amountInUSD, fxRates.FxRateFunctionalCurrency.FxDate)).ConvertedValue;
                }

                if (accountingDocumentLine.StatutoryCurrency != null)
                {
                    accountingDocumentLine.StatutoryCurrency = Math.Round((decimal)accountingDocumentLine.StatutoryCurrency, decimals, MidpointRounding.AwayFromZero); // the default rounding option for .NET is MidPointRounding.ToEven, but that this option does not produce the desired result for some of values: -1119.965 was getting rounded to -1119.96 instead of -1119.97
                }

                if (accountingDocumentLine.FunctionalCurrency != null)
                {
                    accountingDocumentLine.FunctionalCurrency = Math.Round((decimal)accountingDocumentLine.FunctionalCurrency, decimals, MidpointRounding.AwayFromZero); // the default rounding option for .NET is MidPointRounding.ToEven, but that this option does not produce the desired result for some of values: -1119.965 was getting rounded to -1119.96 instead of -1119.97
                }
            }
            else
            {
                accountingDocumentLine.StatutoryCurrency  = null;
                accountingDocumentLine.FunctionalCurrency = null;
            }

            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);
        }
Example #10
0
        private async Task <AccountingDocumentLine> CreateAccountingDocumentLineForMonthEndTA(int docTypeId, Company company, MonthEndTADocumentDto monthEndDocument, FxRateInformation fxRates, MonthEndTALineDto monthEndLine, int postingLineId)
        {
            AccountingDocumentLine accountingDocumentLine = new AccountingDocumentLine();

            accountingDocumentLine.PostingLineId              = postingLineId;
            accountingDocumentLine.ClientReference            = null;
            accountingDocumentLine.PaymentTermCode            = null;
            accountingDocumentLine.SecondaryDocumentReference = null;
            accountingDocumentLine.SourceTALineId             = monthEndLine.TemporaryAdjustmentLineId;

            // Binding the cost type associated with business sector if business sector posting is configured
            if (monthEndDocument.BusinessSectorNominalPostingPurpose == true && monthEndLine.SectionId != null && monthEndLine.BusinessSectorCostTypeCode != null)
            {
                accountingDocumentLine.CostTypeCode = monthEndLine.BusinessSectorCostTypeCode;
            }
            else
            {
                accountingDocumentLine.CostTypeCode = monthEndLine.CostTypeCode;
            }

            accountingDocumentLine.DepartmentId          = monthEndLine.DepartmentId;
            accountingDocumentLine.AssociatedAccountCode = monthEndLine.AssociatedAccountCode;
            accountingDocumentLine.Quantity    = monthEndLine.Quantity != null ? (decimal)monthEndLine.Quantity : monthEndLine.Quantity;
            accountingDocumentLine.CommodityId = monthEndLine.CommodityId;
            accountingDocumentLine.VATTurnover = null;
            accountingDocumentLine.VATCode     = null;
            accountingDocumentLine.CharterId   = monthEndLine.CharterId;
            accountingDocumentLine.CostCenter  = null;
            if (monthEndLine.ReportTypeId == ReportType.Realized)
            {
                accountingDocumentLine.Narrative = "Accruals of " + monthEndDocument.AccountingPeriod.Value.ToString("MMM-yyyy", CultureInfo.InvariantCulture);
            }
            else if (monthEndDocument.TATypeId == (int)TAType.FxDealMonthTemporaryAdjustment)
            {
                accountingDocumentLine.Narrative = "Accruals of " + monthEndDocument.AccountingPeriod.Value.ToString("MMM-yyyy", CultureInfo.InvariantCulture) + " " + monthEndLine.CurrencyCouple + " " + monthEndLine.Reference;
            }
            else
            {
                accountingDocumentLine.Narrative = "AccrualsRev of " + monthEndDocument.AccountingPeriod.Value.ToString("MMM-yyyy", CultureInfo.InvariantCulture) + " " + monthEndLine.InvoiceDocumentReference;
            }

            accountingDocumentLine.SectionId      = monthEndLine.SectionId;
            accountingDocumentLine.SourceFxDealId = monthEndLine.FxDealId;
            accountingDocumentLine.AccrualNumber  = monthEndLine.AccrualNumber;

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

            decimal?amountInUSD = accountingDocumentLine.Amount;

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

            if (amountInUSD != null)
            {
                amountInUSD = Math.Round((decimal)amountInUSD, CommonRules.RoundDecimals);
            }

            accountingDocumentLine.StatutoryCurrency = amountInUSD;
            if (company.StatutoryCurrencyCode != null && amountInUSD != null && company.StatutoryCurrencyCode.ToUpperInvariant() != CommonRules.BaseCurrency)
            {
                accountingDocumentLine.StatutoryCurrency = (await _foreignExchangeRateService.Convert(CommonRules.BaseCurrency, company.StatutoryCurrencyCode, (decimal)amountInUSD, monthEndLine.BLDate)).ConvertedValue;
            }

            accountingDocumentLine.FunctionalCurrency = amountInUSD;
            if (company.FunctionalCurrencyCode != null && amountInUSD != null && company.FunctionalCurrencyCode.ToUpperInvariant() != CommonRules.BaseCurrency)
            {
                accountingDocumentLine.FunctionalCurrency = (await _foreignExchangeRateService.Convert(CommonRules.BaseCurrency, company.FunctionalCurrencyCode, (decimal)amountInUSD, monthEndLine.BLDate)).ConvertedValue;
            }

            if (accountingDocumentLine.StatutoryCurrency != null)
            {
                accountingDocumentLine.StatutoryCurrency = Math.Round((decimal)accountingDocumentLine.StatutoryCurrency, CommonRules.RoundDecimals, MidpointRounding.AwayFromZero); // the default rounding option for .NET is MidPointRounding.ToEven, but that this option does not produce the desired result for some of values: -1119.965 was getting rounded to -1119.96 instead of -1119.97
            }

            if (accountingDocumentLine.FunctionalCurrency != null)
            {
                accountingDocumentLine.FunctionalCurrency = Math.Round((decimal)accountingDocumentLine.FunctionalCurrency, CommonRules.RoundDecimals, MidpointRounding.AwayFromZero); // the default rounding option for .NET is MidPointRounding.ToEven, but that this option does not produce the desired result for some of values: -1119.965 was getting rounded to -1119.96 instead of -1119.97
            }

            if (monthEndDocument.TATypeId != (int)TAType.FxDealMonthTemporaryAdjustment)
            {
                switch (monthEndLine.NominalOrClientLeg)
                {
                case AccountingDocumentLineType.Client:
                    accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.C;
                    accountingDocumentLine.AccountLineTypeId    = monthEndLine.Amount >= 0 ? (int)AccountLineType.C : (int)AccountLineType.V;
                    accountingDocumentLine.ClientAccount        = monthEndLine.AssociatedAccountCode;
                    accountingDocumentLine.PostingLineId        = 1;
                    break;

                case AccountingDocumentLineType.Nominal:
                    accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.N;
                    accountingDocumentLine.AccountLineTypeId    = (int)AccountLineType.L;
                    accountingDocumentLine.ClientAccount        = null;
                    accountingDocumentLine.PostingLineId        = 2;
                    break;
                }
            }

            // Binding the Nominal Account associated with business sector if business sector posting is configured and if account line type is "L"
            if (monthEndDocument.BusinessSectorNominalPostingPurpose == true && monthEndLine.SectionId != null &&
                monthEndLine.BusinessSectorNominalAccountCode != null && accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.L)
            {
                accountingDocumentLine.AccountReference = monthEndLine.BusinessSectorNominalAccountCode;
            }
            else
            {
                accountingDocumentLine.AccountReference = monthEndLine.NominalAccount;
            }

            return(accountingDocumentLine);
        }
Example #11
0
        private async Task <AccountingDocumentLine> CreateAccountingDocumentLineForManualJournal(int docTypeId, Company company, ManualJournalDocumentDto manualJournal, FxRateInformation fxRates, ManualJournalLineDto manualJournalLine, int postingLineId, AccountingSetupDto accountingSetup)
        {
            AccountingDocumentLine accountingDocumentLine = new AccountingDocumentLine();

            accountingDocumentLine.JournalLineId       = manualJournalLine.JournalLineId;
            accountingDocumentLine.SourceJournalLineId = manualJournalLine.JournalLineId;
            accountingDocumentLine.PostingLineId       = postingLineId;
            accountingDocumentLine.CostTypeCode        = manualJournalLine.CostTypeCode;
            accountingDocumentLine.Amount                = manualJournalLine.Amount;
            accountingDocumentLine.DepartmentId          = manualJournalLine.DepartmentId;
            accountingDocumentLine.AssociatedAccountCode = manualJournalLine.AssociatedAccountCode;
            accountingDocumentLine.PaymentTermCode       = null;
            accountingDocumentLine.ContractSectionCode   = manualJournalLine.ContractSectionCode;
            accountingDocumentLine.CommodityId           = manualJournalLine.CommodityId;
            accountingDocumentLine.Quantity              = manualJournalLine.Quantity;
            accountingDocumentLine.VATTurnover           = null;
            accountingDocumentLine.SectionId             = manualJournalLine.SectionId;
            accountingDocumentLine.AccountLineTypeId     = manualJournalLine.AccountLineTypeId;
            if (manualJournal.TATypeId == (int)TAType.ManualMarkToMarket)
            {
                accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.N;
            }
            else
            {
                accountingDocumentLine.AccountingCategoryId = (manualJournalLine.AccountLineTypeId == (int)AccountLineType.C || (manualJournalLine.AccountLineTypeId == (int)AccountLineType.V)) ? (int)AccountingCategory.C : (int)AccountingCategory.N;
            }
            accountingDocumentLine.CompanyId = manualJournalLine.CompanyId;
            accountingDocumentLine.CharterId = manualJournalLine.CharterId;
            accountingDocumentLine.SecondaryDocumentReference = manualJournalLine.SecondaryDocumentReference;
            accountingDocumentLine.CostCenter    = (manualJournal.TATypeId == (int)TAType.ManualMarkToMarket) ? null : manualJournalLine.CostCenter;
            accountingDocumentLine.AccrualNumber = manualJournalLine.AccrualNumber;
            accountingDocumentLine.VATCode       = null;
            accountingDocumentLine.ClientAccount = (manualJournal.TATypeId == (int)TAType.ManualMarkToMarket) ? null : manualJournalLine.ClientAccountCode;
            accountingDocumentLine.Amount        = Math.Round(manualJournalLine.Amount, CommonRules.RoundDecimals);

            if (manualJournal.JLTypeId == (int)JLType.ManualRegularJournal || manualJournal.TATypeId == (int)TAType.ManualTemporaryAdjustment || manualJournal.TATypeId == (int)TAType.ManualMarkToMarket)
            {
                accountingDocumentLine.AccountReference = manualJournalLine.AccountReference;
            }
            else
            {
                accountingDocumentLine.AccountReference = manualJournalLine.AccountLineTypeId == (int)AccountLineType.V ? accountingSetup.PurchaseLedgerControlClientCreditors : accountingSetup.SalesLedgerControlClientDebtors;
            }

            decimal?amountInUSD = accountingDocumentLine.Amount;

            if (manualJournal.CurrencyCode != null && manualJournal.CurrencyCode.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);

            if (docTypeId == (int)DocumentType.MJL)
            {
                accountingDocumentLine.Narrative       = manualJournalLine.Narrative;
                accountingDocumentLine.ClientReference = manualJournalLine.ExternalDocumentReference;
            }

            if (docTypeId == (int)DocumentType.MTA)
            {
                if (manualJournal.TATypeId == (int)TAType.ManualMarkToMarket)
                {
                    accountingDocumentLine.Narrative = manualJournalLine.Narrative;
                }
                else
                {
                    manualJournalLine.Narrative      = manualJournalLine.Narrative == null ? string.Empty : manualJournalLine.Narrative;
                    accountingDocumentLine.Narrative = manualJournalLine.Narrative.Trim().Length > 0 ? manualJournalLine.Narrative : "Manual Accrual of " + manualJournal.AccountingPeriod.ToString("MMM-yyyy", CultureInfo.InvariantCulture);
                }
                accountingDocumentLine.ClientReference = null;
            }

            return(accountingDocumentLine);
        }