/// <summary>
        /// フォーム読込完了時
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void MoveRegistrationWindow_Loaded(object sender, RoutedEventArgs e)
        {
            int?   fromBookId       = this.selectedBookId;
            int?   toBookId         = this.selectedBookId;
            int?   commissionItemId = null;
            string commissionRemark = null;

            // DBから値を読み込む
            switch (this.WVM.RegMode)
            {
            case RegistrationMode.Add:
                // 追加時の日時、金額は帳簿リスト更新時に取得する
                break;

            case RegistrationMode.Edit:
            case RegistrationMode.Copy: {
                DateTime       fromDate        = DateTime.Now;
                DateTime       toDate          = DateTime.Now;
                CommissionKind commissionKind  = CommissionKind.FromBook;
                int            moveValue       = -1;
                int            commissionValue = 0;

                using (DaoBase dao = this.builder.Build()) {
                    DaoReader reader = await dao.ExecQueryAsync(@"
SELECT A.book_id, A.action_id, A.item_id, A.act_time, A.act_value, A.remark, I.move_flg
FROM hst_action A
INNER JOIN (SELECT * FROM mst_item WHERE del_flg = 0) I ON I.item_id = A.item_id
WHERE A.del_flg = 0 AND A.group_id = @{0}
ORDER BY move_flg DESC;", this.groupId);

                    reader.ExecWholeRow((count, record) => {
                            int bookId        = record.ToInt("book_id");
                            DateTime dateTime = record.ToDateTime("act_time");
                            int actionId      = record.ToInt("action_id");
                            int itemId        = record.ToInt("item_id");
                            int actValue      = record.ToInt("act_value");
                            int moveFlg       = record.ToInt("move_flg");
                            string remark     = record["remark"];

                            if (moveFlg == 1)
                            {
                                if (actValue < 0)
                                {
                                    fromBookId        = bookId;
                                    fromDate          = dateTime;
                                    this.fromActionId = actionId;
                                }
                                else
                                {
                                    toBookId        = bookId;
                                    toDate          = dateTime;
                                    this.toActionId = actionId;
                                    moveValue       = actValue;
                                }
                            }
                            else                          // 手数料
                            {
                                if (bookId == fromBookId) // 移動元負担
                                {
                                    commissionKind = CommissionKind.FromBook;
                                }
                                else if (bookId == toBookId)   // 移動先負担
                                {
                                    commissionKind = CommissionKind.ToBook;
                                }
                                this.commissionActionId = actionId;
                                commissionItemId        = itemId;
                                commissionValue         = Math.Abs(actValue);
                                commissionRemark        = remark;
                            }
                            return(true);
                        });
                }

                // WVMに値を設定する
                if (this.WVM.RegMode == RegistrationMode.Edit)
                {
                    this.WVM.FromId       = this.fromActionId;
                    this.WVM.ToId         = this.toActionId;
                    this.WVM.GroupId      = this.groupId;
                    this.WVM.CommissionId = this.commissionActionId;
                }
                this.WVM.IsLink   = (fromDate == toDate);
                this.WVM.FromDate = fromDate;
                this.WVM.ToDate   = toDate;
                this.WVM.SelectedCommissionKind = commissionKind;
                this.WVM.Value      = moveValue;
                this.WVM.Commission = commissionValue;
            }
            break;
            }

            // リストを更新する
            await this.UpdateBookListAsync(fromBookId, toBookId);

            await this.UpdateItemListAsync(commissionItemId);

            await this.UpdateRemarkListAsync(commissionRemark);

            // イベントハンドラを登録する
            this.RegisterEventHandlerToWVM();
        }
        /// <summary>
        /// DBに登録する
        /// </summary>
        /// <returns>登録された帳簿項目ID</returns>
        private async Task <int?> RegisterToDbAsync()
        {
            DateTime       fromDate         = this.WVM.FromDate;
            DateTime       toDate           = this.WVM.ToDate;
            int            fromBookId       = this.WVM.SelectedFromBookVM.Id.Value;
            int            toBookId         = this.WVM.SelectedToBookVM.Id.Value;
            int            actValue         = this.WVM.Value.Value;
            CommissionKind commissionKind   = this.WVM.SelectedCommissionKind;
            int            commissionItemId = this.WVM.SelectedItemVM.Id;
            int            commission       = this.WVM.Commission ?? 0;
            string         remark           = this.WVM.SelectedRemark;

            int?resActionId = null;

            int tmpGroupId = -1; // ローカル用

            using (DaoBase dao = this.builder.Build()) {
                await dao.ExecTransactionAsync(async() => {
                    if (this.groupId == null)   // 追加
                    {
                        #region 帳簿項目を追加する
                        // グループIDを取得する
                        DaoReader reader = await dao.ExecQueryAsync(@"
INSERT INTO hst_group (group_kind, del_flg, update_time, updater, insert_time, inserter)
VALUES (@{0}, 0, 'now', @{1}, 'now', @{2}) RETURNING group_id;", (int)GroupKind.Move, Updater, Inserter);
                        reader.ExecARow((record) => {
                            tmpGroupId = record.ToInt("group_id");
                        });

                        reader = await dao.ExecQueryAsync(@"
-- 移動元
INSERT INTO hst_action (book_id, item_id, act_time, act_value, group_id, del_flg, update_time, updater, insert_time, inserter)
VALUES (@{0}, (
  SELECT item_id FROM mst_item I 
  INNER JOIN (SELECT * FROM mst_category WHERE balance_kind = @{6}) C ON C.category_id = I.category_id
  WHERE move_flg = 1
), @{1}, @{2}, @{3}, 0, 'now', @{4}, 'now', @{5}) RETURNING action_id;",
                                                          fromBookId, fromDate, -actValue, tmpGroupId, Updater, Inserter, (int)BalanceKind.Outgo);
                        if (this.selectedBookId == fromBookId)
                        {
                            reader.ExecARow((record) => {
                                resActionId = record.ToInt("action_id");
                            });
                        }

                        reader = await dao.ExecQueryAsync(@"
-- 移動先
INSERT INTO hst_action (book_id, item_id, act_time, act_value, group_id, del_flg, update_time, updater, insert_time, inserter)
VALUES (@{0}, (
  SELECT item_id FROM mst_item I
  INNER JOIN (SELECT * FROM mst_category WHERE balance_kind = @{6}) C ON C.category_id = I.category_id
  WHERE move_flg = 1
), @{1}, @{2}, @{3}, 0, 'now', @{4}, 'now', @{5}) RETURNING action_id;",
                                                          toBookId, toDate, actValue, tmpGroupId, Updater, Inserter, (int)BalanceKind.Income);
                        if (this.selectedBookId == toBookId)
                        {
                            reader.ExecARow((record) => {
                                resActionId = record.ToInt("action_id");
                            });
                        }
                        #endregion
                    }
                    else   // 編集
                    {
                        #region 帳簿項目を編集する
                        tmpGroupId = this.groupId.Value;
                        await dao.ExecNonQueryAsync(@"
-- 移動元
UPDATE hst_action
SET book_id = @{0}, act_time = @{1}, act_value = @{2}, update_time = 'now', updater = @{3}
WHERE action_id = @{4};", fromBookId, fromDate, -actValue, Updater, this.fromActionId);
                        if (this.selectedBookId == fromBookId)
                        {
                            resActionId = this.fromActionId;
                        }

                        await dao.ExecNonQueryAsync(@"
-- 移動先
UPDATE hst_action
SET book_id = @{0}, act_time = @{1}, act_value = @{2}, update_time = 'now', updater = @{3}
WHERE action_id = @{4};", toBookId, toDate, actValue, Updater, this.toActionId);
                        if (this.selectedBookId == toBookId)
                        {
                            resActionId = this.toActionId;
                        }
                        #endregion
                    }

                    if (commission != 0)
                    {
                        #region 手数料あり
                        int bookId       = -1;
                        DateTime actTime = DateTime.Now;
                        switch (commissionKind)
                        {
                        case CommissionKind.FromBook:
                            bookId  = fromBookId;
                            actTime = fromDate;
                            break;

                        case CommissionKind.ToBook:
                            bookId  = toBookId;
                            actTime = toDate;
                            break;
                        }
                        if (this.commissionActionId != null)
                        {
                            await dao.ExecNonQueryAsync(@"
UPDATE hst_action
SET book_id = @{0}, item_id = @{1}, act_time = @{2}, act_value = @{3}, remark = @{4}, update_time = 'now', updater = @{5}
WHERE action_id = @{6};", bookId, commissionItemId, actTime, -commission, remark, Updater, this.commissionActionId);
                        }
                        else
                        {
                            await dao.ExecNonQueryAsync(@"
INSERT INTO hst_action (book_id, item_id, act_time, act_value, group_id, remark, del_flg, update_time, updater, insert_time, inserter)
VALUES (@{0}, @{1}, @{2}, @{3}, @{4}, @{5}, 0, 'now', @{6}, 'now', @{7});", bookId, commissionItemId, actTime, -commission, tmpGroupId, remark, Updater, Inserter);
                        }
                        #endregion
                    }
                    else
                    {
                        #region 手数料なし
                        if (this.commissionActionId != null)
                        {
                            await dao.ExecNonQueryAsync(@"
UPDATE hst_action
SET del_flg = 1, update_time = 'now', updater = @{0}
WHERE action_id = @{1};", Updater, this.commissionActionId);
                        }
                        #endregion
                    }
                });

                if (remark != string.Empty)
                {
                    #region 備考を追加する
                    DaoReader reader = await dao.ExecQueryAsync(@"
SELECT remark FROM hst_remark
WHERE item_id = @{0} AND remark = @{1};", commissionItemId, remark);

                    if (reader.Count == 0)
                    {
                        await dao.ExecNonQueryAsync(@"
INSERT INTO hst_remark (item_id, remark, remark_kind, used_time, del_flg, update_time, updater, insert_time, inserter)
VALUES (@{0}, @{1}, 0, @{2}, 0, 'now', @{3}, 'now', @{4});", commissionItemId, remark, fromDate > toDate?fromDate : toDate, Updater, Inserter);
                    }
                    else
                    {
                        await dao.ExecNonQueryAsync(@"
UPDATE hst_remark
SET used_time = @{0}, del_flg = 0, update_time = 'now', updater = @{1}
WHERE item_id = @{2} AND remark = @{3} AND used_time < @{0};", fromDate > toDate?fromDate : toDate, Updater, commissionItemId, remark);
                    }
                    #endregion
                }

                return(resActionId);
            }
        }
        /// <summary>
        /// フォーム読込完了時
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void MoveRegistrationWindow_Loaded(object sender, RoutedEventArgs e)
        {
            ObservableCollection <BookViewModel> bookVMList = new ObservableCollection <BookViewModel>();
            int?          movedBookId      = this.selectedBookId;
            int?          movingBookId     = this.selectedBookId;
            BookViewModel movedBookVM      = null;
            BookViewModel movingBookVM     = null;
            int?          commissionItemId = null;
            string        commissionRemark = null;

            switch (this.WVM.RegMode)
            {
            case RegistrationMode.Edit:
            case RegistrationMode.Copy: {
                DateTime       movedDate       = DateTime.Now;
                DateTime       movingDate      = DateTime.Now;
                CommissionKind commissionKind  = CommissionKind.FromBook;
                int            moveValue       = -1;
                int            commissionValue = 0;

                using (DaoBase dao = this.builder.Build()) {
                    DaoReader reader = await dao.ExecQueryAsync(@"
SELECT A.book_id, A.action_id, A.item_id, A.act_time, A.act_value, A.remark, I.move_flg
FROM hst_action A
INNER JOIN (SELECT * FROM mst_item WHERE del_flg = 0) I ON I.item_id = A.item_id
WHERE A.del_flg = 0 AND A.group_id = @{0}
ORDER BY move_flg DESC;", this.groupId);

                    reader.ExecWholeRow((count, record) => {
                            int bookId        = record.ToInt("book_id");
                            DateTime dateTime = record.ToDateTime("act_time");
                            int actionId      = record.ToInt("action_id");
                            int itemId        = record.ToInt("item_id");
                            int actValue      = record.ToInt("act_value");
                            int moveFlg       = record.ToInt("move_flg");
                            string remark     = record["remark"];

                            if (moveFlg == 1)
                            {
                                if (actValue < 0)
                                {
                                    movedBookId       = bookId;
                                    movedDate         = dateTime;
                                    this.fromActionId = actionId;
                                }
                                else
                                {
                                    movingBookId    = bookId;
                                    movingDate      = dateTime;
                                    this.toActionId = actionId;
                                    moveValue       = actValue;
                                }
                            }
                            else                           // 手数料
                            {
                                if (bookId == movedBookId) // 移動元負担
                                {
                                    commissionKind = CommissionKind.FromBook;
                                }
                                else if (bookId == movingBookId)       // 移動先負担
                                {
                                    commissionKind = CommissionKind.ToBook;
                                }
                                this.commissionActionId = actionId;
                                commissionItemId        = itemId;
                                commissionValue         = Math.Abs(actValue);
                                commissionRemark        = remark;
                            }
                            return(true);
                        });
                }

                this.WVM.IsLink                 = (movedDate == movingDate);
                this.WVM.MovedDate              = movedDate;
                this.WVM.MovingDate             = movingDate;
                this.WVM.SelectedCommissionKind = commissionKind;
                this.WVM.Value      = moveValue;
                this.WVM.Commission = commissionValue;
            }
            break;
            }

            int?debitBookId = null;
            int?payDay      = null;

            using (DaoBase dao = this.builder.Build()) {
                DaoReader reader = await dao.ExecQueryAsync(@"
SELECT book_id, book_name, book_kind, debit_book_id, pay_day FROM mst_book WHERE del_flg = 0 ORDER BY sort_order;");

                reader.ExecWholeRow((count, record) => {
                    BookViewModel vm = new BookViewModel()
                    {
                        Id = record.ToInt("book_id"), Name = record["book_name"]
                    };
                    bookVMList.Add(vm);

                    if (movedBookVM == null || movedBookId == vm.Id)
                    {
                        movedBookVM = vm;

                        switch (this.WVM.RegMode)
                        {
                        case RegistrationMode.Add: {
                            if (record.ToInt("book_kind") == (int)BookKind.CreditCard)
                            {
                                debitBookId = record.ToNullableInt("debit_book_id");
                                payDay      = record.ToNullableInt("pay_day");
                            }
                        }
                        break;
                        }
                        ;
                    }
                    if (movingBookVM == null || movingBookId == vm.Id)
                    {
                        movingBookVM = vm;
                    }
                    return(true);
                });
            }

            this.WVM.BookVMList           = bookVMList;
            this.WVM.SelectedMovedBookVM  = movedBookVM;
            this.WVM.SelectedMovingBookVM = movingBookVM;

            switch (this.WVM.RegMode)
            {
            case RegistrationMode.Add: {
                if (debitBookId != null)
                {
                    this.WVM.SelectedMovedBookVM = bookVMList.FirstOrDefault((vm) => { return(vm.Id == debitBookId); });
                }
                this.WVM.MovedDate = this.selectedDate ?? ((this.selectedMonth == null || this.selectedMonth?.Month == DateTime.Today.Month) ? DateTime.Today : this.selectedMonth.Value);
                if (payDay != null)
                {
                    this.WVM.MovedDate = this.WVM.MovedDate.GetDateInMonth(payDay.Value);
                }
                this.WVM.IsLink = true;
                this.WVM.SelectedCommissionKind = CommissionKind.FromBook;
            }
            break;
            }
            ;

            await this.UpdateItemListAsync(commissionItemId);

            await this.UpdateRemarkListAsync(commissionRemark);

            #region イベントハンドラの設定
            this.WVM.FromBookChanged += async() => {
                await this.UpdateItemListAsync();

                await this.UpdateRemarkListAsync();
            };
            this.WVM.ToBookChanged += async() => {
                await this.UpdateItemListAsync();

                await this.UpdateRemarkListAsync();
            };
            this.WVM.CommissionKindChanged += async() => {
                await this.UpdateItemListAsync();

                await this.UpdateRemarkListAsync();
            };
            this.WVM.ItemChanged += async() => {
                await this.UpdateRemarkListAsync();
            };
            #endregion
        }