RecTrans.xaml.cs 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. using comal.timesheets.CustomControls;
  2. using Comal.Classes;
  3. using InABox.Clients;
  4. using InABox.Core;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. using Xamarin.CommunityToolkit.UI.Views;
  11. using Xamarin.Essentials;
  12. using Xamarin.Forms;
  13. using Xamarin.Forms.Xaml;
  14. using XF.Material.Forms.UI.Dialogs;
  15. namespace comal.timesheets
  16. {
  17. [XamlCompilation(XamlCompilationOptions.Compile)]
  18. public partial class RecTrans : BasePage
  19. {
  20. #region Fields + Constructor + Loading
  21. List<StockHoldingShell> issuingHoldings = new List<StockHoldingShell>();
  22. List<StockHoldingShell> receivingHoldings = new List<StockHoldingShell>();
  23. List<StockHoldingShell> originalHoldings = new List<StockHoldingShell>();
  24. StockLocation ReceivingStockLocation = new StockLocation();
  25. StockLocation IssuingStockLocation = new StockLocation();
  26. ProductStyle DefaultStyle = new ProductStyle();
  27. ProductStyle PreviousStyle = new ProductStyle();
  28. Filter<StockHolding> issuingFilter = new Filter<StockHolding>();
  29. Job ReceivingJob = new Job();
  30. bool bTapping = false;
  31. double frameHeight = 80;
  32. List<StockLocation> favourites = new List<StockLocation>();
  33. StockMovementBatchType BatchType = new StockMovementBatchType();
  34. string DeviceType = "";
  35. public RecTrans(StockMovementBatchType batchType, string issuingGuidString = "")
  36. {
  37. InitializeComponent();
  38. Title = BatchType == StockMovementBatchType.Issue
  39. ? "Issue Stock"
  40. : "Transfer Stock";
  41. BatchType = batchType;
  42. var idiom = DeviceInfo.Idiom;
  43. if (idiom.Equals(DeviceIdiom.Tablet))
  44. {
  45. DeviceType = "Tablet";
  46. }
  47. //DisplayAlert("Instructions", "1. Select Issuing Location or use default (incoming stores)." + System.Environment.NewLine
  48. // + System.Environment.NewLine
  49. // + "2. Select Receiving Location or Job to Issue to." + System.Environment.NewLine
  50. // + System.Environment.NewLine
  51. // + "3. Tap items to transfer." + System.Environment.NewLine
  52. // + System.Environment.NewLine
  53. // + "4. Save with photos + notes." + System.Environment.NewLine
  54. // + System.Environment.NewLine
  55. // + "Note: Exiting loses unsaved work", "OK");
  56. IssuingStockLocation.PropertyChanged += IssuingStockLocation_PropertyChanged;
  57. ReceivingStockLocation.PropertyChanged += ReceivingStockLocation_PropertyChanged;
  58. LoadFavourites();
  59. ShowHideButtonsBasedOnType();
  60. LoadFromProductSearch(issuingGuidString);
  61. }
  62. private void LoadFromProductSearch(string issuingGuidString)
  63. {
  64. if (!string.IsNullOrWhiteSpace(issuingGuidString))
  65. {
  66. try
  67. {
  68. Guid issuingLocationID = Guid.Parse(issuingGuidString);
  69. CoreTable table = new Client<StockLocation>().Query(new Filter<StockLocation>(x => x.ID).IsEqualTo(issuingLocationID),
  70. new Columns<StockLocation>(x => x.ID, x => x.Code, x => x.Description)
  71. );
  72. if (table.Rows.Any())
  73. {
  74. List<object> list = table.Rows.First().Values;
  75. IssuingStockLocation.ID = Guid.Parse(list[0].ToString());
  76. IssuingStockLocation.Code = list[1].ToString();
  77. IssuingStockLocation.Description = list[2].ToString();
  78. }
  79. Filter<StockHolding> filter = new Filter<StockHolding>(x => x.Location.ID).IsEqualTo(issuingLocationID);
  80. LoadIncomingListData(filter);
  81. }
  82. catch { }
  83. }
  84. }
  85. private void ShowHideButtonsBasedOnType()
  86. {
  87. if (BatchType == StockMovementBatchType.Issue)
  88. {
  89. receivingFavouriteBtn1.IsEnabled = false;
  90. receivingFavouriteBtn2.IsEnabled = false;
  91. receivingFavouriteBtn3.IsEnabled = false;
  92. chooseReceivingLocationBtn.IsVisible = false;
  93. receivingLocationLbl.Text = "Choose Job";
  94. //titleLbl.Text = "Issue to Job";
  95. }
  96. else if (BatchType == StockMovementBatchType.Transfer)
  97. {
  98. chooseJobBtn.IsVisible = false;
  99. }
  100. }
  101. #endregion
  102. #region Issuing Button Presses
  103. private async void ChooseIssuingLocationBtn_Clicked(object sender, EventArgs e)
  104. {
  105. CollapseExpanderOnButtonPress();
  106. if (receivingHoldings.Count > 0)
  107. {
  108. PromptResetScreen();
  109. }
  110. else
  111. {
  112. ChooseIssuingLocation();
  113. }
  114. }
  115. private void IssuingFavourite_Clicked(object sender, EventArgs e)
  116. {
  117. string chosenFavourite = (sender as Button).Text;
  118. CollapseExpanderOnButtonPress();
  119. if (receivingHoldings.Count > 0)
  120. {
  121. PromptResetScreen(chosenFavourite);
  122. }
  123. else
  124. {
  125. IssuingFavouriteChosen(chosenFavourite);
  126. }
  127. }
  128. #endregion
  129. #region Issuing Location Methods
  130. private void ChooseIssuingLocation()
  131. {
  132. StockLocationSelectionPage page = new StockLocationSelectionPage();
  133. page.OnLocationSelected += (s) =>
  134. {
  135. if (ReceivingStockLocation.ID == s.ID)
  136. return;
  137. IssuingStockLocation.ID = s.ID;
  138. IssuingStockLocation.Code = s.Code;
  139. IssuingStockLocation.Description = s.Description;
  140. Filter<StockHolding> newIssuingFilter = new Filter<StockHolding>(x => x.Location.ID).IsEqualTo(IssuingStockLocation.ID);
  141. issuingHoldings.Clear();
  142. receivingHoldings.Clear();
  143. LoadIncomingListData(newIssuingFilter);
  144. Device.BeginInvokeOnMainThread(() =>
  145. {
  146. });
  147. };
  148. Navigation.PushAsync(page);
  149. }
  150. private async void IssuingFavouriteChosen(string chosenFavourite)
  151. {
  152. ClearLists();
  153. StockLocation location = favourites.Find(x => x.Code.Equals(chosenFavourite));
  154. IssuingStockLocation.ID = location.ID;
  155. IssuingStockLocation.Code = location.Code;
  156. IssuingStockLocation.Description = location.Description;
  157. Filter<StockHolding> filter = new Filter<StockHolding>(x => x.Location.ID).IsEqualTo(IssuingStockLocation.ID);
  158. LoadIncomingListData(filter);
  159. }
  160. #endregion
  161. #region Receiving Button Presses
  162. private async void ChooseReceivingLocationBtn_Clicked(object sender, EventArgs e)
  163. {
  164. string chosenOption = await DisplayActionSheet("Choose an Option", "Cancel", null, "New Location", "Existing Location");
  165. switch (chosenOption)
  166. {
  167. case "Cancel":
  168. return;
  169. break;
  170. case "New Location":
  171. ChooseNewLocation();
  172. CollapseExpanderOnButtonPress();
  173. break;
  174. case "Existing Location":
  175. ChooseReceivingLocation();
  176. CollapseExpanderOnButtonPress();
  177. break;
  178. default:
  179. return;
  180. break;
  181. }
  182. }
  183. private void JobBtn_Clicked(object sender, EventArgs e)
  184. {
  185. ChooseJob();
  186. CollapseExpanderOnButtonPress();
  187. }
  188. private void ReceivingFavourite_Clicked(object sender, EventArgs e)
  189. {
  190. CollapseExpanderOnButtonPress();
  191. string chosenFavourite = (sender as Button).Text;
  192. ReceivingFavouriteChosen(chosenFavourite);
  193. }
  194. #endregion
  195. #region Receiving Location Methods
  196. private void ReceivingFavouriteChosen(string chosenFavourite)
  197. {
  198. StockLocation location = favourites.Find(x => x.Code.Equals(chosenFavourite));
  199. ReceivingStockLocation.ID = location.ID;
  200. ReceivingStockLocation.Code = location.Code;
  201. ReceivingStockLocation.Description = location.Description;
  202. receivingLocationLbl.Text = ReceivingStockLocation.Description;
  203. }
  204. private void ChooseReceivingLocation()
  205. {
  206. StockLocationSelectionPage page = new StockLocationSelectionPage();
  207. page.OnLocationSelected += (s) =>
  208. {
  209. if (s.ID == IssuingStockLocation.ID)
  210. return;
  211. ReceivingStockLocation.ID = s.ID;
  212. ReceivingStockLocation.Code = s.Code;
  213. ReceivingStockLocation.Description = s.Description;
  214. ReceivingJob = new Job();
  215. LoadDefaultStyle();
  216. Device.BeginInvokeOnMainThread(() =>
  217. {
  218. //titleLbl.Text = "Transfer Stock";
  219. receivingLocationLbl.Text = ReceivingStockLocation.Description;
  220. });
  221. };
  222. Navigation.PushAsync(page);
  223. }
  224. private void ChooseNewLocation()
  225. {
  226. try
  227. {
  228. StockLocation location = new StockLocation();
  229. location.Active = true;
  230. location.Warehouse.ID = Guid.Parse("b6249c4a-a834-4927-a42c-87a07895d6bd"); //EXTRUSIONS
  231. location.Warehouse.Description = "Extrusions";
  232. location.Warehouse.Code = "EXTRUSIONS";
  233. location.Area.Warehouse.ID = Guid.Parse("b6249c4a-a834-4927-a42c-87a07895d6bd"); //EXTRUSIONS
  234. location.Area.Warehouse.Description = "Extrusions";
  235. location.Area.ID = Guid.Parse("fa02ecd8-e642-49aa-98b5-c04d7ea0f4eb"); //Rack FLOOR
  236. location.Area.Description = "Rack FLOOR";
  237. location.Area.Code = "FLOOR";
  238. LocationDetailsPage locationDetailsPage = new LocationDetailsPage(location);
  239. locationDetailsPage.OnSave += (o, loc) =>
  240. {
  241. if (String.IsNullOrWhiteSpace(loc.Code))
  242. {
  243. MaterialDialog.Instance.AlertAsync(message: "Code may not be blank!");
  244. return false;
  245. }
  246. if (String.IsNullOrWhiteSpace(loc.Description))
  247. {
  248. MaterialDialog.Instance.AlertAsync(message: "Description may not be blank!");
  249. return false;
  250. }
  251. if (loc.Area.ID == Guid.Empty)
  252. {
  253. MaterialDialog.Instance.AlertAsync(message: "Area may not be blank!");
  254. return false;
  255. }
  256. CoreTable others = new Client<StockLocation>().Query(
  257. new Filter<StockLocation>(x => x.Code).IsEqualTo(loc.Code).And(x => x.ID).IsNotEqualTo(loc.ID),
  258. new Columns<StockLocation>(x => x.ID)
  259. );
  260. if (others.Rows.Any())
  261. {
  262. MaterialDialog.Instance.AlertAsync(message: "Location Code already exists!");
  263. return false;
  264. }
  265. try
  266. {
  267. new Client<StockLocation>().Save(loc, "Created Location");
  268. ReceivingStockLocation.ID = loc.ID;
  269. ReceivingStockLocation.Code = loc.Code;
  270. ReceivingStockLocation.Description = loc.Description;
  271. LoadDefaultStyle();
  272. Device.BeginInvokeOnMainThread(() =>
  273. {
  274. //titleLbl.Text = "Transfer Stock";
  275. receivingLocationLbl.Text = ReceivingStockLocation.Description;
  276. });
  277. }
  278. catch (Exception err)
  279. {
  280. MaterialDialog.Instance.AlertAsync(message: "Unable to save Location\n" + err.Message);
  281. return false;
  282. }
  283. return true;
  284. };
  285. Navigation.PushAsync(locationDetailsPage);
  286. }
  287. catch { }
  288. }
  289. private void ChooseJob()
  290. {
  291. var jobSelectionPage = new JobSelectionPage(
  292. (job) =>
  293. {
  294. ReceivingStockLocation = new StockLocation();
  295. ReceivingJob.ID = job.ID;
  296. ReceivingJob.Name = job.Name;
  297. ReceivingJob.JobNumber = job.JobNumber;
  298. Device.BeginInvokeOnMainThread(() =>
  299. {
  300. //titleLbl.Text = "Issue to Job";
  301. receivingLocationLbl.Text = ReceivingJob.JobNumber;
  302. });
  303. });
  304. Navigation.PushAsync(jobSelectionPage);
  305. }
  306. #endregion
  307. #region Lists Tapped
  308. private void IssuingListView_Tapped(object sender, EventArgs e)
  309. {
  310. if (ReceivingStockLocation.ID == Guid.Empty && ReceivingJob.ID == Guid.Empty)
  311. return;
  312. if (bTapping)
  313. return;
  314. bTapping = true;
  315. StockHoldingShell shell = issuingListView.SelectedItem as StockHoldingShell;
  316. StockHoldingShell originalShell = DuplicateShell(shell);
  317. Job job = new Job();
  318. if (ReceivingStockLocation.Job.ID != Guid.Empty)
  319. {
  320. job.ID = ReceivingStockLocation.Job.ID;
  321. job.JobNumber = ReceivingStockLocation.Job.JobNumber;
  322. job.Name = ReceivingStockLocation.Job.Name;
  323. }
  324. RecTransferPopup popup = new RecTransferPopup(shell, PreviousStyle, job, ReceivingJob);
  325. popup.OnRecTransferItemAccepted += (() =>
  326. {
  327. if (popup.Shell.Units == originalShell.Units)
  328. {
  329. issuingHoldings.Remove(shell);
  330. receivingHoldings.Add(popup.Shell);
  331. RefreshLists();
  332. }
  333. else if (originalShell.Units > popup.Shell.Units)
  334. {
  335. int index = issuingHoldings.FindIndex(x => x.ID.Equals(originalShell.ID));
  336. issuingHoldings.Remove(shell);
  337. originalShell.Units = originalShell.Units - popup.Shell.Units;
  338. originalShell.DisplayUnits = "Units: " + originalShell.Units;
  339. issuingHoldings.Insert(index, originalShell);
  340. //original shell is updated to remove qty taken away
  341. receivingHoldings.Add(popup.Shell);
  342. //popup shell with new properties is added to receiving list
  343. RefreshLists();
  344. }
  345. originalHoldings.Add(originalShell);
  346. PreviousStyle.ID = popup.Shell.StyleID;
  347. PreviousStyle.Code = popup.Shell.StyleCode;
  348. PreviousStyle.Description = popup.Shell.Finish;
  349. bTapping = false;
  350. });
  351. popup.OnRecTransferPopupBackButtonPressed += (() =>
  352. {
  353. int index = issuingHoldings.FindIndex(x => x.ID.Equals(originalShell.ID));
  354. issuingHoldings.Remove(shell);
  355. issuingHoldings.Insert(index, originalShell);
  356. bTapping = false;
  357. RefreshLists();
  358. });
  359. Navigation.PushAsync(popup);
  360. }
  361. private void ReceivingListView_Tapped(object sender, EventArgs e)
  362. {
  363. StockHoldingShell shell = receivingListView.SelectedItem as StockHoldingShell;
  364. RemoveHoldingFromBatch(shell);
  365. }
  366. private void RemoveHoldingFromBatch(StockHoldingShell shell)
  367. {
  368. receivingHoldings.Remove(shell);
  369. if (issuingHoldings.Find(x => x.ID.Equals(shell.ID)) != null)
  370. {
  371. StockHoldingShell existingHolding = issuingHoldings.Find(x => x.ID.Equals(shell.ID));
  372. int index = issuingHoldings.FindIndex(x => x.ID.Equals(existingHolding.ID));
  373. issuingHoldings.Remove(existingHolding);
  374. existingHolding.Units = existingHolding.Units + shell.Units;
  375. existingHolding.DisplayUnits = "Units: " + existingHolding.Units;
  376. issuingHoldings.Insert(index, existingHolding);
  377. }
  378. else
  379. {
  380. issuingHoldings.Add(shell);
  381. }
  382. RefreshLists();
  383. }
  384. #endregion
  385. #region Refresh Reset Screen
  386. private async void PromptResetScreen(string chosenFavourite = "")
  387. {
  388. string chosenOption = await DisplayActionSheet("This will remove items in current batch", "Cancel", null, "Confirm");
  389. switch (chosenOption)
  390. {
  391. case "Confirm":
  392. ClearLists();
  393. if (!string.IsNullOrWhiteSpace(chosenFavourite))
  394. IssuingFavouriteChosen(chosenFavourite);
  395. else
  396. ChooseIssuingLocation();
  397. break;
  398. default:
  399. return;
  400. }
  401. }
  402. private void ClearLists()
  403. {
  404. issuingHoldings.Clear();
  405. receivingHoldings.Clear();
  406. RefreshLists();
  407. }
  408. private void RefreshLists()
  409. {
  410. Device.BeginInvokeOnMainThread(() =>
  411. {
  412. issuingListView.ItemsSource = null;
  413. issuingListView.ItemsSource = issuingHoldings;
  414. receivingListView.ItemsSource = null;
  415. receivingListView.ItemsSource = receivingHoldings;
  416. issuingLocationCountLbl.Text = "Items: " + issuingHoldings.Count();
  417. receivingCountLbl.Text = "Items in Batch: " + receivingHoldings.Count();
  418. searchEnt.Text = "";
  419. if (receivingHoldings.Count > 0)
  420. {
  421. Save.IsEnabled = true;
  422. }
  423. else
  424. {
  425. Save.IsEnabled = false;
  426. }
  427. });
  428. }
  429. #endregion
  430. #region Search
  431. private void SearchEnt_Changed(object sender, EventArgs e)
  432. {
  433. if (string.IsNullOrWhiteSpace(searchEnt.Text))
  434. {
  435. issuingListView.ItemsSource = issuingHoldings;
  436. }
  437. else
  438. {
  439. RunSearch();
  440. }
  441. }
  442. private void RunSearch()
  443. {
  444. issuingListView.ItemsSource = issuingHoldings.Where
  445. (x => x.Code.Contains(searchEnt.Text) || x.Code.Contains(UpperCaseFirst(searchEnt.Text)) || x.Code.Contains(searchEnt.Text.ToLower()) || x.Code.Contains(searchEnt.Text.ToUpper())
  446. || x.Name.Contains(searchEnt.Text) || x.Name.Contains(UpperCaseFirst(searchEnt.Text)) || x.Name.Contains(searchEnt.Text.ToLower()) || x.Name.Contains(searchEnt.Text.ToUpper())
  447. || x.Finish.Contains(searchEnt.Text) || x.Finish.Contains(UpperCaseFirst(searchEnt.Text)) || x.Finish.Contains(searchEnt.Text.ToLower()) || x.Finish.Contains(searchEnt.Text.ToUpper())
  448. );
  449. }
  450. static String UpperCaseFirst(string s)
  451. {
  452. char[] a = s.ToCharArray();
  453. a[0] = char.ToUpper(a[0]);
  454. return new string(a);
  455. }
  456. #endregion
  457. #region Utils
  458. private async void LoadIncomingListData(Filter<StockHolding> filter)
  459. {
  460. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
  461. {
  462. CoreTable table = DoQuery(filter);
  463. while (table == null)
  464. table = DoQuery(filter);
  465. if (table.Rows.Any())
  466. {
  467. foreach (CoreRow row in table.Rows)
  468. {
  469. StockHoldingShell shell = new StockHoldingShell();
  470. shell.ID = row.Get<StockHolding, Guid>(x => x.Location.ID).ToString()
  471. + row.Get<StockHolding, Guid>(x => x.Product.ID).ToString()
  472. + row.Get<StockHolding, Guid>(x => x.Job.ID).ToString()
  473. + row.Get<StockHolding, Guid>(x => x.Style.ID).ToString()
  474. + row.Get<StockHolding, string>(x => x.Dimensions.UnitSize);
  475. shell.Code = row.Get<StockHolding, string>(x => x.Product.Code);
  476. shell.Name = row.Get<StockHolding, string>(x => x.Product.Name);
  477. shell.Finish = row.Get<StockHolding, string>(x => x.Style.Description);
  478. shell.StyleName = "Finish: " + shell.Finish;
  479. shell.DimensionsUnitSize = row.Get<StockHolding, string>(x => x.Dimensions.UnitSize);
  480. shell.Units = row.Get<StockHolding, double>(x => x.Units);
  481. shell.DisplaySize = "Size: " + shell.DimensionsUnitSize;
  482. shell.DisplayUnits = "Units: " + shell.Units;
  483. shell.JobID = row.Get<StockHolding, Guid>(x => x.Job.ID);
  484. shell.JobName = row.Get<StockHolding, string>(x => x.Job.Name);
  485. shell.JobNumber = row.Get<StockHolding, string>(x => x.Job.JobNumber);
  486. shell.DisplayJob = "Job: " + shell.JobNumber;
  487. shell.StyleID = row.Get<StockHolding, Guid>(x => x.Style.ID);
  488. shell.StyleCode = row.Get<StockHolding, string>(x => x.Style.Code);
  489. shell.ProductID = row.Get<StockHolding, Guid>(x => x.Product.ID);
  490. shell.ImageID = row.Get<StockHolding, Guid>(x => x.Product.Image.ID);
  491. shell.DimensionsUnitID = row.Get<StockHolding, Guid>(x => x.Dimensions.Unit.ID);
  492. shell.DimensionsQuantity = row.Get<StockHolding, double>(x => x.Dimensions.Quantity);
  493. shell.DimensionsLength = row.Get<StockHolding, double>(x => x.Dimensions.Length);
  494. shell.DimensionsWidth = row.Get<StockHolding, double>(x => x.Dimensions.Width);
  495. shell.DimensionsHeight = row.Get<StockHolding, double>(x => x.Dimensions.Height);
  496. shell.DimensionsWeight = row.Get<StockHolding, double>(x => x.Dimensions.Weight);
  497. shell.DimensionsValue = row.Get<StockHolding, double>(x => x.Dimensions.Value);
  498. shell.DimensionsHasHeight = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasHeight);
  499. shell.DimensionsHasLength = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasLength);
  500. shell.DimensionsHasWidth = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasWidth);
  501. shell.DimensionsHasWeight = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasWeight);
  502. shell.DimensionsHasQuantity = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasQuantity);
  503. shell.DimensionsUnitFormula = row.Get<StockHolding, string>(x => x.Dimensions.Unit.Formula);
  504. shell.DimensionsUnitFormat = row.Get<StockHolding, string>(x => x.Dimensions.Unit.Format);
  505. shell.DimensionsUnitCode = row.Get<StockHolding, string>(x => x.Dimensions.Unit.Code);
  506. shell.DimensionsUnitDescription = row.Get<StockHolding, string>(x => x.Dimensions.Unit.Description);
  507. if (!shell.Code.Contains("FREIGHT"))
  508. {
  509. if (shell.Units > 0)
  510. {
  511. shell.DisplayUnits = "Units: " + shell.Units;
  512. issuingHoldings.Add(shell);
  513. }
  514. }
  515. }
  516. }
  517. RefreshLists();
  518. LoadProductImages();
  519. }
  520. }
  521. private CoreTable DoQuery(Filter<StockHolding> filter)
  522. {
  523. try
  524. {
  525. return new Client<StockHolding>().Query
  526. (
  527. filter,
  528. new Columns<StockHolding>
  529. (
  530. x => x.ID, //0
  531. x => x.Product.Code, //1
  532. x => x.Product.Name, //2
  533. x => x.Style.Description, //3
  534. x => x.Dimensions.UnitSize, //4
  535. x => x.Units, //5
  536. x => x.Location.ID, //6
  537. x => x.Job.ID, //7
  538. x => x.Job.Name, //8
  539. x => x.Job.JobNumber, //9
  540. x => x.Style.ID, //10
  541. x => x.Style.Code, //11
  542. x => x.Product.ID, //12
  543. x => x.Product.Image.ID, //13
  544. x => x.Dimensions.Unit.ID, //14
  545. x => x.Dimensions.Quantity, //15
  546. x => x.Dimensions.Length, //16
  547. x => x.Dimensions.Width, //17
  548. x => x.Dimensions.Height, //18
  549. x => x.Dimensions.Weight, //19
  550. x => x.Dimensions.Value, //20
  551. x => x.Dimensions.Unit.HasHeight, //21
  552. x => x.Dimensions.Unit.HasLength, //22
  553. x => x.Dimensions.Unit.HasWidth, //23
  554. x => x.Dimensions.Unit.HasWeight, //24
  555. x => x.Dimensions.Unit.HasQuantity, //25
  556. x => x.Dimensions.Unit.Formula, //26
  557. x => x.Dimensions.Unit.Format, //27
  558. x => x.Dimensions.Unit.Code, //28
  559. x => x.Dimensions.Unit.Description //29
  560. ),
  561. null
  562. );
  563. }
  564. catch (Exception ex)
  565. {
  566. InABox.Mobile.MobileLogging.Log(ex);
  567. return null;
  568. }
  569. }
  570. private void LoadProductImages()
  571. {
  572. Task.Run(() =>
  573. {
  574. List<Guid> imageIDs = new List<Guid>();
  575. foreach (var item in issuingHoldings)
  576. {
  577. if (item.ImageID != Guid.Empty)
  578. imageIDs.Add(item.ImageID);
  579. }
  580. CoreTable table = QueryDocuments(imageIDs);
  581. while (table == null)
  582. table = QueryDocuments(imageIDs);
  583. foreach (CoreRow row in table.Rows)
  584. {
  585. Guid id = row.Get<Document, Guid>(x => x.ID);
  586. var item = issuingHoldings.FirstOrDefault(x => x.ImageID == id);
  587. item.ImageSource = ImageSource.FromStream(() => new MemoryStream(row.Get<Document, byte[]>(x => x.Data)));
  588. item.ImageVisible = true;
  589. if (DeviceType == "Tablet")
  590. {
  591. item.LastRowHeight = 300;
  592. }
  593. else
  594. {
  595. item.LastRowHeight = 150;
  596. }
  597. }
  598. Device.BeginInvokeOnMainThread(() =>
  599. {
  600. issuingListView.ItemsSource = null;
  601. issuingListView.ItemsSource = issuingHoldings;
  602. });
  603. });
  604. }
  605. private CoreTable QueryDocuments(List<Guid> imageIDs)
  606. {
  607. try
  608. {
  609. return new Client<Document>().Query(new Filter<Document>(x => x.ID).InList(imageIDs.ToArray()),
  610. new Columns<Document>(x => x.ID, x => x.Data));
  611. }
  612. catch (Exception ex)
  613. {
  614. InABox.Mobile.MobileLogging.Log(ex);
  615. return null;
  616. }
  617. }
  618. private void LoadImages()
  619. {
  620. Task.Run(() =>
  621. {
  622. foreach (StockHoldingShell shell in issuingHoldings)
  623. {
  624. if (shell.ImageID != Guid.Empty)
  625. {
  626. CoreTable table = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(shell.ImageID));
  627. if (table.Rows.Any())
  628. {
  629. CoreRow docrow = table.Rows.FirstOrDefault();
  630. if (docrow != null)
  631. {
  632. byte[] data = docrow.Get<Document, byte[]>(x => x.Data);
  633. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  634. if (src != null)
  635. {
  636. shell.ImageSource = src;
  637. shell.ImageVisible = true;
  638. if (DeviceType == "Tablet")
  639. {
  640. shell.LastRowHeight = 300;
  641. }
  642. else
  643. {
  644. shell.LastRowHeight = 150;
  645. }
  646. Device.BeginInvokeOnMainThread(() =>
  647. {
  648. issuingListView.ItemsSource = null;
  649. issuingListView.ItemsSource = issuingHoldings;
  650. });
  651. }
  652. }
  653. }
  654. }
  655. }
  656. });
  657. }
  658. private void CollapseExpanderOnButtonPress()
  659. {
  660. if (issuingExpander.State.Equals(ExpandState.Expanding) || issuingExpander.State.Equals(ExpandState.Expanded))
  661. {
  662. issuingExpander.IsExpanded = false;
  663. issuingFrame.HeightRequest = frameHeight;
  664. ForceLayout();
  665. }
  666. if (receivingExpander.State.Equals(ExpandState.Expanding) || receivingExpander.State.Equals(ExpandState.Expanded))
  667. {
  668. receivingExpander.IsExpanded = false;
  669. receivingFrame.HeightRequest = frameHeight;
  670. ForceLayout();
  671. }
  672. }
  673. //TODO
  674. private StockHoldingShell DuplicateShell(StockHoldingShell shell)
  675. {
  676. StockHoldingShell NewShell = new StockHoldingShell()
  677. {
  678. ID = shell.ID,
  679. Code = shell.Code,
  680. Name = shell.Name,
  681. Finish = shell.Finish,
  682. Units = shell.Units,
  683. DisplayUnits = shell.DisplayUnits,
  684. JobID = shell.JobID,
  685. JobName = shell.JobName,
  686. JobNumber = shell.JobNumber,
  687. DisplayJob = shell.DisplayJob,
  688. StyleName = shell.StyleName,
  689. StyleID = shell.StyleID,
  690. StyleCode = shell.StyleCode,
  691. ProductID = shell.ProductID,
  692. DisplaySize = shell.DisplaySize,
  693. LastRowHeight = shell.LastRowHeight,
  694. ImageID = shell.ImageID,
  695. ImageSource = shell.ImageSource,
  696. ImageVisible = shell.ImageVisible,
  697. DimensionsUnitID = shell.DimensionsUnitID,
  698. DimensionsQuantity = shell.DimensionsQuantity,
  699. DimensionsLength = shell.DimensionsLength,
  700. DimensionsWidth = shell.DimensionsWidth,
  701. DimensionsHeight = shell.DimensionsHeight,
  702. DimensionsWeight = shell.DimensionsWeight,
  703. DimensionsValue = shell.DimensionsValue,
  704. DimensionsUnitSize = shell.DimensionsUnitSize,
  705. DimensionsHasHeight = shell.DimensionsHasHeight,
  706. DimensionsHasLength = shell.DimensionsHasLength,
  707. DimensionsHasWidth = shell.DimensionsHasWidth,
  708. DimensionsHasWeight = shell.DimensionsHasWeight,
  709. DimensionsHasQuantity = shell.DimensionsHasQuantity,
  710. DimensionsUnitFormula = shell.DimensionsUnitFormula,
  711. DimensionsUnitFormat = shell.DimensionsUnitFormat,
  712. DimensionsUnitCode = shell.DimensionsUnitCode,
  713. DimensionsUnitDescription = shell.DimensionsUnitDescription,
  714. };
  715. return NewShell;
  716. }
  717. private void IssuingExpander_Tapped(object sender, EventArgs e)
  718. {
  719. if (issuingExpander.State.Equals(ExpandState.Expanding) || issuingExpander.State.Equals(ExpandState.Expanded))
  720. {
  721. }
  722. else if (issuingExpander.State.Equals(ExpandState.Collapsing) || issuingExpander.State.Equals(ExpandState.Collapsed))
  723. {
  724. issuingFrame.HeightRequest = frameHeight;
  725. ForceLayout();
  726. }
  727. }
  728. private void ReceivingExpander_Tapped(object sender, EventArgs e)
  729. {
  730. if (receivingExpander.State.Equals(ExpandState.Expanding) || receivingExpander.State.Equals(ExpandState.Expanded))
  731. {
  732. }
  733. else if (receivingExpander.State.Equals(ExpandState.Collapsing) || receivingExpander.State.Equals(ExpandState.Collapsed))
  734. {
  735. receivingFrame.HeightRequest = frameHeight;
  736. ForceLayout();
  737. }
  738. }
  739. private void ReceivingStockLocation_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
  740. {
  741. Device.BeginInvokeOnMainThread(() =>
  742. {
  743. receivingLocationLbl.Text = ReceivingStockLocation.Description;
  744. });
  745. }
  746. private void IssuingStockLocation_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
  747. {
  748. Device.BeginInvokeOnMainThread(() =>
  749. {
  750. issuingLocationLbl.Text = IssuingStockLocation.Description;
  751. });
  752. }
  753. private async void LoadDefaultStyle()
  754. {
  755. try
  756. {
  757. await Task.Run(() =>
  758. {
  759. CoreTable table = new Client<Job>().Query(
  760. new Filter<Job>(x => x.ID).IsEqualTo(ReceivingStockLocation.Job.ID),
  761. new Columns<Job>(x => x.Style.ID, x => x.Style.Code, x => x.Style.Description)
  762. );
  763. if (table.Rows.Any())
  764. {
  765. List<object> list = table.Rows.First().Values;
  766. if (list[0] == null) { list[0] = Guid.Empty; } //0
  767. if (list[1] == null) { list[1] = ""; } //1
  768. if (list[2] == null) { list[2] = ""; } //2
  769. DefaultStyle.ID = Guid.Parse(list[0].ToString());
  770. DefaultStyle.Code = list[1].ToString();
  771. DefaultStyle.Description = list[2].ToString();
  772. }
  773. });
  774. }
  775. catch { }
  776. }
  777. private void LoadFavourites()
  778. {
  779. try
  780. {
  781. CoreTable table = new Client<StockLocation>().Query
  782. (
  783. new Filter<StockLocation>(x => x.Favourite).IsEqualTo(true),
  784. new Columns<StockLocation>(x => x.ID, x => x.Code, x => x.Description)
  785. );
  786. if (table.Rows.Any())
  787. {
  788. foreach (CoreRow row in table.Rows)
  789. {
  790. if (favourites.Count < 3)
  791. {
  792. List<object> list = row.Values;
  793. if (list[0] == null) list[0] = Guid.Empty;
  794. if (list[1] == null) list[1] = "";
  795. if (list[2] == null) list[2] = "";
  796. StockLocation location = new StockLocation()
  797. {
  798. ID = Guid.Parse(list[0].ToString()),
  799. Code = list[1].ToString(),
  800. Description = list[2].ToString(),
  801. };
  802. favourites.Add(location);
  803. }
  804. }
  805. Device.BeginInvokeOnMainThread(() =>
  806. {
  807. if (favourites.Count == 0)
  808. {
  809. DisableButtonOne();
  810. DisableButtonTwo();
  811. DisableButtonThree();
  812. }
  813. if (favourites.Count == 1)
  814. {
  815. issuingFavouriteBtn1.Text = favourites[0].Code;
  816. receivingFavouriteBtn1.Text = favourites[0].Code;
  817. DisableButtonTwo();
  818. DisableButtonThree();
  819. }
  820. if (favourites.Count == 2)
  821. {
  822. issuingFavouriteBtn1.Text = favourites[0].Code;
  823. receivingFavouriteBtn1.Text = favourites[0].Code;
  824. issuingFavouriteBtn2.Text = favourites[1].Code;
  825. receivingFavouriteBtn2.Text = favourites[1].Code;
  826. DisableButtonThree();
  827. }
  828. if (favourites.Count == 3)
  829. {
  830. issuingFavouriteBtn1.Text = favourites[0].Code;
  831. receivingFavouriteBtn1.Text = favourites[0].Code;
  832. issuingFavouriteBtn2.Text = favourites[1].Code;
  833. receivingFavouriteBtn2.Text = favourites[1].Code;
  834. issuingFavouriteBtn3.Text = favourites[2].Code;
  835. receivingFavouriteBtn3.Text = favourites[2].Code;
  836. }
  837. });
  838. }
  839. }
  840. catch
  841. {
  842. }
  843. }
  844. void DisableButtonOne()
  845. {
  846. issuingFavouriteBtn1.Text = "Not set";
  847. issuingFavouriteBtn1.IsEnabled = false;
  848. receivingFavouriteBtn1.Text = "Not set";
  849. receivingFavouriteBtn1.IsEnabled = false;
  850. }
  851. void DisableButtonTwo()
  852. {
  853. issuingFavouriteBtn2.Text = "Not set";
  854. issuingFavouriteBtn2.IsEnabled = false;
  855. receivingFavouriteBtn2.Text = "Not set";
  856. receivingFavouriteBtn2.IsEnabled = false;
  857. }
  858. void DisableButtonThree()
  859. {
  860. issuingFavouriteBtn3.Text = "Not set";
  861. issuingFavouriteBtn3.IsEnabled = false;
  862. receivingFavouriteBtn3.Text = "Not set";
  863. receivingFavouriteBtn3.IsEnabled = false;
  864. }
  865. #endregion
  866. #region Page Navigation / Saving
  867. private async void ExitWithoutSaving(object sender, EventArgs e)
  868. {
  869. if (receivingHoldings.Count > 0)
  870. {
  871. string chosenOption = await DisplayActionSheet("Leave without saving?", "Cancel", null, "Yes", "No");
  872. switch (chosenOption)
  873. {
  874. case "Cancel":
  875. return;
  876. case "Yes":
  877. Navigation.PopAsync();
  878. break;
  879. case "No":
  880. return;
  881. default:
  882. return;
  883. }
  884. }
  885. else
  886. Navigation.PopAsync();
  887. }
  888. private void SaveBatch_Clicked(object sender, EventArgs e)
  889. {
  890. if (receivingHoldings.Count == 0)
  891. return;
  892. if (ReceivingStockLocation.ID == Guid.Empty && ReceivingJob.ID == Guid.Empty)
  893. return;
  894. RecTransCompletion completionPage = new RecTransCompletion(receivingHoldings, originalHoldings, IssuingStockLocation, ReceivingStockLocation, ReceivingJob);
  895. completionPage.OnRecTransCompleted += (() =>
  896. {
  897. ReceivingStockLocation = new StockLocation();
  898. ReceivingJob = new Job();
  899. receivingLocationLbl.Text = "Receiving Location:";
  900. receivingHoldings.Clear();
  901. originalHoldings.Clear();
  902. issuingListView.ItemsSource = null;
  903. receivingListView.ItemsSource = null;
  904. PreviousStyle = new ProductStyle();
  905. RefreshLists();
  906. });
  907. Navigation.PushAsync(completionPage);
  908. }
  909. #endregion
  910. }
  911. }