WarehouseSelectionPage.xaml.cs 22 KB

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