示例#1
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);
        }
示例#2
0
        internal static DateTime CalculateAccountPeriod(AccountingSetupDto accountingSetup, DateTime documentDate, bool isPostOpClosedPrivilege)
        {
            if (accountingSetup == null)
            {
                throw new Exception("Unable to create document header and lines");
            }

            if (IsLastMonthForOperationOpen(accountingSetup.LastMonthClosedForOperation, documentDate))
            {
                return(documentDate);
            }
            else
            {
                if (isPostOpClosedPrivilege)
                {
                    if (IsLastMonthForAccountingOpen(accountingSetup.LastMonthClosed, documentDate, accountingSetup.NumberOfOpenPeriod))
                    {
                        return(documentDate);
                    }
                    else
                    {
                        if (IsLastMonthForAccountingOpen(accountingSetup.LastMonthClosed, accountingSetup.LastMonthClosedForOperation, accountingSetup.NumberOfOpenPeriod))
                        {
                            return(accountingSetup.LastMonthClosedForOperation);
                        }

                        return(accountingSetup.LastMonthClosedForOperation.AddMonths(1));
                    }
                }

                return(accountingSetup.LastMonthClosedForOperation.AddMonths(1));
            }
        }
        private DateTime CalculateAccountPeriod(AccountingSetupDto accountingSetup, DateTime documentDate)
        {
            bool isPostOpClosedPrivilege = false;

            isPostOpClosedPrivilege = CheckPrivileges().Result;

            if (IsLastMonthForOperationOpen(accountingSetup.LastMonthClosedForOperation, documentDate))
            {
                return(documentDate);
            }
            else
            {
                if (isPostOpClosedPrivilege)
                {
                    if (IsLastMonthForAccountingOpen(accountingSetup.LastMonthClosed, documentDate, accountingSetup.NumberOfOpenPeriod))
                    {
                        return(documentDate);
                    }
                    else
                    {
                        if (IsLastMonthForAccountingOpen(accountingSetup.LastMonthClosed, accountingSetup.LastMonthClosedForOperation, accountingSetup.NumberOfOpenPeriod))
                        {
                            return(accountingSetup.LastMonthClosedForOperation);
                        }

                        return(accountingSetup.LastMonthClosedForOperation.AddMonths(1));
                    }
                }

                return(accountingSetup.LastMonthClosedForOperation.AddMonths(1));
            }
        }
        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);
                }
            }
        }
示例#5
0
        internal async Task <int> GetDocumentReferenceYear(DateTime documentDate, string company)
        {
            bool isPostOpClosedPrivilege = false;
            int  documentDateYear        = 0;

            isPostOpClosedPrivilege = true; // await CheckPrivileges();
            AccountingSetupDto accountingSetup = await _accountingQueries.GetAccountingSetup(company);

            if (IsLastMonthOpenForAccounting(accountingSetup.LastMonthClosed, documentDate, accountingSetup.NumberOfOpenPeriod))
            {
                if (IsOperationLastMonthClosed(accountingSetup.LastMonthClosedForOperation, documentDate))
                {
                    documentDateYear = documentDate.Year;
                }
                else
                {
                    if (isPostOpClosedPrivilege)
                    {
                        documentDateYear = documentDate.Year;
                    }
                    else
                    {
                        int nextOpenMonthForOperations = accountingSetup.LastMonthClosedForOperation.Month + 1;
                        if (nextOpenMonthForOperations > 12)
                        {
                            documentDateYear = accountingSetup.LastMonthClosedForOperation.Year + 1;
                        }
                        else
                        {
                            documentDateYear = accountingSetup.LastMonthClosedForOperation.Year;
                        }
                    }
                }
            }
            else
            {
                int nextOpenMonthForOperations = accountingSetup.LastMonthClosedForOperation.Month + 1;
                if (nextOpenMonthForOperations > 12)
                {
                    documentDateYear = accountingSetup.LastMonthClosedForOperation.Year + 1;
                }
                else
                {
                    documentDateYear = accountingSetup.LastMonthClosedForOperation.Year;
                }
            }

            return(documentDateYear);
        }
