/// <summary> /// Retrieves GridVm from DB and builds the full model, including calculations and template rows. If there are any cells from other grids that this grid is dependent upon (e.g. calcs that /// have operands from other grids) then additional, partially formed, GridVm's will be created for just those external dependent cells. /// </summary> /// <param name="gridCode">The GridCode the be built from the DB.</param> /// <param name="exhibit">OPTIONAL: The ExhibitVm that the GridVm (along with any other partially formed dependent gridvm's) will be added to. If null, a new ExhibitVm is instantiated.</param> /// <returns></returns> public static ExhibitVm GetGridVmForUi(string gridCode, ExhibitVm exhibit = null) { if (exhibit == null) { exhibit = InitializeNewExhibit(); } var grid = InitializeNewGrid(gridCode, true); //Make sure any pre existing or partially formed grids are removed with this grid code exhibit.Grids.RemoveAll(g => g.GridCode == gridCode); exhibit.Grids.Add(grid); try { using (var db = new DEV_AF()) { //Make calls to DB for Calcs, Attributes, and Row Relationships, and various parms var calcs = db.UspGetCalcs(gridCode).ToList(); var rowRelations = db.UspGetRowRelationship(gridCode, null).ToList(); var attribs = db.UspGetAttribVal(gridCode, "").ToList(); var showNegativeInParen = false; var negativeParm = db.LOAD_PARAMETERS.FirstOrDefault(p => p.parm_name == "ShowNegativeInParensInUI"); if (negativeParm != null) { showNegativeInParen = negativeParm.parm_value == "Y"; } grid.ShowNegativeNumsInParens = showNegativeInParen; //Initalize calc objects List<UspGetCalcs_Result> rowCalcResults = new List<UspGetCalcs_Result>(); List<UspGetCalcs_Result> cellCalcsExpandedFromRowCalcs = new List<UspGetCalcs_Result>(); List<UspGetCalcs_Result> colCalcResults = new List<UspGetCalcs_Result>(); List<UspGetCalcs_Result> cellCalcsExpandedFromColCalcs = new List<UspGetCalcs_Result>(); List<UspGetCalcs_Result> cellCalcResults = new List<UspGetCalcs_Result>(); //Initalize model for storing cells outside the current grid var externalDependantCells = new List<CellVm>(); //Sort Calcs into RowCalcs, ColCalcs, and Cell Calcs. Also identify any Cells that the calcs are dependent upon that are outside of this grid foreach (var calc in calcs) { if (string.IsNullOrEmpty(calc.TargetColCode) && calc.TargetGridCode == grid.GridCode) { rowCalcResults.Add(calc); } else if (string.IsNullOrEmpty(calc.TargetRowCode) && calc.TargetGridCode == grid.GridCode) { colCalcResults.Add(calc); } else { cellCalcResults.Add(calc); //identify external cells if (calc.TargetGridCode != grid.GridCode && !externalDependantCells.Any(externalCell => CellIsTargetOfCalc(externalCell, calc))) { externalDependantCells.Add(new CellVm() { GridCode = calc.TargetGridCode, RowCode = calc.TargetRowCode, ColCode = calc.TargetColCode }); } //Both target and operand may be external if (calc.GridCode != grid.GridCode && !externalDependantCells.Any(externalCell => CellIsOperandOfCalc(externalCell, calc))) { externalDependantCells.Add(new CellVm() { GridCode = calc.GridCode, RowCode = calc.RowCode, ColCode = calc.ColCode }); } } } //ColCalcs will need to be expanded in UI when a user adds a row, save the unexpanded col calcs in the grid Vm grid.ColCalcs.AddRange(GroupCalcResultsIntoExpressionVm(colCalcResults)); //Cell calcs do not need to be expanded, group the cellCalcResults into a collection of CalcExpressionVm var calcExpressions = new List<CalcExpressionVm>(); calcExpressions.AddRange(GroupCalcResultsIntoExpressionVm(cellCalcResults)); var templateRowCodes = new List<string>(); var templateRowRelations = rowRelations.Where(IsAddRowTemplateRelationContext).ToList(); if (templateRowRelations.Any()) { templateRowCodes = templateRowRelations.Select(tr => tr.ChRowCode).ToList(); } var cellDictionary = new Dictionary<string, Attributes>(); var templateRowVms = new List<RowVm>(); foreach (var attrib in attribs) { if (!string.IsNullOrEmpty(attrib.RowCode) && !string.IsNullOrEmpty(attrib.ColCode)) { cellDictionary.Add(attrib.GridCode + attrib.RowCode + attrib.ColCode, attrib); } else if (string.IsNullOrEmpty(attrib.RowCode) && !string.IsNullOrEmpty(attrib.ColCode)) { grid.Columns.Add(BuildColVmFromAttributes(attrib)); //For Numeric columns expand the row calcs for every column and add to cell calcs if (IsNumericOrPercentType(attrib.Type)) cellCalcsExpandedFromRowCalcs.AddRange( rowCalcResults.Select(rowCalc => new UspGetCalcs_Result() { CalcExpressionId = rowCalc.CalcExpressionId, TargetGridCode = rowCalc.TargetGridCode, TargetRowCode = rowCalc.TargetRowCode, TargetColCode = attrib.ColCode, UpdateContext = rowCalc.UpdateContext, Expression = rowCalc.Expression.Split('.') .Aggregate( (c, n) => n == "" ? c + "." + attrib.ColCode + n : c + "." + n), GridCode = rowCalc.GridCode, RowCode = rowCalc.RowCode, ColCode = attrib.ColCode }) .Where(rowCalc => !cellCalcResults.Any(cellCalc => CalcsHaveMatchingTargets(cellCalc, rowCalc) && CalcUpdatesCellValue(cellCalc)))); } else if (!string.IsNullOrEmpty(attrib.RowCode) && string.IsNullOrEmpty(attrib.ColCode)) { var row = BuildRowVmFromAttributes(attrib, rowRelations); var isTemplateRow = String.Equals(attrib.OutType, Literals.Attribute.OutType.Model, StringComparison.CurrentCultureIgnoreCase) ; if (isTemplateRow) { templateRowVms.Add(row); } else { grid.Rows.Add(row); } SetGridAttribsFromRowAttribs(grid, attrib); if (attrib.Type == Literals.Attribute.RowType.Header || attrib.Type == Literals.Attribute.RowType.Blank || isTemplateRow) continue; cellCalcsExpandedFromColCalcs.AddRange( colCalcResults.Select(colCalc => new UspGetCalcs_Result() { CalcExpressionId = colCalc.CalcExpressionId, TargetGridCode = colCalc.TargetGridCode, TargetRowCode = attrib.RowCode, TargetColCode = colCalc.TargetColCode, UpdateContext = colCalc.UpdateContext, Expression = colCalc.Expression.Split('.').Aggregate((c, n) => n == "" ? c + "." + attrib.RowCode + n : c + "." + n), GridCode = colCalc.GridCode, RowCode = attrib.RowCode, ColCode = colCalc.ColCode }) .Where(colCalc => !cellCalcResults.Any(cellCalc => CalcsHaveMatchingTargets(cellCalc, colCalc) && CalcUpdatesCellValue(cellCalc))) ); } else { //grid.IsEditable = attrib.IsEditable ?? true; TODO - add this back in later //grid.DisplayText = attrib.DisplayText; } } var colCalcExpressions = new List<CalcExpressionVm>(); colCalcExpressions.AddRange(GroupCalcResultsIntoExpressionVm(cellCalcsExpandedFromColCalcs)); var rowCalcExpressions = new List<CalcExpressionVm>(); rowCalcExpressions.AddRange(GroupCalcResultsIntoExpressionVm(cellCalcsExpandedFromRowCalcs)); var allExpandedCalcs = new List<UspGetCalcs_Result>(); allExpandedCalcs.AddRange(cellCalcResults); allExpandedCalcs.AddRange(cellCalcsExpandedFromRowCalcs); allExpandedCalcs.AddRange(cellCalcsExpandedFromColCalcs); //Convert all calcs into dictionaries for easy lookup when building individual cells var cellCalcDic = ConvertCalcsToDictionary(calcExpressions); var colCalcDic = ConvertCalcsToDictionary(colCalcExpressions); var rowCalcDic = ConvertCalcsToDictionary(rowCalcExpressions); if (externalDependantCells.Any()) { GetExternalCells(exhibit, externalDependantCells, db, allExpandedCalcs, cellCalcDic, colCalcDic, rowCalcDic); } //remove expanded row and col calcs that target the same cell as a cell calc //colCalcDic = colCalcDic.Where(cc => !cellCalcDic.Keys.Contains(cc.Key)).ToDictionary(source => source.Key, source => source.Value); //rowCalcDic = rowCalcDic.Where(cc => !cellCalcDic.Keys.Contains(cc.Key)).ToDictionary(source => source.Key, source => source.Value); //Add Template Rows foreach (var templateRow in templateRowVms) { foreach (var col in grid.Columns.Where(c => c.Level == 0).OrderBy(c => c.DisplayOrder)) { var cellAttrib = cellDictionary[grid.GridCode + templateRow.RowCode + col.ColCode]; var cell = BuildCellVmFromAttributes(grid, templateRow, col, cellAttrib); templateRow.Cells.Add(cell); } AppendTemplateRowstoRowVm(templateRow, templateRowVms, templateRowRelations); } foreach (var row in grid.Rows) { foreach (var col in grid.Columns.Where(c => c.Level == 0).OrderBy(c => c.DisplayOrder)) { var cellAttrib = cellDictionary[grid.GridCode + row.RowCode + col.ColCode]; var cell = BuildCellVmFromAttributes(grid, row, col, cellAttrib); cell.Calcs = IsNumericOrPercentType(col.Type) ? GetCalcsForCell(allExpandedCalcs, cellCalcDic, colCalcDic, rowCalcDic, grid.GridCode, row.RowCode, col.ColCode) : null; row.Cells.Add(cell); col.Cells.Add(cell); } AppendTemplateRowstoRowVm(row, templateRowVms, templateRowRelations); } } } catch (Exception e) { var x = e; } return exhibit; }
/// <summary> /// Retrieves GridVm from DB and builds a partial model, excluding calculations and template rows. If there are any cells from other grids that this grid is dependent upon (e.g. calcs that /// have operands from other grids) then additional, partially formed, GridVm's will be created for just those external dependent cells. /// </summary> /// <param name="gridCode"></param> /// <returns></returns> public static ExhibitVm GetGridVmForMidtierCalcs(string gridCode) { var exhibit = InitializeNewExhibit(); var grid = InitializeNewGrid(gridCode, true); //Make sure any pre existing or partially formed grids are removed with this grid code exhibit.Grids.RemoveAll(g => g.GridCode == gridCode); exhibit.Grids.Add(grid); try { using (var db = new DEV_AF()) { var attribs = db.UspGetAttribVal(gridCode, "").ToList(); var rowRelations = db.UspGetRowRelationship(gridCode, null).ToList(); var templateRowCodes = new List<string>(); var templateRowRelations = rowRelations.Where(IsAddRowTemplateRelationContext).ToList(); if (templateRowRelations.Any()) { templateRowCodes = templateRowRelations.Select(tr => tr.ChRowCode).ToList(); } var cellDictionary = new Dictionary<string, Attributes>(); foreach (var attrib in attribs) { if (!string.IsNullOrEmpty(attrib.RowCode) && !string.IsNullOrEmpty(attrib.ColCode)) { cellDictionary.Add(attrib.GridCode + attrib.RowCode + attrib.ColCode, attrib); } else if (string.IsNullOrEmpty(attrib.RowCode) && !string.IsNullOrEmpty(attrib.ColCode)) { grid.Columns.Add(BuildColVmFromAttributes(attrib)); } else if (!string.IsNullOrEmpty(attrib.RowCode) && string.IsNullOrEmpty(attrib.ColCode)) { SetGridAttribsFromRowAttribs(grid, attrib); var row = BuildRowVmFromAttributes(attrib, rowRelations); var isTemplateRow = templateRowCodes.Contains(row.RowCode); if (!isTemplateRow) { grid.Rows.Add(row); } } else { //grid.IsEditable = attrib.IsEditable ?? true; TODO - add this back in later //grid.DisplayText = attrib.DisplayText; } } foreach (var row in grid.Rows) { foreach (var col in grid.Columns.Where(c => c.Level == 0).OrderBy(c => c.DisplayOrder)) { var cellAttrib = cellDictionary[grid.GridCode + row.RowCode + col.ColCode]; var cell = BuildCellVmFromAttributes(grid, row, col, cellAttrib); row.Cells.Add(cell); col.Cells.Add(cell); } } } }catch (Exception e) { } return exhibit; }