using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows.Data; using Tango.Core.Commands; using Tango.Core.Helpers; using Tango.BL.Entities; using Tango.MachineStudio.Common.Notifications; using Tango.SharedUI; using SimpleValidator.Extensions; using Tango.MachineStudio.Common.StudioApplication; using Tango.MachineStudio.Common; using Tango.BL; using Tango.AutoComplete.Editors; using System.Data.Entity; using Tango.BL.Builders; using Tango.MachineStudio.MachineDesigner.Contracts; using System.Windows.Threading; using Tango.Core.Threading; using Tango.MachineStudio.RML.ViewModels; using Tango.Settings; using Tango.MachineStudio.RML.Models; using Tango.BL.ActionLogs; using Tango.MachineStudio.Common.Authentication; using Tango.BL.DTO; namespace Tango.MachineStudio.MachineDesigner.ViewModels { public class MainViewVM : StudioViewModel { private INotificationProvider _notification; private IActionLogManager _actionLogManager; private IAuthenticationProvider _authentication; private ActionTimer _machines_action_timer; private ActionTimer _dispensers_action_timer; private MachineDTO _machineBeforeSave; #region Properties private bool _isNewMachine; public bool IsNewMachine { get { return _isNewMachine; } set { _isNewMachine = value; RaisePropertyChangedAuto(); } } private ObservablesStaticCollections _machinesAdapter; public ObservablesStaticCollections MachinesAdapter { get { return _machinesAdapter; } set { _machinesAdapter = value; RaisePropertyChangedAuto(); } } private ObservablesStaticCollections _activeMachineAdapter; public ObservablesStaticCollections ActiveMachineAdapter { get { return _activeMachineAdapter; } set { _activeMachineAdapter = value; RaisePropertyChangedAuto(); } } private Machine _selectedMachine; /// /// Gets or sets the selected machine from the drop down. /// public Machine SelectedMachine { get { return _selectedMachine; } set { if (_selectedMachine != value) { _selectedMachine = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } } private Machine _activeMachine; /// /// Gets or sets the active machine. /// public Machine ActiveMachine { get { return _activeMachine; } set { _activeMachine = value; RaisePropertyChangedAuto(); } } private IdsPack _selectedIds; /// /// Gets or sets the selected ids pack. /// public IdsPack SelectedIds { get { return _selectedIds; } set { _selectedIds = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private String _dispensersFilter; /// /// Gets or sets the dispensers filter. /// public String DispensersFilter { get { return _dispensersFilter; } set { _dispensersFilter = value; RaisePropertyChangedAuto(); OnDispensersFilterChanged(); } } private String _filter; /// /// Gets or sets the machines filter. /// public String Filter { get { return _filter; } set { _filter = value; RaisePropertyChangedAuto(); OnFilterChanged(); } } private Spool _selectedSpool; public Spool SelectedSpool { get { return _selectedSpool; } set { _selectedSpool = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private Site _selectedSite; public Site SelectedSite { get { return _selectedSite; } set { _selectedSite = value; RaisePropertyChangedAuto(); } } private List _sites; public List Sites { get { return _sites; } set { _sites = value; RaisePropertyChangedAuto(); } } private ColorCalibrationViewVM _colorCalibrationViewVM; public ColorCalibrationViewVM ColorCalibrationViewVM { get { return _colorCalibrationViewVM; } set { _colorCalibrationViewVM = value; RaisePropertyChangedAuto(); } } private HardwareConfigurationViewVM _hardwareConfigurationViewVM; public HardwareConfigurationViewVM HardwareConfigurationViewVM { get { return _hardwareConfigurationViewVM; } set { _hardwareConfigurationViewVM = value; RaisePropertyChangedAuto(); } } private MachineUpdatesViewVM _machineUpdatesViewVM; public MachineUpdatesViewVM MachineUpdatesViewVM { get { return _machineUpdatesViewVM; } set { _machineUpdatesViewVM = value; RaisePropertyChangedAuto(); } } private TupViewVM _tupViewVM; public TupViewVM TupViewVM { get { return _tupViewVM; } set { _tupViewVM = value; RaisePropertyChangedAuto(); } } #endregion #region Commands /// /// Gets or sets the save command. /// public RelayCommand SaveCommand { get; set; } /// /// Gets or sets the add ids command. /// public RelayCommand AddIdsCommand { get; set; } /// /// Gets or sets the remove ids command. /// public RelayCommand RemoveIdsCommand { get; set; } /// /// Gets or sets the remove machine command. /// public RelayCommand RemoveMachineCommand { get; set; } /// /// Gets or sets the add machine command. /// public RelayCommand AddMachineCommand { get; set; } /// /// Gets or sets the edit machine command. /// public RelayCommand EditMachineCommand { get; set; } /// /// Gets or sets the back to machines command. /// public RelayCommand BackToMachinesCommand { get; set; } /// /// Gets or sets the add spool command. /// public RelayCommand AddSpoolCommand { get; set; } /// /// Gets or sets the remove spool command. /// public RelayCommand RemoveSpoolCommand { get; set; } /// /// Gets or sets the clone machine command. /// public RelayCommand CloneMachineCommand { get; set; } /// /// Gets or sets the reset device registration command. /// public RelayCommand ResetDeviceRegistrationCommand { get; set; } /// /// Gets or sets the make prototype command. /// public RelayCommand MakePrototypeCommand { get; set; } #endregion #region Constructors public MainViewVM() { } /// /// Initializes a new instance of the class. /// public MainViewVM(INotificationProvider notification, IAuthenticationProvider authentication, IActionLogManager actionLogManager) { MachinesAdapter = new ObservablesStaticCollections(ObservablesContext.CreateDefault()); _notification = notification; _authentication = authentication; _actionLogManager = actionLogManager; _machines_action_timer = new ActionTimer(TimeSpan.FromMilliseconds(200)); _dispensers_action_timer = new ActionTimer(TimeSpan.FromMilliseconds(200)); AddIdsCommand = new RelayCommand(AddIds, (x) => ActiveMachine != null && ActiveMachine.Configuration != null && ActiveMachine.Configuration.IdsPacks.Count < 8); RemoveIdsCommand = new RelayCommand(RemoveIds, (x) => SelectedIds != null); EditMachineCommand = new RelayCommand(() => LoadSelectedMachine(), () => SelectedMachine != null); BackToMachinesCommand = new RelayCommand(() => View.NavigateTo(MachineDesignerNavigationView.MachinesView)); SaveCommand = new RelayCommand(SaveMachine); AddMachineCommand = new RelayCommand(AddNewMachine); RemoveMachineCommand = new RelayCommand(RemoveSelectedMachine, () => SelectedMachine != null); AddSpoolCommand = new RelayCommand(AddNewSpool); RemoveSpoolCommand = new RelayCommand(RemoveSpool, () => SelectedSpool != null); CloneMachineCommand = new RelayCommand(CloneMachine, () => SelectedMachine != null); ResetDeviceRegistrationCommand = new RelayCommand(ResetDeviceRegistration); MakePrototypeCommand = new RelayCommand(MakePrototype); MachineUpdatesViewVM = new MachineUpdatesViewVM(_notification); TupViewVM = new TupViewVM(_notification); } #endregion #region Application Ready public override async void OnApplicationReady() { MachinesAdapter.MachineVersions = (await MachinesAdapter.Context.MachineVersions.ToListAsync()).ToObservableCollection(); } #endregion private void OnDispensersFilterChanged() { if (!String.IsNullOrWhiteSpace(DispensersFilter)) { _dispensers_action_timer.ResetReplace(() => { Task.Factory.StartNew(() => { ActiveMachineAdapter.Dispensers = ActiveMachineAdapter.Context.Dispensers.Where(x => x.SerialNumber.ToLower().StartsWith(DispensersFilter.ToLower())).OrderBy(x => x.SerialNumber).ToSynchronizedObservableCollection(); }); }); } } #region Drag Drop Handlers /// /// Drops the ids pack. /// /// The ids pack1. /// The ids pack2. public void DropIdsPack(IdsPack idsPack1, IdsPack idsPack2) { ActiveMachine.Configuration.IdsPacks.Swap(idsPack1, idsPack2); ColorCalibrationViewVM.InvalidateCalibrationDataAndColorConversion(); } /// /// Drops the touch panel. /// /// The application display panel version. public void DropTouchPanel(ApplicationDisplayPanelVersion applicationDisplayPanelVersion) { ActiveMachine.Configuration.ApplicationDisplayPanelVersion = applicationDisplayPanelVersion; ActiveMachine.Configuration.ApplicationDisplayPanelVersionGuid = applicationDisplayPanelVersion.Guid; } /// /// Drops the application firmware version. /// /// The application firmware version. public void DropApplicationFirmwareVersion(ApplicationFirmwareVersion applicationFirmwareVersion) { ActiveMachine.Configuration.ApplicationFirmwareVersion = applicationFirmwareVersion; ActiveMachine.Configuration.ApplicationFirmwareVersionGuid = applicationFirmwareVersion.Guid; } /// /// Drops the hardware version. /// /// The hardware version. public void DropHardwareVersion(HardwareVersion hardwareVersion) { ActiveMachine.Configuration.HardwareVersion = hardwareVersion; ActiveMachine.Configuration.HardwareVersionGuid = hardwareVersion.Guid; } /// /// Drops the embedded firmware. /// /// The embedded firmware version. public void DropEmbeddedFirmware(EmbeddedFirmwareVersion embeddedFirmwareVersion) { ActiveMachine.Configuration.EmbeddedFirmwareVersion = embeddedFirmwareVersion; ActiveMachine.Configuration.EmbeddedFirmwareVersionGuid = embeddedFirmwareVersion.Guid; } /// /// Drops the application os version. /// /// The application os version. public void DropApplicationOsVersion(ApplicationOsVersion applicationOsVersion) { ActiveMachine.Configuration.ApplicationOsVersion = applicationOsVersion; ActiveMachine.Configuration.ApplicationOsVersionGuid = applicationOsVersion.Guid; } /// /// Drops the dispenser. /// /// The dispenser. /// The ids pack. public void DropDispenser(Dispenser dispenser, IdsPack idsPack) { idsPack.Dispenser = dispenser; idsPack.DispenserGuid = dispenser.Guid; } /// /// Drops the type of the cartridge. /// /// Type of the cartridge. /// The ids pack. public void DropCartridgeType(CartridgeType cartridgeType, IdsPack idsPack) { idsPack.CartridgeType = cartridgeType; idsPack.CartridgeTypeGuid = cartridgeType.Guid; } /// /// Drops the type of the mid tank. /// /// Type of the mid tank. /// The ids pack. public void DropMidTankType(MidTankType midTankType, IdsPack idsPack) { idsPack.MidTankType = midTankType; idsPack.MidTankTypeGuid = midTankType.Guid; } /// /// Drops the type of the liquid. /// /// Type of the liquid. /// The ids pack. public void DropLiquidType(LiquidType liquidType, IdsPack idsPack) { idsPack.LiquidType = liquidType; idsPack.LiquidTypeGuid = liquidType.Guid; ColorCalibrationViewVM.InvalidateCalibrationDataAndColorConversion(); } /// /// Drops the ids formula. /// /// The ids pack formula. /// The ids pack. /// public void DropIdsFormula(IdsPackFormula idsPackFormula, IdsPack idsPack) { idsPack.IdsPackFormula = idsPackFormula; idsPack.IdsPackFormulaGuid = idsPackFormula.Guid; } #endregion #region Private Methods /// /// Removes the selected IDS pack. /// private void RemoveIds() { ActiveMachineAdapter.Context.IdsPacks.Remove(SelectedIds); SelectedIds = null; ColorCalibrationViewVM.InvalidateCalibrationDataAndColorConversion(); } /// /// Adds a new IDS pack. /// private void AddIds() { ActiveMachineAdapter.Context.IdsPacks.Add(new IdsPack() { Configuration = ActiveMachine.Configuration }); InvalidateRelayCommands(); } private async void LoadSelectedMachine(bool newMachine = false, bool clone = false, MachineCreationDialogVM machineCreationDialogVM = null) { IsNewMachine = false; using (_notification.PushTaskItem("Loading machine details...")) { try { IsFree = false; if (ActiveMachineAdapter != null) { ActiveMachineAdapter.Context.Dispose(); } ActiveMachineAdapter = new ObservablesStaticCollections(ObservablesContext.CreateDefault()); ActiveMachineAdapter.Organizations = (await ActiveMachineAdapter.Context.Organizations.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.MachineVersions = (await ActiveMachineAdapter.Context.MachineVersions.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.Rmls = (await ActiveMachineAdapter.Context.Rmls.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.ColorSpaces = (await ActiveMachineAdapter.Context.ColorSpaces.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.SpoolTypes = (await ActiveMachineAdapter.Context.SpoolTypes.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.ApplicationDisplayPanelVersions = (await ActiveMachineAdapter.Context.ApplicationDisplayPanelVersions.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.ApplicationFirmwareVersions = (await ActiveMachineAdapter.Context.ApplicationFirmwareVersions.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.ApplicationOsVersions = (await ActiveMachineAdapter.Context.ApplicationOsVersions.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.EmbeddedFirmwareVersions = (await ActiveMachineAdapter.Context.EmbeddedFirmwareVersions.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.DispenserTypes = (await ActiveMachineAdapter.Context.DispenserTypes.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.LiquidTypes = (await ActiveMachineAdapter.Context.LiquidTypes.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.MidTankTypes = (await ActiveMachineAdapter.Context.MidTankTypes.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.CartridgeTypes = (await ActiveMachineAdapter.Context.CartridgeTypes.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.IdsPackFormulas = (await ActiveMachineAdapter.Context.IdsPackFormulas.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.HardwareVersions = (await ActiveMachineAdapter.Context.HardwareVersions.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.MachineVersions = (await ActiveMachineAdapter.Context.MachineVersions.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.Organizations = (await ActiveMachineAdapter.Context.Organizations.ToListAsync()).ToObservableCollection(); bool initHwConfig = true; Configuration machineConfigBeforeClone = null; if (!newMachine) { ActiveMachine = (await new MachineBuilder(ActiveMachineAdapter.Context).Set(SelectedMachine.Guid).WithOrganization().WithConfiguration().WithSpools().BuildAsync()); _machineBeforeSave = MachineDTO.FromObservable(ActiveMachine); if (clone) { machineConfigBeforeClone = ActiveMachine.Configuration; IsNewMachine = true; ActiveMachine = ActiveMachine.Clone(); ActiveMachine.Name = machineCreationDialogVM.Name; ActiveMachine.SerialNumber = machineCreationDialogVM.SerialNumber; ActiveMachine.IsDeviceRegistered = false; ActiveMachine.DeviceId = null; ActiveMachine.DeviceName = null; ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); } } else { IsNewMachine = true; if (machineCreationDialogVM.SelectedMachineVersion == null) { ActiveMachine = new Machine(); ActiveMachine.Configuration = new Configuration(); ActiveMachine.SerialNumber = machineCreationDialogVM.SerialNumber; ActiveMachine.Name = machineCreationDialogVM.Name; ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); } else { try { initHwConfig = false; ActiveMachine = machineCreationDialogVM.SelectedMachineVersion.CreatePrototypeMachine(ActiveMachineAdapter.Context); ActiveMachine.SerialNumber = machineCreationDialogVM.SerialNumber; ActiveMachine.Name = machineCreationDialogVM.Name; ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); var version = await new HardwareVersionBuilder(ActiveMachineAdapter.Context).Set(ActiveMachine.Configuration.HardwareVersionGuid).WithHardwareComponents().BuildAsync(); HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); } catch (Exception ex) { _notification.ShowError($"Invalid machine version prototype.\n{ex.FlattenMessage()}"); View.NavigateTo(MachineDesignerNavigationView.MachinesView); return; } } } if ((newMachine || clone) && machineCreationDialogVM.GenerateDispensers) { for (int i = 0; i < 8; i++) { var serial = machineCreationDialogVM.SerialNumber + "-" + (i + 1); var existingDispenser = await ActiveMachineAdapter.Context.Dispensers.Include(x => x.IdsPacks).SingleAsync(x => x.SerialNumber == serial); if (existingDispenser != null) { if (existingDispenser.IsInstalled) { _notification.ShowError($"Dispenser '{serial}' already exists. Cannot create machine."); return; } else { if (!_notification.ShowErrorQuestion($"Dispenser '{serial}' already exists and is not installed. Do you wish to assign the existing dispenser to this machine?")) { return; } } } Dispenser dispenser = new Dispenser(); if (existingDispenser == null) { dispenser.SerialNumber = serial; if (newMachine) { dispenser.NlPerPulse = machineCreationDialogVM.DispenserFactor; dispenser.DispenserTypeGuid = ActiveMachineAdapter.DispenserTypes.First().Guid; } else { var packBefore = machineConfigBeforeClone.NoneEmptyIdsPacks.SingleOrDefault(x => x.PackIndex == i); if (packBefore != null) { dispenser.NlPerPulse = packBefore.Dispenser.NlPerPulse; dispenser.DispenserTypeGuid = packBefore.Dispenser.DispenserType.Guid; } else { continue; } } dispenser.ProductionDate = DateTime.UtcNow; ActiveMachineAdapter.Context.Dispensers.Add(dispenser); } else { dispenser = existingDispenser; } var idsPack = ActiveMachine.Configuration.NoneEmptyIdsPacks.SingleOrDefault(x => x.PackIndex == i); if (idsPack != null) { idsPack.Dispenser = dispenser; idsPack.DispenserGuid = dispenser.Guid; } } } var sites = await ActiveMachineAdapter.Context.Sites.ToListAsync(); sites.Insert(0, new Site() { Name = "NONE", ID = -1 }); Sites = sites; SelectedSite = Sites.SingleOrDefault(x => x.Guid == ActiveMachine.SiteGuid); ColorCalibrationViewVM = new ColorCalibrationViewVM(_notification, ActiveMachine, _activeMachineAdapter.Context) { Rmls = ActiveMachineAdapter.Rmls, LiquidTypesRmls = ActiveMachineAdapter.Rmls.FirstOrDefault().LiquidTypesRmls, SelectedRML = ActiveMachineAdapter.Rmls.FirstOrDefault(), }; if (initHwConfig) { HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); } if (!IsNewMachine) { await MachineUpdatesViewVM.Init(ActiveMachine, ActiveMachineAdapter.Context); TupViewVM.Init(ActiveMachine); } ActiveMachine.Configuration.HardwareVersionChanged += Configuration_HardwareVersionChanged; View.NavigateTo(MachineDesignerNavigationView.MachineDetailsView); } catch (Exception ex) { LogManager.Log(ex, $"Error loading machine details for serial number {SelectedMachine.SerialNumber}"); _notification.ShowError($"An error occurred while trying to load the selected machine details.\n{ex.Message}"); } finally { IsFree = true; InvalidateRelayCommands(); } } } private async void Configuration_HardwareVersionChanged(object sender, HardwareVersion e) { var version = ActiveMachine.Configuration.HardwareVersion; if (version != null) { using (_notification.PushTaskItem("Loading hardware version...")) { try { if (HardwareConfigurationViewVM == null) { HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); } version = await new HardwareVersionBuilder(ActiveMachineAdapter.Context).Set(version.Guid).WithHardwareComponents().BuildAsync(); HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); } catch (Exception ex) { LogManager.Log(ex); } } } } private async void SaveMachine() { foreach (var ids in ActiveMachine.Configuration.IdsPacks) { ids.PackIndex = ActiveMachine.Configuration.IdsPacks.IndexOf(ids); ids.Configuration = ActiveMachine.Configuration; ids.ConfigurationGuid = ActiveMachine.Configuration.Guid; } List errors = new List(); if (ActiveMachine.MachineVersion == null) { errors.Add("Machine version is required."); } if (ActiveMachine.Name.IsNullOrWhiteSpace()) { errors.Add("Machine name is required."); } if (ActiveMachine.Organization == null) { errors.Add("Machine organization is required."); } if (ActiveMachine.SerialNumber.IsNullOrWhiteSpace()) { errors.Add("Machine serial number is required."); } if (ActiveMachine.Configuration.ApplicationDisplayPanelVersion == null) { errors.Add("Touch Panel is required."); } if (ActiveMachine.Configuration.ApplicationFirmwareVersion == null) { errors.Add("Application firmware is required."); } if (ActiveMachine.Configuration.ApplicationOsVersion == null) { errors.Add("Application operation system is required."); } if (ActiveMachine.Configuration.EmbeddedFirmwareVersion == null) { errors.Add("Embedded firmware is required."); } if (ActiveMachine.Configuration.HardwareVersion == null) { errors.Add("Hardware version is required."); } foreach (var pack in ActiveMachine.Configuration.IdsPacks) { if (pack.LiquidType != null || pack.CartridgeType != null || pack.Dispenser != null || pack.IdsPackFormula != null || pack.MidTankType != null) { if (pack.CartridgeType == null) { errors.Add(String.Format("Cartridge type is required on IDS pack '{0}'.", pack.PackIndex)); } if (pack.Dispenser == null) { errors.Add(String.Format("Dispenser is required on IDS pack '{0}'.", pack.PackIndex)); } if (pack.LiquidType == null) { errors.Add(String.Format("Liquid type is required on IDS pack '{0}'.", pack.PackIndex)); } if (pack.MidTankType == null) { errors.Add(String.Format("Mid Tank type is required on IDS pack '{0}'.", pack.PackIndex)); } if (pack.IdsPackFormula == null) { errors.Add(String.Format("Formula type is required on IDS pack '{0}'.", pack.PackIndex)); } pack.IsEmpty = false; } else { pack.IsEmpty = true; } } foreach (var pack in ActiveMachine.Configuration.IdsPacks.Where(x => x.Dispenser != null)) { if (ActiveMachine.Configuration.IdsPacks.Where(x => x.Dispenser == pack.Dispenser).Count() > 1) { errors.Add($"Dispenser '{pack.Dispenser.SerialNumber}' is installed on multiple IDS packs."); } if (ActiveMachineAdapter.Context.IdsPacks.Count(x => x.ConfigurationGuid != pack.ConfigurationGuid && x.DispenserGuid == pack.DispenserGuid) > 0) { errors.Add($"Dispenser '{pack.Dispenser.SerialNumber}' is already installed on a different machine."); } } if (ActiveMachine.Spools.GroupBy(x => x.SpoolType).Any(x => x.Count() > 1)) { errors.Add($"Same spool type is registered multiple times."); } if (errors.Count > 0) { String errorsString = "Please fix the following validation errors before trying to save." + Environment.NewLine + Environment.NewLine; errorsString += String.Join(Environment.NewLine, errors.Distinct()); _notification.ShowError(errorsString); return; } try { IsFree = false; using (_notification.PushTaskItem("Saving Machine Details...")) { ActiveMachine.ConfigurationGuid = ActiveMachine.Configuration.Guid; ActiveMachine.LastUpdated = DateTime.UtcNow; ActiveMachine.SiteGuid = SelectedSite == null ? null : (SelectedSite.ID == -1 ? null : SelectedSite.Guid); ColorCalibrationViewVM.Save(); var hwConfig = HardwareConfigurationViewVM.GetResultingHardwareConfiguration(); ActiveMachine.Configuration.SetHardwareConfiguration(hwConfig); await ActiveMachineAdapter.Context.SaveChangesAsync(); if (IsNewMachine) { _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.MachineCreated, _authentication.CurrentUser, ActiveMachine.Name, ActiveMachine, "New machine created using Machine Studio."); } else { var machineAfterDTO = MachineDTO.FromObservable(ActiveMachine); _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.MachineSaved, _authentication.CurrentUser, _machineBeforeSave.Name, _machineBeforeSave, machineAfterDTO, "Machine saved using Machine Studio."); _machineBeforeSave = machineAfterDTO; } if (SelectedMachine != null) { await SelectedMachine.Reload(MachinesAdapter.Context); } ColorCalibrationViewVM.Invalidate(); } } catch (Exception ex) { LogManager.Log(ex, "Error saving machine details."); _notification.ShowError("An error occurred while trying to save the machine details" + Environment.NewLine + ex.Message); } finally { IsFree = true; InvalidateRelayCommands(); } } private void AddNewMachine() { MachineCreationDialogVM vm = new MachineCreationDialogVM(); vm.IsNewMachine = true; vm.MachineVersions = MachinesAdapter.MachineVersions.ToList(); _notification.ShowModalDialog(vm, (x) => { if (MachinesAdapter.Context.Machines.Any(y => y.SerialNumber == vm.SerialNumber || y.Name.ToLower() == vm.Name.ToLower())) { _notification.ShowError("Machine serial number or name already exists."); return; } if (vm.SelectedMachineVersion != null && String.IsNullOrWhiteSpace(vm.SelectedMachineVersion.PrototypeMachineData)) { _notification.ShowError("The selected version does not contain any prototype machine data."); return; } LoadSelectedMachine(true, false, vm); }, () => { }); } private async void RemoveSelectedMachine() { if (_notification.ShowQuestion("Are you sure you want to delete the selected machine?")) { using (_notification.PushTaskItem("Removing machine...")) { try { IsFree = false; await SelectedMachine.DeleteCascadeAsync(MachinesAdapter.Context); _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.MachineDeleted, _authentication.CurrentUser, SelectedMachine.Name, SelectedMachine, "Machine deleted using Machine Studio."); MachinesAdapter.Context.Machines.Remove(SelectedMachine); MachinesAdapter.Machines.Remove(SelectedMachine); } catch (Exception ex) { LogManager.Log(ex, $"Error removing machine {SelectedMachine.SerialNumber}."); _notification.ShowError($"An error occurred while trying to delete the selected machine.\n{ex.Message}"); } finally { IsFree = true; } } } } private void ResetDeviceRegistration() { if (_notification.ShowQuestion("Are you sure you wish to reset this machine device registration?")) { ActiveMachine.IsDeviceRegistered = false; ActiveMachine.DeviceId = null; ActiveMachine.DeviceName = null; } } private async void MakePrototype() { if (ActiveMachine.MachineVersion == null) { _notification.ShowError("Machine version must be selected in order to make a prototype."); return; } if (_notification.ShowQuestion($"Are you sure you wish to make this machine configuration as a prototype for version '{ActiveMachine.MachineVersion.Name}' ?")) { using (_notification.PushTaskItem($"Making prototype machine for '{ActiveMachine.MachineVersion.Name}'...")) { try { IsFree = false; using (var db = ObservablesContext.CreateDefault()) { var machineVersion = await db.MachineVersions.SingleOrDefaultAsync(x => x.Guid == ActiveMachine.MachineVersionGuid); await machineVersion.ApplyPrototypeMachine(ActiveMachine, db); await db.SaveChangesAsync(); } } catch (Exception ex) { _notification.ShowError($"Error making machine version prototype\n{ex.FlattenMessage()}"); } finally { IsFree = true; } } } } #endregion private void CloneMachine() { MachineCreationDialogVM vm = new MachineCreationDialogVM(); vm.IsNewMachine = false; vm.MachineVersions = MachinesAdapter.MachineVersions.ToList(); _notification.ShowModalDialog(vm, (x) => { if (MachinesAdapter.Context.Machines.Any(y => y.SerialNumber == vm.SerialNumber || y.Name.ToLower() == vm.Name.ToLower())) { _notification.ShowError("Machine serial number or name already exists."); return; } LoadSelectedMachine(false, true, vm); }, () => { }); } private void AddNewSpool() { _activeMachineAdapter.Context.Spools.Add(new Spool() { Machine = ActiveMachine, }); } private void RemoveSpool() { if (SelectedSpool != null) { _activeMachineAdapter.Context.Spools.Remove(SelectedSpool); ActiveMachine.Spools.Remove(SelectedSpool); } } private void OnFilterChanged() { if (Filter != null) { _machines_action_timer.ResetReplace(() => { Task.Factory.StartNew(() => { try { IsFree = false; MachinesAdapter.Machines = MachinesAdapter.Context.Machines.Where(x => x.SerialNumber.StartsWith(Filter)).Include(x => x.Organization).Include(x => x.MachineVersion).OrderBy(x => x.SerialNumber).ToSynchronizedObservableCollection(); } catch { } finally { IsFree = true; } }); }); } } } }