示例#6
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);
        }
        private async Task <AccountingDocumentLine> CreateAccountingDocumentLineForFJDocument(int docTypeId, int postingLineId, AccountingSetupDto accountingSetup, AccountLineType lineType, Company company, FxRateInformation fxRates, FxSettlementDocumentDto fxSettlementDocument)
        {
            AccountingDocumentLine accountingDocumentLine = new AccountingDocumentLine();

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

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

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

                    decimal dealtAmount = fxSettlementDocument.Amount;

                    decimal settledAmount = accountingDocumentLine.Amount;

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

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

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

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

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

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

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

                        decimal crossSettlementROESettCcy = 1;

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

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

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

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

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

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

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

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

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

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

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

                    break;

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

                    break;

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

            return(accountingDocumentLine);
        }
        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);
        }
示例#9
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);
        }
示例#10
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);
        }
        private async Task <IEnumerable <AccountingDocumentLine> > CreateAccountingDocumentLineForCashPaidCashInAnotherCcy(int docTypeId, Company company, FxRateInformation fxRates, AccountingSetupDto accountingSetup, CashInformationDto cashInformation, CashInformationDto paidCashInformation)
        {
            List <AccountingDocumentLine> accountingDocumentLines = new List <AccountingDocumentLine>();

            int postingLineId = 1;

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

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

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

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

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

            accountingDocumentLineForPayment.Amount = directionFactor * paidCashInformation.Amount;

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

            var cashMatchingTotal = accountingDocumentLineForPayment.Amount;

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

            postingLineId++;

            accountingDocumentLines.Add(accountingDocumentLineForPayment);

            decimal totalCostAmountForClient = 0;

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

                    AccountingDocumentLine accountingDocumentLineForAdditionalCosts = new AccountingDocumentLine();

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

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

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

                    decimal?additionalCostAmount = accountingDocumentLineForAdditionalCosts.Amount;

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

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

                    postingLineId++;

                    accountingDocumentLines.Add(accountingDocumentLineForAdditionalCosts);
                }
            }

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

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

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

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

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

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

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

            postingLineId++;
            accountingDocumentLines.Add(accountingDocumentLineForBank);

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

            int postingLineId = 1;

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

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

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

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

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

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

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

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

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

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

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

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

                    AccountingDocumentLine accountingDocumentLineForAdditionalCosts = new AccountingDocumentLine();

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

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

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

                    decimal?additionalCostAmount = accountingDocumentLineForAdditionalCosts.Amount;

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

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

                    postingLineId++;

                    accountingDocumentLines.Add(accountingDocumentLineForAdditionalCosts);
                }
            }

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

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

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

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

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

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

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

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

            postingLineId++;
            accountingDocumentLines.Add(accountingDocumentLineForBank);

            return(accountingDocumentLines);
        }
