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); }
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); } } }
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); }
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); }
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); }
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); }
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); }
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); }
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; } }
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); }
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); }
private async Task <AccountingDocumentLine> CreateAccountingDocumentLineForInvoice( AccountingDocumentLineType accountingDocumentLineType, InvoiceInformationDto invoiceInformation, IEnumerable <SectionsInformationDto> sectionsInformation, IEnumerable <Vat> vats, Company company, AccountingSetupDto accountingSetup, FxRateInformation fxRates, int postingLineId, int index = 0, List <AccountingDocumentLine> accountingDocumentLines = null) { string whiteSpace = " "; InvoiceFunction invoiceFunction = CommonRules.CheckInvoiceType(invoiceInformation.InvoiceType); AccountingDocumentLine accountingDocumentLine = new AccountingDocumentLine(); SectionsInformationDto latestSectionsInformation = sectionsInformation.OrderByDescending(x => x.BLDate).FirstOrDefault(); accountingDocumentLine.AssociatedAccountCode = invoiceInformation.CounterpartyCode; accountingDocumentLine.ClientReference = invoiceInformation.ExternalReference; accountingDocumentLine.PaymentTermCode = invoiceInformation.PaymentTerms; if (invoiceFunction == InvoiceFunction.Commercial) { if (invoiceInformation.CostTypeCode != null) { accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } else { accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? accountingSetup.PurchaseInvoice : accountingSetup.SalesInvoice; } accountingDocumentLine.Narrative = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode); } else if (invoiceFunction == InvoiceFunction.GoodsAndCost) { if (invoiceInformation.CostTypeCode != null) { accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } else { accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.GoodsCostPurchase ? accountingSetup.PurchaseInvoice : accountingSetup.SalesInvoice; } accountingDocumentLine.Narrative = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode); } else if (invoiceFunction == InvoiceFunction.Cost) { accountingDocumentLine.Narrative = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, invoiceInformation.InvoiceLines.ToList()[index].CostType); accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceLines.ToList()[index].CostType; } else if (invoiceFunction == InvoiceFunction.Washout) { if (invoiceInformation.InvoiceLines.ToList()[index].CostDirectionId != null) { accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceLines.ToList()[index].CostType; } else { int purchaseIndex = index % 2 == 0 ? index + 1 : index - 1; var saleLines = invoiceInformation.InvoiceLines.ToList()[index]; var purchaseLines = invoiceInformation.InvoiceLines.ToList()[purchaseIndex]; accountingDocumentLine.CostTypeCode = saleLines.InvoiceLineAmount > purchaseLines.InvoiceLineAmount ? accountingSetup.WashoutInvoiceGains : accountingSetup.WashoutInvoiceLoss; } accountingDocumentLine.Narrative = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode); } else if (invoiceFunction == InvoiceFunction.Cancelled) { accountingDocumentLine.CostTypeCode = invoiceInformation.TransactionDocumentTypeId == (int)MasterDocumentType.CN ? accountingSetup.CancellationLoss : accountingSetup.CancellationGain; accountingDocumentLine.Narrative = invoiceInformation.ExternalReference; } switch (accountingDocumentLineType) { case AccountingDocumentLineType.Client: accountingDocumentLine.PostingLineId = postingLineId; accountingDocumentLine.ContractSectionCode = latestSectionsInformation.ContractSectionCode; accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.C; accountingDocumentLine.VATTurnover = null; accountingDocumentLine.VATCode = null; accountingDocumentLine.AccountReference = (invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase || invoiceInformation.InvoiceType == (int)Entities.InvoiceType.GoodsCostPurchase) ? accountingSetup.PurchaseLedgerControlClientCreditors : accountingSetup.SalesLedgerControlClientDebtors; accountingDocumentLine.CommodityId = latestSectionsInformation.CommodityId; accountingDocumentLine.CharterId = latestSectionsInformation.CharterId; accountingDocumentLine.DepartmentId = latestSectionsInformation.DepartmentId; accountingDocumentLine.SectionId = latestSectionsInformation.SectionId; accountingDocumentLine.SecondaryDocumentReference = null; accountingDocumentLine.ClientAccount = invoiceInformation.CounterpartyCode; if (invoiceFunction == InvoiceFunction.Commercial) { // The quantity of the client line should be the Sum of quantities of Nominal Legs accountingDocumentLine.Quantity = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(x => x.Quantity).Sum(); accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? (int)AccountLineType.V : (int)AccountLineType.C; decimal totalTaxAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum(); accountingDocumentLine.Amount = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? -(invoiceInformation.SumOfInvoiceTotalAmount + totalTaxAmount) : invoiceInformation.SumOfInvoiceTotalAmount - totalTaxAmount; // Binding the cost type associated with business sector if business sector posting is configured if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null) { accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } } else if (invoiceFunction == InvoiceFunction.Cost) { decimal totalNominalAmount = 0; foreach (InvoiceLinesDto invoiceLineNominalClient in invoiceInformation.InvoiceLines) { totalNominalAmount += invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CostCredit || invoiceLineNominalClient.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineNominalClient.InvoiceLineAmount : -invoiceLineNominalClient.InvoiceLineAmount; } decimal totalTaxAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum(); accountingDocumentLine.Amount = totalNominalAmount >= 0 ? -invoiceInformation.SumOfInvoiceTotalAmount : invoiceInformation.SumOfInvoiceTotalAmount; accountingDocumentLine.Amount = accountingDocumentLine.Amount - totalTaxAmount; accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.External ? (int)AccountLineType.V : (int)AccountLineType.C; accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceLines.FirstOrDefault(line => line.InvoiceLineAmount == invoiceInformation.InvoiceLines.Max(max => max.InvoiceLineAmount)).CostType; accountingDocumentLine.Narrative = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode); accountingDocumentLine.AccountReference = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.External ? accountingSetup.PurchaseLedgerControlClientCreditors : accountingSetup.SalesLedgerControlClientDebtors; accountingDocumentLine.Quantity = 0; } else if (invoiceFunction == InvoiceFunction.Washout) { // [WASHOUT_E6] Well, this works only if the washout has only one match (ie only one purchase invoice, one sales invoice...), which is the case // for E6 but which is not true for after e6... InvoiceLinesDto invoiceLinePurchase = invoiceInformation.InvoiceLines.OrderBy(x => Math.Abs(x.InvoiceLineAmount)).FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialPurchase); InvoiceLinesDto invoiceLineSale = invoiceInformation.InvoiceLines.FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialSale); decimal totalNominalAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum(); decimal totalTaxAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum(); accountingDocumentLine.ContractSectionCode = invoiceLinePurchase.PhysicalContractCode; accountingDocumentLine.Quantity = invoiceInformation.InvoiceLines.Where(x => x.Type == (int)Entities.ContractType.CommercialPurchase).Select(x => x.Quantity).Sum(); accountingDocumentLine.Amount = -(totalNominalAmount + totalTaxAmount); //--change done as part of PBI-22258 accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.Inhouse ? (int)AccountLineType.C : (int)AccountLineType.V; accountingDocumentLine.AccountReference = accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.C ? accountingSetup.SalesLedgerControlClientDebtors : accountingSetup.PurchaseLedgerControlClientCreditors; accountingDocumentLine.SectionId = invoiceLinePurchase.SectionId; accountingDocumentLine.CostTypeCode = totalNominalAmount < 0 ? accountingSetup.WashoutInvoiceGains : accountingSetup.WashoutInvoiceLoss; } else if (invoiceFunction == InvoiceFunction.Cancelled) { InvoiceLinesDto invoiceLine = invoiceInformation.InvoiceLines.FirstOrDefault(); decimal totalNominalAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum(); decimal totalTaxAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum(); accountingDocumentLine.ContractSectionCode = invoiceLine.PhysicalContractCode; accountingDocumentLine.Quantity = invoiceLine.Quantity; accountingDocumentLine.Amount = -(totalNominalAmount + totalTaxAmount); accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.Inhouse ? (int)AccountLineType.C : (int)AccountLineType.V; accountingDocumentLine.AccountReference = accountingDocumentLine.AccountLineTypeId == (int)AccountLineType.C ? accountingSetup.SalesLedgerControlClientDebtors : accountingSetup.PurchaseLedgerControlClientCreditors; accountingDocumentLine.SectionId = invoiceLine.SectionId; } else if (invoiceFunction == InvoiceFunction.GoodsAndCost) { var invoiceLinesGoods = invoiceInformation.InvoiceLines.FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialPurchase || x.Type == (int)Entities.ContractType.CommercialSale); var invoiceLineCosts = invoiceInformation.InvoiceLines.Where(x => x.CostDirectionId == (int)Entities.CostDirectionType.Pay || x.CostDirectionId == (int)Entities.CostDirectionType.Receive); decimal totalNominalAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum(); decimal totalTaxAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum(); accountingDocumentLine.Quantity = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(x => x.Quantity).Sum(); accountingDocumentLine.Amount = -(totalNominalAmount + totalTaxAmount); accountingDocumentLine.ContractSectionCode = latestSectionsInformation.ContractSectionCode; accountingDocumentLine.SectionId = latestSectionsInformation.SectionId; if (invoiceLinesGoods != null) { accountingDocumentLine.AccountLineTypeId = invoiceLinesGoods.Type == (int)Entities.ContractType.CommercialPurchase ? (int)AccountLineType.V : (int)AccountLineType.C; if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null) { accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } } else if (invoiceLineCosts != null) { accountingDocumentLine.AccountLineTypeId = invoiceInformation.InvoiceSourceType == (int)InvoiceSourceType.External ? (int)AccountLineType.V : (int)AccountLineType.C; if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null) { accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } else { accountingDocumentLine.CostTypeCode = invoiceLineCosts.FirstOrDefault(line => line.InvoiceLineAmount == invoiceLineCosts.Max(max => max.InvoiceLineAmount)).CostType; } } } break; case AccountingDocumentLineType.Tax: Vat vat = vats.ToList()[index]; decimal totalInvoiceAmount = invoiceInformation.InvoiceLines.Where(invoiceLine => invoiceLine.VATCode == vat.VatCode).Select(x => x.InvoiceTotalAmount).Sum(); decimal totalQuantity = invoiceInformation.InvoiceLines.Where(invoiceLine => invoiceLine.VATCode == vat.VatCode).Select(x => x.Quantity).Sum(); accountingDocumentLine.PostingLineId = postingLineId; accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.T; accountingDocumentLine.VATTurnover = Math.Abs(accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum()); accountingDocumentLine.AccountReference = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? vat.InputAccount.Trim() : vat.OutputAccount.Trim(); accountingDocumentLine.VATCode = vat.VatCode; accountingDocumentLine.CommodityId = latestSectionsInformation.CommodityId; accountingDocumentLine.CharterId = latestSectionsInformation.CharterId; accountingDocumentLine.DepartmentId = latestSectionsInformation.DepartmentId; accountingDocumentLine.ContractSectionCode = latestSectionsInformation.ContractSectionCode; accountingDocumentLine.SectionId = latestSectionsInformation.SectionId; accountingDocumentLine.SecondaryDocumentReference = null; accountingDocumentLine.ClientAccount = null; if (invoiceFunction == InvoiceFunction.Commercial) { accountingDocumentLine.Quantity = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? totalQuantity : -totalQuantity; accountingDocumentLine.Amount = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? totalInvoiceAmount : -totalInvoiceAmount; accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L; if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null) { accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } } else if (invoiceFunction == InvoiceFunction.Cost) { accountingDocumentLine.Quantity = 0; accountingDocumentLine.AccountReference = totalInvoiceAmount >= 0 ? vat.InputAccount.Trim() : vat.OutputAccount.Trim(); accountingDocumentLine.Amount = totalInvoiceAmount; accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L; accountingDocumentLine.CostTypeCode = invoiceInformation.InvoiceLines.FirstOrDefault(line => line.InvoiceLineAmount == invoiceInformation.InvoiceLines.Max(max => max.InvoiceLineAmount)).CostType; accountingDocumentLine.Narrative = string.Concat(latestSectionsInformation.ContractSectionCode, whiteSpace, latestSectionsInformation.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode); } else if (invoiceFunction == InvoiceFunction.Washout) { InvoiceLinesDto invoiceLinePurchase = invoiceInformation.InvoiceLines.OrderBy(x => Math.Abs(x.InvoiceLineAmount)).FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialPurchase); InvoiceLinesDto invoiceLineSale = invoiceInformation.InvoiceLines.FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialSale); accountingDocumentLine.AccountReference = totalInvoiceAmount >= 0 ? vat.InputAccount.Trim() : vat.OutputAccount.Trim(); accountingDocumentLine.ContractSectionCode = invoiceLinePurchase.PhysicalContractCode; accountingDocumentLine.Quantity = invoiceInformation.InvoiceLines.Where(x => x.Type == (int)Entities.ContractType.CommercialPurchase).Select(x => x.Quantity).Sum(); accountingDocumentLine.Amount = totalInvoiceAmount; accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L; accountingDocumentLine.SectionId = invoiceLinePurchase.SectionId; accountingDocumentLine.SectionId = invoiceLinePurchase.SectionId; decimal totalNominalAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(y => y.Amount).Sum(); decimal totalTaxAmount = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.T).Select(y => y.Amount).Sum(); accountingDocumentLine.CostTypeCode = totalNominalAmount < 0 ? accountingSetup.WashoutInvoiceGains : accountingSetup.WashoutInvoiceLoss; } else if (invoiceFunction == InvoiceFunction.Cancelled) { InvoiceLinesDto invoiceLine = invoiceInformation.InvoiceLines.FirstOrDefault(); accountingDocumentLine.AccountReference = totalInvoiceAmount >= 0 ? vat.InputAccount.Trim() : vat.OutputAccount.Trim(); accountingDocumentLine.ContractSectionCode = invoiceLine.PhysicalContractCode; accountingDocumentLine.Quantity = invoiceLine.Quantity; accountingDocumentLine.Amount = 0; accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L; accountingDocumentLine.SectionId = invoiceLine.SectionId; } else if (invoiceFunction == InvoiceFunction.GoodsAndCost) { accountingDocumentLine.Quantity = accountingDocumentLines.Where(x => x.AccountingCategoryId == (int)AccountingCategory.N).Select(x => x.Quantity).Sum(); accountingDocumentLine.Amount = totalInvoiceAmount; if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.CostTypeCode != null) { accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } accountingDocumentLine.AccountReference = totalInvoiceAmount >= 0 ? vat.InputAccount.Trim() : vat.OutputAccount.Trim(); accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L; accountingDocumentLine.ContractSectionCode = latestSectionsInformation.ContractSectionCode; accountingDocumentLine.SectionId = latestSectionsInformation.SectionId; } break; case AccountingDocumentLineType.Nominal: long sectionId = invoiceInformation.InvoiceLines.ToList()[index].SectionId; InvoiceLinesDto invoiceLineNominal = invoiceInformation.InvoiceLines.ToList()[index]; SectionsInformationDto sectionInfo = sectionsInformation.FirstOrDefault(section => section.SectionId == sectionId); decimal invoiceLineAmount = invoiceInformation.InvoiceLines.ToList()[index].InvoiceLineAmount; accountingDocumentLine.PostingLineId = postingLineId; accountingDocumentLine.ContractSectionCode = sectionInfo.ContractSectionCode; accountingDocumentLine.AccountingCategoryId = (int)AccountingCategory.N; accountingDocumentLine.VATTurnover = null; accountingDocumentLine.CommodityId = sectionInfo.CommodityId; accountingDocumentLine.VATCode = invoiceInformation.InvoiceLines.ToList()[index].VATCode; accountingDocumentLine.AccountLineTypeId = (int)AccountLineType.L; accountingDocumentLine.CharterId = sectionInfo.CharterId; accountingDocumentLine.DepartmentId = sectionInfo.DepartmentId; accountingDocumentLine.SectionId = sectionInfo.SectionId; accountingDocumentLine.ClientAccount = null; accountingDocumentLine.SourceInvoiceLineId = invoiceLineNominal.InvoiceLineId; if (invoiceFunction == InvoiceFunction.Commercial) { if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.AccountReference != null && invoiceInformation.CostTypeCode != null) { accountingDocumentLine.AccountReference = invoiceInformation.AccountReference; accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } else { accountingDocumentLine.AccountReference = accountingSetup.NominalCostTypeInfo.Where(x => x.CostTypeCode == accountingDocumentLine.CostTypeCode).FirstOrDefault().NominalAccountCode; } accountingDocumentLine.Quantity = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? invoiceInformation.InvoiceLines.ToList()[index].Quantity : -invoiceInformation.InvoiceLines.ToList()[index].Quantity; accountingDocumentLine.Amount = invoiceInformation.InvoiceType == (int)Entities.InvoiceType.CommercialPurchase ? invoiceLineAmount : -invoiceLineAmount; if (invoiceLineNominal.CostDirectionId != null) { accountingDocumentLine.Amount = invoiceLineNominal.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineAmount : -invoiceLineAmount; } accountingDocumentLine.Narrative = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode); } else if (invoiceFunction == InvoiceFunction.Cost) { accountingDocumentLine.AccountReference = invoiceInformation.InvoiceLines.ToList()[index].NominalAccount; accountingDocumentLine.Quantity = 0; accountingDocumentLine.Amount = invoiceLineNominal.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineAmount : -invoiceLineAmount; accountingDocumentLine.Narrative = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode); } else if (invoiceFunction == InvoiceFunction.Washout) { if (invoiceInformation.InvoiceLines.ToList()[index].CostDirectionId != null) { accountingDocumentLine.AccountReference = invoiceInformation.InvoiceLines.ToList()[index].NominalAccount; } else { accountingDocumentLine.AccountReference = accountingSetup.NominalCostTypeInfo.Where(x => x.CostTypeCode == accountingDocumentLine.CostTypeCode).FirstOrDefault().NominalAccountCode; } accountingDocumentLine.Narrative = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode); accountingDocumentLine.Quantity = invoiceLineNominal.Quantity; if (invoiceLineNominal.CostDirectionId != null) { accountingDocumentLine.Amount = invoiceLineNominal.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineAmount : -invoiceLineAmount; } else { int purchaseIndex = index % 2 == 0 ? index + 1 : index - 1; InvoiceLinesDto invoiceLinePurchase = invoiceInformation.InvoiceLines.ToList()[purchaseIndex]; InvoiceLinesDto invoiceLineSale = invoiceInformation.InvoiceLines.ToList()[index]; accountingDocumentLine.Amount = invoiceLinePurchase.InvoiceLineAmount - invoiceLineSale.InvoiceLineAmount; } } else if (invoiceFunction == InvoiceFunction.Cancelled) { if (invoiceInformation.InvoiceLines.ToList()[index].CostDirectionId != null) { accountingDocumentLine.AccountReference = invoiceInformation.InvoiceLines.ToList()[index].NominalAccount; } else { accountingDocumentLine.AccountReference = accountingSetup.NominalCostTypeInfo.Where(x => x.CostTypeCode == accountingDocumentLine.CostTypeCode).FirstOrDefault().NominalAccountCode; } accountingDocumentLine.Narrative = invoiceInformation.ExternalReference; accountingDocumentLine.Quantity = invoiceLineNominal.Quantity; accountingDocumentLine.Amount = invoiceInformation.TransactionDocumentTypeId == (int)DocumentType.CN ? invoiceInformation.SumOfInvoiceTotalAmount : -invoiceInformation.SumOfInvoiceTotalAmount; } else if (invoiceFunction == InvoiceFunction.GoodsAndCost) { var invoiceLinesGoods = invoiceInformation.InvoiceLines.FirstOrDefault(x => x.Type == (int)Entities.ContractType.CommercialPurchase || x.Type == (int)Entities.ContractType.CommercialSale); var invoiceLineCosts = invoiceInformation.InvoiceLines.Where(x => x.CostDirectionId == (int)Entities.CostDirectionType.Pay || x.CostDirectionId == (int)Entities.CostDirectionType.Receive); if (invoiceLineNominal.CostDirectionId != null) { accountingDocumentLine.Amount = invoiceLineNominal.CostDirectionId == (int)Entities.CostDirectionType.Pay ? invoiceLineAmount : -invoiceLineAmount; accountingDocumentLine.Quantity = 0; if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.AccountReference != null && invoiceInformation.CostTypeCode != null) { accountingDocumentLine.AccountReference = invoiceInformation.AccountReference; accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } else { accountingDocumentLine.AccountReference = invoiceLineNominal.NominalAccount; accountingDocumentLine.CostTypeCode = invoiceLineNominal.CostType; } accountingDocumentLine.Narrative = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, invoiceLineNominal.CostType); } else { // Binding the Account Reference associated with business sector if business sector posting is configured if (invoiceInformation.BusinessSectorNominalPostingPurpose == true && invoiceInformation.AccountReference != null && invoiceInformation.CostTypeCode != null) { accountingDocumentLine.AccountReference = invoiceInformation.AccountReference; accountingDocumentLine.CostTypeCode = invoiceInformation.CostTypeCode; } else { accountingDocumentLine.AccountReference = accountingSetup.NominalCostTypeInfo.Where(x => x.CostTypeCode == accountingDocumentLine.CostTypeCode).FirstOrDefault().NominalAccountCode; } accountingDocumentLine.Amount = invoiceLineNominal.Type == (int)Entities.ContractType.CommercialPurchase ? invoiceLineAmount : -invoiceLineAmount; accountingDocumentLine.Quantity = invoiceLineNominal.Type == (int)Entities.ContractType.CommercialPurchase ? invoiceLineNominal.Quantity : -invoiceLineNominal.Quantity; accountingDocumentLine.Narrative = string.Concat(sectionInfo.ContractSectionCode, whiteSpace, sectionInfo.CharterReference, whiteSpace, accountingDocumentLine.CostTypeCode); } } break; default: throw new Exception("Unable to create document header and lines."); } accountingDocumentLine.Amount = Math.Round(accountingDocumentLine.Amount, CommonRules.RoundDecimals); decimal?amountInUSD = accountingDocumentLine.Amount; if (invoiceInformation.Currency != null && invoiceInformation.Currency.ToUpperInvariant() != "USD") { amountInUSD = (await _foreignExchangeRateService.Convert(fxRates.FxRateInvoiceCurrency.FxCurrency, CommonRules.BaseCurrency, accountingDocumentLine.Amount, fxRates.FxRateInvoiceCurrency.FxDate)).ConvertedValue; } await CommonRules.CalculateFunctionalAndStatutoryCurrency(_foreignExchangeRateService, accountingDocumentLine, amountInUSD, fxRates, company, CommonRules.BaseCurrency, CommonRules.RoundDecimals); return(accountingDocumentLine); }
private async Task <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); } }
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); }