using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.Logikal; using InABox.Wpf; using InABox.WPF; using javax.swing; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PRSDesktop.Utils.LogikalUtils { public static class LogikalCommon { public static JobStatus? JobStatus { get; private set; } public static TaxCode? TaxCode { get; private set; } public static ProductDimensionUnit? ProfileUOM { get; private set; } public static ProductDimensionUnit? ComponentUOM { get; private set; } public static ProductDimensionUnit? GlassUOM { get; private set; } public static bool CheckSettings(LogikalSettings settings) { List errors = new(); MultiQuery query = new MultiQuery(); Progress.ShowModal("Checking Settings", progress => { if (settings.ImportJobs) query.Add( new Filter(x => x.Code).IsEqualTo(settings.JobStatus), Columns.All() ); query.Add( new Filter(x => x.Code).IsEqualTo(settings.TaxCode), Columns.All() ); query.Add( new Filter(x => x.Code) .InList([settings.ProfileUom, settings.ComponentUom, settings.GlassUom]), Columns.All() ); query.Query(); }); if (settings.ImportJobs) { JobStatus = query.Get().ToObjects().FirstOrDefault(); if (JobStatus == null) errors.Add("Job Status has not been configured correctly!"); } TaxCode = query.Get().ToObjects().FirstOrDefault(); if (TaxCode == null) errors.Add("Tax Code has not been configured correctly!"); var _uoms = query.Get().ToObjects().ToList(); ProfileUOM = _uoms.FirstOrDefault(x => string.Equals(x.Code, settings.ProfileUom)); ComponentUOM = _uoms.FirstOrDefault(x => string.Equals(x.Code, settings.ComponentUom)); GlassUOM = _uoms.FirstOrDefault(x => string.Equals(x.Code, settings.GlassUom)); if (ProfileUOM == null) errors.Add("Profile UOM has not been configured correctly!"); if (ComponentUOM == null) errors.Add("Component UOM has not been configured correctly!"); if (GlassUOM == null) errors.Add("Glass UOM has not been configured correctly!"); if (errors.Any()) { MessageWindow.ShowMessage( $"Some Configuration Settings are incorrect:\n\n- {string.Join("\n- ", errors)}\n\nPlease correct this and try again.", "Error"); return false; } return true; } } public class LogikalPartsManager { public List Products { get; private set; } = new(); public List ProductStyles { get; private set; } = new(); public List Activities { get; private set; } = new(); public bool CheckMissingItems(ILogikalPartsResponse bom) { List errors = new(); if (LogikalCommon.ProfileUOM == null) errors.Add("Profile UOM is incorrect"); if (LogikalCommon.ComponentUOM == null) errors.Add("Component UOM is incorrect"); if (LogikalCommon.GlassUOM == null) errors.Add("Glass UOM is incorrect"); if (LogikalCommon.TaxCode == null) errors.Add("Tax Code is incorrect"); if (errors.Any()) { MessageWindow.ShowMessage($"Configuration is invalid\n\n- {string.Join("\n- ",errors)}", "Error"); return false; } string[] _requiredProfiles = bom.Profiles .Select(x => x.Code ?? "") .Where(x => !string.IsNullOrWhiteSpace(x)) .Distinct() .ToArray(); string[] _requiredFinishes = bom.Finishes .Select(x => x.Code ?? "") .Where(x => !string.IsNullOrWhiteSpace(x)) .Distinct() .ToArray(); string[] _requiredComponents = bom.Components .Select(x => x.Code ?? "") .Where(x => !string.IsNullOrWhiteSpace(x)) .Distinct() .ToArray(); string[] _requiredGlass = bom.Glass .Select(x => x.Code ?? "") .Where(x => !string.IsNullOrWhiteSpace(x)) .Distinct() .ToArray(); string[] _requiredProducts = _requiredProfiles .Union(_requiredComponents) .Union(_requiredGlass) .ToArray(); string[] _requiredActivities = bom.Labour .Select(x => x.Code ?? "") .Where(x => !string.IsNullOrWhiteSpace(x)) .Distinct() .ToArray(); MultiQuery query = new MultiQuery(); Progress.ShowModal("Checking Missing Items", progress => { query.Add( new Filter(x => x.Code).InList(_requiredFinishes), Columns.All() ); query.Add( new Filter(x => x.Code).InList(_requiredProducts), Columns.None() .Add(x => x.ID) .Add(x => x.Code) .Add(x => x.Name) .Add(x => x.UnitOfMeasure.ID) .Add(x => x.UnitOfMeasure.Code) .Add(x => x.UnitOfMeasure.Description) .Add(x => x.UnitOfMeasure.HasQuantity) .Add(x => x.UnitOfMeasure.HasLength) .Add(x => x.UnitOfMeasure.HasWidth) .Add(x => x.UnitOfMeasure.HasHeight) .Add(x => x.UnitOfMeasure.Format) .Add(x => x.UnitOfMeasure.Formula) .Add(x => x.TaxCode.ID) .Add(x => x.TaxCode.Code) ); query.Add( new Filter(x => x.Code).InList(_requiredActivities), Columns.All() ); query.Query(); }); ProductStyles = query.Get().ToObjects().ToList(); var _missingFinishes = bom.Finishes.Where(l => !ProductStyles.Any(s => string.Equals(l.Code, s.Code))).ToArray(); if (_missingFinishes.Any()) { var missing = string.Join("\n- ", _missingFinishes.Select(x => $"{x.Code}: {x.Description}")); if (!MessageWindow.ShowYesNo( $"The following Product Styles are missing\n- {missing}\n\nDo you wish to create them now?", "Missing Finishes")) return false; } Products = query.Get().ToObjects().ToList(); var _missingProducts = _requiredProducts.Where(x => Products.Any(p => !string.Equals(p.Code, x))).ToArray(); var _missingProfiles = bom.Profiles.Where(x => _missingProducts.Contains(x.Code)).ToArray(); if (_missingProfiles.Any()) { var missing = string.Join("\n- ", _missingProfiles.Select(x => $"{x.Code}: {x.Description}")); if (!MessageWindow.ShowYesNo( $"The following Profiles are missing\n- {missing}\n\nDo you wish to create them now?", "Missing Profiles")) return false; } var _missingComponents = bom.Components.Where(x => _missingProducts.Contains(x.Code)).ToArray(); if (_missingComponents.Any()) { var missing = string.Join("\n- ", _missingComponents.Select(x => $"{x.Code}: {x.Description}")); if (!MessageWindow.ShowYesNo( $"The following Components are missing\n- {missing}\n\nDo you wish to create them now?", "Missing Components")) return false; } var _missingGlasses = bom.Glass.Where(x => _missingProducts.Contains(x.Code)).ToArray(); if (_missingGlasses.Any()) { var missing = string.Join("\n- ", _missingGlasses.Select(x => $"{x.Code}: {x.Description}")); if (!MessageWindow.ShowYesNo( $"The following Glass Codes are missing\n- {missing}\n\nDo you wish to create them now?", "Missing Glass")) return false; } Activities = query.Get().ToObjects().ToList(); var _missingActivities = bom.Labour.Where(l => !Activities.Any(a => string.Equals(l.Code,a.Code))).ToArray(); if (_missingActivities.Any()) { var missing = string.Join("\n- ", _missingActivities.Select(x => $"{x.Code}: {x.Description}")); if (!MessageWindow.ShowYesNo( $"The following Activities are missing\n- {missing}\n\nDo you wish to create them now?", "Missing Products")) return false; } if (_missingFinishes.Any() || _missingProducts.Any() || _missingActivities.Any()) { Progress.ShowModal("Creating Missing Items", progress => { if (_missingFinishes.Any()) { progress.Report("Creating Missing Finishes"); List _newFinishes = new(); foreach (var _missingFinish in _missingFinishes) { _newFinishes.Add( new ProductStyle() { Code = _missingFinish.Code, Description = _missingFinish.Description } ); } Client.Save(_newFinishes, "Created By LogikalImport"); ProductStyles.AddRange(_newFinishes); } if (_missingProfiles.Any()) { progress.Report("Creating Missing Profiles"); List _newProfiles = new(); foreach (var _missingProfile in _missingProfiles) { var _newprofile = new Product() { Code = _missingProfile.Code ?? "", Name = _missingProfile.Description ?? "" }; _newprofile.Problem.Notes = new string[] { "Created by Logikal Import" }; _newprofile.UnitOfMeasure.CopyFrom(LogikalCommon.ProfileUOM); _newProfiles.Add(_newprofile); } Client.Save(_newProfiles, "Created By LogikalImport"); Products.AddRange(_newProfiles); } if (_missingComponents.Any()) { progress.Report("Creating Missing Components"); List _newComponents = new(); foreach (var _missingComponent in _missingComponents) { var _newComponent = new Product() { Code = _missingComponent.Code ?? "", Name = _missingComponent.Description ?? "", }; _newComponent.Problem.Notes = new string[] { "Created by Logikal Import" }; _newComponent.UnitOfMeasure.CopyFrom(LogikalCommon.ComponentUOM); _newComponents.Add(_newComponent); } Client.Save(_newComponents, "Created By LogikalImport"); Products.AddRange(_newComponents); } if (_missingGlasses.Any()) { progress.Report("Creating Missing Glass"); List _newGlasses = new(); foreach (var _missingGlass in _missingGlasses) { var _newGlass = new Product() { Code = _missingGlass.Code ?? "", Name = _missingGlass.Description ?? "", }; _newGlass.Problem.Notes = new string[] { "Created by Logikal Import" }; _newGlass.UnitOfMeasure.CopyFrom(LogikalCommon.GlassUOM); _newGlasses.Add(_newGlass); } Client.Save(_newGlasses, "Created By LogikalImport"); Products.AddRange(_newGlasses); } if (_missingActivities.Any()) { progress.Report("Creating Missing Activities"); List _newActivities = new(); foreach (var _missingActivity in _missingActivities) { var _newActivity = new Comal.Classes.Activity() { Code = _missingActivity.Code, Description = _missingActivity.Description, }; _newActivity.Problem.Notes = new string[] { "Created by Logikal Import" }; _newActivities.Add(_newActivity); } Client.Save(_newActivities, "Created By LogikalImport"); Activities.AddRange(_newActivities); } }); List _missing = new(); _missing.AddRange(_missingFinishes.Select(x => $"- Style {x.Code}: {x.Description}").Distinct().OrderBy(x => x)); _missing.AddRange(_missingProfiles.Select(x => $"- Profile {x.Code}: {x.Description}").Distinct().OrderBy(x => x)); _missing.AddRange(_missingComponents.Select(x => $"- Component {x.Code}: {x.Description}").Distinct().OrderBy(x => x)); _missing.AddRange(_missingGlasses.Select(x => $"- Glass {x.Code}: {x.Description}").Distinct().OrderBy(x => x)); _missing.AddRange(_missingActivities.Select(x => $"- Activity {x.Code}: {x.Description}").Distinct().OrderBy(x => x)); if (_missing.Any()) MessageWindow.ShowMessage($"The following items were auto-created and should be manually checked:\n{String.Join("\n", _missing)}", "Results"); } return true; } public T[] CreateItems(JobBillOfMaterials jobbom, LogikalBOMResponse bom, Action customise) where T : StockEntity, IJobMaterial, new() { List results = new List(); foreach (var profile in bom.Profiles) { var product = Products.FirstOrDefault(x => string.Equals(x.Code, profile.Code)) ?? new Product(); var finish = ProductStyles.FirstOrDefault(x => string.Equals(x.Code, profile.Finish)) ?? new ProductStyle(); if (product != null) { T newitem = new T(); newitem.Job.ID = jobbom.Job.ID; newitem.Product.CopyFrom(product); newitem.Dimensions.Unit.CopyFrom(product.UnitOfMeasure); newitem.Dimensions.Length = profile.Length; newitem.Style.CopyFrom(finish); customise(profile, newitem); results.Add(newitem); } } foreach (var component in bom.Components) { var product = Products.FirstOrDefault(x => string.Equals(x.Code, component.Code)) ?? new Product(); if (product != null) { T newitem = new T(); newitem.Job.ID = jobbom.Job.ID; newitem.Product.CopyFrom(product); newitem.Dimensions.Unit.CopyFrom(product.UnitOfMeasure); newitem.Dimensions.Quantity = component.PackSize; customise(component, newitem); results.Add(newitem); } } foreach (var glass in bom.Glass) { var product = Products.FirstOrDefault(x => string.Equals(x.Code, glass.Code)) ?? new Product(); if (product != null) { T newitem = new T(); newitem.Job.ID = jobbom.Job.ID; newitem.Product.CopyFrom(product); newitem.Dimensions.Unit.CopyFrom(product.UnitOfMeasure); newitem.Dimensions.Height = glass.Height; newitem.Dimensions.Height = glass.Width; customise(glass, newitem); results.Add(newitem); } } return results.ToArray(); } } }