StagingPanel.xaml.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. using Comal.Classes;
  2. using InABox.Core;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using InABox.Clients;
  9. using InABox.Configuration;
  10. using InABox.DynamicGrid;
  11. using System.Diagnostics;
  12. using System.IO;
  13. namespace PRSDesktop
  14. {
  15. public class StagingPanellSettings : BaseObject, IGlobalConfigurationSettings
  16. {
  17. [Caption("PDF Markup Program Pathway", IncludePath = false)]
  18. [FileNameEditor]
  19. public string MarkupPathway { get; set; }
  20. [FolderEditor(Environment.SpecialFolder.CommonDocuments)]
  21. public string SetoutsFolder { get; set; }
  22. public StagingPanellSettings()
  23. {
  24. MarkupPathway = "";
  25. SetoutsFolder = "";
  26. }
  27. }
  28. /// <summary>
  29. /// Interaction logic for StagingPanel.xaml
  30. /// </summary>
  31. public partial class StagingPanel : UserControl, IPanel<StagingSetout>
  32. {
  33. private StagingPanellSettings _settings = new StagingPanellSettings();
  34. StagingSetout _item = new StagingSetout();
  35. DynamicDataGrid<Document> _materialDocs;
  36. public StagingPanel()
  37. {
  38. InitializeComponent();
  39. SectionName = nameof(StagingPanel);
  40. }
  41. private void DocumentPreviewer_OnApproved(IEntityDocument stagingsetoutdocument)
  42. {
  43. if (_item.Group.ID == Guid.Empty)
  44. {
  45. var message = "Setout has no group assigned";
  46. if (Security.IsAllowed<CanApproveSetoutsWithoutGroup>())
  47. {
  48. if (MessageBox.Show(message + ", continue?", "Continue?", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
  49. return;
  50. }
  51. else
  52. {
  53. MessageBox.Show(message + ", please assign a group!");
  54. return;
  55. }
  56. }
  57. var table = new Client<Setout>().Query(new Filter<Setout>(x => x.Number).IsEqualTo(_item.Number),
  58. new Columns<Setout>(x => x.ID));
  59. var setout = new Setout();
  60. //setout already exists - create new setoutdoc and supercede old ones
  61. if (table.Rows.Any())
  62. {
  63. if (MessageBox.Show("Supercede existing documents?", "Proceed?", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
  64. return;
  65. setout = table.Rows.FirstOrDefault().ToObject<Setout>();
  66. setout.Group.ID = _item.Group.ID;
  67. _item.Setout.ID = setout.ID;
  68. var setoutdoc = new SetoutDocument();
  69. setoutdoc.EntityLink.ID = setout.ID;
  70. setoutdoc.DocumentLink.ID = stagingsetoutdocument.DocumentLink.ID;
  71. List<SetoutDocument> setoutdocs = new List<SetoutDocument>
  72. {
  73. setoutdoc
  74. };
  75. CoreTable oldDocsTable = new Client<SetoutDocument>().Query(
  76. new Filter<SetoutDocument>(x => x.EntityLink.ID).IsEqualTo(setout.ID)
  77. .And(x => x.DocumentLink.ID).IsNotEqualTo(_item.Group.OptimizationDocument.ID)
  78. );
  79. foreach (var row in oldDocsTable.Rows)
  80. {
  81. var oldDoc = row.ToObject<SetoutDocument>();
  82. if (oldDoc.Superceded == DateTime.MinValue)
  83. {
  84. oldDoc.Superceded = DateTime.Now;
  85. setoutdocs.Add(oldDoc);
  86. }
  87. }
  88. new Client<SetoutDocument>().Save(setoutdocs, "Updated from Staging Screen");
  89. new Client<Setout>().Save(setout, "Updated from Staging Screen");
  90. MessageBox.Show("Documents for setout " + _item.Number + " superceded.", "Success");
  91. DeleteAndRefresh(stagingsetoutdocument);
  92. }
  93. //no setout for this pdf - create new
  94. else
  95. {
  96. setout.Number = _item.Number;
  97. setout.JobLink.ID = _item.JobLink.ID;
  98. setout.Group.ID = _item.Group.ID;
  99. var editor = new DynamicDataGrid<Setout>();
  100. editor.OnAfterSave += (editor, items) =>
  101. {
  102. _item.Setout.ID = setout.ID;
  103. var setoutdoc = new SetoutDocument();
  104. setoutdoc.EntityLink.ID = setout.ID;
  105. setoutdoc.DocumentLink.ID = stagingsetoutdocument.DocumentLink.ID;
  106. new Client<SetoutDocument>().Save(setoutdoc, "Added from staging screen");
  107. MessageBox.Show("Setout created for document " + _item.Number, "Success");
  108. DeleteAndRefresh(stagingsetoutdocument);
  109. };
  110. if (!editor.EditItems(new[] { setout }))
  111. {
  112. MessageBox.Show("Setout Creation Cancelled");
  113. return;
  114. }
  115. }
  116. //currently not creating packets due to temporary change in requirements - to uncomment and check for validity when required
  117. //CreatePackets(setout);
  118. }
  119. private void CreatePackets(Setout setout)
  120. {
  121. List<ManufacturingPacket> packets = new List<ManufacturingPacket>();
  122. List<StagingManufacturingPacket> stagingPackets = new List<StagingManufacturingPacket>();
  123. //create new manufacturing packets from the staging packets
  124. foreach (var row in manufacturingControl.Data.Rows)
  125. {
  126. var staging = row.ToObject<StagingManufacturingPacket>();
  127. if (staging.ManufacturingPacket.ID != Guid.Empty)
  128. continue;
  129. var packet = new ManufacturingPacket();
  130. packet.SetoutLink.ID = setout.ID;
  131. packet.Serial = staging.Serial;
  132. packet.ITP.ID = staging.ITP.ID;
  133. packet.JobLink.ID = staging.Job.ID;
  134. packet.ManufacturingTemplateLink.ID = staging.Template.ID;
  135. packet.Title = staging.Title;
  136. packet.Quantity = staging.Quantity;
  137. packet.BarcodeQty = staging.BarcodeQuantity != 0 ? staging.BarcodeQuantity : packet.Quantity;
  138. packet.WaterMark = staging.Watermark.ToString();
  139. packet.Location = staging.Location;
  140. packets.Add(packet);
  141. stagingPackets.Add(staging);
  142. }
  143. //save the newly created packets to provide an ID
  144. new Client<ManufacturingPacket>().Save(packets, "Created from Design Management Panel");
  145. //now work on their stages with the provided packet.ID
  146. List<ManufacturingPacketStage> stages = new List<ManufacturingPacketStage>();
  147. Dictionary<StagingManufacturingPacketComponent, ManufacturingPacketComponent> stagingToActualComponents = new Dictionary<StagingManufacturingPacketComponent, ManufacturingPacketComponent>();
  148. //Handled in this loop:
  149. // - staging packets (update packet.ID)
  150. // - creation of template stages
  151. // - creation of components from staging components
  152. foreach (var stagingPacket in stagingPackets)
  153. {
  154. var packet = packets.FirstOrDefault(x => x.Serial == stagingPacket.Serial);
  155. stagingPacket.ManufacturingPacket.ID = packet.ID;
  156. stages.AddRange(CreateStagesForTemplate(packet.ManufacturingTemplateLink.ID, packet.ID));
  157. CreateComponents(stagingPacket.ID, packet.ID, stagingToActualComponents);
  158. }
  159. //save everything
  160. MultiSave save = new MultiSave();
  161. save.Add(typeof(ManufacturingPacketStage), stages.ToArray());
  162. save.Add(typeof(StagingManufacturingPacket), stagingPackets.ToArray());
  163. save.Add(typeof(ManufacturingPacketComponent), stagingToActualComponents.Values.ToArray());
  164. save.Save(null, "Updated from setout staging screen");
  165. foreach (var pair in stagingToActualComponents)
  166. {
  167. var stagingComponent = pair.Key;
  168. stagingComponent.ComponentID = pair.Value.ID;
  169. }
  170. new Client<StagingManufacturingPacketComponent>().Save(stagingToActualComponents.Keys.ToArray(), "Updated from setout staging screen");
  171. }
  172. private void CreateComponents(Guid stagingPacketID, Guid packetID, Dictionary<StagingManufacturingPacketComponent, ManufacturingPacketComponent> stagingToActualComponents)
  173. {
  174. var components = new List<ManufacturingPacketComponent>();
  175. CoreTable table = new Client<StagingManufacturingPacketComponent>().Query(
  176. new Filter<StagingManufacturingPacketComponent>(x => x.StagingPacket.ID).IsEqualTo(stagingPacketID)
  177. .And(x => x.ComponentID).IsEqualTo(Guid.Empty),
  178. new Columns<StagingManufacturingPacketComponent>(
  179. x => x.Product.ID,
  180. x => x.Quantity,
  181. x => x.Length,
  182. x => x.Height,
  183. x => x.Width
  184. ));
  185. foreach (var row in table.Rows)
  186. {
  187. var stagingComponent = row.ToObject<StagingManufacturingPacketComponent>();
  188. var component = stagingComponent.CreateComponent(packetID);
  189. components.Add(component);
  190. stagingToActualComponents.Add(stagingComponent, component);
  191. }
  192. }
  193. private List<ManufacturingPacketStage> CreateStagesForTemplate(Guid templateID, Guid packetID)
  194. {
  195. var stages = new List<ManufacturingPacketStage>();
  196. CoreTable table = new Client<ManufacturingTemplateStage>().Query(
  197. new Filter<ManufacturingTemplateStage>(x => x.Template.ID).IsEqualTo(templateID),
  198. new Columns<ManufacturingTemplateStage>
  199. (
  200. x => x.Time,
  201. x => x.Sequence,
  202. x => x.SequenceType,
  203. x => x.Section.ID,
  204. x => x.Section.Name
  205. ));
  206. foreach (var row in table.Rows)
  207. {
  208. var templateStage = row.ToObject<ManufacturingTemplateStage>();
  209. var packetStage = templateStage.CreateManufacturingPacketStage();
  210. packetStage.ManufacturingPacketLink.ID = packetID;
  211. stages.Add(packetStage);
  212. }
  213. return stages;
  214. }
  215. private void DeleteAndRefresh(IEntityDocument stagingsetoutdocument)
  216. {
  217. new Client<StagingSetout>().Save(_item, "Updated from staging screen");
  218. _item = new StagingSetout();
  219. documentPreviewer.Document = new StagingSetoutDocument();
  220. Refresh();
  221. }
  222. private void DocumentPreviewer_OnRejected(IEntityDocument stagingsetoutdocument)
  223. {
  224. //dont create setout - setout.id remains blank
  225. //create kanban and populate task.id - this prevents it from appearing on the stagingsetout grid, and allows a new staging setout to be created when the file is saved to the folder again
  226. //attach the document to the task for reference
  227. Kanban task = new Kanban();
  228. task.Title = "Setout Review Task (setout rejected)";
  229. task.Description = "Please review the attached document for setout " + _item.Number;
  230. task.ManagerLink.ID = App.EmployeeID;
  231. var page = new KanbanGrid();
  232. page.MyID = App.EmployeeID;
  233. page.OnAfterSave += (editor, items) =>
  234. {
  235. Kanban savedTask = (Kanban)items[0];
  236. KanbanDocument doc = new KanbanDocument();
  237. doc.EntityLink.ID = savedTask.ID;
  238. doc.DocumentLink.ID = stagingsetoutdocument.DocumentLink.ID;
  239. new Client<KanbanDocument>().Save(doc, "Created from staging screen");
  240. _item.Task.ID = savedTask.ID;
  241. new Client<StagingSetout>().Save(_item, "Updated from staging screen");
  242. MessageBox.Show("Success - Task Created for Document " + _item.Number + " (Task no. " + savedTask.Number + " assigned to " + savedTask.EmployeeLink.Name + ")");
  243. _item = new StagingSetout();
  244. documentPreviewer.Document = new StagingSetoutDocument();
  245. stagingSetoutGrid.Refresh(false, true);
  246. };
  247. if (!page.EditItems(new[] { task }))
  248. MessageBox.Show("Task creation cancelled - setout not rejected");
  249. }
  250. private void StagingSetoutGrid_OnSelectItem(object sender, InABox.DynamicGrid.DynamicGridSelectionEventArgs e)
  251. {
  252. _item = stagingSetoutGrid.SelectedRows.FirstOrDefault().ToObject<StagingSetout>();
  253. var doc = new Client<StagingSetoutDocument>().Query(
  254. new Filter<StagingSetoutDocument>(x => x.EntityLink.ID)
  255. .IsEqualTo(_item.ID),
  256. new Columns<StagingSetoutDocument>(x => x.ID, x => x.DocumentLink.ID, x => x.DocumentLink.FileName))
  257. .Rows.FirstOrDefault().ToObject<StagingSetoutDocument>();
  258. documentPreviewer.Document = doc;
  259. manufacturingControl.StagingSetout = _item;
  260. documentPreviewer.Mode =
  261. _item.Locked == DateTime.MinValue ? InABox.Wpf.DocumentApprovalControl.ControlMode.Markup :
  262. _item.Locked != DateTime.MinValue && _item.LockedBy.ID == App.EmployeeID ? InABox.Wpf.DocumentApprovalControl.ControlMode.Complete :
  263. _item.Locked != DateTime.MinValue && _item.LockedBy.ID != App.EmployeeID ? InABox.Wpf.DocumentApprovalControl.ControlMode.Locked :
  264. InABox.Wpf.DocumentApprovalControl.ControlMode.Markup;
  265. }
  266. public bool IsReady { get; set; }
  267. public string SectionName { get; }
  268. public event DataModelUpdateEvent? OnUpdateDataModel;
  269. public void CreateToolbarButtons(IPanelHost host)
  270. {
  271. host.CreateSetupAction(new PanelAction() { Caption = "Setouts Configuration", Image = PRSDesktop.Resources.specifications, OnExecute = ConfigSettingsClick });
  272. }
  273. private void ConfigSettingsClick(PanelAction obj)
  274. {
  275. //var editor = new ObjectEditor(_settings, "Setouts Configuration");
  276. //if (editor.ShowDialog() == true)
  277. //{
  278. // _settings = (StagingPanellSettings)editor.Input;
  279. // new GlobalConfiguration<StagingPanellSettings>().Save(_settings);
  280. //}
  281. var pages = new DynamicEditorPages();
  282. var propertyEditor = new DynamicEditorForm(typeof(StagingPanellSettings), pages);
  283. propertyEditor.OnDefineLookups += sender =>
  284. {
  285. var editor = sender.EditorDefinition as ILookupEditor;
  286. var colname = sender.ColumnName;
  287. var values = editor.Values(colname, new[] { _settings });
  288. sender.LoadLookups(values);
  289. };
  290. propertyEditor.OnEditorValueChanged += (sender, name, value) =>
  291. {
  292. CoreUtils.SetPropertyValue(_settings, name, value);
  293. return new Dictionary<string, object?>();
  294. };
  295. propertyEditor.OnFormCustomiseEditor += PropertyEditor_OnFormCustomiseEditor;
  296. propertyEditor.Items = new BaseObject[] { _settings };
  297. if (propertyEditor.ShowDialog() == true)
  298. {
  299. new GlobalConfiguration<StagingPanellSettings>().Save(_settings);
  300. }
  301. }
  302. private void PropertyEditor_OnFormCustomiseEditor(IDynamicEditorForm sender, object[] items, DynamicGridColumn column, BaseEditor editor)
  303. {
  304. }
  305. public void Heartbeat(TimeSpan time)
  306. {
  307. }
  308. public void Refresh()
  309. {
  310. //stagingSetoutGrid.ScanFiles(_settings.SetoutsFolder);
  311. stagingSetoutGrid.Refresh(false, true);
  312. manufacturingControl.StagingSetout = new StagingSetout();
  313. manufacturingControl.Refresh();
  314. }
  315. public Dictionary<string, object[]> Selected()
  316. {
  317. return new();
  318. }
  319. public void Setup()
  320. {
  321. _settings = new GlobalConfiguration<StagingPanellSettings>().Load();
  322. documentPreviewer.SetupButtons(
  323. markupVisible: Security.IsAllowed<CanMarkUpSetouts>(),
  324. rejectVisible: Security.IsAllowed<CanApproveSetouts>(),
  325. approveVisible: Security.IsAllowed<CanApproveSetouts>()
  326. );
  327. documentPreviewer.OnMarkupSelected += DocumentPreviewer_OnMarkupSelected;
  328. documentPreviewer.OnMarkupComplete += DocumentPreviewer_OnMarkupComplete;
  329. documentPreviewer.OnRejected += DocumentPreviewer_OnRejected;
  330. documentPreviewer.OnApproved += DocumentPreviewer_OnApproved;
  331. //stagingSetoutGrid.ScanFiles(_settings.SetoutsFolder);
  332. stagingSetoutGrid.Refresh(true, true);
  333. stagingSetoutGrid.OnSelectItem += StagingSetoutGrid_OnSelectItem;
  334. }
  335. private void DocumentPreviewer_OnMarkupSelected(IEntityDocument document)
  336. {
  337. var doc = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(document.DocumentLink.ID)).Rows.FirstOrDefault().ToObject<Document>();
  338. var tempdocpath = Path.GetTempPath() + @"\" + doc.FileName;
  339. _item.SavePath = tempdocpath;
  340. _item.LockedBy.ID = App.EmployeeID;
  341. new Client<StagingSetout>().Save(_item, "Locked from Staging Screen");
  342. File.WriteAllBytes(tempdocpath, doc.Data);
  343. using (Process p = new Process())
  344. {
  345. p.StartInfo = new ProcessStartInfo()
  346. {
  347. UseShellExecute = true,
  348. FileName = tempdocpath
  349. };
  350. p.Start();
  351. }
  352. stagingSetoutGrid.Refresh(false, true);
  353. }
  354. private void DocumentPreviewer_OnMarkupComplete(IEntityDocument document)
  355. {
  356. stagingSetoutGrid.ReloadFile(_item);
  357. stagingSetoutGrid.Refresh(false, true);
  358. }
  359. public void Shutdown()
  360. {
  361. }
  362. public DataModel DataModel(Selection selection)
  363. {
  364. return new AutoDataModel<StagingSetout>(null);
  365. }
  366. }
  367. }