public Task <ReceiptSectionTransfer> SaveAsync(ReceiptSectionTransfer ReceiptSectionTransfer, CancellationToken token = default(CancellationToken))
        {
            var query = @"
INSERT INTO ReceiptSectionTransfer
           (SourceReceiptId
          ,DestinationReceiptId
          ,SourceSectionId
          ,DestinationSectionId
          ,SourceAmount
          ,DestinationAmount
          ,PrintFlag
          ,CreateBy
          ,CreateAt
          ,UpdateBy
          ,UpdateAt
    )
 OUTPUT inserted.* 
 VALUES
          (@SourceReceiptId
          ,@DestinationReceiptId
          ,@SourceSectionId
          ,@DestinationSectionId
          ,@SourceAmount
          ,@DestinationAmount
          ,@PrintFlag
          ,@CreateBy
          , GETDATE()
          ,@UpdateBy
          , GETDATE()
    )";

            return(dbHelper.ExecuteAsync <ReceiptSectionTransfer>(query, ReceiptSectionTransfer, token));
        }
        public Task <int> DeleteAsync(ReceiptSectionTransfer ReceiptSectionTransfer, CancellationToken token = default(CancellationToken))
        {
            var query = @"
DELETE 
  FROM ReceiptSectionTransfer 
 WHERE SourceReceiptId      = @SourceReceiptId 
   AND DestinationReceiptId = @DestinationReceiptId";

            return(dbHelper.ExecuteAsync(query, ReceiptSectionTransfer, token));
        }
        public Task <ReceiptSectionTransfer> GetItemByReceiptIdAsync(ReceiptSectionTransfer ReceiptSectionTransfer, CancellationToken token = default(CancellationToken))
        {
            var query = @"
SELECT * 
  FROM ReceiptSectionTransfer 
 WHERE SourceReceiptId      = @ReceiptId 
   AND DestinationReceiptId = @ReceiptId
                            ";

            return(dbHelper.ExecuteAsync <ReceiptSectionTransfer>(query, ReceiptSectionTransfer, token));
        }
        /// <summary>
        /// 振替取消処理
        /// </summary>
        /// <param name="transfer"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        /// <remarks>
        /// source.Id -> destination.Id
        /// source.Id へ 入金ID の登録があるものは、振替元なので取消不可
        /// source, destination 同一の場合は取消対象
        /// destination.Id が合致する ReceiptSectionTransfer を取得し、取消処理を実施する
        /// 振替後の 入金データが 消込済 の場合は 取消不可
        /// /*取消不可となる条件の不足が気になる*/
        /// </remarks>
        private async Task <ReceiptSectionTransfersResult> CancelAsync(ReceiptSectionTransfer transfer, int loginUserId, CancellationToken token)
        {
            var result  = new ReceiptSectionTransfersResult();
            var receipt = await receiptGetByIdQueryProcessor.GetByIdAsync(transfer.ReceiptId, token);

            if (receipt.AssignmentFlag != 0)
            {
                result.NotClearFlag = true; /* false */
                return(result);
            }
            var receiptTransferSearch = new ReceiptSectionTransfer {
                SourceReceiptId = transfer.ReceiptId
            };
            var transferDB = (await receiptSectionTransferQueryProcessor.GetItemsAsync(receiptTransferSearch, token)).ToList();

            if (transferDB?.Any() ?? false)
            {
                result.TransferFlag = true; // property name was no sence.
                return(result);
            }
            receiptTransferSearch = new ReceiptSectionTransfer {
                DestinationReceiptId = transfer.ReceiptId
            };
            transferDB = (await receiptSectionTransferQueryProcessor.GetItemsAsync(receiptTransferSearch, token)).ToList();
            if (transferDB == null)
            {
                return(result);
            }
            var first = transferDB.Where(x => x.UpdateAt == transferDB.Max(t => t.UpdateAt)).First();
            await deleteReceiptSectionTransferQueryProcessor.DeleteAsync(first, token);

            if (first.DestinationReceiptId == first.SourceReceiptId)
            {
                var updateReceipt = await updateReceiptQueryProcessor.UpdateReceiptSectionAsync(first.SourceSectionId, loginUserId, first.SourceReceiptId, token);

                result.UpdateReceipts.Add(updateReceipt);
            }
            else
            {
                var updateReceipt = await updateReceiptQueryProcessor.UpdateReceiptAmountAsync(first.DestinationAmount, loginUserId, first.SourceReceiptId, token);

                result.UpdateReceipts.Add(updateReceipt);
                var deleteReceipt = await receiptGetByIdQueryProcessor.GetByIdAsync(transfer.ReceiptId, token);

                await deleteReceiptQueryProcessor.DeleteAsync(transfer.ReceiptId, token);

                result.DeleteReceipts.Add(deleteReceipt);
            }
            //result.ProcessResult.Result = true;
            return(result);
        }
        /// <summary>
        /// 振替元 と 先 が同じ
        /// </summary>
        /// <param name="transfer"></param>
        /// <param name="loginUserId"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        private async Task <ReceiptSectionTransfersResult> TransferSameAmountAsync(ReceiptSectionTransfer transfer, int loginUserId, CancellationToken token)
        {
            var result = new ReceiptSectionTransfersResult();

            result.UpdateReceipts.Add(await updateReceiptQueryProcessor.UpdateReceiptSectionAsync(transfer.DestinationSectionId, loginUserId, transfer.ReceiptId, token));

            if (!string.IsNullOrWhiteSpace(transfer.TransferMemo))
            {
                await addReceiptMemoQueryProcessor.SaveAsync(transfer.ReceiptId, transfer.TransferMemo, token);
            }
            else
            {
                var receiptMemo = await receiptMemoQueryProcessor.GetAsync(transfer.ReceiptId, token);

                if (receiptMemo != null)
                {
                    await deleteReceiptMemoQueryProcessor.DeleteAsync(transfer.ReceiptId, token);
                }
            }
            transfer.DestinationReceiptId = transfer.ReceiptId;
            var transferDB = await receiptSectionTransferQueryProcessor.GetItemByReceiptIdAsync(transfer, token);

            if (transferDB == null)
            {
                var saveItem = new ReceiptSectionTransfer
                {
                    SourceReceiptId      = transfer.ReceiptId,
                    DestinationReceiptId = transfer.ReceiptId,
                    SourceSectionId      = transfer.SourceSectionId,
                    DestinationSectionId = transfer.DestinationSectionId,
                    SourceAmount         = transfer.SourceAmount,
                    DestinationAmount    = transfer.DestinationAmount,
                    UpdateBy             = loginUserId,
                    CreateBy             = loginUserId,
                    PrintFlag            = 0,
                };
                result.ReceiptSectionTransfers.Add(await addReceiptSectionTransferQueryProcessor.SaveAsync(saveItem, token));
            }
            else if (transferDB.SourceSectionId == transfer.DestinationSectionId)
            {
                await deleteReceiptSectionTransferQueryProcessor.DeleteAsync(transferDB, token);
            }
            else
            {
                await updateReceiptSectionTransferQueryProcessor.UpdateDestinationSectionAsync(transfer.DestinationSectionId, loginUserId, transferDB.SourceReceiptId, transferDB.DestinationReceiptId, token);
            }
            return(result);
        }
        public Task <IEnumerable <ReceiptSectionTransfer> > GetItemsAsync(ReceiptSectionTransfer ReceiptSectionTransfer, CancellationToken token = default(CancellationToken))
        {
            var query          = @"
SELECT * 
  FROM ReceiptSectionTransfer
 WHERE 1 = 1
";
            var whereCondition = new StringBuilder();

            if (ReceiptSectionTransfer.SourceReceiptId != 0)
            {
                whereCondition.AppendLine(@"
                     AND SourceReceiptId = @SourceReceiptId AND SourceReceiptId <> DestinationReceiptId");
            }
            if (ReceiptSectionTransfer.DestinationReceiptId != 0)
            {
                whereCondition.AppendLine(@"
                     AND DestinationReceiptId = @DestinationReceiptId");
            }
            query += whereCondition.ToString();
            return(dbHelper.GetItemsAsync <ReceiptSectionTransfer>(query, ReceiptSectionTransfer, token));
        }
        /// <summary>
        /// 一つの入金データを 複数に分割
        /// </summary>
        /// <param name="transfer"></param>
        /// <param name="loginUserId"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        private async Task <ReceiptSectionTransfersResult> DivideAsync(ReceiptSectionTransfer transfer, int loginUserId, CancellationToken token)
        {
            var result  = new ReceiptSectionTransfersResult();
            var receipt = await receiptGetByIdQueryProcessor.GetByIdAsync(transfer.ReceiptId, token);

            if (receipt == null)
            {
                return(result);
            }

            receipt.SectionId         = transfer.DestinationSectionId;
            receipt.ReceiptAmount     = transfer.DestinationAmount;
            receipt.RemainAmount      = transfer.DestinationAmount;
            receipt.AssignmentAmount  = 0;
            receipt.AssignmentFlag    = 0;
            receipt.OutputAt          = null;
            receipt.MailedAt          = null;
            receipt.OriginalReceiptId = null;
            receipt.ExcludeFlag       = 0;
            receipt.ExcludeCategoryId = null;
            receipt.ExcludeAmount     = 0;
            receipt.DeleteAt          = null;
            receipt.CreateBy          = loginUserId;
            receipt.UpdateBy          = loginUserId;

            var firstResult = await addReceiptQueryProcessor.SaveAsync(receipt, token : token);

            result.InsertReceipts.Add(firstResult);

            if (!string.IsNullOrWhiteSpace(transfer.TransferMemo))
            {
                await addReceiptMemoQueryProcessor.SaveAsync(firstResult.Id, transfer.TransferMemo, token);
            }

            receipt.SectionId     = transfer.SourceSectionId;
            receipt.ReceiptAmount = transfer.SourceAmount - transfer.DestinationAmount;
            receipt.RemainAmount  = transfer.SourceAmount - transfer.DestinationAmount;

            var secondResult = await addReceiptQueryProcessor.SaveAsync(receipt, token : token);

            result.InsertReceipts.Add(secondResult);

            var receiptMemo = await receiptMemoQueryProcessor.GetAsync(transfer.ReceiptId, token);

            if (receiptMemo != null)
            {
                await addReceiptMemoQueryProcessor.SaveAsync(secondResult.Id, receiptMemo.Memo, token);
            }

            var updateAt = await dbSystemDateTimeQueryProcessor.GetAsync(token);

            result.UpdateReceipts.Add(await updateReceiptQueryProcessor.UpdateOriginalRemainAsync(transfer.ReceiptId, loginUserId, updateAt, token));

            var saveItem = new ReceiptSectionTransfer
            {
                SourceReceiptId      = transfer.ReceiptId,
                DestinationReceiptId = firstResult.Id,
                SourceSectionId      = transfer.SourceSectionId,
                DestinationSectionId = transfer.DestinationSectionId,
                SourceAmount         = transfer.SourceAmount,
                DestinationAmount    = transfer.DestinationAmount,
                PrintFlag            = 0,
                CreateBy             = loginUserId,
                UpdateBy             = loginUserId
            };

            result.ReceiptSectionTransfers.Add(await addReceiptSectionTransferQueryProcessor.SaveAsync(saveItem, token));


            saveItem.DestinationReceiptId = secondResult.Id;
            saveItem.DestinationSectionId = transfer.SourceSectionId;
            saveItem.DestinationAmount    = transfer.SourceAmount - transfer.DestinationAmount;

            result.ReceiptSectionTransfers.Add(await addReceiptSectionTransferQueryProcessor.SaveAsync(saveItem, token));

            return(result);
        }