StoreRequiConfirmationPage.xaml.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  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 = QueryPhotos();
  144. while (table == null)
  145. table = QueryPhotos();
  146. if (table.Rows.Count != 0)
  147. {
  148. foreach (var row in table.Rows)
  149. {
  150. List<object> list = row.Values;
  151. if (list[0] == null) { list[0] = Guid.Empty; }
  152. Guid requisitionDocLinkID = Guid.Parse(list[0].ToString());
  153. new Client<Document>().Query(
  154. new Filter<Document>(x => x.ID).IsEqualTo(requisitionDocLinkID),
  155. null,
  156. null,
  157. (t, e) =>
  158. {
  159. CoreRow docrow = t.Rows.FirstOrDefault();
  160. if (docrow != null)
  161. {
  162. byte[] data = docrow.Get<Document, byte[]>(x => x.Data);
  163. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  164. Image img = new Image();
  165. img.HeightRequest = 150;
  166. img.WidthRequest = 150;
  167. img.Aspect = Aspect.AspectFit;
  168. img.Source = src;
  169. img.GestureRecognizers.Add(new TapGestureRecognizer
  170. {
  171. Command = new Command(OnTap),
  172. CommandParameter = src,
  173. NumberOfTapsRequired = 1
  174. });
  175. Device.BeginInvokeOnMainThread(() =>
  176. {
  177. ImageScroller.IsVisible = true;
  178. images.Children.Add(img);
  179. UpdateColours();
  180. });
  181. }
  182. }
  183. );
  184. }
  185. }
  186. }
  187. }
  188. private CoreTable QueryPhotos()
  189. {
  190. try
  191. {
  192. return new Client<RequisitionDocument>().Query(
  193. new Filter<RequisitionDocument>(x => x.EntityLink.ID).IsEqualTo(requisition.ID),
  194. new Columns<RequisitionDocument>(x => x.DocumentLink.ID),
  195. null
  196. );
  197. }
  198. catch (Exception ex)
  199. {
  200. var log = new MobileLogging(LogType.Query, "QueryPhotos()", ex.Message + ex.StackTrace, this.GetType().Name);
  201. return null;
  202. }
  203. }
  204. #endregion
  205. #region Selection
  206. private void SelectJobBtn_Clicked(object sender, EventArgs e)
  207. {
  208. JobSelectionPage jobSelectionPage = new JobSelectionPage();
  209. jobSelectionPage.OnItemSelected += (() =>
  210. {
  211. requisition.JobLink.ID = jobSelectionPage.Job.ID;
  212. requisition.JobLink.Name = jobSelectionPage.Job.Name;
  213. requisition.JobLink.JobNumber = jobSelectionPage.Job.JobNumber;
  214. UpdateScreen();
  215. });
  216. Navigation.PushAsync(jobSelectionPage);
  217. }
  218. private void ReduceQtyBtn_Clicked(object sender, EventArgs e)
  219. {
  220. if (requisition.Boxes <= 1)
  221. return;
  222. else
  223. {
  224. requisition.Boxes--;
  225. UpdateScreen();
  226. }
  227. }
  228. private void IncreaseQtyBtn_Clicked(object sender, EventArgs e)
  229. {
  230. requisition.Boxes++;
  231. UpdateScreen();
  232. }
  233. private void DueDatePckr_DateSelected(object sender, EventArgs e)
  234. {
  235. requisition.Due = dueDatePckr.Date;
  236. }
  237. #endregion
  238. #region Photos
  239. private void TakePhoto_Clicked(object sender, EventArgs e)
  240. {
  241. TakeAPhoto();
  242. }
  243. private void ChooseImage_Clicked(object sender, EventArgs e)
  244. {
  245. ChooseAPhoto();
  246. }
  247. private async void TakeAPhoto()
  248. {
  249. await CrossMedia.Current.Initialize();
  250. if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
  251. {
  252. await DisplayAlert("No Camera", ":( No camera available.", "OK");
  253. return;
  254. }
  255. String filename = String.Format("{0:yyyy-MM-dd HH:mm:ss.fff}.png", DateTime.Now);
  256. var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
  257. {
  258. Name = filename,
  259. CompressionQuality = 10,
  260. PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full
  261. });
  262. if (file == null)
  263. return;
  264. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo"))
  265. {
  266. Image img = null;
  267. var memoryStream = new MemoryStream();
  268. file.GetStream().CopyTo(memoryStream);
  269. var data = memoryStream.ToArray();
  270. Document doc = new Document()
  271. {
  272. FileName = filename,
  273. Data = data,
  274. CRC = CoreUtils.CalculateCRC(data),
  275. TimeStamp = DateTime.Now
  276. };
  277. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  278. img = new Image();
  279. img.HeightRequest = 150;
  280. img.WidthRequest = 150;
  281. img.Aspect = Aspect.AspectFit;
  282. img.Source = src;
  283. img.GestureRecognizers.Add(new TapGestureRecognizer
  284. {
  285. Command = new Command(OnTap),
  286. CommandParameter = src,
  287. NumberOfTapsRequired = 1
  288. });
  289. imagesDocuments.Add(img, doc);
  290. file.Dispose();
  291. if (img != null)
  292. {
  293. Device.BeginInvokeOnMainThread(() =>
  294. {
  295. ImageScroller.IsVisible = true;
  296. images.Children.Add(img);
  297. UpdateColours();
  298. });
  299. }
  300. }
  301. }
  302. private async void ChooseAPhoto()
  303. {
  304. await CrossMedia.Current.Initialize();
  305. if (!CrossMedia.Current.IsPickPhotoSupported)
  306. {
  307. await DisplayAlert("No Library", ":( No Photo Library available.", "OK");
  308. return;
  309. }
  310. var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions()
  311. {
  312. CompressionQuality = 10,
  313. PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full
  314. });
  315. if (file == null)
  316. return;
  317. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo"))
  318. {
  319. Image img = null;
  320. var memoryStream = new MemoryStream();
  321. file.GetStream().CopyTo(memoryStream);
  322. var data = memoryStream.ToArray();
  323. Document doc = new Document()
  324. {
  325. FileName = Path.GetFileName(file.Path),
  326. Data = data,
  327. CRC = CoreUtils.CalculateCRC(data),
  328. TimeStamp = DateTime.Now
  329. };
  330. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  331. img = new Image();
  332. img.HeightRequest = 150;
  333. img.WidthRequest = 150;
  334. img.Aspect = Aspect.AspectFit;
  335. img.Source = src;
  336. img.GestureRecognizers.Add(new TapGestureRecognizer
  337. {
  338. Command = new Command(OnTap),
  339. CommandParameter = src,
  340. NumberOfTapsRequired = 1
  341. });
  342. imagesDocuments.Add(img, doc);
  343. file.Dispose();
  344. if (img != null)
  345. {
  346. Device.BeginInvokeOnMainThread(() =>
  347. {
  348. ImageScroller.IsVisible = true;
  349. images.Children.Add(img);
  350. UpdateColours();
  351. });
  352. }
  353. }
  354. }
  355. private void OnTap(object obj)
  356. {
  357. ImageViewer viewer = new ImageViewer(obj as ImageSource);
  358. Navigation.PushAsync(viewer);
  359. viewer.ChooseDelete();
  360. viewer.OnDeleteSelected += () =>
  361. {
  362. Image img = imagesDocuments.Keys.First(x => x.Source.Equals(obj as ImageSource));
  363. imagesDocuments.Remove(img);
  364. Device.BeginInvokeOnMainThread(() =>
  365. {
  366. images.Children.Clear();
  367. if (imagesDocuments.Count > 0)
  368. {
  369. foreach (Image image in imagesDocuments.Keys)
  370. {
  371. images.Children.Add(image);
  372. }
  373. }
  374. UpdateColours();
  375. });
  376. };
  377. }
  378. #endregion
  379. #region Save
  380. private async void SaveBtn_Clicked(object sender, EventArgs e)
  381. {
  382. if (CheckSaveOk())
  383. {
  384. if (isNewRequest)
  385. {
  386. requisition.Request = notesEdt.Text;
  387. DoSaveRequi(requisition);
  388. DisplayAlert("Success", "Requisition " + requisition.Number + " Created", "Ok");
  389. }
  390. else
  391. {
  392. if (takenNowRb.IsChecked)
  393. {
  394. requisition.TakenBy.ID = GlobalVariables.EmpID;
  395. requisition.TakenBy.Name = GlobalVariables.EmpName;
  396. }
  397. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving"))
  398. {
  399. SaveRequi();
  400. }
  401. if (requisition.ID != Guid.Empty)
  402. {
  403. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving"))
  404. {
  405. SavePhotos();
  406. SaveItems();
  407. }
  408. await DisplayAlert("Success", "Requisition " + requisition.Number + " Saved", "Ok");
  409. OnSaveSelected?.Invoke();
  410. Navigation.PopAsync();
  411. }
  412. }
  413. }
  414. }
  415. private Requisition DoSaveRequi(Requisition requisition)
  416. {
  417. try
  418. {
  419. new Client<Requisition>().Save(requisition, "Created on Mobile Device");
  420. return requisition;
  421. }
  422. catch (Exception ex)
  423. {
  424. var log = new MobileLogging(LogType.Save, "DoSaveRequi()", ex.Message + ex.StackTrace, this.GetType().Name);
  425. return DoSaveRequi(requisition);
  426. }
  427. }
  428. private void SaveRequi()
  429. {
  430. requisition.Filled = DateTime.Now;
  431. requisition.Notes = new string[] { notesEdt.Text };
  432. DoSaveRequi(requisition);
  433. }
  434. private void SaveItems()
  435. {
  436. Task.Run(() =>
  437. {
  438. List<RequisitionItem> toDelete = new List<RequisitionItem>();
  439. if (oldrequiitems.Count > 0)
  440. {
  441. foreach (StoreRequiItemShell oldshell in oldrequiitems)
  442. {
  443. StoreRequiItemShell shell = requiItems.Find(x => x.ID.Equals(oldshell.ID));
  444. if (shell == null)
  445. {
  446. toDelete.Add(new RequisitionItem { ID = oldshell.ID });
  447. }
  448. }
  449. if (toDelete.Count > 0)
  450. {
  451. DoDeleteRequiItems(toDelete);
  452. }
  453. }
  454. });
  455. List<RequisitionItem> toSave = new List<RequisitionItem>();
  456. foreach (StoreRequiItemShell requiItemShell in requiItems)
  457. {
  458. RequisitionItem item = new RequisitionItem();
  459. item.RequisitionLink.ID = requisition.ID;
  460. item.ID = requiItemShell.ID;
  461. item.Product.ID = requiItemShell.ProductID;
  462. item.Product.Code = requiItemShell.ProductCode;
  463. item.Product.Name = requiItemShell.ProductName;
  464. item.Location.ID = requiItemShell.LocationID;
  465. item.Quantity = requiItemShell.Quantity;
  466. item.Description = requiItemShell.ProductName;
  467. item.Code = requiItemShell.ProductCode;
  468. item.Job.ID = requiItemShell.JobID;
  469. item.Style.ID = requiItemShell.StyleID;
  470. item.Picked = item.Picked == DateTime.MinValue ? DateTime.Now : item.Picked;
  471. item.Dimensions.Unit.ID = requiItemShell.Dimensions.Unit.ID;
  472. item.Dimensions.Unit.HasQuantity = requiItemShell.Dimensions.Unit.HasQuantity;
  473. item.Dimensions.Unit.HasLength = requiItemShell.Dimensions.Unit.HasLength;
  474. item.Dimensions.Unit.HasHeight = requiItemShell.Dimensions.Unit.HasHeight;
  475. item.Dimensions.Unit.HasWeight = requiItemShell.Dimensions.Unit.HasWeight;
  476. item.Dimensions.Unit.HasWidth = requiItemShell.Dimensions.Unit.HasWidth;
  477. item.Dimensions.Quantity = requiItemShell.Dimensions.Quantity;
  478. item.Dimensions.Length = requiItemShell.Dimensions.Length;
  479. item.Dimensions.Height = requiItemShell.Dimensions.Height;
  480. item.Dimensions.Weight = requiItemShell.Dimensions.Weight;
  481. item.Dimensions.Width = requiItemShell.Dimensions.Width;
  482. item.Dimensions.Unit.Format = requiItemShell.Dimensions.Unit.Format;
  483. item.Dimensions.Unit.Formula = requiItemShell.Dimensions.Unit.Formula;
  484. item.Dimensions.UnitSize = requiItemShell.Dimensions.UnitSize;
  485. toSave.Add(item);
  486. }
  487. DoSaveRequiItems(toSave);
  488. }
  489. private void DoDeleteRequiItems(List<RequisitionItem> toDelete)
  490. {
  491. try
  492. {
  493. new Client<RequisitionItem>().Delete(toDelete, "Updated from mobile device");
  494. }
  495. catch (Exception ex)
  496. {
  497. var log = new MobileLogging(LogType.Delete, "DoDeleteRequiItems()", ex.Message + ex.StackTrace, this.GetType().Name);
  498. DoDeleteRequiItems(toDelete);
  499. }
  500. }
  501. private void DoSaveRequiItems(List<RequisitionItem> toSave)
  502. {
  503. try
  504. {
  505. new Client<RequisitionItem>().Save(toSave, "Saved requi on mobile device");
  506. }
  507. catch (Exception ex)
  508. {
  509. var log = new MobileLogging(LogType.Save, "DoSaveRequiItems", ex.Message + ex.StackTrace, this.GetType().Name);
  510. DoSaveRequiItems(toSave);
  511. }
  512. }
  513. private void SavePhotos()
  514. {
  515. Task.Run(() =>
  516. {
  517. if (imagesDocuments.Count != 0)
  518. {
  519. DoSaveDocuments();
  520. List<RequisitionDocument> newRequiDocuments = new List<RequisitionDocument>();
  521. foreach (Document doc in imagesDocuments.Values)
  522. {
  523. var requiDocument = new RequisitionDocument();
  524. requiDocument.EntityLink.ID = requisition.ID;
  525. requiDocument.DocumentLink.ID = doc.ID;
  526. requiDocument.DocumentLink.FileName = doc.FileName;
  527. newRequiDocuments.Add(requiDocument);
  528. }
  529. DoSaveRequiDocuments(newRequiDocuments);
  530. }
  531. });
  532. }
  533. private void DoSaveDocuments()
  534. {
  535. try
  536. {
  537. new Client<Document>().Save(imagesDocuments.Values, "Photo Taken on Mobile device Requis module");
  538. }
  539. catch (Exception ex)
  540. {
  541. var log = new MobileLogging(LogType.Save, "DoSaveDocuments()", ex.Message + ex.StackTrace, this.GetType().Name);
  542. DoSaveDocuments();
  543. }
  544. }
  545. private void DoSaveRequiDocuments(List<RequisitionDocument> newRequiDocuments)
  546. {
  547. try
  548. {
  549. new Client<RequisitionDocument>().Save(newRequiDocuments, "Photo Taken on Mobile device Requis module");
  550. }
  551. catch (Exception ex)
  552. {
  553. var log = new MobileLogging(LogType.Save, "DoSaveRequiDocuments", ex.Message + ex.StackTrace, this.GetType().Name);
  554. DoSaveRequiDocuments(newRequiDocuments);
  555. }
  556. }
  557. private bool CheckSaveOk()
  558. {
  559. bool bOK = false;
  560. if (requisition.JobLink.ID != Guid.Empty)
  561. {
  562. bOK = true;
  563. }
  564. else
  565. {
  566. DisplayAlert("Unable to save", "Add a Job", "OK");
  567. return bOK;
  568. }
  569. if (images.Children.Count > 0)
  570. {
  571. bOK = true;
  572. }
  573. else if (isNewRequest)
  574. {
  575. bOK = true;
  576. }
  577. else
  578. {
  579. bOK = false;
  580. DisplayAlert("Unable to save", "Add a Photo", "OK");
  581. return bOK;
  582. }
  583. return bOK;
  584. }
  585. #endregion
  586. }
  587. }