AWGMappingWindowViewModel.cs 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Net.Http;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Input;
  9. using System.Windows.Media.Imaging;
  10. using Comal.Classes;
  11. using InABox.Clients;
  12. using InABox.Configuration;
  13. using InABox.Core;
  14. using InABox.Integration.Awg;
  15. using InABox.WPF;
  16. using Inflector;
  17. using Microsoft.Xaml.Behaviors.Core;
  18. using sun.text.resources.ro;
  19. namespace PRSDesktop.Integrations.Common;
  20. public class AWGMappingWindowViewModel : DependencyObject
  21. {
  22. private readonly LogikalSettings _settings;
  23. public LogikalSettings Settings => _settings;
  24. public AWGMappingWindowViewModel() : base()
  25. {
  26. _settings = new GlobalConfiguration<LogikalSettings>().Load();
  27. }
  28. private static readonly DependencyProperty SourceTypeProperty = DependencyProperty.Register(
  29. nameof(SourceType),
  30. typeof(IntegrationSourceType),
  31. typeof(AWGMappingWindowViewModel)
  32. );
  33. public IntegrationSourceType SourceType
  34. {
  35. get => (IntegrationSourceType)GetValue(SourceTypeProperty);
  36. set => SetValue(SourceTypeProperty, value);
  37. }
  38. // public static DependencyProperty JobIDProperty = DependencyProperty.Register(
  39. // nameof(JobID),
  40. // typeof(Guid),
  41. // typeof(IntegrationBOMWindowViewModel)
  42. // );
  43. //
  44. // public Guid JobID
  45. // {
  46. // get => (Guid)GetValue(JobIDProperty);
  47. // set => SetValue(JobIDProperty, value);
  48. // }
  49. // public static DependencyProperty BOMProperty = DependencyProperty.Register(
  50. // nameof(BOM),
  51. // typeof(IAwgBOM<IAwgFinish, IAwgProfile, IAwgGasket, IAwgComponent, IAwgGlass, IAwgLabour>),
  52. // typeof(IntegrationBOMWindowViewModel),
  53. // new FrameworkPropertyMetadata(BOMChanged));
  54. //
  55. // private static void BOMChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  56. // {
  57. //
  58. // if (d is not IntegrationBOMWindowViewModel model)
  59. // return;
  60. //
  61. // var bom =
  62. // e.NewValue as IAwgBOM<IAwgFinish, IAwgProfile, IAwgGasket, IAwgComponent, IAwgGlass,
  63. // IAwgLabour>;
  64. //
  65. // var styles = model.ExtractMappings<ProductStyleIntegrationSource, IAwgFinish, ProductStyle, ProductStyleLink, ProductStyleIntegrationSource>(
  66. // bom?.Finishes, x => x.Code, x => x.Description, x => x.Code);
  67. //
  68. // var profiles = model.ExtractMappings<ProductIntegrationSource,IAwgProfile,Product,ProductLink, ProductIntegrationSource>(
  69. // bom?.Profiles, x => x.Code, x => x.Description, x => x.Code);
  70. //
  71. // var gaskets = model.ExtractMappings<ProductIntegrationSource,IAwgGasket,Product,ProductLink, ProductIntegrationSource>(
  72. // bom?.Gaskets, x => x.Code, x => x.Description, x => x.Code);
  73. //
  74. // var components = model.ExtractMappings<ProductIntegrationSource,IAwgComponent,Product,ProductLink, ProductIntegrationSource>(
  75. // bom?.Components, x => x.Code, x => x.Description, x => x.Code);
  76. //
  77. // var glass = model.ExtractMappings<ProductIntegrationSource,IAwgGlass,Product,ProductLink, ProductIntegrationSource>(
  78. // bom?.Glass, x => x.Code, x => x.Description, x => x.Code);
  79. //
  80. // var labour = model.ExtractMappings<ActivityIntegrationSource,IAwgLabour,Activity,ActivityLink, ActivityIntegrationSource>(
  81. // bom?.Labour, x => x.Code, x => x.Description, x => x.Code);
  82. //
  83. // Task.WaitAll(styles, profiles, gaskets, components, glass, labour);
  84. // model.Styles = styles.Result;
  85. // model.Profiles = profiles.Result;
  86. // model.Gaskets = gaskets.Result;
  87. // model.Components = components.Result;
  88. // model.Glass = glass.Result;
  89. // model.Labour = labour.Result;
  90. // model.CheckChanged();
  91. // }
  92. //
  93. // public IAwgBOM<IAwgFinish, IAwgProfile, IAwgGasket, IAwgComponent, IAwgGlass, IAwgLabour>? BOM
  94. // {
  95. // get => GetValue(BOMProperty) as IAwgBOM<IAwgFinish, IAwgProfile, IAwgGasket, IAwgComponent, IAwgGlass, IAwgLabour>;
  96. // set => SetValue(BOMProperty, value);
  97. // }
  98. private static readonly DependencyProperty StylesProperty = DependencyProperty.Register(
  99. nameof(Styles),
  100. typeof(IEnumerable<IAwgStyle>),
  101. typeof(AWGMappingWindowViewModel),
  102. new FrameworkPropertyMetadata(StylesChanged)
  103. );
  104. private static void StylesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  105. {
  106. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgStyle> styles)
  107. return;
  108. var mappings =
  109. model.ExtractMappings<ProductStyleIntegrationSource, IAwgStyle, ProductStyle, ProductStyleLink>(
  110. styles,
  111. (logikal, mapping) =>
  112. {
  113. mapping.Cost = logikal.Cost;
  114. mapping.StyleType = logikal.StyleType;
  115. },
  116. x => x.Code
  117. );
  118. mappings.Wait();
  119. model.StyleMappings = mappings.Result;
  120. model.CheckChanged();
  121. }
  122. public IEnumerable<IAwgStyle>? Styles
  123. {
  124. get => GetValue(StylesProperty) as IEnumerable<IAwgStyle>;
  125. set => SetValue(StylesProperty, value);
  126. }
  127. private static readonly DependencyProperty GroupsProperty = DependencyProperty.Register(
  128. nameof(Groups),
  129. typeof(IEnumerable<IAwgGroup>),
  130. typeof(AWGMappingWindowViewModel),
  131. new FrameworkPropertyMetadata(GroupsChanged)
  132. );
  133. private static void GroupsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  134. {
  135. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgGroup> groups)
  136. return;
  137. var mappings =
  138. model.ExtractMappings<ProductGroupIntegrationSource, IAwgGroup, ProductGroup, ProductGroupLink>(
  139. groups,
  140. (logikal, mapping) =>
  141. {
  142. mapping.Parent = logikal.Parent;
  143. },
  144. x => x.Code
  145. );
  146. mappings.Wait();
  147. model.GroupMappings = mappings.Result;
  148. model.CheckChanged();
  149. }
  150. public IEnumerable<IAwgGroup>? Groups
  151. {
  152. get => GetValue(GroupsProperty) as IEnumerable<IAwgGroup>;
  153. set => SetValue(GroupsProperty, value);
  154. }
  155. private static readonly DependencyProperty SuppliersProperty = DependencyProperty.Register(
  156. nameof(Suppliers),
  157. typeof(IEnumerable<IAwgSupplier>),
  158. typeof(AWGMappingWindowViewModel),
  159. new FrameworkPropertyMetadata(SuppliersChanged)
  160. );
  161. private static void SuppliersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  162. {
  163. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgSupplier> suppliers)
  164. return;
  165. var mappings =
  166. model.ExtractMappings<SupplierIntegrationSource, IAwgSupplier, Supplier, SupplierLink>(
  167. suppliers,
  168. null,
  169. x => x.Code
  170. );
  171. mappings.Wait();
  172. model.SupplierMappings = mappings.Result;
  173. model.CheckChanged();
  174. }
  175. public IEnumerable<IAwgSupplier>? Suppliers
  176. {
  177. get => GetValue(SuppliersProperty) as IEnumerable<IAwgSupplier>;
  178. set => SetValue(SuppliersProperty, value);
  179. }
  180. private static readonly DependencyProperty ProfilesProperty = DependencyProperty.Register(
  181. nameof(Profiles),
  182. typeof(IEnumerable<IAwgProfile>),
  183. typeof(AWGMappingWindowViewModel),
  184. new FrameworkPropertyMetadata(ProfilesChanged)
  185. );
  186. private static void ProfilesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  187. {
  188. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgProfile> profiles)
  189. return;
  190. var mappings = model.ExtractMappings<ProductIntegrationSource, IAwgProfile, Product, ProductLink>(
  191. profiles,
  192. (logikal, mapping) =>
  193. {
  194. mapping.Style = logikal.Finish;
  195. mapping.Dimensions.Unit.CopyFrom(model.Settings.ProfileUom);
  196. mapping.Dimensions.Length = logikal.Length;
  197. mapping.Group = logikal.Group;
  198. mapping.Supplier = logikal.Supplier;
  199. mapping.Cost = logikal.Cost;
  200. mapping.Quantity = logikal.Quantity;
  201. mapping.TreatmentParameters[AwgStyleType.Powdercoated] = logikal.PaintPerimeter;
  202. mapping.TreatmentParameters[AwgStyleType.Anodised] = logikal.AnodizePerimeter;
  203. },
  204. x => x.Code
  205. );
  206. mappings.Wait();
  207. model.ProfileMappings = mappings.Result;
  208. model.CheckChanged();
  209. }
  210. public IEnumerable<IAwgProfile>? Profiles
  211. {
  212. get => GetValue(ProfilesProperty) as IEnumerable<IAwgProfile>;
  213. set => SetValue(ProfilesProperty, value);
  214. }
  215. private static readonly DependencyProperty GasketsProperty = DependencyProperty.Register(
  216. nameof(Gaskets),
  217. typeof(IEnumerable<IAwgGasket>),
  218. typeof(AWGMappingWindowViewModel),
  219. new FrameworkPropertyMetadata(GasketsChanged)
  220. );
  221. private static void GasketsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  222. {
  223. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgGasket> gaskets)
  224. return;
  225. var mappings = model.ExtractMappings<ProductIntegrationSource, IAwgGasket, Product, ProductLink>(
  226. gaskets,
  227. (logikal, mapping) =>
  228. {
  229. mapping.Group = logikal.Group;
  230. mapping.Supplier = logikal.Supplier;
  231. mapping.Dimensions.Unit.CopyFrom(model.Settings.GasketUom);
  232. mapping.Dimensions.Length = logikal.Length;
  233. mapping.Cost = logikal.Cost;
  234. mapping.Quantity = logikal.Quantity;
  235. },
  236. x => x.Code
  237. );
  238. mappings.Wait();
  239. model.GasketMappings = mappings.Result;
  240. model.CheckChanged();
  241. }
  242. public IEnumerable<IAwgGasket>? Gaskets
  243. {
  244. get => GetValue(GasketsProperty) as IEnumerable<IAwgGasket>;
  245. set => SetValue(GasketsProperty, value);
  246. }
  247. private static readonly DependencyProperty ComponentsProperty = DependencyProperty.Register(
  248. nameof(Components),
  249. typeof(IEnumerable<IAwgComponent>),
  250. typeof(AWGMappingWindowViewModel),
  251. new FrameworkPropertyMetadata(ComponentsChanged)
  252. );
  253. private static void ComponentsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  254. {
  255. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgComponent> components)
  256. return;
  257. var mappings = model.ExtractMappings<ProductIntegrationSource, IAwgComponent, Product, ProductLink>(
  258. components,
  259. (logikal, mapping) =>
  260. {
  261. mapping.Dimensions.Unit.CopyFrom(model.Settings.ComponentUom);
  262. mapping.Dimensions.Quantity = logikal.PackSize;
  263. mapping.Quantity = logikal.Quantity;
  264. mapping.Cost = logikal.Cost;
  265. mapping.Group = logikal.Group;
  266. mapping.Supplier = logikal.Supplier;
  267. },
  268. x => x.Code
  269. );
  270. mappings.Wait();
  271. model.ComponentMappings = mappings.Result;
  272. model.CheckChanged();
  273. }
  274. public IEnumerable<IAwgComponent>? Components
  275. {
  276. get => GetValue(ComponentsProperty) as IEnumerable<IAwgComponent>;
  277. set => SetValue(ComponentsProperty, value);
  278. }
  279. private static readonly DependencyProperty GlassProperty = DependencyProperty.Register(
  280. nameof(Glass),
  281. typeof(IEnumerable<IAwgGlass>),
  282. typeof(AWGMappingWindowViewModel),
  283. new FrameworkPropertyMetadata(GlassChanged)
  284. );
  285. private static void GlassChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  286. {
  287. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgGlass> glass)
  288. return;
  289. var mappings = model.ExtractMappings<ProductIntegrationSource, IAwgGlass, Product, ProductLink>(
  290. glass,
  291. (logikal, mapping) =>
  292. {
  293. mapping.Group = logikal.Group;
  294. mapping.Supplier = logikal.Supplier;
  295. mapping.Dimensions.Unit.CopyFrom(model.Settings.GlassUom);
  296. mapping.Dimensions.Height = logikal.Height;
  297. mapping.Dimensions.Width = logikal.Width;
  298. mapping.Style = logikal.Treatment;
  299. mapping.Quantity = logikal.Quantity;
  300. mapping.Cost = logikal.Cost;
  301. },
  302. x => x.Code
  303. );
  304. mappings.Wait();
  305. model.GlassMappings = mappings.Result;
  306. model.CheckChanged();
  307. }
  308. public IEnumerable<IAwgGlass>? Glass
  309. {
  310. get => GetValue(GlassProperty) as IEnumerable<IAwgGlass>;
  311. set => SetValue(GlassProperty, value);
  312. }
  313. private static readonly DependencyProperty LabourProperty = DependencyProperty.Register(
  314. nameof(Labour),
  315. typeof(IEnumerable<IAwgLabour>),
  316. typeof(AWGMappingWindowViewModel),
  317. new FrameworkPropertyMetadata(LabourChanged)
  318. );
  319. private static void LabourChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  320. {
  321. if (d is not AWGMappingWindowViewModel model || e.NewValue is not IEnumerable<IAwgLabour> labour)
  322. return;
  323. var mappings = model.ExtractMappings<ActivityIntegrationSource, IAwgLabour, Activity, ActivityLink>(
  324. labour,
  325. (logikal, mapping) =>
  326. {
  327. mapping.Quantity = logikal.Quantity;
  328. },
  329. x => x.Code
  330. );
  331. mappings.Wait();
  332. model.LabourMappings = mappings.Result;
  333. model.CheckChanged();
  334. }
  335. public IEnumerable<IAwgLabour>? Labour
  336. {
  337. get => GetValue(LabourProperty) as IEnumerable<IAwgLabour>;
  338. set => SetValue(LabourProperty, value);
  339. }
  340. private static void SectionCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  341. {
  342. if (d is AWGMappingWindowViewModel model)
  343. model.CheckChanged();
  344. }
  345. private static readonly DependencyProperty StyleMappingsProperty = DependencyProperty.Register(
  346. nameof(StyleMappings),
  347. typeof(List<ProductStyleIntegrationSource>),
  348. typeof(AWGMappingWindowViewModel)
  349. );
  350. public List<ProductStyleIntegrationSource>? StyleMappings
  351. {
  352. get => GetValue(StyleMappingsProperty) as List<ProductStyleIntegrationSource>;
  353. set => SetValue(StyleMappingsProperty, value);
  354. }
  355. private static readonly DependencyProperty StylesCheckedProperty = DependencyProperty.Register(
  356. nameof(StylesChecked),
  357. typeof(bool),
  358. typeof(AWGMappingWindowViewModel),
  359. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback: SectionCheckedChanged)
  360. );
  361. public bool StylesChecked
  362. {
  363. get => (bool)GetValue(StylesCheckedProperty);
  364. set => SetValue(StylesCheckedProperty, value);
  365. }
  366. private static readonly DependencyProperty GroupMappingsProperty = DependencyProperty.Register(
  367. nameof(GroupMappings),
  368. typeof(List<ProductGroupIntegrationSource>),
  369. typeof(AWGMappingWindowViewModel)
  370. );
  371. public List<ProductGroupIntegrationSource>? GroupMappings
  372. {
  373. get => GetValue(GroupMappingsProperty) as List<ProductGroupIntegrationSource>;
  374. set => SetValue(GroupMappingsProperty, value);
  375. }
  376. private static readonly DependencyProperty GroupsCheckedProperty = DependencyProperty.Register(
  377. nameof(GroupsChecked),
  378. typeof(bool),
  379. typeof(AWGMappingWindowViewModel),
  380. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback: SectionCheckedChanged)
  381. );
  382. public bool GroupsChecked
  383. {
  384. get => (bool)GetValue(GroupsCheckedProperty);
  385. set => SetValue(GroupsCheckedProperty, value);
  386. }
  387. private static readonly DependencyProperty SupplierMappingsProperty = DependencyProperty.Register(
  388. nameof(SupplierMappings),
  389. typeof(List<SupplierIntegrationSource>),
  390. typeof(AWGMappingWindowViewModel)
  391. );
  392. public List<SupplierIntegrationSource>? SupplierMappings
  393. {
  394. get => GetValue(SupplierMappingsProperty) as List<SupplierIntegrationSource>;
  395. set => SetValue(SupplierMappingsProperty, value);
  396. }
  397. private static readonly DependencyProperty SuppliersCheckedProperty = DependencyProperty.Register(
  398. nameof(SuppliersChecked),
  399. typeof(bool),
  400. typeof(AWGMappingWindowViewModel),
  401. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback: SectionCheckedChanged)
  402. );
  403. public bool SuppliersChecked
  404. {
  405. get => (bool)GetValue(SuppliersCheckedProperty);
  406. set => SetValue(SuppliersCheckedProperty, value);
  407. }
  408. private static readonly DependencyProperty ProfileMappingsProperty = DependencyProperty.Register(
  409. nameof(ProfileMappings),
  410. typeof(List<ProductIntegrationSource>),
  411. typeof(AWGMappingWindowViewModel)
  412. );
  413. public List<ProductIntegrationSource>? ProfileMappings
  414. {
  415. get => GetValue(ProfileMappingsProperty) as List<ProductIntegrationSource>;
  416. set => SetValue(ProfileMappingsProperty, value);
  417. }
  418. private static readonly DependencyProperty ProfilesCheckedProperty = DependencyProperty.Register(
  419. nameof(ProfilesChecked),
  420. typeof(bool),
  421. typeof(AWGMappingWindowViewModel),
  422. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback: SectionCheckedChanged)
  423. );
  424. public bool ProfilesChecked
  425. {
  426. get => (bool)GetValue(ProfilesCheckedProperty);
  427. set => SetValue(ProfilesCheckedProperty, value);
  428. }
  429. private static readonly DependencyProperty GasketMappingsProperty = DependencyProperty.Register(
  430. nameof(GasketMappings),
  431. typeof(List<ProductIntegrationSource>),
  432. typeof(AWGMappingWindowViewModel)
  433. );
  434. public List<ProductIntegrationSource>? GasketMappings
  435. {
  436. get => GetValue(GasketMappingsProperty) as List<ProductIntegrationSource>;
  437. set => SetValue(GasketMappingsProperty, value);
  438. }
  439. private static readonly DependencyProperty GasketsCheckedProperty = DependencyProperty.Register(
  440. nameof(GasketsChecked),
  441. typeof(bool),
  442. typeof(AWGMappingWindowViewModel),
  443. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback: SectionCheckedChanged)
  444. );
  445. public bool GasketsChecked
  446. {
  447. get => (bool)GetValue(GasketsCheckedProperty);
  448. set => SetValue(GasketsCheckedProperty, value);
  449. }
  450. private static readonly DependencyProperty ComponentMappingsProperty = DependencyProperty.Register(
  451. nameof(ComponentMappings),
  452. typeof(List<ProductIntegrationSource>),
  453. typeof(AWGMappingWindowViewModel)
  454. );
  455. public List<ProductIntegrationSource>? ComponentMappings
  456. {
  457. get => GetValue(ComponentMappingsProperty) as List<ProductIntegrationSource>;
  458. set => SetValue(ComponentMappingsProperty, value);
  459. }
  460. private static readonly DependencyProperty ComponentsCheckedProperty = DependencyProperty.Register(
  461. nameof(ComponentsChecked),
  462. typeof(bool),
  463. typeof(AWGMappingWindowViewModel),
  464. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback: SectionCheckedChanged)
  465. );
  466. public bool ComponentsChecked
  467. {
  468. get => (bool)GetValue(ComponentsCheckedProperty);
  469. set => SetValue(ComponentsCheckedProperty, value);
  470. }
  471. private static readonly DependencyProperty GlassMappingsProperty = DependencyProperty.Register(
  472. nameof(GlassMappings),
  473. typeof(List<ProductIntegrationSource>),
  474. typeof(AWGMappingWindowViewModel)
  475. );
  476. public List<ProductIntegrationSource>? GlassMappings
  477. {
  478. get => GetValue(GlassMappingsProperty) as List<ProductIntegrationSource>;
  479. set => SetValue(GlassMappingsProperty, value);
  480. }
  481. private static readonly DependencyProperty GlassCheckedProperty = DependencyProperty.Register(
  482. nameof(GlassChecked),
  483. typeof(bool),
  484. typeof(AWGMappingWindowViewModel),
  485. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback: SectionCheckedChanged)
  486. );
  487. public bool GlassChecked
  488. {
  489. get => (bool)GetValue(GlassCheckedProperty);
  490. set => SetValue(GlassCheckedProperty, value);
  491. }
  492. private static readonly DependencyProperty LabourMappingsProperty = DependencyProperty.Register(
  493. nameof(LabourMappings),
  494. typeof(List<ActivityIntegrationSource>),
  495. typeof(AWGMappingWindowViewModel)
  496. );
  497. public List<ActivityIntegrationSource>? LabourMappings
  498. {
  499. get => GetValue(LabourMappingsProperty) as List<ActivityIntegrationSource>;
  500. set => SetValue(LabourMappingsProperty, value);
  501. }
  502. private static readonly DependencyProperty LabourCheckedProperty = DependencyProperty.Register(
  503. nameof(LabourChecked),
  504. typeof(bool),
  505. typeof(AWGMappingWindowViewModel),
  506. new FrameworkPropertyMetadata(defaultValue: true, propertyChangedCallback: SectionCheckedChanged)
  507. );
  508. public bool LabourChecked
  509. {
  510. get => (bool)GetValue(LabourCheckedProperty);
  511. set => SetValue(LabourCheckedProperty, value);
  512. }
  513. private static readonly DependencyProperty SectionsProperty = DependencyProperty.Register(
  514. nameof(Sections),
  515. typeof(CoreObservableCollection<KeyValuePair<string, BitmapImage>>),
  516. typeof(AWGMappingWindowViewModel),
  517. new PropertyMetadata(new CoreObservableCollection<KeyValuePair<string, BitmapImage>>())
  518. );
  519. public CoreObservableCollection<KeyValuePair<string, BitmapImage>> Sections
  520. {
  521. get => (CoreObservableCollection<KeyValuePair<string, BitmapImage>>)GetValue(SectionsProperty);
  522. set => SetValue(SectionsProperty, value);
  523. }
  524. private static readonly DependencyProperty SelectedSectionProperty = DependencyProperty.Register(
  525. nameof(SelectedSection),
  526. typeof(KeyValuePair<string, BitmapImage>?),
  527. typeof(AWGMappingWindowViewModel)
  528. );
  529. public KeyValuePair<string, BitmapImage>? SelectedSection
  530. {
  531. get => (KeyValuePair<string, BitmapImage>?)GetValue(SelectedSectionProperty);
  532. set => SetValue(SelectedSectionProperty, value);
  533. }
  534. private static readonly DependencyProperty MappingsCompleteProperty = DependencyProperty.Register(
  535. nameof(MappingsComplete),
  536. typeof(bool),
  537. typeof(AWGMappingWindowViewModel)
  538. );
  539. public bool MappingsComplete
  540. {
  541. get => (bool)GetValue(MappingsCompleteProperty);
  542. set => SetValue(MappingsCompleteProperty, value);
  543. }
  544. private Task<List<TCode>> ExtractMappings<TCode, TType, TEntity, TLink>(
  545. IEnumerable<TType>? items,
  546. Action<TType, TCode>? populate,
  547. Expression<Func<TEntity, object?>> entitycode
  548. )
  549. where TType : IAwgItem
  550. where TCode : BaseIntegrationSource<TEntity, TLink>, IRemotable, IPersistent, new()
  551. where TEntity : Entity, IRemotable, IPersistent, new()
  552. where TLink : EntityLink<TEntity>
  553. {
  554. return Task.Run(() =>
  555. {
  556. var results = new List<TCode>();
  557. if (items == null)
  558. return results;
  559. //var sourceitems = new Dictionary<string, string>();
  560. //foreach (var item in items)
  561. // sourceitems[item.Code] = item.Description;
  562. var keys = items.Select(x => x.Code).Distinct().ToArray();
  563. MultiQuery query = new();
  564. query.Add(
  565. new Filter<TEntity>(entitycode).InList(keys),
  566. Columns.Required<TEntity>().Add(x => x.ID).Add(entitycode)
  567. );
  568. var entitycodecol = $"Entity.{CoreUtils.GetFullPropertyName(entitycode, ".")}";
  569. query.Add(
  570. new Filter<TCode>(x => x.Code).InList(keys),
  571. Columns.Required<TCode>()
  572. .Add(x => x.ID)
  573. .Add(x => x.Code)
  574. .Add(x => x.Entity.ID)
  575. .Add(entitycodecol)
  576. );
  577. query.Query();
  578. var mappings = query.Get<TCode>().ToObjects<TCode>().ToArray();
  579. var entities = query.Get<TEntity>();
  580. foreach (var item in items)
  581. {
  582. var result = new TCode()
  583. {
  584. Code = item.Code,
  585. Description = item.Description
  586. };
  587. populate?.Invoke(item, result);
  588. var mapping = mappings.FirstOrDefault(x => string.Equals(x.Code, item.Code));
  589. if (mapping != null)
  590. result.Entity.CopyFrom(mapping.Entity);
  591. else
  592. {
  593. var entity = entities.Rows.FirstOrDefault(r => Equals(item.Code, r.Get(entitycode)));
  594. if (entity != null)
  595. {
  596. result.Entity.CopyFrom(entity.ToObject<TEntity>());
  597. result.DirectMatch = true;
  598. }
  599. }
  600. results.Add(result);
  601. // result.PropertyChanged += (_, _) =>
  602. // {
  603. // // TMapping mapping = mappingtable.Rows.FirstOrDefault(r =>
  604. // // string.Equals(r.Get<TMapping, String>(c => c.Code), result.Code))?.ToObject<TMapping>();
  605. // // if (mapping == null)
  606. // // mapping = new TMapping() { Code = result.Code };
  607. // // mapping.Entity.ID = result.Entity.ID;
  608. // // new Client<TMapping>().Save(mapping, "Created from BOM Integration Window");
  609. //
  610. // CheckChanged();
  611. // };
  612. }
  613. return results;
  614. });
  615. }
  616. public void CheckChanged()
  617. {
  618. Dispatcher.BeginInvoke(() =>
  619. {
  620. var curSel = SelectedSection?.Key ?? "";
  621. SelectedSection = null;
  622. Sections.Clear();
  623. if (StylesChecked && StyleMappings?.Any() == true)
  624. Sections.Add(new KeyValuePair<string, BitmapImage>("Styles", Resources.palette.AsBitmapImage(64, 64)));
  625. if (GroupsChecked && GroupMappings?.Any() == true)
  626. Sections.Add(
  627. new KeyValuePair<string, BitmapImage>("Groups", Resources.productgroup.AsBitmapImage(64, 64)));
  628. if (SuppliersChecked && SupplierMappings?.Any() == true)
  629. Sections.Add(
  630. new KeyValuePair<string, BitmapImage>("Suppliers", Resources.supplier.AsBitmapImage(64, 64)));
  631. if (ProfilesChecked && ProfileMappings?.Any() == true)
  632. Sections.Add(
  633. new KeyValuePair<string, BitmapImage>("Profiles", Resources.profile.AsBitmapImage(64, 64)));
  634. if (GasketsChecked && GasketMappings?.Any() == true)
  635. Sections.Add(new KeyValuePair<string, BitmapImage>("Gaskets", Resources.gasket.AsBitmapImage(64, 64)));
  636. if (ComponentsChecked && ComponentMappings?.Any() == true)
  637. Sections.Add(
  638. new KeyValuePair<string, BitmapImage>("Components", Resources.fixings.AsBitmapImage(64, 64)));
  639. if (GlassChecked && GlassMappings?.Any() == true)
  640. Sections.Add(new KeyValuePair<string, BitmapImage>("Glass", Resources.glass.AsBitmapImage(64, 64)));
  641. if (LabourChecked && LabourMappings?.Any() == true)
  642. Sections.Add(new KeyValuePair<string, BitmapImage>("Labour", Resources.quality.AsBitmapImage(64, 64)));
  643. SelectedSection = Sections.Any(x => string.Equals(x.Key, curSel))
  644. ? Sections.First(x => string.Equals(x.Key, curSel))
  645. : Sections.FirstOrDefault();
  646. var styles = !StylesChecked || (StyleMappings?.Any() != true) || (StyleMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  647. var groups = !GroupsChecked || (GroupMappings?.Any() != true) || (GroupMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  648. var suppliers = !SuppliersChecked || (SupplierMappings?.Any() != true) || (SupplierMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  649. var profiles = !ProfilesChecked || (ProfileMappings?.Any() != true) || (ProfileMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  650. var gaskets = !GasketsChecked || (GasketMappings?.Any() != true) || (GasketMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  651. var components = !ComponentsChecked || (ComponentMappings?.Any() != true) || (ComponentMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  652. var glass = !GlassChecked || (GlassMappings?.Any() != true) || (GlassMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  653. var labour = !LabourChecked || (LabourMappings?.Any() != true) || (LabourMappings?.All(x => x.Entity.ID != Guid.Empty) ?? false);
  654. MappingsComplete = styles && groups && suppliers && profiles && gaskets && components && glass && labour;
  655. });
  656. }
  657. public ICommand CreateStyle => new ActionCommand(
  658. o =>
  659. {
  660. if (o is IntegrationGridCreateEntityArgs<ProductStyle, ProductStyleIntegrationSource> args)
  661. {
  662. args.Entity.Code = args.Mapping.Code ?? "";
  663. args.Entity.Description = args.Mapping.Description ?? "";
  664. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  665. TreatmentTypeLink? type = args.Mapping.StyleType == AwgStyleType.Powdercoated
  666. ? _settings.PowdercoatedType
  667. : args.Mapping.StyleType == AwgStyleType.Anodised
  668. ? _settings.AnodisedType
  669. : args.Mapping.StyleType == AwgStyleType.Varnished
  670. ? _settings.VarnishedType
  671. : args.Mapping.StyleType == AwgStyleType.Taped
  672. ? _settings.TapedType
  673. : null;
  674. if (type != null)
  675. {
  676. args.Entity.TreatmentType.CopyFrom(type);
  677. var product = new Client<Product>().Query(
  678. new Filter<Product>(x => x.Code).IsEqualTo(args.Entity.Code),
  679. Columns.Local<Product>()
  680. ).ToArray<Product>().FirstOrDefault();
  681. if (product == null)
  682. {
  683. product = new Product();
  684. product.Code = args.Entity.Code;
  685. product.Name = args.Entity.Description;
  686. product.Problem.Notes = ["Created from BOM Integration Window"];
  687. product.TreatmentType.CopyFrom(type);
  688. Client.Save(product, "Created from AWG Mapping Window");
  689. }
  690. args.Entity.StockTreatmentProduct.CopyFrom(product);
  691. args.Entity.ManufacturingTreatmentProduct.CopyFrom(product);
  692. }
  693. }
  694. }
  695. );
  696. public ICommand CreateGroup => new ActionCommand(
  697. o =>
  698. {
  699. if (o is IntegrationGridCreateEntityArgs<ProductGroup, ProductGroupIntegrationSource> args)
  700. {
  701. Guid parentid = Guid.Empty;
  702. var parentcodes = args.Mapping.Parent.Split('/').Select(x => x.Trim().ToUpper()).ToArray();
  703. var parents = Client.Query(
  704. new Filter<ProductGroup>(x => x.Code).InList(parentcodes),
  705. Columns.None<ProductGroup>().Add(x => x.ID).Add(x => x.Code)
  706. ).ToArray<ProductGroup>();
  707. foreach (var parentcode in parentcodes)
  708. {
  709. var parent = parents.FirstOrDefault(x => Equals(x.Code,parentcode));
  710. if (parent == null)
  711. {
  712. parent = new ProductGroup();
  713. parent.Code = parentcode;
  714. parent.Description = parentcode.Titleize();
  715. parent.Parent.ID = parentid;
  716. parent.Problem.Notes = ["Created from BOM Integration Window"];
  717. Client.Save(parent, "Created from AWG Mapping Window");
  718. }
  719. parentid = parent.ID;
  720. }
  721. args.Entity.Parent.ID = parentid;
  722. args.Entity.Code = args.Mapping.Code ?? "";
  723. args.Entity.Description = args.Mapping.Description ?? "";
  724. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  725. }
  726. }
  727. );
  728. public ICommand CreateSupplier => new ActionCommand(
  729. o =>
  730. {
  731. if (o is IntegrationGridCreateEntityArgs<Supplier, SupplierIntegrationSource> args)
  732. {
  733. args.Entity.Code = args.Mapping.Code ?? "";
  734. args.Entity.Name = args.Mapping.Description ?? "";
  735. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  736. }
  737. }
  738. );
  739. public ICommand CreateProfile => new ActionCommand(
  740. o =>
  741. {
  742. if (o is IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  743. {
  744. args.Entity.Code = args.Mapping.Code ?? "";
  745. args.Entity.Name = args.Mapping.Description ?? "";
  746. args.Entity.UnitOfMeasure.CopyFrom(_settings.ProfileUom);
  747. var group = GroupMappings?.FirstOrDefault(x => Equals(x.Code, args.Mapping.Group));
  748. if (group != null)
  749. args.Entity.Group.CopyFrom(group.Entity);
  750. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  751. CreateImage(args);
  752. }
  753. }
  754. );
  755. public ICommand AfterCreateProduct => new ActionCommand(
  756. o =>
  757. {
  758. if (o is IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  759. {
  760. CreateTreatmentParams(args, AwgStyleType.Powdercoated, Settings.PowdercoatedType);
  761. CreateTreatmentParams(args, AwgStyleType.Anodised, Settings.AnodisedType);
  762. CreateTreatmentParams(args, AwgStyleType.Taped, Settings.TapedType);
  763. CreateTreatmentParams(args, AwgStyleType.Varnished, Settings.VarnishedType);
  764. CreateSupplierProduct(args);
  765. }
  766. }
  767. );
  768. private void CreateImage(IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  769. {
  770. if (!string.IsNullOrWhiteSpace(_settings.ImageUrl))
  771. {
  772. var model = new LogikalCodeModel() { Code = args.Mapping.Code };
  773. var _expression = new CoreExpression<LogikalCodeModel, string>(_settings.ImageUrl);
  774. if (_expression.Evaluate(model).Get(out var eval, out var e))
  775. {
  776. var tcs = new TaskCompletionSource<byte[]>();
  777. new HttpClient().GetByteArrayAsync(eval)
  778. .ContinueWith(
  779. t =>
  780. {
  781. if (t.IsFaulted)
  782. tcs.SetException(t.Exception);
  783. else
  784. tcs.SetResult(t.Result);
  785. });
  786. try
  787. {
  788. var data = tcs.Task.Result;
  789. var document = new Document()
  790. {
  791. Data = tcs.Task.Result,
  792. CRC = CoreUtils.CalculateCRC(data),
  793. FileName = args.Mapping.Code
  794. };
  795. Client.Save(document,"Created from AWG Mapping Window");
  796. args.Entity.Image.ID = document.ID;
  797. }
  798. catch (Exception exception)
  799. {
  800. Logger.Send(LogType.Error,"",$"Exception in CreateImage(): {exception.Message}");
  801. }
  802. }
  803. }
  804. }
  805. private void CreateTreatmentParams(IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args, AwgStyleType type, TreatmentTypeLink link)
  806. {
  807. if (args.Mapping.TreatmentParameters.ContainsKey(type) && !Equals(link.ID,Guid.Empty))
  808. {
  809. ProductTreatment treatment = new();
  810. treatment.Product.CopyFrom(args.Entity);
  811. treatment.TreatmentType.CopyFrom(link);
  812. treatment.Parameter = args.Mapping.TreatmentParameters[type];
  813. Client.Save(treatment,"Created from AWG Mapping Window");
  814. }
  815. }
  816. private void CreateSupplierProduct(IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  817. {
  818. var supplier = SupplierMappings?.FirstOrDefault(x => Equals(x.Code, args.Mapping.Supplier));
  819. if (supplier != null)
  820. {
  821. SupplierProduct sp = new SupplierProduct();
  822. sp.Product.ID = args.Entity.ID;
  823. sp.SupplierLink.ID = supplier.Entity.ID;
  824. sp.SupplierCode = args.Mapping.Code;
  825. sp.SupplierDescription = args.Mapping.Description;
  826. sp.Dimensions.CopyFrom(args.Mapping.Dimensions);
  827. var style = StyleMappings?.FirstOrDefault(x => Equals(x.Code, args.Mapping.Style));
  828. if (style != null)
  829. sp.Style.CopyFrom(style.Entity);
  830. sp.TradePrice = args.Mapping.Cost; // * (args.Mapping.Quantity.IsEffectivelyEqual(0.0) ? 1.0 : args.Mapping.Dimensions.Quantity);
  831. Client.Save(sp,"Created from AWG Mapping Window");
  832. }
  833. }
  834. public ICommand CreateGasket => new ActionCommand(
  835. o =>
  836. {
  837. if (o is IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  838. {
  839. args.Entity.Code = args.Mapping.Code ?? "";
  840. args.Entity.Name = args.Mapping.Description ?? "";
  841. args.Entity.UnitOfMeasure.CopyFrom(_settings.GasketUom);
  842. var group = GroupMappings?.FirstOrDefault(x => Equals(x.Code, args.Mapping.Group));
  843. if (group != null)
  844. args.Entity.Group.CopyFrom(group.Entity);
  845. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  846. }
  847. }
  848. );
  849. public ICommand CreateComponent => new ActionCommand(
  850. o =>
  851. {
  852. if (o is IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  853. {
  854. args.Entity.Code = args.Mapping.Code ?? "";
  855. args.Entity.Name = args.Mapping.Description ?? "";
  856. args.Entity.UnitOfMeasure.CopyFrom(_settings.ComponentUom);
  857. var group = GroupMappings?.FirstOrDefault(x => Equals(x.Code, args.Mapping.Group));
  858. if (group != null)
  859. args.Entity.Group.CopyFrom(group.Entity);
  860. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  861. }
  862. }
  863. );
  864. public ICommand CreateGlass => new ActionCommand(
  865. o =>
  866. {
  867. if (o is IntegrationGridCreateEntityArgs<Product, ProductIntegrationSource> args)
  868. {
  869. args.Entity.Code = args.Mapping.Code ?? "";
  870. args.Entity.Name = args.Mapping.Description ?? "";
  871. args.Entity.UnitOfMeasure.CopyFrom(_settings.GlassUom);
  872. var group = GroupMappings?.FirstOrDefault(x => Equals(x.Code, args.Mapping.Group));
  873. if (group != null)
  874. args.Entity.Group.CopyFrom(group.Entity);
  875. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  876. }
  877. }
  878. );
  879. public ICommand CreateActivity => new ActionCommand(
  880. o =>
  881. {
  882. if (o is IntegrationGridCreateEntityArgs<Activity, ActivityIntegrationSource> args)
  883. {
  884. args.Entity.Code = args.Mapping.Code ?? "";
  885. args.Entity.Description = args.Mapping.Description ?? "";
  886. args.Entity.Problem.Notes = ["Created from BOM Integration Window"];
  887. }
  888. }
  889. );
  890. private class RawDimensions : IBaseDimensions
  891. {
  892. public double Quantity { get; set; }
  893. public double Length { get; set; }
  894. public double Width { get; set; }
  895. public double Height { get; set; }
  896. public double Weight { get; set; }
  897. }
  898. public void GetParts(
  899. Action<ProductLink, ProductStyleLink?, IBaseDimensions, double, double>? productCallback,
  900. Action<ActivityLink, TimeSpan, double>? labourCallback)
  901. {
  902. GetParts(Profiles,Gaskets,Components,Glass,Labour,productCallback,labourCallback);
  903. }
  904. public void GetParts<TProfile, TGasket, TComponent, TGlass, TLabour>(
  905. IEnumerable<TProfile>? profiles,
  906. IEnumerable<TGasket>? gaskets,
  907. IEnumerable<TComponent>? components,
  908. IEnumerable<TGlass>? glasses,
  909. IEnumerable<TLabour>? labour,
  910. Action<ProductLink, ProductStyleLink?, IBaseDimensions, double, double>? productCallback,
  911. Action<ActivityLink, TimeSpan, double>? labourCallback)
  912. where TProfile : IAwgProfile
  913. where TGasket : IAwgGasket
  914. where TComponent : IAwgComponent
  915. where TGlass : IAwgGlass
  916. where TLabour : IAwgLabour
  917. {
  918. if (ProfilesChecked && profiles != null)
  919. {
  920. foreach (var profile in profiles)
  921. {
  922. var profilemapping = ProfileMappings?.FirstOrDefault(x => x.Code == profile.Code);
  923. var stylemapping = StyleMappings?.FirstOrDefault(x => string.Equals(x.Code, profile.Finish));
  924. if (profilemapping != null && productCallback is not null)
  925. {
  926. productCallback(
  927. profilemapping.Entity,
  928. stylemapping?.Entity,
  929. new RawDimensions() { Length = profile.Length },
  930. profile.Quantity,
  931. profile.Cost * profile.Quantity);
  932. }
  933. }
  934. }
  935. if (GasketsChecked && gaskets != null)
  936. {
  937. foreach (var gasket in gaskets)
  938. {
  939. var gasketmapping = GasketMappings?.FirstOrDefault(x => x.Code == gasket.Code);
  940. if (gasketmapping != null && productCallback is not null)
  941. {
  942. var totalcost = gasket.Quantity * gasket.Cost;
  943. var length = PRSDimensionUtils.DimensionUtils.ConvertDimensions(
  944. gasketmapping.Dimensions,
  945. gasketmapping.Quantity,
  946. (f,c) => Client.Query(f,c)
  947. );
  948. productCallback(
  949. gasketmapping.Entity,
  950. null,
  951. new RawDimensions() { Length = gasketmapping.Dimensions.Length },
  952. length,
  953. totalcost);
  954. }
  955. }
  956. }
  957. if (ComponentsChecked && components != null)
  958. {
  959. foreach (var component in components)
  960. {
  961. var componentmapping = ComponentMappings?.FirstOrDefault(x => string.Equals(x.Code, component.Code));
  962. if (componentmapping != null && productCallback is not null)
  963. {
  964. var totalcost = component.Cost * componentmapping.Quantity;
  965. var qty = PRSDimensionUtils.DimensionUtils.ConvertDimensions(
  966. componentmapping.Dimensions,
  967. componentmapping.Quantity,
  968. (f,c) => Client.Query(f,c)
  969. );
  970. productCallback(
  971. componentmapping.Entity,
  972. null,
  973. new RawDimensions() { Quantity = componentmapping.Dimensions.Quantity },
  974. qty,
  975. totalcost);
  976. }
  977. }
  978. }
  979. if (GlassChecked && glasses != null)
  980. {
  981. foreach (var glass in glasses)
  982. {
  983. var glassmapping = GlassMappings?.FirstOrDefault(x => string.Equals(x.Code, glass.Code));
  984. if (glassmapping != null && productCallback is not null)
  985. {
  986. productCallback(
  987. glassmapping.Entity,
  988. null,
  989. new RawDimensions() { Height = glass.Height, Width = glass.Width },
  990. glass.Quantity,
  991. glass.Quantity * glass.Cost);
  992. }
  993. }
  994. }
  995. if (LabourChecked && labour != null)
  996. {
  997. foreach (var activity in labour)
  998. {
  999. var activitymapping = LabourMappings?.FirstOrDefault(x => string.Equals(x.Code, activity.Code));
  1000. if (activitymapping != null && labourCallback is not null)
  1001. {
  1002. labourCallback(
  1003. activitymapping.Entity,
  1004. TimeSpan.FromHours(activity.Quantity),
  1005. activity.Quantity * activity.Cost);
  1006. }
  1007. }
  1008. }
  1009. }
  1010. }