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 <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> > 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 <List <AccountingDocument> > GetInformationForCash(bool postOpClosedPrivilege, long docId, int docTypeId, AccountingSetupDto accountingSetup, Company company, DateTime companyDate)
        {
            List <AccountingDocument> accountingDocuments = new List <AccountingDocument>();
            CashInformationDto        cashInformation     = await _accountingQueries.GetCashInformationForAccountingDocument(docId, company.CompanyId);

            if (accountingSetup == null)
            {
                throw new Exception("No accounting setup found.");
            }

            var fxRates = CommonRules.GetFxRateInformation(cashInformation.DocumentDate, cashInformation.Currency, company);

            if (cashInformation.CashTypeId == (int)CashSelectionType.SimpleCashPayment || cashInformation.CashTypeId == (int)CashSelectionType.SimpleCashReceipt)
            {
                /* Simple cash */

                var accountingDocument = await CommonRules.CreateAccountingDocument(_masterDataService, _identityService.GetUserAtlasId(), postOpClosedPrivilege, docId, docTypeId, CommonRules.BaseCurrency, fxRates.FxRateInvoiceCurrency, accountingSetup, null, cashInformation);

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

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

                // the cashLines list is supposed to contain one unique cash line information  ; we initialize the "C" acc line with the ID of the cash line
                if (cashInformation.CashLines != null && cashInformation.CashLines.Any())
                {
                    var cashLineRecord = cashInformation.CashLines.FirstOrDefault();
                    foreach (var accountingLine in accountingDocument.AccountingDocumentLines)
                    {
                        if (accountingLine.AccountingCategoryId == (int)AccountingCategory.C)
                        {
                            accountingLine.SourceCashLineId = cashLineRecord.CashLineId;
                        }
                    }
                }
            }
            else
            {
                /* Cash by picking */
                var accountingDocument = await CommonRules.CreateAccountingDocument(_masterDataService, _identityService.GetUserAtlasId(), postOpClosedPrivilege, docId, docTypeId, CommonRules.BaseCurrency, fxRates.FxRateInvoiceCurrency, accountingSetup, null, cashInformation);

                accountingDocument.AccountingDocumentLines = await CreateAccountingDocumentLinesForCashPickingTransaction(docTypeId, company, fxRates, accountingSetup, cashInformation);

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

                accountingDocuments.Add(accountingDocument);

                // If diff ccy, then process the paid cash (the one with the same currency than the invoices)
                if (cashInformation.CashTypeId == (int)CashSelectionType.PaymentDifferentCurrency || cashInformation.CashTypeId == (int)CashSelectionType.ReceiptDifferentCurrency)
                {
                    // Get information for the paid cash
                    CashInformationDto paidCashInformation = await _accountingQueries.GetCashInformationForAccountingDocument(cashInformation.PaymentTransactionDocumentId.Value, company.CompanyId);

                    if (paidCashInformation == null)
                    {
                        throw new AtlasBusinessException("Cannot retrieve information for the associated cash.");
                    }

                    fxRates = CommonRules.GetFxRateInformation(paidCashInformation.DocumentDate, paidCashInformation.Currency, company);
                    var accountingDocumentForPaidCash = await CommonRules.CreateAccountingDocument(_masterDataService, _identityService.GetUserAtlasId(), postOpClosedPrivilege, cashInformation.PaymentTransactionDocumentId.Value, docTypeId, CommonRules.BaseCurrency, fxRates.FxRateInvoiceCurrency, accountingSetup, null, paidCashInformation);

                    // Create the lines for the accounting document in the cash currency (in case of diff ccy)
                    accountingDocumentForPaidCash.AccountingDocumentLines = await CreateAccountingDocumentLineForCashPaidCashInAnotherCcy(docTypeId, company, fxRates, accountingSetup, cashInformation, paidCashInformation);

                    // We don't want this accounting document to be individually posted ; the posting will be done
                    // automatically when posting the matched cash. Puttin the status id to the value "Incomplete" prevent to send this document to the message queue
                    // later in the code
                    accountingDocumentForPaidCash.StatusId = PostingStatus.Incomplete;

                    // Overriding the Roe + type with the information entered by the end user within the screen
                    // (we don't want to use the "current" roe)
                    // This is done the cash which is NOT in USD ; as a reminder, in cash by picking diff ccy, we have the assumption that
                    // one of the currency is USD, and the second is not!
                    if (accountingDocument.CurrencyCode != "USD")
                    {
                        accountingDocument.Roe = paidCashInformation.MatchingRate;
                    }
                    else
                    {
                        accountingDocumentForPaidCash.Roe = paidCashInformation.MatchingRate;
                    }

                    accountingDocuments.Add(accountingDocumentForPaidCash);
                }
            }

            return(accountingDocuments);
        }
