/// <summary> /// Computes the sub-system budget results /// </summary> /// <param name="budgetConfig">The <see cref="BudgetConfig"/></param> /// <param name="element">The current <see cref="ElementDefinition"/> to compute the budget for</param> /// <param name="option">The current <see cref="Option"/></param> /// <param name="currentDomain">The current <see cref="DomainOfExpertise"/></param> /// <returns>The results</returns> public override IReadOnlyList <ISubSystemBudgetResult> ComputeResult(BudgetConfig budgetConfig, ElementDefinition element, Option option, DomainOfExpertise currentDomain) { var subSystems = new List <SubSystem>(); // identify sub-systems and equipments this.WalkProductTree(element, option, eu => this.FindSubSystem(eu, subSystems, budgetConfig)); this.WalkProductTree(element, option, eu => this.FindSubSystemEquipment(eu, subSystems, budgetConfig)); var ssResults = new List <ISubSystemBudgetResult>(); foreach (var subSystem in subSystems) { var ssResult = new SubSystemMassBudgetResult(subSystem, budgetConfig, option, currentDomain); ssResults.Add(ssResult); } var scales = ssResults.Select(x => x.Scale).Where(x => x != null).Distinct(); if (scales.Count() > 1) { throw new BudgetComputationException("Multiple scales in the different sub-system identified."); } return(ssResults); }
/// <summary> /// Initializes a new instance of the <see cref="MassBudgetSummaryViewModel"/> class /// </summary> /// <param name="budgetConfig">The <see cref="BudgetConfig"/></param> /// <param name="rootElement">The root <see cref="ElementDefinition"/></param> /// <param name="option">The current <see cref="Option"/></param> /// <param name="session">The <see cref="ISession"/></param> public MassBudgetSummaryViewModel(BudgetConfig budgetConfig, ElementDefinition rootElement, Option option, ISession session, Action refreshOptionOverview) : base(budgetConfig, rootElement, option, session, refreshOptionOverview) { this.WhenAnyValue(x => x.WetTotal).Subscribe(x => this.SummaryTotal = x); this.ExtraMassContributions = new ReactiveList <ExtraMassContributionRowViewModel>(); this.ComputeBudget(); this.ComputeTotal(); }
/// <summary> /// Initializes a new instance of the <see cref="SubSystemBudgetResult{T}"/> class /// </summary> /// <param name="subsystem">The corresponding <see cref="SubSystem"/></param> /// <param name="config">The <see cref="Config.BudgetConfig"/></param> /// <param name="option">The current <see cref="Option"/></param> /// <param name="domain">The current <see cref="DomainOfExpertise"/></param> protected SubSystemBudgetResult(SubSystem subsystem, BudgetConfig config, Option option, DomainOfExpertise domain) { this.SubSystem = subsystem; this.BudgetConfig = config; this.Option = option; this.CurrentDomain = domain; }
/// <summary> /// Setup that include test data /// </summary> public virtual void Setup() { this.session = new Mock <ISession>(); this.uri = new Uri("http://www.rheagroup.com"); this.cache = new ConcurrentDictionary <CacheKey, Lazy <Thing> >(); this.InitializeRefData(); this.domainOfExpertise = new DomainOfExpertise(Guid.NewGuid(), this.cache, this.uri) { ShortName = "SYS", Name = "System" }; this.iteration = new Iteration(Guid.NewGuid(), this.cache, this.uri); this.option_A = new Option(Guid.NewGuid(), this.cache, this.uri) { ShortName = "OPT_A", Name = "Option A" }; this.option_B = new Option(Guid.NewGuid(), this.cache, this.uri) { ShortName = "OPT_B", Name = "Option B" }; this.InitializeElementDef(); this.iteration.Option.Add(this.option_A); this.iteration.Option.Add(this.option_B); this.iteration.DefaultOption = this.option_A; this.iteration.Element.Add(this.rootEd); this.iteration.Element.Add(this.ssEd); this.iteration.TopElement = this.rootEd; var subSysdef = new SubSystemDefinition(new List <Category> { this.ssCat }, new List <Category> { this.eqtCat }); var extraConfig = new ExtraMassContributionConfiguration(new List <Category> { this.consCat }, this.mass, this.massMargin); var paramConfig = new MassBudgetParameterConfig(new BudgetParameterMarginPair(this.mass, this.massMargin), new List <ExtraMassContributionConfiguration> { extraConfig }); this.MassBudgetConfig = new BudgetConfig(new List <ElementDefinition> { this.rootEd }, new List <SubSystemDefinition> { subSysdef }, paramConfig, this.number, null, null, null); }
/// <summary> /// Computes the extra mass contributions /// </summary> /// <param name="budgetConfig">The current <see cref="BudgetConfig"/></param> /// <param name="element">The current <see cref="ElementDefinition"/> to compute the budget for</param> /// <param name="option">The current <see cref="Option"/></param> /// <param name="currentDomain">The current <see cref="DomainOfExpertise"/></param> /// <returns>The list of <see cref="ExtraContribution"/></returns> public IReadOnlyList <ExtraContribution> GetExtraMassContributions(BudgetConfig budgetConfig, ElementDefinition element, Option option, DomainOfExpertise currentDomain) { var config = (MassBudgetParameterConfig)budgetConfig.BudgetParameterConfig; var extraMassContributorUsages = new Dictionary <ExtraMassContributionConfiguration, List <ElementUsage> >(); foreach (var extraConfig in config.ExtraMassContributionConfigurations) { extraMassContributorUsages.Add(extraConfig, new List <ElementUsage>()); } this.WalkProductTree(element, option, eu => this.FindExtraMassContributors(eu, config, extraMassContributorUsages)); MeasurementScale scale = null; var results = new List <ExtraContribution>(); foreach (var extraMassContributorUsage in extraMassContributorUsages) { var total = 0f; var totalWithMargin = 0f; foreach (var elementUsage in extraMassContributorUsage.Value) { var floatValue = elementUsage.GetFloatActualValue(extraMassContributorUsage.Key.MassParameterType, null, option, currentDomain); var marginValue = extraMassContributorUsage.Key.MarginParameterType != null ? elementUsage.GetFloatActualValue(extraMassContributorUsage.Key.MarginParameterType, null, option, currentDomain) : 0f; var ptScale = elementUsage.GetScale(extraMassContributorUsage.Key.MassParameterType); if (scale == null && ptScale != null) { scale = ptScale; } else if (ptScale != null && scale.Iid != ptScale.Iid) { throw new BudgetComputationException($"Different scales used in the element-usage {elementUsage.Name}.{extraMassContributorUsage.Key.MassParameterType.ShortName}"); } if (floatValue.HasValue) { total += floatValue.Value; if (marginValue.HasValue) { totalWithMargin += floatValue.Value * (1 + marginValue.Value / 100f); } else { totalWithMargin += floatValue.Value; } } } results.Add(new ExtraContribution(extraMassContributorUsage.Key.ContributionCategories, total, totalWithMargin, extraMassContributorUsage.Key.MassParameterType, scale)); } return(results); }
/// <summary> /// Initializes a new instance of the <see cref="BudgetConfigViewModel"/> class /// </summary> /// <param name="iteration">The current iteration</param> /// <param name="currentConfig">An existing <see cref="BudgetConfig"/></param> public BudgetConfigViewModel(Iteration iteration, BudgetConfig currentConfig) { this.PopulateRdl(iteration); this.InitializeCommand(); if (currentConfig != null) { this.LoadExistingConfiguration(currentConfig); } }
/// <summary> /// Initializes a new instance of the <see cref="BudgetSummaryViewModel"/> class /// </summary> protected BudgetSummaryViewModel(BudgetConfig budgetConfig, ElementDefinition element, Option option, ISession session, Action refreshOptionOverview) { this.BudgetConfig = budgetConfig; this.Disposable = new List <IDisposable>(); this.SubSystemSummary = new ReactiveList <IBudgetRowViewModelBase>(); this.CurrentOption = option; this.Session = session; this.RootElement = element; this.WhenAnyValue(x => x.SystemMargin).Skip(1).Subscribe(_ => this.ComputeTotal()); this.WhenAnyValue(x => x.SummaryTotal).Skip(1).Subscribe(_ => refreshOptionOverview()); this.ElementName = this.RootElement.Name; }
/// <summary> /// Load the current <see cref="BudgetConfig"/> into the current view /// </summary> /// <param name="configuration">The existing configuration</param> private void LoadExistingConfiguration(BudgetConfig configuration) { this.SelectedElements = new ReactiveList <ElementDefinition>(this.PossibleElementDefinitions.Where(x => configuration.Elements != null && configuration.Elements.Any(y => y.Iid == x.Iid))); this.NumberOfElement = this.PossibleParameterTypes.SingleOrDefault(x => configuration.NumberOfElementParameterType != null && x.Iid == configuration.NumberOfElementParameterType.Iid); this.SystemLevel = this.PossibleSystemLevelParameterTypes.SingleOrDefault(x => configuration.SystemLevelToUse != null && x.Iid == configuration.SystemLevelToUse.Iid); this.SelectedSubSystemEnum = this.PossibleSystemLevelEnum != null && this.PossibleSystemLevelEnum.Count > 0 && configuration.SubSystemLevelEnum != null ? this.PossibleSystemLevelEnum.SingleOrDefault(x => x.Iid == configuration.SubSystemLevelEnum.Iid) : null; this.SelectedEquipmentEnum = this.PossibleSystemLevelEnum != null && this.PossibleSystemLevelEnum.Count > 0 && configuration.EquipmentLevelEnum != null ? this.PossibleSystemLevelEnum.SingleOrDefault(x => x.Iid == configuration.EquipmentLevelEnum.Iid) : null; var massBudgetConfig = configuration.BudgetParameterConfig as MassBudgetParameterConfig; if (massBudgetConfig != null) { this.SelectedBudgetKind = BudgetKind.Mass; var vm = new MassBudgetParameterConfigViewModel(this.PossibleParameterTypes, this.UpdateCanOk, this.usedCategories); vm.DryMassConfig.SelectedParameterType = this.PossibleParameterTypes.FirstOrDefault(x => x.Iid == massBudgetConfig.DryMassTuple.MainParameterType.Iid); vm.DryMassConfig.SelectedMarginParameterType = massBudgetConfig.DryMassTuple.MarginParameterType != null ? this.PossibleParameterTypes.FirstOrDefault(x => x.Iid == massBudgetConfig.DryMassTuple.MarginParameterType.Iid) : null; vm.AddExtraContributionFromExistingConf(massBudgetConfig.ExtraMassContributionConfigurations); this.BudgetParameterConfig = vm; } var genericBudgetConfig = configuration.BudgetParameterConfig as GenericBudgetParameterConfig; if (genericBudgetConfig != null) { this.SelectedBudgetKind = BudgetKind.Generic; var vm = new GenericBudgetParameterConfigViewModel(this.PossibleParameterTypes, this.UpdateCanOk); vm.GenericConfig.SelectedParameterType = this.PossibleParameterTypes.FirstOrDefault(x => x.Iid == genericBudgetConfig.GenericTuple.MainParameterType.Iid); vm.GenericConfig.SelectedMarginParameterType = genericBudgetConfig.GenericTuple.MarginParameterType != null ? this.PossibleParameterTypes.FirstOrDefault(x => x.Iid == genericBudgetConfig.GenericTuple.MarginParameterType.Iid) : null; this.BudgetParameterConfig = vm; } foreach (var subSystemDefinition in configuration.SubSystemDefinition) { var subsysrow = new SubSystemConfigViewModel(this.usedCategories, this.UpdateCanOk, vm => this.SubSystemDefinitions.Remove(vm)); subsysrow.SubSystemDefinitions.SelectedCategories = new ReactiveList <Category>(subsysrow.SubSystemDefinitions.PossibleCategories.Where(x => subSystemDefinition.Categories.Select(y => y.Iid).Contains(x.Iid))); subsysrow.SubSystemElementDefinition.SelectedCategories = new ReactiveList <Category>(subsysrow.SubSystemElementDefinition.PossibleCategories.Where(x => subSystemDefinition.ElementCategories.Select(y => y.Iid).Contains(x.Iid))); this.SubSystemDefinitions.Add(subsysrow); } }
/// <summary> /// Executes the <see cref="OkCommand"/> /// </summary> private void ExecuteOkCommand() { var subSysDefinitions = new List <SubSystemDefinition>(); foreach (var ssDef in this.SubSystemDefinitions) { var subSysCat = new SubSystemDefinition(ssDef.SubSystemDefinitions.SelectedCategories, ssDef.SubSystemElementDefinition.SelectedCategories); if (subSysDefinitions.Contains(subSysCat)) { continue; } subSysDefinitions.Add(subSysCat); } BudgetParameterConfigBase parameterConfig; switch (this.SelectedBudgetKind) { case BudgetKind.Mass: var massBudgetVm = (MassBudgetParameterConfigViewModel)this.BudgetParameterConfig; var drymassConfig = new BudgetParameterMarginPair(massBudgetVm.DryMassConfig.SelectedParameterType, massBudgetVm.DryMassConfig.SelectedMarginParameterType); var extraConf = new List <ExtraMassContributionConfiguration>(); foreach (var extraMassContributionConfigurationViewModel in massBudgetVm.ExtraMassContributions) { extraConf.Add(new ExtraMassContributionConfiguration(extraMassContributionConfigurationViewModel.SelectedCategories, extraMassContributionConfigurationViewModel.SelectedParameter, extraMassContributionConfigurationViewModel.SelectedMarginParameter)); } parameterConfig = new MassBudgetParameterConfig(drymassConfig, extraConf); break; case BudgetKind.Generic: var costBudgetVm = (GenericBudgetParameterConfigViewModel)this.BudgetParameterConfig; parameterConfig = new GenericBudgetParameterConfig(new BudgetParameterMarginPair(costBudgetVm.GenericConfig.SelectedParameterType, costBudgetVm.GenericConfig.SelectedMarginParameterType)); break; default: throw new NotImplementedException($"Case {this.SelectedBudgetKind} not implemented"); } var config = new BudgetConfig(this.SelectedElements, subSysDefinitions, parameterConfig, this.NumberOfElement, this.SystemLevel, this.SelectedSubSystemEnum, this.SelectedEquipmentEnum); this.DialogResult = new BudgetConfigDialogResult(true, config); }
/// <summary> /// Initializes a new instance of the <see cref="OptionBudgetViewModel"/> class /// </summary> /// <param name="option">The option</param> /// <param name="budgetConfig">The current <see cref="BudgetConfig"/></param> /// <param name="session">The current <see cref="ISession"/></param> public OptionBudgetViewModel(Option option, BudgetConfig budgetConfig, ISession session, Action refreshOptionOverview) { this.BudgetSummary = new ReactiveList <BudgetSummaryViewModel>(); this.Option = option; foreach (var budgetConfigElement in budgetConfig.Elements) { if (budgetConfig.BudgetParameterConfig is MassBudgetParameterConfig) { this.GroupTitle = $"{MASS_BUDGET_TITLE}: {option.Name}"; this.BudgetSummary.Add(new MassBudgetSummaryViewModel(budgetConfig, budgetConfigElement, option, session, refreshOptionOverview)); } else if (budgetConfig.BudgetParameterConfig is GenericBudgetParameterConfig) { this.GroupTitle = $"{GENERIC_BUDGET_TITLE}: {option.Name}"; this.BudgetSummary.Add(new GenericBudgetSummaryViewModel(budgetConfig, budgetConfigElement, option, session, refreshOptionOverview)); } else if (budgetConfig.BudgetParameterConfig is PowerBudgetParameterConfig) { this.GroupTitle = $"{POWER_BUDGET_TITLE}: {option.Name}"; } } }
/// <summary> /// Initializes a new instance of the <see cref="SubSystemGenericBudgetResult"/> class /// </summary> /// <param name="subsystem">The corresponding <see cref="SubSystem"/></param> /// <param name="config">The <see cref="BudgetConfig"/></param> /// <param name="option">The current <see cref="Option"/></param> /// <param name="domain">The current <see cref="DomainOfExpertise"/></param> public SubSystemGenericBudgetResult(SubSystem subsystem, BudgetConfig config, Option option, DomainOfExpertise domain) : base(subsystem, config, option, domain) { this.ComputeValuesFromSubSystem(); this.ComputeValuesFromEquipment(); }
/// <summary> /// Determines whether the <paramref name="usage"/> is a sub-system /// </summary> /// <param name="usage">The <see cref="ElementUsage"/></param> /// <param name="subSystemList">The list of sub-systems</param> /// <param name="config">The current <see cref="BudgetConfig"/></param> protected void FindSubSystem(ElementUsage usage, List <SubSystem> subSystemList, BudgetConfig config) { var associatedSubSystems = config.SubSystemDefinition.Where(x => x.IsThisSubSystem(usage)).ToList(); if (associatedSubSystems.Count > 1) { throw new BudgetComputationException($"multiple sub-system definitions match the element usage {usage.Name}."); } if (associatedSubSystems.Count == 1) { var associatedSubSystem = associatedSubSystems.Single(); var subSystem = new SubSystem(associatedSubSystem, usage); if (subSystemList.Any(x => x.SubSystemDefinition == associatedSubSystem)) { throw new BudgetComputationException("multiple same subsystems found."); } subSystemList.Add(subSystem); } }
/// <summary> /// Determines whether the <paramref name="usage"/> is a sub-system equipment /// </summary> /// <param name="usage">An <see cref="ElementUsage"/></param> /// <param name="subSystemList">The list of sub-systems</param> /// <param name="config">The current <see cref="BudgetConfig"/></param> protected void FindSubSystemEquipment(ElementUsage usage, List <SubSystem> subSystemList, BudgetConfig config) { var associatedSubSystems = subSystemList.Where(x => x.SubSystemDefinition.IsThisSubSystemEquipment(usage)).ToList(); if (associatedSubSystems.Count > 1) { throw new BudgetComputationException($"multiple sub-system definitions match the element usage {usage.Name}."); } if (associatedSubSystems.Count == 1) { var associatedSubSystem = associatedSubSystems.Single(); associatedSubSystem.AddEquipment(usage); } }
/// <summary> /// Initializes a new instance of the <see cref="GenericBudgetSummaryViewModel"/> class /// </summary> /// <param name="budgetConfig">The <see cref="BudgetConfig"/></param> /// <param name="rootElement">The root <see cref="ElementDefinition"/></param> /// <param name="option">The current <see cref="Option"/></param> /// <param name="session">The <see cref="ISession"/></param> public GenericBudgetSummaryViewModel(BudgetConfig budgetConfig, ElementDefinition rootElement, Option option, ISession session, Action refreshOptionOverview) : base(budgetConfig, rootElement, option, session, refreshOptionOverview) { this.ComputeBudget(); this.ComputeTotal(); this.WhenAnyValue(x => x.TotalWithSystemMargin).Subscribe(x => this.SummaryTotal = x); }
/// <summary> /// Initializes a new instance of the <see cref="SubSystemGenericOfTBudgetResult{T}"/> class /// </summary> /// <param name="subsystem">The corresponding <see cref="SubSystem"/></param> /// <param name="config">The <see cref="BudgetConfig"/></param> /// <param name="option">The current <see cref="Option"/></param> /// <param name="domain">The current <see cref="DomainOfExpertise"/></param> protected SubSystemGenericOfTBudgetResult(SubSystem subsystem, BudgetConfig config, Option option, DomainOfExpertise domain) : base(subsystem, config, option, domain) { }
/// <summary> /// Computes the sub-system budget results /// </summary> /// <param name="budgetConfig">The <see cref="BudgetConfig"/></param> /// <param name="element">The current <see cref="ElementDefinition"/> to compute the budget for</param> /// <param name="option">The current <see cref="Option"/></param> /// <param name="currentDomain">The current <see cref="DomainOfExpertise"/></param> /// <returns>The results</returns> public abstract IReadOnlyList <ISubSystemBudgetResult> ComputeResult(BudgetConfig budgetConfig, ElementDefinition element, Option option, DomainOfExpertise currentDomain);
/// <summary> /// Initializes a new instance of the <see cref="BudgetConfigDialogResult"/> class /// </summary> /// <param name="result">The result of the dialog operation</param> /// <param name="config">The resulting <see cref="BudgetConfig"/></param> public BudgetConfigDialogResult(bool result, BudgetConfig config) { this.Result = result; this.BudgetConfig = config; }