HoldingViewer.xaml.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.ComponentModel;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Threading.Tasks;
  8. using comal.timesheets.Tasks;
  9. using Comal.Classes;
  10. using InABox.Clients;
  11. using InABox.Configuration;
  12. using InABox.Core;
  13. using Plugin.Media;
  14. using Xamarin.Forms;
  15. using Xamarin.Forms.Xaml;
  16. using XF.Material.Forms.UI;
  17. using XF.Material.Forms.UI.Dialogs;
  18. namespace comal.timesheets.Products
  19. {
  20. public delegate void ExitHoldingsSelectedEvent();
  21. [XamlCompilation(XamlCompilationOptions.Compile)]
  22. public partial class HoldingViewer
  23. {
  24. public ExitHoldingsSelectedEvent OnExitSelected;
  25. Guid productID = Guid.Empty;
  26. Guid imageID = Guid.Empty;
  27. ObservableList<StockHoldingShell> stockHoldingShells = new ObservableList<StockHoldingShell>();
  28. ObservableList<Document> newPhotoDocuments = new ObservableList<Document>();
  29. String productName = "";
  30. Image img = null;
  31. public HoldingViewer(Guid _productID, string _productName, Guid _imageID)
  32. {
  33. InitializeComponent();
  34. NavigationPage.SetHasBackButton(this, false);
  35. productID = _productID;
  36. productName = _productName;
  37. titleLbl.Text = productName;
  38. imageID = _imageID;
  39. }
  40. protected override void OnAppearing()
  41. {
  42. LoadPhoto();
  43. LoadStockHoldings();
  44. base.OnAppearing();
  45. }
  46. private void Exit_Clicked(object sender, EventArgs e)
  47. {
  48. Navigation.PopAsync();
  49. }
  50. //saves photo on disappearing if new photo present
  51. protected override async void OnDisappearing()
  52. {
  53. base.OnDisappearing();
  54. if (newPhotoDocuments.Count > 0)
  55. {
  56. await Task.Run(() =>
  57. {
  58. Document doc = newPhotoDocuments.FirstOrDefault<Document>();
  59. new Client<Document>().Save(doc, "Updated from mobile device");
  60. new Client<Product>().Query(
  61. new Filter<Product>(x => x.ID).IsEqualTo(productID),
  62. new Columns<Product>(x => x.ID, x => x.Image.ID),
  63. null,
  64. (t, e) =>
  65. {
  66. CoreRow row = t.Rows.FirstOrDefault();
  67. if (row != null)
  68. {
  69. Product product = row.ToObject<Product>();
  70. product.Image.ID = doc.ID;
  71. imageID = doc.ID;
  72. new Client<Product>().Save(product, "Updated from mobile device");
  73. }
  74. });
  75. });
  76. }
  77. }
  78. private async void LoadStockHoldings()
  79. {
  80. titleLbl.Text = "Loading Holdings...";
  81. stockHoldingShells.Clear();
  82. await Task.Run(() =>
  83. {
  84. CoreTable table = new Client<StockHolding>().Query(
  85. new Filter<StockHolding>(x => x.Product.ID).IsEqualTo(productID),
  86. new Columns<StockHolding>(
  87. x => x.Location.Description, //0
  88. x => x.Location.Area.Code, //1
  89. x => x.Job.JobNumber, //2
  90. x => x.Style.Description, //3
  91. x => x.Units, //4
  92. x => x.Location.ID, //5
  93. x => x.Dimensions.UnitSize //6 STRING
  94. ),
  95. null
  96. );
  97. string emptyString = "";
  98. foreach (CoreRow row in table.Rows)
  99. {
  100. List<object> list = row.Values;
  101. if (list[0] == null) { list[0] = emptyString; } //0
  102. if (list[1] == null) { list[1] = emptyString; } //1
  103. if (list[2] == null) { list[2] = emptyString; } //2
  104. if (list[3] == null) { list[3] = emptyString; } //3
  105. if (list[4] == null) { list[4] = 0; } //4
  106. if (list[5] == null) { list[5] = Guid.Empty; } //5
  107. if (list[6] == null) { list[6] = emptyString; } //3
  108. double units = double.Parse(list[4].ToString());
  109. if (units > 0)
  110. {
  111. if (((Math.Round(units) * 100) / 100) != 0)
  112. {
  113. StockHoldingShell stockHoldingShell = new StockHoldingShell();
  114. stockHoldingShell.LocationName = list[0].ToString();
  115. stockHoldingShell.AreaName = "Area: " + list[1].ToString();
  116. stockHoldingShell.JobNumber = "Job: " + list[2].ToString();
  117. stockHoldingShell.StyleName = "Style: " + list[3].ToString();
  118. stockHoldingShell.Units = double.Parse(list[4].ToString());
  119. stockHoldingShell.LocationID = Guid.Parse(list[5].ToString());
  120. stockHoldingShell.DimensionsUnitSize = "Unit Size: " + list[6].ToString();
  121. stockHoldingShells.Add(stockHoldingShell);
  122. }
  123. }
  124. }
  125. Device.BeginInvokeOnMainThread(() =>
  126. {
  127. titleLbl.Text = "Holdings (" + stockHoldingShells.Count + ")";
  128. holdingListView.ItemsSource = null;
  129. holdingListView.ItemsSource = stockHoldingShells;
  130. photoFrame.IsVisible = true;
  131. });
  132. });
  133. }
  134. private async void Pack_Tapped(object sender, EventArgs e)
  135. {
  136. string chosenOption = await DisplayActionSheet("Choose stock movements to create", "Cancel", null,
  137. "Issue from this location", "Transfer from this location", "Stocktake this location");
  138. switch (chosenOption)
  139. {
  140. case "Cancel":
  141. return;
  142. case "Issue from this location":
  143. OpenLocation(StockMovementBatchType.Issue);
  144. break;
  145. case "Transfer from this location":
  146. OpenLocation(StockMovementBatchType.Transfer);
  147. break;
  148. case "Stocktake this location":
  149. OpenLocation(StockMovementBatchType.Stocktake);
  150. break;
  151. default:
  152. return;
  153. }
  154. //if (ClientFactory.IsAllowed<CanModifyStockMovements>())
  155. //{
  156. // string chosenOption = await DisplayActionSheet("Choose stock movements to create", "Cancel", null, "Issue from this location", "Transfer from this location");
  157. // switch (chosenOption)
  158. // {
  159. // case "Cancel":
  160. // return;
  161. // case "Issue from this location":
  162. // OpenLocation(StockMovementBatchType.Issue);
  163. // break;
  164. // case "Transfer from this location":
  165. // OpenLocation(StockMovementBatchType.Transfer);
  166. // break;
  167. // default:
  168. // return;
  169. // }
  170. //}
  171. //else
  172. //{
  173. // DisplayAlert("Alert", "Your current security settings do not allow you to view this module"
  174. // + System.Environment.NewLine + "(Setting - Can Modify Stock Movements)", "OK");
  175. //}
  176. }
  177. private void OpenLocation(StockMovementBatchType type)
  178. {
  179. StockHoldingShell stockHoldingShell = holdingListView.SelectedItem as StockHoldingShell;
  180. if (type == StockMovementBatchType.Stocktake)
  181. {
  182. StocktakePage stocktakePage = new StocktakePage(stockHoldingShell.LocationID);
  183. Navigation.PushAsync(stocktakePage);
  184. }
  185. else
  186. {
  187. RecTrans recTrans = new RecTrans(type, stockHoldingShell.LocationID.ToString());
  188. Navigation.PushAsync(recTrans);
  189. }
  190. }
  191. #region Photos
  192. private async void LoadPhoto()
  193. {
  194. if (imageID != Guid.Empty)
  195. {
  196. photoFrame.IsVisible = true;
  197. photoLbl.Text = "Loading Image";
  198. await Task.Run(() =>
  199. {
  200. new Client<Document>().Query(
  201. new Filter<Document>(x => x.ID).IsEqualTo(imageID),
  202. null,
  203. null,
  204. (t, e) =>
  205. {
  206. CoreRow docrow = t.Rows.FirstOrDefault();
  207. if (docrow != null)
  208. {
  209. byte[] data = docrow.Get<Document, byte[]>(x => x.Data);
  210. DataToImage(data);
  211. }
  212. }
  213. );
  214. });
  215. }
  216. }
  217. private async void TakePhoto_Clicked(object sender, EventArgs e)
  218. {
  219. if (img != null)
  220. {
  221. string chosenOption = await DisplayActionSheet("Would you like to replace the current photo?", "Cancel", null, "Yes", "No");
  222. switch (chosenOption)
  223. {
  224. case "Cancel":
  225. return;
  226. case "Yes":
  227. break;
  228. case "No":
  229. return;
  230. default:
  231. return;
  232. }
  233. }
  234. await CrossMedia.Current.Initialize();
  235. if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
  236. {
  237. await DisplayAlert("No Camera", ":( No camera available.", "OK");
  238. return;
  239. }
  240. String filename = String.Format("{0:yyyy-MM-dd HH:mm:ss.fff}.png", DateTime.Now);
  241. var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
  242. {
  243. Name = filename,
  244. CompressionQuality = 10,
  245. PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full
  246. });
  247. if (file == null)
  248. return;
  249. AddPhoto(file);
  250. }
  251. private async void ChooseImage_Clicked(object sender, EventArgs e)
  252. {
  253. if (img != null)
  254. {
  255. string chosenOption = await DisplayActionSheet("Would you like to replace the current photo?", "Cancel", null, "Yes", "No");
  256. switch (chosenOption)
  257. {
  258. case "Cancel":
  259. return;
  260. case "Yes":
  261. break;
  262. case "No":
  263. return;
  264. default:
  265. return;
  266. }
  267. }
  268. await CrossMedia.Current.Initialize();
  269. if (!CrossMedia.Current.IsPickPhotoSupported)
  270. {
  271. await DisplayAlert("No Library", ":( No Photo Library available.", "OK");
  272. return;
  273. }
  274. var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions()
  275. {
  276. CompressionQuality = 10,
  277. PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full
  278. });
  279. if (file == null)
  280. return;
  281. AddPhoto(file);
  282. }
  283. private async void AddPhoto(Plugin.Media.Abstractions.MediaFile file)
  284. {
  285. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo"))
  286. {
  287. var memoryStream = new MemoryStream();
  288. file.GetStream().CopyTo(memoryStream);
  289. var data = memoryStream.ToArray();
  290. Document doc = new Document()
  291. {
  292. FileName = Path.GetFileName(file.Path),
  293. Data = data,
  294. CRC = CoreUtils.CalculateCRC(data),
  295. TimeStamp = DateTime.Now
  296. };
  297. newPhotoDocuments.Clear();
  298. newPhotoDocuments.Add(doc);
  299. DataToImage(data);
  300. file.Dispose();
  301. }
  302. }
  303. private void DataToImage(byte[] data)
  304. {
  305. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  306. img = new Image();
  307. img.HeightRequest = 150;
  308. img.WidthRequest = 150;
  309. img.Aspect = Aspect.AspectFit;
  310. img.Source = src;
  311. img.GestureRecognizers.Add(new TapGestureRecognizer
  312. {
  313. Command = new Command(OnTap),
  314. CommandParameter = src,
  315. NumberOfTapsRequired = 1
  316. });
  317. if (img != null)
  318. {
  319. Device.BeginInvokeOnMainThread(() =>
  320. {
  321. photoLbl.Text = "Product Image";
  322. images.Children.Clear();
  323. images.Children.Add(img);
  324. images.IsVisible = true;
  325. });
  326. }
  327. }
  328. private void OnTap(object obj)
  329. {
  330. ImageViewer viewer = new ImageViewer(obj as ImageSource);
  331. Navigation.PushAsync(viewer);
  332. }
  333. #endregion Photos
  334. }
  335. }