WarehouseSelectionPage.xaml.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using Comal.Classes;
  6. using InABox.Clients;
  7. using InABox.Core;
  8. using Xamarin.Forms;
  9. using XF.Material.Forms.UI;
  10. using XF.Material.Forms.UI.Dialogs;
  11. using System.Threading.Tasks;
  12. namespace PRS.Mobile
  13. {
  14. public delegate void ExitWarehousingSelectedEvent();
  15. public partial class WarehouseSelectionPage
  16. {
  17. public event ExitWarehousingSelectedEvent OnExitSelected;
  18. #region Fields
  19. List<ProductShell> productShells = new List<ProductShell>();
  20. bool productsLoaded = false;
  21. bool loadedFromProducts = false;
  22. ScannerPage _scannerpage = null;
  23. Guid _warehouseid = Guid.Empty;
  24. String _warehousename = "Select Warehouse";
  25. Guid _areaid = Guid.Empty;
  26. String _areaname = "Select Area";
  27. Guid _locationid = Guid.Empty;
  28. String _locationname = "Select Location";
  29. bool _istransient = false;
  30. StockHoldingPage _holdingpage = null;
  31. Job job = new Job();
  32. #endregion
  33. #region Constructors
  34. public WarehouseSelectionPage() //(Employee employee)
  35. {
  36. InitializeComponent();
  37. AddToolbarItems();
  38. }
  39. public WarehouseSelectionPage(string locationCode) //For loading from Products Module
  40. {
  41. loadedFromProducts = true;
  42. InitializeComponent();
  43. AddToolbarItems();
  44. LoadFromProductsModule(locationCode);
  45. UpdateScreen();
  46. }
  47. private void AddToolbarItems()
  48. {
  49. Title = "Warehousing";
  50. NavigationPage.SetHasBackButton(this, false);
  51. ToolbarItems.Clear();
  52. ToolbarItems.Add(new ToolbarItem("Exit", "", () =>
  53. {
  54. OnExitSelected?.Invoke();
  55. Navigation.PopAsync();
  56. }));
  57. ToolbarItems.Add(new ToolbarItem("Back", "", () =>
  58. {
  59. Navigation.PopAsync();
  60. }));
  61. }
  62. #endregion
  63. #region OnAppearing and Update Screen
  64. protected override void OnAppearing()
  65. {
  66. base.OnAppearing();
  67. if (_scannerpage != null)
  68. _scannerpage = null;
  69. if (_holdingpage != null)
  70. _holdingpage = null;
  71. UpdateScreen();
  72. }
  73. private void UpdateScreen()
  74. {
  75. Warehouse.Text = _warehousename;
  76. Warehouse.SetValue(Grid.ColumnSpanProperty, _warehouseid == Guid.Empty ? 3 : 2);
  77. Warehouse.Margin = new Thickness(10, 10, _warehouseid == Guid.Empty ? 5 : 0, 0);
  78. Warehouse_Clear.IsVisible = _warehouseid != Guid.Empty;
  79. Warehouse_Clear.Margin = new Thickness(0, 10, 5, 0);
  80. Area.Text = _areaname;
  81. Area.SetValue(Grid.ColumnSpanProperty, _areaid == Guid.Empty ? 3 : 2);
  82. Area.Margin = new Thickness(10, 0, _areaid == Guid.Empty ? 5 : 0, 0);
  83. Area_Clear.IsVisible = _areaid != Guid.Empty;
  84. Area_Clear.Margin = new Thickness(0, 0, 5, 0);
  85. Location_New.IsVisible = (_areaid != Guid.Empty) && (_locationid == Guid.Empty);
  86. Location_New.Margin = new Thickness(10, 0, 0, 0);
  87. Location.Text = _locationname;
  88. Location.SetValue(Grid.ColumnProperty, (_areaid != Guid.Empty) && (_locationid == Guid.Empty) ? 1 : 0);
  89. Location.SetValue(Grid.ColumnSpanProperty, _locationid != Guid.Empty ? 2 : _areaid != Guid.Empty ? 2 : 3);
  90. Location.Margin = new Thickness(Location_New.IsVisible ? 0 : 10, 0, _locationid == Guid.Empty ? 5 : 0, 0);
  91. Location_Clear.IsVisible = _locationid != Guid.Empty;
  92. Location_Clear.Margin = new Thickness(0, 0, 5, 0);
  93. ReceiveGrid.Opacity = _locationid != Guid.Empty ? 1.0F : 0.3F;
  94. IssueGrid.Opacity = _locationid != Guid.Empty ? 1.0F : 0.3F;
  95. MoveGrid.Opacity = _locationid != Guid.Empty ? 1.0F : 0.3F;
  96. TransferGrid.Opacity = _locationid != Guid.Empty ? 1.0F : 0.3F;
  97. StocktakeGrid.Opacity = _locationid != Guid.Empty ? 1.0F : 0.3F;
  98. }
  99. void LoadFromProductsModule(string locationCode)
  100. {
  101. CoreTable table = new Client<StockLocation>().Query(
  102. new Filter<StockLocation>(x => x.Code).IsEqualTo(locationCode),
  103. new Columns<StockLocation>(
  104. x => x.ID,
  105. x => x.Description,
  106. x => x.Area.Warehouse.ID,
  107. x => x.Area.Warehouse.Description,
  108. x => x.Area.ID,
  109. x => x.Area.Description
  110. ),
  111. null
  112. );
  113. if (table.Rows.Any())
  114. {
  115. CoreRow row = table.Rows.FirstOrDefault();
  116. StockLocation location = row.ToObject<StockLocation>();
  117. _warehouseid = location.Area.Warehouse.ID;
  118. _warehousename = location.Area.Warehouse.Description;
  119. _areaid = location.Area.ID;
  120. _areaname = location.Area.Description;
  121. _locationid = location.ID;
  122. _locationname = location.Description;
  123. }
  124. }
  125. #endregion
  126. #region Warehouse/Area/Location buttons clicked
  127. void Warehouse_Clicked(System.Object sender, System.EventArgs e)
  128. {
  129. GenericSelectionPage page = new GenericSelectionPage(
  130. "Select Warehouse",
  131. new SelectionViewModel<StockWarehouse>(
  132. new Filter<StockWarehouse>(X => X.Active).IsEqualTo(true),
  133. new Expression<Func<StockWarehouse, object>>[] { X => X.Description },
  134. new Expression<Func<StockWarehouse, object>>[] { },
  135. new SortOrder<StockWarehouse>(x => x.Description)
  136. )
  137. );
  138. page.OnItemSelected += (o,e) =>
  139. {
  140. var warehouse = e.Row.ToObject<StockWarehouse>();
  141. if (_warehouseid != warehouse.ID)
  142. {
  143. _warehouseid = warehouse.ID;
  144. _warehousename = warehouse.Description;
  145. _areaid = Guid.Empty;
  146. _areaname = "Select Area";
  147. _locationid = Guid.Empty;
  148. _locationname = "Select Location";
  149. }
  150. };
  151. Navigation.PushAsync(page);
  152. }
  153. void Area_Clicked(System.Object sender, System.EventArgs e)
  154. {
  155. Filter<StockArea> areafilter = new Filter<StockArea>(X => X.Active).IsEqualTo(true);
  156. if (_warehouseid != Guid.Empty)
  157. areafilter = areafilter.And(x => x.Warehouse.ID).IsEqualTo(_warehouseid);
  158. GenericSelectionPage page = new GenericSelectionPage(
  159. "Select Area",
  160. new SelectionViewModel<StockArea>(
  161. areafilter,
  162. new Expression<Func<StockArea, object>>[] { X => X.Description },
  163. new Expression<Func<StockArea, object>>[] { x => x.Warehouse.ID, x => x.Warehouse.Description },
  164. new SortOrder<StockArea>(x => x.Description)
  165. )
  166. );
  167. page.OnItemSelected += (o,e) =>
  168. {
  169. var area = e.Row.ToObject<StockArea>();
  170. if (_areaid != area.ID)
  171. {
  172. _warehouseid = area.Warehouse.ID;
  173. _warehousename = area.Warehouse.Description;
  174. _areaid = area.ID;
  175. _areaname = area.Description;
  176. _locationid = Guid.Empty;
  177. _locationname = "Select Location";
  178. }
  179. };
  180. Navigation.PushAsync(page);
  181. }
  182. void Location_Clicked(System.Object sender, System.EventArgs e)
  183. {
  184. Filter<StockLocation> filter = new Filter<StockLocation>(X => X.Active).IsEqualTo(true);
  185. if (_warehouseid != Guid.Empty)
  186. filter = filter.And(x => x.Warehouse.ID).IsEqualTo(_warehouseid);
  187. if (_areaid != Guid.Empty)
  188. filter = filter.And(x => x.Area.ID).IsEqualTo(_areaid);
  189. GenericSelectionPage page = new GenericSelectionPage(
  190. "Select Location",
  191. new SelectionViewModel<StockLocation>(
  192. filter,
  193. new Expression<Func<StockLocation, object>>[] { x => x.Code, X => X.Description },
  194. new Expression<Func<StockLocation, object>>[] { x => x.Area.Warehouse.ID, x => x.Area.Warehouse.Description, x => x.Area.ID, x => x.Area.Description,
  195. x => x.Job.ID, x => x.Job.JobNumber, x => x.Job.Name},
  196. new SortOrder<StockLocation>(x => x.Description)
  197. )
  198. );
  199. page.OnItemSelected += (o,e) =>
  200. {
  201. var location = e.Row.ToObject<StockLocation>();
  202. if (_locationid != location.ID)
  203. {
  204. _warehouseid = location.Area.Warehouse.ID;
  205. _warehousename = location.Area.Warehouse.Description;
  206. _areaid = location.Area.ID;
  207. _areaname = location.Area.Description;
  208. _locationid = location.ID;
  209. _locationname = location.Description;
  210. job.ID = location.Job.ID;
  211. job.JobNumber = location.Job.JobNumber;
  212. job.Name = location.Job.Name;
  213. }
  214. };
  215. Navigation.PushAsync(page);
  216. }
  217. #endregion
  218. #region Scanner
  219. void Scan_Clicked(System.Object sender, System.EventArgs e)
  220. {
  221. _scannerpage = new ScannerPage();
  222. _scannerpage.ItemScanned = async (args) => OnScan(args);
  223. Navigation.PushModalAsync(_scannerpage);
  224. }
  225. private async void OnScan(ScannerPageItemScannedArgs args)
  226. {
  227. if (Guid.TryParse(args.Text, out Guid id))
  228. {
  229. CoreTable result = new Client<StockLocation>().Query(
  230. new Filter<StockLocation>(X => X.ID).IsEqualTo(id),
  231. new Columns<StockLocation>(
  232. x => x.Warehouse.ID,
  233. X => X.Warehouse.Description,
  234. X => X.Area.ID,
  235. X => X.Area.Description,
  236. x => x.ID,
  237. X => X.Description,
  238. x => x.Type
  239. )
  240. );
  241. if (result.Rows.Any())
  242. {
  243. CoreRow r = result.Rows.First();
  244. _warehouseid = r.Get<StockLocation, Guid>(c => c.Warehouse.ID);
  245. _warehousename = r.Get<StockLocation, String>(c => c.Warehouse.Description);
  246. _areaid = r.Get<StockLocation, Guid>(c => c.Area.ID);
  247. _areaname = r.Get<StockLocation, String>(c => c.Area.Description);
  248. _locationid = r.Get<StockLocation, Guid>(c => c.ID);
  249. _locationname = r.Get<StockLocation, String>(c => c.Description);
  250. _istransient = r.Get<StockLocation, StockLocationType>(x => x.Type) == StockLocationType.Transient;
  251. }
  252. }
  253. }
  254. #endregion
  255. #region Holding Page Load Types
  256. async void LoadHoldingPage(StockMovementBatchType type)
  257. {
  258. if (_locationid == Guid.Empty)
  259. return;
  260. var progress = await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading Stock Holding");
  261. _holdingpage = new StockHoldingPage(_locationid, _locationname, _istransient, type, job);
  262. await progress.DismissAsync();
  263. await Navigation.PushAsync(_holdingpage);
  264. }
  265. async void ReceiveTapped(System.Object sender, System.EventArgs e)
  266. {
  267. LoadHoldingPage(StockMovementBatchType.Receipt);
  268. }
  269. async void StockTakeTapped(System.Object sender, System.EventArgs e)
  270. {
  271. LoadHoldingPage(StockMovementBatchType.Stocktake);
  272. }
  273. async void IssueTapped(System.Object sender, System.EventArgs e)
  274. {
  275. LoadHoldingPage(StockMovementBatchType.Issue);
  276. }
  277. async void TransferTapped(System.Object sender, System.EventArgs e)
  278. {
  279. LoadHoldingPage(StockMovementBatchType.Transfer);
  280. }
  281. #endregion
  282. #region Warehouse/Area/Location Clear buttons
  283. void Warehouse_Clear_Clicked(System.Object sender, System.EventArgs e)
  284. {
  285. _warehouseid = Guid.Empty;
  286. _warehousename = "Select Warehouse";
  287. _areaid = Guid.Empty;
  288. _areaname = "Select Area";
  289. _locationid = Guid.Empty;
  290. _locationname = "Select Location";
  291. UpdateScreen();
  292. }
  293. void Area_Clear_Clicked(System.Object sender, System.EventArgs e)
  294. {
  295. _areaid = Guid.Empty;
  296. _areaname = "Select Area";
  297. _locationid = Guid.Empty;
  298. _locationname = "Select Location";
  299. UpdateScreen();
  300. }
  301. void Location_Clear_Clicked(System.Object sender, System.EventArgs e)
  302. {
  303. _locationid = Guid.Empty;
  304. _locationname = "Select Location";
  305. UpdateScreen();
  306. }
  307. #endregion
  308. #region Change/new Stock Location
  309. void NewLocationClicked(System.Object sender, System.EventArgs e)
  310. {
  311. StockLocation location = new StockLocation();
  312. location.Active = true;
  313. location.Warehouse.ID = _warehouseid;
  314. location.Warehouse.Description = _warehousename;
  315. location.Area.Warehouse.ID = _warehouseid;
  316. location.Area.Warehouse.Description = _warehousename;
  317. location.Area.ID = _areaid;
  318. location.Area.Description = _areaname;
  319. LocationDetailsPage page = new LocationDetailsPage(location);
  320. page.OnSave += (o, loc) =>
  321. {
  322. if (String.IsNullOrWhiteSpace(loc.Code))
  323. {
  324. MaterialDialog.Instance.AlertAsync(message: "Code may not be blank!");
  325. return false;
  326. }
  327. if (String.IsNullOrWhiteSpace(loc.Description))
  328. {
  329. MaterialDialog.Instance.AlertAsync(message: "Description may not be blank!");
  330. return false;
  331. }
  332. if (loc.Area.ID == Guid.Empty)
  333. {
  334. MaterialDialog.Instance.AlertAsync(message: "Area may not be blank!");
  335. return false;
  336. }
  337. CoreTable others = new Client<StockLocation>().Query(
  338. new Filter<StockLocation>(x => x.Code).IsEqualTo(loc.Code).And(x => x.ID).IsNotEqualTo(loc.ID),
  339. new Columns<StockLocation>(x => x.ID)
  340. );
  341. if (others.Rows.Any())
  342. {
  343. MaterialDialog.Instance.AlertAsync(message: "Location Code already exists!");
  344. return false;
  345. }
  346. try
  347. {
  348. new Client<StockLocation>().Save(loc, "Created Location");
  349. }
  350. catch (Exception err)
  351. {
  352. MaterialDialog.Instance.AlertAsync(message: "Unable to save Location\n" + err.Message);
  353. return false;
  354. }
  355. _warehouseid = loc.Area.Warehouse.ID;
  356. _warehousename = loc.Area.Warehouse.Description;
  357. _areaid = loc.Area.ID;
  358. _areaname = loc.Area.Description;
  359. _locationid = loc.ID;
  360. _locationname = loc.Description;
  361. try
  362. {
  363. job.ID = loc.Job.ID;
  364. job.JobNumber = loc.Job.JobNumber;
  365. job.Name = loc.Job.Name;
  366. }
  367. catch { }
  368. return true;
  369. };
  370. Navigation.PushAsync(page);
  371. }
  372. void MoveLocation(System.Object sender, System.EventArgs e)
  373. {
  374. if (_locationid == Guid.Empty)
  375. return;
  376. Filter<StockArea> areafilter = new Filter<StockArea>(X => X.Active).IsEqualTo(true);
  377. GenericSelectionPage page = new GenericSelectionPage(
  378. "Move Stock Location to:",
  379. new SelectionViewModel<StockArea>(
  380. areafilter,
  381. new Expression<Func<StockArea, object>>[] { X => X.Description },
  382. new Expression<Func<StockArea, object>>[] { x => x.Warehouse.ID, x => x.Warehouse.Description },
  383. new SortOrder<StockArea>(x => x.Description)
  384. )
  385. );
  386. page.OnItemSelected += async (o,e) =>
  387. {
  388. var area = e.Row.ToObject<StockArea>();
  389. if (_areaid != area.ID)
  390. {
  391. string chosenOption = await DisplayActionSheet("Change this Location Area?", "Cancel", null, "Yes", "No");
  392. switch (chosenOption)
  393. {
  394. case "No":
  395. break;
  396. case "Cancel":
  397. break;
  398. case "Yes":
  399. StockLocation location = new StockLocation();
  400. location.ID = _locationid;
  401. location.Area.ID = area.ID;
  402. location.Warehouse.ID = area.Warehouse.ID;
  403. new Client<StockLocation>().Save(location, "Updated Stock Area", (o, err) => { });
  404. _warehouseid = area.Warehouse.ID;
  405. _warehousename = area.Warehouse.Description;
  406. _areaid = area.ID;
  407. _areaname = area.Description;
  408. UpdateScreen();
  409. break;
  410. default:
  411. break;
  412. }
  413. }
  414. };
  415. Navigation.PushAsync(page);
  416. }
  417. #endregion
  418. void Find_Clicked(object sender, EventArgs e)
  419. {
  420. if (loadedFromProducts)
  421. {
  422. Navigation.PopAsync();
  423. }
  424. else
  425. {
  426. if (App.Data.Products.Loaded)
  427. {
  428. ProductList2 products = new ProductList2();
  429. products.OnExitSelected += () =>
  430. {
  431. Navigation.PopAsync();
  432. };
  433. Navigation.PushAsync(products);
  434. }
  435. else
  436. {
  437. ProductList2 products = new ProductList2();
  438. products.OnExitSelected += () =>
  439. {
  440. Navigation.PopAsync();
  441. };
  442. Navigation.PushAsync(products);
  443. }
  444. }
  445. }
  446. //being replaced
  447. //void Find_Clicked(System.Object sender, System.EventArgs e)
  448. //{
  449. // GenericSelectionPage products = new GenericSelectionPage(
  450. // "Select Product",
  451. // new SelectionViewModel<Product>(
  452. // new Filter<Product>(X => X.Expired).IsEqualTo(DateTime.MinValue),
  453. // new Expression<Func<Product, object>>[] { X => X.Code, X => X.Name },
  454. // new Expression<Func<Product, object>>[] { },
  455. // new SortOrder<Product>(x => x.Code)
  456. // )
  457. // );
  458. // products.AutoClose = false;
  459. // products.OnItemSelected += (p) =>
  460. // {
  461. // var product = p.ToObject<Product>();
  462. // GenericSelectionPage holdings = new GenericSelectionPage(
  463. // "Select Stock Holding",
  464. // new SelectionViewModel<StockHolding>(
  465. // new Filter<StockHolding>(X => X.Product.ID).IsEqualTo(product.ID),
  466. // new Expression<Func<StockHolding, object>>[] { },
  467. // new Expression<Func<StockHolding, object>>[] {
  468. // X => X.Location.Area.Warehouse.ID,
  469. // x=>x.Location.Area.Warehouse.Code,
  470. // x=>x.Location.Area.Warehouse.Description,
  471. // x => x.Location.Area.ID,
  472. // x=>x.Location.Area.Code,
  473. // x=>x.Location.Area.Description,
  474. // x => x.Location.ID,
  475. // x=>x.Location.Code,
  476. // x=>x.Location.Description,
  477. // x=>x.Style.Code,
  478. // x=>x.Units
  479. // },
  480. // new SortOrder<StockHolding>(x => x.Location.Area.Warehouse.Code).ThenBy(x=>x.Location.Area.Code).ThenBy(x=>x.Location.Code),
  481. // (r) => String.Format("{0} {1}: {2} ({3} {4})",
  482. // r.Get<StockHolding, String>(x => x.Location.Area.Warehouse.Code),
  483. // r.Get<StockHolding, String>(x => x.Location.Area.Code),
  484. // r.Get<StockHolding, String>(x => x.Location.Code),
  485. // r.Get<StockHolding, double>(x => x.Units),
  486. // r.Get<StockHolding, String>(x => x.Style.Code)
  487. // )
  488. // )
  489. // );
  490. // holdings.OnItemSelected += (h) =>
  491. // {
  492. // var holding = h.ToObject<StockHolding>();
  493. // _warehouseid = holding.Location.Area.Warehouse.ID;
  494. // _warehousename = holding.Location.Area.Warehouse.Description;
  495. // _areaid = holding.Location.Area.ID;
  496. // _areaname = holding.Location.Area.Description;
  497. // _locationid = holding.Location.ID;
  498. // _locationname = holding.Location.Description;
  499. // // Close the Product Page as well :=)
  500. // Navigation.PopAsync();
  501. // };
  502. // Navigation.PushAsync(holdings);
  503. // };
  504. // Navigation.PushAsync(products);
  505. //}
  506. }
  507. }