diff options
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs')
| -rw-r--r-- | Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs | 420 |
1 files changed, 320 insertions, 100 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs index ee21b9ac3..cadd1fb95 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs @@ -21,12 +21,19 @@ using Tango.MachineStudio.RML.Views; using Tango.PMR.ColorLab; using System.Data.Entity; using Tango.Core.ExtensionMethods; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.ActionLogs; +using Tango.BL.DTO; +using Tango.BL.Enumerations; namespace Tango.MachineStudio.RML.ViewModels { public class MainViewVM : StudioViewModel<IMainView> { private INotificationProvider _notification; + private IAuthenticationProvider _authentication; + private IActionLogManager _actionLogManager; + private RmlDTO _rmlBeforeSave; private ObservablesContext _rmls_context; private ObservablesContext _active_context; @@ -38,6 +45,20 @@ namespace Tango.MachineStudio.RML.ViewModels set { _rmls = value; RaisePropertyChangedAuto(); } } + private ICollectionView _rmlssCollectionView; + /// <summary> + /// Gets or sets the RML collection view. + /// </summary> + public ICollectionView RmlsCollectionView + { + get { return _rmlssCollectionView; } + set + { + _rmlssCollectionView = value; + RaisePropertyChangedAuto(); + } + } + private ObservableCollection<MediaMaterial> _materials; public ObservableCollection<MediaMaterial> Materials { @@ -80,6 +101,13 @@ namespace Tango.MachineStudio.RML.ViewModels set { _fiberSynths = value; RaisePropertyChangedAuto(); } } + private ObservableCollection<SpoolType> _spoolTypes; + public ObservableCollection<SpoolType> SpoolTypes + { + get { return _spoolTypes; } + set { _spoolTypes = value; RaisePropertyChangedAuto(); } + } + private Rml _selectedRML; public Rml SelectedRML { @@ -143,6 +171,30 @@ namespace Tango.MachineStudio.RML.ViewModels set { _colorConversionViewVM = value; RaisePropertyChangedAuto(); } } + private RmlsSpool _selectedSpool; + public RmlsSpool SelectedSpool + { + get { return _selectedSpool; } + set { _selectedSpool = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private ColorCalibrationViewVM _colorCalibrationVM; + public ColorCalibrationViewVM ColorCalibrationVM + { + get { return _colorCalibrationVM; } + set { _colorCalibrationVM = value; RaisePropertyChangedAuto(); } + } + + private String _RMLFilter; + /// <summary> + /// Gets or sets the job filter. + /// </summary> + public String RMLFilter + { + get { return _RMLFilter; } + set { _RMLFilter = value; RaisePropertyChangedAuto(); OnRMLFilterChanged(); } + } + /// <summary> /// Gets or sets the manage RML command. /// </summary> @@ -185,9 +237,21 @@ namespace Tango.MachineStudio.RML.ViewModels public RelayCommand ImportRMLFileCommand { get; set; } - public MainViewVM(INotificationProvider notificationProvider) + /// <summary> + /// Gets or sets the add spool command. + /// </summary> + public RelayCommand AddSpoolCommand { get; set; } + + /// <summary> + /// Gets or sets the remove spool command. + /// </summary> + public RelayCommand RemoveSpoolCommand { get; set; } + + public MainViewVM(INotificationProvider notificationProvider, IAuthenticationProvider authentication, IActionLogManager actionLogManager) { _notification = notificationProvider; + _authentication = authentication; + _actionLogManager = actionLogManager; ManageRmlCommand = new RelayCommand(() => LoadActiveRML(SelectedRML.Guid), () => SelectedRML != null); RemoveRmlCommand = new RelayCommand(RemoveSelectedRml, () => SelectedRML != null); CloneRmlCommand = new RelayCommand(CloneSelectedRml, () => SelectedRML != null); @@ -206,6 +270,9 @@ namespace Tango.MachineStudio.RML.ViewModels ExportRMLFileCommand = new RelayCommand(ExportRmlFile, () => SelectedRML != null && IsFree); ImportRMLFileCommand = new RelayCommand(ImportRmlFile, () => IsFree); + + AddSpoolCommand = new RelayCommand(AddNewSpool); + RemoveSpoolCommand = new RelayCommand(RemoveSpool, () => SelectedSpool != null); } public override void OnApplicationReady() @@ -215,130 +282,177 @@ namespace Tango.MachineStudio.RML.ViewModels private async void LoadRmls() { - if (_rmls_context != null) _rmls_context.Dispose(); + try + { + IsFree = false; - _rmls_context = ObservablesContext.CreateDefault(); - Rmls = await new RmlsCollectionBuilder(_rmls_context).SetAll().WithLiquidFactors().WithMediaProperties().BuildAsync(); + using (_notification.PushTaskItem("Loading Rmls...")) + { + if (_rmls_context != null) _rmls_context.Dispose(); - //Load CCT file names... - var ccts = await _rmls_context.Ccts.Select(x => new - { - x.Guid, - x.FileName - }).ToListAsync(); + _rmls_context = ObservablesContext.CreateDefault(); + Rmls = await new RmlsCollectionBuilder(_rmls_context).SetAll().WithLiquidFactors().WithMediaProperties().BuildAsync(); + //Load CCT file names... + var ccts = await _rmls_context.Ccts.Select(x => new + { + x.Guid, + x.FileName + }).ToListAsync(); - foreach (var rml in Rmls) - { - var cct = ccts.SingleOrDefault(x => x.Guid == rml.CctGuid); + foreach (var rml in Rmls) + { + var cct = ccts.SingleOrDefault(x => x.Guid == rml.CctGuid); - if (cct != null) - { - rml.Cct = new Cct() + if (cct != null) + { + rml.Cct = new Cct() + { + Guid = cct.Guid, + FileName = cct.FileName, + }; + } + } + RmlsCollectionView = CollectionViewSource.GetDefaultView(Rmls); + RmlsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Rml.LastUpdated), ListSortDirection.Descending)); + //RmlsCollectionView.Filter = new Predicate<object>(FilterCollection); + + RmlsCollectionView.Filter = (rml) => { - Guid = cct.Guid, - FileName = cct.FileName, + Rml r = rml as Rml; + return String.IsNullOrWhiteSpace(RMLFilter) + || r.Name.ToLower().Contains(RMLFilter.ToLower()); }; + } } + catch (Exception ex) + { + LogManager.Log(ex, $"Error loading RMLS.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } } private async void LoadActiveRML(String guid) { using (_notification.PushTaskItem("Loading RML...")) { - IsFree = false; - - if (_active_context != null) + try { - _active_context.Dispose(); - } - - _active_context = ObservablesContext.CreateDefault(); + IsFree = false; - CCTS = _active_context.Ccts - .Select(x => new CctModel() + if (_active_context != null) { - Guid = x.Guid, - FileName = x.FileName, + _active_context.Dispose(); + } - }).ToObservableCollection(); + _active_context = ObservablesContext.CreateDefault(); - CCTS.Where(x => String.IsNullOrWhiteSpace(x.FileName)).ToList().ForEach(x => x.FileName = x.Guid); + CCTS = _active_context.Ccts + .Select(x => new CctModel() + { + Guid = x.Guid, + FileName = x.FileName, - LoadRmlProperties(); + }).ToObservableCollection(); - ActiveRML = await new RmlBuilder(_active_context) - .Set(guid) - .WithActiveParametersGroup() - .WithLiquidFactors() - .WithCCT() - .BuildAsync(); + CCTS.Where(x => String.IsNullOrWhiteSpace(x.FileName)).ToList().ForEach(x => x.FileName = x.Guid); - if (ActiveRML.Cct != null) - { - SelectedCCT = CCTS.SingleOrDefault(x => x.Guid == ActiveRML.Cct.Guid); - } + LoadRmlProperties(); - if (ActiveRML.ProcessParametersTablesGroups.ToList().Count == 0) - { - if (!_notification.ShowQuestion("Could not find any process group for the selected RML. Would you like to create one?")) + ActiveRML = await new RmlBuilder(_active_context) + .Set(guid) + .WithActiveParametersGroup() + .WithLiquidFactors() + .WithCCT() + .WithSpools() + .BuildAsync(); + + if (ActiveRML.Cct != null) { - _notification.ShowError("Cannot load an RML with no process group."); - IsFree = true; - return; + SelectedCCT = CCTS.SingleOrDefault(x => x.Guid == ActiveRML.Cct.Guid); } - else + + if (ActiveRML.ProcessParametersTablesGroups.ToList().Count == 0) { - ProcessParametersTablesGroup group = new ProcessParametersTablesGroup(); - group.Name = "Active Group"; - group.Active = true; - group.ProcessParametersTables.Add(new ProcessParametersTable() + if (!_notification.ShowQuestion("Could not find any process group for the selected RML. Would you like to create one?")) + { + _notification.ShowError("Cannot load an RML with no process group."); + IsFree = true; + return; + } + else { - Name = "Process Table 1", - }); + ProcessParametersTablesGroup group = new ProcessParametersTablesGroup(); + group.Name = "Active Group"; + group.Active = true; + group.ProcessParametersTables.Add(new ProcessParametersTable() + { + Name = "Process Table 1", + }); - group.Rml = ActiveRML; + group.Rml = ActiveRML; - _active_context.ProcessParametersTablesGroups.Add(group); - _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]); - await _active_context.SaveChangesAsync(); - LoadActiveRML(ActiveRML.Guid); - return; + _active_context.ProcessParametersTablesGroups.Add(group); + _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]); + await _active_context.SaveChangesAsync(); + LoadActiveRML(ActiveRML.Guid); + return; + } } - } - ActiveProcessParametersGroup = ActiveRML.ProcessParametersTablesGroups.ToList().FirstOrDefault(); - ActiveProcessParametersTableView = CollectionViewSource.GetDefaultView(ActiveProcessParametersGroup.ProcessParametersTables); - ActiveProcessParametersTableView.SortDescriptions.Add(new SortDescription(nameof(ProcessParametersTable.TableIndex), ListSortDirection.Ascending)); + ActiveProcessParametersGroup = ActiveRML.ProcessParametersTablesGroups.ToList().FirstOrDefault(); + ActiveProcessParametersTableView = CollectionViewSource.GetDefaultView(ActiveProcessParametersGroup.ProcessParametersTables); + ActiveProcessParametersTableView.SortDescriptions.Add(new SortDescription(nameof(ProcessParametersTable.TableIndex), ListSortDirection.Ascending)); - CalibrationDataViewVM = new CalibrationDataViewVM(_notification); - LiquidTypesRmls = ActiveRML.LiquidTypesRmls; + CalibrationDataViewVM = new CalibrationDataViewVM(_notification); + LiquidTypesRmls = ActiveRML.LiquidTypesRmls; - foreach (var liquidTypeRml in LiquidTypesRmls) - { - CalibrationDataVM catVM = new CalibrationDataVM(liquidTypeRml.LiquidType); - - if (liquidTypeRml.DefaultCatData != null) + foreach (var liquidTypeRml in LiquidTypesRmls) { - catVM.CalibrationPoints = liquidTypeRml.GetCalibrationData().CalibrationPoints.Select(x => new CalibrationDataPointVM(x.X, x.Y)).ToObservableCollection(); + CalibrationDataVM catVM = new CalibrationDataVM(liquidTypeRml.LiquidType); + + if (liquidTypeRml.DefaultCatData != null) + { + catVM.CalibrationPoints = liquidTypeRml.GetCalibrationData().CalibrationPoints.Select(x => new CalibrationDataPointVM(x.X, x.Y)).ToObservableCollection(); + } + + CalibrationDataViewVM.LiquidsCalibrationData.Add(catVM); } - CalibrationDataViewVM.LiquidsCalibrationData.Add(catVM); - } + ColorConversionViewVM = new ColorConversionViewVM(_notification) + { + RML = ActiveRML, + CCT = SelectedCCT, + LiquidsCalibrationData = CalibrationDataViewVM.LiquidsCalibrationData, + LiquidTypesRmls = LiquidTypesRmls, + }; - ColorConversionViewVM = new ColorConversionViewVM(_notification) - { - RML = ActiveRML, - CCT = SelectedCCT, - LiquidsCalibrationData = CalibrationDataViewVM.LiquidsCalibrationData, - LiquidTypesRmls = LiquidTypesRmls, - }; + ColorCalibrationVM = new ColorCalibrationViewVM(_notification) + { + RML = ActiveRML, + LiquidTypes = LiquidTypesRmls.Where(x => x.LiquidType.HasPigment).ToList().Select(y => y.LiquidType).ToList(), + }; - View.NavigateTo(RmlNavigationView.RmlView); + _rmlBeforeSave = RmlDTO.FromObservable(ActiveRML); - InvalidateRelayCommands(); + View.NavigateTo(RmlNavigationView.RmlView); - IsFree = true; + InvalidateRelayCommands(); + + IsFree = true; + } + catch (Exception ex) + { + LogManager.Log($"Error loading RML '{ActiveRML.Name}'..."); + _notification.ShowError($"Error loading the selected thread.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } } } @@ -371,6 +485,7 @@ namespace Tango.MachineStudio.RML.ViewModels LinearMassDensityUnits = _active_context.LinearMassDensityUnits.ToObservableCollection(); FiberShapes = _active_context.FiberShapes.ToObservableCollection(); FiberSynths = _active_context.FiberSynths.ToObservableCollection(); + SpoolTypes = _active_context.SpoolTypes.ToObservableCollection(); } private async void AddNewRml() @@ -400,8 +515,10 @@ namespace Tango.MachineStudio.RML.ViewModels Rml rml = new Rml(); rml.Name = name; + rml.DisplayName = name; + rml.QualificationDate = DateTime.UtcNow; rml.Manufacturer = "Twine"; - rml.Code = Rmls.Max(x => x.Code) + 1; + rml.Code = Rmls.Count > 0 ? Rmls.Max(x => x.Code) + 1 : 1; rml.MediaMaterial = Materials.FirstOrDefault(); rml.MediaPurpose = Purposes.FirstOrDefault(); rml.MediaCondition = Conditions.FirstOrDefault(); @@ -423,6 +540,9 @@ namespace Tango.MachineStudio.RML.ViewModels _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]); _active_context.Rmls.Add(rml); await _active_context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, rml.Name, rml, "Rml created using Machine Studio."); + LoadActiveRML(rml.Guid); IsFree = true; @@ -432,25 +552,64 @@ namespace Tango.MachineStudio.RML.ViewModels private async void RemoveSelectedRml() { - if (_notification.ShowQuestion("Removing the selected RML will result in the loss of all related process parameters and default calibration data. Are you sure you want to delete the selected RML?")) + if (_notification.ShowQuestion("Removing the selected thread will result in the loss of all related process parameters and default calibration data. Are you sure you want to delete the selected RML?")) { - IsFree = false; - using (_notification.PushTaskItem("Removing RML...")) { try { + IsFree = false; + + var rml_jobs = await _rmls_context.Jobs.Where(x => x.RmlGuid == SelectedRML.Guid).Include(x => x.Machine).OrderBy(x => x.Machine.SerialNumber).ToListAsync(); + + if (rml_jobs.Count > 0) + { + var vm = new RmlDeleteDialogViewVM(SelectedRML, Rmls.ToList(), rml_jobs.ToList()); + _notification.ShowModalDialog<RmlDeleteDialogViewVM, RmlDeleteDialogView>(vm, (x) => { }, () => { }); + + if (!vm.DialogResult) + { + return; + } + + //Perform actions... + using (var db = ObservablesContext.CreateDefault()) + { + foreach (var jobAction in vm.JobsActions) + { + if (jobAction.Action == RmlDeleteDialogViewVM.RmlDeleteJobAction.Delete) + { + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.JobDeleted, _authentication.CurrentUser.Guid, jobAction.Job.Name, jobAction.Job.Guid, $"Job deleted due to RML '{SelectedRML.Name}' being removed."); + await jobAction.Job.DeleteCascadeAsync(db); + } + else if (jobAction.Action == RmlDeleteDialogViewVM.RmlDeleteJobAction.Change) + { + var job = await db.Jobs.SingleOrDefaultAsync(x => x.Guid == jobAction.Job.Guid); + job.RmlGuid = jobAction.TargetRml.Guid; + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.JobSaved, _authentication.CurrentUser.Guid, jobAction.Job.Name, jobAction.Job.Guid, $"Job RML changed to '{jobAction.TargetRml.Name}' due to RML '{SelectedRML.Name}' being removed."); + } + } + + await db.SaveChangesAsync(); + } + } + await SelectedRML.DeleteCascadeAsync(_rmls_context); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlDeleted, _authentication.CurrentUser, SelectedRML.Name, SelectedRML, "RML deleted from Machine Studio."); + LoadRmls(); } catch (Exception ex) { - LogManager.Log(ex, $"Error removing selected RML {SelectedRML.Name}."); - _notification.ShowError($"An error occurred while trying to remove the selected RML.\n{ex.Message}"); + LogManager.Log(ex, $"Error removing selected RML {SelectedRML?.Name}."); + _notification.ShowError($"An error occurred while trying to remove the selected RML.\n{ex.FlattenMessage()}"); + LoadRmls(); + } + finally + { + IsFree = true; } } - - IsFree = true; } } @@ -468,15 +627,18 @@ namespace Tango.MachineStudio.RML.ViewModels using (var context = ObservablesContext.CreateDefault()) { - var rml = await new RmlBuilder(context).Set(SelectedRML.Guid).WithActiveParametersGroup().WithLiquidFactors().BuildAsync(); + var rml = await new RmlBuilder(context).Set(SelectedRML.Guid).WithActiveParametersGroup().WithLiquidFactors().WithSpools().BuildAsync(); Rml cloned = new Rml(); - rml.MapPrimitivesWithStrings(cloned); + rml.MapPropertiesTo(cloned, MappingFlags.NoReferenceTypes); cloned.Code = Rmls.Max(x => x.Code) + 1; cloned.Guid = Guid.NewGuid().ToString(); cloned.ID = 0; cloned.Name = name; + cloned.DisplayName = name; + cloned.RmlQualificationLevel = RmlQualifications.Provisional; + cloned.QualificationDate = DateTime.UtcNow; ProcessParametersTablesGroup group = new ProcessParametersTablesGroup(); group.Name = rml.GetActiveProcessGroup().Name; @@ -502,8 +664,19 @@ namespace Tango.MachineStudio.RML.ViewModels cloned.LiquidTypesRmls.Add(l); } + foreach (var spool in rml.RmlsSpools) + { + RmlsSpool s = new RmlsSpool(); + spool.MapPropertiesTo(s, MappingFlags.ValueTypesOnly); + s.RmlGuid = cloned.Guid; + s.SpoolTypeGuid = spool.SpoolTypeGuid; + cloned.RmlsSpools.Add(s); + } + context.Rmls.Add(cloned); await context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, cloned.Name, cloned, "RML cloned from Machine Studio."); } LoadRmls(); @@ -558,6 +731,11 @@ namespace Tango.MachineStudio.RML.ViewModels ActiveProcessParametersTableView.Refresh(); } + private void OnRMLFilterChanged() + { + RmlsCollectionView.Refresh(); + } + private void RemoveLiquidFactor(LiquidTypesRml liquidFactor) { if (_notification.ShowQuestion("Removing this liquid factor will remove the liquid type association with the RML and will drop the calibration data. Are you sure?")) @@ -648,6 +826,11 @@ namespace Tango.MachineStudio.RML.ViewModels ActiveRML.LastUpdated = DateTime.UtcNow; + if (_rmlBeforeSave.QualificationLevel != ActiveRML.QualificationLevel) + { + ActiveRML.QualificationDate = DateTime.UtcNow; + } + if (SelectedCCT != null) { if (SelectedCCT.IsNew) @@ -665,18 +848,26 @@ namespace Tango.MachineStudio.RML.ViewModels } } + var rmlAfter = RmlDTO.FromObservable(ActiveRML); + await _active_context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlSaved, _authentication.CurrentUser, _rmlBeforeSave.Name, _rmlBeforeSave, rmlAfter, "RML saved using Machine Studio."); + + _rmlBeforeSave = rmlAfter; + + LoadActiveRML(ActiveRML.Guid); } } catch (Exception ex) { LogManager.Log(ex, $"Error saving RML {ActiveRML.Name}"); - _notification.ShowError($"An error occurred while trying to save the current RML.\n{ex.Message}"); + _notification.ShowError($"An error occurred while trying to save the current RML.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; } - - LoadActiveRML(ActiveRML.Guid); - - IsFree = true; } private void BackToRmls() @@ -692,6 +883,12 @@ namespace Tango.MachineStudio.RML.ViewModels String file = GetCCTFileOpen(); if (file != null) { + if (CCTS.ToList().Exists(x => x.FileName == Path.GetFileName(file))) + { + _notification.ShowError("The selected CCT file already exists on the database. Please select the CCT file from the dropdown box."); + return; + } + CctModel cctModel = new CctModel(); cctModel.Guid = Guid.NewGuid().ToString(); cctModel.IsNew = true; @@ -804,6 +1001,8 @@ namespace Tango.MachineStudio.RML.ViewModels var rmlFile = await Rml.FromRmlFile(db, json); db.Rmls.Add(rmlFile); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlImported, _authentication.CurrentUser, rmlFile.Name, rmlFile, "RML imported from Machine Studio."); } await db.SaveChangesAsync(); @@ -860,5 +1059,26 @@ namespace Tango.MachineStudio.RML.ViewModels } #endregion + + #region Spools + + private void AddNewSpool() + { + _active_context.RmlsSpools.Add(new RmlsSpool() + { + Rml = ActiveRML, + }); + } + + private void RemoveSpool() + { + if (SelectedSpool != null) + { + _active_context.RmlsSpools.Remove(SelectedSpool); + ActiveRML.RmlsSpools.Remove(SelectedSpool); + } + } + + #endregion } } |
