Beispiel #1
0
 public async Task <IEnumerable <CustomerPaymentContract> > GetAsync(IEnumerable <int> ids, CancellationToken token = default(CancellationToken))
 => await customerPaymentContractQueryProcessor.GetAsync(ids, token);
        /// <summary>回収予定表 データ抽出/整形</summary>
        /// <param name="searchOption"></param>
        /// <returns></returns>
        /// <remarks>
        /// 得意先 回収区分の情報をどのように取り扱うか ビジネスロジックはここに寄せる
        /// </remarks>
        public async Task <IEnumerable <CollectionSchedule> > GetAsync(CollectionScheduleSearch searchOption, CancellationToken token, IProgressNotifier notifier)
        {
            var initializeResult = searchOption.InitializeYearMonth();

            var schedules = (await collectionScheduleQueryProcessor.GetAsync(searchOption, token, notifier))
                            .Where(x => x.HasAnyValue).ToList();

            if (!(schedules?.Any() ?? false))
            {
                notifier?.UpdateState();
                return(Enumerable.Empty <CollectionSchedule>());
            }

            const int    collectCategoryType = 3;
            const string ContractCode        = "00";
            var          categories          = (await categoryByCodeQueryProcessor.GetAsync(new CategorySearch {
                CompanyId = searchOption.CompanyId, CategoryType = collectCategoryType
            }, token)).ToList();
            var contractId  = categories.FirstOrDefault(x => x.Code == ContractCode)?.Id ?? 0;
            var customerIds = schedules.Where(x => x.CustomerCollectCategoryId == contractId)
                              .Select(x => x.CustomerId).Distinct().ToArray();
            var contracts = await customerPaymentContractQueryProcessor.GetAsync(customerIds, token);


            var result     = new List <CollectionSchedule>();
            var groupCount = 0;

            var subtotal = new Dictionary <string, Dictionary <int, decimal> >();
            var subDpt   = new Dictionary <string, Dictionary <int, decimal> >();
            var subStf   = new Dictionary <string, Dictionary <int, decimal> >();
            var deptBuf  = string.Empty;
            var stafBuf  = string.Empty;
            var requireDepartmentSubtotal = searchOption.IsPrint && searchOption.NewPagePerDepartment;
            var requireStaffSubtotal      = searchOption.IsPrint && searchOption.NewPagePerStaff;

            foreach (var group in schedules.GroupBy(x => x.CustomerId))
            {
                var detail       = group.First();
                var category     = categories.FirstOrDefault(x => x.Id != contractId && x.Id == detail.CustomerCollectCategoryId);
                var contract     = contracts.FirstOrDefault(x => x.CustomerId == detail.CustomerId);
                var customerInfo = GetCustomerInfo(detail, category, contract);

                if (requireStaffSubtotal &&
                    !string.IsNullOrEmpty(stafBuf) && stafBuf != detail.StaffCode)
                {
                    result.AddRange(GetSubtotalRecords(subStf, categories, deptBuf, stafBuf, 1, "担当者計", ref groupCount));
                }

                if (requireDepartmentSubtotal &&
                    !string.IsNullOrEmpty(deptBuf) && deptBuf != detail.DepartmentCode)
                {
                    result.AddRange(GetSubtotalRecords(subDpt, categories, deptBuf, stafBuf, 2, "部門計", ref groupCount));
                }

                var list = new List <CollectionSchedule>();

                CollectionSchedule contractPayment = null;
                foreach (var item in group)
                {
                    if (item.CollectCategoryCode == ContractCode)
                    {
                        contractPayment = item;
                        continue;
                    }
                    list.Add(item);
                }

                if (contractPayment != null && contract != null)
                {
                    foreach (var divided in Divide(contractPayment, contract))
                    {
                        var index = list.FindIndex(x => x.CollectCategoryCode == divided.CollectCategoryCode);
                        if (index < 0)
                        {
                            list.Add(divided);
                            continue;
                        }
                        list[index].UncollectedAmountLast += divided.UncollectedAmountLast;
                        list[index].UncollectedAmount0    += divided.UncollectedAmount0;
                        list[index].UncollectedAmount1    += divided.UncollectedAmount1;
                        list[index].UncollectedAmount2    += divided.UncollectedAmount2;
                        list[index].UncollectedAmount3    += divided.UncollectedAmount3;
                    }
                    list.Sort((x, y) => string.Compare(x.CollectCategoryCode, y.CollectCategoryCode));
                }

                for (var i = 0; i < list.Count; i++)
                {
                    if (i == 0)
                    {
                        list[i].RowId = ++groupCount;
                    }
                    else
                    {
                        list[i].DepartmentName = string.Empty;
                        list[i].StaffName      = string.Empty;
                        list[i].ClosingDay     = null;
                    }

                    var code = list[i].CollectCategoryCode;
                    if (!subtotal.ContainsKey(code))
                    {
                        subtotal.Add(code, Pivot(null));
                    }
                    if (requireDepartmentSubtotal && !subDpt.ContainsKey(code))
                    {
                        subDpt.Add(code, Pivot(null));
                    }
                    if (requireStaffSubtotal && !subStf.ContainsKey(code))
                    {
                        subStf.Add(code, Pivot(null));
                    }

                    if (!list[i].HasAnyValue)
                    {
                        continue;
                    }

                    AddValue(subtotal[code], list[i]);
                    if (requireDepartmentSubtotal)
                    {
                        AddValue(subDpt[code], list[i]);
                    }
                    if (requireStaffSubtotal)
                    {
                        AddValue(subStf[code], list[i]);
                    }
                }

                for (var i = 0; i < customerInfo.Count; i++)
                {
                    if (list.Count <= i)
                    {
                        var item = new CollectionSchedule();
                        item.CustomerId     = detail.CustomerId;
                        item.StaffCode      = detail.StaffCode;
                        item.DepartmentCode = detail.DepartmentCode;
                        list.Add(item);
                    }
                    list[i].CustomerInfo = customerInfo[i];
                }
                result.AddRange(list);

                deptBuf = detail.DepartmentCode;
                stafBuf = detail.StaffCode;
            }

            if (requireStaffSubtotal)
            {
                result.AddRange(GetSubtotalRecords(subStf, categories, deptBuf, stafBuf, 1, "担当者計", ref groupCount));
            }

            if (requireDepartmentSubtotal)
            {
                result.AddRange(GetSubtotalRecords(subDpt, categories, deptBuf, stafBuf, 2, "部門計", ref groupCount));
            }

            // grand total
            {
                // category total
                result.AddRange(GetSubtotalRecords(new Dictionary <string, Dictionary <int, decimal> >(subtotal), categories, "", "", 3, "合計", ref groupCount));

                var item = GetNewItem(string.Empty, string.Empty);
                item.CustomerInfo = "総合計";
                item.RowId        = ++groupCount;
                item.RecordType   = 4;
                foreach (var key in subtotal.Keys)
                {
                    foreach (var field in subtotal[key].Keys)
                    {
                        SetValue(item, field, subtotal[key][field]);
                    }
                }

                result.Add(item);
            }

            if (searchOption.UnitPrice != 1M)
            {
                foreach (var item in result)
                {
                    item.Truncate(searchOption.UnitPrice);
                }
            }
            notifier?.UpdateState();
            return(result);
        }