示例#13
0
        private async Task <bool> CheckIfDocumentDateAccountingPeriodValid(ManualJournalDocument manualJournalDocument, AccountingSetupDto accountingSetup)
        {
            bool allChecksPassed = true;

            bool isPostOpClosedPrivilege = false;

            isPostOpClosedPrivilege = await CheckPrivileges();

            if (manualJournalDocument.TransactionDocumentTypeId == (int)MasterDocumentType.JL)
            {
                if (IsLastMonthForAccountingOpen(accountingSetup.LastMonthClosed, manualJournalDocument.AccountingPeriod, accountingSetup.NumberOfOpenPeriod, accountingSetup.LastMonthClosedForOperation))
                {
                    if (!isPostOpClosedPrivilege)
                    {
                        if (IsPeriodBeforeLastMonthForOperation(accountingSetup.LastMonthClosedForOperation, manualJournalDocument.AccountingPeriod))
                        {
                            allChecksPassed = false;
                        }
                    }
                }
                else
                {
                    allChecksPassed = false;
                }
            }
            else if (manualJournalDocument.TransactionDocumentTypeId == (int)MasterDocumentType.TA)
            {
                bool checkAccountingPeriod = IsLastMonthForAccountingOpen(accountingSetup.LastMonthClosed, manualJournalDocument.AccountingPeriod, accountingSetup.NumberOfOpenPeriod, accountingSetup.LastMonthClosedForOperation);
                bool checkDocumentDate     = IsLastMonthForAccountingOpen(accountingSetup.LastMonthClosed, manualJournalDocument.DocumentDate, accountingSetup.NumberOfOpenPeriod, accountingSetup.LastMonthClosedForOperation);
                if (checkAccountingPeriod && checkDocumentDate)
                {
                    if (!isPostOpClosedPrivilege)
                    {
                        bool checkAccountingPeriodInlastMonthOperations = IsPeriodBeforeLastMonthForOperation(accountingSetup.LastMonthClosedForOperation, manualJournalDocument.AccountingPeriod);
                        bool checkDocumentDateInlastMonthOperations     = IsPeriodBeforeLastMonthForOperation(accountingSetup.LastMonthClosedForOperation, manualJournalDocument.DocumentDate);
                        if (checkAccountingPeriodInlastMonthOperations || checkDocumentDateInlastMonthOperations)
                        {
                            allChecksPassed = false;
                        }
                    }
                }
                else
                {
                    allChecksPassed = false;
                }
            }

            return(allChecksPassed);
        }
        /// <summary>
        /// Handling the creation of an accounting document
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <IEnumerable <long> > Handle(CreateAccountingDocumentCommand request, CancellationToken cancellationToken)
        {
            _unitOfWork.BeginTransaction();
            IEnumerable <AccountingDocumentCreationStatus> accountingDocumentCreationStatusList = null;
            long accountingId = -1;
            IEnumerable <long> createdAccountingDocumentIds = null;

            Company company = null;

            try
            {
                TransactionDocumentDto transactionDocument = await _accountingQueries.GetTransactionDocumentTypeByDocId(request.DocId, request.Company);

                if (transactionDocument == null)
                {
                    throw new NotFoundException("TransactionDocument", request.DocId);
                }

                if (transactionDocument.TransactionDocumentTypeId == (int)DocumentType.CP ||
                    transactionDocument.TransactionDocumentTypeId == (int)DocumentType.CI)
                {
                    // Note: the "CreateAccounting" background process is called also for cash status updates, after a
                    // 'response' received from the TRAX system. In this context, the caller just sends a "creaete accounting doc" message
                    // Below, we are checking the existance of the acc doc for the cash (through the SP update).

                    // Updates the document date and the value date of the given cash
                    accountingId = await _accountingDocumentRepository.UpdateAccountingDocumentForTraxResponse(request.DocId, request.Company);

                    // If the doc accounting doc of the cash exists, then accountingId is >0...
                }

                if (accountingId > 0)
                {
                    // ... and in this case, we just queue the cash for posting. As a reminder, the TRAX-ed cash cannot have the “Authorized for posting” flag
                    // set by the user (the UI prevents it)
                    List <long> listOfDocId = new List <long>();
                    listOfDocId.Add(accountingId);
                    await AuthorizeForPosting(listOfDocId, request.Company, request.PostOpClosedPolicy);

                    _unitOfWork.Commit();
                }
                else
                {
                    List <AccountingDocument> accountingDocuments = new List <AccountingDocument>();
                    int docTypeId = transactionDocument.TransactionDocumentTypeId;
                    AccountingSetupDto accountingSetup = await _accountingQueries.GetAccountingSetup(docTypeId, request.Company);

                    var transactionIdOfReversedDoc = await _accountingQueries.GetTransactionDocumentIdByReversalId(request.DocId, request.Company);

                    if (transactionIdOfReversedDoc != null)
                    {
                        // We are in the situation of a reversal
                        var accountingCreationStatusList = await _accountingDocumentRepository.CreateAccountingDocumentForReversal(
                            request.DocId,                      // TransDocId of the Reversal
                            transactionIdOfReversedDoc.Value,   // TransDocId of the Reversed (original)
                            request.Company,
                            request.PostOpClosedPolicy);
                        await EnqueueBulkPostingProcessorMessage(
                            accountingCreationStatusList,
                            request.Company,
                            request.PostOpClosedPolicy);
                    }
                    else
                    {
                        // The document is a standard non-reversed document for which to generate the accounting document
                        company = await _masterDataService.GetCompanyByIdAsync(request.Company);

                        long transactionDocumentId = request.DocId;
                        var  companyDate           = await _systemDateTimeService.GetCompanyDate(request.Company);

                        switch (docTypeId)
                        {
                        case (int)DocumentType.PI:
                        case (int)DocumentType.SI:
                        case (int)DocumentType.CN:
                        case (int)DocumentType.DN:
                            accountingDocuments.Add(await GetInformationForInvoice(request.PostOpClosedPolicy, transactionDocumentId, docTypeId, accountingSetup, company, request.Company, companyDate));
                            break;

                        case (int)DocumentType.CP:
                        case (int)DocumentType.CI:
                            accountingDocuments.AddRange(await GetInformationForCash(request.PostOpClosedPolicy, transactionDocumentId, docTypeId, accountingSetup, company, companyDate));

                            /*CashForCounterpartyDto cashForCounterpartyDto = null;
                             * cashForCounterpartyDto = await _accountingQueries.GetCashTypeIdForCounterParty(transactionDocumentId);
                             * if (cashForCounterpartyDto != null && cashForCounterpartyDto.CashTypeId == (int)CashSelectionType.PaymentDifferentClient && cashForCounterpartyDto.JLTypeId == (int)JLType.CounterPartyTransfer)
                             * {
                             *  accountingDocuments.Add(await GetInformationForCounterParty(request.PostOpClosedPolicy, cashForCounterpartyDto.TransactionDocumentId, docTypeId, accountingSetup, company, companyDate, cashForCounterpartyDto));
                             * }*/

                            break;

                        case (int)DocumentType.MJL:
                        case (int)DocumentType.MTA:
                            TransactionDocumentDto transactionDocumentDto = null;
                            transactionDocumentDto = await _accountingQueries.GetJLDocumentTypeByTransactionDocumentId(transactionDocumentId, company.CompanyId);

                            if (transactionDocumentDto != null && transactionDocumentDto.JLTypeId == 2)     // JLType = 2 = Reval
                            {
                                var revalInformation = await _accountingQueries.GetRevalInformationForAccountingDocument(
                                    transactionDocumentId, company.CompanyId);

                                var revalAccountingDocument = await GetInformationForRevaluation(
                                    request.PostOpClosedPolicy,
                                    transactionDocumentId,
                                    docTypeId,
                                    accountingSetup,
                                    company,
                                    companyDate,
                                    revalInformation);

                                if (revalAccountingDocument != null &&
                                    revalAccountingDocument.AccountingDocumentLines != null &&
                                    revalAccountingDocument.AccountingDocumentLines.Count() > 0)
                                {
                                    // We create the accounting document for reval only if it contains non-0 records
                                    accountingDocuments.Add(revalAccountingDocument);
                                    // Stores a new document matching in the database, to link the revaluation record to it, so that
                                    // it appears as linked in the "delete match" screen
                                    await _invoicingRepository.CreateDocumentMatchingAsync(new DocumentMatching
                                    {
                                        CompanyId             = company.CompanyId,
                                        MatchFlagId           = revalInformation.MatchFlagId,
                                        TransactionDocumentId = transactionDocumentId,
                                        ValueDate             = revalInformation.PaymentDocumentDate,
                                        DepartmentId          = revalInformation.DepartmentId
                                    });
                                }
                                else
                                {
                                    // We delete the Revaluation Transaction document if no accounting
                                    // document has to be associated to it
                                    await _invoicingRepository.DeleteManualJLOrRevaluationAsync(
                                        transactionDocumentId, request.Company);
                                }
                            }
                            else
                            {
                                (AccountingDocument adTAJL, MonthEndTADocumentDto MonthEnd) = await CreateAccountingForTAandJL(request.PostOpClosedPolicy, transactionDocument, transactionDocumentId, docTypeId, accountingSetup, company, companyDate);

                                if (docTypeId == (int)DocumentType.MTA)
                                {
                                    var accountingDocumentPerAccuralNumberTA = await CreateAccountingDocumentPerAccuralNumberTA(adTAJL, MonthEnd, request.Company, transactionDocumentId);

                                    accountingDocuments.AddRange(accountingDocumentPerAccuralNumberTA);
                                }
                                else
                                {
                                    accountingDocuments.Add(adTAJL);
                                }
                            }

                            break;

                        case (int)DocumentType.FJ:
                            accountingDocuments.Add(await CreateAccountingDocumentForFxDeal(request.PostOpClosedPolicy, transactionDocumentId, docTypeId, accountingSetup, company, request.Company, companyDate));
                            break;
                        }

                        var createdAccountingDocuments = await CreateAccountingDocumentsAndEnqueueForPosting(request.Company, accountingDocuments, request.PostOpClosedPolicy);

                        createdAccountingDocumentIds = createdAccountingDocuments.Select(a => a.AccountingId);
                    }

                    _unitOfWork.Commit();
                }

                if (transactionDocument.TransactionDocumentTypeId == (int)DocumentType.FJ && accountingDocumentCreationStatusList != null)
                {
                    long createdAccountingId = accountingDocumentCreationStatusList.ToList().FirstOrDefault().AccountingId;

                    await UpdateFxDealInformation(company.Id, request.DocId, createdAccountingId, request.Company);
                }

                _logger.LogInformation("Doc with id {Atlas_DocId}.", request.DocId);
            }
            catch (Exception ex)
            {
                _logger.LogError("Exception on Creating Accouting Document for {Atlas_DocId}.", request.DocId, ex);
                _unitOfWork.Rollback();

                throw;
            }

            return(createdAccountingDocumentIds);
        }
        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);
        }
