public async Task AuthorizeForPosting(List <long> listOfDocId, string company, bool postOpClosedPolicy)
        {
            List <AccountingDocument> accountDocumentsDto = (await _accountingDocumentRepository.GetAccountingDocumentsByAccountingIdsAsync(listOfDocId, company)).ToList();

            var companyDate = await _systemDateTimeService.GetCompanyDate(company);

            foreach (AccountingDocument accountingDocumentDto in accountDocumentsDto)
            {
                await CommonRules.CalculateFunctionalAndStatutoryCurrencyAccountingLine(_foreignExchangeRateService, accountingDocumentDto);

                AccountingSetupDto accountingSetup = await _accountingQueries.GetAccountingSetup((int)accountingDocumentDto.TransactionDocumentTypeId, company);

                accountingDocumentDto.StatusId = await CommonRules.ReturnAccountingDocumentStatus(_accountingQueries, accountingDocumentDto, companyDate, company, accountingSetup);

                await _accountingDocumentRepository.UpdateAccountingDocumentStatutoryAndFunctionalCurrencyAmounts(company, accountingDocumentDto);
            }

            var listOfAuthorizedDocument = accountDocumentsDto.Where(x => x.StatusId == PostingStatus.Authorised).ToList();

            if (listOfAuthorizedDocument.Count > 0)
            {
                foreach (AccountingDocument accountingDocument in listOfAuthorizedDocument)
                {
                    await EnqueuePostingProcessorMessage(accountingDocument.AccountingId, company, postOpClosedPolicy);
                }
            }
        }
Exemplo n.º 2
0
        public async Task <Unit> Handle(AuthorizeForPostingCommand request, CancellationToken cancellationToken)
        {
            _unitOfWork.BeginTransaction();

            try
            {
                // TODO: validation = Only document within following status can be updated: PostingStatus.MappingError, PostingStatus.Held, PostingStatus.Incomplete
                var listOfDocId = request.AccountingDocuments.Select(d => d.AccountingId).ToList();

                bool postOpClosedPolicy = await CommonRules.CheckPrivileges(_authorizationService, _identityService);

                await AuthorizeForPosting(listOfDocId, request.Company, postOpClosedPolicy);

                _unitOfWork.Commit();

                _logger.LogInformation($"Authorize for posting documents {string.Join(",", listOfDocId)}.");
            }
            catch
            {
                _unitOfWork.Rollback();
                throw;
            }

            return(Unit.Value);
        }
Exemplo n.º 3
0
        private async Task <AccountingDocument> GetInformationForMonthEndTA(
            bool postOpClosedPrivilege,
            long docId,
            int docTypeId,
            AccountingSetupDto accountingSetup,
            Company company,
            DateTime companyDate,
            MonthEndTADocumentDto monthEndTADocument)
        {
            AccountingDocument accountingDocument = null;

            DateTime documentDate = new DateTime(monthEndTADocument.ValueDate.Value.Year, monthEndTADocument.ValueDate.Value.Month, 1).AddDays(-1);

            var fxRates = CommonRules.GetFxRateInformation(documentDate, monthEndTADocument.CurrencyCode, company);

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

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

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

            return(accountingDocument);
        }
        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);
        }
Exemplo n.º 5
0
        public async Task <Unit> Handle(ProcessHeldAndMappingErrorDocumentCommand request, CancellationToken cancellationToken)
        {
            _unitOfWork.BeginTransaction();

            try
            {
                var companyDate = await _systemDateTimeService.GetCompanyDate(request.Company);

                IEnumerable <AccountingDocument> accountingDocuments = await _accountingQueries.GetAccountingDocumentInHeldAndMappingErrorState(request.Company);

                foreach (AccountingDocument accountingDocument in accountingDocuments)
                {
                    await CommonRules.CalculateFunctionalAndStatutoryCurrencyAccountingLine(_foreignExchangeRateService, accountingDocument);

                    AccountingSetupDto accountingSetup = await _accountingQueries.GetAccountingSetup((int)accountingDocument.TransactionDocumentTypeId, request.Company);

                    accountingDocument.StatusId = await ReturnAccountingDocumentStatus(accountingDocument, companyDate, request.Company, accountingSetup);

                    await _accountingDocumentRepository.UpdateAccountingDocument(accountingDocument, request.Company);

                    if (accountingDocument.StatusId == PostingStatus.Authorised)
                    {
                        bool postOpClosedPolicy = await CommonRules.CheckPrivileges(_authorizationService, _identityService);

                        await EnqueuePostingProcessorMessage(accountingDocument.AccountingId, request.Company, postOpClosedPolicy);
                    }
                }

                _unitOfWork.Commit();
            }
            catch
            {
                _unitOfWork.Rollback();

                throw;
            }

            return(Unit.Value);
        }
