IntegrationBOMWindowViewModel.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. using System.Linq.Expressions;
  7. using System.Runtime.CompilerServices;
  8. using System.Threading.Tasks;
  9. using System.Windows;
  10. using System.Windows.Media.Imaging;
  11. using AutoProperties;
  12. using Comal.Classes;
  13. using InABox.Core;
  14. using InABox.DynamicGrid;
  15. using InABox.Integration.Logikal;
  16. using InABox.WPF;
  17. using PRSDesktop.Integrations.Logikal;
  18. namespace PRSDesktop.Integrations.Common;
  19. public class IntegrationBOMWindowViewModel : DependencyObject
  20. {
  21. private ILogikalPartsResponse<LogikalFinish, LogikalProfile, LogikalComponent, LogikalGlass, LogikalLabour> _bom;
  22. public static DependencyProperty BOMProperty = DependencyProperty.Register(
  23. nameof(BOM),
  24. typeof(ILogikalPartsResponse<LogikalFinish, LogikalProfile, LogikalComponent, LogikalGlass, LogikalLabour>),
  25. typeof(IntegrationBOMWindowViewModel),
  26. new FrameworkPropertyMetadata(BOMChanged));
  27. private static void BOMChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  28. {
  29. if (d is not IntegrationBOMWindowViewModel model)
  30. return;
  31. var bom =
  32. e.NewValue as ILogikalPartsResponse<LogikalFinish, LogikalProfile, LogikalComponent, LogikalGlass,
  33. LogikalLabour>;
  34. ExtractMappings<ProductStyleIntegrationCode, LogikalFinish, ProductStyle, ProductStyleLink, ProductStyleIntegrationSource>(
  35. bom?.Finishes, x => x.Code, x => x.Description, x => x.Code, s => model.Styles = s);
  36. ExtractMappings<ProductIntegrationCode,LogikalProfile,Product,ProductLink, ProductIntegrationSource>(
  37. bom?.Profiles, x => x.Code, x => x.Description, x => x.Code, p => model.Profiles = p);
  38. ExtractMappings<ProductIntegrationCode,LogikalComponent,Product,ProductLink, ProductIntegrationSource>(
  39. bom?.Components, x => x.Code, x => x.Description, x => x.Code, c => model.Components = c);
  40. ExtractMappings<ProductIntegrationCode,LogikalGlass,Product,ProductLink, ProductIntegrationSource>(
  41. bom?.Glass, x => x.Code, x => x.Description, x => x.Code, g => model.Glass = g);
  42. ExtractMappings<ActivityIntegrationCode,LogikalLabour,Activity,ActivityLink, ActivityIntegrationSource>(
  43. bom?.Labour, x => x.Code, x => x.Description, x => x.Code, l => model.Labour = l);
  44. }
  45. public ILogikalPartsResponse<LogikalFinish, LogikalProfile, LogikalComponent, LogikalGlass, LogikalLabour>? BOM
  46. {
  47. get => GetValue(BOMProperty) as ILogikalPartsResponse<LogikalFinish, LogikalProfile, LogikalComponent, LogikalGlass, LogikalLabour>;
  48. set => SetValue(BOMProperty, value);
  49. }
  50. private static readonly DependencyProperty StylesProperty = DependencyProperty.Register(
  51. nameof(Styles),
  52. typeof(List<ProductStyleIntegrationCode>),
  53. typeof(IntegrationBOMWindowViewModel)
  54. );
  55. public List<ProductStyleIntegrationCode>? Styles
  56. {
  57. get => GetValue(StylesProperty) as List<ProductStyleIntegrationCode>;
  58. set => SetValue(StylesProperty, value);
  59. }
  60. private static readonly DependencyProperty ProfilesProperty = DependencyProperty.Register(
  61. nameof(Profiles),
  62. typeof(List<ProductIntegrationCode>),
  63. typeof(IntegrationBOMWindowViewModel)
  64. );
  65. public List<ProductIntegrationCode>? Profiles
  66. {
  67. get => GetValue(ProfilesProperty) as List<ProductIntegrationCode>;
  68. set => SetValue(ProfilesProperty, value);
  69. }
  70. private static readonly DependencyProperty ComponentsProperty = DependencyProperty.Register(
  71. nameof(Components),
  72. typeof(List<ProductIntegrationCode>),
  73. typeof(IntegrationBOMWindowViewModel)
  74. );
  75. public List<ProductIntegrationCode>? Components
  76. {
  77. get => GetValue(ComponentsProperty) as List<ProductIntegrationCode>;
  78. set => SetValue(ComponentsProperty, value);
  79. }
  80. private static readonly DependencyProperty GlassProperty = DependencyProperty.Register(
  81. nameof(Glass),
  82. typeof(List<ProductIntegrationCode>),
  83. typeof(IntegrationBOMWindowViewModel)
  84. );
  85. public List<ProductIntegrationCode>? Glass
  86. {
  87. get => GetValue(GlassProperty) as List<ProductIntegrationCode>;
  88. set => SetValue(GlassProperty, value);
  89. }
  90. private static readonly DependencyProperty LabourProperty = DependencyProperty.Register(
  91. nameof(Labour),
  92. typeof(List<ActivityIntegrationCode>),
  93. typeof(IntegrationBOMWindowViewModel)
  94. );
  95. public List<ActivityIntegrationCode>? Labour
  96. {
  97. get => GetValue(LabourProperty) as List<ActivityIntegrationCode>;
  98. set => SetValue(LabourProperty, value);
  99. }
  100. private static readonly DependencyProperty SectionsProperty = DependencyProperty.Register(
  101. nameof(Sections),
  102. typeof(Dictionary<string, BitmapImage>),
  103. typeof(IntegrationBOMWindowViewModel)
  104. );
  105. private Dictionary<string,BitmapImage> _sections = new()
  106. {
  107. { nameof(Styles), PRSDesktop.Resources.palette.AsBitmapImage(64, 64) },
  108. { nameof(Profiles), PRSDesktop.Resources.profile.AsBitmapImage(64, 64) },
  109. { nameof(Components), PRSDesktop.Resources.fixings.AsBitmapImage(64, 64) },
  110. { nameof(Glass), PRSDesktop.Resources.glass.AsBitmapImage(64, 64) },
  111. { nameof(Labour), PRSDesktop.Resources.quality.AsBitmapImage(64, 64) },
  112. };
  113. public Dictionary<string, BitmapImage> Sections
  114. {
  115. get => (Dictionary<string, BitmapImage>)GetValue(SectionsProperty);
  116. set => SetValue(SectionsProperty, value);
  117. }
  118. private static readonly DependencyProperty SelectedSectionProperty = DependencyProperty.Register(
  119. nameof(SelectedSection),
  120. typeof(KeyValuePair<string, BitmapImage>),
  121. typeof(IntegrationBOMWindowViewModel)
  122. );
  123. public KeyValuePair<string, BitmapImage> SelectedSection
  124. {
  125. get => (KeyValuePair<string, BitmapImage>)GetValue(SelectedSectionProperty);
  126. set => SetValue(SelectedSectionProperty, value);
  127. }
  128. public IntegrationBOMWindowViewModel()
  129. {
  130. Sections = _sections;
  131. SelectedSection = Sections.First();
  132. }
  133. private static void ExtractMappings<TCode,TLogikal,TEntity,TLink,TMapping>(
  134. IEnumerable<TLogikal>? items,
  135. Func<TLogikal,string?> logikalcode,
  136. Func<TLogikal,string?> logikaldescription,
  137. Expression<Func<TEntity,object?>> entitycode,
  138. Action<List<TCode>> update)
  139. where TCode : BaseIntegrationCode<TEntity,TLink>, new()
  140. where TEntity : Entity, IRemotable,IPersistent, new()
  141. where TLink :EntityLink<TEntity>
  142. where TMapping : BaseIntegrationSource<TEntity,TLink>, IRemotable, IPersistent, new()
  143. {
  144. Task.Run<List<TCode>>(() =>
  145. {
  146. var f = entitycode.Compile();
  147. var results = new List<TCode>();
  148. if (items == null)
  149. return results;
  150. var sourceitems = new Dictionary<string, string>(
  151. items.Select(x =>
  152. new KeyValuePair<string, string>(logikalcode(x) ?? "", logikaldescription(x) ?? "")
  153. ).Distinct()
  154. );
  155. MultiQuery query = new();
  156. query.Add<TEntity>(
  157. new Filter<TEntity>(entitycode).InList(sourceitems.Keys.ToArray()),
  158. Columns.Required<TEntity>().Add(x => x.ID).Add(entitycode)
  159. );
  160. query.Add<TMapping>(
  161. new Filter<TMapping>(x => x.Code).InList(sourceitems.Keys.ToArray()),
  162. Columns.Required<TMapping>().Add(x => x.ID).Add(x => x.Code)
  163. );
  164. query.Query();
  165. var mappings = query.Get<TMapping>().ToDictionary<TMapping,string,Guid>(x=>x.Code ?? "",x=>x.ID);
  166. var entities = query.Get<TEntity>().ToDictionary(entitycode, x=>x.ID);
  167. foreach (var sourceitem in sourceitems)
  168. {
  169. var result = new TCode()
  170. {
  171. Code = sourceitem.Key,
  172. Description = sourceitem.Value
  173. };
  174. if (mappings.ContainsKey(sourceitem.Key))
  175. {
  176. result.Entity.ID = mappings[sourceitem.Key];
  177. CoreUtils.SetPropertyValue(result.Entity,CoreUtils.GetFullPropertyName(entitycode,"."),sourceitem.Key);
  178. }
  179. else if (entities.ContainsKey(sourceitem.Key))
  180. {
  181. result.Entity.ID = entities[sourceitem.Key];
  182. CoreUtils.SetPropertyValue(result.Entity,CoreUtils.GetFullPropertyName(entitycode,"."),sourceitem.Key);
  183. }
  184. results.Add(result);
  185. }
  186. return results.ToList<TCode>();
  187. }
  188. ).ContinueWith(
  189. (task) => update?.Invoke(task.Result),
  190. TaskScheduler.FromCurrentSynchronizationContext()
  191. );
  192. }
  193. }