TransferModule.xaml.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. using InABox.Clients;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Security.Cryptography.X509Certificates;
  7. using System.Threading.Tasks;
  8. using InABox.Core;
  9. using InABox.Mobile;
  10. using Syncfusion.SfImageEditor.XForms;
  11. using Xamarin.CommunityToolkit.UI.Views;
  12. using Xamarin.Essentials;
  13. using Xamarin.Forms;
  14. using Xamarin.Forms.Xaml;
  15. using XF.Material.Forms.UI.Dialogs;
  16. namespace PRS.Mobile
  17. {
  18. [XamlCompilation(XamlCompilationOptions.Compile)]
  19. public partial class TransferModule
  20. {
  21. #region Fields + Constructor + Loading
  22. public TransferModule(Guid? locationid = null)
  23. {
  24. InitializeComponent();
  25. // Need to deal with Launching from specific location
  26. }
  27. protected override async Task<bool> OnBackButtonClicked()
  28. {
  29. if (_viewModel.Transactions.Count > 0 || _viewModel.Images.Count > 0)
  30. {
  31. if (await DisplayAlert("Cancel", "Leave without saving?", "OK", "CANCEL") != true)
  32. return false;
  33. }
  34. return true;
  35. }
  36. #endregion
  37. #region Search
  38. private void SearchEnt_Changed(object sender, EventArgs e)
  39. {
  40. // if (string.IsNullOrWhiteSpace(searchEnt.Text))
  41. // {
  42. // issuingListView.ItemsSource = issuingHoldings;
  43. // }
  44. // else
  45. // {
  46. // RunSearch();
  47. // }
  48. }
  49. #endregion
  50. private async void SaveBatch_Clicked(object sender, EventArgs e)
  51. {
  52. if (_viewModel.Transactions.Count == 0)
  53. {
  54. DisplayAlert("Error","No Transfers to Save","OK");
  55. return;
  56. }
  57. if (!_viewModel.Images.Any())
  58. {
  59. DisplayAlert("Error","No Images provided","OK");
  60. return;
  61. }
  62. if (String.IsNullOrWhiteSpace(_viewModel.Notes))
  63. {
  64. DisplayAlert("Error","Transfer Notes are blank","OK");
  65. return;
  66. }
  67. if (await DisplayAlert("Confirm", "Save Transfer Batch?", "OK", "CANCEL") == true)
  68. {
  69. using(var dialog = await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving Data"))
  70. {
  71. Progress<String> progress = new Progress<string>((s) => dialog.MessageText = s);
  72. await _viewModel.Save(progress);
  73. }
  74. Navigation.PopAsync();
  75. }
  76. }
  77. private void From_Clicked(object sender, MobileButtonClickEventArgs args)
  78. {
  79. StockLocationSelectionPage page = new StockLocationSelectionPage(
  80. new StockSelectionPageOptions()
  81. {
  82. ExcludeLocations = new Guid[] { _viewModel?.Source?.ID ?? Guid.Empty, _viewModel?.Target?.ID ?? Guid.Empty }
  83. }
  84. );
  85. page.OnLocationSelected += (s, e) =>
  86. {
  87. var location = e.Locations.FirstOrDefault();
  88. _viewModel.Source = location != null
  89. ? location
  90. : new StockLocationShell();
  91. };
  92. Navigation.PushAsync(page);
  93. }
  94. private void To_Clicked(object sender, MobileButtonClickEventArgs args)
  95. {
  96. StockLocationSelectionPage page = new StockLocationSelectionPage(
  97. new StockSelectionPageOptions()
  98. {
  99. ExcludeLocations = new Guid[] { _viewModel?.Source?.ID ?? Guid.Empty, _viewModel?.Target?.ID ?? Guid.Empty }
  100. }
  101. );
  102. page.OnLocationSelected += (s, e) =>
  103. {
  104. var location = e.Locations.FirstOrDefault();
  105. _viewModel.Target = location != null
  106. ? location
  107. : new StockLocationShell();
  108. };
  109. Navigation.PushAsync(page);
  110. }
  111. private void Holding_Clicked(object sender, EventArgs e)
  112. {
  113. if ((sender as MobileCard)?.BindingContext is StockHoldingShell shell && shell.LocationID == _viewModel.Source.ID)
  114. {
  115. if (_viewModel.Target.ID == Guid.Empty)
  116. {
  117. DisplayAlert("ERROR", "Please select a Location to Transfer to!", "OK");
  118. return;
  119. }
  120. var transaction = new StockTransaction(StockTransactionType.Transfer, shell, shell);
  121. if (_viewModel.Target.ID != Guid.Empty)
  122. {
  123. transaction.Target.LocationID = _viewModel.Target.ID;
  124. transaction.Target.LocationCode = _viewModel.Target.Code;
  125. transaction.Target.LocationDescription = _viewModel.Target.Description;
  126. transaction.Allocations = shell.Allocations;
  127. var others = _viewModel.Transactions.Where(x =>
  128. x.Source.LocationID == shell.LocationID
  129. && x.Source.StyleID == shell.StyleID
  130. && x.ProductID == shell.ProductID
  131. && x.DimensionsUnitID == shell.DimensionsUnitID
  132. && x.DimensionsHeight == shell.DimensionsHeight
  133. && x.DimensionsWidth == shell.DimensionsWidth
  134. && x.DimensionsLength == shell.DimensionsLength
  135. && x.DimensionsQuantity == shell.DimensionsQuantity
  136. && x.DimensionsWeight == shell.DimensionsWeight).ToArray();
  137. var allocations = new List<StockTransactionAllocation>();
  138. foreach (var alloc in shell.Allocations)
  139. {
  140. var newalloc = new StockTransactionAllocation();
  141. newalloc.ID = alloc.ID;
  142. newalloc.Description = alloc.Description;
  143. newalloc.Quantity = alloc.Quantity;
  144. foreach (var other in others)
  145. newalloc.Quantity -= other.Allocations.Where(x => x.ID == alloc.ID).Sum(x => x.Quantity);
  146. newalloc.Maximum = newalloc.Quantity;
  147. allocations.Add(newalloc);
  148. }
  149. transaction.Allocations = allocations.ToArray();
  150. }
  151. var popup = new TransferEdit(transaction, _viewModel.Transactions);
  152. popup.TransactionSaved += (o,e) =>
  153. {
  154. shell.Parent.Transactions?.Add(transaction);
  155. _sourceHoldings.ItemsSource = null;
  156. _sourceHoldings.ItemsSource = _viewModel.SourceHoldings.Items;
  157. _targetHoldings.ItemsSource = null;
  158. _targetHoldings.ItemsSource = _viewModel.TargetHoldings.Items;
  159. };
  160. Navigation.PushAsync(popup);
  161. }
  162. }
  163. private async void TakePhoto_Clicked(object sender, EventArgs args)
  164. {
  165. try
  166. {
  167. MobileDocument file = await MobileDocument.From(PhotoUtils.CreateCameraOptions());
  168. if (file?.Data?.Any() == true)
  169. _viewModel.Images.Add(
  170. new StockTransactionImage(
  171. file,
  172. MobileUtils.ImageTools.CreateThumbnail(file.Data, 256, 256)
  173. )
  174. );
  175. }
  176. catch (Exception e)
  177. {
  178. await MaterialDialog.Instance.AlertAsync(e.Message, "ERROR");
  179. }
  180. }
  181. private async void PickPhoto_Clicked(object sender, EventArgs args)
  182. {
  183. try
  184. {
  185. MobileDocument file = await MobileDocument.From(PhotoUtils.CreatePhotoLibraryOptions());
  186. if (file?.Data?.Any() == true)
  187. _viewModel.Images.Add(
  188. new StockTransactionImage(
  189. file,
  190. MobileUtils.ImageTools.CreateThumbnail(file.Data, 256, 256)
  191. )
  192. );
  193. }
  194. catch (Exception e)
  195. {
  196. await MaterialDialog.Instance.AlertAsync(e.Message, "ERROR");
  197. }
  198. }
  199. private void Image_Clicked(object sender, EventArgs e)
  200. {
  201. if ((sender as MobileCard)?.BindingContext is StockTransactionImage image)
  202. {
  203. ShowPopup(() =>
  204. {
  205. var editor = new SfImageEditor()
  206. {
  207. Source = ImageSource.FromStream(() => new MemoryStream(image.Document.Data)),
  208. BackgroundColor = Color.Transparent,
  209. };
  210. editor.ToolbarSettings.HeaderToolbarHeight = 0;
  211. editor.ImageEdited += (o, args) =>
  212. {
  213. // Trigger the Dispatcher to allow the edit to complete before saving
  214. // Otherwise the autosaved image is one edit behind the editor itself
  215. Dispatcher.BeginInvokeOnMainThread(() => editor.Save());
  216. };
  217. editor.ImageSaving += (o, args) =>
  218. {
  219. using (var ms = new MemoryStream())
  220. {
  221. args.Stream.CopyTo(ms);
  222. image.Document.Data = ms.GetBuffer();
  223. image.Thumbnail = MobileUtils.ImageTools.CreateThumbnail(image.Document.Data, 256, 256);
  224. }
  225. args.Cancel = true;
  226. };
  227. return editor;
  228. });
  229. }
  230. }
  231. private async void DeleteTransaction_Clicked(object sender, MobileMenuButtonClickedEventArgs args)
  232. {
  233. if ((sender as MobileMenuButton)?.BindingContext is StockTransaction transaction)
  234. {
  235. if (await DisplayAlert("Confirm", "Remove Tranasaction?", "OK", "CANCEL") == true)
  236. _viewModel.Transactions.Remove(transaction);
  237. }
  238. }
  239. private void TransactionImage_Clicked(object sender, EventArgs args)
  240. {
  241. if ((sender as Image)?.BindingContext is StockTransaction transaction && transaction.Image?.Any() == true)
  242. {
  243. ShowPopup(() =>
  244. {
  245. var editor = new SfImageEditor()
  246. {
  247. Source = ImageSource.FromStream(() => new MemoryStream(transaction.Image)),
  248. BackgroundColor = Color.Transparent,
  249. };
  250. editor.ToolbarSettings.IsVisible = false;
  251. return editor;
  252. });
  253. }
  254. }
  255. private void Transaction_Clicked(object sender, EventArgs e)
  256. {
  257. if ((sender as MobileCard)?.BindingContext is StockTransaction transaction)
  258. {
  259. var popup = new TransferEdit(transaction, _viewModel.Transactions);
  260. //popup.TransactionSaved += (o, e) => _viewModel.Transactions?.Add(transaction);
  261. Navigation.PushAsync(popup);
  262. }
  263. }
  264. private void TargetSearch_OnTextChanged(object sender, TextChangedEventArgs e)
  265. {
  266. _viewModel.TargetHoldings.Search(x =>
  267. String.IsNullOrWhiteSpace(e.NewTextValue)
  268. || x.ProductDisplay.ToUpper().Contains(e.NewTextValue.ToUpper())
  269. || x.StyleDisplay.ToUpper().Contains(e.NewTextValue.ToUpper())
  270. || x.JobDisplay.ToUpper().Contains(e.NewTextValue.ToUpper())
  271. );
  272. }
  273. private void SourceSearch_OnTextChanged(object sender, TextChangedEventArgs e)
  274. {
  275. _viewModel.SourceHoldings.Search(x =>
  276. String.IsNullOrWhiteSpace(e.NewTextValue)
  277. || x.ProductDisplay.ToUpper().Contains(e.NewTextValue.ToUpper())
  278. || x.StyleDisplay.ToUpper().Contains(e.NewTextValue.ToUpper())
  279. || x.JobDisplay.ToUpper().Contains(e.NewTextValue.ToUpper())
  280. );
  281. }
  282. }
  283. }