Exemplo n.º 6
0
        private async Task <AccountingDocument> GetInformationForManualJournal(bool postOpClosedPolicy, long docId, int docTypeId, AccountingSetupDto accountingSetup, Company company, DateTime companyDate)
        {
            AccountingDocument accountingDocument = null;

            ManualJournalDocumentDto manualJournal = null;

            manualJournal = await _accountingQueries.GetManualJournalbyTransactionDocumentId(docId, company.CompanyId);

            var fxRates = CommonRules.GetFxRateInformation(manualJournal.DocumentDate, manualJournal.CurrencyCode, company);

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

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

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

            return(accountingDocument);
        }
Exemplo n.º 7
0
        private async Task <AccountingDocument> MapCommandToAccountingDocument(UpdateAccountingDocumentCommand command)
        {
            AccountingDocument accountingDocument = new AccountingDocument();

            accountingDocument.AccountingPeriod          = command.AccountingPeriod;
            accountingDocument.AccountingId              = command.AccountingId;
            accountingDocument.CurrencyCode              = command.CurrencyCode;
            accountingDocument.DocumentDate              = command.DocumentDate;
            accountingDocument.ValueDate                 = command.ValueDate;
            accountingDocument.ToInterface               = command.ToInterface;
            accountingDocument.DmsId                     = command.DmsId;
            accountingDocument.TransactionDocumentTypeId = (int)command.TransactionDocumentTypeId;
            if (command.StatusId == PostingStatus.Posted)
            {
                accountingDocument.StatusId = command.StatusId;
            }
            else if (!command.IsAuthorizedControlEnabled)
            {
                accountingDocument.StatusId = PostingStatus.Incomplete;
            }

            accountingDocument.AccountingDocumentLines = command.AccountingDocumentLines;

            Company company = await _masterDataService.GetCompanyByIdAsync(command.Company);

            var fxRates = CommonRules.GetFxRateInformation(accountingDocument.DocumentDate, accountingDocument.CurrencyCode, company);

            if (fxRates.FxRateInvoiceCurrency != null)
            {
                foreach (AccountingDocumentLine accountingDocumentLine in accountingDocument.AccountingDocumentLines)
                {
                    if (accountingDocumentLine.AccountingCategoryId <= 0 && accountingDocumentLine.AccountLineTypeId >= 1)
                    {
                        if (accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.C || accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.V)
                        {
                            accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.C;
                        }
                        else if (accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.B || accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.L)
                        {
                            accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.N;
                        }
                    }

                    if (string.IsNullOrEmpty(accountingDocumentLine.Narrative) && accountingDocument.TransactionDocumentTypeId == (int)DocumentType.MTA)
                    {
                        accountingDocumentLine.Narrative = "Manual Accrual of " + accountingDocument.AccountingPeriod.ToString("MMM-yyyy", CultureInfo.InvariantCulture);
                    }

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

                    decimal?amountInUSD = accountingDocumentLine.Amount;

                    if (accountingDocument.CurrencyCode != null && accountingDocument.CurrencyCode.ToUpperInvariant() != CommonRules.BaseCurrency)
                    {
                        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);
                }
            }

            accountingDocument.GLDate = command.GLDate;
            return(accountingDocument);
        }
        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 <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);
        }
        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);
        }