示例#17
0
        private async Task <(AccountingDocument, MonthEndTADocumentDto)> CreateAccountingForTAandJL(bool postOpClosedPrivilege, TransactionDocumentDto transactionDocument, long docId, int docTypeId, AccountingSetupDto accountingSetup, Company company, DateTime companyDate)
        {
            var monthEnd = await _accountingQueries.GetMonthEndTAbyTransactionDocumentId(company.CompanyId, docId);

            AccountingDocument accountingDocument = null;

            if (monthEnd == null)
            {
                accountingDocument = await GetInformationForManualJournal(postOpClosedPrivilege, docId, docTypeId, accountingSetup, company, companyDate);

                accountingDocument.StatusId     = transactionDocument.AuthorizedForPosting ? accountingDocument.StatusId : PostingStatus.Incomplete;
                accountingDocument.ErrorMessage = transactionDocument.AuthorizedForPosting ? accountingDocument.ErrorMessage : string.Empty;
            }
            else
            {
                accountingDocument = await GetInformationForMonthEndTA(postOpClosedPrivilege, docId, docTypeId, accountingSetup, company, companyDate, monthEnd);
            }

            return(accountingDocument, monthEnd);
        }
示例#18
0
        public async Task <ManualJournalResponse> Handle(CreateManualJournalDocumentCommand request, CancellationToken cancellationToken)
        {
            _unitOfWork.BeginTransaction();
            AccountingSetupDto accountingSetup = null;
            Company            company         = null;

            try
            {
                string documentLabel              = string.Empty;
                string year                       = string.Empty;
                int    documentReferenceYear      = 0;
                string documentReferenceYearValue = string.Empty;

                ManualJournalDocument manualJournalDocument = request.ManualJournal;
                company = await _masterDataService.GetCompanyByIdAsync(request.Company);

                CommonRules commonRules = new CommonRules(_accountingQueries, _authorizationService, _identityService);

                if (manualJournalDocument.AccountingPeriod.Year < manualJournalDocument.DocumentDate.Year ||
                    (manualJournalDocument.AccountingPeriod.Year <= manualJournalDocument.DocumentDate.Year &&
                     manualJournalDocument.AccountingPeriod.Month < manualJournalDocument.DocumentDate.Month))
                {
                    throw new AtlasBusinessException("A/c period should not be before doc. Date");
                }

                accountingSetup = await _accountingQueries.GetAccountingSetup(request.Company);

                if (accountingSetup != null)
                {
                    if (await CheckIfDocumentDateAccountingPeriodValid(manualJournalDocument, accountingSetup))
                    {
                        if (company.IsProvinceEnable)
                        {
                            foreach (var item in manualJournalDocument.ManualJournalLines)
                            {
                                item.ProvinceId = company.DefaultProvinceId;
                                item.BranchId   = company.DefaultBranchId;
                            }
                        }
                        else
                        {
                            foreach (var item in manualJournalDocument.ManualJournalLines)
                            {
                                item.ProvinceId = item.BranchId = null;
                            }
                        }
                        if (manualJournalDocument.TransactionDocumentTypeId == (int)MasterDocumentType.TA ||
                            manualJournalDocument.TransactionDocumentTypeId == (int)MasterDocumentType.JL)
                        {
                            documentLabel         = Enum.GetName(typeof(MasterDocumentType), manualJournalDocument.TransactionDocumentTypeId);
                            year                  = manualJournalDocument.DocumentDate.Year.ToString(CultureInfo.InvariantCulture).Substring(2, 2);
                            documentReferenceYear = await commonRules.GetDocumentReferenceYear(manualJournalDocument.DocumentDate, request.Company);

                            documentReferenceYearValue = documentReferenceYear.ToString(System.Globalization.CultureInfo.InvariantCulture).Substring(2, 2);
                        }

                        if (manualJournalDocument.TransactionDocumentTypeId == (int)MasterDocumentType.JL)
                        {
                            manualJournalDocument.JLTypeId = (int)JLType.ManualRegularJournal;
                        }
                        else if (manualJournalDocument.TransactionDocumentTypeId == (int)MasterDocumentType.TA)
                        {
                            if (manualJournalDocument.TATypeId != null)
                            {
                                manualJournalDocument.TATypeId = (int)TAType.ManualMarkToMarket;
                            }
                            else
                            {
                                manualJournalDocument.TATypeId = (int)TAType.ManualTemporaryAdjustment;
                            }
                        }


                        int referencenumber = await _manualJournalQueries.GetManualDocumentReferenceValues(request.Company, (int)manualJournalDocument.TransactionDocumentTypeId, documentReferenceYear);

                        manualJournalDocument.YearNumber = referencenumber;

                        manualJournalDocument.Year = documentReferenceYear;

                        manualJournalDocument.DocumentReference = string.Concat(documentLabel, documentReferenceYearValue, string.Format(CultureInfo.InvariantCulture, "{0:D5}", referencenumber));

                        var objResponse = await _manualJournalRepository.CreateManualJournal(manualJournalDocument, request.Company);

                        var authorizationResult = await _authorizationService.AuthorizeAsync(_identityService.GetUser(), Policies.PostOpClosedPolicy);

                        var content = new JObject();
                        content.Add(new JProperty("docId", objResponse.TransactionDocumentId));
                        content.Add(new JProperty("postOpClosedPolicy", authorizationResult.Succeeded));

                        Atlas.Application.Core.Entities.ProcessMessage message = new Atlas.Application.Core.Entities.ProcessMessage​
                        {
                            ProcessTypeId = (long)Atlas.Application.Core.Entities.ProcessType.AtlasAccountingDocumentProcessor,
                            CompanyId     = request.Company,
                            Content       = content.ToString(),
                        };

                        await _processMessageService.SendMessage(message);

                        _unitOfWork.Commit();

                        return(objResponse);
                    }
                    else
                    {
                        throw new AtlasSecurityException($"Please check the document date and accounting period");
                    }
                }
                else
                {
                    throw new AtlasSecurityException($"No Accounting Setup found");
                }
            }
            catch
            {
                _unitOfWork.Rollback();

                throw;
            }
        }
示例#19
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 <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);
        }
示例#21
0
        internal static async Task <PostingStatus> GetAccountingDocumentStatus(AccountingSetupDto accountingSetup, IAccountingDocumentQueries accountingQuerie, AccountingDocument accountingDocument, string company, DateTime companyDate, InvoiceInformationDto invoiceInformation = null, CashInformationDto cashInformation = null, RevaluationInformationDto revalInformation = null, CounterpartyInformationDto counterpartyInformation = null)
        {
            accountingDocument.ErrorMessage = string.Empty;

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

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

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

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

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

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

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

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

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

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

                        return(PostingStatus.Held);
                    }

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

                    return(PostingStatus.Authorised);
                }
                else
                {
                    accountingDocument.ErrorMessage = "No Fxrate found";
                    return(PostingStatus.Held);
                }
            }
            else
            {
                accountingDocument.ErrorMessage = "Unbalanced document";
                return(PostingStatus.Held);
            }
        }
        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);
        }
示例#23
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);
        }
示例#24
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);
            }
        }
示例#25
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);
        }