Пример #1
0
        public ARmDataSet MergeDataSet(IEnumerable <ARmDataSet> list, string expand, MergingMode mode, Func <IEnumerable <ARmDataSet>, string, MergingMode, ARmDataSet> del)
        {
            ARmDataSet dataSet = del(list, expand, mode);

            string rmType = Base.Report.Current.Type;

            if (rmType == ARmReport.PM)
            {
                foreach (ARmDataSet set in list)
                {
                    if (set == null)
                    {
                        continue;
                    }

                    RMReportWildcard.ConcatenateRangeWithDataSet(dataSet, set, Keys.StartAccountGroup, Keys.EndAccountGroup, mode);
                    RMReportWildcard.ConcatenateRangeWithDataSet(dataSet, set, Keys.StartProject, Keys.EndProject, mode);
                    RMReportWildcard.ConcatenateRangeWithDataSet(dataSet, set, Keys.StartProjectTask, Keys.EndProjectTask, mode);
                    RMReportWildcard.ConcatenateRangeWithDataSet(dataSet, set, Keys.StartInventory, Keys.EndInventory, mode);
                }

                dataSet.Expand = list.First().Expand;
            }

            return(dataSet);
        }
Пример #2
0
        public virtual void PMEnsureInitialized()
        {
            if (_historyLoaded == null)
            {
                _reportPeriods = new RMReportPeriods <PMHistory>(this.Base);

                var accountGroupSelect = new PXSelect <PMAccountGroup>(this.Base);
                accountGroupSelect.View.Clear();
                accountGroupSelect.Cache.Clear();

                var projectSelect = new PXSelect <PMProject, Where <PMProject.isTemplate, Equal <False>, And <PMProject.nonProject, Equal <False>, And <PMProject.baseType, Equal <PMProject.ProjectBaseType> > > > >(this.Base);
                projectSelect.View.Clear();
                projectSelect.Cache.Clear();

                var taskSelect = new PXSelectJoin <PMTask, InnerJoin <PMProject, On <PMTask.projectID, Equal <PMProject.contractID> > >, Where <PMProject.isTemplate, Equal <False>, And <PMProject.nonProject, Equal <False> > > >(this.Base);
                taskSelect.View.Clear();
                taskSelect.Cache.Clear();

                var itemSelect = new PXSelectJoinGroupBy <InventoryItem, InnerJoin <PMHistory, On <InventoryItem.inventoryID, Equal <PMHistory.inventoryID> > >, Aggregate <GroupBy <InventoryItem.inventoryID> > >(this.Base);
                itemSelect.View.Clear();
                itemSelect.Cache.Clear();

                if (Base.Report.Current.ApplyRestrictionGroups == true)
                {
                    projectSelect.WhereAnd <Where <Match <Current <AccessInfo.userName> > > >();
                    taskSelect.WhereAnd <Where <Match <Current <AccessInfo.userName> > > >();
                    itemSelect.WhereAnd <Where <Match <Current <AccessInfo.userName> > > >();
                }

                accountGroupSelect.Select();
                projectSelect.Select();
                taskSelect.Select();

                foreach (InventoryItem item in itemSelect.Select())
                {
                    //The PXSelectJoinGroupBy is read-only, and Inventory items won't be added to the cache. Add them manually.
                    itemSelect.Cache.SetStatus(item, PXEntryStatus.Notchanged);
                }

                _historySegments       = new HashSet <PMHistoryKeyTuple>();
                _pmhistoryPeriodsByKey = new Dictionary <PMHistoryKeyTuple, Dictionary <string, PMHistory> >();
                _historyLoaded         = new HashSet <int>();

                _accountGroupsRangeCache = new RMReportRange <PMAccountGroup>(Base, PM.AccountGroupAttribute.DimensionName, RMReportConstants.WildcardMode.Fixed, RMReportConstants.BetweenMode.Fixed);
                _projectsRangeCache      = new RMReportRange <PMProject>(Base, PM.ProjectAttribute.DimensionName, RMReportConstants.WildcardMode.Fixed, RMReportConstants.BetweenMode.Fixed);
                _tasksRangeCache         = new RMReportRange <PMTask>(Base, PM.ProjectTaskAttribute.DimensionName, RMReportConstants.WildcardMode.Normal, RMReportConstants.BetweenMode.Fixed);
                _itemRangeCache          = new RMReportRange <InventoryItem>(Base, IN.InventoryAttribute.DimensionName, RMReportConstants.WildcardMode.Fixed, RMReportConstants.BetweenMode.Fixed);

                //Add Inventory <OTHER> with InventoryID=0
                InventoryItem other = new InventoryItem
                {
                    InventoryCD = RMReportWildcard.EnsureWildcardForFixed(Messages.OtherItem, _itemRangeCache.Wildcard),
                    InventoryID = PMInventorySelectorAttribute.EmptyInventoryID,
                    Descr       = Messages.OtherItemDescription
                };
                itemSelect.Cache.SetStatus(other, PXEntryStatus.Notchanged);
            }
        }
        public List <T> GetPeriodsForRegularAmount(RMDataSourceGL dsGL, Dictionary <string, T> periodsForKey)
        {
            if (dsGL.StartPeriod != null)
            {
                var periods = new List <T>();

                string per = RMReportWildcard.EnsureWildcard(dsGL.StartPeriod, _perWildcard);
                if (!per.Contains(_perWildcard) && dsGL.StartPeriodOffset != null && dsGL.StartPeriodOffset != 0 || dsGL.StartPeriodYearOffset != 0)
                {
                    per = GetFinPeriod(per, dsGL.StartPeriodYearOffset, dsGL.StartPeriodOffset);
                }
                if (dsGL.EndPeriod == null)
                {
                    if (!per.Contains(_perWildcard))
                    {
                        T v;
                        if (periodsForKey.TryGetValue(per, out v))
                        {
                            periods.Add(v);
                        }
                    }
                    else
                    {
                        foreach (var p in periodsForKey)
                        {
                            if (RMReportWildcard.IsLike(per, p.Key))
                            {
                                periods.Add(p.Value);
                            }
                        }
                    }
                }
                else
                {
                    string toper = RMReportWildcard.EnsureWildcard(dsGL.EndPeriod, _perWildcard);
                    if (!toper.Contains(RMReportConstants.DefaultWildcardChar) && dsGL.EndPeriodOffset != null && dsGL.EndPeriodOffset != 0 || dsGL.EndPeriodYearOffset != 0)
                    {
                        toper = GetFinPeriod(toper, dsGL.EndPeriodYearOffset, dsGL.EndPeriodOffset);
                    }
                    toper = toper.Replace(RMReportConstants.DefaultWildcardChar, '9');

                    foreach (var p in periodsForKey)
                    {
                        if (RMReportWildcard.IsBetween(per, toper, p.Key))
                        {
                            periods.Add(p.Value);
                        }
                    }
                }

                return(periods);
            }
            else
            {
                return(periodsForKey.Values.ToList <T>());
            }
        }
        public List <T> GetPeriodsForBeginningBalanceAmount(RMDataSourceGL dsGL, Dictionary <string, T> periodsForKey, bool limitToStartYear, out bool takeLast)
        {
            takeLast = false;

            if (dsGL.StartPeriod != null)
            {
                string per = RMReportWildcard.EnsureWildcard(dsGL.StartPeriod, _perWildcard);
                if (!per.Contains(_perWildcard))
                {
                    per = GetFinPeriod(per, dsGL.StartPeriodYearOffset, dsGL.StartPeriodOffset);
                    string mostRecentPeriod;

                    if (limitToStartYear)
                    {
                        // For profit and loss accounts, we only look into same fiscal year as the end period.
                        mostRecentPeriod = GetMostRecentPeriodInList(periodsForKey, per.Substring(0, 4), per);
                    }
                    else
                    {
                        // For other type of accounts, we retrive the most recent row, no matter what is the year
                        mostRecentPeriod = GetMostRecentPeriodInList(periodsForKey, per);
                    }

                    if (String.IsNullOrEmpty(mostRecentPeriod))
                    {
                        return(null);
                    }
                    else
                    {
                        takeLast = per != mostRecentPeriod;
                        return(new List <T> {
                            periodsForKey[mostRecentPeriod]
                        });
                    }
                }
                else
                {
                    return(periodsForKey.Values.ToList <T>());
                }
            }
            else
            {
                return(periodsForKey.Values.ToList <T>());
            }
        }
        private HashSet <T> GetItems(string range, Func <T, string> getValuePredicate, Action <T, string> prepareForLocatePredicate)
        {
            var items = new HashSet <T>();

            string[] pairs = range.Split(RMReportConstants.RangeUnionChar);

            foreach (string pair in pairs)
            {
                string start, end;
                ParseRangeStartEndPair(pair, out start, out end);

                if (!String.IsNullOrEmpty(start))
                {
                    if (String.IsNullOrEmpty(end) || end == start)
                    {
                        string itemCode = String.Empty;

                        if (_wildcardMode == RMReportConstants.WildcardMode.Fixed)
                        {
                            itemCode = RMReportWildcard.EnsureWildcardForFixed(start, _wildcard);
                        }
                        else if (_wildcardMode == RMReportConstants.WildcardMode.Normal)
                        {
                            itemCode = RMReportWildcard.EnsureWildcard(start, _wildcard);
                        }
                        else
                        {
                            throw new ArgumentException(Messages.InvalidWildcardMode);
                        }

                        if (itemCode.Contains(RMReportConstants.DefaultWildcardChar))
                        {
                            items.UnionWith(from T x in _cache.Cached where RMReportWildcard.IsLike(itemCode, getValuePredicate(x)) select x);
                        }
                        else
                        {
                            prepareForLocatePredicate(_instance, itemCode);
                            if (_cache.IsKeysFilled(_instance))
                            {
                                T x = (T)_cache.Locate(_instance);
                                if (x != null)
                                {
                                    items.Add(x);
                                }
                            }
                            else     // composite key
                            {
                                items.UnionWith(from T x in _cache.Cached where String.Equals(itemCode, getValuePredicate(x), StringComparison.Ordinal) select x);
                            }
                        }
                    }
                    else
                    {
                        if (_betweenMode == RMReportConstants.BetweenMode.ByChar)
                        {
                            items.UnionWith(from T x in _cache.Cached where RMReportWildcard.IsBetweenByChar(start, end, getValuePredicate(x)) select x);
                        }
                        else if (_betweenMode == RMReportConstants.BetweenMode.Fixed)
                        {
                            items.UnionWith(RMReportWildcard.GetBetweenForFixed <T>(start, end, _wildcard, _cache.Cached, getValuePredicate));
                        }
                        else
                        {
                            throw new ArgumentException(Messages.InvalidBetweenMode);
                        }
                    }
                }
                else
                {
                    items.UnionWith(_cache.Cached.Cast <T>());
                }
            }
            return(items);
        }
        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);
        }
Пример #7
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);
        }