Exemplo n.º 12
0
        private async Task <AccountingDocument> GetInformationForInvoice(bool postOpClosedPrivilege, long docId, int docTypeId, AccountingSetupDto accountingSetup, Company company, string companyId, DateTime companyDate)
        {
            AccountingDocument    accountingDocument;
            InvoiceInformationDto invoiceInformation;
            BusinessSectorDto     businessSectorInfo;
            IEnumerable <SectionsInformationDto> sectionsInformation;

            IEnumerable <Vat> vat = null;

            invoiceInformation = await _accountingQueries.GetInvoiceInformationForAccountingDocument(docId, company.CompanyId);

            if (invoiceInformation != null)
            {
                if (invoiceInformation.BusinessSectorNominalPostingPurpose == true)
                {
                    var businessSectorCode = invoiceInformation.InvoiceLines.FirstOrDefault().BusinessSectorCode;
                    if (businessSectorCode != null)
                    {
                        businessSectorInfo = await _accountingQueries.GetAccountNumberbyBusinessSectorId(company.CompanyId, businessSectorCode);

                        if (businessSectorInfo != null)
                        {
                            invoiceInformation.CostTypeCode     = businessSectorInfo.CostTypeCode;
                            invoiceInformation.AccountReference = businessSectorInfo.AccountNumber;
                        }
                    }
                }

                sectionsInformation = await _accountingQueries.GetSectionsInformationForAccountingDocument(companyId, invoiceInformation.InvoiceId);

                var vatCodes = invoiceInformation.InvoiceLines.Select(x => x.VATCode).Distinct();

                if (sectionsInformation != null && sectionsInformation.Any())
                {
                    vat = await _masterDataService.GetVat(vatCodes, companyId);

                    var blDateList = sectionsInformation.Where(section => section.BLDate != null).ToList();

                    DateTime?blDate = null;

                    if (blDateList.Count > 0)
                    {
                        blDate = blDateList.OrderByDescending(x => x.BLDate).FirstOrDefault().BLDate.Value;

                        if (blDate == null)
                        {
                            blDate = invoiceInformation.InvoiceDate;
                        }
                    }
                    else
                    {
                        blDate = invoiceInformation.InvoiceDate;
                    }

                    var fxRates = CommonRules.GetFxRateInformation((DateTime)blDate, invoiceInformation.Currency, company);

                    if (accountingSetup != null && fxRates.AreAllFilled() && company != null && vat != null)
                    {
                        accountingDocument = await CommonRules.CreateAccountingDocument(_masterDataService, _identityService.GetUserAtlasId(), postOpClosedPrivilege, docId, docTypeId, CommonRules.BaseCurrency, fxRates.FxRateInvoiceCurrency, accountingSetup, invoiceInformation, null, blDate);

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

                            CommonRules.PostingLineIdOrder(accountingDocument.AccountingDocumentLines);

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

                            _logger.LogInformation("Doc with id {Atlas_DocId}.", docId);
                        }
                        else
                        {
                            throw new Exception("Unable to create document header and lines");
                        }
                    }
                    else
                    {
                        throw new Exception("Unable to create document header and lines. Insufficient Information");
                    }
                }
                else
                {
                    throw new Exception("Unable to create document header and lines. There is no section information available.");
                }
            }
            else
            {
                throw new Exception("Unable to create document header and lines. There is no invoice information available.");
            }

            return(accountingDocument);
        }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
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);
        }
        private async Task <AccountingDocument> GetInformationForRevaluation(
            bool postOpClosedPrivilege,
            long transactionDocumentId,
            int docTypeId,
            AccountingSetupDto accountingSetup,
            Company company,
            DateTime companyDate,
            RevaluationInformationDto revalInformation)
        {
            AccountingDocument accountingDocument = null;

            if (accountingSetup != null)
            {
                // Creating the accounting header
                accountingDocument = new AccountingDocument()
                {
                    UserCreator           = _identityService.GetUserAtlasId(),
                    TransactionDocumentId = transactionDocumentId,
                    ProvinceId            = null,
                    OriginalReferenceId   = null,
                    Roe     = 1,
                    RoeType = "D",
                    TransactionDocumentTypeId = docTypeId,
                    AcknowledgementDate       = null,
                    CurrencyCode      = revalInformation.CurrencyCode,
                    DocumentDate      = revalInformation.PaymentDocumentDate,
                    ValueDate         = revalInformation.PaymentDocumentDate,
                    GLDate            = revalInformation.PaymentDocumentDate,
                    AccountingPeriod  = CommonRules.CalculateAccountPeriod(accountingSetup, revalInformation.PaymentDocumentDate, postOpClosedPrivilege),
                    AccountingDate    = CommonRules.CalculateAccountPeriod(accountingSetup, revalInformation.PaymentDocumentDate, postOpClosedPrivilege),
                    OriginalValueDate = revalInformation.PaymentDocumentDate
                };

                var documentReference = revalInformation.ExistingDocumentMatchingInfo.FirstOrDefault(b => b.TransactionDocumentId == transactionDocumentId).DocumentReference;

                // Creation of a copy of the document matching in which we will:
                // - update the roe of the values in all ccies
                // - sign the value in a "Accounting lines" oriented way
                List <InputInfoLinesForRevaluation> inputInfoLinesForRevaluationList = new List <InputInfoLinesForRevaluation>();
                foreach (var item in revalInformation.DocumentMatchingForMatchedDocuments)
                {
                    int inversionFactor = 1;
                    switch ((TransactionDocumentType)item.TransactionDocumentTypeId)
                    {
                    case TransactionDocumentType.CashReceipt:
                    case TransactionDocumentType.PurchaseInvoice:
                    case TransactionDocumentType.CreditNote:
                        inversionFactor = -1;
                        break;

                    case TransactionDocumentType.CashPay:
                    case TransactionDocumentType.SalesInvoice:
                    case TransactionDocumentType.DebitNote:
                    case TransactionDocumentType.ManualRegularJournal:
                        inversionFactor = 1;
                        break;
                    }

                    var inputInfoLinesForRevaluation = new InputInfoLinesForRevaluation()
                    {
                        DepartmentId         = item.DepartmentId,
                        AccountingLineTypeId = item.AccountingLineTypeId,
                        Amount = item.Amount * inversionFactor,
                        FunctionalCcyAmount = item.FunctionalCcyAmount * inversionFactor,
                        StatutoryCcyAmount  = item.StatutoryCcyAmount * inversionFactor,
                    };

                    // Rounding the converted values to 2 digits (only if currencies are not the same)
                    if (revalInformation.MatchingCurrency != company.FunctionalCurrencyCode)
                    {
                        inputInfoLinesForRevaluation.FunctionalCcyAmount = Math.Round(inputInfoLinesForRevaluation.FunctionalCcyAmount.Value, 2, 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 (revalInformation.MatchingCurrency != company.StatutoryCurrencyCode)
                    {
                        inputInfoLinesForRevaluation.StatutoryCcyAmount = Math.Round(inputInfoLinesForRevaluation.StatutoryCcyAmount.Value, 2, 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
                    }

                    inputInfoLinesForRevaluationList.Add(inputInfoLinesForRevaluation);
                }

                // Summing by department and accountinglinetype
                var revaluationJournalClientListOne = inputInfoLinesForRevaluationList.GroupBy(d => new { d.DepartmentId, d.AccountingLineTypeId })
                                                      .Select(g => new
                {
                    g.Key.DepartmentId,
                    g.Key.AccountingLineTypeId,
                    Amount = g.Sum(s => s.Amount),
                    FunctionalCcyAmount = g.Sum(s => s.FunctionalCcyAmount),
                    StatutoryCcyAmount  = g.Sum(s => s.StatutoryCcyAmount),
                }).ToList();

                // Creation of the lines
                List <AccountingDocumentLine> accountingDocumentLines = new List <AccountingDocumentLine>();
                int postingLineId = 1;
                foreach (var item in revaluationJournalClientListOne)
                {
                    if (item.FunctionalCcyAmount.Value == 0 &&
                        item.StatutoryCcyAmount.Value == 0)
                    {
                        // We dont create reval lines if there is no difference in the values
                        continue;
                    }

                    AccountingDocumentLine accountingDocLine = new AccountingDocumentLine();
                    accountingDocLine.AssociatedAccountId  = revalInformation.CounterpartyId;
                    accountingDocLine.CostTypeCode         = revalInformation.CostTypeCode;
                    accountingDocLine.CostTypeId           = revalInformation.CostTypeId;
                    accountingDocLine.PaymentTermId        = null;
                    accountingDocLine.PaymentTermCode      = null;
                    accountingDocLine.DepartmentId         = item.DepartmentId;
                    accountingDocLine.AccountReferenceId   = null;
                    accountingDocLine.ClientAccountId      = revalInformation.CounterpartyId;
                    accountingDocLine.AccountReference     = accountingSetup.NominalCostTypeInfo.Where(x => x.CostTypeCode == revalInformation.CostTypeCode).FirstOrDefault().NominalAccountCode;
                    accountingDocLine.PostingLineId        = postingLineId;
                    accountingDocLine.AccountingCategoryId = (int)AccountingCategory.C;
                    accountingDocLine.AccountLineTypeId    = item.AccountingLineTypeId;
                    accountingDocLine.AccountReference     = item.AccountingLineTypeId == (int)AccountLineType.V ? accountingSetup.PurchaseLedgerControlClientCreditors : accountingSetup.SalesLedgerControlClientDebtors;
                    accountingDocLine.ClientReference      = null;
                    accountingDocLine.Narrative            = "Revaluation For Match";
                    accountingDocLine.Amount             = (-1) * item.Amount;
                    accountingDocLine.FunctionalCurrency = (-1) * item.FunctionalCcyAmount;
                    accountingDocLine.StatutoryCurrency  = (-1) * item.StatutoryCcyAmount;

                    //Diff Client
                    if (revalInformation.DifferentClientMatchFlagId != null)
                    {
                        var secRef = revalInformation.DocumentMatchingForMatchedDocuments.FirstOrDefault(i => i.DocumentType == DocumentType.MJL)?.DocumentReference;
                        accountingDocLine.SecondaryDocumentReference = secRef ?? revalInformation.CashByPickingReference;
                    }
                    else
                    {
                        accountingDocLine.SecondaryDocumentReference = revalInformation.CashByPickingReference;
                    }

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

                var accLinesOfTypeClient = revaluationJournalClientListOne.GroupBy(d => d.DepartmentId)
                                           .Select(g => new
                {
                    DepartmentId        = g.Key,
                    Amount              = (-1) * g.Sum(s => s.Amount),
                    FunctionalCcyAmount = (-1) * g.Sum(s => s.FunctionalCcyAmount),
                    StatutoryCcyAmount  = (-1) * g.Sum(s => s.StatutoryCcyAmount),
                }).ToList();

                foreach (var accLineOfTypeClient in accLinesOfTypeClient)
                {
                    if (accLineOfTypeClient.FunctionalCcyAmount.Value == 0 &&
                        accLineOfTypeClient.StatutoryCcyAmount.Value == 0)
                    {
                        // We dont create reval lines if there is no difference in the values
                        continue;
                    }

                    AccountingDocumentLine accountingDocumentLineFormanualDocumentMatching = new AccountingDocumentLine();
                    accountingDocumentLineFormanualDocumentMatching.CostTypeCode         = revalInformation.CostTypeCode;
                    accountingDocumentLineFormanualDocumentMatching.CostTypeId           = revalInformation.CostTypeId;
                    accountingDocumentLineFormanualDocumentMatching.PaymentTermId        = null;
                    accountingDocumentLineFormanualDocumentMatching.PaymentTermCode      = null;
                    accountingDocumentLineFormanualDocumentMatching.DepartmentId         = accLineOfTypeClient.DepartmentId;
                    accountingDocumentLineFormanualDocumentMatching.PostingLineId        = postingLineId;
                    accountingDocumentLineFormanualDocumentMatching.AccountingCategoryId = (int)AccountingCategory.N;
                    accountingDocumentLineFormanualDocumentMatching.AssociatedAccountId  = revalInformation.CounterpartyId;
                    accountingDocumentLineFormanualDocumentMatching.AccountLineTypeId    = (int)AccountLineType.L;
                    accountingDocumentLineFormanualDocumentMatching.ClientReference      = null;
                    accountingDocumentLineFormanualDocumentMatching.Narrative            = "Revaluation For Match";
                    accountingDocumentLineFormanualDocumentMatching.Amount             = 0;
                    accountingDocumentLineFormanualDocumentMatching.FunctionalCurrency = -accLineOfTypeClient.FunctionalCcyAmount;
                    accountingDocumentLineFormanualDocumentMatching.StatutoryCurrency  = -accLineOfTypeClient.StatutoryCcyAmount;

                    //Diff Client
                    if (revalInformation.DifferentClientMatchFlagId != null)
                    {
                        var secRef = revalInformation.DocumentMatchingForMatchedDocuments.FirstOrDefault(i => i.DocumentType == DocumentType.MJL)?.DocumentReference;
                        accountingDocumentLineFormanualDocumentMatching.SecondaryDocumentReference = secRef ?? revalInformation.CashByPickingReference;
                    }
                    else
                    {
                        accountingDocumentLineFormanualDocumentMatching.SecondaryDocumentReference = revalInformation.CashByPickingReference;
                    }

                    accountingDocumentLineFormanualDocumentMatching.AccountReference      = revalInformation.AccountNumber;
                    accountingDocumentLineFormanualDocumentMatching.ClientReference       = null;
                    accountingDocumentLineFormanualDocumentMatching.AssociatedAccountCode = revalInformation.CounterpartyCode;

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

                accountingDocument.AccountingDocumentLines = accountingDocumentLines;
                accountingDocument.StatusId = PostingStatus.Authorised;
            }

            return(accountingDocument);
        }
Exemplo n.º 17
0
        private async Task <PostingStatus> ReturnAccountingDocumentStatus(AccountingDocument accountingDocument, DateTime companyDate, string company, AccountingSetupDto accountingSetup)
        {
            accountingDocument.ErrorMessage = string.Empty;

            // Sanity Check
            bool isLegSumValid = CommonRules.CheckSanityCheck(accountingDocument);
            MappingErrorMessages messages;

            if (isLegSumValid)
            {
                if (CommonRules.CheckFxRateConverted(accountingDocument))
                {
                    bool ifInterface = await CommonRules.CheckIfInterface(_accountingQueries, accountingDocument.TransactionDocumentId, company);

                    messages = await CommonRules.CheckMappingError(_accountingQueries, accountingDocument.AccountingDocumentLines, company, accountingDocument.TransactionDocumentTypeId);

                    if (ifInterface)
                    {
                        if (messages.C2CCode == null)
                        {
                            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.DepartmentAlternativeCode == null)
                        {
                            accountingDocument.ErrorMessage += "Department Alternative Code Is NULL ;";
                        }

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

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

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

                        return(PostingStatus.Held);
                    }

                    if (accountingDocument.DocumentDate.Date > companyDate.Date)
                    {
                        accountingDocument.ErrorMessage = "Future document date";
                        return(PostingStatus.Held);
                    }

                    if (!CommonRules.IsLastMonthForAccountingOpen(accountingSetup.LastMonthClosed, accountingDocument.AccountingDate, accountingSetup.NumberOfOpenPeriod))
                    {
                        accountingDocument.ErrorMessage = "Month is not yet open for accounting period";
                        return(PostingStatus.Held);
                    }

                    return(PostingStatus.Authorised);
                }
                else
                {
                    accountingDocument.ErrorMessage = "No Fxrates Found";
                    return(PostingStatus.Held);
                }
            }
            else
            {
                accountingDocument.ErrorMessage = "Unbalanced document";
                return(PostingStatus.Held);
            }
        }
Exemplo n.º 18
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);
        }