StoreRequiConfirmationPage.xaml.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Xamarin.Essentials;
  7. using Xamarin.Forms;
  8. using ZXing;
  9. using ZXing;
  10. using Xamarin.Forms;
  11. using Xamarin.Forms.Xaml;
  12. using comal.timesheets.CustomControls;
  13. using Comal.Classes;
  14. using InABox.Core;
  15. using InABox.Clients;
  16. using System.Threading;
  17. using Plugin.Media;
  18. using XF.Material.Forms.UI.Dialogs;
  19. using System.IO;
  20. namespace comal.timesheets.StoreRequis
  21. {
  22. [XamlCompilation(XamlCompilationOptions.Compile)]
  23. public partial class StoreRequiConfirmationPage : ContentPage
  24. {
  25. #region Fields
  26. public delegate void SaveSelectedEvent();
  27. public event SaveSelectedEvent OnSaveSelected;
  28. JobShell job = new JobShell();
  29. bool newRequi;
  30. Requisition requisition;
  31. bool isNewRequest = false;
  32. Dictionary<Image, Document> imagesDocuments = new Dictionary<Image, Document>();
  33. List<StoreRequiItemShell> requiItems = new List<StoreRequiItemShell>();
  34. List<StoreRequiItemShell> oldrequiitems = new List<StoreRequiItemShell>();
  35. #endregion
  36. #region Constructor and appearing
  37. public StoreRequiConfirmationPage(Requisition _requisition, List<StoreRequiItemShell> _requiitems, List<StoreRequiItemShell> _oldrequiitems) //requi could be existing or a blank/new requi (ID empty)
  38. {
  39. InitializeComponent();
  40. requiItems = _requiitems;
  41. if (requiItems[0].IsNotes == true)
  42. {
  43. requiItems.RemoveAt(0);
  44. }
  45. oldrequiitems = _oldrequiitems;
  46. requiStatusLbl.IsVisible = true;
  47. requiStatusFrame.IsVisible = true;
  48. boxesLbl.IsVisible = true;
  49. boxesQtyFrame.IsVisible = true;
  50. photosLbl.IsVisible = true;
  51. photosFrame.IsVisible = true;
  52. if (_requisition.ID != Guid.Empty)
  53. forDeliveryRb.IsChecked = true;
  54. else
  55. takenNowRb.IsChecked = true;
  56. dueLbl.IsVisible = false;
  57. dueFrame.IsVisible = false;
  58. ChooseTrack(_requisition);
  59. }
  60. public StoreRequiConfirmationPage() //when no requi is passed, app is creating a new requi request
  61. {
  62. InitializeComponent();
  63. isNewRequest = true;
  64. NewRequiTrack();
  65. UpdateColours();
  66. notesTitleLbl.Text = "Request";
  67. dueDatePckr.IsEnabled = true;
  68. reduceQtyBtn.IsEnabled = false;
  69. increaseQtyBtn.IsEnabled = false;
  70. TakePhoto.IsEnabled = false;
  71. ChooseImage.IsEnabled = false;
  72. }
  73. private void ChooseTrack(Requisition _requisition)
  74. {
  75. if (_requisition.ID == Guid.Empty)
  76. {
  77. NewRequiTrack();
  78. }
  79. else
  80. {
  81. ExistingRequiTrack(_requisition);
  82. }
  83. }
  84. private void NewRequiTrack()
  85. {
  86. newRequi = true;
  87. requisition = new Requisition();
  88. requisition.Title = "New Requisition";
  89. requisition.Boxes = 1;
  90. boxQtyLbl.Text = requisition.Boxes.ToString();
  91. titleLbl.Text = "New Requisition";
  92. requisition.Title = "New Requisition";
  93. requisition.Due = DateTime.Now;
  94. requisition.RequestedBy.ID = GlobalVariables.EmpID;
  95. requisition.RequestedBy.Name = GlobalVariables.EmpName;
  96. //create new requi
  97. }
  98. private void ExistingRequiTrack(Requisition _requisition)
  99. {
  100. newRequi = false;
  101. requisition = _requisition;
  102. titleLbl.Text = "Requi " + _requisition.Number.ToString();
  103. LoadPhotos();
  104. UpdateScreen();
  105. }
  106. #endregion
  107. #region Screen Update
  108. private void UpdateScreen()
  109. {
  110. jobLbl.Text = requisition.JobLink.JobNumber + " " + requisition.JobLink.Name;
  111. boxQtyLbl.Text = requisition.Boxes.ToString();
  112. if (string.IsNullOrEmpty(notesEdt.Text))
  113. {
  114. List<string> notes = new List<string>();
  115. foreach (string s in requisition.Notes)
  116. {
  117. string substring = s.Replace("=", string.Empty);
  118. substring = substring.Trim();
  119. if (!string.IsNullOrWhiteSpace(substring))
  120. notes.Add(substring);
  121. }
  122. notesEdt.Text = String.Join("\n", notes);
  123. }
  124. UpdateColours();
  125. }
  126. private void UpdateColours()
  127. {
  128. if (requisition.JobLink.ID == Guid.Empty)
  129. jobFrame.BorderColor = Color.Red;
  130. else
  131. jobFrame.BorderColor = Color.Gray;
  132. if (images.Children.Count == 0)
  133. photosFrame.BorderColor = Color.Red;
  134. else
  135. photosFrame.BorderColor = Color.Gray;
  136. if (isNewRequest)
  137. photosFrame.BorderColor = Color.Gray;
  138. }
  139. private void LoadPhotos()
  140. {
  141. if (requisition.Documents != 0)
  142. {
  143. var table = new Client<RequisitionDocument>().Query(
  144. new Filter<RequisitionDocument>(x => x.EntityLink.ID).IsEqualTo(requisition.ID),
  145. new Columns<RequisitionDocument>(x => x.DocumentLink.ID),
  146. null
  147. );
  148. if (table.Rows.Count != 0)
  149. {
  150. foreach (var row in table.Rows)
  151. {
  152. List<object> list = row.Values;
  153. if (list[0] == null) { list[0] = Guid.Empty; }
  154. Guid requisitionDocLinkID = Guid.Parse(list[0].ToString());
  155. new Client<Document>().Query(
  156. new Filter<Document>(x => x.ID).IsEqualTo(requisitionDocLinkID),
  157. null,
  158. null,
  159. (t, e) =>
  160. {
  161. CoreRow docrow = t.Rows.FirstOrDefault();
  162. if (docrow != null)
  163. {
  164. byte[] data = docrow.Get<Document, byte[]>(x => x.Data);
  165. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  166. Image img = new Image();
  167. img.HeightRequest = 150;
  168. img.WidthRequest = 150;
  169. img.Aspect = Aspect.AspectFit;
  170. img.Source = src;
  171. img.GestureRecognizers.Add(new TapGestureRecognizer
  172. {
  173. Command = new Command(OnTap),
  174. CommandParameter = src,
  175. NumberOfTapsRequired = 1
  176. });
  177. Device.BeginInvokeOnMainThread(() =>
  178. {
  179. ImageScroller.IsVisible = true;
  180. images.Children.Add(img);
  181. UpdateColours();
  182. });
  183. }
  184. }
  185. );
  186. }
  187. }
  188. }
  189. }
  190. #endregion
  191. #region Selection
  192. private void SelectJobBtn_Clicked(object sender, EventArgs e)
  193. {
  194. JobSelectionPage jobSelectionPage = new JobSelectionPage();
  195. jobSelectionPage.OnItemSelected += (() =>
  196. {
  197. requisition.JobLink.ID = jobSelectionPage.Job.ID;
  198. requisition.JobLink.Name = jobSelectionPage.Job.Name;
  199. requisition.JobLink.JobNumber = jobSelectionPage.Job.JobNumber;
  200. UpdateScreen();
  201. });
  202. Navigation.PushAsync(jobSelectionPage);
  203. }
  204. private void ReduceQtyBtn_Clicked(object sender, EventArgs e)
  205. {
  206. if (requisition.Boxes <= 1)
  207. return;
  208. else
  209. {
  210. requisition.Boxes--;
  211. UpdateScreen();
  212. }
  213. }
  214. private void IncreaseQtyBtn_Clicked(object sender, EventArgs e)
  215. {
  216. requisition.Boxes++;
  217. UpdateScreen();
  218. }
  219. private void DueDatePckr_DateSelected(object sender, EventArgs e)
  220. {
  221. requisition.Due = dueDatePckr.Date;
  222. }
  223. #endregion
  224. #region Photos
  225. private void TakePhoto_Clicked(object sender, EventArgs e)
  226. {
  227. TakeAPhoto();
  228. }
  229. private void ChooseImage_Clicked(object sender, EventArgs e)
  230. {
  231. ChooseAPhoto();
  232. }
  233. private async void TakeAPhoto()
  234. {
  235. await CrossMedia.Current.Initialize();
  236. if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
  237. {
  238. await DisplayAlert("No Camera", ":( No camera available.", "OK");
  239. return;
  240. }
  241. String filename = String.Format("{0:yyyy-MM-dd HH:mm:ss.fff}.png", DateTime.Now);
  242. var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
  243. {
  244. Name = filename,
  245. CompressionQuality = 10,
  246. PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full
  247. });
  248. if (file == null)
  249. return;
  250. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo"))
  251. {
  252. Image img = null;
  253. var memoryStream = new MemoryStream();
  254. file.GetStream().CopyTo(memoryStream);
  255. var data = memoryStream.ToArray();
  256. Document doc = new Document()
  257. {
  258. FileName = filename,
  259. Data = data,
  260. CRC = CoreUtils.CalculateCRC(data),
  261. TimeStamp = DateTime.Now
  262. };
  263. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  264. img = new Image();
  265. img.HeightRequest = 150;
  266. img.WidthRequest = 150;
  267. img.Aspect = Aspect.AspectFit;
  268. img.Source = src;
  269. img.GestureRecognizers.Add(new TapGestureRecognizer
  270. {
  271. Command = new Command(OnTap),
  272. CommandParameter = src,
  273. NumberOfTapsRequired = 1
  274. });
  275. imagesDocuments.Add(img, doc);
  276. file.Dispose();
  277. if (img != null)
  278. {
  279. Device.BeginInvokeOnMainThread(() =>
  280. {
  281. ImageScroller.IsVisible = true;
  282. images.Children.Add(img);
  283. UpdateColours();
  284. });
  285. }
  286. }
  287. }
  288. private async void ChooseAPhoto()
  289. {
  290. await CrossMedia.Current.Initialize();
  291. if (!CrossMedia.Current.IsPickPhotoSupported)
  292. {
  293. await DisplayAlert("No Library", ":( No Photo Library available.", "OK");
  294. return;
  295. }
  296. var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions()
  297. {
  298. CompressionQuality = 10,
  299. PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full
  300. });
  301. if (file == null)
  302. return;
  303. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo"))
  304. {
  305. Image img = null;
  306. var memoryStream = new MemoryStream();
  307. file.GetStream().CopyTo(memoryStream);
  308. var data = memoryStream.ToArray();
  309. Document doc = new Document()
  310. {
  311. FileName = Path.GetFileName(file.Path),
  312. Data = data,
  313. CRC = CoreUtils.CalculateCRC(data),
  314. TimeStamp = DateTime.Now
  315. };
  316. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  317. img = new Image();
  318. img.HeightRequest = 150;
  319. img.WidthRequest = 150;
  320. img.Aspect = Aspect.AspectFit;
  321. img.Source = src;
  322. img.GestureRecognizers.Add(new TapGestureRecognizer
  323. {
  324. Command = new Command(OnTap),
  325. CommandParameter = src,
  326. NumberOfTapsRequired = 1
  327. });
  328. imagesDocuments.Add(img, doc);
  329. file.Dispose();
  330. if (img != null)
  331. {
  332. Device.BeginInvokeOnMainThread(() =>
  333. {
  334. ImageScroller.IsVisible = true;
  335. images.Children.Add(img);
  336. UpdateColours();
  337. });
  338. }
  339. }
  340. }
  341. private void OnTap(object obj)
  342. {
  343. ImageViewer viewer = new ImageViewer(obj as ImageSource);
  344. Navigation.PushAsync(viewer);
  345. viewer.ChooseDelete();
  346. viewer.OnDeleteSelected += () =>
  347. {
  348. Image img = imagesDocuments.Keys.First(x => x.Source.Equals(obj as ImageSource));
  349. imagesDocuments.Remove(img);
  350. Device.BeginInvokeOnMainThread(() =>
  351. {
  352. images.Children.Clear();
  353. if (imagesDocuments.Count > 0)
  354. {
  355. foreach (Image image in imagesDocuments.Keys)
  356. {
  357. images.Children.Add(image);
  358. }
  359. }
  360. UpdateColours();
  361. });
  362. };
  363. }
  364. #endregion
  365. #region Save
  366. private async void SaveBtn_Clicked(object sender, EventArgs e)
  367. {
  368. if (CheckSaveOk())
  369. {
  370. if (isNewRequest)
  371. {
  372. requisition.Request = notesEdt.Text;
  373. new Client<Requisition>().Save(requisition, "Created on Mobile Device");
  374. DisplayAlert("Success", "Requisition " + requisition.Number + " Created", "Ok");
  375. }
  376. else
  377. {
  378. if (takenNowRb.IsChecked)
  379. {
  380. requisition.TakenBy.ID = GlobalVariables.EmpID;
  381. requisition.TakenBy.Name = GlobalVariables.EmpName;
  382. }
  383. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving"))
  384. {
  385. SaveRequi();
  386. }
  387. if (requisition.ID != Guid.Empty)
  388. {
  389. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving"))
  390. {
  391. SavePhotos();
  392. SaveItems();
  393. }
  394. await DisplayAlert("Success", "Requisition " + requisition.Number + " Saved", "Ok");
  395. OnSaveSelected?.Invoke();
  396. Navigation.PopAsync();
  397. }
  398. }
  399. }
  400. }
  401. private void SaveRequi()
  402. {
  403. requisition.Filled = DateTime.Now;
  404. requisition.Notes = new string[] { notesEdt.Text };
  405. new Client<Requisition>().Save(requisition, "Saved requi on mobile device");
  406. }
  407. private async void SaveItems()
  408. {
  409. Task.Run(() =>
  410. {
  411. List<RequisitionItem> toDelete = new List<RequisitionItem>();
  412. if (oldrequiitems.Count > 0)
  413. {
  414. foreach (StoreRequiItemShell oldshell in oldrequiitems)
  415. {
  416. StoreRequiItemShell shell = requiItems.Find(x => x.ID.Equals(oldshell.ID));
  417. if (shell == null)
  418. {
  419. toDelete.Add(new RequisitionItem { ID = oldshell.ID });
  420. }
  421. }
  422. if (toDelete.Count > 0)
  423. {
  424. new Client<RequisitionItem>().Delete(toDelete, "Updated from mobile device");
  425. }
  426. }
  427. });
  428. List<RequisitionItem> toSave = new List<RequisitionItem>();
  429. foreach (StoreRequiItemShell itemShell in requiItems)
  430. {
  431. RequisitionItem item = new RequisitionItem();
  432. item.RequisitionLink.ID = requisition.ID;
  433. item.ID = itemShell.ID;
  434. item.Product.ID = itemShell.ProductID;
  435. item.Product.Code = itemShell.ProductCode;
  436. item.Product.Name = itemShell.ProductName;
  437. item.Location.ID = itemShell.HoldingID;
  438. item.Quantity = itemShell.Quantity;
  439. item.Description = item.Product.Name;
  440. item.Code = item.Product.Code;
  441. toSave.Add(item);
  442. }
  443. new Client<RequisitionItem>().Save(toSave, "Saved requi on mobile device");
  444. }
  445. private async void SavePhotos()
  446. {
  447. Task.Run(() =>
  448. {
  449. if (imagesDocuments.Count != 0)
  450. {
  451. new Client<Document>().Save(imagesDocuments.Values, "Photo Taken on Mobile device Requis module");
  452. List<RequisitionDocument> newRequiDocuments = new List<RequisitionDocument>();
  453. foreach (Document doc in imagesDocuments.Values)
  454. {
  455. var requiDocument = new RequisitionDocument();
  456. requiDocument.EntityLink.ID = requisition.ID;
  457. requiDocument.DocumentLink.ID = doc.ID;
  458. requiDocument.DocumentLink.FileName = doc.FileName;
  459. newRequiDocuments.Add(requiDocument);
  460. }
  461. new Client<RequisitionDocument>().Save(newRequiDocuments, "Photo Taken on Mobile device Requis module");
  462. }
  463. });
  464. }
  465. private bool CheckSaveOk()
  466. {
  467. bool bOK = false;
  468. if (requisition.JobLink.ID != Guid.Empty)
  469. {
  470. bOK = true;
  471. }
  472. else
  473. {
  474. DisplayAlert("Unable to save", "Add a Job", "OK");
  475. return bOK;
  476. }
  477. if (images.Children.Count > 0)
  478. {
  479. bOK = true;
  480. }
  481. else if (isNewRequest)
  482. {
  483. bOK = true;
  484. }
  485. else
  486. {
  487. bOK = false;
  488. DisplayAlert("Unable to save", "Add a Photo", "OK");
  489. return bOK;
  490. }
  491. return bOK;
  492. }
  493. #endregion
  494. }
  495. }