//run the analyes for everything else //descendentstock holds input and output stock totals and calculators public bool RunAnalyses(ME2Stock me2Stock, List <Calculator1> calcs) { bool bHasAnalyses = false; bHasAnalyses = SetAnalyses(me2Stock, calcs); return(bHasAnalyses); }
private static bool HasChangeMatchByLabel(string aggLabel, ME2Stock change, List <ME2Stock> changeStocks, string changeType) { bool bHasMatch = false; bool bStart = false; foreach (ME2Stock rp in changeStocks) { if (rp.ChangeType == changeType) { if (bStart) { if (aggLabel == change.Label) { bHasMatch = true; break; } } if (rp.Id == change.Id) { bStart = true; } } } return(bHasMatch); }
public bool SetBIGroupME2Calculations(ref XElement currentCalculationsElement, ref XElement currentElement) { bool bHasCalculations = false; //set the parent budget group for holding collection of budgets if (this.BudgetGroup == null) { this.BudgetGroup = new BudgetInvestmentGroup(); } this.BudgetGroup.SetBudgetInvestmentGroupProperties(this.GCCalculatorParams, currentCalculationsElement, currentElement); //easier to set multipliers with base els; copy into me2; subsequent CopyStockCalc handles automatically this.BudgetGroup.Multiplier = 1; //set this.ME2 props ME2Stock me2 = SetME2Properties(this.BudgetGroup, currentCalculationsElement, currentElement); //add the calculations to the base element if (this.BudgetGroup.Calculators == null) { this.BudgetGroup.Calculators = new List <Calculator1>(); } if (me2 != null) { this.BudgetGroup.Calculators.Add(me2); } bHasCalculations = true; //don't reset for next collection return(bHasCalculations); }
private static ME2Stock GetBaseChangeStockByLabel(ME2Stock actual, List <int> ids, List <ME2Stock> changeStocks, string changeType) { //won't get a true planned cumulative if the last actual can't find a matching planned //that's why benchmark planned must be displayed too ME2Stock plannedMatch = null; //make sure the aggLabel can be matched in planned sequence if (changeStocks.Any(p => p.Label == actual.Label && p.ChangeType == changeType)) { foreach (ME2Stock change in changeStocks) { if (change.ChangeType == changeType) { if (actual.Label == change.Label) { plannedMatch = change; //break the for loop break; } } } } return(plannedMatch); }
public bool SetOutputGroupME2Calculations(ref XElement currentCalculationsElement, ref XElement currentElement) { bool bHasCalculations = false; //set the parent budget group for holding collection of budgets if (this.OutputGroup == null) { this.OutputGroup = new OutputGroup(); } //this also sets the labels, groupid, and typeid for aggregation this.OutputGroup.SetOutputGroupProperties(this.GCCalculatorParams, currentCalculationsElement, currentElement); this.OutputGroup.Multiplier = 1; ME2Stock me2 = SetME2Properties(this.OutputGroup, currentCalculationsElement, currentElement); //add the calculations to the base element if (this.OutputGroup.Calculators == null) { this.OutputGroup.Calculators = new List <Calculator1>(); } if (me2 != null) { this.OutputGroup.Calculators.Add(me2); } if (this.OutputGroup.Outputs == null) { this.OutputGroup.Outputs = new List <Output>(); } bHasCalculations = true; //don't reset for next collection return(bHasCalculations); }
private static List <ME2Change1> GetXMinus1Changes(List <int> xMinus1Ids, ME2Stock me2Stock, ME2Stock observation) { List <ME2Change1> xminus1Totals = new List <ME2Change1>(); ME2Stock xminus1 = GetChangeStockByLabel(observation, xMinus1Ids, me2Stock.Stocks, Calculator1.CHANGE_TYPES.xminus1.ToString()); if (xminus1 != null) { if (xminus1.Total1 != null) { if (xminus1.Total1.Stocks != null) { //loop through the indicator label-aggregated totals foreach (ME2Total1 total in xminus1.Total1.Stocks) { //and fill in the base list ME2Change1 xminus1Change = new ME2Change1(observation.CalcParameters); xminus1Change.CopyTotalME2IndicatorStockProperties(xminus1Change, total); xminus1Totals.Add(xminus1Change); } } } } return(xminus1Totals); }
private static List <ME2Change1> GetBaseChanges(List <int> baseIds, ME2Stock me2Stock, ME2Stock observation) { List <ME2Change1> baseTotals = new List <ME2Change1>(); ME2Stock benchmark = GetChangeStockByLabel(observation, baseIds, me2Stock.Stocks, Calculator1.CHANGE_TYPES.baseline.ToString()); if (benchmark != null) { if (benchmark.Total1 != null) { if (benchmark.Total1.Stocks != null) { //loop through the indicator label-aggregated totals foreach (ME2Total1 total in benchmark.Total1.Stocks) { //and fill in the base list ME2Change1 baseChange = new ME2Change1(observation.CalcParameters); baseChange.CopyTotalME2IndicatorStockProperties(baseChange, total); baseTotals.Add(baseChange); } } } } return(baseTotals); }
public bool SetOutputSeriesME2Calculations(ref XElement currentCalculationsElement, ref XElement currentElement) { bool bHasCalculations = false; //set the parent opcomp for holding collection of mandECostOutputs if (this.Output == null) { this.Output = new Output(); } //this also sets the labels, groupid, and typeid for aggregation Output outputserie = new Output(); outputserie.SetOutputProperties(this.GCCalculatorParams, currentCalculationsElement, currentElement); outputserie.Multiplier = outputserie.Amount; ME2Stock me2 = SetME2Properties(outputserie, currentCalculationsElement, currentElement); //add the calculations to the base element if (outputserie.Calculators == null) { outputserie.Calculators = new List <Calculator1>(); } if (me2 != null) { outputserie.Calculators.Add(me2); } if (this.Output.Outputs == null) { this.Output.Outputs = new List <Output>(); } this.Output.Outputs.Add(outputserie); bHasCalculations = true; return(bHasCalculations); }
public static bool CopyandInitStockCalculator(Calculator1 calc, ME2Stock newStock) { bool bHasCopy = false; if (calc != null) { if (calc.GetType().Equals(newStock.GetType())) { ME2Stock oldStock = (ME2Stock)calc; if (oldStock != null) { //initiate analyzer objects newStock.InitTotalME2StocksProperties(); //but keep calc props newStock.CopyCalculatorProperties(oldStock); if (oldStock.CalcParameters != null) { newStock.CalcParameters = new CalculatorParameters(oldStock.CalcParameters); } bHasCopy = true; } } } return(bHasCopy); }
public bool SetTechOutputME2Calculations(ref XElement currentCalculationsElement, ref XElement currentElement) { bool bHasCalculations = false; //set the parent opcomp for holding collection of mandECostOutputs if (this.Outcome == null) { this.Outcome = new Outcome(); } //this also sets the labels, groupid, and typeid for aggregation this.Output = new Output(); this.Output.SetOutputProperties(this.GCCalculatorParams, currentCalculationsElement, currentElement); this.Output.Multiplier = this.Output.Amount * this.Output.Times * this.Output.CompositionAmount; ME2Stock me2 = SetME2Properties(this.Output, currentCalculationsElement, currentElement); //add the calculations to the base element if (this.Output.Calculators == null) { this.Output.Calculators = new List <Calculator1>(); } if (me2 != null) { this.Output.Calculators.Add(me2); } //add to collection if (this.Outcome.Outputs == null) { this.Outcome.Outputs = new List <Output>(); } this.Outcome.Outputs.Add(this.Output); bHasCalculations = true; return(bHasCalculations); }
private bool SetAnalyses(ME2Stock me2Stock) { bool bHasTotals = false; if (me2Stock.Stocks != null) { bHasTotals = SetChangesAnalysis(me2Stock); } return(bHasTotals); }
private void SetIds(Calculator1 baseElement, ME2Stock stock) { SetCalculatorId(baseElement, stock); //alt2 is stored with the base element for some elements (ocs and outcomes, tps) if (baseElement.Alternative2 != 0) { //the CalculatorId is used to set the Id (Id is the base element_ stock.Alternative2 = baseElement.Alternative2; } }
private void SetCalculatorId(Calculator1 baseElement, ME2Stock stock) { //the initial collections don't store initial stock calculators //related calculator.Id are stored with the base element if (baseElement.CalculatorId != 0) { //the CalculatorId is used to set the Id (Id is the base element_ stock.CalculatorId = baseElement.CalculatorId; stock.Id = baseElement.CalculatorId; } }
public static bool CopyStockCalculator(ME2Stock oldStock, ME2Stock newStock) { bool bHasCopy = false; if (oldStock != null && newStock != null) { //the copy will also copy calcprops and calcparams for newstock and newstock.Stocks newStock.CopyTotalME2StocksProperties(oldStock); bHasCopy = true; } return(bHasCopy); }
//run the analyses for inputs an outputs public bool RunAnalyses(ME2Stock me2Stock) { bool bHasAnalyses = false; //add totals to me2stock.Total1 if (me2Stock.Total1 == null) { return(bHasAnalyses); } //add totals to me stocks ( bHasAnalyses = me2Stock.Total1.SetTotals(me2Stock.Total1); return(bHasAnalyses); }
public virtual void CopyME2CalculatorToME2Stock(ME2Calculator calculator) { //analyzers hold all calcs and analyses if (this.Total1 == null) { this.Total1 = new ME2Total1(this.CalcParameters); } if (this.Stat1 == null) { this.Stat1 = new ME2Stat1(this.CalcParameters); } if (this.Change1 == null) { this.Change1 = new ME2Change1(this.CalcParameters); } if (this.Progress1 == null) { this.Progress1 = new ME2Progress1(this.CalcParameters); } //need to organize stocks by observations this.Stocks = new List <ME2Stock>(); //MEStock uses this.AnalyzerType for most calcs calculator.AnalyzerType = this.AnalyzerType; this.CopyCalculatorProperties(calculator); ME2Stock stock = new ME2Stock(this.CalcParameters); //this copies the ME2Calc.Indicators to the analyzer if (this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.mestat1.ToString()) { stock.Stat1 = new ME2Stat1(this.CalcParameters); stock.Stat1.CopyME2Properties(calculator); } else if (this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.mechangeyr.ToString() || this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.mechangeid.ToString() || this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.mechangealt.ToString()) { stock.Change1 = new ME2Change1(this.CalcParameters); stock.Change1.CopyME2Properties(calculator); } else if (this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.meprogress1.ToString()) { stock.Progress1 = new ME2Progress1(this.CalcParameters); stock.Progress1.CopyME2Properties(calculator); } else { stock.Total1 = new ME2Total1(this.CalcParameters); stock.Total1.CopyME2Properties(calculator); } this.Stocks.Add(stock); }
private List <Calculator1> SetTotals(ME2Stock me2Stock, List <Calculator1> calcs) { //build a list of initial totals that can be used to runtotals List <Calculator1> stocks = new List <Calculator1>(); foreach (Calculator1 calc in calcs) { if (calc.GetType().Equals(me2Stock.GetType())) { ME2Stock stock = (ME2Stock)calc; if (stock != null) { //this initial calculator results are placed in this object if (stock.Stocks != null) { List <ME2Stock> obsStocks = new List <ME2Stock>(); foreach (ME2Stock obsStock in stock.Stocks) { //id comes from original calc obsStock.CopyCalculatorProperties(stock); if (obsStock.Stat1 != null) { obsStock.Total1 = new ME2Total1(this.CalcParameters); if (obsStock.Stat1.ME2Indicators != null) { if (obsStock.Stat1.ME2Indicators.Count > 0) { obsStock.Total1.CopyME2IndicatorsProperties(obsStock.Stat1); //id comes from original calc obsStock.Total1.CopyCalculatorProperties(stock); //clear the initial indicators obsStock.Stat1.ME2Indicators = new List <ME2Indicator>(); obsStocks.Add(obsStock); } } } } //reset stock.Storks stock.Stocks = new List <ME2Stock>(); foreach (ME2Stock ostock in obsStocks) { stock.Stocks.Add(ostock); } stocks.Add(stock); } } } } return(stocks); }
private static bool SetBudgetChanges(ME2Stock me2Stock) { bool bHasChanges = false; //replace list of totalstocks with list of changestocks List <ME2Stock> obsStocks = new List <ME2Stock>(); List <int> baseIds = new List <int>(); List <int> xMinus1Ids = new List <int>(); int i = 0; foreach (ME2Stock observation in me2Stock.Stocks) { //actual totals are contained in observation.Total1.Stocks (and Stocks are Total1s) if (observation.Total1 != null && observation.ChangeType == CHANGE_TYPES.current.ToString()) { //unlike totals, obsstock needs obs.CopyCalcs so it matches with baseelement ME2Stock observationStock = new ME2Stock(observation.CalcParameters, me2Stock.CalcParameters.AnalyzerParms.AnalyzerType); //need the base el id observationStock.CopyCalculatorProperties(observation); //where the stats go observationStock.Change1 = new ME2Change1(observation.CalcParameters); observationStock.Change1.CalcParameters = new CalculatorParameters(me2Stock.CalcParameters); observationStock.Change1.CopyCalculatorProperties(observation); foreach (ME2Total1 total in observation.Total1.Stocks) { //add to observationStock for potential Ancestor calcs use observationStock.Change1.InitTotalME2Change1Properties(observationStock.Change1); observationStock.Change1.CopyTotalME2IndicatorStockProperties(observationStock.Change1, total); } //each of the stocks is a unique label-dependent total observationStock.Change1.Stocks = new List <ME2Stock>(); //lists needed to store label-aggregated indicators (a1010, a1011) for each observation List <ME2Change1> baseTotals = GetBaseChanges(baseIds, me2Stock, observation); List <ME2Change1> xminus1Totals = GetXMinus1Changes(xMinus1Ids, me2Stock, observation); AddChangesToStock(i, observation, observationStock, baseTotals, xminus1Totals); obsStocks.Add(observationStock); i++; } } if (obsStocks.Count > 0) { //replace the totalstocks with change stocks me2Stock.Stocks = obsStocks; bHasChanges = true; } return(bHasChanges); }
public static void CopyStockCalculator(List <Calculator1> calcs, ME2Stock newStock) { if (calcs != null) { foreach (Calculator1 calc in calcs) { bool bHasCopy = CopyStockCalculator(calc, newStock); if (bHasCopy) { break; } } } }
//calcs holds the collections needing statistical analysis public bool RunAnalyses(ME2Stock me2Stock, List <Calculator1> calcs) { bool bHasAnalyses = false; //convert calcs to totals List <Calculator1> totals = SetTotals(me2Stock, calcs); //run calcs and set up me2Stock.Stocks collection bool bHasTotals = me2Stock.Total1.RunAnalyses(me2Stock, totals); //run a statistical analysis //the alternative2 aggregator was already used in Total1, don't use it again if (bHasTotals) { bHasAnalyses = SetAnalyses(me2Stock); } return(bHasAnalyses); }
public virtual void InitTotalME2StocksProperties() { if (this.Total1 == null) { this.Total1 = new ME2Total1(this.CalcParameters); } if (this.Stat1 == null) { this.Stat1 = new ME2Stat1(this.CalcParameters); } if (this.Change1 == null) { this.Change1 = new ME2Change1(this.CalcParameters); } if (this.Progress1 == null) { this.Progress1 = new ME2Progress1(this.CalcParameters); } //need to organize stocks by observations this.Stocks = new List <ME2Stock>(); ME2Stock stock = new ME2Stock(this.CalcParameters); if (this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.mestat1.ToString()) { stock.Stat1 = new ME2Stat1(this.CalcParameters); stock.Stat1.InitTotalME2Stat1Properties(stock.Stat1); } else if (this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.mechangeyr.ToString() || this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.mechangeid.ToString() || this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.mechangealt.ToString()) { stock.Change1 = new ME2Change1(this.CalcParameters); stock.Change1.InitTotalME2Change1Properties(stock.Change1); } else if (this.AnalyzerType == ME2AnalyzerHelper.ANALYZER_TYPES.meprogress1.ToString()) { stock.Progress1 = new ME2Progress1(this.CalcParameters); stock.Progress1.InitTotalME2Progress1Properties(stock.Progress1); } else { //default are total indicators stock.Total1 = new ME2Total1(this.CalcParameters); stock.Total1.InitTotalME2Total1Properties(stock.Total1); } this.Stocks.Add(stock); }
public bool SetTechInputME2Calculations(ref XElement currentCalculationsElement, ref XElement currentElement) { bool bHasCalculations = false; //set the parent opcomp for holding collection of mandECostInputs if (this.OpComp == null) { this.OpComp = new OperationComponent(); } //this also sets the labels, groupid, and typeid for aggregation this.Input = new Input(); this.Input.SetInputProperties(this.GCCalculatorParams, currentCalculationsElement, currentElement); if (this.GCCalculatorParams.SubApplicationType == Constants.SUBAPPLICATION_TYPES.investments || this.GCCalculatorParams.SubApplicationType == Constants.SUBAPPLICATION_TYPES.componentprices) { this.Input.Multiplier = this.Input.CAPAmount * this.Input.Times; } else { this.Input.Multiplier = this.Input.OCAmount * this.Input.Times; } ME2Stock me2 = SetME2Properties(this.Input, currentCalculationsElement, currentElement); //add the calculations to the base element if (this.Input.Calculators == null) { this.Input.Calculators = new List <Calculator1>(); } if (me2 != null) { this.Input.Calculators.Add(me2); } //add to collection if (this.OpComp.Inputs == null) { this.OpComp.Inputs = new List <Input>(); } this.OpComp.Inputs.Add(this.Input); bHasCalculations = true; return(bHasCalculations); }
public static bool CopyStockCalculator(Calculator1 calc, ME2Stock newStock) { bool bHasCopy = false; if (calc != null) { if (calc.GetType().Equals(newStock.GetType())) { ME2Stock oldStock = (ME2Stock)calc; if (oldStock != null) { //only one me2stock is initialized in object model bHasCopy = CopyStockCalculator(oldStock, newStock); } } } return(bHasCopy); }
private static ME2Stock GetChangeStockByLabel(ME2Stock actual, List <int> ids, List <ME2Stock> changeStocks, string changeType) { //won't get a true planned cumulative if the last actual can't find a matching planned //that's why benchmark planned must be displayed too ME2Stock plannedMatch = null; //make sure the aggLabel can be matched in planned sequence if (changeStocks.Any(p => p.Label == actual.Label && p.ChangeType == changeType)) { int iIndex = 1; foreach (ME2Stock change in changeStocks) { if (change.ChangeType == changeType) { if (actual.Label == change.Label) { //make sure it hasn't already been used (2 or more els with same Labels) if (!ids.Any(i => i == iIndex)) { plannedMatch = change; //index based check is ok ids.Add(iIndex); //break the for loop break; } else { //break if no remaining planned has same label bool bHasMatch = HasChangeMatchByLabel(actual.Label, change, changeStocks, changeType); if (!bHasMatch) { break; } } } } iIndex++; } } return(plannedMatch); }
public bool SetTimePeriodME2Calculations(ref XElement currentCalculationsElement, ref XElement currentElement) { bool bHasCalculations = false; //set the parent budget for holding collection of timeperiods if (this.Budget == null) { this.Budget = new BudgetInvestment(); } if (this.TimePeriod == null) { this.TimePeriod = new TimePeriod(); } //this also sets the labels, groupid, and typeid for aggregation this.TimePeriod.SetTimePeriodProperties(this.GCCalculatorParams, currentCalculationsElement, currentElement); this.TimePeriod.Multiplier = this.TimePeriod.Amount; ME2Stock me2 = SetME2Properties(this.TimePeriod, currentCalculationsElement, currentElement); //add the calculations to the base element if (this.TimePeriod.Calculators == null) { this.TimePeriod.Calculators = new List <Calculator1>(); } if (me2 != null) { this.TimePeriod.Calculators.Add(me2); } //add to collection if (this.Budget.TimePeriods == null) { this.Budget.TimePeriods = new List <TimePeriod>(); } //calculators start with inputs and outputs AddNewTPToCollection(this.TimePeriod, this.Budget.TimePeriods); //if startingnode is a tp, won't have a good starting budgetgroup //(stops running calcs at tp level) AddNewBudgetToTP(); //reset for next collection this.TimePeriod = null; bHasCalculations = true; return(bHasCalculations); }
public bool SetBIME2Calculations(ref XElement currentCalculationsElement, ref XElement currentElement) { //miscellaneous aggregations (i.e. inputgroup, operationgroug) bool bHasCalculations = false; //set the parent budget group for holding collection of budgets if (this.BudgetGroup == null) { this.BudgetGroup = new BudgetInvestmentGroup(); } if (this.Budget == null) { this.Budget = new BudgetInvestment(); } //this also sets the labels, groupid, and typeid for aggregation this.Budget.SetBudgetInvestmentProperties(this.GCCalculatorParams, currentCalculationsElement, currentElement); this.Budget.Multiplier = 1; ME2Stock me2 = SetME2Properties(this.Budget, currentCalculationsElement, currentElement); //add the calculations to the base element if (this.Budget.Calculators == null) { this.Budget.Calculators = new List <Calculator1>(); } if (me2 != null) { this.Budget.Calculators.Add(me2); } if (this.BudgetGroup.BudgetInvestments == null) { this.BudgetGroup.BudgetInvestments = new List <BudgetInvestment>(); } //calculators start with inputs and outputs //don't use byref collections (or this.Budget = null will set byref members to null) AddNewBudgetToCollection(this.Budget, this.BudgetGroup.BudgetInvestments); //reset for next collection this.Budget = null; bHasCalculations = true; return(bHasCalculations); }
public static void CopyStockCalculator(CalculatorParameters calcParams, List <Calculator1> oldcalcs, List <Calculator1> newcalcs) { if (oldcalcs != null) { if (newcalcs == null) { newcalcs = new List <Calculator1>(); } foreach (Calculator1 calc in oldcalcs) { //don't init newstock with this.GCCalcParam, use the oldcalc.CalcParams ME2Stock newStock = new ME2Stock(calcParams); bool bHasCopy = CopyStockCalculator(calc, newStock); if (bHasCopy) { newcalcs.Add(newStock); } } } }
public bool SetOutputME2Calculations(ref XElement currentCalculationsElement, ref XElement currentElement) { bool bHasCalculations = false; //set the parent opcomp for holding collection of mandECostOutputs if (this.OutputGroup == null) { this.OutputGroup = new OutputGroup(); } //might have inputseries if (this.Output == null) { this.Output = new Output(); } //this also sets the labels, groupid, and typeid for aggregation this.Output.SetOutputProperties(this.GCCalculatorParams, currentCalculationsElement, currentElement); this.Output.Multiplier = this.Output.Amount; ME2Stock me2 = SetME2Properties(this.Output, currentCalculationsElement, currentElement); //add the calculations to the base element if (this.Output.Calculators == null) { this.Output.Calculators = new List <Calculator1>(); } if (me2 != null) { this.Output.Calculators.Add(me2); } if (this.OutputGroup.Outputs == null) { this.OutputGroup.Outputs = new List <Output>(); } AddNewOutput(this.OutputGroup, this.Output); bHasCalculations = true; //reset for next series collection this.Output = null; return(bHasCalculations); }
public static ME2Stock GetNewME2Stock(CalculatorParameters calcParams, Calculator1 baseElement, List <Calculator1> calcs, ME2Stock descendant) { ME2Stock newStock = new ME2Stock(calcParams, calcParams.AnalyzerParms.AnalyzerType); if (calcs == null) { calcs = new List <Calculator1>(); } if (calcs.Count > 0) { ME2AnalyzerHelper.CopyandInitStockCalculator(calcs .FirstOrDefault(), newStock); } else { //need the options newStock.CopyCalculatorProperties(descendant); } BIME2StockAnalyzer.CopyBaseElementProperties(baseElement, newStock); return(newStock); }
private bool SetChangesAnalysis(ME2Stock me2Stock) { bool bHasTotalChanges = false; if (me2Stock.Stocks != null) { //set the total observations total bool bHasCurrents = me2Stock.Stocks .Any(c => c.ChangeType == Calculator1.CHANGE_TYPES.current.ToString()); //if any changestock has this property, it's trying to compare antecedents, rather than siblings if (bHasCurrents) { //budgets uses antecendent, rather than sibling, comparators bHasTotalChanges = SetBudgetChanges(me2Stock); } else { //set change numbers bHasTotalChanges = SetChanges(me2Stock); } } return(bHasTotalChanges); }