Update_8_57.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. using com.sun.org.apache.xml.@internal.security.utils;
  2. using Comal.Classes;
  3. using InABox.Core;
  4. using InABox.Database;
  5. using Syncfusion.XlsIO.FormatParser.FormatTokens;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using InABox.Database.SQLite;
  12. namespace PRS.Shared.Database_Update_Scripts;
  13. internal class Update_8_57 : DatabaseUpdateScript
  14. {
  15. public override VersionNumber Version => new(8, 57);
  16. private void ApproveOldSetouts(IProvider provider)
  17. {
  18. Logger.Send(LogType.Information, "", "Approving all old setouts");
  19. if (provider is SQLiteProvider p)
  20. {
  21. var sql = $"update setout set [status]='Approved'";
  22. p.Update(sql);
  23. return;
  24. }
  25. var ids = provider.Query(
  26. Filter<StagingSetout>.Where(x => x.Setout.ID).IsNotEqualTo(Guid.Empty).And(
  27. Filter<StagingSetout>.Where(x => x.Task.ID).IsNotEqualTo(Guid.Empty)
  28. .Or(x => x.UnapprovedDocuments).IsGreaterThan(0)
  29. ),
  30. Columns.None<StagingSetout>().Add(x => x.ID)).ExtractValues<StagingSetout, Guid>(x => x.Setout.ID);
  31. var setouts = provider.Query(
  32. Filter<Setout>.Where(x => x.Status).IsEqualTo(SetoutStatus.Unapproved)
  33. .And(x => x.ID).NotInList(ids),
  34. Columns.None<Setout>()
  35. .Add(x => x.ID)
  36. .Add(x => x.Status))
  37. .ToArray<Setout>()
  38. .ToQueue();
  39. var totalsetouts = setouts.Count;
  40. var processedsetouts = 0;
  41. while (setouts.Count > 0)
  42. {
  43. Logger.Send(LogType.Information, "", $"Updating {setouts.Count} staging setouts; {processedsetouts}/{totalsetouts}");
  44. var updates = setouts.Dequeue(100).ToArray();
  45. foreach(var update in updates)
  46. update.Status = SetoutStatus.Approved;
  47. provider.Save(updates);
  48. processedsetouts += updates.Length;
  49. };
  50. }
  51. private static void ApproveAllManufacturingPackets(IProvider provider)
  52. {
  53. Logger.Send(LogType.Information, "", "Approving all old manufacturing packets");
  54. if (provider is SQLiteProvider p)
  55. {
  56. var sql = $"update manufacturingpacket set [approved]=[created] where [approved] is null";
  57. p.Update(sql);
  58. return;
  59. }
  60. var packets = provider.Query(
  61. Filter<ManufacturingPacket>.Where(x => x.Approved).IsEqualTo(DateTime.MinValue),
  62. Columns.None<ManufacturingPacket>()
  63. .Add(x => x.ID)
  64. .Add(x => x.Approved)
  65. .Add(x => x.Created))
  66. .ToArray<ManufacturingPacket>()
  67. .ToQueue();
  68. var totalpackets = packets.Count;
  69. var processedpackets = 0;
  70. while (packets.Count > 0)
  71. {
  72. Logger.Send(LogType.Information, "", $"Updating {packets.Count} staging setouts; {processedpackets}/{totalpackets}");
  73. var updates = packets.Dequeue(100).ToArray();
  74. foreach(var update in updates)
  75. update.Approved = update.Created;
  76. provider.Save(updates);
  77. processedpackets += updates.Length;
  78. }
  79. }
  80. public override bool Update()
  81. {
  82. var provider = DbFactory.NewProvider(Logger.Main);
  83. ApproveOldSetouts(provider);
  84. ApproveAllManufacturingPackets(provider);
  85. ConvertStagingSetouts(provider);
  86. return true;
  87. }
  88. private void ConvertStagingSetouts(IProvider provider)
  89. {
  90. var stagingSetoutsQueue = provider.Query(
  91. Filter<StagingSetout>.Where(x => x.Setout.ID).IsEqualTo(Guid.Empty)
  92. .Or(x => x.Task.ID).IsNotEqualTo(Guid.Empty)
  93. .Or(x => x.UnapprovedDocuments).IsGreaterThan(0),
  94. Columns.None<StagingSetout>()
  95. .Add(x => x.ID)
  96. .Add(x => x.Created)
  97. .Add(x => x.CreatedBy)
  98. .Add(x => x.Number)
  99. .Add(x => x.JobLink.ID)
  100. .Add(x => x.Group.ID)
  101. .Add(x => x.OriginalPath)
  102. .Add(x => x.OriginalCRC)
  103. .Add(x => x.SavePath)
  104. .Add(x => x.Archived)
  105. .Add(x => x.LockedBy.ID)
  106. .Add(x => x.Task.ID)
  107. .Add(x => x.Task.EmployeeLink.ID)
  108. .Add(x => x.Task.Title)
  109. .Add(x => x.Task.Description)
  110. .Add(x => x.Task.Notes)
  111. .Add(x => x.Task.Completed)
  112. .Add(x => x.JobScope.ID)
  113. .Add(x => x.Setout.ID))
  114. .ToArray<StagingSetout>()
  115. .ToQueue();
  116. Logger.Send(LogType.Information, "", $"Updating {stagingSetoutsQueue.Count} staging setouts");
  117. var total = stagingSetoutsQueue.Count;
  118. var processed = 0;
  119. while(stagingSetoutsQueue.Count > 0)
  120. {
  121. Logger.Send(LogType.Information, "", $"Updating {stagingSetoutsQueue.Count} staging setouts; {processed}/{total}");
  122. var stagingSetouts = stagingSetoutsQueue.Dequeue(100).ToArray();
  123. ProcessStagingSetouts(provider, stagingSetouts);
  124. processed += stagingSetouts.Length;
  125. }
  126. }
  127. void ProcessStagingSetouts(IProvider provider, StagingSetout[] stagingSetouts)
  128. {
  129. var setoutIDs = stagingSetouts.ToArray(x => x.ID);
  130. var stagingSetoutDocuments = provider.Query(
  131. Filter<StagingSetoutDocument>.Where(x => x.EntityLink.ID).InList(setoutIDs),
  132. Columns.None<StagingSetoutDocument>()
  133. .Add(x => x.Approved)
  134. .Add(x => x.Notes)
  135. .Add(x => x.Superceded)
  136. .Add(x => x.Thumbnail)
  137. .Add(x => x.Type.ID)
  138. .Add(x => x.EntityLink.ID)
  139. .Add(x => x.DocumentLink.ID))
  140. .ToObjects<StagingSetoutDocument>()
  141. .GroupByDictionary(x => x.EntityLink.ID);
  142. var stagingSetoutForms = provider.Query(
  143. Filter<StagingSetoutForm>.Where(x => x.Parent.ID).InList(setoutIDs),
  144. Columns.None<StagingSetoutForm>()
  145. .Add(x => x.Parent.ID)
  146. .Add(x => x.Number)
  147. .Add(x => x.Description)
  148. .Add(x => x.Form.ID)
  149. .Add(x => x.FormData)
  150. .Add(x => x.BlobData)
  151. .Add(x => x.FormStarted)
  152. .Add(x => x.FormCompleted)
  153. .Add(x => x.FormProcessed)
  154. .Add(x => x.FormCancelled)
  155. .Add(x => x.FormCompletedBy.ID)
  156. .Add(x => x.Location.Address)
  157. .Add(x => x.Location.Latitude)
  158. .Add(x => x.Location.Longitude)
  159. .Add(x => x.Location.Timestamp)
  160. .Add(x => x.FormOpen)
  161. .Add(x => x.Sequence))
  162. .ToObjects<StagingSetoutForm>()
  163. .GroupByDictionary(x => x.Parent.ID);
  164. var stagingSetoutComponents = provider.Query(
  165. Filter<StagingSetoutComponent>.Where(x => x.StagingSetout.ID).InList(setoutIDs)
  166. .And(x => x.StagingManufacturingPacketComponent.ID).IsEqualTo(Guid.Empty),
  167. Columns.None<StagingSetoutComponent>()
  168. .Add(x => x.StagingSetout.ID)
  169. .Add(x => x.Product.ID)
  170. .Add(x => x.Description)
  171. .AddDimensionsColumns(x => x.Dimensions, Dimensions.ColumnsType.Local)
  172. .Add(x => x.Quantity)
  173. .Add(x => x.Sequence))
  174. .ToObjects<StagingSetoutComponent>()
  175. .GroupByDictionary(x => x.StagingSetout.ID);
  176. var stagingManufacturingPackets = provider.Query(
  177. Filter<StagingManufacturingPacket>.Where(x => x.StagingSetout.ID).InList(setoutIDs),
  178. Columns.None<StagingManufacturingPacket>()
  179. .Add(x => x.ID)
  180. .Add(x => x.Title)
  181. .Add(x => x.Serial)
  182. .Add(x => x.ITP.ID)
  183. .Add(x => x.StagingSetout.ID)
  184. .Add(x => x.Watermark)
  185. .Add(x => x.Location)
  186. .Add(x => x.Quantity)
  187. .Add(x => x.BarcodeQuantity)
  188. .Add(x => x.Group.ID)
  189. .Add(x => x.Group.Watermark)
  190. .Add(x => x.Template.ID)
  191. .Add(x => x.ManufacturingPacket.ID))
  192. .ToObjects<StagingManufacturingPacket>()
  193. .GroupByDictionary(x => x.StagingSetout.ID);
  194. var manufacturingPackets = provider.Query(
  195. Filter<ManufacturingPacket>.Where(x => x.SetoutLink.ID).IsEqualTo(Guid.Empty)
  196. .And(x => x.ID).InQuery(
  197. Filter<StagingManufacturingPacket>.Where(x => x.StagingSetout.ID).InList(setoutIDs),
  198. x => x.ManufacturingPacket.ID),
  199. Columns.None<ManufacturingPacket>()
  200. .Add(x => x.ID)
  201. .Add(x => x.SetoutLink.ID))
  202. .ToObjects<ManufacturingPacket>()
  203. .ToDictionary(x => x.ID);
  204. var stagingManufacturingPacketComponents = provider.Query(
  205. Filter<StagingManufacturingPacketComponent>.Where(x => x.Packet.ID).InQuery(
  206. Filter<StagingManufacturingPacket>.Where(x => x.StagingSetout.ID).InList(setoutIDs),
  207. x => x.ID),
  208. Columns.None<StagingManufacturingPacketComponent>()
  209. .Add(x => x.Packet.ID)
  210. .Add(x => x.Description)
  211. .Add(x => x.Product.ID)
  212. .Add(x => x.Quantity)
  213. .AddDimensionsColumns(x => x.Dimensions, Dimensions.ColumnsType.Local))
  214. .ToObjects<StagingManufacturingPacketComponent>()
  215. .GroupByDictionary(x => x.Packet.ID);
  216. var stagingManufacturingPacketStages = provider.Query(
  217. Filter<StagingManufacturingPacketStage>.Where(x => x.Packet.ID).InQuery(
  218. Filter<StagingManufacturingPacket>.Where(x => x.StagingSetout.ID).InList(setoutIDs),
  219. x => x.ID),
  220. Columns.None<StagingManufacturingPacketStage>()
  221. .Add(x => x.Packet.ID)
  222. .Add(x => x.Time)
  223. .Add(x => x.Sequence)
  224. .Add(x => x.SequenceType)
  225. .Add(x => x.QualityChecks)
  226. .Add(x => x.Section.ID))
  227. .ToObjects<StagingManufacturingPacketStage>()
  228. .GroupByDictionary(x => x.Packet.ID);
  229. var stagingManufacturingPacketTreatments = provider.Query(
  230. Filter<StagingManufacturingPacketTreatment>.Where(x => x.Packet.ID).InQuery(
  231. Filter<StagingManufacturingPacket>.Where(x => x.StagingSetout.ID).InList(setoutIDs),
  232. x => x.ID),
  233. Columns.None<StagingManufacturingPacketTreatment>()
  234. .Add(x => x.Packet.ID)
  235. .Add(x => x.Product.ID)
  236. .Add(x => x.Parameter))
  237. .ToObjects<StagingManufacturingPacketTreatment>()
  238. .GroupByDictionary(x => x.Packet.ID);
  239. var oldSetouts = provider.Query(
  240. Filter<Setout>.Where(x => x.ID).InList(stagingSetouts.ToArray(x => x.Setout.ID)),
  241. Columns.None<Setout>()
  242. .Add(x => x.ID))
  243. .ToObjects<Setout>()
  244. .ToDictionary(x => x.ID);
  245. var oldMap = new Dictionary<Setout, StagingSetout>();
  246. var setouts = new List<Setout>();
  247. var setoutDocuments = new Dictionary<Setout, List<SetoutDocument>>();
  248. var setoutForms = new Dictionary<Setout, List<SetoutForm>>();
  249. var components = new Dictionary<Setout, List<ManufacturingPacketComponent>>();
  250. var packets = new Dictionary<Setout, List<ManufacturingPacket>>();
  251. var packetComponents = new Dictionary<Setout, Dictionary<ManufacturingPacket, List<ManufacturingPacketComponent>>>();
  252. var packetStages = new Dictionary<ManufacturingPacket, List<ManufacturingPacketStage>>();
  253. var packetTreatments = new Dictionary<ManufacturingPacket, List<ManufacturingTreatment>>();
  254. foreach(var stagingSetout in stagingSetouts)
  255. {
  256. if(stagingSetout.Setout.ID == Guid.Empty
  257. || !oldSetouts.TryGetValue(stagingSetout.Setout.ID, out var setout))
  258. {
  259. setout = new Setout();
  260. setout.Created = stagingSetout.Created;
  261. setout.CreatedBy = stagingSetout.CreatedBy;
  262. setout.Number = stagingSetout.Number;
  263. setout.JobLink.ID = stagingSetout.JobLink.ID;
  264. setout.Group.ID = stagingSetout.Group.ID;
  265. setout.Status = SetoutStatus.Unapproved;
  266. setout.JobScope.ID = stagingSetout.JobScope.ID;
  267. }
  268. else
  269. {
  270. }
  271. if (oldMap.TryAdd(setout, stagingSetout))
  272. {
  273. setouts.Add(setout);
  274. }
  275. if(stagingSetoutDocuments.TryGetValue(stagingSetout.ID, out var documents))
  276. {
  277. var newSetoutDocuments = setoutDocuments.GetValueOrAdd(setout);
  278. //if(documents.All(x => x.Approved))
  279. //{
  280. // setout.Status = SetoutStatus.Approved;
  281. //}
  282. foreach(var stagingSetoutDocument in documents)
  283. {
  284. var setoutDocument = new SetoutDocument();
  285. setoutDocument.DocumentLink.ID = stagingSetoutDocument.DocumentLink.ID;
  286. setoutDocument.Type.ID = stagingSetoutDocument.Type.ID;
  287. setoutDocument.Thumbnail = stagingSetoutDocument.Thumbnail;
  288. setoutDocument.Superceded = stagingSetoutDocument.Superceded;
  289. setoutDocument.Notes = stagingSetoutDocument.Notes;
  290. setoutDocument.Staging.OriginalCRC = stagingSetout.OriginalCRC;
  291. setoutDocument.Staging.OriginalPath = stagingSetout.OriginalPath;
  292. setoutDocument.Staging.SavePath = stagingSetout.SavePath;
  293. setoutDocument.Staging.LockedBy.ID = stagingSetout.LockedBy.ID;
  294. newSetoutDocuments.Add(setoutDocument);
  295. }
  296. }
  297. if(stagingSetout.Task.ID != Guid.Empty)
  298. {
  299. setout.Status = SetoutStatus.Cancelled;
  300. setout.Problem.AssignedTo.ID = stagingSetout.Task.EmployeeLink.ID;
  301. var notes = new List<string>()
  302. {
  303. stagingSetout.Task.Title,
  304. stagingSetout.Task.Description,
  305. };
  306. if (stagingSetout.Task.Notes != null)
  307. notes.AddRange(stagingSetout.Task.Notes);
  308. setout.Problem.Notes = notes.ToArray();
  309. setout.Problem.Resolved = stagingSetout.Task.Completed;
  310. }
  311. if(stagingSetoutForms.TryGetValue(stagingSetout.ID, out var forms))
  312. {
  313. var newSetoutForms = setoutForms.GetValueOrAdd(setout);
  314. foreach(var form in forms)
  315. {
  316. var newForm = new SetoutForm();
  317. newForm.Number = form.Number;
  318. newForm.Description = form.Description;
  319. newForm.Form.ID = form.Form.ID;
  320. newForm.FormData = form.FormData;
  321. newForm.BlobData = form.BlobData;
  322. newForm.FormStarted = form.FormStarted;
  323. newForm.FormCompleted = form.FormCompleted;
  324. newForm.FormProcessed = form.FormProcessed;
  325. newForm.FormCancelled = form.FormCancelled;
  326. newForm.FormCompletedBy.ID = form.FormCompletedBy.ID;
  327. newForm.Location.CopyFrom(form.Location);
  328. newForm.FormOpen = form.FormOpen;
  329. newForm.Sequence = form.Sequence;
  330. newSetoutForms.Add(newForm);
  331. }
  332. }
  333. if(stagingSetoutComponents.TryGetValue(stagingSetout.ID, out var componentsList))
  334. {
  335. var newComponents = components.GetValueOrAdd(setout);
  336. foreach(var component in componentsList)
  337. {
  338. var newComponent = new ManufacturingPacketComponent();
  339. newComponent.Product.ID = component.Product.ID;
  340. newComponent.Description = component.Description;
  341. newComponent.Dimensions.CopyFrom(component.Dimensions);
  342. newComponent.Quantity = component.Quantity;
  343. newComponent.Sequence = component.Sequence;
  344. newComponents.Add(newComponent);
  345. }
  346. }
  347. if(stagingManufacturingPackets.TryGetValue(stagingSetout.ID, out var stagingPackets))
  348. {
  349. var newPackets = packets.GetValueOrAdd(setout);
  350. var newSetoutPacketComponents = packetComponents.GetValueOrAdd(setout);
  351. foreach(var stagingPacket in stagingPackets)
  352. {
  353. if(stagingPacket.ManufacturingPacket.ID != Guid.Empty)
  354. {
  355. if(manufacturingPackets.TryGetValue(stagingPacket.ManufacturingPacket.ID, out var oldPacket))
  356. {
  357. newPackets.Add(oldPacket);
  358. }
  359. }
  360. else
  361. {
  362. var newPacket = new ManufacturingPacket();
  363. newPacket.Title = stagingPacket.Title;
  364. newPacket.Serial = stagingPacket.Serial;
  365. newPacket.ITP.ID = stagingPacket.ITP.ID;
  366. newPacket.WaterMark = stagingPacket.Watermark.NotWhiteSpaceOr(stagingPacket.Group.Watermark);
  367. newPacket.Location = stagingPacket.Location;
  368. newPacket.Quantity = stagingPacket.Quantity;
  369. newPacket.BarcodeQty = stagingPacket.BarcodeQuantity.IsNullOrWhiteSpace()
  370. ? stagingPacket.Quantity
  371. : int.Parse(stagingPacket.BarcodeQuantity);
  372. newPacket.TemplateGroup.ID = stagingPacket.Group.ID;
  373. newPacket.ManufacturingTemplateLink.ID = stagingPacket.Template.ID;
  374. newPackets.Add(newPacket);
  375. if(stagingManufacturingPacketComponents.TryGetValue(stagingPacket.ID, out var stagingComponents))
  376. {
  377. var newPacketComponents = new List<ManufacturingPacketComponent>();
  378. newSetoutPacketComponents.Add(newPacket, newPacketComponents);
  379. foreach(var stagingComponent in stagingComponents)
  380. {
  381. var component = new ManufacturingPacketComponent();
  382. component.Description = stagingComponent.Description;
  383. component.Product.ID = stagingComponent.Product.ID;
  384. component.Quantity = stagingComponent.Quantity;
  385. component.Dimensions.CopyFrom(stagingComponent.Dimensions);
  386. newPacketComponents.Add(component);
  387. }
  388. }
  389. if(stagingManufacturingPacketStages.TryGetValue(stagingPacket.ID, out var stagingStages))
  390. {
  391. var newStages = new List<ManufacturingPacketStage>();
  392. packetStages.Add(newPacket, newStages);
  393. foreach(var stagingStage in stagingStages)
  394. {
  395. var stage = new ManufacturingPacketStage
  396. {
  397. Time = stagingStage.Time,
  398. Sequence = stagingStage.Sequence,
  399. SequenceType = stagingStage.SequenceType,
  400. Started = DateTime.MinValue,
  401. PercentageComplete = 0.0F,
  402. Completed = DateTime.MinValue,
  403. QualityChecks = stagingStage.QualityChecks,
  404. QualityStatus = QualityStatus.NotChecked,
  405. QualityNotes = ""
  406. };
  407. stage.ManufacturingSectionLink.ID = stagingStage.Section.ID;
  408. newStages.Add(stage);
  409. }
  410. }
  411. if(stagingManufacturingPacketTreatments.TryGetValue(stagingPacket.ID, out var stagingTreatments))
  412. {
  413. var newTreatments = new List<ManufacturingTreatment>();
  414. packetTreatments.Add(newPacket, newTreatments);
  415. foreach(var stagingTreatment in stagingTreatments)
  416. {
  417. var treatment = new ManufacturingTreatment();
  418. treatment.Product.ID = stagingTreatment.Product.ID;
  419. treatment.Parameter = stagingTreatment.Parameter;
  420. newTreatments.Add(treatment);
  421. }
  422. }
  423. }
  424. }
  425. }
  426. }
  427. provider.Save(setouts);
  428. foreach(var setout in setouts)
  429. {
  430. if(oldMap.TryGetValue(setout, out var stagingSetout))
  431. {
  432. stagingSetout.Setout.ID = setout.ID;
  433. }
  434. if(setoutDocuments.TryGetValue(setout, out var documents))
  435. {
  436. foreach(var document in documents)
  437. {
  438. document.EntityLink.ID = setout.ID;
  439. }
  440. }
  441. if(setoutForms.TryGetValue(setout, out var forms))
  442. {
  443. foreach(var form in forms)
  444. {
  445. form.Parent.ID = setout.ID;
  446. }
  447. }
  448. if(components.TryGetValue(setout, out var setoutComponents))
  449. {
  450. foreach(var component in setoutComponents)
  451. {
  452. component.Setout.ID = setout.ID;
  453. }
  454. }
  455. if(packets.TryGetValue(setout, out var setoutPackets))
  456. {
  457. var setoutPacketComponents = packetComponents.GetValueOrDefault(setout);
  458. foreach(var packet in setoutPackets)
  459. {
  460. packet.SetoutLink.ID = setout.ID;
  461. }
  462. }
  463. }
  464. provider.Save(stagingSetouts);
  465. provider.Save(setoutDocuments.SelectMany(x => x.Value).Where(x => x.EntityLink.ID != Guid.Empty));
  466. provider.Save(setoutForms.SelectMany(x => x.Value).Where(x => x.Parent.ID != Guid.Empty));
  467. provider.Save(packets.SelectMany(x => x.Value).Where(x => x.SetoutLink.ID != Guid.Empty));
  468. foreach(var (setout, setoutPackets) in packets)
  469. {
  470. var setoutComponents = packetComponents.GetValueOrDefault(setout);
  471. foreach(var packet in setoutPackets)
  472. {
  473. if (packet.SetoutLink.ID == Guid.Empty) continue;
  474. if(setoutComponents is not null
  475. && setoutComponents.TryGetValue(packet, out var manufacturingPacketComponents))
  476. {
  477. foreach(var component in manufacturingPacketComponents)
  478. {
  479. component.Setout.ID = setout.ID;
  480. component.Packet.ID = packet.ID;
  481. }
  482. }
  483. if(packetStages.TryGetValue(packet, out var stages))
  484. {
  485. foreach(var stage in stages)
  486. {
  487. stage.Parent.ID = packet.ID;
  488. }
  489. }
  490. if(packetTreatments.TryGetValue(packet, out var treatments))
  491. {
  492. foreach(var treatment in treatments)
  493. {
  494. treatment.Packet.ID = packet.ID;
  495. }
  496. }
  497. }
  498. }
  499. provider.Save(components.SelectMany(x => x.Value).Where(x => x.Setout.ID != Guid.Empty)
  500. .Concat(packetComponents.SelectMany(x => x.Value).SelectMany(x => x.Value).Where(x => x.Packet.ID != Guid.Empty && x.Setout.ID != Guid.Empty)));
  501. provider.Save(packetStages.SelectMany(x => x.Value).Where(x => x.Parent.ID != Guid.Empty));
  502. provider.Save(packetTreatments.SelectMany(x => x.Value).Where(x => x.Packet.ID != Guid.Empty));
  503. }
  504. }