RecTrans.xaml.cs 41 KB

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