Esempio n. 5
0
 internal static int CalculateDirectionFactorForClientLines(CashInformationDto cashInformation)
 {
     return(CalculateDirectionFactorForClientLines((CashSelectionType)cashInformation.CashTypeId));
 }
Esempio n. 6
0
        internal static bool CheckPostingForAuthorized(InvoiceInformationDto invoiceInformation = null, CashInformationDto cashInformation = null, RevaluationInformationDto revalInformation = null, CounterpartyInformationDto counterpartyInformation = null)
        {
            if (invoiceInformation != null)
            {
                return(invoiceInformation.AuthorizedForPosting);
            }

            if (revalInformation != null)
            {
                return(true);
            }

            if (counterpartyInformation != null)
            {
                return(true);
            }

            return(cashInformation.AuthorizedForPosting);
        }
Esempio n. 7
0
        internal static async Task <PostingStatus> GetAccountingDocumentStatus(AccountingSetupDto accountingSetup, IAccountingDocumentQueries accountingQuerie, AccountingDocument accountingDocument, string company, DateTime companyDate, InvoiceInformationDto invoiceInformation = null, CashInformationDto cashInformation = null, RevaluationInformationDto revalInformation = null, CounterpartyInformationDto counterpartyInformation = null)
        {
            accountingDocument.ErrorMessage = string.Empty;

            if (invoiceInformation != null)
            {
                if (!CheckPostingForAuthorized(invoiceInformation))
                {
                    return(PostingStatus.Incomplete);
                }
            }
            else if (cashInformation != null)
            {
                if (!CheckPostingForAuthorized(null, cashInformation))
                {
                    return(PostingStatus.Incomplete);
                }
            }
            else if (revalInformation != null)
            {
                if (!CheckPostingForAuthorized(null, null, revalInformation))
                {
                    return(PostingStatus.Incomplete);
                }
            }
            else if (counterpartyInformation != null)
            {
                if (!CheckPostingForAuthorized(null, null, null, counterpartyInformation))
                {
                    return(PostingStatus.Incomplete);
                }
            }

            if (CheckSanityCheck(accountingDocument))
            {
                if (CheckFxRateConverted(accountingDocument))
                {
                    bool ifInterface = await CheckIfInterface(accountingQuerie, accountingDocument.TransactionDocumentId, company);

                    MappingErrorMessages messages = await CheckMappingError(accountingQuerie, accountingDocument.AccountingDocumentLines, company, accountingDocument.TransactionDocumentTypeId);

                    if (ifInterface)
                    {
                        if (!messages.C2CCode)
                        {
                            accountingDocument.ErrorMessage = "C2C Code Is NULL ;";
                        }

                        if (!messages.CostAlternativeCode)
                        {
                            accountingDocument.ErrorMessage += "Cost Alternative Code Is NULL ;";
                        }

                        if (!messages.TaxInterfaceCode)
                        {
                            accountingDocument.ErrorMessage += "Tax Interface Code Is NULL ;";
                        }

                        if (!messages.NominalAlternativeAccount)
                        {
                            accountingDocument.ErrorMessage += "Nominal Alternative Code Is NULL ;";
                        }

                        if (!messages.DepartmentAlternativeCode)
                        {
                            accountingDocument.ErrorMessage += "Department Alternative Code Is NULL ;";
                        }

                        if (!string.IsNullOrEmpty(accountingDocument.ErrorMessage))
                        {
                            return(PostingStatus.MappingError);
                        }
                    }

                    if (MandatoryFieldValidation(accountingDocument))
                    {
                        accountingDocument.ErrorMessage = "Mandatory Field Missing";

                        return(PostingStatus.Held);
                    }

                    if (CheckFutureDate(accountingDocument, companyDate))
                    {
                        accountingDocument.ErrorMessage = "Future document date";
                        return(PostingStatus.Held);
                    }
                    if (!IsMonthOpenForAccounting(accountingSetup.LastMonthClosed, accountingDocument.AccountingDate, accountingSetup.NumberOfOpenPeriod))
                    {
                        accountingDocument.ErrorMessage = "Period is not open for accounting";
                        return(PostingStatus.Held);
                    }

                    return(PostingStatus.Authorised);
                }
                else
                {
                    accountingDocument.ErrorMessage = "No Fxrate found";
                    return(PostingStatus.Held);
                }
            }
            else
            {
                accountingDocument.ErrorMessage = "Unbalanced document";
                return(PostingStatus.Held);
            }
        }
