From 621230afe9d9040536b43241e63117c9bb34beaa Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 11 Dec 2019 20:57:30 +0200 Subject: Implemented Jobs, JobRuns & Machine Events Synchronization. Added synchronizations to Updates view on Machine Designer. Removed request response events logging from machine studio. Fixed issue with exception throwing from machine service. Implemented "New jobs synchronized" notification item to PPC. Added synchronization to PPC settings. Added Synchronization view to technician module. Implemented PPC Schema synchronizer utility. Added custom query support to EntityCollectionBuilder. Added synchronization status to TangoUpdate. Removed FK from Jobs and Job runs. --- .../Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index 63cfa10b8..46b4c301f 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -1914,6 +1914,7 @@ namespace Tango.MachineStudio.Developer.ViewModels { LogManager.Log(String.Format("Saving the active job {0}...", ActiveJob.Name)); ActiveJob.LastUpdated = DateTime.UtcNow; + ActiveJob.IsSynchronized = false; ActiveJob.Rml = SelectedRML; ActiveJob.EstimatedDurationMili = (int)EstimatedDuration.TotalMilliseconds; _activeJobDbContext.SaveChanges(); -- cgit v1.3.1 From e8ee7dfb8e166e34c7950e90d5fe9bcf31dc351b Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Mon, 16 Dec 2019 10:33:43 +0200 Subject: Some fixes. --- .../Advanced Installer Projects/PPC Installer.aip | 58 +++++++++------------ .../ViewModels/MainViewVM.cs | 2 +- .../PPC/Modules/Tango.PPC.Jobs/Images/sync-job.png | Bin 6743 -> 0 bytes .../PPC/Modules/Tango.PPC.Jobs/Images/sync_job.png | Bin 0 -> 6743 bytes .../NewSynchronizardJobsNotificationItemView.xaml | 6 ++- .../Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj | 5 +- .../Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs | 1 + .../PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs | 2 +- .../Visual_Studio/Tango.BL/ObservableEntity.cs | 11 +++- .../Configurations/ProvisionMachine.xml | Bin 87374 -> 87410 bytes 10 files changed, 46 insertions(+), 39 deletions(-) delete mode 100644 Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Images/sync-job.png create mode 100644 Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Images/sync_job.png (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer') diff --git a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip index 2270cca22..17bdd452f 100644 --- a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip +++ b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip @@ -18,10 +18,10 @@ - + - + @@ -42,11 +42,10 @@ + - - @@ -118,8 +117,6 @@ - - @@ -157,12 +154,14 @@ + + @@ -179,45 +178,42 @@ + + + + + - + - - - - - - - - @@ -229,22 +225,16 @@ - - - - - - @@ -262,7 +252,6 @@ - @@ -276,33 +265,23 @@ - - - - - - - - - - @@ -352,6 +331,9 @@ + + + @@ -369,7 +351,9 @@ - + + + @@ -411,7 +395,10 @@ + + + @@ -421,6 +408,9 @@ + + + @@ -433,7 +423,7 @@ - + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index 46b4c301f..4f517165b 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -1917,11 +1917,11 @@ namespace Tango.MachineStudio.Developer.ViewModels ActiveJob.IsSynchronized = false; ActiveJob.Rml = SelectedRML; ActiveJob.EstimatedDurationMili = (int)EstimatedDuration.TotalMilliseconds; + ActiveJob.MarkModified(_activeJobDbContext); _activeJobDbContext.SaveChanges(); _machineDbContext.Entry(SelectedMachineJob).Reload(); - _machineDbContext.Entry(SelectedMachineJob).Collection(x => x.Segments).Load(); foreach (var segment in SelectedMachineJob.Segments.ToList()) diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Images/sync-job.png b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Images/sync-job.png deleted file mode 100644 index 4e46ee447..000000000 Binary files a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Images/sync-job.png and /dev/null differ diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Images/sync_job.png b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Images/sync_job.png new file mode 100644 index 000000000..4e46ee447 Binary files /dev/null and b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Images/sync_job.png differ diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/NotificationItems/NewSynchronizardJobsNotificationItemView.xaml b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/NotificationItems/NewSynchronizardJobsNotificationItemView.xaml index 23a64676b..5a57e3db7 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/NotificationItems/NewSynchronizardJobsNotificationItemView.xaml +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/NotificationItems/NewSynchronizardJobsNotificationItemView.xaml @@ -10,10 +10,14 @@ x:Name="MessageNotificationItemControl" d:DesignHeight="60" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:NewSynchronizardJobsNotificationItem, IsDesignTimeCreatable=False}" MinHeight="90" Height="90" MaxHeight="150" Background="White"> + + + + - + diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj index 5e1fd39bd..33b9de808 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Tango.PPC.Jobs.csproj @@ -503,10 +503,13 @@ + + + - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs index 5ec1c34ec..0175b949e 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs @@ -595,6 +595,7 @@ namespace Tango.PPC.Jobs.ViewModels Job.LastUpdated = DateTime.UtcNow; Job.IsSynchronized = false; Job.JobStatus = BL.Enumerations.JobStatuses.Draft; + Job.MarkModified(_db); await _db.SaveChangesAsync(); _current_job_string = Job.ToJobFileWhenLoaded().ToString(); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs index 02099e659..cfe0a03a0 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs @@ -8,4 +8,4 @@ using System.Windows; // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Tango PPC Application")] -[assembly: AssemblyVersion("1.0.50.0")] +[assembly: AssemblyVersion("1.1.0.0")] diff --git a/Software/Visual_Studio/Tango.BL/ObservableEntity.cs b/Software/Visual_Studio/Tango.BL/ObservableEntity.cs index e9bb711da..4f03263d9 100644 --- a/Software/Visual_Studio/Tango.BL/ObservableEntity.cs +++ b/Software/Visual_Studio/Tango.BL/ObservableEntity.cs @@ -154,6 +154,15 @@ namespace Tango.BL #region Public Methods + /// + /// Marks this entity as modified so all properties are saved. + /// + /// The context. + public virtual void MarkModified(ObservablesContext context) + { + context.Entry(this).State = EntityState.Modified; + } + /// /// Saves the changes on this entity to database. /// @@ -336,7 +345,7 @@ namespace Tango.BL /// The context. public virtual void Delete(ObservablesContext context) { - + } #endregion diff --git a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/ProvisionMachine.xml b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/ProvisionMachine.xml index c36c6a9b7..3f61fe617 100644 Binary files a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/ProvisionMachine.xml and b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/ProvisionMachine.xml differ -- cgit v1.3.1 From bdf56799cd6c4c42ec7a8dc36f56ddd17a5feeab Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Tue, 17 Dec 2019 00:02:49 +0200 Subject: Added SOURCE to JOB. Added IS_SYNCHRONIZED to TANGO_UPDATE. Added OfflineUpdates to Synchronization. Added TangoUpdates on PPC side. --- Software/DB/PPC/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/PPC/Tango_log.ldf | Bin 53673984 -> 53673984 bytes Software/DB/TCC/TCC.mdf | Bin 8388608 -> 8388608 bytes Software/DB/TCC/TCC_log.ldf | Bin 8388608 -> 8388608 bytes Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../ViewModels/MainViewVM.cs | 3 + .../Tango.PPC.Jobs/ViewModels/JobsViewVM.cs | 2 + .../MachineSetup/MachineSetupManager.cs | 27 +++ .../MachineUpdate/MachineUpdateManager.cs | 181 ++++++++++++++++++--- .../PPC/Tango.PPC.Common/Publish/PublishInfo.cs | 16 ++ .../DefaultMachineDataSynchronizer.cs | 33 ++++ .../Tango.PPC.Common/Web/CheckForUpdateResponse.cs | 1 + .../Tango.PPC.Common/Web/DownloadUpdateResponse.cs | 2 + .../Tango.PPC.Common/Web/MachineSetupResponse.cs | 2 + .../Web/UploadMachineDataRequest.cs | 2 + .../Web/UploadMachineDataResponse.cs | 2 + Software/Visual_Studio/Tango.BL/DTO/JobDTOBase.cs | 8 + .../Tango.BL/DTO/TangoUpdateDTOBase.cs | 8 + Software/Visual_Studio/Tango.BL/Entities/Job.cs | 11 ++ .../Visual_Studio/Tango.BL/Entities/JobBase.cs | 39 +++++ .../Visual_Studio/Tango.BL/Entities/TangoUpdate.cs | 22 ++- .../Tango.BL/Entities/TangoUpdateBase.cs | 38 +++++ .../Tango.BL/Enumerations/JobSource.cs | 20 +++ .../Tango.BL/Enumerations/TangoUpdateStatuses.cs | 7 + Software/Visual_Studio/Tango.BL/Tango.BL.csproj | 3 +- Software/Visual_Studio/Tango.DAL.Remote/DB/JOB.cs | 1 + .../Tango.DAL.Remote/DB/RemoteADO.edmx | 6 + .../Tango.DAL.Remote/DB/RemoteADO.edmx.diagram | 154 +++++++++--------- .../Tango.DAL.Remote/DB/TANGO_UPDATES.cs | 1 + .../Controllers/PPCController.cs | 31 ++++ 31 files changed, 518 insertions(+), 102 deletions(-) create mode 100644 Software/Visual_Studio/Tango.BL/Enumerations/JobSource.cs (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer') diff --git a/Software/DB/PPC/Tango.mdf b/Software/DB/PPC/Tango.mdf index 8bce1236f..8ad9bc103 100644 Binary files a/Software/DB/PPC/Tango.mdf and b/Software/DB/PPC/Tango.mdf differ diff --git a/Software/DB/PPC/Tango_log.ldf b/Software/DB/PPC/Tango_log.ldf index 9e9f5d60a..9bce4a9c4 100644 Binary files a/Software/DB/PPC/Tango_log.ldf and b/Software/DB/PPC/Tango_log.ldf differ diff --git a/Software/DB/TCC/TCC.mdf b/Software/DB/TCC/TCC.mdf index f77c2e733..3540a7786 100644 Binary files a/Software/DB/TCC/TCC.mdf and b/Software/DB/TCC/TCC.mdf differ diff --git a/Software/DB/TCC/TCC_log.ldf b/Software/DB/TCC/TCC_log.ldf index 048d3ccb0..94b99ac61 100644 Binary files a/Software/DB/TCC/TCC_log.ldf and b/Software/DB/TCC/TCC_log.ldf differ diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 6af55afc8..e70e0e6e3 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 33e76f9de..e65b718bb 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index 4f517165b..71cbd9ffe 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -50,6 +50,7 @@ using Tango.Core.ExtensionMethods; using Tango.ColorConversion; using Tango.PMR.Exports; using Microsoft.WindowsAPICodePack.Dialogs; +using Tango.BL.Enumerations; namespace Tango.MachineStudio.Developer.ViewModels { @@ -2211,6 +2212,8 @@ namespace Tango.MachineStudio.Developer.ViewModels var settings = SettingsManager.Default.GetOrCreate(); Job newJob = new Job(); + newJob.LastUpdated = DateTime.UtcNow; + newJob.JobSource = JobSource.Remote; newJob.Name = jobName; newJob.CreationDate = DateTime.UtcNow; newJob.UserGuid = AuthenticationProvider.CurrentUser.Guid; diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs index 785472d0d..1eb7e1f04 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs @@ -500,6 +500,8 @@ namespace Tango.PPC.Jobs.ViewModels settings.Save(); Job job = new Job(); + job.LastUpdated = DateTime.UtcNow; + job.JobSource = JobSource.Local; job.Name = "untitled"; job.NumberOfHeads = 1; job.NumberOfUnits = 1; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs index dfa9b833b..582eec83b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs @@ -11,6 +11,8 @@ using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; using Tango.Core; using Tango.Core.DB; using Tango.Core.ExtensionMethods; @@ -29,6 +31,7 @@ using Tango.Settings; using Tango.SharedUI.Helpers; using Tango.SQLExaminer; using Tango.Transport.Web; +using System.Data.Entity; namespace Tango.PPC.Common.MachineSetup { @@ -45,6 +48,7 @@ namespace Tango.PPC.Common.MachineSetup private PPCWebClient _client; private List _logs; private bool _isUpdating; + private DateTime _setupStartDate; #region Events @@ -164,6 +168,28 @@ namespace Tango.PPC.Common.MachineSetup } } + if (response != null) + { + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + TangoUpdate update = new TangoUpdate(); + update.ApplicationVersion = response.Version; + update.FirmwareVersion = response.FirmwareVersion; + update.MachineGuid = (await db.Machines.FirstAsync()).Guid; + update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.SetupCompleted; + update.StartDate = _setupStartDate; + update.EndDate = DateTime.UtcNow; + await db.SaveChangesAsync(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving tango setup information to database."); + } + } + _isUpdating = false; } @@ -191,6 +217,7 @@ namespace Tango.PPC.Common.MachineSetup TaskCompletionSource result = new TaskCompletionSource(); MachineSetupResponse setup_response = null; + _setupStartDate = DateTime.UtcNow; try { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs index 088e80f61..666b6813c 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs @@ -10,6 +10,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Tango.BL; +using Tango.BL.Entities; using Tango.Core; using Tango.Core.DB; using Tango.Core.ExtensionMethods; @@ -29,6 +30,7 @@ using Tango.Settings; using Tango.SharedUI.Helpers; using Tango.SQLExaminer; using Tango.Transport.Web; +using System.Data.Entity; namespace Tango.PPC.Common.MachineUpdate { @@ -42,6 +44,7 @@ namespace Tango.PPC.Common.MachineUpdate private System.Timers.Timer _checkForUpdateTimer; private bool _isUpdating; private PPCSettings _settings; + private DateTime _updateStartDate; #region Events @@ -140,7 +143,7 @@ namespace Tango.PPC.Common.MachineUpdate }); } - private async void OnFailed(Exception ex, TaskCompletionSource completionSource, DownloadUpdateResponse response, bool performDatabaseRollback, String dbBackupFile, String backupsFolder, String tempDbName, Tango.Core.DataSource localDataSource, String tempUpdatePackageFolder = null) + private async void OnFailed(Exception ex, TaskCompletionSource completionSource, DownloadUpdateResponse response, bool performDatabaseRollback, String dbBackupFile, String backupsFolder, String tempDbName, Tango.Core.DataSource localDataSource, String tempUpdatePackageFolder = null, PublishInfo tupPublishInfo = null) { LogManager.Log(ex, "An error occurred in machine update."); @@ -217,6 +220,8 @@ namespace Tango.PPC.Common.MachineUpdate completionSource.SetException(ex); + String logs = GetLogsStringAndClear(); + if (response != null) { try @@ -226,19 +231,65 @@ namespace Tango.PPC.Common.MachineUpdate Token = response.NotifyCompletedToken, Status = BL.Enumerations.TangoUpdateStatuses.UpdateFailed, FailedReason = ex.FlattenMessage(), - FailedLog = GetLogsStringAndClear(), + FailedLog = logs, }); } catch (Exception xx) { LogManager.Log(xx, "Error notifying update failed."); } + + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + TangoUpdate update = new TangoUpdate(); + update.ApplicationVersion = response.Version; + update.FirmwareVersion = response.FirmwareVersion; + update.MachineGuid = _machineProvider.Machine.Guid; + update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.UpdateFailed; + update.StartDate = _updateStartDate; + update.EndDate = DateTime.UtcNow; + update.FailedReason = ex.FlattenMessage(); + update.FailedLog = logs; + await db.SaveChangesAsync(); + } + } + catch (Exception xxx) + { + LogManager.Log(xxx, "Error saving tango update information to database."); + } + } + + + if (tupPublishInfo != null) + { + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + TangoUpdate update = new TangoUpdate(); + update.ApplicationVersion = tupPublishInfo.ApplicationVersion; + update.FirmwareVersion = tupPublishInfo.GetFirmwareVersion(); + update.MachineGuid = _machineProvider.Machine.Guid; + update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.OfflineUpdateFailed; + update.StartDate = _updateStartDate; + update.EndDate = DateTime.UtcNow; + update.FailedReason = ex.FlattenMessage(); + update.FailedLog = logs; + await db.SaveChangesAsync(); + } + } + catch (Exception xxx) + { + LogManager.Log(xxx, "Error saving tango offline update information to database."); + } } _isUpdating = false; } - private async void OnCompleted(MachineUpdateResult result, TaskCompletionSource completionSource, DownloadUpdateResponse response, String tempDbName, String backupsFolder, Core.DataSource localDataSource) + private async void OnCompleted(MachineUpdateResult result, TaskCompletionSource completionSource, DownloadUpdateResponse response, String tempDbName, String backupsFolder, Core.DataSource localDataSource, PublishInfo tupPublishInfo = null) { await Task.Factory.StartNew(() => { @@ -299,26 +350,47 @@ namespace Tango.PPC.Common.MachineUpdate { LogManager.Log(ex, "Error notifying update completed."); } + + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + TangoUpdate update = new TangoUpdate(); + update.ApplicationVersion = response.Version; + update.FirmwareVersion = response.FirmwareVersion; + update.MachineGuid = (await db.Machines.FirstAsync()).Guid; + update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.UpdateCompleted; + update.StartDate = _updateStartDate; + update.EndDate = DateTime.UtcNow; + await db.SaveChangesAsync(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving tango update information to database."); + } } - _isUpdating = false; - } - private void OnCompleted(UpdateDBResponse response) - { - if (response != null) + if (tupPublishInfo != null) { try { - var r = _client.NotifyUpdateCompleted(new MachineUpdateCompletedRequest() + using (ObservablesContext db = ObservablesContext.CreateDefault()) { - Token = response.NotifyCompletedToken, - Status = BL.Enumerations.TangoUpdateStatuses.DatabaseCompleted, - }).Result; + TangoUpdate update = new TangoUpdate(); + update.ApplicationVersion = tupPublishInfo.ApplicationVersion; + update.FirmwareVersion = tupPublishInfo.GetFirmwareVersion(); + update.MachineGuid = _machineProvider.Machine.Guid; + update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.OfflineUpdateCompleted; + update.StartDate = _updateStartDate; + update.EndDate = DateTime.UtcNow; + await db.SaveChangesAsync(); + } } - catch (Exception ex) + catch (Exception xxx) { - LogManager.Log(ex, "Error notifying database completed."); + LogManager.Log(xxx, "Error saving tango offline update information to database."); } } @@ -357,6 +429,8 @@ namespace Tango.PPC.Common.MachineUpdate } } + String logs = GetLogsStringAndClear(); + if (response != null) { try @@ -366,13 +440,74 @@ namespace Tango.PPC.Common.MachineUpdate Token = response.NotifyCompletedToken, Status = BL.Enumerations.TangoUpdateStatuses.DatabaseFailed, FailedReason = ex.FlattenMessage(), - FailedLog = GetLogsStringAndClear(), + FailedLog = logs, }).Result; } catch (Exception xx) { LogManager.Log(xx, "Error notifying database failed."); } + + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + TangoUpdate update = new TangoUpdate(); + update.ApplicationVersion = _app_manager.Version.ToString(); + update.FirmwareVersion = _app_manager.FirmwareVersion.ToString(); + update.MachineGuid = _machineProvider.Machine.Guid; + update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.DatabaseFailed; + update.StartDate = _updateStartDate; + update.EndDate = DateTime.UtcNow; + update.FailedReason = ex.FlattenMessage(); + update.FailedLog = logs; + db.SaveChanges(); + } + } + catch (Exception exx) + { + LogManager.Log(exx, "Error saving database update information to database."); + } + } + + _isUpdating = false; + } + + private void OnCompleted(UpdateDBResponse response) + { + if (response != null) + { + try + { + var r = _client.NotifyUpdateCompleted(new MachineUpdateCompletedRequest() + { + Token = response.NotifyCompletedToken, + Status = BL.Enumerations.TangoUpdateStatuses.DatabaseCompleted, + }).Result; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error notifying database completed."); + } + + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + TangoUpdate update = new TangoUpdate(); + update.ApplicationVersion = _app_manager.Version.ToString(); + update.FirmwareVersion = _app_manager.FirmwareVersion.ToString(); + update.MachineGuid = _machineProvider.Machine.Guid; + update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.DatabaseCompleted; + update.StartDate = _updateStartDate; + update.EndDate = DateTime.UtcNow; + db.SaveChanges(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving database update information to database."); + } } _isUpdating = false; @@ -404,6 +539,7 @@ namespace Tango.PPC.Common.MachineUpdate /// Database tango does not exists. public async Task Update(bool setupFirmware, bool setupFPGA) { + _updateStartDate = DateTime.UtcNow; _logs.Clear(); TaskCompletionSource result = new TaskCompletionSource(); @@ -739,6 +875,7 @@ namespace Tango.PPC.Common.MachineUpdate /// public Task UpdateDB(DbCompareResult dbCompareResult, String serialNumber) { + _updateStartDate = DateTime.UtcNow; _logs.Clear(); return Task.Factory.StartNew(() => @@ -975,6 +1112,7 @@ namespace Tango.PPC.Common.MachineUpdate /// public async Task UpdateFromTUP(string fileName, bool setupFirmware, bool setupFPGA) { + _updateStartDate = DateTime.UtcNow; _logs.Clear(); TaskCompletionSource result = new TaskCompletionSource(); @@ -986,6 +1124,7 @@ namespace Tango.PPC.Common.MachineUpdate String tempDbFileName = tempDbName + ".bak"; String backupsFolder = "C:\\Backups"; bool replaceBinaries = false; + PublishInfo publishInfo = null; String serialNumber = _machineProvider.Machine.SerialNumber; @@ -1035,7 +1174,7 @@ namespace Tango.PPC.Common.MachineUpdate //Extracting publish info UpdateProgress("Exploring package", "Verifying..."); - PublishInfo publishInfo = PublishInfo.FromJson(File.ReadAllText(Path.Combine(_newPackageTempFolder, "version.json"))); + publishInfo = PublishInfo.FromJson(File.ReadAllText(Path.Combine(_newPackageTempFolder, "version.json"))); if (!publishInfo.IsMachineTupPackage) { @@ -1214,7 +1353,7 @@ namespace Tango.PPC.Common.MachineUpdate handler.Failed += (_, ex) => { stream.Dispose(); - OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder); + OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder, publishInfo); }; handler.Completed += (_, __) => { @@ -1224,12 +1363,12 @@ namespace Tango.PPC.Common.MachineUpdate { UpdatePackagePath = _newPackageTempFolder, RequiresBinariesUpdate = replaceBinaries, - }, result, null, tempDbName, backupsFolder, localDataSource); + }, result, null, tempDbName, backupsFolder, localDataSource, publishInfo); }; handler.Canceled += (_, __) => { stream.Dispose(); - OnFailed(new Exception("The operation has been canceled."), result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder); + OnFailed(new Exception("The operation has been canceled."), result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder, publishInfo); }; handler.Progress += (_, e) => { @@ -1242,12 +1381,12 @@ namespace Tango.PPC.Common.MachineUpdate { UpdatePackagePath = _newPackageTempFolder, RequiresBinariesUpdate = replaceBinaries, - }, result, null, tempDbName, backupsFolder, localDataSource); + }, result, null, tempDbName, backupsFolder, localDataSource, publishInfo); } } catch (Exception ex) { - OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder); + OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder, publishInfo); } return await result.Task; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs index df5690a05..1bbdb80d0 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs @@ -32,5 +32,21 @@ namespace Tango.PPC.Common.Publish { return JsonConvert.DeserializeObject(json); } + + public String GetFirmwareVersion() + { + Version version = new Version("1.0.0.0"); + + var s = Firmware.FileDescriptors.FirstOrDefault(x => x.Destination == VersionFileDestination.Mcu); + if (s != null) + { + if (Version.TryParse(s.Version,out version)) + { + return version.ToString(); + } + } + + return version.ToString(); + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs index 8260eb4b3..22c3dbe20 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs @@ -40,6 +40,7 @@ namespace Tango.PPC.Common.Synchronization public int MaxJobs { get; set; } public int MaxJobRuns { get; set; } public int MaxMachinesEvents { get; set; } + public int MaxOfflineUpdates { get; set; } private SynchronizationStatus _currentStatus; public SynchronizationStatus CurrentStatus @@ -80,6 +81,7 @@ namespace Tango.PPC.Common.Synchronization MaxJobs = 10; MaxJobRuns = 100; MaxMachinesEvents = 100; + MaxOfflineUpdates = 50; var settings = SettingsManager.Default.GetOrCreate(); Interval = settings.SynchronizationInterval; @@ -190,6 +192,21 @@ namespace Tango.PPC.Common.Synchronization request.MachineEvents.Add(dto); } } + + if (syncDiagnostics) + { + LogManager.Log("Checking Offline Updates..."); + + var tangoUpdates = await db.TangoUpdates.Where(x => !x.IsSynchronized && (x.Status == (int)TangoUpdateStatuses.OfflineUpdateCompleted || x.Status == (int)TangoUpdateStatuses.OfflineUpdateFailed)).Take(MaxOfflineUpdates).OrderByDescending(x => x.LastUpdated).ToListAsync(); + List dtos = new List(); + + foreach (var tangoUpdate in tangoUpdates) + { + tangoUpdate.IsSynchronized = true; + var dto = TangoUpdateDTO.FromObservable(tangoUpdate); + request.OfflineUpdates.Add(dto); + } + } } return request; @@ -247,6 +264,22 @@ namespace Tango.PPC.Common.Synchronization } } + //Finalize tango updates + foreach (var tangoUpdate in request.OfflineUpdates) + { + var failedTangoUpdate = response.FailedOfflineUpdates.SingleOrDefault(x => x.Guid == tangoUpdate.Guid); + + if (failedTangoUpdate == null) + { + var dbTangoUpdate = await db.TangoUpdates.SingleOrDefaultAsync(x => x.Guid == tangoUpdate.Guid); + dbTangoUpdate.IsSynchronized = true; + } + else + { + LogManager.Log($"Synchronization Error - TangoUpdate '{tangoUpdate.ID}' cannot be stored on the server due to the following reason:\n{failedTangoUpdate.Reason}", LogCategory.Error); + } + } + await db.SaveChangesAsync(); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/CheckForUpdateResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/CheckForUpdateResponse.cs index 63d870834..a857a20a1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/CheckForUpdateResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/CheckForUpdateResponse.cs @@ -12,6 +12,7 @@ namespace Tango.PPC.Common.Web public bool IsUpdateAvailable { get; set; } public bool IsDatabaseUpdateAvailable { get; set; } public String Version { get; set; } + public String FirmwareVersion { get; set; } public bool SetupFirmware { get; set; } public bool SetupFPGA { get; set; } public UpdateDBResponse UpdateDBResponse { get; set; } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadUpdateResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadUpdateResponse.cs index b092aedbe..2fc7e4810 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadUpdateResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadUpdateResponse.cs @@ -14,6 +14,8 @@ namespace Tango.PPC.Common.Web public String Version { get; set; } + public String FirmwareVersion { get; set; } + public String BlobAddress { get; set; } public String CdnAddress { get; set; } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupResponse.cs index 714a413ab..a642eddf2 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupResponse.cs @@ -14,6 +14,8 @@ namespace Tango.PPC.Common.Web public String Version { get; set; } + public String FirmwareVersion { get; set; } + public String BlobAddress { get; set; } public String CdnAddress { get; set; } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs index dc0b05988..d7475819c 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs @@ -14,6 +14,7 @@ namespace Tango.PPC.Common.Web public List Jobs { get; set; } public List JobRuns { get; set; } public List MachineEvents { get; set; } + public List OfflineUpdates { get; set; } public String ApplicationVersion { get; set; } public String FirmwareVersion { get; set; } @@ -22,6 +23,7 @@ namespace Tango.PPC.Common.Web Jobs = new List(); JobRuns = new List(); MachineEvents = new List(); + OfflineUpdates = new List(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs index e4dda4013..0119c07b6 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs @@ -14,6 +14,7 @@ namespace Tango.PPC.Common.Web public List FailedJobs { get; set; } public List FailedJobRuns { get; set; } public List FailedMachineEvents { get; set; } + public List FailedOfflineUpdates { get; set; } public String NotifyCompletedToken { get; set; } public UploadMachineDataResponse() @@ -21,6 +22,7 @@ namespace Tango.PPC.Common.Web FailedJobs = new List(); FailedJobRuns = new List(); FailedMachineEvents = new List(); + FailedOfflineUpdates = new List(); } } } diff --git a/Software/Visual_Studio/Tango.BL/DTO/JobDTOBase.cs b/Software/Visual_Studio/Tango.BL/DTO/JobDTOBase.cs index c3c418f1f..2960381fc 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/JobDTOBase.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/JobDTOBase.cs @@ -282,5 +282,13 @@ namespace Tango.BL.DTO get; set; } + /// + /// source + /// + public Int32 Source + { + get; set; + } + } } diff --git a/Software/Visual_Studio/Tango.BL/DTO/TangoUpdateDTOBase.cs b/Software/Visual_Studio/Tango.BL/DTO/TangoUpdateDTOBase.cs index 5eb16841c..8e87df812 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/TangoUpdateDTOBase.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/TangoUpdateDTOBase.cs @@ -85,5 +85,13 @@ namespace Tango.BL.DTO get; set; } + /// + /// is synchronized + /// + public Boolean IsSynchronized + { + get; set; + } + } } diff --git a/Software/Visual_Studio/Tango.BL/Entities/Job.cs b/Software/Visual_Studio/Tango.BL/Entities/Job.cs index d2a416271..c4847c5e9 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/Job.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/Job.cs @@ -100,6 +100,17 @@ namespace Tango.BL.Entities set { Status = value.ToInt32(); RaisePropertyChangedAuto(); } } + /// + /// Gets or sets the origin of the job. + /// + [NotMapped] + [JsonIgnore] + public JobSource JobSource + { + get { return (JobSource)Source; } + set { Source = value.ToInt32(); RaisePropertyChangedAuto(); } + } + /// /// Gets or sets the job property as enum instead of int. /// diff --git a/Software/Visual_Studio/Tango.BL/Entities/JobBase.cs b/Software/Visual_Studio/Tango.BL/Entities/JobBase.cs index 599e379a8..45e0e3437 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/JobBase.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/JobBase.cs @@ -83,6 +83,8 @@ namespace Tango.BL.Entities public event EventHandler IsSynchronizedChanged; + public event EventHandler SourceChanged; + public event EventHandler ColorCatalogChanged; public event EventHandler ColorSpaceChanged; @@ -1022,6 +1024,34 @@ namespace Tango.BL.Entities } } + protected Int32 _source; + + /// + /// 0 = Remote + /// 1 = Local + /// + + [Column("SOURCE")] + + public Int32 Source + { + get + { + return _source; + } + + set + { + if (_source != value) + { + _source = value; + + OnSourceChanged(value); + + } + } + } + protected ColorCatalog _colorcatalog; /// @@ -1537,6 +1567,15 @@ namespace Tango.BL.Entities RaisePropertyChanged(nameof(IsSynchronized)); } + /// + /// Called when the Source has changed. + /// + protected virtual void OnSourceChanged(Int32 source) + { + SourceChanged?.Invoke(this, source); + RaisePropertyChanged(nameof(Source)); + } + /// /// Called when the ColorCatalog has changed. /// diff --git a/Software/Visual_Studio/Tango.BL/Entities/TangoUpdate.cs b/Software/Visual_Studio/Tango.BL/Entities/TangoUpdate.cs index 4ab67b7c5..f290618cb 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/TangoUpdate.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/TangoUpdate.cs @@ -78,6 +78,19 @@ namespace Tango.BL.Entities } } + [NotMapped] + [JsonIgnore] + public bool IsOfflineUpdate + { + get + { + return + UpdateStatus == TangoUpdateStatuses.OfflineUpdateStarted || + UpdateStatus == TangoUpdateStatuses.OfflineUpdateCompleted || + UpdateStatus == TangoUpdateStatuses.OfflineUpdateFailed; + } + } + [NotMapped] [JsonIgnore] public bool IsStarted @@ -88,7 +101,8 @@ namespace Tango.BL.Entities UpdateStatus == TangoUpdateStatuses.SetupStarted || UpdateStatus == TangoUpdateStatuses.UpdateStarted || UpdateStatus == TangoUpdateStatuses.DatabaseStarted || - UpdateStatus == TangoUpdateStatuses.SynchronizationStarted; + UpdateStatus == TangoUpdateStatuses.SynchronizationStarted || + UpdateStatus == TangoUpdateStatuses.OfflineUpdateStarted; } } @@ -102,7 +116,8 @@ namespace Tango.BL.Entities UpdateStatus == TangoUpdateStatuses.SetupCompleted || UpdateStatus == TangoUpdateStatuses.UpdateCompleted || UpdateStatus == TangoUpdateStatuses.DatabaseCompleted || - UpdateStatus == TangoUpdateStatuses.SynchronizationCompleted; + UpdateStatus == TangoUpdateStatuses.SynchronizationCompleted || + UpdateStatus == TangoUpdateStatuses.OfflineUpdateCompleted; } } @@ -116,7 +131,8 @@ namespace Tango.BL.Entities UpdateStatus == TangoUpdateStatuses.SetupFailed || UpdateStatus == TangoUpdateStatuses.UpdateFailed || UpdateStatus == TangoUpdateStatuses.DatabaseFailed || - UpdateStatus == TangoUpdateStatuses.SynchronizationFailed; + UpdateStatus == TangoUpdateStatuses.SynchronizationFailed || + UpdateStatus == TangoUpdateStatuses.OfflineUpdateFailed; } } diff --git a/Software/Visual_Studio/Tango.BL/Entities/TangoUpdateBase.cs b/Software/Visual_Studio/Tango.BL/Entities/TangoUpdateBase.cs index 9f75b0021..57475977b 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/TangoUpdateBase.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/TangoUpdateBase.cs @@ -40,6 +40,8 @@ namespace Tango.BL.Entities public event EventHandler> EndDateChanged; + public event EventHandler IsSynchronizedChanged; + protected String _applicationversion; /// @@ -254,6 +256,33 @@ namespace Tango.BL.Entities } } + protected Boolean _issynchronized; + + /// + /// Gets or sets the tangoupdatebase is synchronized. + /// + + [Column("IS_SYNCHRONIZED")] + + public Boolean IsSynchronized + { + get + { + return _issynchronized; + } + + set + { + if (_issynchronized != value) + { + _issynchronized = value; + + OnIsSynchronizedChanged(value); + + } + } + } + /// /// Called when the ApplicationVersion has changed. /// @@ -317,6 +346,15 @@ namespace Tango.BL.Entities RaisePropertyChanged(nameof(EndDate)); } + /// + /// Called when the IsSynchronized has changed. + /// + protected virtual void OnIsSynchronizedChanged(Boolean issynchronized) + { + IsSynchronizedChanged?.Invoke(this, issynchronized); + RaisePropertyChanged(nameof(IsSynchronized)); + } + /// /// Initializes a new instance of the class. /// diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/JobSource.cs b/Software/Visual_Studio/Tango.BL/Enumerations/JobSource.cs new file mode 100644 index 000000000..2327f5b66 --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/Enumerations/JobSource.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.BL.Enumerations +{ + public enum JobSource + { + /// + /// The job was originated from an application that is working directly against the main db (Machine Studio etc.) + /// + Remote = 0, + /// + /// The job was originated from an application that is working against a private local db (PPC etc.). + /// + Local = 1, + } +} diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/TangoUpdateStatuses.cs b/Software/Visual_Studio/Tango.BL/Enumerations/TangoUpdateStatuses.cs index 855d8b29b..5fdf24e22 100644 --- a/Software/Visual_Studio/Tango.BL/Enumerations/TangoUpdateStatuses.cs +++ b/Software/Visual_Studio/Tango.BL/Enumerations/TangoUpdateStatuses.cs @@ -36,5 +36,12 @@ namespace Tango.BL.Enumerations SynchronizationCompleted = 301, [Description("Synchronization failed")] SynchronizationFailed = 302, + + [Description("Offline update started but did not complete")] + OfflineUpdateStarted = 400, + [Description("Offline update completed successfully")] + OfflineUpdateCompleted = 401, + [Description("Offline update failed")] + OfflineUpdateFailed = 402, } } diff --git a/Software/Visual_Studio/Tango.BL/Tango.BL.csproj b/Software/Visual_Studio/Tango.BL/Tango.BL.csproj index 99855796d..6111a1a35 100644 --- a/Software/Visual_Studio/Tango.BL/Tango.BL.csproj +++ b/Software/Visual_Studio/Tango.BL/Tango.BL.csproj @@ -370,6 +370,7 @@ + @@ -579,7 +580,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/JOB.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/JOB.cs index 923cceacf..f30b43230 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/JOB.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/JOB.cs @@ -57,6 +57,7 @@ namespace Tango.DAL.Remote.DB public int EDITING_STATE { get; set; } public double LENGTH_PERCENTAGE_FACTOR { get; set; } public bool IS_SYNCHRONIZED { get; set; } + public int SOURCE { get; set; } public virtual COLOR_CATALOGS COLOR_CATALOGS { get; set; } public virtual COLOR_SPACES COLOR_SPACES { get; set; } diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx index 83e251c1e..f8f4f9505 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx @@ -637,6 +637,7 @@ + @@ -1015,6 +1016,7 @@ + @@ -3734,6 +3736,7 @@ + @@ -4172,6 +4175,7 @@ + @@ -6020,6 +6024,7 @@ + @@ -6442,6 +6447,7 @@ + diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram index 77b14d7c2..f13138208 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram @@ -5,83 +5,83 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/TANGO_UPDATES.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/TANGO_UPDATES.cs index d91e9920c..b591f562c 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/TANGO_UPDATES.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/TANGO_UPDATES.cs @@ -25,5 +25,6 @@ namespace Tango.DAL.Remote.DB public string FAILED_LOG { get; set; } public System.DateTime START_DATE { get; set; } public Nullable END_DATE { get; set; } + public bool IS_SYNCHRONIZED { get; set; } } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 77b3a180f..4bde9148a 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -107,6 +107,7 @@ namespace Tango.MachineService.Controllers var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); response.Version = latest_machine_version.Version; + response.FirmwareVersion = latest_machine_version.FirmwareVersion; var manager = new BlobStorageManager(); var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER); @@ -195,6 +196,7 @@ namespace Tango.MachineService.Controllers var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); response.Version = latest_machine_version.Version; + response.FirmwareVersion = latest_machine_version.FirmwareVersion; var manager = new BlobStorageManager(); var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER); @@ -313,6 +315,7 @@ namespace Tango.MachineService.Controllers } response.Version = latest_machine_version.Version; + response.FirmwareVersion = latest_machine_version.FirmwareVersion; //Compare database @@ -588,6 +591,34 @@ namespace Tango.MachineService.Controllers } } } + + //Insert TangoUpdates. + foreach (var dto in request.OfflineUpdates) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + try + { + var update = dto.ToObservable(); + update.ID = 0; + update.IsSynchronized = true; + + if (db.TangoUpdates.SingleOrDefault(x => x.Guid == update.Guid) == null) + { + db.TangoUpdates.Add(update); + db.SaveChanges(); + } + } + catch (Exception ex) + { + response.FailedOfflineUpdates.Add(new SynchronizationFailedEntity() + { + Guid = dto.Guid, + Reason = ex.FlattenMessage(), + }); + } + } + } } catch (Exception ex) { -- cgit v1.3.1 From b98fb311b28c8e36b7b44775c641083d501ef92a Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Tue, 17 Dec 2019 12:57:27 +0200 Subject: Add JobSource handling on PPC and Machine Studio Job Import. --- .../Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs | 1 + .../Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs | 1 + 2 files changed, 2 insertions(+) (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index 71cbd9ffe..ceb093be2 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -2606,6 +2606,7 @@ namespace Tango.MachineStudio.Developer.ViewModels var bytes = File.ReadAllBytes(file); var jobFile = JobFile.Parser.ParseFrom(bytes); var job = await Job.FromJobFile(jobFile, SelectedMachine.Guid, AuthenticationProvider.CurrentUser.Guid); + job.JobSource = JobSource.Remote; _machineDbContext.Jobs.Add(job); } diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs index 1eb7e1f04..109e3e27a 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs @@ -809,6 +809,7 @@ namespace Tango.PPC.Jobs.ViewModels { JobFile jFile = JobFile.Parser.ParseFrom(File.ReadAllBytes(jobFile.Path)); var job = await Job.FromJobFile(jFile, MachineProvider.Machine.Guid, AuthenticationProvider.CurrentUser.Guid); + job.JobSource = JobSource.Local; jobContext.Jobs.Add(job); await jobContext.SaveChangesAsync(); LoadJobs(() => -- cgit v1.3.1 From 74d6b86d46819376f0389d6fd4055e40e4e01598 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Tue, 17 Dec 2019 20:04:34 +0200 Subject: Started working on Action Logs !!! --- Software/DB/PPC/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/PPC/Tango_log.ldf | Bin 53673984 -> 53673984 bytes Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../ViewModels/MainViewVM.cs | 12 +- .../Tango.MachineStudio.UI/ViewModelLocator.cs | 3 + .../Tango.BL/ActionLogs/BasicActionLogComparer.cs | 181 +++++++++++++ .../Tango.BL/ActionLogs/DefaultActionLogManager.cs | 122 +++++++++ .../Tango.BL/ActionLogs/IActionLogComparable.cs | 21 ++ .../Tango.BL/ActionLogs/IActionLogManager.cs | 23 ++ .../Visual_Studio/Tango.BL/DTO/ActionLogDTO.cs | 14 + .../Visual_Studio/Tango.BL/DTO/ActionLogDTOBase.cs | 73 ++++++ .../Visual_Studio/Tango.BL/DTO/BrushStopDTO.cs | 5 +- Software/Visual_Studio/Tango.BL/DTO/JobDTO.cs | 7 + .../Visual_Studio/Tango.BL/Entities/ActionLog.cs | 60 +++++ .../Tango.BL/Entities/ActionLogBase.cs | 282 +++++++++++++++++++++ Software/Visual_Studio/Tango.BL/Entities/Job.cs | 2 + .../Visual_Studio/Tango.BL/Entities/UserBase.cs | 38 +++ .../Tango.BL/Enumerations/ActionLogType.cs | 90 +++++++ .../Visual_Studio/Tango.BL/ObservableEntity.cs | 28 +- .../Visual_Studio/Tango.BL/ObservableEntityDTO.cs | 24 +- .../Visual_Studio/Tango.BL/ObservablesContext.cs | 8 + .../ObservablesEntitiesAdapterExtension.cs | 38 +++ .../ObservablesStaticCollectionsExtension.cs | 38 +++ Software/Visual_Studio/Tango.BL/Tango.BL.csproj | 12 +- .../Tango.BL/ValueObjects/ActionLogDifference.cs | 16 ++ .../Tango.DAL.Remote/DB/ACTION_LOGS.cs | 29 +++ .../Tango.DAL.Remote/DB/RemoteADO.Context.cs | 1 + .../Tango.DAL.Remote/DB/RemoteADO.Designer.cs | 2 +- .../Tango.DAL.Remote/DB/RemoteADO.edmx | 79 ++++++ .../Tango.DAL.Remote/DB/RemoteADO.edmx.diagram | 156 ++++++------ Software/Visual_Studio/Tango.DAL.Remote/DB/USER.cs | 3 + .../Tango.DAL.Remote/Tango.DAL.Remote.csproj | 5 +- 33 files changed, 1288 insertions(+), 84 deletions(-) create mode 100644 Software/Visual_Studio/Tango.BL/ActionLogs/BasicActionLogComparer.cs create mode 100644 Software/Visual_Studio/Tango.BL/ActionLogs/DefaultActionLogManager.cs create mode 100644 Software/Visual_Studio/Tango.BL/ActionLogs/IActionLogComparable.cs create mode 100644 Software/Visual_Studio/Tango.BL/ActionLogs/IActionLogManager.cs create mode 100644 Software/Visual_Studio/Tango.BL/DTO/ActionLogDTO.cs create mode 100644 Software/Visual_Studio/Tango.BL/DTO/ActionLogDTOBase.cs create mode 100644 Software/Visual_Studio/Tango.BL/Entities/ActionLog.cs create mode 100644 Software/Visual_Studio/Tango.BL/Entities/ActionLogBase.cs create mode 100644 Software/Visual_Studio/Tango.BL/Enumerations/ActionLogType.cs create mode 100644 Software/Visual_Studio/Tango.BL/ValueObjects/ActionLogDifference.cs create mode 100644 Software/Visual_Studio/Tango.DAL.Remote/DB/ACTION_LOGS.cs (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer') diff --git a/Software/DB/PPC/Tango.mdf b/Software/DB/PPC/Tango.mdf index 41603a45f..4d696d2c1 100644 Binary files a/Software/DB/PPC/Tango.mdf and b/Software/DB/PPC/Tango.mdf differ diff --git a/Software/DB/PPC/Tango_log.ldf b/Software/DB/PPC/Tango_log.ldf index 12b0bd50c..9e60e0704 100644 Binary files a/Software/DB/PPC/Tango_log.ldf and b/Software/DB/PPC/Tango_log.ldf differ diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 5d5ff5ddb..a4bdfc14b 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 4ff9f3fd3..2fe319056 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index ceb093be2..d598e2458 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -51,6 +51,8 @@ using Tango.ColorConversion; using Tango.PMR.Exports; using Microsoft.WindowsAPICodePack.Dialogs; using Tango.BL.Enumerations; +using Tango.BL.DTO; +using Tango.BL.ActionLogs; namespace Tango.MachineStudio.Developer.ViewModels { @@ -86,6 +88,8 @@ namespace Tango.MachineStudio.Developer.ViewModels private TaskItem _preparingTaskItem; private IColorConverter _converter; private string _current_job_string; + private JobDTO _beforeSaveJobDTO; + private IActionLogManager _actionLogManager; #region Properties @@ -748,7 +752,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// /// The application manager. /// The notification provider. - public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, INavigationManager navigationManager, IAuthenticationProvider authentication, IEventLogger eventLogger, ISpeechProvider speech) + public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, INavigationManager navigationManager, IAuthenticationProvider authentication, IEventLogger eventLogger, ISpeechProvider speech, IActionLogManager actionLogManager) { _converter = new DefaultColorConverter(); @@ -757,6 +761,7 @@ namespace Tango.MachineStudio.Developer.ViewModels AuthenticationProvider = authentication; + _actionLogManager = actionLogManager; _notification = notificationProvider; _speech = speech; _navigation = navigation; @@ -1848,6 +1853,7 @@ namespace Tango.MachineStudio.Developer.ViewModels //_activeJobDbContext.IdsPacks.Where(x => x.ConfigurationGuid == ActiveJob.Machine.ConfigurationGuid).ToList(); + _beforeSaveJobDTO = JobDTO.FromObservable(ActiveJob); LogManager.Log("Setting selected segment..."); @@ -1921,6 +1927,10 @@ namespace Tango.MachineStudio.Developer.ViewModels ActiveJob.MarkModified(_activeJobDbContext); _activeJobDbContext.SaveChanges(); + var afterJobDTO = JobDTO.FromObservable(ActiveJob); + _actionLogManager.InsertLog(ActionLogType.JobSaved, AuthenticationProvider.CurrentUser, _beforeSaveJobDTO.Name, _beforeSaveJobDTO, afterJobDTO, "Job saved from research module in Machine Studio.").GetAwaiter().GetResult(); + _beforeSaveJobDTO = afterJobDTO; + _machineDbContext.Entry(SelectedMachineJob).Reload(); _machineDbContext.Entry(SelectedMachineJob).Collection(x => x.Segments).Load(); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs index 25843d1c3..a61f14746 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Windows; +using Tango.BL.ActionLogs; using Tango.Core.DI; using Tango.Integration.ExternalBridge; using Tango.Logging; @@ -70,6 +71,7 @@ namespace Tango.MachineStudio.UI TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); @@ -93,6 +95,7 @@ namespace Tango.MachineStudio.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(new DefaultActionLogManager() { ThrowExceptions = false }); TangoIOC.Default.Register(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com", String.Empty, "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa")); diff --git a/Software/Visual_Studio/Tango.BL/ActionLogs/BasicActionLogComparer.cs b/Software/Visual_Studio/Tango.BL/ActionLogs/BasicActionLogComparer.cs new file mode 100644 index 000000000..61fc373a8 --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/ActionLogs/BasicActionLogComparer.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.ValueObjects; + +namespace Tango.BL.ActionLogs +{ + public class BasicActionLogComparer + { + public Task> Compare(IActionLogComparable before, IActionLogComparable after) + { + return Task.Factory.StartNew>(() => + { + List diffs = new List(); + + Compare(diffs, before, after, null); + + return diffs; + }); + } + + private void Compare(List diffs, Object before, Object after, HashSet scannedObjects) + { + if (scannedObjects == null) + { + scannedObjects = new HashSet(); + } + + if (before == null && after == null) return; + + if (before != null) + { + if (scannedObjects.Contains(before)) return; + scannedObjects.Add(before); + } + + if (after != null) + { + if (scannedObjects.Contains(after)) return; + scannedObjects.Add(after); + } + + String component = GetComponentName(before, after); + + foreach (var prop in GetProperties(before, after)) + { + if (GetShouldIgnore(prop, before, after)) continue; + + if (prop.PropertyType.IsPrimitive || prop.PropertyType.IsValueType || prop.PropertyType == typeof(String)) + { + object beforeValue = null; + object afterValue = null; + + if (before != null) + { + beforeValue = prop.GetValue(before); + } + + if (after != null) + { + afterValue = prop.GetValue(after); + } + + if (afterValue == null && beforeValue != null) AddDiff(diffs, component, prop.Name, beforeValue, afterValue); + if (afterValue != null && beforeValue == null) AddDiff(diffs, component, prop.Name, beforeValue, afterValue); + + if (afterValue != null && beforeValue != null) + { + if (!afterValue.Equals(beforeValue)) + { + AddDiff(diffs, component, prop.Name, beforeValue, afterValue); + } + } + } + else if (!prop.PropertyType.IsGenericType) + { + object beforePropInstance = null; + object afterPropInstance = null; + + if (before != null) + { + beforePropInstance = prop.GetValue(before); + } + + if (after != null) + { + afterPropInstance = prop.GetValue(after); + } + + Compare(diffs, beforePropInstance, afterPropInstance, scannedObjects); + } + else + { + IList beforeCollection = null; + IList afterCollection = null; + + if (before != null) + { + beforeCollection = prop.GetValue(before) as IList; + } + + if (after != null) + { + afterCollection = prop.GetValue(after) as IList; + } + + if (beforeCollection != null && beforeCollection == null) + { + for (int i = 0; i < beforeCollection.Count; i++) + { + Compare(diffs, beforeCollection[i], null, scannedObjects); + } + } + else if (beforeCollection == null && afterCollection != null) + { + for (int i = 0; i < afterCollection.Count; i++) + { + Compare(diffs, null, afterCollection[i], scannedObjects); + } + } + + if (beforeCollection != null && afterCollection != null) + { + for (int i = 0; i < Math.Max(beforeCollection.Count, afterCollection.Count); i++) + { + var beforeItem = i < beforeCollection.Count ? beforeCollection[i] : null; + var afterItem = i < afterCollection.Count ? afterCollection[i] : null; + Compare(diffs, beforeItem, afterItem, scannedObjects); + } + } + } + } + } + + private void AddDiff(List diffs, String component, String property, object before, object after) + { + diffs.Add(new ActionLogDifference() + { + Component = component, + Property = property, + Before = before, + After = after + }); + } + + private String GetComponentName(Object before, Object after) + { + return after != null ? after.GetType().Name : before.GetType().Name; + } + + private PropertyInfo GetProperty(String name, Object before, Object after) + { + return after != null ? after.GetType().GetProperty(name) : before.GetType().GetProperty(name); + } + + private List GetProperties(BindingFlags flags, Object before, Object after) + { + return after != null ? after.GetType().GetProperties(flags).ToList() : before.GetType().GetProperties(flags).ToList(); + } + + private List GetProperties(Object before, Object after) + { + return after != null ? after.GetType().GetProperties().ToList() : before.GetType().GetProperties().ToList(); + } + + private bool GetShouldIgnore(PropertyInfo prop, Object before, Object after) + { + var beforeCast = before as IActionLogComparable; + var afterCast = after as IActionLogComparable; + + if (beforeCast != null) return beforeCast.ShouldActionLogIgnore(prop.Name); + if (afterCast != null) return afterCast.ShouldActionLogIgnore(prop.Name); + + return false; + } + } +} diff --git a/Software/Visual_Studio/Tango.BL/ActionLogs/DefaultActionLogManager.cs b/Software/Visual_Studio/Tango.BL/ActionLogs/DefaultActionLogManager.cs new file mode 100644 index 000000000..23562bee0 --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/ActionLogs/DefaultActionLogManager.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.BL.Enumerations; +using Tango.BL.ValueObjects; +using Tango.Core; +using Tango.Core.ExtensionMethods; + +namespace Tango.BL.ActionLogs +{ + public class DefaultActionLogManager : ExtendedObject, IActionLogManager + { + public bool ThrowExceptions { get; set; } + + public DefaultActionLogManager() + { + ThrowExceptions = true; + } + + public async Task InsertLog(ActionLogType type, string userGuid, string relatedObjectName, string relatedObjectGuid, List differences, string message = null) + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + try + { + ActionLog log = new ActionLog(); + log.ActionType = type; + log.LastUpdated = DateTime.UtcNow; + log.UserGuid = userGuid; + log.RelatedObjectName = relatedObjectName; + log.RelatedObjectGuid = relatedObjectGuid; + log.Message = message; + log.Differences = differences; + + db.ActionLogs.Add(log); + + await db.SaveChangesAsync(); + + LogManager.Log($"Action log '{type}' inserted."); + + if (differences != null && differences.Count > 0) + { + Debug.WriteLine($"Action log differences:\n{differences.ToJsonString()}"); + } + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error inserting action log '{type}'."); + + if (ThrowExceptions) + { + throw ex; + } + } + } + } + + public async Task InsertLog(ActionLogType type, string userGuid, string relatedObjectName, IActionLogComparable relatedObjectBefore, IActionLogComparable relatedObjectAfter, string message = null) + { + List diffs = null; + + try + { + if (relatedObjectAfter != null) + { + diffs = await relatedObjectAfter.CompareTo(relatedObjectBefore); + } + else + { + diffs = await relatedObjectBefore.CompareTo(relatedObjectAfter); + } + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error while comparing for action log '{type}'."); + + if (ThrowExceptions) + { + throw ex; + } + } + + if (diffs.Count > 0) + { + await InsertLog(type, userGuid, relatedObjectName, relatedObjectAfter.Guid, diffs, message); + } + else + { + LogManager.Log($"Action log '{type}' was about to be inserted but skipped due to no differences."); + } + } + + public Task InsertLog(ActionLogType type, User user, string relatedObjectName, IActionLogComparable relatedObjectBefore, IActionLogComparable relatedObjectAfter, string message = null) + { + return InsertLog(type, user.Guid, relatedObjectName, relatedObjectBefore, relatedObjectAfter, message); + } + + public Task InsertLog(ActionLogType type, string userGuid, string relatedObjectName, string relatedObjectGuid, string message = null) + { + return InsertLog(type, userGuid, relatedObjectName, relatedObjectGuid, null, message); + } + + public Task InsertLog(ActionLogType type, User user, string relatedObjectName, IObservableEntity relatedObject, string message = null) + { + return InsertLog(type, user.Guid, relatedObjectName, relatedObject?.Guid, message); + } + + public Task InsertLog(ActionLogType type, string userGuid, string message = null) + { + return InsertLog(type, userGuid, null, null, message); + } + + public Task InsertLog(ActionLogType type, User user, string message = null) + { + return InsertLog(type, user.Guid, message); + } + } +} diff --git a/Software/Visual_Studio/Tango.BL/ActionLogs/IActionLogComparable.cs b/Software/Visual_Studio/Tango.BL/ActionLogs/IActionLogComparable.cs new file mode 100644 index 000000000..de534141b --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/ActionLogs/IActionLogComparable.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.ValueObjects; + +namespace Tango.BL.ActionLogs +{ + public interface IActionLogComparable + { + String Guid { get; } + Task> CompareTo(IActionLogComparable before); + bool ShouldActionLogIgnore(String propName); + } + + public interface IActionLogComparable : IActionLogComparable where T : class + { + Task> CompareTo(T before); + } +} diff --git a/Software/Visual_Studio/Tango.BL/ActionLogs/IActionLogManager.cs b/Software/Visual_Studio/Tango.BL/ActionLogs/IActionLogManager.cs new file mode 100644 index 000000000..fd903bbba --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/ActionLogs/IActionLogManager.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.BL.Enumerations; +using Tango.BL.ValueObjects; + +namespace Tango.BL.ActionLogs +{ + public interface IActionLogManager + { + bool ThrowExceptions { get; set; } + Task InsertLog(ActionLogType type, String userGuid, String relatedObjectName, String relatedObjectGuid, List differences, String message = null); + Task InsertLog(ActionLogType type, String userGuid, String relatedObjectName, IActionLogComparable relatedObjectBefore, IActionLogComparable relatedObjectAfter, String message = null); + Task InsertLog(ActionLogType type, User user, String relatedObjectName, IActionLogComparable relatedObjectBefore, IActionLogComparable relatedObjectAfter, String message = null); + Task InsertLog(ActionLogType type, String userGuid, String relatedObjectName, String relatedObjectGuid, String message = null); + Task InsertLog(ActionLogType type, User user, String relatedObjectName, IObservableEntity relatedObject, String message = null); + Task InsertLog(ActionLogType type, String userGuid, String message = null); + Task InsertLog(ActionLogType type, User user, String message = null); + } +} diff --git a/Software/Visual_Studio/Tango.BL/DTO/ActionLogDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/ActionLogDTO.cs new file mode 100644 index 000000000..a847c6f24 --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/DTO/ActionLogDTO.cs @@ -0,0 +1,14 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.BL.DTO +{ + public class ActionLogDTO : ActionLogDTOBase + { + + } +} diff --git a/Software/Visual_Studio/Tango.BL/DTO/ActionLogDTOBase.cs b/Software/Visual_Studio/Tango.BL/DTO/ActionLogDTOBase.cs new file mode 100644 index 000000000..24cf4e94f --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/DTO/ActionLogDTOBase.cs @@ -0,0 +1,73 @@ + +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Tango Observables Generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. Do not modify! +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; + +namespace Tango.BL.DTO +{ + public abstract class ActionLogDTOBase : ObservableEntityDTO + { + + /// + /// type + /// + public Int32 Type + { + get; set; + } + + /// + /// user guid + /// + public String UserGuid + { + get; set; + } + + /// + /// related object name + /// + public String RelatedObjectName + { + get; set; + } + + /// + /// related object guid + /// + public String RelatedObjectGuid + { + get; set; + } + + /// + /// message + /// + public String Message + { + get; set; + } + + /// + /// difference + /// + public String Difference + { + get; set; + } + + } +} diff --git a/Software/Visual_Studio/Tango.BL/DTO/BrushStopDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/BrushStopDTO.cs index 447509ba7..585f2f2ee 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/BrushStopDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/BrushStopDTO.cs @@ -9,6 +9,9 @@ namespace Tango.BL.DTO { public class BrushStopDTO : BrushStopDTOBase { - + protected override bool OnShouldActionLogIgnore(string propName) + { + return propName == nameof(Corrected); + } } } diff --git a/Software/Visual_Studio/Tango.BL/DTO/JobDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/JobDTO.cs index 7ee6c9bb0..36f7ea9be 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/JobDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/JobDTO.cs @@ -15,5 +15,12 @@ namespace Tango.BL.DTO { Segments = new List(); } + + protected override bool OnShouldActionLogIgnore(string propName) + { + return propName == nameof(JobDTO.LastRun) || + propName == nameof(JobDTO.Status) || + propName == nameof(JobDTO.IsSynchronized); + } } } diff --git a/Software/Visual_Studio/Tango.BL/Entities/ActionLog.cs b/Software/Visual_Studio/Tango.BL/Entities/ActionLog.cs new file mode 100644 index 000000000..af88ee7f1 --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/Entities/ActionLog.cs @@ -0,0 +1,60 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Enumerations; +using Tango.BL.ValueObjects; + +namespace Tango.BL.Entities +{ + public class ActionLog : ActionLogBase + { + private List _differences; + + [NotMapped] + [JsonIgnore] + public ActionLogType ActionType + { + get { return (ActionLogType)Type; } + set { Type = value.ToInt32(); RaisePropertyChanged(nameof(ActionType)); } + } + + [NotMapped] + [JsonIgnore] + public List Differences + { + get + { + if (_differences != null) + { + try + { + _differences = JsonConvert.DeserializeObject>(Difference); + } + catch + { + _differences = new List(); + } + } + else + { + _differences = new List(); + } + + return _differences; + } + set + { + _differences = value; + + if (_differences != null) + { + Difference = JsonConvert.SerializeObject(_differences); + } + } + } + } +} diff --git a/Software/Visual_Studio/Tango.BL/Entities/ActionLogBase.cs b/Software/Visual_Studio/Tango.BL/Entities/ActionLogBase.cs new file mode 100644 index 000000000..077c834d2 --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/Entities/ActionLogBase.cs @@ -0,0 +1,282 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Tango Observables Generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. Do not modify! +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Xml.Serialization; +using Newtonsoft.Json; +using System.Linq; +using Tango.DAL.Remote.DB; +using Tango.Core; +using System.ComponentModel; + +namespace Tango.BL.Entities +{ + [Table("ACTION_LOGS")] + public abstract class ActionLogBase : ObservableEntity + { + + public event EventHandler TypeChanged; + + public event EventHandler RelatedObjectNameChanged; + + public event EventHandler MessageChanged; + + public event EventHandler DifferenceChanged; + + public event EventHandler UserChanged; + + protected Int32 _type; + + /// + /// Gets or sets the actionlogbase type. + /// + + [Column("TYPE")] + + public Int32 Type + { + get + { + return _type; + } + + set + { + if (_type != value) + { + _type = value; + + OnTypeChanged(value); + + } + } + } + + protected String _userguid; + + /// + /// Gets or sets the actionlogbase user guid. + /// + + [Column("USER_GUID")] + [ForeignKey("User")] + + public String UserGuid + { + get + { + return _userguid; + } + + set + { + if (_userguid != value) + { + _userguid = value; + + } + } + } + + protected String _relatedobjectname; + + /// + /// Gets or sets the actionlogbase related object name. + /// + + [Column("RELATED_OBJECT_NAME")] + + public String RelatedObjectName + { + get + { + return _relatedobjectname; + } + + set + { + if (_relatedobjectname != value) + { + _relatedobjectname = value; + + OnRelatedObjectNameChanged(value); + + } + } + } + + protected String _relatedobjectguid; + + /// + /// Gets or sets the actionlogbase related object guid. + /// + + [Column("RELATED_OBJECT_GUID")] + + public String RelatedObjectGuid + { + get + { + return _relatedobjectguid; + } + + set + { + if (_relatedobjectguid != value) + { + _relatedobjectguid = value; + + } + } + } + + protected String _message; + + /// + /// Gets or sets the actionlogbase message. + /// + + [Column("MESSAGE")] + + public String Message + { + get + { + return _message; + } + + set + { + if (_message != value) + { + _message = value; + + OnMessageChanged(value); + + } + } + } + + protected String _difference; + + /// + /// Gets or sets the actionlogbase difference. + /// + + [Column("DIFFERENCE")] + + public String Difference + { + get + { + return _difference; + } + + set + { + if (_difference != value) + { + _difference = value; + + OnDifferenceChanged(value); + + } + } + } + + protected User _user; + + /// + /// Gets or sets the actionlogbase user. + /// + + [XmlIgnore] + [JsonIgnore] + public virtual User User + { + get + { + return _user; + } + + set + { + if (_user != value) + { + _user = value; + + if (User != null) + { + UserGuid = User.Guid; + } + + OnUserChanged(value); + + } + } + } + + /// + /// Called when the Type has changed. + /// + protected virtual void OnTypeChanged(Int32 type) + { + TypeChanged?.Invoke(this, type); + RaisePropertyChanged(nameof(Type)); + } + + /// + /// Called when the RelatedObjectName has changed. + /// + protected virtual void OnRelatedObjectNameChanged(String relatedobjectname) + { + RelatedObjectNameChanged?.Invoke(this, relatedobjectname); + RaisePropertyChanged(nameof(RelatedObjectName)); + } + + /// + /// Called when the Message has changed. + /// + protected virtual void OnMessageChanged(String message) + { + MessageChanged?.Invoke(this, message); + RaisePropertyChanged(nameof(Message)); + } + + /// + /// Called when the Difference has changed. + /// + protected virtual void OnDifferenceChanged(String difference) + { + DifferenceChanged?.Invoke(this, difference); + RaisePropertyChanged(nameof(Difference)); + } + + /// + /// Called when the User has changed. + /// + protected virtual void OnUserChanged(User user) + { + UserChanged?.Invoke(this, user); + RaisePropertyChanged(nameof(User)); + } + + /// + /// Initializes a new instance of the class. + /// + public ActionLogBase() : base() + { + } + } +} diff --git a/Software/Visual_Studio/Tango.BL/Entities/Job.cs b/Software/Visual_Studio/Tango.BL/Entities/Job.cs index c4847c5e9..1a5883557 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/Job.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/Job.cs @@ -10,8 +10,10 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows.Media.Imaging; +using Tango.BL.ActionLogs; using Tango.BL.Builders; using Tango.BL.Enumerations; +using Tango.BL.ValueObjects; using Tango.Core; using Tango.Core.ExtensionMethods; using Tango.Logging; diff --git a/Software/Visual_Studio/Tango.BL/Entities/UserBase.cs b/Software/Visual_Studio/Tango.BL/Entities/UserBase.cs index 5445b2980..805cf9d57 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/UserBase.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/UserBase.cs @@ -34,6 +34,8 @@ namespace Tango.BL.Entities public event EventHandler> LastLoginChanged; + public event EventHandler> ActionLogsChanged; + public event EventHandler
AddressChanged; public event EventHandler ContactChanged; @@ -236,6 +238,31 @@ namespace Tango.BL.Entities } } + protected SynchronizedObservableCollection _actionlogs; + + /// + /// Gets or sets the userbase action logs. + /// + + public virtual SynchronizedObservableCollection ActionLogs + { + get + { + return _actionlogs; + } + + set + { + if (_actionlogs != value) + { + _actionlogs = value; + + OnActionLogsChanged(value); + + } + } + } + protected Address _address; /// @@ -493,6 +520,15 @@ namespace Tango.BL.Entities RaisePropertyChanged(nameof(LastLogin)); } + /// + /// Called when the ActionLogs has changed. + /// + protected virtual void OnActionLogsChanged(SynchronizedObservableCollection actionlogs) + { + ActionLogsChanged?.Invoke(this, actionlogs); + RaisePropertyChanged(nameof(ActionLogs)); + } + /// /// Called when the Address has changed. /// @@ -571,6 +607,8 @@ namespace Tango.BL.Entities public UserBase() : base() { + ActionLogs = new SynchronizedObservableCollection(); + Jobs = new SynchronizedObservableCollection(); MachineStudioVersions = new SynchronizedObservableCollection(); diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/ActionLogType.cs b/Software/Visual_Studio/Tango.BL/Enumerations/ActionLogType.cs new file mode 100644 index 000000000..94eb07cda --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/Enumerations/ActionLogType.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.BL.Enumerations +{ + public enum ActionLogType + { + //Organizations and Users + [Description("Organization Created")] + OrganizationCreated = 1, + [Description("Organization Deleted")] + OrganizationDeleted = 2, + [Description("Organization Saved")] + OrganizationSaved = 3, + [Description("User Created")] + UserCreated = 4, + [Description("User Deleted")] + UserDeleted = 5, + [Description("User Saved")] + UserSaved = 6, + [Description("User Login")] + UserLogin = 7, + [Description("User Logout")] + UserLogout = 8, + + //Hardware Version + [Description("Hardware Version Created")] + HardwareVersionCreated = 100, + [Description("Hardware Version Deleted")] + HardwareVersionDeleted = 101, + [Description("Hardware Version Saved")] + HardwareVersionSaved = 102, + + //RML + [Description("RML Created")] + RmlCreated = 200, + [Description("RML Deleted")] + RmlDeleted = 201, + [Description("RML Saved")] + RmlSaved = 202, + + //Jobs + [Description("Job Created")] + JobCreated = 300, + [Description("Job Deleted")] + JobDeleted = 301, + [Description("Job Saved")] + JobSaved = 302, + + //Machines + [Description("Machine Created")] + MachineCreated = 400, + [Description("Machine Deleted")] + MachineDeleted = 401, + [Description("Machine Saved")] + MachineSaved = 402, + + //Catalogs + [Description("Catalog Created")] + CatalogCreated = 500, + [Description("Catalog Deleted")] + CatalogDeleted = 501, + [Description("Catalog Saved")] + CatalogSaved = 502, + + //Sites + [Description("Site Created")] + SiteCreated = 600, + [Description("Site Deleted")] + SiteDeleted = 601, + [Description("Site Saved")] + SiteSaved = 602, + + //Dispensers + [Description("Dispenser Created")] + DispenserCreated = 700, + [Description("Dispenser Deleted")] + DispenserDeleted = 701, + [Description("Dispenser Saved")] + DispenserSaved = 702, + + //Firmware + [Description("Firmware Upgraded")] + FirmwareUpgraded = 800, + } +} diff --git a/Software/Visual_Studio/Tango.BL/ObservableEntity.cs b/Software/Visual_Studio/Tango.BL/ObservableEntity.cs index 4f03263d9..11aca0e99 100644 --- a/Software/Visual_Studio/Tango.BL/ObservableEntity.cs +++ b/Software/Visual_Studio/Tango.BL/ObservableEntity.cs @@ -27,6 +27,8 @@ using Tango.Core.Json; using Newtonsoft.Json.Converters; using Tango.BL.Serialization; using Newtonsoft.Json.Linq; +using Tango.BL.ActionLogs; +using Tango.BL.ValueObjects; namespace Tango.BL { @@ -50,7 +52,7 @@ namespace Tango.BL /// /// [Serializable] - public abstract class ObservableEntity : ExtendedObject, IObservableEntity where T : class, IObservableEntity + public abstract class ObservableEntity : ExtendedObject, IObservableEntity, IActionLogComparable where T : class, IObservableEntity { #region Events @@ -658,5 +660,29 @@ namespace Tango.BL } #endregion + + #region Action Log + + public Task> CompareTo(T before) + { + return new BasicActionLogComparer().Compare(before as IActionLogComparable, this); + } + + Task> IActionLogComparable.CompareTo(IActionLogComparable before) + { + return CompareTo(before as T); + } + + bool IActionLogComparable.ShouldActionLogIgnore(string propName) + { + return propName == nameof(LastUpdated) || OnShouldActionLogIgnore(propName); + } + + protected virtual bool OnShouldActionLogIgnore(string propName) + { + return false; + } + + #endregion } } diff --git a/Software/Visual_Studio/Tango.BL/ObservableEntityDTO.cs b/Software/Visual_Studio/Tango.BL/ObservableEntityDTO.cs index 5950a3cd2..f587147e1 100644 --- a/Software/Visual_Studio/Tango.BL/ObservableEntityDTO.cs +++ b/Software/Visual_Studio/Tango.BL/ObservableEntityDTO.cs @@ -5,10 +5,12 @@ using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; +using Tango.BL.ActionLogs; +using Tango.BL.ValueObjects; namespace Tango.BL { - public abstract class ObservableEntityDTO : IObservableEntityDTO, IEquatable where T : IObservableEntity where DTO : ObservableEntityDTO + public abstract class ObservableEntityDTO : IObservableEntityDTO, IEquatable, IActionLogComparable where T : IObservableEntity where DTO : ObservableEntityDTO { public int ID { get; set; } @@ -207,5 +209,25 @@ namespace Tango.BL { return EqualsToObservable(observable); } + + public Task> CompareTo(DTO before) + { + return new BasicActionLogComparer().Compare(before, this); + } + + Task> IActionLogComparable.CompareTo(IActionLogComparable before) + { + return CompareTo(before as DTO); + } + + bool IActionLogComparable.ShouldActionLogIgnore(string propName) + { + return propName == nameof(LastUpdated) || OnShouldActionLogIgnore(propName); + } + + protected virtual bool OnShouldActionLogIgnore(string propName) + { + return false; + } } } diff --git a/Software/Visual_Studio/Tango.BL/ObservablesContext.cs b/Software/Visual_Studio/Tango.BL/ObservablesContext.cs index 4eaf256d2..3511a7624 100644 --- a/Software/Visual_Studio/Tango.BL/ObservablesContext.cs +++ b/Software/Visual_Studio/Tango.BL/ObservablesContext.cs @@ -30,6 +30,14 @@ namespace Tango.BL get; set; } + /// + /// Gets or sets the ActionLogs. + /// + public DbSet ActionLogs + { + get; set; + } + /// /// Gets or sets the Addresses. /// diff --git a/Software/Visual_Studio/Tango.BL/ObservablesEntitiesAdapterExtension.cs b/Software/Visual_Studio/Tango.BL/ObservablesEntitiesAdapterExtension.cs index c86933713..cccc2fcae 100644 --- a/Software/Visual_Studio/Tango.BL/ObservablesEntitiesAdapterExtension.cs +++ b/Software/Visual_Studio/Tango.BL/ObservablesEntitiesAdapterExtension.cs @@ -53,6 +53,42 @@ namespace Tango.BL } + private ObservableCollection _actionlogs; + /// + /// Gets or sets the ActionLogs. + /// + public ObservableCollection ActionLogs + { + get + { + return _actionlogs; + } + + set + { + _actionlogs = value; RaisePropertyChanged(nameof(ActionLogs)); + } + + } + + private ICollectionView _actionlogsViewSource; + /// + /// Gets or sets the ActionLogs View Source. + /// + public ICollectionView ActionLogsViewSource + { + get + { + return _actionlogsViewSource; + } + + set + { + _actionlogsViewSource = value; RaisePropertyChanged(nameof(ActionLogsViewSource)); + } + + } + private ObservableCollection
_addresses; /// /// Gets or sets the Addresses. @@ -2833,6 +2869,8 @@ namespace Tango.BL SyncConfigurationsViewSource = CreateCollectionView(SyncConfigurations); + ActionLogsViewSource = CreateCollectionView(ActionLogs); + AddressesViewSource = CreateCollectionView(Addresses); ApplicationDisplayPanelVersionsViewSource = CreateCollectionView(ApplicationDisplayPanelVersions); diff --git a/Software/Visual_Studio/Tango.BL/ObservablesStaticCollectionsExtension.cs b/Software/Visual_Studio/Tango.BL/ObservablesStaticCollectionsExtension.cs index efa188fec..4e108deb2 100644 --- a/Software/Visual_Studio/Tango.BL/ObservablesStaticCollectionsExtension.cs +++ b/Software/Visual_Studio/Tango.BL/ObservablesStaticCollectionsExtension.cs @@ -53,6 +53,42 @@ namespace Tango.BL } + private ObservableCollection _actionlogs; + /// + /// Gets or sets the ActionLogs. + /// + public ObservableCollection ActionLogs + { + get + { + return _actionlogs; + } + + set + { + _actionlogs = value; RaisePropertyChanged(nameof(ActionLogs)); + } + + } + + private ICollectionView _actionlogsViewSource; + /// + /// Gets or sets the ActionLogs View Source. + /// + public ICollectionView ActionLogsViewSource + { + get + { + return _actionlogsViewSource; + } + + set + { + _actionlogsViewSource = value; RaisePropertyChanged(nameof(ActionLogsViewSource)); + } + + } + private ObservableCollection
_addresses; /// /// Gets or sets the Addresses. @@ -2833,6 +2869,8 @@ namespace Tango.BL SyncConfigurationsViewSource = CreateCollectionView(SyncConfigurations); + ActionLogsViewSource = CreateCollectionView(ActionLogs); + AddressesViewSource = CreateCollectionView(Addresses); ApplicationDisplayPanelVersionsViewSource = CreateCollectionView(ApplicationDisplayPanelVersions); diff --git a/Software/Visual_Studio/Tango.BL/Tango.BL.csproj b/Software/Visual_Studio/Tango.BL/Tango.BL.csproj index 6111a1a35..469e23165 100644 --- a/Software/Visual_Studio/Tango.BL/Tango.BL.csproj +++ b/Software/Visual_Studio/Tango.BL/Tango.BL.csproj @@ -84,6 +84,10 @@ GlobalVersionInfo.cs + + + + @@ -115,6 +119,8 @@ + + @@ -269,6 +275,8 @@ + + @@ -368,6 +376,7 @@ + @@ -500,6 +509,7 @@ + @@ -580,7 +590,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.BL/ValueObjects/ActionLogDifference.cs b/Software/Visual_Studio/Tango.BL/ValueObjects/ActionLogDifference.cs new file mode 100644 index 000000000..a89348249 --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/ValueObjects/ActionLogDifference.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.BL.ValueObjects +{ + public class ActionLogDifference + { + public String Component { get; set; } + public String Property { get; set; } + public Object Before { get; set; } + public Object After { get; set; } + } +} diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/ACTION_LOGS.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/ACTION_LOGS.cs new file mode 100644 index 000000000..7bfa1fa2c --- /dev/null +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/ACTION_LOGS.cs @@ -0,0 +1,29 @@ +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Tango.DAL.Remote.DB +{ + using System; + using System.Collections.Generic; + + public partial class ACTION_LOGS + { + public int ID { get; set; } + public string GUID { get; set; } + public System.DateTime LAST_UPDATED { get; set; } + public int TYPE { get; set; } + public string USER_GUID { get; set; } + public string RELATED_OBJECT_NAME { get; set; } + public string RELATED_OBJECT_GUID { get; set; } + public string MESSAGE { get; set; } + public string DIFFERENCE { get; set; } + + public virtual USER USER { get; set; } + } +} diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.Context.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.Context.cs index 3ef793f7f..2a158ad49 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.Context.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.Context.cs @@ -26,6 +26,7 @@ namespace Tango.DAL.Remote.DB } public virtual DbSet SYNC_CONFIGURATIONS { get; set; } + public virtual DbSet ACTION_LOGS { get; set; } public virtual DbSet
ADDRESSES { get; set; } public virtual DbSet APPLICATION_DISPLAY_PANEL_VERSIONS { get; set; } public virtual DbSet APPLICATION_FIRMWARE_VERSIONS { get; set; } diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.Designer.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.Designer.cs index d26e67908..17bc2683d 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.Designer.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.Designer.cs @@ -1,4 +1,4 @@ -// T4 code generation is enabled for model 'C:\DATA\Development\Tango\Software\Visual_Studio\Tango.DAL.Remote\DB\RemoteADO.edmx'. +// T4 code generation is enabled for model 'D:\Development\Tango\Software\Visual_Studio\Tango.DAL.Remote\DB\RemoteADO.edmx'. // To enable legacy code generation, change the value of the 'Code Generation Strategy' designer // property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model // is open in the designer. diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx index f8f4f9505..eb161228c 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx @@ -5,6 +5,20 @@ + + + + + + + + + + + + + + @@ -1155,6 +1169,18 @@ + + + + + + + + + + + + @@ -2204,6 +2230,7 @@ + @@ -2282,6 +2309,10 @@ + + + + @@ -2613,6 +2644,7 @@ + @@ -2690,6 +2722,10 @@ + + + + @@ -3023,6 +3059,21 @@ + + + + + + + + + + + + + + + @@ -4294,6 +4345,7 @@ + @@ -4327,6 +4379,18 @@ + + + + + + + + + + + + @@ -5390,6 +5454,21 @@ + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram index f13138208..a9ff9aacf 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram @@ -5,83 +5,85 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/USER.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/USER.cs index f8c124d43..e71c100ff 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/USER.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/USER.cs @@ -17,6 +17,7 @@ namespace Tango.DAL.Remote.DB [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public USER() { + this.ACTION_LOGS = new HashSet(); this.JOBS = new HashSet(); this.MACHINE_STUDIO_VERSIONS = new HashSet(); this.MACHINES_EVENTS = new HashSet(); @@ -35,6 +36,8 @@ namespace Tango.DAL.Remote.DB public string ADDRESS_GUID { get; set; } public Nullable LAST_LOGIN { get; set; } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + public virtual ICollection ACTION_LOGS { get; set; } public virtual ADDRESS ADDRESS { get; set; } public virtual CONTACT CONTACT { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] diff --git a/Software/Visual_Studio/Tango.DAL.Remote/Tango.DAL.Remote.csproj b/Software/Visual_Studio/Tango.DAL.Remote/Tango.DAL.Remote.csproj index 75fa9179c..0a0cad6e2 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/Tango.DAL.Remote.csproj +++ b/Software/Visual_Studio/Tango.DAL.Remote/Tango.DAL.Remote.csproj @@ -66,6 +66,9 @@ GlobalVersionInfo.cs + + RemoteADO.tt + RemoteADO.tt @@ -365,7 +368,7 @@ - + \ No newline at end of file -- cgit v1.3.1