DeliveryStore.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Text;
  4. using Comal.Classes;
  5. using InABox.Core;
  6. using System;
  7. namespace Comal.Stores;
  8. internal class DeliveryStore : BaseStore<Delivery>
  9. {
  10. private void SendNotifications(Delivery delivery)
  11. {
  12. if (delivery == null)
  13. return;
  14. var delnumber = delivery.Number;
  15. var jobid = delivery.Job.ID;
  16. var delemp = delivery.Employee.ID;
  17. // Get Job Details
  18. var job = jobid.Equals(Guid.Empty)
  19. ? null
  20. : Provider.Query(
  21. new Filter<Job>(x => x.ID).IsEqualTo(jobid),
  22. Columns.None<Job>().Add(
  23. x => x.JobNumber,
  24. x => x.Name,
  25. x => x.SiteLead.ID,
  26. x => x.ProjectLead.ID
  27. )
  28. ).Rows.FirstOrDefault();
  29. var jobnumber = job != null ? job.Get<Job, string>(x => x.JobNumber) : "";
  30. var jobname = job != null ? job.Get<Job, string>(x => x.Name) : "";
  31. var sitelead = job != null ? job.Get<Job, Guid>(x => x.SiteLead.ID) : Guid.Empty;
  32. var projlead = job != null ? job.Get<Job, Guid>(x => x.ProjectLead.ID) : Guid.Empty;
  33. // Scan for Delivery Items and Build the List to Send
  34. var items = Provider.Query(
  35. new Filter<DeliveryItem>(x => x.Delivery.ID).IsEqualTo(delivery.ID),
  36. Columns.None<DeliveryItem>().Add(
  37. x => x.ID,
  38. x => x.ShipmentLink.ID,
  39. x => x.ShipmentLink.Code,
  40. x => x.RequisitionLink.ID,
  41. x => x.RequisitionLink.Number,
  42. x => x.Piece,
  43. x => x.Title,
  44. x => x.Barcode,
  45. x => x.ManufacturingPacketLink.Serial,
  46. x => x.Description
  47. )
  48. );
  49. var lines = new Dictionary<string, List<string>>();
  50. foreach (var row in items.Rows)
  51. {
  52. var tag = "";
  53. if (row.IsEntityLinkValid<DeliveryItem, ShipmentLink>(x => x.ShipmentLink))
  54. tag = string.Format("Rack #{0}", row.Get<DeliveryItem, string>(c => c.ShipmentLink.Code));
  55. else if (row.IsEntityLinkValid<DeliveryItem, RequisitionLink>(x => x.RequisitionLink))
  56. tag = string.Format("Requisition #{0}", row.Get<DeliveryItem, int>(c => c.RequisitionLink.Number));
  57. if (!string.IsNullOrWhiteSpace(tag))
  58. {
  59. if (!lines.ContainsKey(tag))
  60. lines[tag] = new List<string>();
  61. if (row.IsEntityLinkValid<DeliveryItem, RequisitionLink>(x => x.RequisitionLink))
  62. lines[tag].Add(string.Format("{0}: {1}", row.Get<DeliveryItem, string>(c => c.Piece),
  63. row.Get<DeliveryItem, string>(c => c.Description)));
  64. else
  65. lines[tag].Add(string.Format("{0}: {1} - {2}", row.Get<DeliveryItem, string>(c => c.Barcode),
  66. row.Get<DeliveryItem, string>(c => c.ManufacturingPacketLink.Serial), row.Get<DeliveryItem, string>(c => c.Description)));
  67. }
  68. }
  69. var sb = new StringBuilder();
  70. sb.AppendLine("The following items have been delivered:");
  71. foreach (var key in lines.Keys)
  72. {
  73. sb.AppendLine(" ");
  74. sb.AppendLine(key);
  75. sb.AppendLine(new string('=', key.Length));
  76. foreach (var line in lines[key])
  77. sb.AppendLine(line);
  78. }
  79. // Send the notifications
  80. var emps = Provider.Query(
  81. new Filter<Employee>(x => x.UserLink.UserID).IsEqualTo(UserID)
  82. .Or(x => x.ID).IsEqualTo(delemp)
  83. .Or(x => x.ID).IsEqualTo(sitelead)
  84. .Or(x => x.ID).IsEqualTo(projlead)
  85. ,
  86. Columns.None<Employee>().Add(
  87. x => x.ID,
  88. x => x.UserLink.ID
  89. )
  90. );
  91. var me = emps.Rows.FirstOrDefault(r => r.Get<Employee, Guid>(c => c.UserLink.ID) == UserGuid);
  92. var notifications = new List<Notification>();
  93. foreach (var emp in emps.Rows)
  94. if (emp.Get<Employee, Guid>(x => x.UserLink.ID) != UserGuid)
  95. {
  96. var notification = new Notification();
  97. notification.Employee.ID = emp.Get<Employee, Guid>(x => x.ID);
  98. notification.Title = string.Format("Delivery #{0} ({1}: {2}) has been Delivered", delnumber, jobnumber, jobname);
  99. notification.Description = sb.ToString();
  100. notification.Job.ID = jobid;
  101. notification.EntityType = typeof(Delivery).EntityName();
  102. notification.EntityID = delivery.ID;
  103. notification.Sender.ID = me != null ? me.Get<Employee, Guid>(x => x.ID) : Guid.Empty;
  104. notifications.Add(notification);
  105. }
  106. if (notifications.Any())
  107. FindSubStore<Notification>().Save(notifications, "");
  108. }
  109. private void UpdateEquipment(Delivery delivery)
  110. {
  111. var deliveryEquipments = Provider.Query(
  112. new Filter<DeliveryEquipment>(x => x.Delivery.ID).IsEqualTo(delivery.ID),
  113. Columns.None<DeliveryEquipment>()
  114. .Add(x => x.Equipment.ID).Add(x => x.Type))
  115. .ToObjects<DeliveryEquipment>();
  116. var jobEquipments = Provider.Query(
  117. new Filter<JobEquipment>(x => x.JobLink.ID).IsEqualTo(delivery.Job.ID),
  118. Columns.Required<JobEquipment>()
  119. .Add(x => x.ID)
  120. .Add(x => x.EquipmentLink.ID)
  121. .Add(x => x.OnSite))
  122. .ToObjects<JobEquipment>()
  123. .ToDictionary(x => x.EquipmentLink.ID);
  124. var jobEquipmentStore = FindSubStore<JobEquipment>();
  125. var toSave = new List<JobEquipment>();
  126. foreach(var deliveryEquipment in deliveryEquipments)
  127. {
  128. if(jobEquipments.TryGetValue(deliveryEquipment.Equipment.ID, out var jobEquipment))
  129. {
  130. jobEquipment.OnSite = deliveryEquipment.Type == DeliveryEquipmentType.DropOff;
  131. toSave.Add(jobEquipment);
  132. }
  133. else
  134. {
  135. var newJobEquipment = new JobEquipment();
  136. newJobEquipment.EquipmentLink.CopyFrom(deliveryEquipment.Equipment);
  137. newJobEquipment.JobLink.CopyFrom(delivery.Job);
  138. newJobEquipment.OnSite = deliveryEquipment.Type == DeliveryEquipmentType.DropOff;
  139. toSave.Add(newJobEquipment);
  140. }
  141. }
  142. jobEquipmentStore.Save(toSave, "Updated by delivery.");
  143. }
  144. protected override void AfterSave(Delivery entity)
  145. {
  146. base.AfterSave(entity);
  147. if (!entity.Delivered.IsEmpty() && entity.HasOriginalValue(x => x.Delivered) && entity.GetOriginalValue(x => x.Delivered).IsEmpty())
  148. {
  149. SendNotifications(entity);
  150. UpdateEquipment(entity);
  151. }
  152. UpdateTrackingKanban<DeliveryKanban, Delivery, DeliveryLink>(entity, d =>
  153. {
  154. return !entity.Delivered.IsEmpty()
  155. ? KanbanStatus.Complete
  156. : entity.Assignment.IsValid()
  157. ? KanbanStatus.InProgress
  158. : KanbanStatus.Open;
  159. });
  160. //requi tracking kanban is usually updated in RequisitionStore, the requi is not necessarily saved when a delivery is completed
  161. if (entity.Delivered != DateTime.MinValue)
  162. {
  163. CoreTable table = Provider.Query<Requisition>(new Filter<Requisition>(x => x.Delivery.ID).IsEqualTo(entity.ID));
  164. if (table.Rows.Any())
  165. {
  166. foreach (CoreRow row in table.Rows)
  167. {
  168. Requisition requisition = row.ToObject<Requisition>();
  169. UpdateTrackingKanban<RequisitionKanban, Requisition, RequisitionLink>(requisition, e => { return KanbanStatus.Complete; });
  170. }
  171. }
  172. }
  173. }
  174. protected override void BeforeDelete(Delivery entity)
  175. {
  176. UnlinkTrackingKanban<DeliveryKanban, Delivery, DeliveryLink>(entity);
  177. }
  178. }