AWGMappingWindowViewModel.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Threading.Tasks;
  6. using System.Windows;
  7. using System.Windows.Input;
  8. using System.Windows.Media.Imaging;
  9. using Comal.Classes;
  10. using InABox.Clients;
  11. using InABox.Configuration;
  12. using InABox.Core;
  13. using InABox.Integration.Awg;
  14. using InABox.Integration.Logikal;
  15. using InABox.WPF;
  16. using Microsoft.Xaml.Behaviors.Core;
  17. using PRSDesktop.Integrations.Logikal;
  18. namespace PRSDesktop.Integrations.Common;
  19. public class AWGMappingWindowViewModel : DependencyObject
  20. {
  21. private static readonly DependencyProperty SourceTypeProperty = DependencyProperty.Register(
  22. nameof(SourceType),
  23. typeof(IntegrationSourceType),
  24. typeof(AWGMappingWindowViewModel)
  25. );
  26. public IntegrationSourceType SourceType
  27. {
  28. get => (IntegrationSourceType)GetValue(SourceTypeProperty);
  29. set => SetValue(SourceTypeProperty, value);
  30. }
  31. // public static DependencyProperty JobIDProperty = DependencyProperty.Register(
  32. // nameof(JobID),
  33. // typeof(Guid),
  34. // typeof(IntegrationBOMWindowViewModel)
  35. // );
  36. //
  37. // public Guid JobID
  38. // {
  39. // get => (Guid)GetValue(JobIDProperty);
  40. // set => SetValue(JobIDProperty, value);
  41. // }
  42. // public static DependencyProperty BOMProperty = DependencyProperty.Register(
  43. // nameof(BOM),
  44. // typeof(IAwgBOM<IAwgFinish, IAwgProfile, IAwgGasket, IAwgComponent, IAwgGlass, IAwgLabour>),
  45. // typeof(IntegrationBOMWindowViewModel),
  46. // new FrameworkPropertyMetadata(BOMChanged));
  47. //
  48. // private static void BOMChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  49. // {
  50. //
  51. // if (d is not IntegrationBOMWindowViewModel model)
  52. // return;
  53. //
  54. // var bom =
  55. // e.NewValue as IAwgBOM<IAwgFinish, IAwgProfile, IAwgGasket, IAwgComponent, IAwgGlass,
  56. // IAwgLabour>;
  57. //
  58. // var styles = model.ExtractMappings<ProductStyleIntegrationSource, IAwgFinish, ProductStyle, ProductStyleLink, ProductStyleIntegrationSource>(
  59. // bom?.Finishes, x => x.Code, x => x.Description, x => x.Code);
  60. //
  61. // var profiles = model.ExtractMappings<ProductIntegrationSource,IAwgProfile,Product,ProductLink, ProductIntegrationSource>(
  62. // bom?.Profiles, x => x.Code, x => x.Description, x => x.Code);
  63. //
  64. // var gaskets = model.ExtractMappings<ProductIntegrationSource,IAwgGasket,Product,ProductLink, ProductIntegrationSource>(
  65. // bom?.Gaskets, x => x.Code, x => x.Description, x => x.Code);
  66. //
  67. // var components = model.ExtractMappings<ProductIntegrationSource,IAwgComponent,Product,ProductLink, ProductIntegrationSource>(
  68. // bom?.Components, x => x.Code, x => x.Description, x => x.Code);
  69. //
  70. // var glass = model.ExtractMappings<ProductIntegrationSource,IAwgGlass,Product,ProductLink, ProductIntegrationSource>(
  71. // bom?.Glass, x => x.Code, x => x.Description, x => x.Code);
  72. //
  73. // var labour = model.ExtractMappings<ActivityIntegrationSource,IAwgLabour,Activity,ActivityLink, ActivityIntegrationSource>(
  74. // bom?.Labour, x => x.Code, x => x.Description, x => x.Code);
  75. //
  76. // Task.WaitAll(styles, profiles, gaskets, components, glass, labour);
  77. // model.Styles = styles.Result;
  78. // model.Profiles = profiles.Result;
  79. // model.Gaskets = gaskets.Result;
  80. // model.Components = components.Result;
  81. // model.Glass = glass.Result;
  82. // model.Labour = labour.Result;
  83. // model.CheckChanged();
  84. // }
  85. //
  86. // public IAwgBOM<IAwgFinish, IAwgProfile, IAwgGasket, IAwgComponent, IAwgGlass, IAwgLabour>? BOM
  87. // {
  88. // get => GetValue(BOMProperty) as IAwgBOM<IAwgFinish, IAwgProfile, IAwgGasket, IAwgComponent, IAwgGlass, IAwgLabour>;
  89. // set => SetValue(BOMProperty, value);
  90. // }
  91. private static readonly DependencyProperty FinishesProperty = DependencyProperty.Register(
  92. nameof(Finishes),
  93. typeof(IEnumerable<IAwgFinish>),
  94. typeof(AWGMappingWindowViewModel),
  95. new FrameworkPropertyMetadata(FinishesChanged)
  96. );
  97. private static void FinishesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  98. {
  99. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgFinish> finishes)
  100. return;
  101. var mappings =
  102. model.ExtractMappings<ProductStyleIntegrationSource, IAwgFinish, ProductStyle, ProductStyleLink>(
  103. finishes, x => x.Code, x => x.Description, x => x.Code);
  104. mappings.Wait();
  105. model.FinishMappings = mappings.Result;
  106. model.CheckChanged();
  107. }
  108. public IEnumerable<IAwgFinish>? Finishes
  109. {
  110. get => GetValue(FinishesProperty) as IEnumerable<IAwgFinish>;
  111. set => SetValue(FinishesProperty, value);
  112. }
  113. private static readonly DependencyProperty ProfilesProperty = DependencyProperty.Register(
  114. nameof(Profiles),
  115. typeof(IEnumerable<IAwgProfile>),
  116. typeof(AWGMappingWindowViewModel),
  117. new FrameworkPropertyMetadata(ProfilesChanged)
  118. );
  119. private static void ProfilesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  120. {
  121. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgProfile> profiles)
  122. return;
  123. var mappings = model.ExtractMappings<ProductIntegrationSource,IAwgProfile,Product,ProductLink>(
  124. profiles, x => x.Code, x => x.Description, x => x.Code);
  125. mappings.Wait();
  126. model.ProfileMappings = mappings.Result;
  127. model.CheckChanged();
  128. }
  129. public IEnumerable<IAwgProfile>? Profiles
  130. {
  131. get => GetValue(ProfilesProperty) as IEnumerable<IAwgProfile>;
  132. set => SetValue(ProfilesProperty, value);
  133. }
  134. private static readonly DependencyProperty GasketsProperty = DependencyProperty.Register(
  135. nameof(Gaskets),
  136. typeof(IEnumerable<IAwgGasket>),
  137. typeof(AWGMappingWindowViewModel),
  138. new FrameworkPropertyMetadata(GasketsChanged)
  139. );
  140. private static void GasketsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  141. {
  142. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgGasket> gaskets)
  143. return;
  144. var mappings = model.ExtractMappings<ProductIntegrationSource,IAwgGasket,Product,ProductLink>(
  145. gaskets, x => x.Code, x => x.Description, x => x.Code);
  146. mappings.Wait();
  147. model.GasketMappings = mappings.Result;
  148. model.CheckChanged();
  149. }
  150. public IEnumerable<IAwgGasket>? Gaskets
  151. {
  152. get => GetValue(GasketsProperty) as IEnumerable<IAwgGasket>;
  153. set => SetValue(GasketsProperty, value);
  154. }
  155. private static readonly DependencyProperty ComponentsProperty = DependencyProperty.Register(
  156. nameof(Components),
  157. typeof(IEnumerable<IAwgComponent>),
  158. typeof(AWGMappingWindowViewModel),
  159. new FrameworkPropertyMetadata(ComponentsChanged)
  160. );
  161. private static void ComponentsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  162. {
  163. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgComponent> components)
  164. return;
  165. var mappings = model.ExtractMappings<ProductIntegrationSource,IAwgComponent,Product,ProductLink>(
  166. components, x => x.Code, x => x.Description, x => x.Code);
  167. mappings.Wait();
  168. model.ComponentMappings = mappings.Result;
  169. model.CheckChanged();
  170. }
  171. public IEnumerable<IAwgComponent>? Components
  172. {
  173. get => GetValue(ComponentsProperty) as IEnumerable<IAwgComponent>;
  174. set => SetValue(ComponentsProperty, value);
  175. }
  176. private static readonly DependencyProperty GlassProperty = DependencyProperty.Register(
  177. nameof(Glass),
  178. typeof(IEnumerable<IAwgGlass>),
  179. typeof(AWGMappingWindowViewModel),
  180. new FrameworkPropertyMetadata(GlassChanged)
  181. );
  182. private static void GlassChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  183. {
  184. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgGlass> glass)
  185. return;
  186. var mappings = model.ExtractMappings<ProductIntegrationSource,IAwgGlass,Product,ProductLink>(
  187. glass, x => x.Code, x => x.Description, x => x.Code);
  188. mappings.Wait();
  189. model.GlassMappings = mappings.Result;
  190. model.CheckChanged();
  191. }
  192. public IEnumerable<IAwgGlass>? Glass
  193. {
  194. get => GetValue(GlassProperty) as IEnumerable<IAwgGlass>;
  195. set => SetValue(GlassProperty, value);
  196. }
  197. private static readonly DependencyProperty LabourProperty = DependencyProperty.Register(
  198. nameof(Labour),
  199. typeof(IEnumerable<IAwgLabour>),
  200. typeof(AWGMappingWindowViewModel),
  201. new FrameworkPropertyMetadata(LabourChanged)
  202. );
  203. private static void LabourChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  204. {
  205. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgLabour> labour)
  206. return;
  207. var mappings = model.ExtractMappings<ActivityIntegrationSource,IAwgLabour,Activity,ActivityLink>(
  208. labour, x => x.Code, x => x.Description, x => x.Code);
  209. mappings.Wait();
  210. model.LabourMappings = mappings.Result;
  211. model.CheckChanged();
  212. }
  213. public IEnumerable<IAwgLabour>? Labour
  214. {
  215. get => GetValue(LabourProperty) as IEnumerable<IAwgLabour>;
  216. set => SetValue(LabourProperty, value);
  217. }
  218. private static readonly DependencyProperty FinishMappingsProperty = DependencyProperty.Register(
  219. nameof(FinishMappings),
  220. typeof(List<ProductStyleIntegrationSource>),
  221. typeof(AWGMappingWindowViewModel)
  222. );
  223. public List<ProductStyleIntegrationSource>? FinishMappings
  224. {
  225. get => GetValue(FinishMappingsProperty) as List<ProductStyleIntegrationSource>;
  226. set => SetValue(FinishMappingsProperty, value);
  227. }
  228. private static readonly DependencyProperty FinishesCheckedProperty = DependencyProperty.Register(
  229. nameof(FinishesChecked),
  230. typeof(bool),
  231. typeof(AWGMappingWindowViewModel),
  232. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback:SectionCheckedChanged)
  233. );
  234. private static void SectionCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  235. {
  236. if (d is AWGMappingWindowViewModel model)
  237. model.CheckChanged();
  238. }
  239. public bool FinishesChecked
  240. {
  241. get => (bool)GetValue(FinishesCheckedProperty);
  242. set => SetValue(FinishesCheckedProperty, value);
  243. }
  244. private static readonly DependencyProperty ProfileMappingsProperty = DependencyProperty.Register(
  245. nameof(ProfileMappings),
  246. typeof(List<ProductIntegrationSource>),
  247. typeof(AWGMappingWindowViewModel)
  248. );
  249. public List<ProductIntegrationSource>? ProfileMappings
  250. {
  251. get => GetValue(ProfileMappingsProperty) as List<ProductIntegrationSource>;
  252. set => SetValue(ProfileMappingsProperty, value);
  253. }
  254. private static readonly DependencyProperty ProfilesCheckedProperty = DependencyProperty.Register(
  255. nameof(ProfilesChecked),
  256. typeof(bool),
  257. typeof(AWGMappingWindowViewModel),
  258. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback:SectionCheckedChanged)
  259. );
  260. public bool ProfilesChecked
  261. {
  262. get => (bool)GetValue(ProfilesCheckedProperty);
  263. set => SetValue(ProfilesCheckedProperty, value);
  264. }
  265. private static readonly DependencyProperty GasketMappingsProperty = DependencyProperty.Register(
  266. nameof(GasketMappings),
  267. typeof(List<ProductIntegrationSource>),
  268. typeof(AWGMappingWindowViewModel)
  269. );
  270. public List<ProductIntegrationSource>? GasketMappings
  271. {
  272. get => GetValue(GasketMappingsProperty) as List<ProductIntegrationSource>;
  273. set => SetValue(GasketMappingsProperty, value);
  274. }
  275. private static readonly DependencyProperty GasketsCheckedProperty = DependencyProperty.Register(
  276. nameof(GasketsChecked),
  277. typeof(bool),
  278. typeof(AWGMappingWindowViewModel),
  279. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback:SectionCheckedChanged)
  280. );
  281. public bool GasketsChecked
  282. {
  283. get => (bool)GetValue(GasketsCheckedProperty);
  284. set => SetValue(GasketsCheckedProperty, value);
  285. }
  286. private static readonly DependencyProperty ComponentMappingsProperty = DependencyProperty.Register(
  287. nameof(ComponentMappings),
  288. typeof(List<ProductIntegrationSource>),
  289. typeof(AWGMappingWindowViewModel)
  290. );
  291. public List<ProductIntegrationSource>? ComponentMappings
  292. {
  293. get => GetValue(ComponentMappingsProperty) as List<ProductIntegrationSource>;
  294. set => SetValue(ComponentMappingsProperty, value);
  295. }
  296. private static readonly DependencyProperty ComponentsCheckedProperty = DependencyProperty.Register(
  297. nameof(ComponentsChecked),
  298. typeof(bool),
  299. typeof(AWGMappingWindowViewModel),
  300. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback:SectionCheckedChanged)
  301. );
  302. public bool ComponentsChecked
  303. {
  304. get => (bool)GetValue(ComponentsCheckedProperty);
  305. set => SetValue(ComponentsCheckedProperty, value);
  306. }
  307. private static readonly DependencyProperty GlassMappingsProperty = DependencyProperty.Register(
  308. nameof(GlassMappings),
  309. typeof(List<ProductIntegrationSource>),
  310. typeof(AWGMappingWindowViewModel)
  311. );
  312. public List<ProductIntegrationSource>? GlassMappings
  313. {
  314. get => GetValue(GlassMappingsProperty) as List<ProductIntegrationSource>;
  315. set => SetValue(GlassMappingsProperty, value);
  316. }
  317. private static readonly DependencyProperty GlassCheckedProperty = DependencyProperty.Register(
  318. nameof(GlassChecked),
  319. typeof(bool),
  320. typeof(AWGMappingWindowViewModel),
  321. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback:SectionCheckedChanged)
  322. );
  323. public bool GlassChecked
  324. {
  325. get => (bool)GetValue(GlassCheckedProperty);
  326. set => SetValue(GlassCheckedProperty, value);
  327. }
  328. private static readonly DependencyProperty LabourMappingsProperty = DependencyProperty.Register(
  329. nameof(LabourMappings),
  330. typeof(List<ActivityIntegrationSource>),
  331. typeof(AWGMappingWindowViewModel)
  332. );
  333. public List<ActivityIntegrationSource>? LabourMappings
  334. {
  335. get => GetValue(LabourMappingsProperty) as List<ActivityIntegrationSource>;
  336. set => SetValue(LabourMappingsProperty, value);
  337. }
  338. private static readonly DependencyProperty LabourCheckedProperty = DependencyProperty.Register(
  339. nameof(LabourChecked),
  340. typeof(bool),
  341. typeof(AWGMappingWindowViewModel),
  342. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback:SectionCheckedChanged)
  343. );
  344. public bool LabourChecked
  345. {
  346. get => (bool)GetValue(LabourCheckedProperty);
  347. set => SetValue(LabourCheckedProperty, value);
  348. }
  349. private static readonly DependencyProperty SectionsProperty = DependencyProperty.Register(
  350. nameof(Sections),
  351. typeof(CoreObservableCollection<KeyValuePair<string,BitmapImage>>),
  352. typeof(AWGMappingWindowViewModel),
  353. new PropertyMetadata(new CoreObservableCollection<KeyValuePair<string,BitmapImage>>())
  354. );
  355. public CoreObservableCollection<KeyValuePair<string,BitmapImage>> Sections
  356. {
  357. get => (CoreObservableCollection<KeyValuePair<string,BitmapImage>>)GetValue(SectionsProperty);
  358. set => SetValue(SectionsProperty, value);
  359. }
  360. private static readonly DependencyProperty SelectedSectionProperty = DependencyProperty.Register(
  361. nameof(SelectedSection),
  362. typeof(KeyValuePair<string, BitmapImage>?),
  363. typeof(AWGMappingWindowViewModel)
  364. );
  365. public KeyValuePair<string, BitmapImage>? SelectedSection
  366. {
  367. get => (KeyValuePair<string, BitmapImage>?)GetValue(SelectedSectionProperty);
  368. set => SetValue(SelectedSectionProperty, value);
  369. }
  370. private static readonly DependencyProperty MappingsCompleteProperty = DependencyProperty.Register(
  371. nameof(MappingsComplete),
  372. typeof(bool),
  373. typeof(AWGMappingWindowViewModel)
  374. );
  375. public bool MappingsComplete
  376. {
  377. get => (bool)GetValue(MappingsCompleteProperty);
  378. set => SetValue(MappingsCompleteProperty, value);
  379. }
  380. private LogikalSettings _settings;
  381. public AWGMappingWindowViewModel()
  382. {
  383. _settings = new GlobalConfiguration<LogikalSettings>().Load();
  384. }
  385. public Task<List<TCode>> ExtractMappings<TCode,TType,TEntity,TLink>(
  386. IEnumerable<TType>? items,
  387. Func<TType,string?> logikalcode,
  388. Func<TType,string?> logikaldescription,
  389. Expression<Func<TEntity,object?>> entitycode)
  390. where TType : IAwgBOMItem
  391. where TCode : BaseIntegrationSource<TEntity,TLink>, IRemotable, IPersistent, new()
  392. where TEntity : Entity, IRemotable,IPersistent, new()
  393. where TLink :EntityLink<TEntity>
  394. {
  395. return Task.Run(() =>
  396. {
  397. var f = entitycode.Compile();
  398. var results = new List<TCode>();
  399. if (items == null)
  400. return results;
  401. var sourceitems = new Dictionary<string, string>();
  402. foreach (var item in items)
  403. sourceitems[logikalcode(item) ?? ""] = logikaldescription(item) ?? "";
  404. MultiQuery query = new();
  405. query.Add<TEntity>(
  406. new Filter<TEntity>(entitycode).InList(sourceitems.Keys.ToArray()),
  407. Columns.Required<TEntity>().Add(x => x.ID).Add(entitycode)
  408. );
  409. var entitycodecol = $"Entity.{CoreUtils.GetFullPropertyName(entitycode, ".")}";
  410. query.Add<TCode>(
  411. new Filter<TCode>(x => x.Code).InList(sourceitems.Keys.ToArray()),
  412. Columns.Required<TCode>()
  413. .Add(x => x.ID)
  414. .Add(x => x.Code)
  415. .Add(x=>x.Entity.ID)
  416. .Add(entitycodecol)
  417. );
  418. query.Query();
  419. var mappings = query.Get<TCode>().ToObjects<TCode>().ToArray();
  420. var entities = query.Get<TEntity>();
  421. foreach (var sourceitem in sourceitems)
  422. {
  423. var result = new TCode()
  424. {
  425. Code = sourceitem.Key,
  426. Description = sourceitem.Value
  427. };
  428. var mapping = mappings.FirstOrDefault(x => string.Equals(x.Code, sourceitem.Key));
  429. if (mapping != null)
  430. result.Entity.CopyFrom(mapping.Entity);
  431. else
  432. {
  433. var entity = entities.Rows.FirstOrDefault(r => string.Equals(sourceitem.Key,r.Get<TEntity,object?>(entitycode)));
  434. if (entity != null)
  435. result.Entity.CopyFrom(entity.ToObject<TEntity>());
  436. }
  437. results.Add(result);
  438. result.PropertyChanged += (s, e) =>
  439. {
  440. // TMapping mapping = mappingtable.Rows.FirstOrDefault(r =>
  441. // string.Equals(r.Get<TMapping, String>(c => c.Code), result.Code))?.ToObject<TMapping>();
  442. // if (mapping == null)
  443. // mapping = new TMapping() { Code = result.Code };
  444. // mapping.Entity.ID = result.Entity.ID;
  445. // new Client<TMapping>().Save(mapping, "Created from BOM Integration Window");
  446. CheckChanged();
  447. };
  448. }
  449. return results;
  450. });
  451. }
  452. private void CheckChanged()
  453. {
  454. Dispatcher.BeginInvoke(() =>
  455. {
  456. var curSel = SelectedSection?.Key ?? "";
  457. SelectedSection = null;
  458. Sections.Clear();
  459. if (FinishesChecked && FinishMappings?.Any() == true)
  460. Sections.Add(new KeyValuePair<string, BitmapImage>("Finishes",PRSDesktop.Resources.palette.AsBitmapImage(64, 64)));
  461. if (ProfilesChecked && ProfileMappings?.Any() == true)
  462. Sections.Add(new KeyValuePair<string, BitmapImage>("Profiles",PRSDesktop.Resources.profile.AsBitmapImage(64, 64)));
  463. if (GasketsChecked && GasketMappings?.Any() == true)
  464. Sections.Add(new KeyValuePair<string, BitmapImage>("Gaskets",PRSDesktop.Resources.gasket.AsBitmapImage(64, 64)));
  465. if (ComponentsChecked && ComponentMappings?.Any() == true)
  466. Sections.Add(new KeyValuePair<string, BitmapImage>("Components",PRSDesktop.Resources.fixings.AsBitmapImage(64, 64)));
  467. if (GlassChecked && GlassMappings?.Any() == true)
  468. Sections.Add(new KeyValuePair<string, BitmapImage>("Glass",PRSDesktop.Resources.glass.AsBitmapImage(64, 64)));
  469. if (LabourChecked && LabourMappings?.Any() == true)
  470. Sections.Add(new KeyValuePair<string, BitmapImage>("Labour",PRSDesktop.Resources.quality.AsBitmapImage(64, 64)));
  471. SelectedSection = Sections.Any(x=>string.Equals(x.Key,curSel))
  472. ? Sections.First(x=>string.Equals(x.Key,curSel))
  473. : Sections.FirstOrDefault();
  474. var styles = !FinishesChecked || (FinishMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  475. var profiles = !ProfilesChecked || (ProfileMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  476. var glass = !GlassChecked || (GlassMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  477. var components = !ComponentsChecked || (ComponentMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  478. var labour = !LabourChecked || (LabourMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  479. MappingsComplete = styles && profiles && glass && components && labour;
  480. });
  481. }
  482. public ICommand CreateStyle => new ActionCommand(
  483. o =>
  484. {
  485. if (o is IntegrationGridCreateEntityArgs<ProductStyle, ProductStyleIntegrationSource> args)
  486. {
  487. args.Entity.Code = args.Mapping.Code ?? "";
  488. args.Entity.Description = args.Mapping.Description ?? "";
  489. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  490. }
  491. }
  492. );
  493. public ICommand CreateProfile => new ActionCommand(
  494. o =>
  495. {
  496. if (o is IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  497. {
  498. args.Entity.Code = args.Mapping.Code ?? "";
  499. args.Entity.Name = args.Mapping.Description ?? "";
  500. args.Entity.UnitOfMeasure.CopyFrom(_settings.ProfileUom);
  501. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  502. }
  503. }
  504. );
  505. public ICommand CreateGasket => new ActionCommand(
  506. o =>
  507. {
  508. if (o is IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  509. {
  510. args.Entity.Code = args.Mapping.Code ?? "";
  511. args.Entity.Name = args.Mapping.Description ?? "";
  512. args.Entity.UnitOfMeasure.CopyFrom(_settings.GasketUom);
  513. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  514. }
  515. }
  516. );
  517. public ICommand CreateComponent => new ActionCommand(
  518. o =>
  519. {
  520. if (o is IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  521. {
  522. args.Entity.Code = args.Mapping.Code ?? "";
  523. args.Entity.Name = args.Mapping.Description ?? "";
  524. args.Entity.UnitOfMeasure.CopyFrom(_settings.ComponentUom);
  525. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  526. }
  527. }
  528. );
  529. public ICommand CreateGlass => new ActionCommand(
  530. o =>
  531. {
  532. if (o is IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  533. {
  534. args.Entity.Code = args.Mapping.Code ?? "";
  535. args.Entity.Name = args.Mapping.Description ?? "";
  536. args.Entity.UnitOfMeasure.CopyFrom(_settings.GlassUom);
  537. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  538. }
  539. }
  540. );
  541. public ICommand CreateActivity => new ActionCommand(
  542. o =>
  543. {
  544. if (o is IntegrationGridCreateEntityArgs<Activity, ActivityIntegrationSource> args)
  545. {
  546. args.Entity.Code = args.Mapping.Code ?? "";
  547. args.Entity.Description = args.Mapping.Description ?? "";
  548. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  549. }
  550. }
  551. );
  552. private class RawDimensions : IBaseDimensions
  553. {
  554. public double Quantity { get; set; }
  555. public double Length { get; set; }
  556. public double Width { get; set; }
  557. public double Height { get; set; }
  558. public double Weight { get; set; }
  559. }
  560. public void GetParts(
  561. Action<ProductLink, ProductStyleLink?, IBaseDimensions, double, double>? productCallback,
  562. Action<ActivityLink, TimeSpan, double>? labourCallback)
  563. {
  564. GetParts(Profiles,Gaskets,Components,Glass,Labour,productCallback,labourCallback);
  565. }
  566. public void GetParts<TProfile, TGasket, TComponent, TGlass, TLabour>(
  567. IEnumerable<TProfile>? profiles,
  568. IEnumerable<TGasket>? gaskets,
  569. IEnumerable<TComponent>? components,
  570. IEnumerable<TGlass>? glasses,
  571. IEnumerable<TLabour>? labour,
  572. Action<ProductLink, ProductStyleLink?, IBaseDimensions, double, double>? productCallback,
  573. Action<ActivityLink, TimeSpan, double>? labourCallback)
  574. where TProfile : IAwgProfile
  575. where TGasket : IAwgGasket
  576. where TComponent : IAwgComponent
  577. where TGlass : IAwgGlass
  578. where TLabour : IAwgLabour
  579. {
  580. if (ProfilesChecked && profiles != null)
  581. {
  582. foreach (var profile in profiles)
  583. {
  584. var profilemapping = ProfileMappings?.FirstOrDefault(x => x.Code == profile.Code);
  585. var stylemapping = FinishMappings?.FirstOrDefault(x => string.Equals(x.Code, profile.Finish));
  586. if (profilemapping != null && productCallback is not null)
  587. {
  588. productCallback(
  589. profilemapping.Entity,
  590. stylemapping?.Entity,
  591. new RawDimensions() { Length = profile.Length },
  592. profile.Quantity,
  593. profile.Cost);
  594. }
  595. }
  596. }
  597. if (GasketsChecked && gaskets != null)
  598. {
  599. foreach (var gasket in gaskets)
  600. {
  601. var gasketmapping = GasketMappings?.FirstOrDefault(x => x.Code == gasket.Code);
  602. if (gasketmapping != null && productCallback is not null)
  603. {
  604. productCallback(
  605. gasketmapping.Entity,
  606. null,
  607. new RawDimensions() { Length = 1.0 },
  608. gasket.Quantity,
  609. gasket.Cost);
  610. }
  611. }
  612. }
  613. if (ComponentsChecked && components != null)
  614. {
  615. foreach (var component in components)
  616. {
  617. var componentmapping = ComponentMappings?.FirstOrDefault(x => string.Equals(x.Code, component.Code));
  618. if (componentmapping != null && productCallback is not null)
  619. {
  620. productCallback(
  621. componentmapping.Entity,
  622. null,
  623. new RawDimensions() { Quantity = component.PackSize },
  624. component.Quantity,
  625. component.Cost);
  626. }
  627. }
  628. }
  629. if (GlassChecked && glasses != null)
  630. {
  631. foreach (var glass in glasses)
  632. {
  633. var glassmapping = GlassMappings?.FirstOrDefault(x => string.Equals(x.Code, glass.Code));
  634. if (glassmapping != null && productCallback is not null)
  635. {
  636. productCallback(
  637. glassmapping.Entity,
  638. null,
  639. new RawDimensions() { Height = glass.Height, Width = glass.Width },
  640. glass.Quantity,
  641. glass.Cost);
  642. }
  643. }
  644. }
  645. if (LabourChecked && labour != null)
  646. {
  647. foreach (var activity in labour)
  648. {
  649. var activitymapping = LabourMappings?.FirstOrDefault(x => string.Equals(x.Code, activity.Code));
  650. if (activitymapping != null && labourCallback is not null)
  651. {
  652. labourCallback(
  653. activitymapping.Entity,
  654. TimeSpan.FromHours(activity.Quantity),
  655. activity.Cost);
  656. }
  657. }
  658. }
  659. }
  660. // public void CreateBOM()
  661. // {
  662. // if (Finishes == null || Profiles == null || Gaskets == null || Components == null || Glass == null || Labour == null)
  663. // return;
  664. //
  665. // List<JobBillOfMaterialsItem> items = new List<JobBillOfMaterialsItem>();
  666. //
  667. // foreach (var profile in Profiles)
  668. // {
  669. // var profilemapping = ProfileMappings?.FirstOrDefault(x => x.Code == profile.Code);
  670. // var stylemapping = FinishMappings?.FirstOrDefault(x => string.Equals(x.Code, profile.Finish));
  671. // if (profilemapping != null)
  672. // {
  673. // JobBillOfMaterialsItem newitem = new JobBillOfMaterialsItem();
  674. // newitem.Product.CopyFrom(profilemapping.Entity);
  675. // newitem.Dimensions.Unit.CopyFrom(profilemapping.Entity.UnitOfMeasure);
  676. // newitem.Dimensions.Length = profile.Length;
  677. // if (stylemapping != null)
  678. // newitem.Style.CopyFrom(stylemapping.Entity);
  679. // newitem.Quantity = profile.Quantity;
  680. // newitem.UnitCost = profile.Cost;
  681. // items.Add(newitem);
  682. // }
  683. // }
  684. //
  685. // foreach (var component in Components)
  686. // {
  687. // var componentmapping = ComponentMappings?.FirstOrDefault(x => string.Equals(x.Code, component.Code));
  688. // if (componentmapping != null)
  689. // {
  690. // JobBillOfMaterialsItem newitem = new JobBillOfMaterialsItem();
  691. // newitem.Product.CopyFrom(componentmapping.Entity);
  692. // newitem.Dimensions.Unit.CopyFrom(componentmapping.Entity.UnitOfMeasure);
  693. // newitem.Dimensions.Quantity = component.PackSize;
  694. // newitem.Quantity = component.Quantity;
  695. // newitem.UnitCost = component.Cost;
  696. // items.Add(newitem);
  697. // }
  698. // }
  699. //
  700. // foreach (var glass in Glass)
  701. // {
  702. // var glassmapping = GlassMappings?.FirstOrDefault(x => string.Equals(x.Code, glass.Code));
  703. // if (glassmapping != null)
  704. // {
  705. // JobBillOfMaterialsItem newitem = new JobBillOfMaterialsItem();
  706. // newitem.Product.CopyFrom(glassmapping.Entity);
  707. // newitem.Dimensions.Unit.CopyFrom(glassmapping.Entity.UnitOfMeasure);
  708. // newitem.Dimensions.Height = glass.Height;
  709. // newitem.Dimensions.Height = glass.Width;
  710. // newitem.Quantity = glass.Quantity;
  711. // newitem.UnitCost = glass.Cost;
  712. // items.Add(newitem);
  713. // }
  714. // }
  715. //
  716. // List<JobBillOfMaterialsActivity> activities = new List<JobBillOfMaterialsActivity>();
  717. //
  718. // foreach (var activity in Labour)
  719. // {
  720. // var activitymapping = LabourMappings?.FirstOrDefault(x => string.Equals(x.Code, activity.Code));
  721. // if (activitymapping != null)
  722. // {
  723. // JobBillOfMaterialsActivity newactivity = new JobBillOfMaterialsActivity();
  724. // newactivity.ActivityLink.CopyFrom(activitymapping.Entity);
  725. // newactivity.Duration = TimeSpan.FromHours(activity.Quantity);
  726. // newactivity.HourlyCost = activity.Cost;
  727. // activities.Add(newactivity);
  728. // }
  729. // }
  730. //
  731. // var _jobbom = new JobBillOfMaterials();
  732. // _jobbom.Job.ID = JobID;
  733. // _jobbom.Description = $"BOM Imported {DateTime.Now}";
  734. //
  735. // Progress.ShowModal("Creating BOM...", progress =>
  736. // {
  737. // Client.Save(_jobbom, "Imported From Logikal");
  738. //
  739. // progress.Report("Updating Items");
  740. // foreach (var item in items)
  741. // {
  742. // item.BillOfMaterials.ID = _jobbom.ID;
  743. // item.Job.ID = _jobbom.Job.ID;
  744. // }
  745. //
  746. // Client.Save(items, "Imported From Logikal");
  747. //
  748. // progress.Report("Updating Labour");
  749. // foreach (var activity in activities)
  750. // {
  751. // activity.BillOfMaterials.ID = _jobbom.ID;
  752. // activity.JobLink.ID = _jobbom.Job.ID;
  753. // }
  754. //
  755. // Client.Save(activities, "Imported From Logikal");
  756. //
  757. //
  758. // });
  759. // }
  760. }