AWGMappingWindowViewModel.cs 29 KB

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