protected virtual void NormalizeDataSource(RMDataSourcePM dsPM) { if (dsPM.StartAccountGroup != null && dsPM.StartAccountGroup.TrimEnd() == "") { dsPM.StartAccountGroup = null; } if (dsPM.EndAccountGroup != null && dsPM.EndAccountGroup.TrimEnd() == "") { dsPM.EndAccountGroup = null; } if (dsPM.StartProject != null && dsPM.StartProject.TrimEnd() == "") { dsPM.StartProject = null; } if (dsPM.EndProject != null && dsPM.EndProject.TrimEnd() == "") { dsPM.EndProject = null; } if (dsPM.StartProjectTask != null && dsPM.StartProjectTask.TrimEnd() == "") { dsPM.StartProjectTask = null; } if (dsPM.EndProjectTask != null && dsPM.EndProjectTask.TrimEnd() == "") { dsPM.EndProjectTask = null; } if (dsPM.StartInventory != null && dsPM.StartInventory.TrimEnd() == "") { dsPM.StartInventory = null; } if (dsPM.EndInventory != null && dsPM.EndInventory.TrimEnd() == "") { dsPM.EndInventory = null; } }
private void EnsureHistoryLoaded(RMDataSourcePM dsPM) { //Unlike RMReportReaderGL, there is no lazy loading for now, given the way PMHistory is structured we need to load whole project history to get balances for a given project //We could do lazy loading by project, but that would be slower if report including a large number of projects (ex: project profitability list) var key = 1; if (!_historyLoaded.Contains(key)) { ProcessPMResultset(PXSelectReadonly2 <PMHistory, InnerJoin <PMTask, On <PMHistory.projectTaskID, Equal <PMTask.taskID> > > > .Select(this.Base)); _historyLoaded.Add(key); } }
private void FillDataSourceInternal(RMDataSource ds, ARmDataSet dst, string rmType) { if (ds != null && ds.DataSourceID != null) { RMDataSourcePM dsPM = Base.Caches[typeof(RMDataSource)].GetExtension <RMDataSourcePM>(ds); dst[Keys.StartAccountGroup] = dsPM.StartAccountGroup; dst[Keys.EndAccountGroup] = dsPM.EndAccountGroup; dst[Keys.StartProject] = dsPM.StartProject; dst[Keys.EndProject] = dsPM.EndProject; dst[Keys.StartProjectTask] = dsPM.StartProjectTask; dst[Keys.EndProjectTask] = dsPM.EndProjectTask; dst[Keys.StartInventory] = dsPM.StartInventory; dst[Keys.EndInventory] = dsPM.EndInventory; } }
private object CalculateAndExpandValue(bool drilldown, RMDataSource ds, RMDataSourceGL dsGL, RMDataSourcePM dsPM, ARmDataSet dataSet, List <PMAccountGroup> accountGroups, List <PMProject> projects, List <PMTask> tasks, List <InventoryItem> items, List <object[]> splitret) { decimal totalAmount = 0; object locker = new object(); Dictionary <PMHistoryKeyTuple, PXResult <PMHistory, PMProject, PMTask, PMAccountGroup, InventoryItem> > drilldownData = null; if (drilldown) { drilldownData = new Dictionary <PMHistoryKeyTuple, PXResult <PMHistory, PMProject, PMTask, PMAccountGroup, InventoryItem> >(); } Parallel.For(0, accountGroups.Count, accountGroup => { PMAccountGroup currentAccountGroup = accountGroups[accountGroup]; if (!_historySegments.Contains(new PMHistoryKeyTuple(0, String.Empty, currentAccountGroup.GroupID.Value, 0))) { return; } Parallel.For(0, projects.Count, project => { PMProject currentProject = projects[project]; if (!_historySegments.Contains(new PMHistoryKeyTuple(currentProject.ContractID.Value, String.Empty, currentAccountGroup.GroupID.Value, 0))) { return; } Parallel.For(0, tasks.Count, task => { PMTask currentTask = tasks[task]; if (!_historySegments.Contains(new PMHistoryKeyTuple(currentProject.ContractID.Value, currentTask.TaskCD, currentAccountGroup.GroupID.Value, 0))) { return; } if (ds.Expand != ExpandType.ProjectTask && currentTask.ProjectID != currentProject.ContractID) { return; } Parallel.For(0, items.Count, item => { InventoryItem currentItem = items[item]; List <PMHistory> periods = GetPeriodsToCalculate(currentProject, currentTask, currentAccountGroup, currentItem, ds, dsGL); if (periods == null) { return; } foreach (var hist in periods) { decimal amount = GetAmountFromPMHistory(ds, hist); lock (locker) { totalAmount += amount; } if (drilldown) { var key = new PMHistoryKeyTuple(currentProject.ContractID.Value, currentTask.TaskCD, currentAccountGroup.GroupID.Value, currentItem.InventoryID.Value); PXResult <PMHistory, PMProject, PMTask, PMAccountGroup, InventoryItem> drilldownRow = null; lock (drilldownData) { if (!drilldownData.TryGetValue(key, out drilldownRow)) { drilldownRow = new PXResult <PMHistory, PMProject, PMTask, PMAccountGroup, InventoryItem>(new PMHistory(), currentProject, currentTask, currentAccountGroup, currentItem); drilldownData.Add(key, drilldownRow); } } lock (drilldownRow) { AggregatePMHistoryForDrilldown(drilldownRow, hist); } } if (ds.Expand == ExpandType.AccountGroup) { lock (currentAccountGroup) { splitret[accountGroup][2] = (decimal)splitret[accountGroup][2] + amount; if (splitret[accountGroup][3] == null) { var dataSetCopy = new ARmDataSet(dataSet); dataSetCopy[PX.Objects.CS.RMReportReaderPM.Keys.StartAccountGroup] = dataSetCopy[PX.Objects.CS.RMReportReaderPM.Keys.EndAccountGroup] = currentAccountGroup.GroupCD; splitret[accountGroup][3] = dataSetCopy; } } } else if (ds.Expand == ExpandType.Project) { lock (currentProject) { splitret[project][2] = (decimal)splitret[project][2] + amount; if (splitret[project][3] == null) { var dataSetCopy = new ARmDataSet(dataSet); dataSetCopy[PX.Objects.CS.RMReportReaderPM.Keys.StartProject] = dataSetCopy[PX.Objects.CS.RMReportReaderPM.Keys.EndProject] = currentProject.ContractCD; splitret[project][3] = dataSetCopy; } } } else if (ds.Expand == ExpandType.ProjectTask) { lock (currentItem) { splitret[task][2] = (decimal)splitret[task][2] + amount; if (splitret[task][3] == null) { var dataSetCopy = new ARmDataSet(dataSet); dataSetCopy[PX.Objects.CS.RMReportReaderPM.Keys.StartProjectTask] = dataSetCopy[PX.Objects.CS.RMReportReaderPM.Keys.EndProjectTask] = currentTask.TaskCD; splitret[task][3] = dataSetCopy; } } } else if (ds.Expand == ExpandType.Inventory) { lock (currentItem) { splitret[item][2] = (decimal)splitret[item][2] + amount; if (splitret[item][3] == null) { var dataSetCopy = new ARmDataSet(dataSet); dataSetCopy[PX.Objects.CS.RMReportReaderPM.Keys.StartInventory] = dataSetCopy[PX.Objects.CS.RMReportReaderPM.Keys.EndInventory] = currentItem.InventoryCD; splitret[item][3] = dataSetCopy; } } } } }); }); }); }); if (drilldown) { var resultset = new PXResultset <PMHistory, PMProject, PMTask, PMAccountGroup, InventoryItem>(); foreach (var r in from row in drilldownData.Values let projectCD = ((PMProject)row[typeof(PMProject)]).With(_ => _.ContractCD) let taskCD = ((PMTask)row[typeof(Sub)]).With(_ => _.TaskCD) let accGroupCD = ((PMAccountGroup)row[typeof(PMAccountGroup)]).With(_ => _.GroupCD) let inventoryCD = ((InventoryItem)row[typeof(InventoryItem)]).With(_ => _.InventoryCD) orderby projectCD, taskCD, accGroupCD, inventoryCD select row) { resultset.Add(r); } return(resultset); } else if (ds.Expand != ExpandType.Nothing) { return(splitret); } else { return(totalAmount); } }
public virtual object GetHistoryValue(ARmDataSet dataSet, bool drilldown, Func <ARmDataSet, bool, object> del) { string rmType = Base.Report.Current.Type; if (rmType == ARmReport.PM) { RMDataSource ds = Base.DataSourceByID.Current; RMDataSourcePM dsPM = Base.Caches[typeof(RMDataSource)].GetExtension <RMDataSourcePM>(ds); ds.AmountType = (short?)dataSet[RMReportReaderGL.Keys.AmountType]; dsPM.StartAccountGroup = dataSet[Keys.StartAccountGroup] as string ?? ""; dsPM.EndAccountGroup = dataSet[Keys.EndAccountGroup] as string ?? ""; dsPM.StartProject = dataSet[Keys.StartProject] as string ?? ""; dsPM.EndProject = dataSet[Keys.EndProject] as string ?? ""; dsPM.StartProjectTask = dataSet[Keys.StartProjectTask] as string ?? ""; dsPM.EndProjectTask = dataSet[Keys.EndProjectTask] as string ?? ""; dsPM.StartInventory = dataSet[Keys.StartInventory] as string ?? ""; dsPM.EndInventory = dataSet[Keys.EndInventory] as string ?? ""; RMDataSourceGL dsGL = Base.Caches[typeof(RMDataSource)].GetExtension <RMDataSourceGL>(ds); dsGL.StartBranch = dataSet[RMReportReaderGL.Keys.StartBranch] as string ?? ""; dsGL.EndBranch = dataSet[RMReportReaderGL.Keys.EndBranch] as string ?? ""; dsGL.EndPeriod = ((dataSet[RMReportReaderGL.Keys.EndPeriod] as string ?? "").Length > 2 ? ((dataSet[RMReportReaderGL.Keys.EndPeriod] as string ?? "").Substring(2) + " ").Substring(0, 4) : " ") + ((dataSet[RMReportReaderGL.Keys.EndPeriod] as string ?? "").Length > 2 ? (dataSet[RMReportReaderGL.Keys.EndPeriod] as string ?? "").Substring(0, 2) : dataSet[RMReportReaderGL.Keys.EndPeriod] as string ?? ""); dsGL.EndPeriodOffset = (short?)(int?)dataSet[RMReportReaderGL.Keys.EndOffset]; dsGL.EndPeriodYearOffset = (short?)(int?)dataSet[RMReportReaderGL.Keys.EndYearOffset]; dsGL.StartPeriod = ((dataSet[RMReportReaderGL.Keys.StartPeriod] as string ?? "").Length > 2 ? ((dataSet[RMReportReaderGL.Keys.StartPeriod] as string ?? "").Substring(2) + " ").Substring(0, 4) : " ") + ((dataSet[RMReportReaderGL.Keys.StartPeriod] as string ?? "").Length > 2 ? (dataSet[RMReportReaderGL.Keys.StartPeriod] as string ?? "").Substring(0, 2) : dataSet[RMReportReaderGL.Keys.StartPeriod] as string ?? ""); dsGL.StartPeriodOffset = (short?)(int?)dataSet[RMReportReaderGL.Keys.StartOffset]; dsGL.StartPeriodYearOffset = (short?)(int?)dataSet[RMReportReaderGL.Keys.StartYearOffset]; List <object[]> splitret = null; if (ds.Expand != ExpandType.Nothing) { splitret = new List <object[]>(); } if (ds.AmountType == null || ds.AmountType == 0) { return(0m); } PMEnsureInitialized(); EnsureHistoryLoaded(dsPM); NormalizeDataSource(dsPM); List <PMAccountGroup> accountGroups = _accountGroupsRangeCache.GetItemsInRange(dataSet[Keys.StartAccountGroup] as string, group => group.GroupCD, (group, code) => group.GroupCD = code); List <PMProject> projects = _projectsRangeCache.GetItemsInRange(dataSet[Keys.StartProject] as string, project => project.ContractCD, (project, code) => project.ContractCD = code); List <PMTask> tasks = _tasksRangeCache.GetItemsInRange(dataSet[Keys.StartProjectTask] as string, task => task.TaskCD, (task, code) => task.TaskCD = code); List <InventoryItem> items = _itemRangeCache.GetItemsInRange(dataSet[Keys.StartInventory] as string, item => item.InventoryCD, (item, code) => item.InventoryCD = code); if (ds.Expand == ExpandType.AccountGroup) { accountGroups.ForEach(a => splitret.Add(new object[] { a.GroupCD, a.Description, 0m, null, string.Empty })); } else if (ds.Expand == ExpandType.Project) { projects.ForEach(p => splitret.Add(new object[] { p.ContractCD, p.Description, 0m, null, string.Empty })); } else if (ds.Expand == ExpandType.ProjectTask) { //To avoid useless expansion, first restrict list of tasks to those tasks which point to current projects tasks = tasks.Where(t => projects.Any(p => t.ProjectID == p.ContractID)).ToList <PMTask>(); tasks = tasks.GroupBy(t => t.TaskCD).Select(g => new PMTask() { TaskCD = g.Key, TaskID = g.Min(t => t.TaskID), Description = g.Min(t => t.Description) }).ToList <PMTask>(); tasks.ForEach(pt => splitret.Add(new object[] { pt.TaskCD, pt.Description, 0m, null, string.Empty })); } else if (ds.Expand == ExpandType.Inventory) { items.ForEach(i => splitret.Add(new object[] { i.InventoryCD, i.Descr, 0m, null, string.Empty })); } return(CalculateAndExpandValue(drilldown, ds, dsGL, dsPM, dataSet, accountGroups, projects, tasks, items, splitret)); } else { return(del(dataSet, drilldown)); } }