public async Task <IEnumerable <CustomerGroup> > SaveAsync(MasterImportData <CustomerGroup> items, CancellationToken token = default(CancellationToken))
        {
            var result = new List <CustomerGroup>();

            using (var scope = transactionScopeBuilder.Create())
            {
                foreach (var x in items.DeleteItems)
                {
                    await deleteCustomerGroupQueryProcessor.DeleteAsync(x, token);
                }

                foreach (var x in items.InsertItems)
                {
                    result.Add(await addCustomerGroupQueryProcessor.SaveAsync(x, token));
                }

                scope.Complete();
            }
            return(result);
        }
        public async Task <MatchingResult> MatchAsync(
            MatchingSource source,
            CancellationToken token    = default(CancellationToken),
            IProgressNotifier notifier = null)
        {
            var matchings        = source.Matchings;
            var loginUserId      = source.LoginUserId;
            var companyId        = source.CompanyId;
            var customerId       = source.CustomerId ?? 0;
            var paymentAgencyId  = source.PaymentAgencyId ?? 0;
            var childCustomerIds = source.ChildCustomerIds;
            var useKanaLearning  = source.UseKanaLearning == 1;
            var useFeeLearning   = source.UseFeeLearning == 1;

            var appControl = await applicationControlQueryProcessor.GetAsync(companyId, token);

            var updateAt = await dbSystemDateTimeQueryProcessor.GetAsync(token);

            source.UpdateAt = updateAt;

            var useAuthorization = appControl?.UseAuthorization == 1;
            var nettingReceipts  = new List <Receipt>();
            // DBサーバーから取得する

            var billings = new List <Billing>();
            var receipts = new List <Receipt>();
            var matchingBillingDiscounts = new List <MatchingBillingDiscount>();
            var billingScheduledIncomes  = new List <BillingScheduledIncome>();
            var billingDiscounts         = new HashSet <long>();

            MatchingResult validateResult = null;

            if (!(await ValidateMatchingDataAsync(source,
                                                  x => validateResult = x,
                                                  token)))
            {
                return(validateResult);
            }

            var currencyId = source.Matchings.First().CurrencyId;


            using (var scope = transactionScopeBuilder.Create())
            {
                #region 相殺データ変換
                nettingReceipts = await PrepareNettingDataAsync(source, loginUserId, updateAt, token);

                foreach (var r in nettingReceipts)
                {
                    var item = source.Receipts.First(x => x.Id == r.Id);
                    item.UpdateAt = r.UpdateAt;
                }
                #endregion

                #region matchingHeader
                var header = source.MatchingHeader;
                header.MatchingProcessType = 1;
                header.Approved            = useAuthorization ? 0 : 1;
                header.CreateBy            = loginUserId;
                header.UpdateBy            = loginUserId;
                header.CreateAt            = updateAt;
                header.UpdateAt            = updateAt;
                #endregion

                #region 手数料学習
                var bankFee = header.BankTransferFee;
                if (useFeeLearning)
                {
                    await SaveBankTransferFeeAsync(customerId, paymentAgencyId, currencyId, bankFee, updateAt, loginUserId, token);
                }
                #endregion

                #region 債権代表者登録
                if (childCustomerIds.Any())
                {
                    var isParent = 1;
                    await updateCustomerQueryProcessor.UpdateIsParentAsync(isParent, loginUserId, new[] { customerId }, token);

                    foreach (var childId in childCustomerIds)
                    {
                        var group = new CustomerGroup();
                        group.ParentCustomerId = customerId;
                        group.ChildCustomerId  = childId;
                        group.CreateAt         = updateAt;
                        group.CreateBy         = loginUserId;
                        group.UpdateAt         = updateAt;
                        group.UpdateBy         = loginUserId;
                        await addCustomerGroupQueryProcessor.SaveAsync(group, token);
                    }
                }
                #endregion

                #region  学習履歴の登録
                if (useKanaLearning)
                {
                    await SaveKanaLearningAsync(matchings, companyId, customerId, paymentAgencyId, loginUserId, updateAt);
                }
                #endregion

                var matchingResult = await matchingSaveProcessor.SaveAsync(source, appControl, token);

                if (matchingResult.ProcessResult.Result)
                {
                    scope.Complete();
                }

                matchingResult.NettingReceipts = nettingReceipts;

                return(matchingResult);
            }
        }