public static List <ARmUnit> ExpandUnit(RMReportReader report, RMDataSource ds, ARmUnit unit, object startKey, object endKey, Func <ARmDataSet, List <T> > fetchRangePredicate, Func <T, string> unitCodePredicate, Func <T, string> unitDescriptionPredicate, Action <T, string> applyWildcardToItemAction)
        {
            string nonExpandingWildcard = null;

            PreProcessNonExpandingWildcardChar(unit.DataSet, startKey, out nonExpandingWildcard);

            //This will validate Start/End range and merge the pair into a single range-like value that FillSubsList expects.
            ARmDataSet rangeToFetch = new ARmDataSet();

            RMReportWildcard.ConcatenateRangeWithDataSet(rangeToFetch, unit.DataSet, startKey, endKey, MergingMode.Intersection);

            List <T> unitItems = fetchRangePredicate(rangeToFetch);

            if (nonExpandingWildcard != null)
            {
                //TODO: Build a better auto-description based on segment values instead of copying code to description?
                unitItems = ReduceListByNonExpandingWildcard(nonExpandingWildcard, unitItems,
                                                             (u) => unitCodePredicate(u),
                                                             (u, mv) => applyWildcardToItemAction(u, mv));
            }

            switch (ds.RowDescription.Trim().ToUpper())
            {
            case RowDescriptionType.CodeDescription:
                unitItems.Sort((x, y) => (unitCodePredicate(x) + unitDescriptionPredicate(x)).CompareTo(unitCodePredicate(y) + unitDescriptionPredicate(y)));
                break;

            case RowDescriptionType.DescriptionCode:
                unitItems.Sort((x, y) => (unitDescriptionPredicate(x) + unitCodePredicate(x)).CompareTo(unitDescriptionPredicate(y) + unitCodePredicate(y)));
                break;

            case RowDescriptionType.Description:
                unitItems.Sort((x, y) => unitDescriptionPredicate(x).CompareTo(unitDescriptionPredicate(y)));
                break;

            default:
                unitItems.Sort((x, y) => unitCodePredicate(x).CompareTo(unitCodePredicate(y)));
                break;
            }

            List <ARmUnit> units = new List <ARmUnit>();
            int            n     = 0;

            foreach (T unitItem in unitItems)
            {
                n++;
                var u = new ARmUnit();
                report.FillDataSource(ds, u.DataSet, report.Report.Current.Type);
                u.DataSet[startKey] = unitCodePredicate(unitItem);
                u.DataSet[endKey]   = null;
                u.Code = unit.Code + n.ToString("D5");

                switch (ds.RowDescription.Trim())
                {
                case RowDescriptionType.CodeDescription:
                    u.Description = string.Format("{0}{1}{2}", unitCodePredicate(unitItem).Trim(), "-", unitDescriptionPredicate(unitItem));
                    break;

                case RowDescriptionType.DescriptionCode:
                    u.Description = string.Format("{0}{1}{2}", unitDescriptionPredicate(unitItem), "-", unitCodePredicate(unitItem).Trim());
                    break;

                case RowDescriptionType.Description:
                    u.Description = unitDescriptionPredicate(unitItem);
                    break;

                default:
                    u.Description = unitCodePredicate(unitItem).Trim();
                    break;
                }

                u.Formula       = unit.Formula;
                u.PrintingGroup = unit.PrintingGroup;
                units.Add(u);
            }
            return(units);
        }
