diff --git a/BodyshopUploader/BodyshopUploader.csproj b/BodyshopUploader/BodyshopUploader.csproj index 9ed6cf9..a1d28c0 100644 --- a/BodyshopUploader/BodyshopUploader.csproj +++ b/BodyshopUploader/BodyshopUploader.csproj @@ -251,6 +251,7 @@ MSBuild:Compile Designer + @@ -264,6 +265,7 @@ True True + @@ -278,6 +280,7 @@ + diff --git a/BodyshopUploader/Models/Bodyshop.cs b/BodyshopUploader/Models/Bodyshop.cs new file mode 100644 index 0000000..38b5c68 --- /dev/null +++ b/BodyshopUploader/Models/Bodyshop.cs @@ -0,0 +1,52 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BodyshopUploader.Models +{ + [JsonConverter(typeof(Utils.JsonPathConverter))] + public class Bodyshop : DTO_Base + { + private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + + public Bodyshop() + { + + } + + private string id; + [JsonProperty("id")] + public string Id + { + get { return id; } + set { SetProperty(ref id, value); } + } + + private string _shopname; + [JsonProperty("shopname")] + public string ShopName + { + get { return _shopname; } + set { SetProperty(ref _shopname, value); } + } + + private string _associationId; + [JsonProperty("associations[0].id")] + public string AssociationId + { + get { return _associationId; } + set { SetProperty(ref _associationId, value); } + } + + private bool _associationActive; + [JsonProperty("associations[0].active")] + public bool AssociationActive + { + get { return _associationActive; } + set { SetProperty(ref _associationActive, value); } + } + } +} diff --git a/BodyshopUploader/Utils/ApplicationExceptionHandler.cs b/BodyshopUploader/Utils/ApplicationExceptionHandler.cs new file mode 100644 index 0000000..1d41514 --- /dev/null +++ b/BodyshopUploader/Utils/ApplicationExceptionHandler.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BodyshopUploader.Utils +{ + public static class ApplicationExceptionHandler + { + private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + + public static void InitExceptionHandlers() + { + AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); + //do something with the file contents + } + + public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + logger.Fatal((e.ExceptionObject as Exception), "Unhandled generic exception."); + } + } +} diff --git a/BodyshopUploader/Utils/JobProcessingQueue.cs b/BodyshopUploader/Utils/JobProcessingQueue.cs index 7fe78df..9b414b1 100644 --- a/BodyshopUploader/Utils/JobProcessingQueue.cs +++ b/BodyshopUploader/Utils/JobProcessingQueue.cs @@ -79,8 +79,6 @@ namespace BodyshopUploader.Utils private static void DecodeQueueItemJob(DTO_QueueItem item) { - //Process the job. - logger.Info("Should process the job here. {0}", item.FilePath); item.Job = Utils.Decoder.EstimateDecoder.CIECAEstimateImport.DecodeEstimate(item.FilePath); } diff --git a/BodyshopUploader/Utils/JsonConverter.cs b/BodyshopUploader/Utils/JsonConverter.cs new file mode 100644 index 0000000..1faefd0 --- /dev/null +++ b/BodyshopUploader/Utils/JsonConverter.cs @@ -0,0 +1,57 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace BodyshopUploader.Utils +{ + class JsonPathConverter : JsonConverter + { + public override object ReadJson(JsonReader reader, Type objectType, + object existingValue, JsonSerializer serializer) + { + JObject jo = JObject.Load(reader); + object targetObj = Activator.CreateInstance(objectType); + + foreach (PropertyInfo prop in objectType.GetProperties() + .Where(p => p.CanRead && p.CanWrite)) + { + JsonPropertyAttribute att = prop.GetCustomAttributes(true) + .OfType() + .FirstOrDefault(); + + string jsonPath = (att != null ? att.PropertyName : prop.Name); + JToken token = jo.SelectToken(jsonPath); + + if (token != null && token.Type != JTokenType.Null) + { + object value = token.ToObject(prop.PropertyType, serializer); + prop.SetValue(targetObj, value, null); + } + } + + return targetObj; + } + + public override bool CanConvert(Type objectType) + { + // CanConvert is not called when [JsonConverter] attribute is used + return false; + } + + public override bool CanWrite + { + get { return false; } + } + + public override void WriteJson(JsonWriter writer, object value, + JsonSerializer serializer) + { + throw new NotImplementedException(); + } + } +} diff --git a/BodyshopUploader/ViewModels/MainViewModel.cs b/BodyshopUploader/ViewModels/MainViewModel.cs index 2760371..744fd82 100644 --- a/BodyshopUploader/ViewModels/MainViewModel.cs +++ b/BodyshopUploader/ViewModels/MainViewModel.cs @@ -2,9 +2,11 @@ using BodyshopUploader.Utils.Growls; using GraphQL.Client; using GraphQL.Common.Request; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -18,9 +20,38 @@ namespace BodyshopUploader.ViewModels public MainViewModel() { + logger.Trace("Main VM constructed."); + + BackgroundWorker bw = new BackgroundWorker(); + bw.DoWork += bw_InitVm; + bw.WorkerReportsProgress = true; + bw.ProgressChanged += Bw_ProgressChanged; + bw.RunWorkerCompleted += Bw_RunWorkerCompleted; + bw.RunWorkerAsync(); + Growler = new GrowlNotification(this); Utils.JobProcessingQueue.SetGrowler(Growler); + + } + + private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + ((BackgroundWorker)sender).Dispose(); + //Progress = 0; + logger.Trace("BW Completed."); + } + + private void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + Progress = e.ProgressPercentage; + } + + private void bw_InitVm(object sender, DoWorkEventArgs e) + { + BackgroundWorker _callingThread = sender as BackgroundWorker; + _callingThread.ReportProgress(1); + //Restore list of paths, convert to monitor object. List listOfPaths = Properties.Settings.Default.MonitoringPaths; if (listOfPaths == null) listOfPaths = new List(); @@ -29,9 +60,19 @@ namespace BodyshopUploader.ViewModels MonitoringPaths.Add(new Models.Monitor() { FilePath = p }); } MonitoringPaths.CollectionChanged += MonitoringPathsChanged; - logger.Trace("Main VM Created."); + _callingThread.ReportProgress(30); + + //Cannot use await. + LoadBodyshopData().Wait(); ; + + + _callingThread.ReportProgress(80); + + logger.Debug("VM Init Complete"); + _callingThread.ReportProgress(100); } + private void MonitoringPathsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { logger.Warn("TODO: Change monitoring lifecycles for folder watchers."); @@ -83,6 +124,84 @@ namespace BodyshopUploader.ViewModels } } + public async Task LoadBodyshopData() + { + var r = new GraphQLRequest + { + Query = @"query QUERY_BODYSHOPS { + bodyshops { + shopname + id + associations { + id + active + } + } + }" + }; + + using (var g = Utils.GraphQL.CreateGQLClient()) + { + logger.Trace("Firing GQL Query: {0}", r.ToString()); + var graphQLResponse = await g.PostAsync(r); + if (graphQLResponse.Errors == null) + { + logger.Trace("GQL Response: {0}", graphQLResponse.Data.bodyshops); + var p = graphQLResponse.Data.bodyshops; + ShopData = graphQLResponse.Data.bodyshops.ToObject>(); + + } + else + { + logger.Error("Error querying bodyshop data."); + } + + } + } + + public async Task SetActiveBodyshop(Bodyshop b) + { + foreach (var s in ShopData) + { + if (s.Id == ActiveShop.Id) s.AssociationActive = true; + else s.AssociationActive = false; + + + var r = new GraphQLRequest + { + Query = @" + mutation UPDATE_ASSOCIATION($assocId: uuid, $assocActive: Boolean) { + update_associations(where: {id: {_eq: $assocId}}, _set: {active: $assocActive}) { + returning { + id + active + } + } + } + ", + Variables = new + { + assocId = s.AssociationId, + assocActive = s.AssociationActive + } + }; + + using (var g = Utils.GraphQL.CreateGQLClient()) + { + logger.Trace("Firing GQL Query: {0}", r.ToString()); + var graphQLResponse = await g.PostAsync(r); + if (graphQLResponse.Errors == null) + { + logger.Trace("GQL Response: {0}", graphQLResponse.Data); + } + else + { + logger.Error("Error mutating data."); + } + } + } + } + public async Task TestGql() { Notification _n = new Notification() @@ -98,20 +217,18 @@ namespace BodyshopUploader.ViewModels var r = new GraphQLRequest { Query = @" - query { - jobs { - id - est_number - ro_number - } - } - " + query QUERY_BODYSHOPS { + bodyshops { + shopname + id + } + }" }; using (var g = Utils.GraphQL.CreateGQLClient()) { var graphQLResponse = await g.PostAsync(r); - logger.Info(graphQLResponse.Data.jobs); + logger.Info("GQL Response: {0}", graphQLResponse.Data.bodyshops); } } } diff --git a/BodyshopUploader/ViewModels/MainViewModel.props.cs b/BodyshopUploader/ViewModels/MainViewModel.props.cs index 17d5e84..d50d276 100644 --- a/BodyshopUploader/ViewModels/MainViewModel.props.cs +++ b/BodyshopUploader/ViewModels/MainViewModel.props.cs @@ -19,5 +19,27 @@ namespace BodyshopUploader.ViewModels get { return _monitoringPaths; } set { SetProperty(ref _monitoringPaths, value); } } + + private ObservableCollection _shopData; + public ObservableCollection ShopData + { + get { return _shopData; } + set { SetProperty(ref _shopData, value); } + } + + private int _progress; + public int Progress + { + get { return _progress; } + set { SetProperty(ref _progress, value); } + } + + + private Bodyshop _activeShop; + public Bodyshop ActiveShop + { + get { return _activeShop; } + set { SetProperty(ref _activeShop, value); SetActiveBodyshop(value); } + } } } diff --git a/BodyshopUploader/Views/Login.xaml.cs b/BodyshopUploader/Views/Login.xaml.cs index 438bfe3..43e3739 100644 --- a/BodyshopUploader/Views/Login.xaml.cs +++ b/BodyshopUploader/Views/Login.xaml.cs @@ -23,6 +23,7 @@ namespace BodyshopUploader.Views public Login() { InitializeComponent(); + Utils.ApplicationExceptionHandler.InitExceptionHandlers(); } private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) { diff --git a/BodyshopUploader/Views/Main.xaml b/BodyshopUploader/Views/Main.xaml index 3499df0..342c6d2 100644 --- a/BodyshopUploader/Views/Main.xaml +++ b/BodyshopUploader/Views/Main.xaml @@ -67,6 +67,16 @@ + + + + + + + +