diff --git a/BodyshopUploader/BodyshopUploader.csproj b/BodyshopUploader/BodyshopUploader.csproj index e70a0f0..9ed6cf9 100644 --- a/BodyshopUploader/BodyshopUploader.csproj +++ b/BodyshopUploader/BodyshopUploader.csproj @@ -253,6 +253,7 @@ + Resources.es-MX.resx True diff --git a/BodyshopUploader/Models/DTO_QueueItem.cs b/BodyshopUploader/Models/DTO_QueueItem.cs index a4e08bd..1cfc6b0 100644 --- a/BodyshopUploader/Models/DTO_QueueItem.cs +++ b/BodyshopUploader/Models/DTO_QueueItem.cs @@ -4,6 +4,16 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +namespace BodyshopUploader +{ + public enum SourceSystem + { + Mitchell = 0, + Audatex = 1, + CCC = 2 + } +} + namespace BodyshopUploader.Models { public class DTO_QueueItem : DTO_Base @@ -13,6 +23,13 @@ namespace BodyshopUploader.Models } + private SourceSystem _source; + public SourceSystem Source + { + get { return _source; } + set { SetProperty(ref _source, value); } + } + private dynamic _job; public dynamic Job { diff --git a/BodyshopUploader/Models/Monitor.cs b/BodyshopUploader/Models/Monitor.cs new file mode 100644 index 0000000..0b74053 --- /dev/null +++ b/BodyshopUploader/Models/Monitor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BodyshopUploader.Models +{ + public class Monitor : DTO_Base + { + private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + + public Monitor() + { + + } + + private SourceSystem _source; + public SourceSystem Source + { + get { return _source; } + set { SetProperty(ref _source, value); } + } + + private string _filePath; + public string FilePath + { + get { return _filePath; } + set { SetProperty(ref _filePath, value); } + } + + private string _status; + public string Status + { + get { return _status; } + set { SetProperty(ref _status, value); } + } + + private Utils.CIECAMonitor _folderMonitor; + public Utils.CIECAMonitor FolderMonitor + { + get { return _folderMonitor; } + set { SetProperty(ref _folderMonitor, value); } + } + + public void StartMonitor() + { + logger.Debug("Starting folder monitor for path {0}", FilePath); + System.IO.Directory.CreateDirectory(FilePath); + FolderMonitor = new Utils.CIECAMonitor(FilePath); + } + + public void StopMonitor() + { + logger.Debug("Stopping folder monitor for path {0}", FilePath); + FolderMonitor?.Dispose(); + } + } +} diff --git a/BodyshopUploader/Properties/Resources.Designer.cs b/BodyshopUploader/Properties/Resources.Designer.cs index ab23683..f08b708 100644 --- a/BodyshopUploader/Properties/Resources.Designer.cs +++ b/BodyshopUploader/Properties/Resources.Designer.cs @@ -114,6 +114,24 @@ namespace BodyshopUploader.Properties { } } + /// + /// Looks up a localized string similar to File Path. + /// + public static string Label_FilePath { + get { + return ResourceManager.GetString("Label_FilePath", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Source System. + /// + public static string Label_SourceSystem { + get { + return ResourceManager.GetString("Label_SourceSystem", resourceCulture); + } + } + /// /// Looks up a localized string similar to Start All Monitors. /// @@ -141,6 +159,15 @@ namespace BodyshopUploader.Properties { } } + /// + /// Looks up a localized string similar to New Job Uploaded. + /// + public static string Msg_NewJobUploaded { + get { + return ResourceManager.GetString("Msg_NewJobUploaded", resourceCulture); + } + } + /// /// Looks up a localized string similar to Password. /// diff --git a/BodyshopUploader/Properties/Resources.resx b/BodyshopUploader/Properties/Resources.resx index 13594ef..5a29646 100644 --- a/BodyshopUploader/Properties/Resources.resx +++ b/BodyshopUploader/Properties/Resources.resx @@ -135,6 +135,12 @@ Add Path + + File Path + + + Source System + Start All Monitors @@ -144,6 +150,9 @@ Login + + New Job Uploaded + Password diff --git a/BodyshopUploader/Properties/Settings.Designer.cs b/BodyshopUploader/Properties/Settings.Designer.cs index bef4441..c341a1a 100644 --- a/BodyshopUploader/Properties/Settings.Designer.cs +++ b/BodyshopUploader/Properties/Settings.Designer.cs @@ -49,9 +49,9 @@ namespace BodyshopUploader.Properties { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("C:\\ImEX\r\nC:\\000")] - public global::System.Collections.ObjectModel.ObservableCollection MonitoringPaths { + public global::System.Collections.Generic.List MonitoringPaths { get { - return ((global::System.Collections.ObjectModel.ObservableCollection)(this["MonitoringPaths"])); + return ((global::System.Collections.Generic.List)(this["MonitoringPaths"])); } set { this["MonitoringPaths"] = value; diff --git a/BodyshopUploader/Properties/Settings.settings b/BodyshopUploader/Properties/Settings.settings index 13c3c86..83df96f 100644 --- a/BodyshopUploader/Properties/Settings.settings +++ b/BodyshopUploader/Properties/Settings.settings @@ -8,7 +8,7 @@ - + C:\ImEX C:\000 diff --git a/BodyshopUploader/Utils/CIECAMonitor.cs b/BodyshopUploader/Utils/CIECAMonitor.cs index 1940f35..0636592 100644 --- a/BodyshopUploader/Utils/CIECAMonitor.cs +++ b/BodyshopUploader/Utils/CIECAMonitor.cs @@ -43,7 +43,7 @@ namespace BodyshopUploader.Utils //Deleted += Watcher_Deleted; //Renamed += Watcher_Renamed; Error += Wathcer_Error; - logger.Debug("CIECA Folder watcher started for path: {0}", Path); + logger.Debug("CIECA Folder watcher initialized for path: {0}", Path); } private void Wathcer_Error(object sender, ErrorEventArgs e) diff --git a/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs b/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs index 62b5e35..4acc480 100644 --- a/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs +++ b/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs @@ -23,11 +23,9 @@ namespace BodyshopUploader.Utils.Decoder /// public static dynamic DecodeEstimate(string FilePath) { - //Sleep the thread so that all files can finish writing. - Thread.Sleep(1000); dynamic ret = new JObject(); - ret.CiecaId = Path.GetFileNameWithoutExtension(FilePath); + ret.ciecaid = Path.GetFileNameWithoutExtension(FilePath); string _dir = Path.GetDirectoryName(FilePath) + @"\"; @@ -42,18 +40,18 @@ namespace BodyshopUploader.Utils.Decoder public static void ParseAd1File(ref dynamic j, string RootFilePath) { - if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; } - logger.Trace(@"Parsing AD1 at: {0}{1}", RootFilePath, j.CiecaId.Value); + logger.Trace(@"Parsing AD1 at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; while (retryNumber < 11) { try { - using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + "A.ad1", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + "A.ad1", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var reader = new DBFReader(fis); reader.SetSelectFields(new string[] { "INS_CO_NM", "CLM_NO", "OWNR_LN", "OWNR_FN", "OWNR_EA", "OWNR_PH1" }); @@ -80,16 +78,16 @@ namespace BodyshopUploader.Utils.Decoder public static void ParseVehFile(ref dynamic j, string RootFilePath) { - if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; } + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; } - logger.Trace(@"Parsing Veh at: {0}{1}", RootFilePath, j.CiecaId.Value); + logger.Trace(@"Parsing Veh at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; while (retryNumber < 11) { try { - using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + "v.veh", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + "v.veh", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var reader = new DBFReader(fis); reader.SetSelectFields(new string[] { "V_MODEL_YR", "V_MAKEDESC", "V_MODEL", "V_COLOR", "PLATE_NO", "V_VIN" }); @@ -115,9 +113,9 @@ namespace BodyshopUploader.Utils.Decoder public static void ParseTtlFile(ref dynamic j, string RootFilePath) { - if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; } + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; } - logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.CiecaId.Value); + logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.ciecaid.Value); @@ -126,7 +124,7 @@ namespace BodyshopUploader.Utils.Decoder { try { - using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + ".ttl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + ".ttl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var reader = new DBFReader(fis); reader.SetSelectFields(new string[] { "G_TTL_AMT" }); @@ -146,9 +144,9 @@ namespace BodyshopUploader.Utils.Decoder public static void ParseStlFile(ref dynamic j, string RootFilePath) { - if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; } + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; } - logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.CiecaId.Value); + logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.ciecaid.Value); @@ -157,7 +155,7 @@ namespace BodyshopUploader.Utils.Decoder { try { - using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + ".stl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + ".stl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var reader = new DBFReader(fis); reader.SetSelectFields(new string[] { "TTL_TYPECD", "T_HRS" }); @@ -192,9 +190,9 @@ namespace BodyshopUploader.Utils.Decoder public static void ParseLinFile(ref dynamic j, string RootFilePath) { - if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; } + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; } - logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.CiecaId.Value); + logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.ciecaid.Value); //j.JobSublets = new List(); string _maxSupp = ""; @@ -204,7 +202,7 @@ namespace BodyshopUploader.Utils.Decoder { try { - using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + ".lin", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + ".lin", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var reader = new DBFReader(fis); reader.SetSelectFields(new string[] { "PART_TYPE", "LINE_DESC", "UNQ_SEQ", "LINE_IND" }); diff --git a/BodyshopUploader/Utils/Growls/GrowlNotification.xaml b/BodyshopUploader/Utils/Growls/GrowlNotification.xaml index 42dd3ea..a83a28e 100644 --- a/BodyshopUploader/Utils/Growls/GrowlNotification.xaml +++ b/BodyshopUploader/Utils/Growls/GrowlNotification.xaml @@ -6,13 +6,11 @@ xmlns:local="clr-namespace:BodyshopUploader.Utils.Growls" mc:Ignorable="d" SizeToContent="WidthAndHeight" - AllowsTransparency="True" WindowStyle="None" ShowInTaskbar="False" Topmost="True" UseLayoutRounding="True" - Title="BodyshopUploader Notification" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" TextElement.Foreground="{DynamicResource MaterialDesignBody}" @@ -37,9 +35,9 @@ Background="Transparent" SizeChanged="NotificationWindowSizeChanged"> + Duration="0:0:1" + BeginTime="0:0:2" /> diff --git a/BodyshopUploader/Utils/Growls/Notification.cs b/BodyshopUploader/Utils/Growls/Notification.cs index de38944..c194be0 100644 --- a/BodyshopUploader/Utils/Growls/Notification.cs +++ b/BodyshopUploader/Utils/Growls/Notification.cs @@ -36,19 +36,6 @@ namespace BodyshopUploader.Utils.Growls } } - private int threadid; - public int ThreadId - { - get { return threadid; } - - set - { - if (threadid == value) return; - threadid = value; - OnPropertyChanged("ThreadId"); - } - } - private string imageUrl; public string ImageUrl { diff --git a/BodyshopUploader/Utils/JobProcessingQueue.cs b/BodyshopUploader/Utils/JobProcessingQueue.cs index 3646e86..cac0b83 100644 --- a/BodyshopUploader/Utils/JobProcessingQueue.cs +++ b/BodyshopUploader/Utils/JobProcessingQueue.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using BodyshopUploader.Utils; using BodyshopUploader.Models; +using BodyshopUploader.Utils.Growls; namespace BodyshopUploader.Utils { @@ -15,6 +16,12 @@ namespace BodyshopUploader.Utils private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private static Queue _jobs = new Queue(); private static bool _delegateQueuedOrRunning = false; + private static GrowlNotification Growler; + + public static void SetGrowler(GrowlNotification g) + { + Growler = g; + } public static void Enqueue(DTO_QueueItem item) { @@ -60,9 +67,10 @@ namespace BodyshopUploader.Utils DecodeQueueItemJob(item); UpsertQueueItem(item); } - catch + catch (Exception ex) { ThreadPool.UnsafeQueueUserWorkItem(ProcessQueuedItems, null); + logger.Error(ex, "Error processing job queue item. "); throw; } } @@ -79,7 +87,17 @@ namespace BodyshopUploader.Utils { //Save the job to the DB. logger.Info("Should upsert the job graphqlly here. {0}", item.Job); + App.Current.Dispatcher.Invoke(() => + { + Growler.AddNotification(new Notification() + { + Title = Properties.Resources.Msg_NewJobUploaded, + Subtitle = item.Job?.owner?.first_name?.Value + " " + item.Job?.owner?.last_name?.Value, + Message = item.Job?.vehicle?.v_model_yr?.Value + " " + item.Job?.vehicle?.v_make_desc?.Value + " " + item.Job?.vehicle?.v_model_desc?.Value + }); + }); + _jobs.Dequeue(); } diff --git a/BodyshopUploader/ViewModels/MainViewModel.commands.cs b/BodyshopUploader/ViewModels/MainViewModel.commands.cs index d538ebc..bbe6495 100644 --- a/BodyshopUploader/ViewModels/MainViewModel.commands.cs +++ b/BodyshopUploader/ViewModels/MainViewModel.commands.cs @@ -63,8 +63,8 @@ namespace BodyshopUploader.ViewModels if (_removeMonitoringPathCommand == null) { _removeMonitoringPathCommand = new RelayCommand( - p => FolderMonitors.Count == 0, - p => RemoveFolderMonitoringPath(p as string) + p => true, + p => RemoveFolderMonitoringPath(p as Models.Monitor) ); } return _removeMonitoringPathCommand; @@ -95,7 +95,7 @@ namespace BodyshopUploader.ViewModels if (_stopFolderMonitorsCommand == null) { _stopFolderMonitorsCommand = new RelayCommand( - p => FolderMonitors.Count > 0, + p => MonitoringPaths.Count > 0, p => StopAllFolderMonitors() ); } diff --git a/BodyshopUploader/ViewModels/MainViewModel.cs b/BodyshopUploader/ViewModels/MainViewModel.cs index 28eefe9..2760371 100644 --- a/BodyshopUploader/ViewModels/MainViewModel.cs +++ b/BodyshopUploader/ViewModels/MainViewModel.cs @@ -1,4 +1,5 @@ -using BodyshopUploader.Utils.Growls; +using BodyshopUploader.Models; +using BodyshopUploader.Utils.Growls; using GraphQL.Client; using GraphQL.Common.Request; using System; @@ -17,12 +18,18 @@ namespace BodyshopUploader.ViewModels public MainViewModel() { - logger.Trace("Main VM Created."); Growler = new GrowlNotification(this); + Utils.JobProcessingQueue.SetGrowler(Growler); - //Create Variables - if (MonitoringPaths == null) MonitoringPaths = new ObservableCollection(); + //Restore list of paths, convert to monitor object. + List listOfPaths = Properties.Settings.Default.MonitoringPaths; + if (listOfPaths == null) listOfPaths = new List(); + foreach (var p in listOfPaths) + { + MonitoringPaths.Add(new Models.Monitor() { FilePath = p }); + } MonitoringPaths.CollectionChanged += MonitoringPathsChanged; + logger.Trace("Main VM Created."); } private void MonitoringPathsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) @@ -36,42 +43,43 @@ namespace BodyshopUploader.ViewModels if (dialog.ShowDialog().GetValueOrDefault()) { logger.Debug("Adding folder {0} to monitoring paths.", dialog.SelectedPath); - MonitoringPaths.Add(dialog.SelectedPath); - Properties.Settings.Default.MonitoringPaths = MonitoringPaths; + MonitoringPaths.Add(new Models.Monitor() { FilePath = dialog.SelectedPath }); + Properties.Settings.Default.MonitoringPaths = MonitoringPaths.Select(x => x.FilePath).ToList(); ; Properties.Settings.Default.Save(); } } - public void RemoveFolderMonitoringPath(string Path) + public void RemoveFolderMonitoringPath(Monitor m) { - logger.Debug("Removing folder {0} to monitoring paths.", Path); - MonitoringPaths.Remove(Path); - Properties.Settings.Default.MonitoringPaths = MonitoringPaths; + logger.Debug("Removing folder {0} to monitoring paths.", m.FilePath); + m.StopMonitor(); + MonitoringPaths.Remove(m); + Properties.Settings.Default.MonitoringPaths = MonitoringPaths.Select(x => x.FilePath).ToList(); Properties.Settings.Default.Save(); } public void StartAllFolderMonitors() { - if (FolderMonitors.Count > 0) - foreach (var m in FolderMonitors) + if (MonitoringPaths.Count > 0) + foreach (var m in MonitoringPaths) { - m.Dispose(); + m.StopMonitor(); } foreach (var p in MonitoringPaths) { //Ensure the directory exists, then start monitoring for CIECA files. - System.IO.Directory.CreateDirectory(p); - FolderMonitors.Add(new Utils.CIECAMonitor(p)); + p.StartMonitor(); + } } public void StopAllFolderMonitors() { - if (FolderMonitors.Count > 0) - foreach (var m in FolderMonitors) + if (MonitoringPaths.Count > 0) + foreach (var m in MonitoringPaths) { - m.Dispose(); + m.StopMonitor(); } } @@ -80,7 +88,6 @@ namespace BodyshopUploader.ViewModels Notification _n = new Notification() { Id = 123, - ThreadId = 123, Title = "This is a title", Subtitle = "Subtitle", Message = "Somethin" diff --git a/BodyshopUploader/ViewModels/MainViewModel.props.cs b/BodyshopUploader/ViewModels/MainViewModel.props.cs index 34370e8..17d5e84 100644 --- a/BodyshopUploader/ViewModels/MainViewModel.props.cs +++ b/BodyshopUploader/ViewModels/MainViewModel.props.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using BodyshopUploader.Utils.Growls; +using BodyshopUploader.Models; namespace BodyshopUploader.ViewModels { @@ -12,15 +13,8 @@ namespace BodyshopUploader.ViewModels { public GrowlNotification Growler; - private ObservableCollection _folderMonitors = new ObservableCollection() ; - public ObservableCollection FolderMonitors - { - get { return _folderMonitors; } - set { SetProperty(ref _folderMonitors, value); } - } - - private ObservableCollection _monitoringPaths = Properties.Settings.Default.MonitoringPaths ; - public ObservableCollection MonitoringPaths + private ObservableCollection _monitoringPaths = new ObservableCollection(); + public ObservableCollection MonitoringPaths { get { return _monitoringPaths; } set { SetProperty(ref _monitoringPaths, value); } diff --git a/BodyshopUploader/Views/Main.xaml b/BodyshopUploader/Views/Main.xaml index 9dcd139..3499df0 100644 --- a/BodyshopUploader/Views/Main.xaml +++ b/BodyshopUploader/Views/Main.xaml @@ -68,12 +68,38 @@ + + + + + + +