示例#2
0
        public virtual List <ARmUnit> ExpandUnit(RMDataSource ds, ARmUnit unit, Func <RMDataSource, ARmUnit, List <ARmUnit> > del)
        {
            string rmType = Base.Report.Current.Type;

            if (rmType == ARmReport.PM)
            {
                if (unit.DataSet.Expand != ExpandType.Nothing)
                {
                    PMEnsureInitialized();
                    if (ds.Expand == ExpandType.AccountGroup)
                    {
                        return(RMReportUnitExpansion <PMAccountGroup> .ExpandUnit(Base, ds, unit, Keys.StartAccountGroup, Keys.EndAccountGroup,
                                                                                  rangeToFetch => _accountGroupsRangeCache.GetItemsInRange(rangeToFetch[Keys.StartAccountGroup] as string,
                                                                                                                                           accountGroup => accountGroup.GroupCD,
                                                                                                                                           (accountGroup, code) => accountGroup.GroupCD = code),
                                                                                  accountGroup => accountGroup.GroupCD, accountGroup => accountGroup.Description,
                                                                                  (accountGroup, wildcard) => { accountGroup.GroupCD = wildcard; accountGroup.Description = wildcard; }));
                    }
                    else if (ds.Expand == ExpandType.Project)
                    {
                        return(RMReportUnitExpansion <PMProject> .ExpandUnit(Base, ds, unit, Keys.StartProject, Keys.EndProject,
                                                                             rangeToFetch => _projectsRangeCache.GetItemsInRange(rangeToFetch[Keys.StartProject] as string,
                                                                                                                                 project => project.ContractCD,
                                                                                                                                 (project, code) => project.ContractCD = code),
                                                                             project => project.ContractCD, project => project.Description,
                                                                             (project, wildcard) => { project.ContractCD = wildcard; project.Description = wildcard; }));
                    }
                    else if (ds.Expand == ExpandType.ProjectTask)
                    {
                        return(RMReportUnitExpansion <PMTask> .ExpandUnit(Base, ds, unit, Keys.StartProjectTask, Keys.EndProjectTask,
                                                                          rangeToFetch => {
                            List <PMTask> tasks = _tasksRangeCache.GetItemsInRange(rangeToFetch[Keys.StartProjectTask] as string,
                                                                                   task => task.TaskCD,
                                                                                   (task, code) => task.TaskCD = code);

                            ARmDataSet projectRange = new ARmDataSet();
                            RMReportWildcard.ConcatenateRangeWithDataSet(projectRange, unit.DataSet, Keys.StartProject, Keys.EndProject, MergingMode.Intersection);

                            if (!String.IsNullOrEmpty(projectRange[Keys.StartProject] as string))
                            {
                                //A project range is specified in the unit; restrict tasks to tasks of this project range.
                                List <PMProject> projects = _projectsRangeCache.GetItemsInRange(projectRange[Keys.StartProject] as string,
                                                                                                project => project.ContractCD,
                                                                                                (project, code) => project.ContractCD = code);
                                tasks = tasks.Where(t => projects.Any(p => t.ProjectID == p.ContractID)).ToList <PMTask>();
                            }

                            //Same project TaskCD can be reused in multiple projects; it only makes sense to get distinct values for the purpose of filling the unit tree
                            List <PMTask> groupedTasks = tasks.GroupBy(t => t.TaskCD).Select(g => new PMTask()
                            {
                                TaskCD = g.Key, Description = g.Min(t => t.Description)
                            }).ToList <PMTask>();
                            return groupedTasks;
                        },
                                                                          task => task.TaskCD, project => project.Description,
                                                                          (task, wildcard) => { task.TaskCD = wildcard; task.Description = wildcard; }));
                    }
                    else if (ds.Expand == ExpandType.Inventory)
                    {
                        return(RMReportUnitExpansion <InventoryItem> .ExpandUnit(Base, ds, unit, Keys.StartInventory, Keys.EndInventory,
                                                                                 rangeToFetch => _itemRangeCache.GetItemsInRange(rangeToFetch[Keys.StartInventory] as string,
                                                                                                                                 item => item.InventoryCD,
                                                                                                                                 (item, code) => item.InventoryCD = code),
                                                                                 item => item.InventoryCD, item => item.Descr,
                                                                                 (item, wildcard) => { item.InventoryCD = wildcard; item.Descr = wildcard; }));
                    }
                }
            }
            else
            {
                return(del(ds, unit));
            }

            return(null);
        }