public async Task <AdvanceReceivedResult> CancelAsync(IEnumerable <AdvanceReceived> receiveds, CancellationToken token = default(CancellationToken)) { var result = new AdvanceReceivedResult { ProcessResult = new ProcessResult(), AdvancedReceiveItems = new List <AdvanceReceived>(), }; using (var scope = transactionScopeBuilder.Create()) { foreach (var item in receiveds) { var receipt = await updateReceiptQueryProcessor.UpdateCancelAdvancedReceivedAsync(item.ReceiptId, item.OriginalReceiptId, item.LoginUserId, item.OriginalUpdateAt, token); if (receipt == null) { result.ProcessResult.ErrorCode = Rac.VOne.Common.ErrorCode.OtherUserAlreadyUpdated; return(result); } result.AdvancedReceiveItems.Add(new AdvanceReceived { ReceiptId = receipt.Id, ReceiptCategoryId = receipt.ReceiptCategoryId, LoginUserId = receipt.UpdateBy, UpdateAt = receipt.UpdateAt, }); await deleteReceiptQueryProcessor.CancelAdvanceReceivedAsync(item.ReceiptId, token); } result.ProcessResult.Result = true; scope.Complete(); } return(result); }
public async Task <MatchingResult> CancelAsync(IEnumerable <MatchingHeader> headers, int loginUserId, CancellationToken token = default(CancellationToken), IProgressNotifier notifier = null) { var headersArray = headers.ToArray(); var updateAt = await dbSystemDatetimeQueryProcessor.GetAsync(token); List <Matching> details = null; List <Billing> billings = null; List <Receipt> receipts = null; var deleteMatchings = new List <Matching>(); var deleteReceipts = new List <Receipt>(); var companyId = headers.Select(x => x.CompanyId).First(); var appControl = await applicationControlGetByCompanyIdQueryProcessor.GetAsync(companyId, token); var useCashOnDueDates = appControl.UseCashOnDueDates == 1; using (var scope = transactionScopeBuilder.Create()) { foreach (var header in headers) { if (token.IsCancellationRequested) { return new MatchingResult { MatchingErrorType = MatchingErrorType.ProcessCanceled } } ; #region 1.消込データ(Matching)取得 details = (await cancelMatchingQueryProcessor.GetByHeaderIdAsync(header.Id, token)).ToList(); deleteMatchings.AddRange(details); #endregion #region 2.消込済請求データ取得 // billing deleteAt など matching 以外の情報が必要なので、 query で呼び出し必須 billings = (await cancelMatchingQueryProcessor.GetMatchedBillingsForCancelAsync(header.Id, token)).ToList(); #endregion if (billings.Count == 0) { notifier?.Abort(); return(new MatchingResult { MatchingErrorType = MatchingErrorType.NotExistBillingData }); } //3.請求データチェック if (billings.Any(e => e.DeleteAt.HasValue)) { notifier?.Abort(); return(new MatchingResult { MatchingErrorType = MatchingErrorType.BillingOmitted, ErrorIndex = Array.IndexOf(headersArray, header), }); } if (useCashOnDueDates && await cancelMatchingQueryProcessor.ExistAssignmentScheduledIncomeAsync(details.Select(x => x.Id).ToArray(), token)) { notifier?.Abort(); return(new MatchingResult { MatchingErrorType = MatchingErrorType.CashOnDueDateOmitted, ErrorIndex = Array.IndexOf(headersArray, header), }); } #region 4.請求データ消込解除処理 // 期日現金管理用 請求ID -> 消込ID の Dictionary Dictionary <long, long[]> billingIdToMatchingIds = null; if (useCashOnDueDates) { billingIdToMatchingIds = details.GroupBy(x => x.BillingId) .ToDictionary(x => x.Key, x => x.Select(y => y.Id).ToArray()); } foreach (var billing in billings) { var item = billing; var matchingAmount = billing.AssignmentAmount; var bankFee = billing.BankTransferFee; var taxDiff = billing.TaxDifference; var discount = billing.DiscountAmount; var amount = matchingAmount + bankFee + discount - (taxDiff < 0 ? taxDiff : 0M); item.CompanyId = header.CompanyId; item.RemainAmount = amount; item.AssignmentAmount = amount; item.UpdateBy = loginUserId; item.UpdateAt = updateAt; var updatedBilling = await cancelMatchingQueryProcessor.UpdateBillingForCancelMatchingAsync(item, token); if (updatedBilling == null) { notifier?.Abort(); return(new MatchingResult { MatchingErrorType = MatchingErrorType.CancelError }); } await cancelMatchingQueryProcessor.UpdatePreviousBillingLogsAsync(header.Id, billing.Id, amount, loginUserId, updateAt, token); if (useCashOnDueDates) { foreach (var matchingId in billingIdToMatchingIds[billing.Id]) { var income = await cancelMatchingQueryProcessor.GetBillingScheduledIncomeAsync(matchingId, token); if (income != null) { await cancelMatchingQueryProcessor.DeleteBillingShceduledIncomeAsync(income.BillingId, token); await deleteBillingByIdQueryProcessor.DeleteAsync(income.BillingId, token); } } } } #endregion #region 5.相殺データ消込解除処理 var nettings = (await nettingQueryProcessor.GetByMatchingHeaderIdAsync(header.Id, token)).ToList(); var nettingReceiptIds = new List <long>(); foreach (var netting in nettings) { nettingReceiptIds.Add((long)netting.ReceiptId); var cancelFlag = 1; await updateNettingQueryProcessor.UpdateMatchingNettingAsync(header.CompanyId, 0, netting.Id, cancelFlag, token); } if (nettings.Any()) { var receiptsForNetting = await receiptGetByIdsQueryProcessor.GetByIdsAsync(nettings.Select(n => (long)n.ReceiptId), token); deleteReceipts.AddRange(receiptsForNetting); } #endregion #region 7.消込済入金データ取得 receipts = (await cancelMatchingQueryProcessor.GetMatchedReceiptsForCancelAsync(header, token)).ToList(); #endregion if (receipts.Count == 0) { notifier?.Abort(); return(new MatchingResult { MatchingErrorType = MatchingErrorType.NotExistReceiptData }); } #region 8.入金データチェック if (receipts.Any(e => e.DeleteAt.HasValue)) { notifier?.Abort(); return(new MatchingResult { MatchingErrorType = MatchingErrorType.ReceiptOmitted, ErrorIndex = Array.IndexOf(headersArray, header), }); } #endregion #region 9.入金データ消込解除処理 var hasAdvanceReceivedOccured = details.Any(x => (x.AdvanceReceivedOccured == 1)); foreach (var receipt in receipts) { var prepare_receipt_update = receipt; var receiptId = receipt.Id; var amount = prepare_receipt_update.AssignmentAmount; prepare_receipt_update.RemainAmount = amount; prepare_receipt_update.AssignmentAmount = amount; prepare_receipt_update.CompanyId = header.CompanyId; prepare_receipt_update.UpdateBy = loginUserId; prepare_receipt_update.UpdateAt = updateAt; await cancelMatchingQueryProcessor.UpdateReceiptForCancelMatchingAsync(prepare_receipt_update, token); // 入金残ログ洗替え await cancelMatchingQueryProcessor.UpdatePreviousReceiptLogsAsync(header.Id, receiptId, amount, loginUserId, updateAt, token); if (!hasAdvanceReceivedOccured) { continue; } //前受データの削除 var maeuke_receipt_flg = details.Exists(x => ((x.AdvanceReceivedOccured == 1) && (x.ReceiptId == receipt.Id))); if (!maeuke_receipt_flg) { continue; } var originalReceiptId = receipt.Id; //前受のテータ取得 var maeuke_Receipts = (await cancelMatchingQueryProcessor.GetByOriginalIdAsync(originalReceiptId)).ToList(); foreach (var maeuke_receipt in maeuke_Receipts) { int canel_flg = await deleteReceiptQueryProcessor.CancelAdvanceReceivedAsync(maeuke_receipt.Id, token); if (canel_flg != 1) { continue; } // データ同期用 deleteReceipts.Add(maeuke_receipt); var originalReceipt = receipts.Find(x => (x.Id == originalReceiptId)); originalReceipt.RemainAmount = maeuke_receipt.ReceiptAmount; originalReceipt.AssignmentAmount = 0; //消込額から減算は不要なので originalReceipt.UpdateBy = loginUserId; originalReceipt.UpdateAt = updateAt; await cancelMatchingQueryProcessor.UpdateReceiptForCancelMatchingAsync(originalReceipt, token); } } #endregion #region 8.その他処理 #region 消込履歴データ検索・出力済データ(MatchingOutputed)の削除 await cancelMatchingQueryProcessor.DeleteMatchingOutputedAsync(header.Id, token); #endregion #region 消込歩引データ(MatchingBillingDiscount)の削除 foreach (var matching in details) { await deleteMatchingBillingDiscountQueryProcessor.DeleteByMatchingIdAsync(matching.Id, token); } #endregion #region 消込データ(Matching)の削除 var deleteMatchingResult = await cancelMatchingQueryProcessor.DeleteMatchingAsync(header.Id, header.MatchingUpdateAt, token); if (deleteMatchingResult <= 0) { notifier?.Abort(); return(new MatchingResult { MatchingErrorType = MatchingErrorType.MatchingHeaderChanged, ErrorIndex = Array.IndexOf(headersArray, header), }); } #endregion #region MatchingHeaderの削除 var deleteResult = await deleteMatchingHeaderQueryProcessor.DeleteAsync(header, token); if (deleteResult <= 0) { notifier?.Abort(); return(new MatchingResult { MatchingErrorType = MatchingErrorType.MatchingHeaderChanged, ErrorIndex = Array.IndexOf(headersArray, header), }); } #endregion #region 相殺データから変換した入金データの削除 foreach (long receiptId in nettingReceiptIds) { await deleteReceiptByIdQueryProcessor.DeleteAsync(receiptId, token); } #endregion #endregion notifier?.UpdateState(); } scope.Complete(); return(new MatchingResult { ProcessResult = new ProcessResult { Result = true }, Matchings = deleteMatchings, DeleteReceipts = deleteReceipts, }); } } }