using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Media.Imaging; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.Wpf; using InABox.WPF; using NPOI.OpenXmlFormats.Wordprocessing; namespace PRSDesktop; public class V6ProjectImportGrid : DynamicItemsListGrid { private static BitmapImage Quotation => PRSDesktop.Resources.quotation.AsBitmapImage(); private static BitmapImage Revision => PRSDesktop.Resources.revision.AsBitmapImage(); public V6ProjectImportGrid() { ActionColumns.Add(new DynamicImageColumn(StatusImage) { Position = DynamicActionColumnPosition.Start}); } private BitmapImage? StatusImage(CoreRow? row) { return row == null ? Quotation : string.IsNullOrWhiteSpace(row.Get(x => x.Variation)) ? Quotation : Revision; } protected override void DoReconfigure(DynamicGridOptions options) { base.DoReconfigure(options); options.FilterRows = true; options.HideDatabaseFilters = true; } } public partial class V6ProjectImport : Window { private readonly V6Client _client; public V6ProjectImport() { InitializeComponent(); _client = new V6Client(); ImportCosts.SelectedValue = _client.Settings.ImportCosts; ImportDesigns.SelectedValue = _client.Settings.ImportDesigns; if (_client.Connect()) { Task> v6Task = Task.Run(() => { var _quotes = _client.IsConnected ? _client?.GetQuotes()?.ToList() : null; return _quotes ?? new List(); }); Task> prsTask = Task.Run(() => Client.Query(null, Columns.None().Add(x => x.Job.ID).Add(x => x.Job.JobNumber).Add(x=>x.Job.SourceRef).Add(x=>x.Job.DefaultScope.ID).Add(x=>x.ID).Add(x=>x.Number).Add(x=>x.SourceRef) ).ToObjects().ToList()); Task.WaitAll(v6Task,prsTask); var quotes = v6Task.Result; var scopes = prsTask.Result; Projects.Items = quotes .Where(q => string.IsNullOrWhiteSpace(q.Variation) ? !scopes.Any(x=>string.Equals(x.Job.DefaultScope.SourceRef, $"{q.Number}")) : !scopes.Any(x=> string.Equals(x.SourceRef,$"{q.Number}"))) .ToList(); } else { MessageWindow.ShowMessage("Cannot connect to V6!","Error"); Projects.Items = new List(); } Projects.Refresh(true,true); } private void OK_Click(object sender, RoutedEventArgs e) { var _project = Projects.LoadItem(Projects.SelectedRows.First()); var _importCosts = (V6ImportCosts)ImportCosts.SelectedValue; var _importDesigns = (V6ImportDesigns)ImportDesigns.SelectedValue; JobStatus? _statusCode = new(); TaxCode? _taxCode = new(); ProductDimensionUnit? _profileUom = new(); ProductDimensionUnit? _componentUom = new(); ProductDimensionUnit? _glassUom = new(); ManufacturingTemplate? _template = new ManufacturingTemplate(); ManufacturingTemplateStage[] _stages = []; MultiQuery query = new MultiQuery(); query.Add( new Filter(x=>x.Code).IsEqualTo(_client.Settings.JobStatus), Columns.All().Add(x=>x.ID) ); query.Add( new Filter(x=>x.Code).IsEqualTo(_client.Settings.TaxCode), Columns.All() ); if (_importCosts != V6ImportCosts.None) { query.Add( new Filter(x => x.Code).InList(new string[] { _client.Settings.ProfileUom, _client.Settings.ComponentUom, _client.Settings.GlassUom }), Columns.All() ); } if (_importDesigns == V6ImportDesigns.ToManufacturing) { query.Add(new Filter(x => x.Code).IsEqualTo(_client.Settings.PacketTemplate)); query.Add(new Filter(x => x.Template.Code).IsEqualTo(_client.Settings.PacketTemplate)); } query.Query(); _statusCode = query.Get().Rows.FirstOrDefault()?.ToObject(); if (_statusCode == null) { MessageWindow.ShowMessage( "Job Status setting has not been configured correctly!\nPlease correct this and try again.", "Error"); return; } _taxCode = query.Get().Rows.FirstOrDefault()?.ToObject(); if (_taxCode == null) { MessageWindow.ShowMessage( "Tax Code setting has not been configured correctly!\nPlease correct this and try again.", "Error"); return; } if (_importDesigns == V6ImportDesigns.ToManufacturing) { _template = query.Get().Rows.FirstOrDefault()?.ToObject(); _stages = query.Get().ToObjects().ToArray(); } if (_importCosts != V6ImportCosts.None) { var _uoms = query.Get().ToObjects().ToList(); _profileUom = _uoms.FirstOrDefault(x => string.Equals(x.Code, _client.Settings.ProfileUom)); _componentUom = _uoms.FirstOrDefault(x => string.Equals(x.Code, _client.Settings.ComponentUom)); _glassUom = _uoms.FirstOrDefault(x => string.Equals(x.Code, _client.Settings.GlassUom)); } if (_profileUom == null) { MessageWindow.ShowMessage( "Profile UOM setting has not been configured correctly!\nPlease correct this and try again.", "Error"); return; } if (_componentUom == null) { MessageWindow.ShowMessage( "Component UOM settings has not been configured correctly!\nPlease correct this and try again.", "Error"); return; } if (_glassUom == null) { MessageWindow.ShowMessage( "Glass UOM setting has not been configured correctly!\nPlease correct this and try again.", "Error"); return; } if (_template == null) { MessageWindow.ShowMessage( "Packet Template setting has not been configured correctly!\nPlease correct this and try again.", "Error"); return; } List _finishes = new(); List _profiles = new(); List _components = new(); List _glass = new(); List _labour = new(); List _styles = new(); List _products = new(); List _activities = new(); Dictionary _designs = new(); List _missingProfiles = new(); List _missingComponents = new(); List _missingGlass = new(); List _missingLabour = new(); List _missingFinishes = new(); string exception = null; if (_importCosts != V6ImportCosts.None) { Progress.ShowModal("Checking Products", progress => { try { progress.Report("Loading Profiles"); _profiles = _client.GetProfiles(_project.Number, _project.Variation); } catch (Exception _exception) { exception = $"Error retrieving Profiles : {_exception.Message}"; return; } try { progress.Report("Loading Components"); _components = _client.GetComponents(_project.Number, _project.Variation); } catch (Exception _exception) { exception = $"Error retrieving Components : {_exception.Message}"; return; } try { progress.Report("Loading Glass"); _glass = _client.GetGlass(_project.Number, _project.Variation); } catch (Exception _exception) { exception = $"Error retrieving Glass : {_exception.Message}"; return; } progress.Report("Checking PRS Codes"); MultiQuery query = new MultiQuery(); var _productStyles = _profiles.Select(x => x.Finish) .Union(_glass.Select(x => x.Treatment)) .Distinct() .ToArray(); query.Add( new Filter(x => x.Code).InList(_productStyles), Columns.None().Add(x => x.ID).Add(x => x.Code) ); var _productcodes = _profiles.Select(x => x.Code) .Union(_components.Select(x => x.Code)) .Union(_glass.Select(x => x.Code)) .Distinct() .ToArray(); query.Add( new Filter(x => x.Code).InList(_productcodes), 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.Query(); _styles = query.Get().ToObjects().ToList(); _products = query.Get().ToObjects().ToList(); _missingFinishes.AddRange(_productStyles.Where(c => !string.IsNullOrWhiteSpace(c) && !_styles.Any(p => string.Equals(p.Code, c)))); var _missingCodes = _productcodes.Where(c => !_products.Any(p => string.Equals(p.Code, c))).ToArray(); _missingProfiles.AddRange(_profiles.Where(x => _missingCodes.Contains(x.Code))); _missingComponents.AddRange(_components.Where(x => _missingCodes.Contains(x.Code))); _missingGlass.AddRange(_glass.Where(x => _missingCodes.Contains(x.Code))); }); if (!string.IsNullOrWhiteSpace(exception)) { MessageWindow.ShowMessage(exception,"V6 Error",PRSDesktop.Resources.warning.AsBitmapImage()); return; } if (_missingProfiles.Any() || _missingComponents.Any() || _missingGlass.Any()) { if (!MessageWindow.ShowYesNo( $"The following products do not exist in PRS\n" + $"- {string.Join("\n- ", _missingProfiles.Select(x => x.Code) .Union(_missingComponents.Select(x => x.Code)) .Union(_missingGlass.Select(x => x.Code)) .Distinct().OrderBy(x => x))}\n\n" + $"Do you wish to create them now?", "Create Missing Products")) return; } if (_missingFinishes.Any()) { if (!MessageWindow.ShowYesNo( $"The following styles do not exist in PRS\n" + $"- {string.Join("\n- ", _missingFinishes .Distinct().OrderBy(x => x))}\n\n" + $"Do you wish to create them now?", "Create Missing Styles")) return; } Progress.ShowModal("Checking Labour", progress => { progress.Report("Loading Labour"); _labour = _client.GetLabour(_project.Number, _project.Variation); var _labourcodes = _labour.Select(x => x.Code).Distinct().ToArray(); _activities = Client.Query( new Filter(x => x.Code).InList(_labourcodes), Columns.None() .Add(x => x.ID) .Add(x => x.Code) .Add(x => x.Description) ).ToObjects().ToList(); var _missingCodes = _labourcodes.Where(l => !_activities.Any(a => string.Equals(a.Code, l))).ToArray(); _missingLabour.AddRange(_labour.Where(x => _missingCodes.Contains(x.Code))); }); if (_missingLabour.Any()) { if (!MessageWindow.ShowOKCancel( $"The following products do not exist in PRS\n" + $"- {string.Join("\n- ", _missingLabour.Select(x => x.Code).Distinct().OrderBy(x => x))}\n\n" + $"Do you wish to create them?", "Create Missing Activities")) return; } } List designExceptions = new(); if (_importDesigns != V6ImportDesigns.None) { List _designlist = new(); Progress.ShowModal("Checking Designs", progress => { try { _designlist = _client.GetItems(_project.Number, _project.Variation); } catch (Exception _exception) { designExceptions.Add($"Error retrieving designs : {_exception.Message}"); return; } foreach (var _design in _designlist) { try { _designs[_design] = new V6Drawings(); } catch (Exception _exception) { designExceptions.Add($"Error retrieving design [{_design.Description}]: {_exception.Message}"); } } }); } if (designExceptions.Any()) { MessageWindow.ShowMessage(string.Join("\n",designExceptions),"V6 Error",PRSDesktop.Resources.warning.AsBitmapImage()); return; } string createException = ""; Progress.ShowModal("Creating Job", progress => { try { var _scope = CreateJob(_project, _statusCode, _taxCode); if (_importCosts != V6ImportCosts.None) { CreateMissingStyles(_missingFinishes, _styles); CreateMissingProducts(_profileUom, _taxCode, _missingProfiles, _products); CreateMissingProducts(_componentUom, _taxCode, _missingComponents, _products); CreateMissingProducts(_glassUom, _taxCode, _missingGlass, _products); CreateMissingLabour(_missingLabour, _activities); progress.Report("Creating Bill of Materials"); var bom = CreateBillofMaterials(_project, _scope, _profiles, _profileUom, _components, _componentUom, _glass, _glassUom, _products, _styles); if (_importCosts == V6ImportCosts.Requisitions) { // Convert BOM to Requisition } progress.Report("Creating Labour Budget"); CreateActivities(_project, _scope, _labour, _activities); } if (_importDesigns != V6ImportDesigns.None) { progress.Report("Loading Drawings"); foreach (var _key in _designs.Keys) { progress.Report($"Loading Drawing: {_key.Description}"); _designs[_key] = _client.GetDrawings(_key.ID); } if (_importDesigns == V6ImportDesigns.ForApproval) CreateStagedSetouts(_project, _scope, _designs, _template, _stages); else CreateManufacturingPackets(_project, _scope, _designs, _template, _stages); } } catch (Exception _exception) { createException = $"Error Creating Job: {_exception.Message}\n{_exception.StackTrace}"; } }); if (!string.IsNullOrWhiteSpace(createException)) { MessageWindow.ShowMessage(createException,"PRS Error",PRSDesktop.Resources.warning.AsBitmapImage()); return; } List _missing = new(); _missing.AddRange(_missingLabour.Select(x => $"- Activity {x.Code}: {x.Description}").Distinct().OrderBy(x => x)); _missing.AddRange(_missingFinishes.Select(x => $"- Style {x}").Distinct().OrderBy(x => x)); _missing.AddRange(_missingProfiles.Select(x => $"- Product {x.Code}: {x.Description}") .Union(_missingComponents.Select(x => $"- Product {x.Code}: {x.Description}")) .Union(_missingGlass.Select(x => $"- Product {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"); DialogResult = true; } private static void CreateMissingLabour(List missinglabour, List activitylist) { List _updates = new(); foreach (var _missing in missinglabour) { if (!_updates.Any(x => String.Equals(x.Code, _missing.Code))) { var _activity = new Activity(); _activity.Code = _missing.Code; _activity.Description = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(_missing.Code.ToLower()); _activity.Issues = $"Created By V6 Import"; _updates.Add(_activity); } } Client.Save(_updates, "Created by V6 Import"); activitylist.AddRange(_updates); } private static void CreateMissingStyles( List missingitems, List styleList) { List _updates = new(); foreach (var _missingitem in missingitems) { if (!_updates.Any(x => String.Equals(x.Code, _missingitem))) { var _productstyle = new ProductStyle(); _productstyle.Code = _missingitem; _productstyle.Description = _missingitem; _productstyle.Issues = $"Created By V6 Import"; _updates.Add(_productstyle); } } Client.Save(_updates, "Created by V6 Import"); styleList.AddRange(_updates); } private static void CreateMissingProducts(ProductDimensionUnit uom, TaxCode tax, List missingitems, List productlist) where T : V6BOMItem { List _updates = new(); foreach (var _missingitem in missingitems) { if (!_updates.Any(x => String.Equals(x.Code, _missingitem.Code))) { var _product = new Product(); _product.UnitOfMeasure.CopyFrom(uom); _product.Code = _missingitem.Code; _product.Name = _missingitem.Description; _product.Issues = $"Created By V6 Import"; _product.TaxCode.CopyFrom(tax); _updates.Add(_product); } } Client.Save(_updates, "Created by V6 Import"); productlist.AddRange(_updates); } private static JobScope CreateJob(V6Quote quote, JobStatus status, TaxCode tax) { var _jobno = $"V{quote.Number}"; MultiQuery query = new MultiQuery(); query.Add( new Filter(x=>x.JobNumber).IsEqualTo(_jobno), Columns.Required().Add(x=>x.DefaultScope.ID) ); query.Query(); var _scope = new JobScope(); var _job = query.Get().ToObjects()?.FirstOrDefault(); if (_job == null) { _job = new Job(); _job.JobNumber = _jobno; _job.Name = quote.Title; _job.JobStatus.CopyFrom(status); Client.Save(_job,"Imported From V6"); _scope.ID = _job.DefaultScope.ID; _scope.CommitChanges(); } _scope.Job.ID = _job.ID; _scope.Number = quote.Variation; _scope.SourceRef = $"{quote.ID}.{quote.Revision}"; _scope.Description = string.IsNullOrWhiteSpace(quote.Variation) ? "Main Job" : quote.Title; _scope.ExTax = quote.SellPrice; _scope.TaxCode.CopyFrom(tax); _scope.Type = string.IsNullOrWhiteSpace(quote.Variation) ? JobScopeType.Contract : JobScopeType.Variation; Client.Save(_scope, "Imported From V6"); return _scope; } private JobBillOfMaterials CreateBillofMaterials(V6Quote quote, JobScope scope, List profiles, ProductDimensionUnit profileUOM, List components, ProductDimensionUnit componentUOM, List glass, ProductDimensionUnit glassUOM, List _products, List _styles) { var _bom = new JobBillOfMaterials(); _bom.Job.ID = scope.Job.ID; _bom.Description = string.IsNullOrWhiteSpace(quote.Variation) ? "Main Job" : $"{quote.Variation}"; Client.Save(_bom,"Imported From V6"); List _bomitems = new(); foreach (var _profile in profiles) { var _bomitem = new JobBillOfMaterialsItem(); _bomitem.BillOfMaterials.ID = _bom.ID; _bomitem.Job.ID = scope.Job.ID; _bomitem.Scope.ID = scope.ID; if (_products.FirstOrDefault(x => x.Code == _profile.Code) is { } _p) { _bomitem.Product.CopyFrom(_p); _bomitem.Dimensions.Unit.CopyFrom(profileUOM); _bomitem.Dimensions.Length = _profile.Length; } else _bomitem.Issues = $"Unable to Locate Product: {_profile.Quantity} x {_profile.Code}: {_profile.Description} ({_profile.Length})"; if (!string.IsNullOrWhiteSpace(_profile.Finish)) { if (_styles.FirstOrDefault(x => x.Code == _profile.Finish) is { } _s) _bomitem.Style.CopyFrom(_s); else _bomitem.Issues = $"Unable to Locate Style: {_profile.Finish}"; } _bomitem.Quantity = _profile.Quantity; _bomitem.UnitCost = _profile.Cost; _bomitems.Add(_bomitem); } foreach (var _component in components) { var _bomitem = new JobBillOfMaterialsItem(); _bomitem.BillOfMaterials.ID = _bom.ID; _bomitem.Job.ID = scope.Job.ID; _bomitem.Scope.ID = scope.ID; if (_products.FirstOrDefault(x => x.Code == _component.Code) is { } _s) { _bomitem.Product.CopyFrom(_s); _bomitem.Dimensions.Unit.CopyFrom(componentUOM); _bomitem.Dimensions.Quantity = 1; _bomitems.Add(_bomitem); } else _bomitem.Issues = $"Unable to Locate Product: {_component.Quantity} x {_component.Code}: {_component.Description} ({_component.PackSize})"; _bomitem.Quantity = _component.Quantity * _component.PackSize; _bomitem.UnitCost = _component.Cost; } foreach (var _glass in glass) { var _bomitem = new JobBillOfMaterialsItem(); _bomitem.BillOfMaterials.ID = _bom.ID; _bomitem.Job.ID = scope.Job.ID; _bomitem.Scope.ID = scope.ID; if (_products.FirstOrDefault(x => x.Code == _glass.Code) is { } _p) { _bomitem.Product.CopyFrom(_p); _bomitem.Dimensions.Unit.CopyFrom(glassUOM); _bomitem.Dimensions.Height = _glass.Height * 25.4; _bomitem.Dimensions.Width = _glass.Width * 25.4; _bomitems.Add(_bomitem); } else _bomitem.Issues = $"Unable to Locate Product: {_glass.Code}: {_glass.Description} ({_glass.Height} x {_glass.Width})"; if (!string.IsNullOrWhiteSpace(_glass.Treatment)) { if (_styles.FirstOrDefault(x => x.Code == _glass.Treatment) is { } _s) _bomitem.Style.CopyFrom(_s); else _bomitem.Issues = $"Unable to Locate Style: {_glass.Treatment})"; } _bomitem.Quantity = _glass.Quantity; _bomitem.UnitCost = _glass.Cost; } Client.Save(_bomitems,"Imported From V6"); return _bom; } private void CreateActivities(V6Quote project, JobScope scope, List labour, List activities) { var _jobactivities = Client.Query( new Filter(x => x.JobLink.ID).IsEqualTo(scope.Job.ID), Columns.Required() .Add(x => x.JobLink.ID) .Add(x => x.ActivityLink.ID) .Add(x => x.Budget) ).ToObjects().ToList(); List _updates = new List(); foreach (var _labour in labour) { var _activity = activities.FirstOrDefault(x => string.Equals(x.Code, _labour.Code)) ?? new Activity(); var _jobactivity = _jobactivities.FirstOrDefault(x => x.ActivityLink.ID == _activity.ID) ?? new JobActivity(); _jobactivity.JobLink.ID = scope.Job.ID; _jobactivity.ActivityLink.CopyFrom(_activity); _jobactivity.Budget += TimeSpan.FromMinutes(_labour.Minutes); _updates.Add(_jobactivity); } Client.Save(_updates,"Imported From V6"); } private void CreateManufacturingPackets(V6Quote project, JobScope scope, Dictionary designs, ManufacturingTemplate template, ManufacturingTemplateStage[] stages) { foreach (var _design in designs) { var _setout = new Setout(); _setout.JobLink.ID = scope.Job.ID; _setout.Description = _design.Key.Description; _setout.Number = _design.Key.Description; Client.Save(_setout,"Imported From V6"); var _drawings = _client.DecodeDrawings(_design.Value.Drawings, new string[] { "FrameDrawing" }); List _documents = new(); foreach (var _drawing in _drawings) { var _document = new Document(); _document.FileName = System.IO.Path.ChangeExtension(_drawing.FileName, ".pdf"); _document.Data = ImageUtils.BitmapToPdf(_drawing.Data); _documents.Add(_document); } if (_documents.Any()) Client.Save(_documents, "Imported From V6"); List _setoutdocuments = new(); foreach (var _document in _documents) { var _setoutdocument = new SetoutDocument(); _setoutdocument.EntityLink.CopyFrom(_setout); _setoutdocument.DocumentLink.CopyFrom(_document); _setoutdocument.Thumbnail = ImageUtils.GetPDFThumbnail(_document.Data, 256, 256); _setoutdocuments.Add(_setoutdocument); } if (_setoutdocuments.Any()) Client.Save(_setoutdocuments, "Imported From V6"); var _packet = new ManufacturingPacket(); _packet.SetoutLink.ID = _setout.ID; _packet.ManufacturingTemplateLink.CopyFrom(template); _packet.Title = _setout.Description; _packet.Quantity = _design.Key.Quantity; Client.Save(_packet,"Imported From V6"); List _packetstages = new(); foreach (var _templatestage in stages) { var _packetstage = new ManufacturingPacketStage { Time = _templatestage.Time, SequenceType = _templatestage.SequenceType, Sequence = _templatestage.Sequence }; _packetstage.Parent.ID = _packet.ID; _packetstage.ManufacturingSectionLink.ID = _templatestage.Section.ID; _packetstage.ManufacturingSectionLink.Name = _templatestage.Section.Name; _packetstages.Add(_packetstage); } if (_packetstages.Any()) Client.Save(_packetstages,"Imported from V6"); } } private void CreateStagedSetouts(V6Quote project, JobScope scope, Dictionary designs, ManufacturingTemplate template, ManufacturingTemplateStage[] stages) { foreach (var _design in designs) { var _setout = new StagingSetout(); _setout.JobLink.ID = scope.Job.ID; _setout.Number = _design.Key.Description; Client.Save(_setout,"Imported From V6"); var _drawings = _client.DecodeDrawings(_design.Value.Drawings, new string[] { "FrameDrawing" }); List _documents = new(); foreach (var _drawing in _drawings) { var _document = new Document(); _document.FileName = System.IO.Path.ChangeExtension(_drawing.FileName, ".pdf"); _document.Data = ImageUtils.BitmapToPdf(_drawing.Data); _documents.Add(_document); } if (_documents.Any()) Client.Save(_documents, "Imported From V6"); List _setoutdocuments = new(); foreach (var _document in _documents) { var _setoutdocument = new StagingSetoutDocument(); _setoutdocument.EntityLink.CopyFrom(_setout); _setoutdocument.DocumentLink.CopyFrom(_document); _setoutdocument.Thumbnail = ImageUtils.GetPDFThumbnail(_document.Data, 256, 256); _setoutdocuments.Add(_setoutdocument); } if (_setoutdocuments.Any()) Client.Save(_setoutdocuments, "Imported From V6"); var _packet = new StagingManufacturingPacket(); _packet.StagingSetout.ID = _setout.ID; _packet.Template.CopyFrom(template); _packet.Title = _setout.Number; _packet.Quantity = _design.Key.Quantity; Client.Save(_packet,"Imported From V6"); List _packetstages = new(); foreach (var _templatestage in stages) { var _packetstage = new StagingManufacturingPacketStage { Time = _templatestage.Time, SequenceType = _templatestage.SequenceType, Sequence = _templatestage.Sequence }; _packetstage.Packet.ID = _packet.ID; _packetstage.Section.ID = _templatestage.Section.ID; _packetstage.Section.Name = _templatestage.Section.Name; _packetstages.Add(_packetstage); } if (_packetstages.Any()) Client.Save(_packetstages,"Imported from V6"); } } private void Cancel_Click(object sender, RoutedEventArgs e) { DialogResult = false; } private void Projects_OnOnSelectItem(object sender, DynamicGridSelectionEventArgs e) { Ok.IsEnabled = Projects.SelectedRows.Any(); } }