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