Receivals.xaml.cs 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using InABox.Core;
  7. using InABox.Clients;
  8. using Comal.Classes;
  9. using Xamarin.Forms;
  10. using Xamarin.Forms.Xaml;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using comal.timesheets.QAForms;
  14. using XF.Material.Forms.UI.Dialogs;
  15. using comal.timesheets;
  16. using Xamarin.Essentials;
  17. using System.IO;
  18. using PRSSecurity = InABox.Core.Security;
  19. namespace comal.timesheets
  20. {
  21. [XamlCompilation(XamlCompilationOptions.Compile)]
  22. public partial class Receivals : ContentPage
  23. {
  24. #region Fields & Constructor, OnAppearing
  25. Guid POID = Guid.Empty;
  26. List<POItemShell> poItemShells = new List<POItemShell>();
  27. List<StockLocationShell> stockLocationShells = new List<StockLocationShell>();
  28. bool bOpening = false;
  29. List<Guid> holdingsToLookup = new List<Guid>();
  30. string deviceType = "";
  31. Guid supplierID = Guid.Empty;
  32. string PONumber = "";
  33. Guid consignmentID = Guid.Empty;
  34. string consignmentNumber = "";
  35. List<POItemShell> listReceived = new List<POItemShell>();
  36. public Receivals(Guid _poID, string _PONumber, Guid _supplierID)
  37. {
  38. InitializeComponent();
  39. NavigationPage.SetHasBackButton(this, false);
  40. POID = _poID;
  41. PONumber = _PONumber;
  42. poNumberLbl.Text = "PO: " + _PONumber;
  43. var idiom = DeviceInfo.Idiom;
  44. if (idiom.Equals(DeviceIdiom.Tablet))
  45. {
  46. deviceType = "Tablet";
  47. }
  48. LoadPOItems();
  49. supplierID = _supplierID;
  50. AddIncomingStores();
  51. }
  52. protected override void OnAppearing()
  53. {
  54. base.OnAppearing();
  55. bOpening = false;
  56. }
  57. #endregion
  58. #region User Interaction
  59. private async void Exit_Clicked(object sender, EventArgs e)
  60. {
  61. if (listReceived.Count > 0)
  62. {
  63. DisplayAlert("Alert", "Consignment has items received and must be saved with photos before exiting", "OK");
  64. }
  65. else
  66. Navigation.PopAsync();
  67. }
  68. private async void Save_Clicked(object sender, EventArgs e)
  69. {
  70. ConsignmentCompletionPage completionPage = new ConsignmentCompletionPage(listReceived, consignmentID, consignmentNumber);
  71. completionPage.OnConsignmentSaved += () =>
  72. {
  73. Navigation.PopAsync();
  74. };
  75. Navigation.PushAsync(completionPage);
  76. }
  77. private void ConsignmentList_Tapped(object sender, EventArgs e)
  78. {
  79. if (bOpening)
  80. return;
  81. if (!PRSSecurity.IsAllowed<CanReceiveConsignments>())
  82. {
  83. DisplayAlert("Not allowed", "Please check security setting: Receive Consignments", "OK");
  84. return;
  85. }
  86. bOpening = true;
  87. POItemShell poItemShell = poItemListView.SelectedItem as POItemShell;
  88. if (poItemShell.Nonstock == true)
  89. {
  90. ChooseQtyNonStockItem(poItemShell);
  91. }
  92. else
  93. {
  94. ChooseQtyStockItem(poItemShell);
  95. }
  96. }
  97. private async void ChooseQtyStockItem(POItemShell poItemShell)
  98. {
  99. ConsignmentDetailsPopup popup = new ConsignmentDetailsPopup(poItemShell, stockLocationShells);
  100. popup.OnConsignmentPopupAccepted += async () =>
  101. {
  102. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
  103. {
  104. poItemShell.StockLocationID = popup._POItemShell.StockLocationID;
  105. poItemShell.StockLocationCode = popup._POItemShell.StockLocationCode;
  106. poItemShell.StockLocationDescription = popup._POItemShell.StockLocationDescription;
  107. poItemShell.ReceivedQty = popup._POItemShell.ReceivedQty;
  108. StockLocationShell location = stockLocationShells.Find(x => x.ID.Equals(poItemShell.StockLocationID));
  109. if (location == null)
  110. {
  111. StockLocationShell newLocation = new StockLocationShell()
  112. {
  113. ID = poItemShell.StockLocationID,
  114. Code = poItemShell.StockLocationCode,
  115. Description = poItemShell.StockLocationDescription
  116. };
  117. stockLocationShells.Add(newLocation);
  118. }
  119. ChooseSavePathwayAsync(poItemShell);
  120. }
  121. };
  122. Navigation.PushAsync(popup);
  123. bOpening = false;
  124. }
  125. private async void ChooseQtyNonStockItem(POItemShell poItemShell)
  126. {
  127. Device.BeginInvokeOnMainThread(async () =>
  128. {
  129. //if nonstock item - only rec qty, otherwise open popup page
  130. string chosenOption = await DisplayPromptAsync("Enter Received Quantity", "", initialValue: poItemShell.ExpectedQty.ToString(), keyboard: Keyboard.Numeric);
  131. if (!string.IsNullOrEmpty(chosenOption) || chosenOption != "Cancel")
  132. {
  133. try
  134. {
  135. double qty = double.Parse(chosenOption);
  136. poItemShell.ReceivedQty = qty;
  137. }
  138. catch
  139. {
  140. DisplayAlert("Error", "Invalid Qty", "OK");
  141. bOpening = false;
  142. return;
  143. }
  144. bOpening = false;
  145. ChooseSavePathwayAsync(poItemShell);
  146. }
  147. else
  148. bOpening = false;
  149. });
  150. }
  151. private void SearchEnt_Changed(object sender, EventArgs e)
  152. {
  153. if (string.IsNullOrWhiteSpace(searchEnt.Text))
  154. {
  155. poItemListView.ItemsSource = poItemShells;
  156. }
  157. else
  158. {
  159. poItemListView.ItemsSource = poItemShells.Where(x =>
  160. x.Description.Contains(searchEnt.Text) || x.Description.Contains(UpperCaseFirst(searchEnt.Text)) || x.Description.Contains(LowerCaseFirst(searchEnt.Text))
  161. || x.Description.Contains(searchEnt.Text.ToUpper()) || x.Description.Contains(searchEnt.Text.ToLower()) ||
  162. x.ExpectedQty.ToString().Contains(searchEnt.Text)
  163. );
  164. }
  165. }
  166. static String UpperCaseFirst(string s)
  167. {
  168. char[] a = s.ToCharArray();
  169. a[0] = char.ToUpper(a[0]);
  170. return new string(a);
  171. }
  172. static String LowerCaseFirst(string s)
  173. {
  174. char[] a = s.ToCharArray();
  175. a[0] = char.ToLower(a[0]);
  176. return new string(a);
  177. }
  178. #endregion
  179. #region Saving
  180. private async Task ChooseSavePathwayAsync(POItemShell poItemShell)
  181. {
  182. if (consignmentID == Guid.Empty)
  183. await CreateNewConsignment();
  184. if (poItemShell.ReceivedQty == poItemShell.ExpectedQty)
  185. {
  186. SaveCorrectQuantityPOItem(poItemShell);
  187. }
  188. else if (poItemShell.ReceivedQty < poItemShell.ExpectedQty && poItemShell.ReceivedQty != 0)
  189. {
  190. SaveLesserQuantityPOItem(poItemShell);
  191. }
  192. else if (poItemShell.ReceivedQty > poItemShell.ExpectedQty)
  193. {
  194. SaveExtraQuantityPOItem(poItemShell);
  195. }
  196. }
  197. private async void SaveCorrectQuantityPOItem(POItemShell poItemShell)
  198. {
  199. await Task.Run(() =>
  200. {
  201. poItemShell.ReceivedQty = poItemShell.ExpectedQty;
  202. poItemShell.ReceivedDate = DateTime.Now;
  203. poItemShell.ConsignmentID = consignmentID;
  204. poItemShell.ConsignmentNumber = consignmentNumber;
  205. SavePOItem(poItemShell);
  206. int index = poItemShells.FindIndex(x => x.ID.Equals(poItemShell.ID));
  207. poItemShells.RemoveAt(index);
  208. RefreshLists(poItemShell);
  209. });
  210. }
  211. private void SavePOItem(POItemShell poItemShell)
  212. {
  213. Task.Run(() =>
  214. {
  215. listReceived.Add(poItemShell);
  216. PurchaseOrderItem purchaseOrderItem = new PurchaseOrderItem();
  217. purchaseOrderItem.Description = poItemShell.Description;
  218. purchaseOrderItem.ID = poItemShell.ID;
  219. purchaseOrderItem.Qty = poItemShell.ReceivedQty;
  220. purchaseOrderItem.ReceivedDate = DateTime.Now;
  221. purchaseOrderItem.Consignment.ID = consignmentID;
  222. purchaseOrderItem.PurchaseOrderLink.PONumber = poItemShell.PONumber;
  223. purchaseOrderItem.PurchaseOrderLink.ID = poItemShell.POID;
  224. purchaseOrderItem = CopyDetails(purchaseOrderItem, poItemShell);
  225. new Client<PurchaseOrderItem>().Save(purchaseOrderItem, "Updated from mobile device");
  226. });
  227. }
  228. private void RefreshLists(POItemShell poItemShell)
  229. {
  230. Device.BeginInvokeOnMainThread(() =>
  231. {
  232. poItemListView.ItemsSource = null;
  233. poItemListView.ItemsSource = poItemShells;
  234. poItemCountLbl.Text = "Items Unreceived: " + poItemShells.Count;
  235. if (poItemShell.StockLocationID != Guid.Empty)
  236. {
  237. StockLocationShell location = stockLocationShells.Find(x => x.ID.Equals(poItemShell.StockLocationID));
  238. location.PoItems.Add(poItemShell);
  239. location.NumberOfReceivedItems = "Received items: " + location.PoItems.Count;
  240. locationsStackLayout.Children.Clear();
  241. foreach (StockLocationShell shell in stockLocationShells)
  242. {
  243. StockLocationViewCell viewcell = new StockLocationViewCell(shell);
  244. locationsStackLayout.Children.Add(viewcell);
  245. }
  246. }
  247. });
  248. }
  249. private async void SaveLesserQuantityPOItem(POItemShell poItemShell)
  250. {
  251. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
  252. {
  253. try
  254. {
  255. string originalDescription = poItemShell.Description;
  256. int index = poItemShells.FindIndex(x => x.ID.Equals(poItemShell.ID));
  257. poItemShells.RemoveAt(index);
  258. //placeholder added while all the loading / saving happens - to be replaced later when new purchaseorderitem ID is returned
  259. POItemShell placeHolderShell = poItemShell.DuplicateNewShell(poItemShell);
  260. placeHolderShell.ExpectedQty = poItemShell.ExpectedQty - poItemShell.ReceivedQty;
  261. poItemShells.Insert(index, placeHolderShell);
  262. SavePOItem(poItemShell); //original POItem is saved
  263. CoreTable table = new Client<PurchaseOrderItem>().Query(new Filter<PurchaseOrderItem>(x => x.ID).IsEqualTo(poItemShell.ID),
  264. columns);
  265. PurchaseOrderItem purchaseOrderItem = table.Rows.FirstOrDefault()?.ToObject<PurchaseOrderItem>();
  266. if (purchaseOrderItem == null)
  267. return;
  268. purchaseOrderItem.ID = Guid.Empty;
  269. purchaseOrderItem.Created = DateTime.Now;
  270. purchaseOrderItem.LastUpdate = DateTime.Now;
  271. purchaseOrderItem.OriginalValues.Remove("ID", out object obj);
  272. purchaseOrderItem.ReceivedDate = DateTime.MinValue;
  273. purchaseOrderItem.Qty = poItemShell.ExpectedQty - poItemShell.ReceivedQty;
  274. purchaseOrderItem.Description = originalDescription;
  275. purchaseOrderItem.Consignment.ID = Guid.Empty;
  276. purchaseOrderItem = CopyDetails(purchaseOrderItem, poItemShell);
  277. new Client<PurchaseOrderItem>().Save(purchaseOrderItem, "Update from mobile device");
  278. //new purchase order is split from original with different quantity and no consignment linked, saved to database
  279. POItemShell newShell = poItemShell.DuplicateNewShell(poItemShell);
  280. newShell.ID = purchaseOrderItem.ID;
  281. newShell.Description = purchaseOrderItem.Description;
  282. newShell.ExpectedQty = purchaseOrderItem.Qty;
  283. newShell.ConsignmentID = Guid.Empty;
  284. newShell.ConsignmentNumber = "";
  285. //placeholder is replaced by new shell with correct ID
  286. poItemShells.RemoveAt(index);
  287. poItemShells.Insert(index, newShell);
  288. RefreshLists(poItemShell);
  289. }
  290. catch { }
  291. }
  292. }
  293. private async void SaveExtraQuantityPOItem(POItemShell poItemShell)
  294. {
  295. await Task.Run(() =>
  296. {
  297. try
  298. {
  299. string originalDescription = poItemShell.Description;
  300. double originalExpectedQty = poItemShell.ExpectedQty;
  301. double originalReceivedQty = poItemShell.ReceivedQty;
  302. double extraSupplied = originalReceivedQty - originalExpectedQty;
  303. int index = poItemShells.FindIndex(x => x.ID.Equals(poItemShell.ID));
  304. poItemShells.RemoveAt(index);
  305. poItemShell.ReceivedDate = DateTime.Now;
  306. poItemShell.ConsignmentID = consignmentID;
  307. poItemShell.ConsignmentNumber = consignmentNumber;
  308. poItemShell.ReceivedQty = poItemShell.ExpectedQty;
  309. SavePOItem(poItemShell);
  310. RefreshLists(poItemShell);
  311. listReceived.Add(poItemShell);
  312. //for responsive view only
  313. POItemShell newShell = poItemShell.DuplicateNewShell(poItemShell);
  314. newShell.ReceivedQty = extraSupplied;
  315. newShell.ExpectedQty = extraSupplied;
  316. RefreshLists(newShell);
  317. listReceived.Add(newShell);
  318. CoreTable table = new Client<PurchaseOrderItem>().Query(new Filter<PurchaseOrderItem>(x => x.ID).IsEqualTo(poItemShell.ID)
  319. , columns);
  320. PurchaseOrderItem newPurchaseOrderItem = table.Rows.FirstOrDefault().ToObject<PurchaseOrderItem>();
  321. if (newPurchaseOrderItem == null)
  322. return;
  323. newPurchaseOrderItem.ReceivedDate = DateTime.Now;
  324. newPurchaseOrderItem.ID = Guid.Empty;
  325. newPurchaseOrderItem.Created = DateTime.Now;
  326. newPurchaseOrderItem.LastUpdate = DateTime.Now;
  327. newPurchaseOrderItem.OriginalValues.Remove("ID", out object obj);
  328. newPurchaseOrderItem.Qty = extraSupplied;
  329. newPurchaseOrderItem.Description = newShell.Description;
  330. newPurchaseOrderItem.Consignment.ID = consignmentID;
  331. newPurchaseOrderItem = CopyDetails(newPurchaseOrderItem, poItemShell);
  332. new Client<PurchaseOrderItem>().Save(newPurchaseOrderItem, "Update from mobile device");
  333. //new purchase order is split from original with different quantity, and consignment linked, saved to database
  334. }
  335. catch
  336. { }
  337. });
  338. }
  339. private PurchaseOrderItem CopyDetails(PurchaseOrderItem purchaseOrderItem, POItemShell poItemShell)
  340. {
  341. purchaseOrderItem.Product.ID = poItemShell.ProductID;
  342. purchaseOrderItem.Product.NonStock = poItemShell.Nonstock;
  343. purchaseOrderItem.Job.ID = poItemShell.JobID;
  344. purchaseOrderItem.Job.JobNumber = poItemShell.JobNumber;
  345. purchaseOrderItem.Job.Name = poItemShell.JobName;
  346. purchaseOrderItem.Style.ID = poItemShell.StyleID;
  347. purchaseOrderItem.Style.Code = poItemShell.StyleCode;
  348. purchaseOrderItem.Style.Description = poItemShell.StyleDescription;
  349. purchaseOrderItem.StockLocation.ID = poItemShell.StockLocationID;
  350. purchaseOrderItem.StockLocation.Description = poItemShell.StockLocationDescription;
  351. purchaseOrderItem.StockLocation.Code = poItemShell.StockLocationCode;
  352. purchaseOrderItem.Dimensions.Unit.ID = poItemShell.DimensionsUnitID;
  353. purchaseOrderItem.Dimensions.Quantity = poItemShell.DimensionsQuantity;
  354. purchaseOrderItem.Dimensions.Length = poItemShell.DimensionsLength;
  355. purchaseOrderItem.Dimensions.Width = poItemShell.DimensionsWidth;
  356. purchaseOrderItem.Dimensions.Height = poItemShell.DimensionsHeight;
  357. purchaseOrderItem.Dimensions.Weight = poItemShell.DimensionsWeight;
  358. purchaseOrderItem.Dimensions.Value = poItemShell.DimensionsValue;
  359. purchaseOrderItem.Dimensions.UnitSize = poItemShell.DimensionsUnitSize;
  360. purchaseOrderItem.Cost = poItemShell.Cost;
  361. purchaseOrderItem.Dimensions.Unit.HasHeight = poItemShell.DimensionsHasHeight;
  362. purchaseOrderItem.Dimensions.Unit.HasLength = poItemShell.DimensionsHasLength;
  363. purchaseOrderItem.Dimensions.Unit.HasWidth = poItemShell.DimensionsHasWidth;
  364. purchaseOrderItem.Dimensions.Unit.HasWeight = poItemShell.DimensionsHasWeight;
  365. purchaseOrderItem.Dimensions.Unit.HasQuantity = poItemShell.DimensionsHasQuantity;
  366. purchaseOrderItem.Dimensions.Unit.Formula = poItemShell.DimensionsUnitFormula;
  367. purchaseOrderItem.Dimensions.Unit.Format = poItemShell.DimensionsUnitFormat;
  368. purchaseOrderItem.Dimensions.Unit.Code = poItemShell.DimensionsUnitCode;
  369. purchaseOrderItem.Dimensions.Unit.Description = poItemShell.DimensionsUnitDescription;
  370. return purchaseOrderItem;
  371. }
  372. #region ChoosingLocations
  373. private async void ChooseReceivingLocationBtn_Clicked(object sender, EventArgs e)
  374. {
  375. string chosenOption = await DisplayActionSheet("Choose an Option", "Cancel", null, "New Location / Pack", "Existing Location / Pack");
  376. switch (chosenOption)
  377. {
  378. case "Cancel":
  379. return;
  380. break;
  381. case "New Location / Pack":
  382. ChooseNewLocation();
  383. break;
  384. case "Existing Location / Pack":
  385. ChooseReceivingLocation();
  386. break;
  387. default:
  388. return;
  389. break;
  390. }
  391. }
  392. private void ChooseNewLocation()
  393. {
  394. try
  395. {
  396. StockLocation location = new StockLocation();
  397. location.Active = true;
  398. location.Warehouse.ID = Guid.Parse("b6249c4a-a834-4927-a42c-87a07895d6bd"); //EXTRUSIONS
  399. location.Warehouse.Description = "Extrusions";
  400. location.Warehouse.Code = "EXTRUSIONS";
  401. location.Area.Warehouse.ID = Guid.Parse("b6249c4a-a834-4927-a42c-87a07895d6bd"); //EXTRUSIONS
  402. location.Area.Warehouse.Description = "Extrusions";
  403. location.Area.ID = Guid.Parse("fa02ecd8-e642-49aa-98b5-c04d7ea0f4eb"); //Rack FLOOR
  404. location.Area.Description = "Rack FLOOR";
  405. location.Area.Code = "FLOOR";
  406. LocationDetailsPage locationDetailsPage = new LocationDetailsPage(location);
  407. locationDetailsPage.OnSave += (o, loc) =>
  408. {
  409. if (String.IsNullOrWhiteSpace(loc.Code))
  410. {
  411. MaterialDialog.Instance.AlertAsync(message: "Code may not be blank!");
  412. return false;
  413. }
  414. if (String.IsNullOrWhiteSpace(loc.Description))
  415. {
  416. MaterialDialog.Instance.AlertAsync(message: "Description may not be blank!");
  417. return false;
  418. }
  419. if (loc.Area.ID == Guid.Empty)
  420. {
  421. MaterialDialog.Instance.AlertAsync(message: "Area may not be blank!");
  422. return false;
  423. }
  424. CoreTable others = new Client<StockLocation>().Query(
  425. new Filter<StockLocation>(x => x.Code).IsEqualTo(loc.Code).And(x => x.ID).IsNotEqualTo(loc.ID),
  426. new Columns<StockLocation>(x => x.ID)
  427. );
  428. if (others.Rows.Any())
  429. {
  430. MaterialDialog.Instance.AlertAsync(message: "Location Code already exists!");
  431. return false;
  432. }
  433. try
  434. {
  435. new Client<StockLocation>().Save(loc, "Created Location");
  436. StockLocationShell shell = new StockLocationShell();
  437. shell.ID = loc.ID;
  438. shell.Code = loc.Code;
  439. shell.Description = loc.Description;
  440. stockLocationShells.Add(shell);
  441. Device.BeginInvokeOnMainThread(() =>
  442. {
  443. locationsStackLayout.Children.Clear();
  444. foreach (StockLocationShell shell2 in stockLocationShells)
  445. {
  446. StockLocationViewCell viewcell = new StockLocationViewCell(shell2);
  447. viewcell.stockLocationShell.NumberOfReceivedItems = "Received items: " + shell2.PoItems.Count();
  448. locationsStackLayout.Children.Add(viewcell);
  449. }
  450. });
  451. }
  452. catch (Exception err)
  453. {
  454. MaterialDialog.Instance.AlertAsync(message: "Unable to save Location\n" + err.Message);
  455. return false;
  456. }
  457. return true;
  458. };
  459. Navigation.PushAsync(locationDetailsPage);
  460. }
  461. catch { }
  462. }
  463. private void ChooseReceivingLocation()
  464. {
  465. if (bOpening)
  466. return;
  467. bOpening = true;
  468. StockLocationSelectionPage stockLocationSelectionPage = new StockLocationSelectionPage(true);
  469. stockLocationSelectionPage.OnMultiLocationSelected += async (s) =>
  470. {
  471. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
  472. {
  473. foreach (StockLocationShell shell in s)
  474. {
  475. if (!stockLocationShells.Any(x => x.ID == shell.ID))
  476. {
  477. shell.Color = Color.Default;
  478. shell.NumberOfReceivedItems = "Received items: " + shell.PoItems.Count();
  479. stockLocationShells.Add(shell);
  480. }
  481. }
  482. Device.BeginInvokeOnMainThread(() =>
  483. {
  484. locationsStackLayout.Children.Clear();
  485. foreach (StockLocationShell shell in stockLocationShells)
  486. {
  487. StockLocationViewCell viewcell = new StockLocationViewCell(shell);
  488. viewcell.stockLocationShell.NumberOfReceivedItems = "Received items: " + shell.PoItems.Count();
  489. locationsStackLayout.Children.Add(viewcell);
  490. }
  491. });
  492. }
  493. };
  494. Navigation.PushAsync(stockLocationSelectionPage);
  495. }
  496. #endregion
  497. #endregion
  498. #region Loading
  499. private void AddIncomingStores()
  500. {
  501. Task.Run(() =>
  502. {
  503. try
  504. {
  505. StockLocation location = new Client<StockLocation>().Query(
  506. new Filter<StockLocation>(x => x.ID).IsEqualTo(Guid.Parse("3ebb1fe3-21f4-4731-b80a-a28f814982ea")),
  507. new Columns<StockLocation>(x => x.ID, x => x.Code, x => x.Description))
  508. .Rows.FirstOrDefault().ToObject<StockLocation>();
  509. stockLocationShells.Add(new StockLocationShell
  510. {
  511. ID = location.ID,
  512. Code = location.Code,
  513. Description = location.Description,
  514. NumberOfReceivedItems = "Received items: ",
  515. });
  516. StockLocationViewCell viewcell = new StockLocationViewCell(stockLocationShells[0]);
  517. Device.BeginInvokeOnMainThread(() =>
  518. {
  519. locationsStackLayout.Children.Add(viewcell);
  520. });
  521. }
  522. catch { }
  523. });
  524. }
  525. private void LoadPOItems()
  526. {
  527. Task.Run(() =>
  528. {
  529. try
  530. {
  531. CoreTable table = new Client<PurchaseOrderItem>().Query(
  532. new Filter<PurchaseOrderItem>(x => x.PurchaseOrderLink.ID).IsEqualTo(POID).And(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue),
  533. columns);
  534. if (table.Rows.Any())
  535. {
  536. foreach (CoreRow row in table.Rows)
  537. {
  538. List<object> list = row.Values;
  539. if (list[0] == null) { list[0] = Guid.Empty; } //0
  540. if (list[1] == null) { list[1] = ""; } //1
  541. if (list[2] == null) { list[2] = ""; } //2
  542. if (list[3] == null) { list[3] = ""; } //3
  543. if (list[4] == null) { list[4] = ""; } //4
  544. if (list[5] == null) { list[5] = ""; } //5
  545. if (list[6] == null) { list[6] = 0F; } //6
  546. if (list[7] == null) { list[7] = Guid.Empty; } //7
  547. if (list[8] == null) { list[8] = Guid.Empty; } //8
  548. if (list[9] == null) { list[9] = DateTime.MinValue; } //9
  549. if (list[10] == null) { list[10] = Guid.Empty; } //10
  550. if (list[11] == null) { list[11] = ""; } //11
  551. if (list[12] == null) { list[12] = Guid.Empty; } //12
  552. if (list[13] == null) { list[13] = false; } //13
  553. if (list[14] == null) { list[14] = Guid.Empty; } //14
  554. if (list[15] == null) { list[15] = ""; } //15
  555. if (list[16] == null) { list[16] = ""; } //16
  556. if (list[17] == null) { list[17] = Guid.Empty; } //17
  557. if (list[18] == null) { list[18] = ""; } //18
  558. if (list[19] == null) { list[19] = ""; } //19
  559. if (list[20] == null) { list[20] = Guid.Empty; } //20
  560. if (list[21] == null) { list[21] = 0; } //21
  561. if (list[22] == null) { list[22] = 0; } //22
  562. if (list[23] == null) { list[23] = 0; } //23
  563. if (list[24] == null) { list[24] = 0; } //24
  564. if (list[25] == null) { list[25] = 0; } //25
  565. if (list[26] == null) { list[26] = 0; } //26
  566. if (list[27] == null) { list[27] = ""; } //27
  567. if (list[28] == null) { list[28] = 0; } //28
  568. if (list[28] == null) { list[29] = false; } //29
  569. if (list[29] == null) { list[30] = false; } //30
  570. if (list[30] == null) { list[31] = false; } //31
  571. if (list[31] == null) { list[32] = false; } //32
  572. if (list[32] == null) { list[33] = false; } //33
  573. if (list[33] == null) { list[34] = ""; } //34
  574. if (list[34] == null) { list[35] = ""; } //35
  575. if (list[35] == null) { list[36] = ""; } //36
  576. if (list[36] == null) { list[37] = ""; } //37
  577. POItemShell item = new POItemShell()
  578. {
  579. ID = Guid.Parse(list[0].ToString()),
  580. PONumber = list[1].ToString(),
  581. ConsignmentNumber = "Cons: " + list[2].ToString(),
  582. JobName = list[3].ToString(),
  583. JobNumber = list[4].ToString(),
  584. Description = list[5].ToString(),
  585. ConsignmentID = Guid.Parse(list[7].ToString()),
  586. POID = Guid.Parse(list[8].ToString()),
  587. //FormCompleted = DateTime.Parse(list[10].ToString()),
  588. ReceivedDate = DateTime.Parse(list[9].ToString()),
  589. JobID = Guid.Parse(list[10].ToString()),
  590. SupplierCode = list[11].ToString(),
  591. ProductID = Guid.Parse(list[12].ToString()),
  592. Nonstock = Boolean.Parse(list[13].ToString()),
  593. StyleID = Guid.Parse(list[14].ToString()),
  594. StyleCode = list[15].ToString(),
  595. StyleDescription = list[16].ToString(),
  596. StockLocationID = Guid.Parse(list[17].ToString()),
  597. StockLocationDescription = list[18].ToString(),
  598. StockLocationCode = list[19].ToString(),
  599. DimensionsUnitID = Guid.Parse(list[20].ToString()),
  600. DimensionsQuantity = double.Parse(list[21].ToString()),
  601. DimensionsLength = double.Parse(list[22].ToString()),
  602. DimensionsWidth = double.Parse(list[23].ToString()),
  603. DimensionsHeight = double.Parse(list[24].ToString()),
  604. DimensionsWeight = double.Parse(list[25].ToString()),
  605. DimensionsValue = double.Parse(list[26].ToString()),
  606. DimensionsUnitSize = list[27].ToString(),
  607. Cost = double.Parse(list[28].ToString()),
  608. DimensionsHasHeight = bool.Parse(list[29].ToString()),
  609. DimensionsHasLength = bool.Parse(list[30].ToString()),
  610. DimensionsHasWidth = bool.Parse(list[31].ToString()),
  611. DimensionsHasWeight = bool.Parse(list[32].ToString()),
  612. DimensionsHasQuantity = bool.Parse(list[33].ToString()),
  613. DimensionsUnitFormula = list[34].ToString(),
  614. DimensionsUnitFormat = list[35].ToString(),
  615. DimensionsUnitCode = list[36].ToString(),
  616. DimensionsUnitDescription = list[37].ToString(),
  617. };
  618. if (double.TryParse(list[6].ToString(), out double result))
  619. item.ExpectedQty = result;
  620. poItemShells.Add(item);
  621. }
  622. LoadProductImages();
  623. Device.BeginInvokeOnMainThread(() =>
  624. {
  625. poItemListView.ItemsSource = poItemShells;
  626. poItemCountLbl.Text = "Items Unreceived: " + poItemShells.Count;
  627. });
  628. }
  629. }
  630. catch (Exception ex)
  631. {
  632. Device.BeginInvokeOnMainThread(() => { DisplayAlert("Error loading Purchase Order items - please try again", ex.Message, "OK"); });
  633. }
  634. });
  635. }
  636. private void LoadProductImages()
  637. {
  638. Task.Run(() =>
  639. {
  640. foreach (POItemShell shell in poItemShells)
  641. {
  642. if (shell.ProductID != Guid.Empty)
  643. {
  644. CoreTable table = new Client<Product>().Query
  645. (
  646. new Filter<Product>(x => x.ID).IsEqualTo(shell.ProductID).And(x => x.Image.ID).IsNotEqualTo(Guid.Empty),
  647. new Columns<Product>(x => x.Image.ID)
  648. );
  649. CoreTable table1 = new Client<Document>().Query
  650. (
  651. new Filter<Document>(x => x.ID).IsEqualTo(Guid.Parse(table.Rows.First().Values[0].ToString())),
  652. new Columns<Document>(x => x.Data)
  653. );
  654. CoreRow docrow = table1.Rows.FirstOrDefault();
  655. if (docrow != null)
  656. {
  657. byte[] data = docrow.Get<Document, byte[]>(x => x.Data);
  658. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  659. if (src != null)
  660. {
  661. shell.ImageSource = src;
  662. shell.ImageVisible = true;
  663. if (deviceType == "Tablet")
  664. {
  665. shell.LastRowHeight = 300;
  666. }
  667. else
  668. {
  669. shell.LastRowHeight = 150;
  670. }
  671. Device.BeginInvokeOnMainThread(() =>
  672. {
  673. poItemListView.ItemsSource = null;
  674. poItemListView.ItemsSource = poItemShells;
  675. });
  676. }
  677. }
  678. }
  679. }
  680. });
  681. }
  682. private async Task CreateNewConsignment()
  683. {
  684. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Creating new consignment"))
  685. {
  686. try
  687. {
  688. Consignment newConsignment = new Consignment() { };
  689. string name = "Unknown Supplier";
  690. if (supplierID != Guid.Empty)
  691. {
  692. newConsignment.Supplier.ID = supplierID;
  693. CoreTable supplierNameTable = new Client<Supplier>().Query(
  694. new Filter<Supplier>(x => x.ID).IsEqualTo(supplierID),
  695. new Columns<Supplier>(x => x.Name)
  696. );
  697. name = supplierNameTable.Rows.FirstOrDefault().Values[0].ToString();
  698. }
  699. newConsignment.Description = "Consignment for receival of items from " + name + ". Auto generated from mobile app by " + GlobalVariables.EmpName;
  700. CoreTable consignmentNumberTable = new Client<Consignment>().Query(
  701. new Filter<Consignment>(x => x.Number).Contains("APP").And(x => x.Created).IsGreaterThan(DateTime.Today.AddDays(-60)),
  702. new Columns<Consignment>(x => x.Number, x => x.Created),
  703. new SortOrder<Consignment>(x => x.Created));
  704. if (consignmentNumberTable.Rows.Any())
  705. {
  706. SetConsignmentNumber(newConsignment, consignmentNumberTable);
  707. }
  708. else
  709. {
  710. CoreTable consignmentNumberTable2 = new Client<Consignment>().Query(
  711. new Filter<Consignment>(x => x.Number).Contains("APP"),
  712. new Columns<Consignment>(x => x.Number, x => x.Created),
  713. new SortOrder<Consignment>(x => x.Created));
  714. if (consignmentNumberTable2.Rows.Any())
  715. {
  716. SetConsignmentNumber(newConsignment, consignmentNumberTable2);
  717. }
  718. else
  719. newConsignment.Number = "APP1" + " From PO: " + PONumber;
  720. }
  721. new Client<Consignment>().Save(newConsignment, "Updated from mobile device");
  722. consignmentID = newConsignment.ID;
  723. saveBtn.IsVisible = true;
  724. consignmentNumber = newConsignment.Number;
  725. consignmentNumberLbl.Text = "Consignment: " + newConsignment.Number;
  726. if (consignmentID == Guid.Empty)
  727. {
  728. DisplayAlert("Error", "Unable to create new consignment", "OK");
  729. Navigation.PopAsync();
  730. }
  731. }
  732. catch { }
  733. }
  734. }
  735. private Consignment SetConsignmentNumber(Consignment newConsignment, CoreTable table)
  736. {
  737. List<int> numbers = new List<int>();
  738. foreach (CoreRow row in table.Rows)
  739. {
  740. string number = row.Values[0].ToString();
  741. if (number.Contains(" From PO"))
  742. {
  743. int index = number.IndexOf(" From PO");
  744. string firstSubstring = number.Substring(0, index);
  745. string secondSubString = firstSubstring.Substring(3, firstSubstring.Length - 3);
  746. try
  747. {
  748. int i = int.Parse(secondSubString);
  749. numbers.Add(i);
  750. }
  751. catch { }
  752. }
  753. }
  754. numbers.Sort();
  755. int lastInt = numbers.Last();
  756. lastInt++;
  757. newConsignment.Number = "APP" + lastInt.ToString() + " From PO" + PONumber;
  758. return newConsignment;
  759. }
  760. Columns<PurchaseOrderItem> columns = new Columns<PurchaseOrderItem>(x => x.ID, //0
  761. x => x.PurchaseOrderLink.PONumber, //1
  762. x => x.Consignment.Number, //2
  763. x => x.Job.Name, //3
  764. x => x.Job.JobNumber, //4
  765. x => x.Description, //5
  766. x => x.Qty, //6
  767. x => x.Consignment.ID, //7
  768. x => x.PurchaseOrderLink.ID, //8
  769. x => x.ReceivedDate, //9
  770. x => x.Job.ID, //10
  771. x => x.SupplierCode, //11
  772. x => x.Product.ID, //12
  773. x => x.Product.NonStock, //13
  774. x => x.Style.ID, //14
  775. x => x.Style.Code, //15
  776. x => x.Style.Description, //16
  777. x => x.Product.DefaultLocation.ID, //17
  778. x => x.Product.DefaultLocation.Description, //18
  779. x => x.Product.DefaultLocation.Code, //19
  780. x => x.Dimensions.Unit.ID, //20
  781. x => x.Dimensions.Quantity, //21
  782. x => x.Dimensions.Length, //22
  783. x => x.Dimensions.Width, //23
  784. x => x.Dimensions.Height, //24
  785. x => x.Dimensions.Weight, //25
  786. x => x.Dimensions.Value, //26
  787. x => x.Dimensions.UnitSize, //27
  788. x => x.Cost, //28
  789. x => x.Dimensions.Unit.HasHeight, //29
  790. x => x.Dimensions.Unit.HasLength, //30
  791. x => x.Dimensions.Unit.HasWidth, //31
  792. x => x.Dimensions.Unit.HasWeight, //32
  793. x => x.Dimensions.Unit.HasQuantity, //33
  794. x => x.Dimensions.Unit.Formula, //34
  795. x => x.Dimensions.Unit.Format, //35
  796. x => x.Dimensions.Unit.Code, //36
  797. x => x.Dimensions.Unit.Description //37
  798. );
  799. }
  800. #endregion
  801. }
  802. #region Classes
  803. public class POItemShell
  804. {
  805. public Guid ID { get; set; }
  806. public string PONumber { get; set; }
  807. public string ConsignmentNumber { get; set; }
  808. public string Description { get; set; }
  809. public Guid ConsignmentID { get; set; }
  810. public Guid POID { get; set; }
  811. public double ExpectedQty { get; set; }
  812. public Color Color { get; set; }
  813. public double ReceivedQty { get; set; }
  814. public bool HasQAForm { get; set; }
  815. public bool IsReadyForQA { get; set; }
  816. public Color QATextColor { get; set; }
  817. public Color QABtnColor { get; set; }
  818. public Guid DigitalFormID { get; set; }
  819. public DateTime FormCompleted { get; set; }
  820. public DateTime ReceivedDate { get; set; }
  821. public string SupplierCode { get; set; }
  822. public Guid ProductID { get; set; }
  823. public bool Nonstock { get; set; }
  824. public Guid JobID { get; set; }
  825. public string JobName { get; set; }
  826. public string JobNumber { get; set; }
  827. public Guid StyleID { get; set; }
  828. public string StyleCode { get; set; }
  829. public string StyleDescription { get; set; }
  830. public Guid StockLocationID { get; set; }
  831. public string StockLocationDescription { get; set; }
  832. public string StockLocationCode { get; set; }
  833. public bool ImageVisible { get; set; }
  834. public ImageSource ImageSource { get; set; }
  835. public double LastRowHeight { get; set; }
  836. public double Cost { get; set; }
  837. public Guid DimensionsUnitID { get; set; }
  838. public double DimensionsQuantity { get; set; }
  839. public double DimensionsLength { get; set; }
  840. public double DimensionsWidth { get; set; }
  841. public double DimensionsHeight { get; set; }
  842. public double DimensionsWeight { get; set; }
  843. public double DimensionsValue { get; set; }
  844. public string DimensionsUnitSize { get; set; }
  845. public bool DimensionsHasHeight { get; set; }
  846. public bool DimensionsHasLength { get; set; }
  847. public bool DimensionsHasWidth { get; set; }
  848. public bool DimensionsHasWeight { get; set; }
  849. public bool DimensionsHasQuantity { get; set; }
  850. public string DimensionsUnitFormula { get; set; }
  851. public string DimensionsUnitFormat { get; set; }
  852. public string DimensionsUnitCode { get; set; }
  853. public string DimensionsUnitDescription { get; set; }
  854. public POItemShell()
  855. {
  856. ID = Guid.Empty;
  857. PONumber = string.Empty;
  858. ConsignmentNumber = string.Empty;
  859. JobID = Guid.Empty;
  860. JobName = string.Empty;
  861. JobNumber = string.Empty;
  862. Description = string.Empty;
  863. ConsignmentID = Guid.Empty;
  864. POID = Guid.Empty;
  865. ExpectedQty = 0;
  866. Color = Color.Default;
  867. ReceivedQty = 0;
  868. HasQAForm = false;
  869. IsReadyForQA = false;
  870. QATextColor = Color.LightGray;
  871. DigitalFormID = Guid.Empty;
  872. FormCompleted = DateTime.MinValue;
  873. ReceivedDate = DateTime.MinValue;
  874. SupplierCode = string.Empty;
  875. ProductID = Guid.Empty;
  876. Nonstock = false;
  877. StyleID = Guid.Empty;
  878. StyleCode = string.Empty;
  879. StyleDescription = string.Empty;
  880. StockLocationID = Guid.Empty;
  881. StockLocationCode = "";
  882. StockLocationDescription = "";
  883. ImageVisible = false;
  884. ImageSource = "";
  885. LastRowHeight = 0;
  886. DimensionsUnitID = Guid.Empty;
  887. DimensionsQuantity = 0;
  888. DimensionsLength = 0;
  889. DimensionsWidth = 0;
  890. DimensionsHeight = 0;
  891. DimensionsWeight = 0;
  892. DimensionsValue = 0;
  893. DimensionsUnitSize = "";
  894. Cost = 0.0;
  895. DimensionsHasHeight = false;
  896. DimensionsHasLength = false;
  897. DimensionsHasWidth = false;
  898. DimensionsHasWeight = false;
  899. DimensionsHasQuantity = false;
  900. DimensionsUnitFormula = "";
  901. DimensionsUnitFormat = "";
  902. DimensionsUnitCode = "";
  903. DimensionsUnitDescription = "";
  904. }
  905. public POItemShell DuplicateNewShell(POItemShell poitemshell)
  906. {
  907. POItemShell shell = new POItemShell
  908. {
  909. ID = poitemshell.ID,
  910. PONumber = poitemshell.PONumber,
  911. ConsignmentNumber = poitemshell.ConsignmentNumber,
  912. JobID = poitemshell.JobID,
  913. JobName = poitemshell.JobName,
  914. JobNumber = poitemshell.JobNumber,
  915. Description = poitemshell.Description,
  916. ConsignmentID = poitemshell.ConsignmentID,
  917. POID = poitemshell.POID,
  918. ExpectedQty = poitemshell.ExpectedQty,
  919. Color = poitemshell.Color,
  920. ReceivedQty = poitemshell.ReceivedQty,
  921. HasQAForm = poitemshell.HasQAForm,
  922. IsReadyForQA = poitemshell.IsReadyForQA,
  923. QATextColor = poitemshell.QATextColor,
  924. QABtnColor = poitemshell.QABtnColor,
  925. DigitalFormID = poitemshell.DigitalFormID,
  926. FormCompleted = poitemshell.FormCompleted,
  927. ReceivedDate = poitemshell.ReceivedDate,
  928. SupplierCode = poitemshell.SupplierCode,
  929. ProductID = poitemshell.ProductID,
  930. Nonstock = poitemshell.Nonstock,
  931. StyleID = poitemshell.StyleID,
  932. StyleCode = poitemshell.StyleCode,
  933. StyleDescription = poitemshell.StyleDescription,
  934. StockLocationID = poitemshell.StockLocationID,
  935. StockLocationCode = poitemshell.StockLocationCode,
  936. StockLocationDescription = poitemshell.StockLocationDescription,
  937. ImageVisible = poitemshell.ImageVisible,
  938. ImageSource = poitemshell.ImageSource,
  939. LastRowHeight = poitemshell.LastRowHeight,
  940. DimensionsUnitID = poitemshell.DimensionsUnitID,
  941. DimensionsQuantity = poitemshell.DimensionsQuantity,
  942. DimensionsLength = poitemshell.DimensionsLength,
  943. DimensionsWidth = poitemshell.DimensionsWidth,
  944. DimensionsHeight = poitemshell.DimensionsHeight,
  945. DimensionsWeight = poitemshell.DimensionsWeight,
  946. DimensionsValue = poitemshell.DimensionsValue,
  947. DimensionsUnitSize = poitemshell.DimensionsUnitSize,
  948. Cost = poitemshell.Cost,
  949. DimensionsHasHeight = poitemshell.DimensionsHasHeight,
  950. DimensionsHasLength = poitemshell.DimensionsHasLength,
  951. DimensionsHasWidth = poitemshell.DimensionsHasWidth,
  952. DimensionsHasWeight = poitemshell.DimensionsHasWeight,
  953. DimensionsHasQuantity = poitemshell.DimensionsHasQuantity,
  954. DimensionsUnitFormula = poitemshell.DimensionsUnitFormula,
  955. DimensionsUnitFormat = poitemshell.DimensionsUnitFormat,
  956. DimensionsUnitCode = poitemshell.DimensionsUnitCode,
  957. DimensionsUnitDescription = poitemshell.DimensionsUnitDescription
  958. };
  959. return shell;
  960. }
  961. }
  962. #endregion