ManufacturingPacket.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using InABox.Core;
  6. namespace Comal.Classes
  7. {
  8. public class ManufacturingPacketArea : IFormula<ManufacturingPacket, object>
  9. {
  10. public Expression<Func<ManufacturingPacket, object>> Value => x => x.Height;
  11. public Expression<Func<ManufacturingPacket, object>>[] Modifiers =>
  12. new Expression<Func<ManufacturingPacket, object>>[] { x => x.Width, x => 0.000001m };
  13. public FormulaOperator Operator => FormulaOperator.Multiply;
  14. public FormulaType Type => FormulaType.Virtual;
  15. }
  16. public class ManufacturingPacketVolume : IFormula<ManufacturingPacket, object>
  17. {
  18. public Expression<Func<ManufacturingPacket, object>> Value => x => x.Height;
  19. public Expression<Func<ManufacturingPacket, object>>[] Modifiers => new Expression<Func<ManufacturingPacket, object>>[]
  20. { x => x.Width, x => x.Length, x => 0.000000001m };
  21. public FormulaOperator Operator => FormulaOperator.Multiply;
  22. public FormulaType Type => FormulaType.Virtual;
  23. }
  24. public class ManufacturingPacketTime : CoreAggregate<ManufacturingPacket, ManufacturingPacketStage, TimeSpan>
  25. {
  26. public override Expression<Func<ManufacturingPacketStage, TimeSpan>> Aggregate => x => x.Time;
  27. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  28. public override Dictionary<Expression<Func<ManufacturingPacketStage, object>>, Expression<Func<ManufacturingPacket, object>>> Links =>
  29. new Dictionary<Expression<Func<ManufacturingPacketStage, object>>, Expression<Func<ManufacturingPacket, object>>>()
  30. {
  31. { ManufacturingPacketStage => ManufacturingPacketStage.Parent.ID, ManufacturingPacket => ManufacturingPacket.ID }
  32. };
  33. }
  34. public class ManufacturingPacketTimeRemaining : CoreAggregate<ManufacturingPacket, ManufacturingPacketStage, TimeSpan>
  35. {
  36. public override Expression<Func<ManufacturingPacketStage, TimeSpan>> Aggregate => x => x.TimeRemaining;
  37. public Expression<Func<ManufacturingPacketStage, Guid>> Link => x => x.Parent.ID;
  38. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  39. public override Dictionary<Expression<Func<ManufacturingPacketStage, object>>, Expression<Func<ManufacturingPacket, object>>> Links =>
  40. new Dictionary<Expression<Func<ManufacturingPacketStage, object>>, Expression<Func<ManufacturingPacket, object>>>()
  41. {
  42. { ManufacturingPacketStage => ManufacturingPacketStage.Parent.ID, ManufacturingPacket => ManufacturingPacket.ID }
  43. };
  44. }
  45. public class ManufacturingPacketActualTime : CoreAggregate<ManufacturingPacket, ManufacturingHistory, TimeSpan>
  46. {
  47. public override Expression<Func<ManufacturingHistory, TimeSpan>> Aggregate => x => x.WorkDuration;
  48. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  49. public override Dictionary<Expression<Func<ManufacturingHistory, object>>, Expression<Func<ManufacturingPacket, object>>> Links =>
  50. new Dictionary<Expression<Func<ManufacturingHistory, object>>, Expression<Func<ManufacturingPacket, object>>>()
  51. {
  52. { ManufacturingHistory => ManufacturingHistory.Packet.ID, ManufacturingPacket => ManufacturingPacket.ID }
  53. };
  54. }
  55. [UserTracking("Manufacturing")]
  56. [Caption("Manufacturing")]
  57. public class ManufacturingPacket : Entity, IPersistent, IRemotable, IOneToMany<Setout>, ILicense<ManufacturingLicense>, IIssues, IProblems<ManagedProblem>
  58. {
  59. [TextBoxEditor]
  60. [EditorSequence(1)]
  61. public string Title { get; set; }
  62. [CodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]
  63. [EditorSequence(2)]
  64. public string Serial { get; set; }
  65. private class SetoutLookup : LookupDefinitionGenerator<Setout, ManufacturingPacket>
  66. {
  67. public override Filter<Setout> DefineFilter(ManufacturingPacket[] items)
  68. {
  69. return Filter<Setout>.Where(x => x.Job.ID).IsEqualTo(items.First().Setout.Job.ID);
  70. }
  71. public override Columns<ManufacturingPacket> DefineFilterColumns()
  72. => Columns.None<ManufacturingPacket>().Add(x => x.Setout.Job.ID);
  73. }
  74. [LookupDefinition(typeof(SetoutLookup))]
  75. [EditorSequence(3)]
  76. [EntityRelationship(DeleteAction.Cascade)]
  77. [RequiredColumn]
  78. public SetoutLink Setout { get; set; }
  79. [Obsolete("Replaced by Setout")]
  80. public SetoutLink SetoutLink
  81. {
  82. get => Setout;
  83. set { }
  84. }
  85. private class JobITPLookup : LookupDefinitionGenerator<JobITP, ManufacturingPacket>
  86. {
  87. public override Filter<JobITP> DefineFilter(ManufacturingPacket[] items)
  88. {
  89. if (items.Length == 1)
  90. return Filter<JobITP>.Where(x => x.Job.ID).IsEqualTo(items.First().Setout.Job.ID);
  91. return LookupFactory.DefineFilter<JobITP>();
  92. }
  93. public override Columns<ManufacturingPacket> DefineFilterColumns()
  94. => Columns.None<ManufacturingPacket>().Add(x => x.Setout.Job.ID);
  95. }
  96. [EditorSequence(4)]
  97. [LookupDefinition(typeof(JobITPLookup))]
  98. public JobITPLink ITP { get; set; }
  99. [TextBoxEditor]
  100. [EditorSequence(5)]
  101. public string Location { get; set; }
  102. // Used to calculate time & materials
  103. [EditorSequence(7)]
  104. [IntegerEditor]
  105. public int Quantity { get; set; }
  106. [EditorSequence(8)]
  107. [IntegerEditor]
  108. // Determines # of barcodes to print
  109. public int BarcodeQty { get; set; }
  110. [EditorSequence(9)]
  111. [TimestampEditor(Editable = Editable.Hidden)]
  112. public override DateTime Created
  113. {
  114. get => base.Created;
  115. set => base.Created = value;
  116. }
  117. [EditorSequence(10)]
  118. [DateTimeEditor]
  119. public DateTime DueDate { get; set; }
  120. [EditorSequence("Design", 101)]
  121. [EntityRelationship(DeleteAction.Cascade)]
  122. public PDFDocumentLink Drawing { get; set; }
  123. // To be overlaid over the PDF document
  124. [EditorSequence("Design", 102)]
  125. [TextBoxEditor]
  126. public string WaterMark { get; set; }
  127. [EditorSequence("Design", 103)]
  128. public double Height { get; set; }
  129. [EditorSequence("Design", 104)]
  130. public double Width { get; set; }
  131. [EditorSequence("Design", 105)]
  132. public double Length { get; set; }
  133. [EditorSequence("Staging", 1)]
  134. [TimestampEditor(Editable = Editable.Disabled)]
  135. public DateTime Approved { get; set; }
  136. [EditorSequence("Staging", 2)]
  137. public ManufacturingTemplateGroupLink TemplateGroup { get; set; }
  138. [EditorSequence("Manufacturing", 200)]
  139. public ManufacturingTemplateLink ManufacturingTemplate { get; set; }
  140. [Obsolete("Replaced by ManufacturingTemplate")]
  141. public ManufacturingTemplateLink ManufacturingTemplateLink
  142. {
  143. get => ManufacturingTemplate;
  144. set { }
  145. }
  146. [EditorSequence("Manufacturing", 201)]
  147. [TimestampEditor(Editable = Editable.Disabled)]
  148. public DateTime Issued { get; set; }
  149. [EditorSequence("Manufacturing", 202)]
  150. [LoggableProperty]
  151. public bool Priority { get; set; }
  152. [EditorSequence("Manufacturing", 203)]
  153. [LoggableProperty]
  154. public bool Distributed { get; set; }
  155. [EditorSequence("Manufacturing", 204)]
  156. [TextBoxEditor(Editable = Editable.Disabled)]
  157. public string Trolleys { get; set; }
  158. [EditorSequence("Manufacturing", 205)]
  159. [TimestampEditor(Editable = Editable.Hidden)]
  160. public DateTime BarcodePrinted { get; set; }
  161. [EditorSequence("Manufacturing", 206)]
  162. [DateTimeEditor(Editable = Editable.Disabled)]
  163. [SecondaryIndex]
  164. public DateTime Completed { get; set; }
  165. [SecondaryIndex]
  166. [TimestampEditor]
  167. [EditorSequence("Manufacturing", 207)]
  168. public DateTime Archived { get; set; } = DateTime.MinValue;
  169. [NullEditor]
  170. [Obsolete("Replaced with Problem", true)]
  171. public string Issues { get; set; }
  172. [EditorSequence("Issues", 1)]
  173. public ManagedProblem Problem { get; set; }
  174. [CheckBoxEditor]
  175. [EditorSequence("Issues", 2)]
  176. [LoggableProperty]
  177. public bool OnHold { get; set; }
  178. public override string ToString()
  179. {
  180. return string.Format("{0} {1}", Setout.Number, Serial);
  181. }
  182. public static void Progress(IEnumerable<ManufacturingPacket> packets, ManufacturingPacketStage[] Stages)
  183. {
  184. //List<ManufacturingPacketStage> updates = new List<ManufacturingPacketStage>();
  185. foreach (var packet in packets.Where(x => !x.Stage.Equals(CoreUtils.FullGuid)))
  186. {
  187. var stages = Stages.Where(x => x.Parent.ID.Equals(packet.ID));
  188. long sequence = 0;
  189. var stage = stages.FirstOrDefault(x => x.ID.Equals(packet.Stage.ID));
  190. if (stage != null)
  191. {
  192. stage.Completed = DateTime.Now;
  193. stage.PercentageComplete = 100.0F;
  194. sequence = stage.Sequence;
  195. }
  196. // Update the pointer to the next stage
  197. stage = stages.Where(x => x.Sequence > sequence).FirstOrDefault();
  198. if (stage != null)
  199. {
  200. stage.QualityStatus = QualityStatus.NotChecked;
  201. stage.QualityNotes = "";
  202. stage.Station = 0;
  203. stage.Started = DateTime.MinValue;
  204. stage.Completed = DateTime.MinValue;
  205. stage.PercentageComplete = 0.0F;
  206. packet.Stage.ID = stage.ID;
  207. packet.Stage.Synchronise(stage);
  208. }
  209. else
  210. {
  211. packet.Stage.ID = CoreUtils.FullGuid;
  212. }
  213. packet.Issued = !packet.Stage.IsValid() ? DateTime.MinValue : packet.Issued.IsEmpty() ? DateTime.Now : packet.Issued;
  214. packet.Completed = packet.Stage.ID.Equals(CoreUtils.FullGuid)
  215. ? packet.Completed.IsEmpty() ? DateTime.Now : packet.Completed
  216. : DateTime.MinValue;
  217. }
  218. }
  219. public static void Regress(IEnumerable<ManufacturingPacket> pkts, ManufacturingPacketStage[] stgs)
  220. {
  221. foreach(var packet in pkts)
  222. {
  223. var stages = stgs.Where(x => x.Parent.ID.Equals(packet.ID));
  224. var sequence = long.MaxValue;
  225. var stage = stages.FirstOrDefault(x => x.ID.Equals(packet.Stage.ID));
  226. if (stage != null)
  227. {
  228. stage.Completed = DateTime.MinValue;
  229. stage.PercentageComplete = 0.0F;
  230. stage.QualityStatus = QualityStatus.NotChecked;
  231. stage.QualityNotes = "";
  232. sequence = stage.Sequence;
  233. }
  234. // Update the pointer to the previous stage
  235. stage = stages.Where(x => x.Sequence < sequence).LastOrDefault();
  236. if (stage != null)
  237. {
  238. stage.QualityStatus = QualityStatus.NotChecked;
  239. stage.QualityNotes = "";
  240. stage.Station = 0;
  241. stage.Started = DateTime.MinValue;
  242. stage.Completed = DateTime.MinValue;
  243. stage.PercentageComplete = 0.0F;
  244. }
  245. packet.Stage.ID = stage == null ? Guid.Empty : stage.ID;
  246. packet.Issued = !packet.Stage.IsValid() ? DateTime.MinValue : packet.Issued.IsEmpty() ? DateTime.Now : packet.Issued;
  247. packet.DueDate = packet.Issued.IsEmpty() ? DateTime.MinValue : packet.DueDate;
  248. packet.Completed = packet.Stage.ID.Equals(CoreUtils.FullGuid)
  249. ? packet.Completed.IsEmpty() ? DateTime.Now : packet.Completed
  250. : DateTime.MinValue;
  251. }
  252. }
  253. #region Aggregates
  254. [EditorSequence(300)]
  255. [DoubleEditor(Editable = Editable.Hidden)]
  256. [Formula(typeof(ManufacturingPacketArea))]
  257. public double Area { get; set; }
  258. [EditorSequence(301)]
  259. [DoubleEditor(Editable = Editable.Hidden)]
  260. [Formula(typeof(ManufacturingPacketVolume))]
  261. public double Volume { get; set; }
  262. [EditorSequence(302)]
  263. [Aggregate(typeof(ManufacturingPacketTime))]
  264. public TimeSpan Time { get; set; }
  265. [EditorSequence(303)]
  266. [Aggregate(typeof(ManufacturingPacketTimeRemaining))]
  267. public TimeSpan TimeRemaining { get; set; }
  268. [EditorSequence(304)]
  269. [Aggregate(typeof(ManufacturingPacketActualTime))]
  270. public TimeSpan ActualTime { get; set; }
  271. #endregion
  272. #region Internal / NullEditor Properties
  273. private class ManufacturingPacketStageLookup : LookupDefinitionGenerator<ManufacturingPacketStage, ManufacturingPacket>
  274. {
  275. public override Filter<ManufacturingPacketStage>? DefineFilter(ManufacturingPacket[] items)
  276. {
  277. if (items.Any())
  278. return Filter<ManufacturingPacketStage>.Where(x => x.Parent.ID).IsEqualTo(items.First().ID);
  279. return null;
  280. }
  281. public override Columns<ManufacturingPacket> DefineFilterColumns()
  282. => Columns.None<ManufacturingPacket>().Add(x => x.ID);
  283. }
  284. [LookupDefinition(typeof(ManufacturingPacketStageLookup))]
  285. [NullEditor]
  286. public ManufacturingPacketStageLink Stage { get; set; }
  287. [Obsolete("Replaced by Stage")]
  288. public ManufacturingPacketStageLink StageLink
  289. {
  290. get => Stage;
  291. set { }
  292. }
  293. [NullEditor]
  294. public QAFormLink QAForm { get; set; }
  295. // I think ITPs will end up being linked to a stage,
  296. // So this might get obsoleted at some point
  297. private class JobStageLookup : LookupDefinitionGenerator<JobStage, ManufacturingPacket>
  298. {
  299. public override Filter<JobStage> DefineFilter(ManufacturingPacket[] items)
  300. {
  301. if (items.Length == 1)
  302. return Filter<JobStage>.Where(x => x.Job.ID).IsEqualTo(items.First().Setout.Job.ID).And(x => x.IsHeader).IsEqualTo(false);
  303. return Filter<JobStage>.Where(x => x.ID).IsEqualTo(Guid.Empty);
  304. }
  305. public override Columns<ManufacturingPacket> DefineFilterColumns()
  306. => Columns.None<ManufacturingPacket>().Add(x => x.Setout.Job.ID);
  307. }
  308. [LookupDefinition(typeof(JobStageLookup))]
  309. [NullEditor]
  310. public JobStageLink JobStage { get; set; }
  311. [NullEditor]
  312. [EntityRelationship(DeleteAction.SetNull)]
  313. public PurchaseOrderItemLink OrderItem { get; set; }
  314. [NullEditor]
  315. public DateTime EstimatedDate { get; set; }
  316. #endregion
  317. #region Obsolete Properties
  318. // The code of the Linked Manufacturing Template
  319. // Suggested - set to obsolete?
  320. [NullEditor]
  321. [Obsolete("Replaced with ManufacturingTemplateLink.Code", true)]
  322. public string Code { get; set; }
  323. // The Factory to which this packet template belongs
  324. // Suggestion - Set to obsolete?
  325. [NullEditor]
  326. [Obsolete("Replaced with ManufacturingTemplateLink.FactoryLink.ID")]
  327. public string Group { get; set; }
  328. [NullEditor]
  329. [Obsolete("Replaced with BarcodeQty")]
  330. public bool GroupedBarcode { get; set; }
  331. private BarcodeType _barcodetype = BarcodeType.Unspecified;
  332. [NullEditor]
  333. [Obsolete("Replaced with BarcodeQty")]
  334. public BarcodeType BarcodeType
  335. {
  336. get => _barcodetype == BarcodeType.Unspecified ? GroupedBarcode ? BarcodeType.Grouped : BarcodeType.Individual : _barcodetype;
  337. set => _barcodetype = value;
  338. }
  339. // Comes from Setout.Title (Should be Reference)
  340. [NullEditor]
  341. [Obsolete("Replaced with SetoutLink.Reference")]
  342. public string Reference { get; set; }
  343. // Comes from Setout.Location
  344. [NullEditor]
  345. [Obsolete("Replaced with SetoutLink.Description")]
  346. public string Description { get; set; }
  347. [Obsolete("Replaced With ManufacturingTemplateLink")]
  348. [NullEditor]
  349. public Guid ManufacturingItemID { get; set; }
  350. [NullEditor]
  351. [Obsolete("Replaced with ManufacturingPacketLink.Code")]
  352. public string Template { get; set; }
  353. [Obsolete("Replaced With SetoutLink.JobLink")]
  354. [EntityRelationship(DeleteAction.Cascade)]
  355. [NullEditor]
  356. public JobLink JobLink { get; set; }
  357. #endregion
  358. #region Functions
  359. //public void MovePrevious()
  360. //{
  361. // bool bFound = false;
  362. // SetoutStage prev = null;
  363. // foreach (SetoutStage stage in Stages)
  364. // {
  365. // if (bFound)
  366. // {
  367. // stage.Started = DateTime.MinValue;
  368. // stage.Completed = DateTime.MinValue;
  369. // stage.PercentageComplete = 0.0F;
  370. // }
  371. // else if (stage.Completed.IsEmpty())
  372. // {
  373. // stage.Started = DateTime.MinValue;
  374. // stage.Completed = DateTime.MinValue;
  375. // stage.PercentageComplete = 0.0F;
  376. // bFound = true;
  377. // if (prev != null)
  378. // prev.Completed = DateTime.MinValue;
  379. // }
  380. // else
  381. // prev = stage;
  382. // }
  383. // if (prev == null)
  384. // Issued = DateTime.MinValue;
  385. // Completed = DateTime.MinValue;
  386. // Stage = CurrentStage();
  387. //}
  388. //public void MoveNext()
  389. //{
  390. // bool bFound = false;
  391. // bool bComplete = true;
  392. // if (Issued.IsEmpty())
  393. // Issued = DateTime.Now;
  394. // foreach (SetoutStage stage in Stages)
  395. // {
  396. // if (bFound)
  397. // {
  398. // stage.Started = DateTime.MinValue;
  399. // stage.Completed = DateTime.MinValue;
  400. // stage.PercentageComplete = 0.0F;
  401. // bComplete = false;
  402. // }
  403. // else if (stage.Started.IsEmpty())
  404. // {
  405. // //stage.Started = DateTime.Now;
  406. // stage.Completed = DateTime.MinValue;
  407. // stage.PercentageComplete = 0.0F;
  408. // bComplete = false;
  409. // bFound = true;
  410. // }
  411. // else if (stage.Completed.IsEmpty())
  412. // {
  413. // stage.Completed = DateTime.Now;
  414. // stage.PercentageComplete = 100.0F;
  415. // bFound = true;
  416. // }
  417. // }
  418. // //Completed = bComplete ? DateTime.Now : DateTime.MinValue;
  419. // bool bIsComplete = !Stages.Any(x => x.Completed.Equals(DateTime.MinValue));
  420. // if (bIsComplete && Completed.Equals(DateTime.MinValue))
  421. // Completed = DateTime.Now;
  422. // Stage = CurrentStage();
  423. //}
  424. //public Boolean IsComplete()
  425. //{
  426. // if ((!Issued.IsEmpty()) && (Stages != null))
  427. // {
  428. // foreach (SetoutStage stage in Stages)
  429. // {
  430. // if (stage.Completed.IsEmpty())
  431. // return false;
  432. // }
  433. // return true;
  434. // }
  435. // return false;
  436. //}
  437. //public String Status()
  438. //{
  439. // if ((Stages == null) || (!Stages.Any()))
  440. // return "No Template!";
  441. // if (Issued.IsEmpty())
  442. // return "To Be Issued";
  443. // var stage = GetCurrentStage();
  444. // if (stage != null)
  445. // {
  446. // if (!Archived.IsEmpty())
  447. // return "Cancelled";
  448. // else
  449. // return String.Format("{0} ({1:F2}%)", stage.Name, stage.PercentageComplete);
  450. // }
  451. // return "Complete";
  452. //}
  453. //public Guid CurrentStage()
  454. //{
  455. // if (Issued.IsEmpty())
  456. // return Guid.Empty;
  457. // SetoutStage stage = GetCurrentStage();
  458. // if (stage != null)
  459. // return stage.SectionID;
  460. // return CoreUtils.FullGuid;
  461. //}
  462. //public SetoutStage GetCurrentStage()
  463. //{
  464. // if ((!Issued.IsEmpty()) && (Stages != null))
  465. // {
  466. // foreach (SetoutStage stage in Stages)
  467. // {
  468. // if (stage.Completed.IsEmpty())
  469. // return stage;
  470. // }
  471. // }
  472. // return null;
  473. //}
  474. //public void SetStage(Guid id, bool complete = false)
  475. //{
  476. // bool bFound = id == Guid.Empty;
  477. // Issued = (id == Guid.Empty) ? DateTime.MinValue : Issued.IsEmpty() ? DateTime.Now : Issued;
  478. // if (id == CoreUtils.FullGuid)
  479. // {
  480. // foreach (SetoutStage stage in Stages)
  481. // {
  482. // stage.Started = stage.Started.IsEmpty() ? DateTime.Now : stage.Started;
  483. // stage.Completed = stage.Completed.IsEmpty() ? DateTime.Now : stage.Completed;
  484. // stage.PercentageComplete = 100.0F;
  485. // Completed = stage.Completed;
  486. // }
  487. // }
  488. // else
  489. // {
  490. // //Completed = DateTime.MinValue;
  491. // foreach (SetoutStage stage in Stages)
  492. // {
  493. // if (stage.SectionID.Equals(id))
  494. // {
  495. // bFound = true;
  496. // //stage.Started = stage.Started.IsEmpty() ? DateTime.Now : stage.Started;
  497. // stage.Completed = complete ? DateTime.Now : DateTime.MinValue;
  498. // stage.PercentageComplete = stage.Completed.IsEmpty() ? 0.0F : 100.0F;
  499. // }
  500. // else
  501. // {
  502. // if (!bFound)
  503. // {
  504. // // Stages Before this stage - Update Started and Completed if Empty
  505. // if (stage.Started.IsEmpty())
  506. // stage.Started = DateTime.Now;
  507. // if (stage.Completed.IsEmpty())
  508. // stage.Completed = DateTime.Now;
  509. // stage.PercentageComplete = 100.0F;
  510. // }
  511. // else
  512. // {
  513. // // Stages After This Stage - Blank out Started and Completed
  514. // stage.Started = DateTime.MinValue;
  515. // stage.Completed = DateTime.MinValue;
  516. // stage.PercentageComplete = 0.0F;
  517. // }
  518. // }
  519. // }
  520. // }
  521. // bool bIsComplete = !Stages.Any(x => x.Completed.Equals(DateTime.MinValue));
  522. // if (bIsComplete && Completed.Equals(DateTime.MinValue))
  523. // Completed = DateTime.Now;
  524. // Stage = CurrentStage();
  525. //}
  526. #endregion
  527. }
  528. }