Esempio n. 8
0
        internal static async Task <AccountingDocument> CreateAccountingDocument(
            IMasterDataService masterDataService,
            long userId,
            bool postOpClosedPrivilege,
            long docId,
            int docTypeId,
            string baseCurrency,
            FxRateConversion fxRate,
            AccountingSetupDto accountingSetup,
            InvoiceInformationDto invoiceInformation = null,
            CashInformationDto cashInformation       = null,
            DateTime?blDate = null,
            ManualJournalDocumentDto manualJournal             = null,
            RevaluationInformationDto revalInformation         = null,
            MonthEndTADocumentDto monthEndTADocument           = null,
            CounterpartyInformationDto counterpartyInformation = null,
            CashForCounterpartyDto cashForCounterpartyDto      = null,
            FxSettlementDocumentDto fxSettlementDocument       = null)
        {
            AccountingDocument accountingDocument = new AccountingDocument();

            accountingDocument.UserCreator           = userId;
            accountingDocument.TransactionDocumentId = docId;
            accountingDocument.ProvinceId            = null;
            accountingDocument.OriginalReferenceId   = null;

            if (fxRate.FxCurrency.ToUpperInvariant() == baseCurrency)
            {
                accountingDocument.Roe     = 1;
                accountingDocument.RoeType = "M";
            }
            else
            {
                FxRate fxRateUSD = await masterDataService.GetFxRateAsync(fxRate.FxDate, fxRate.FxCurrency);

                accountingDocument.Roe     = fxRateUSD != null ? fxRateUSD.Rate : null;
                accountingDocument.RoeType = fxRateUSD != null ? fxRateUSD.CurrencyRoeType : null;
            }

            accountingDocument.TransactionDocumentTypeId = docTypeId;
            accountingDocument.AcknowledgementDate       = null;

            switch (docTypeId)
            {
            case (int)DocumentType.PI:
            case (int)DocumentType.SI:
            case (int)DocumentType.CN:
            case (int)DocumentType.DN:
                accountingDocument.CurrencyCode      = invoiceInformation.Currency;
                accountingDocument.AccountingPeriod  = CommonRules.CalculateAccountPeriod(accountingSetup, invoiceInformation.InvoiceDate, postOpClosedPrivilege);
                accountingDocument.DocumentDate      = invoiceInformation.InvoiceDate;
                accountingDocument.ValueDate         = invoiceInformation.InvoiceDueDate;
                accountingDocument.GLDate            = blDate;
                accountingDocument.OriginalValueDate = invoiceInformation.InvoiceDueDate;
                accountingDocument.AccountingDate    = CommonRules.CalculateAccountPeriod(accountingSetup, invoiceInformation.InvoiceDate, postOpClosedPrivilege);

                break;

            case (int)DocumentType.CP:
            case (int)DocumentType.CI:
                if (counterpartyInformation != null && cashForCounterpartyDto.CashTypeId == (int)CashSelectionType.PaymentDifferentClient && cashForCounterpartyDto.JLTypeId == (int)JLType.CounterPartyTransfer)
                {
                    accountingDocument.CurrencyCode      = counterpartyInformation.CurrencyCode;
                    accountingDocument.AccountingPeriod  = CommonRules.CalculateAccountPeriod(accountingSetup, counterpartyInformation.DocumentDate, postOpClosedPrivilege);
                    accountingDocument.DocumentDate      = counterpartyInformation.DocumentDate;
                    accountingDocument.ValueDate         = counterpartyInformation.ValueDate == null ? counterpartyInformation.DocumentDate : (DateTime)counterpartyInformation.ValueDate;
                    accountingDocument.GLDate            = counterpartyInformation.DocumentDate;
                    accountingDocument.OriginalValueDate = counterpartyInformation.ValueDate == null ? counterpartyInformation.DocumentDate : (DateTime)counterpartyInformation.ValueDate;
                    accountingDocument.AccountingDate    = CommonRules.CalculateAccountPeriod(accountingSetup, counterpartyInformation.DocumentDate, postOpClosedPrivilege);
                }
                else
                {
                    accountingDocument.CurrencyCode      = cashInformation.Currency;
                    accountingDocument.AccountingPeriod  = CommonRules.CalculateAccountPeriod(accountingSetup, cashInformation.DocumentDate, postOpClosedPrivilege);
                    accountingDocument.DocumentDate      = cashInformation.DocumentDate;
                    accountingDocument.ValueDate         = cashInformation.ValueDate;
                    accountingDocument.GLDate            = cashInformation.DocumentDate;
                    accountingDocument.OriginalValueDate = cashInformation.ValueDate;
                    accountingDocument.AccountingDate    = CommonRules.CalculateAccountPeriod(accountingSetup, cashInformation.DocumentDate, postOpClosedPrivilege);
                }

                break;

            case (int)DocumentType.MTA:
            case (int)DocumentType.MJL:
                if (monthEndTADocument != null && (monthEndTADocument.TATypeId == (int)TAType.MonthEndTemporaryAdjustment || monthEndTADocument.TATypeId == (int)TAType.FxDealMonthTemporaryAdjustment))
                {
                    accountingDocument.CurrencyCode      = monthEndTADocument.CurrencyCode;
                    accountingDocument.ValueDate         = monthEndTADocument.ValueDate;
                    accountingDocument.DocumentDate      = new DateTime(accountingDocument.ValueDate.Value.Year, accountingDocument.ValueDate.Value.Month, 1).AddDays(-1);
                    accountingDocument.AccountingPeriod  = monthEndTADocument.AccountingPeriod.Value;
                    accountingDocument.GLDate            = monthEndTADocument.MonthEndTALines.FirstOrDefault().BLDate;
                    accountingDocument.OriginalValueDate = (DateTime)monthEndTADocument.ValueDate;
                    accountingDocument.AccountingDate    = accountingDocument.DocumentDate.Year == monthEndTADocument.AccountingPeriod.Value.Year && accountingDocument.DocumentDate.Month == monthEndTADocument.AccountingPeriod.Value.Month ? accountingDocument.DocumentDate : new DateTime(monthEndTADocument.AccountingPeriod.Value.Year, monthEndTADocument.AccountingPeriod.Value.Month, 1);
                }
                else
                {
                    accountingDocument.CurrencyCode      = manualJournal.CurrencyCode;
                    accountingDocument.AccountingPeriod  = manualJournal.AccountingPeriod;
                    accountingDocument.DocumentDate      = manualJournal.DocumentDate;
                    accountingDocument.GLDate            = manualJournal.DocumentDate;
                    accountingDocument.OriginalValueDate = manualJournal.ValueDate == null ? manualJournal.DocumentDate : (DateTime)manualJournal.ValueDate;
                    accountingDocument.AccountingDate    = manualJournal.DocumentDate;

                    if (docTypeId == (int)DocumentType.MTA)
                    {
                        accountingDocument.ValueDate = manualJournal.ValueDate == null ? new DateTime(manualJournal.DocumentDate.Year, manualJournal.DocumentDate.Month, 1).AddMonths(1) : (DateTime)manualJournal.ValueDate;
                    }

                    if (docTypeId == (int)DocumentType.MJL)
                    {
                        accountingDocument.ValueDate = manualJournal.ValueDate == null ? manualJournal.DocumentDate : manualJournal.ValueDate;
                    }
                }

                break;

            case (int)DocumentType.FJ:
                accountingDocument.DocumentReference = fxSettlementDocument.DocumentReference;
                if (fxSettlementDocument.IsNdf)
                {
                    accountingDocument.ValueDate = fxSettlementDocument.NdfAgreedDate;
                }
                else
                {
                    accountingDocument.ValueDate = fxSettlementDocument.MaturityDate;
                }
                accountingDocument.DocumentDate      = fxSettlementDocument.MaturityDate;
                accountingDocument.GLDate            = fxSettlementDocument.MaturityDate;
                accountingDocument.OriginalValueDate = fxSettlementDocument.DocumentDate;
                if (fxSettlementDocument != null && fxSettlementDocument.FxSettlementDocumentTypeId != FxSettlementDocumentType.FxDeal)
                {
                    accountingDocument.CurrencyCode = fxSettlementDocument.SettlementCurrencyCode;
                }
                else
                {
                    accountingDocument.CurrencyCode = fxSettlementDocument.CurrencyCode;
                }

                break;
            }

            return(accountingDocument);
        }
        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);
        }