|
@@ -1,848 +0,0 @@
|
|
|
-using System;
|
|
|
-using System.Collections.Generic;
|
|
|
-using System.IO;
|
|
|
-using System.Linq;
|
|
|
-using System.Linq.Expressions;
|
|
|
-using System.Threading.Tasks;
|
|
|
-using Comal.Classes;
|
|
|
-using InABox.Clients;
|
|
|
-using InABox.Core;
|
|
|
-using InABox.Mobile;
|
|
|
-using Xamarin.Essentials;
|
|
|
-using Xamarin.Forms;
|
|
|
-using XF.Material.Forms.UI;
|
|
|
-using XF.Material.Forms.UI.Dialogs;
|
|
|
-
|
|
|
-namespace PRS.Mobile
|
|
|
-{
|
|
|
-
|
|
|
- public class StockItemModel
|
|
|
- {
|
|
|
- public StockHolding Holding { get; set; }
|
|
|
- public ImageSource Image { get; set; }
|
|
|
- public bool ImageVisible { get { return Image != null; } }
|
|
|
- public bool ImageHidden { get { return Image == null; } }
|
|
|
- public double ImageHeight { get; set; }
|
|
|
- public String Description { get; set; }
|
|
|
- public String Style { get; set; }
|
|
|
- public String Job { get; set; }
|
|
|
- public String OnHand { get; set; }
|
|
|
- public Brush Background { get; set; }
|
|
|
- public Color BackgroundColor { get; set; }
|
|
|
- }
|
|
|
-
|
|
|
- public partial class StockHoldingPage
|
|
|
- {
|
|
|
- #region Fields
|
|
|
- private Guid _locationid = Guid.Empty;
|
|
|
- private String _locationname = "";
|
|
|
- private bool _istransient = false;
|
|
|
- private StockMovementBatchType _type = StockMovementBatchType.Stocktake;
|
|
|
- private List<StockHolding> _holdings = new List<StockHolding>();
|
|
|
- private List<StockItemModel> _models = new List<StockItemModel>();
|
|
|
- private Dictionary<StockHolding, StockMovement> _movements = new Dictionary<StockHolding, StockMovement>();
|
|
|
- private String _notes = "";
|
|
|
- private NotesPage _notespage = null;
|
|
|
- private StockMovementPage _movementpage = null;
|
|
|
- private NewHoldingPage _newpage = null;
|
|
|
- List<Document> _images = new List<Document>();
|
|
|
- Dictionary<String, byte[]> _photos = new Dictionary<String, byte[]>();
|
|
|
- private bool bFirst = true;
|
|
|
- Job job = new Job();
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region Constructor
|
|
|
- public StockHoldingPage(Guid locationid, String locationname, bool istransient, StockMovementBatchType type, Job _job)
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- job.ID = _job.ID;
|
|
|
- job.JobNumber = _job.JobNumber;
|
|
|
- job.Name = _job.Name;
|
|
|
- }
|
|
|
- catch { }
|
|
|
- _type = type;
|
|
|
- _locationid = locationid;
|
|
|
- _locationname = locationname;
|
|
|
- _istransient = istransient;
|
|
|
- //StatusLabel.IsVisible = _istransient;
|
|
|
- //StatusFrame.IsVisible = _istransient;
|
|
|
-
|
|
|
- InitializeComponent();
|
|
|
-
|
|
|
- NavigationPage.SetHasBackButton(this, false);
|
|
|
- ToolbarItems.Clear();
|
|
|
- ToolbarItems.Add(new ToolbarItem("Back", "", async () =>
|
|
|
- {
|
|
|
- if (!String.IsNullOrEmpty(_notes) || _movements.Any() || _photos.Any())
|
|
|
- {
|
|
|
- string chosenOption = await DisplayActionSheet("Unsaved changes will be lost if you close", "Cancel", null, "Yes", "No");
|
|
|
- switch (chosenOption)
|
|
|
- {
|
|
|
- case "No":
|
|
|
- break;
|
|
|
- case "Cancel":
|
|
|
- break;
|
|
|
- case "Yes":
|
|
|
- await Navigation.PopAsync();
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- await Navigation.PopAsync();
|
|
|
- }));
|
|
|
-
|
|
|
- Title = String.Format("{0}: {1}", _locationname, type.ToString());
|
|
|
-
|
|
|
- NewProduct.IsVisible = _type.Equals(StockMovementBatchType.Receipt) || type.Equals(StockMovementBatchType.Stocktake);
|
|
|
- All.IsVisible = _type.Equals(StockMovementBatchType.Issue) || type.Equals(StockMovementBatchType.Transfer);
|
|
|
-
|
|
|
- _holdings = new Client<StockHolding>().Query(
|
|
|
- new Filter<StockHolding>(x => x.Location.ID).IsEqualTo(_locationid),
|
|
|
- new Columns<StockHolding>(
|
|
|
- x => x.ID,
|
|
|
- X => X.Product.ID,
|
|
|
- X => X.Product.Code,
|
|
|
- X => X.Product.Name,
|
|
|
- X => X.Product.Image.ID,
|
|
|
- X => X.Style.ID,
|
|
|
- X => X.Style.Code,
|
|
|
- X => X.Style.Description,
|
|
|
- X => X.Job.ID,
|
|
|
- X => X.Job.JobNumber,
|
|
|
- X => X.Job.Name,
|
|
|
- X => X.Units,
|
|
|
- X => X.Product.Units.ID,
|
|
|
- X => X.Product.Units.Code,
|
|
|
- X => X.Location.ID,
|
|
|
- X => X.Location.Code,
|
|
|
- X => X.Location.Description
|
|
|
- ),
|
|
|
- null
|
|
|
- ).Rows.Select(r => r.ToObject<StockHolding>()).Where(x => !x.Units.Equals(0.0F)).ToList();
|
|
|
-
|
|
|
- List<Guid> imageids = new List<Guid>();
|
|
|
- foreach (var holding in _holdings)
|
|
|
- {
|
|
|
- Guid imageid = holding.Product.Image.ID;
|
|
|
- if ((imageid != Guid.Empty) && !imageids.Contains(imageid))
|
|
|
- imageids.Add(imageid);
|
|
|
- }
|
|
|
-
|
|
|
- if (imageids.Any())
|
|
|
- {
|
|
|
- _images = new Client<Document>().Load(
|
|
|
- new Filter<Document>(x => x.ID).InList(imageids.ToArray()),
|
|
|
- null
|
|
|
- ).ToList();
|
|
|
- }
|
|
|
- }
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region OnAppearing & Screen updating
|
|
|
- protected override void OnAppearing()
|
|
|
- {
|
|
|
- base.OnAppearing();
|
|
|
- if (_movementpage != null)
|
|
|
- _movementpage = null;
|
|
|
- if (_notespage != null)
|
|
|
- {
|
|
|
- Notes.Text = _notes;
|
|
|
- Notes.IsVisible = !String.IsNullOrEmpty(_notes);
|
|
|
- _notespage = null;
|
|
|
- }
|
|
|
- RefreshScreen(false);
|
|
|
- }
|
|
|
- private void RefreshScreen(bool scrollToLast)
|
|
|
- {
|
|
|
- int selected = Items.CurrentItem != null ? _models.IndexOf(Items.CurrentItem as StockItemModel) : 0;
|
|
|
-
|
|
|
- Items.ItemsSource = null;
|
|
|
- _models.Clear();
|
|
|
-
|
|
|
- foreach (var holding in _holdings)
|
|
|
- {
|
|
|
-
|
|
|
- StockItemModel model = new StockItemModel();
|
|
|
-
|
|
|
- StockMovement movement = _movements.ContainsKey(holding) ? _movements[holding] : null;
|
|
|
- Color color = Color.White;
|
|
|
- double value = 0.0F;
|
|
|
- if (movement != null)
|
|
|
- {
|
|
|
- value = movement.Received - movement.Issued;
|
|
|
- color = value == 0.0F ? Color.LightGreen : Color.LightSalmon;
|
|
|
- }
|
|
|
-
|
|
|
- model.Description = String.Format("{0}: {1}", holding.Product.Code, holding.Product.Name); ;
|
|
|
- model.Style = String.Format("{0}: {1}", holding.Style.Code, holding.Style.Description);
|
|
|
- model.Job = holding.Job.ID != Guid.Empty ? String.Format("{0}: {1}", holding.Job.JobNumber, holding.Job.JobNumber) : "General Stock";
|
|
|
-
|
|
|
- String onhand = "";
|
|
|
- if (value > 0.0F)
|
|
|
- onhand = String.Format("{0} ({1} {2})", onhand, Math.Round(value, 4), _type == StockMovementBatchType.Stocktake ? "Extra" : "Received");
|
|
|
- else if (value < 0.0F)
|
|
|
- onhand = String.Format("{0} ({1} {2})", onhand, Math.Abs(Math.Round(value, 4)), _type == StockMovementBatchType.Stocktake ? "Missing" : "Issued");
|
|
|
- model.OnHand = onhand;
|
|
|
-
|
|
|
- var doc = _images.FirstOrDefault(x => x.ID.Equals(holding.Product.Image.ID));
|
|
|
- if (doc != null)
|
|
|
- {
|
|
|
- ImageSource src = ImageSource.FromStream(() => new MemoryStream(doc.Data));
|
|
|
- model.Image = src;
|
|
|
- }
|
|
|
- else
|
|
|
- model.Image = null;
|
|
|
-
|
|
|
- model.ImageHeight = this.Height - 400;
|
|
|
-
|
|
|
- model.Background = new SolidColorBrush(color);
|
|
|
-
|
|
|
- model.BackgroundColor = color;
|
|
|
-
|
|
|
- model.Holding = holding;
|
|
|
-
|
|
|
- _models.Add(model);
|
|
|
-
|
|
|
- }
|
|
|
- Items.ItemsSource = _models;
|
|
|
-
|
|
|
- if (selected != 0)
|
|
|
- Items.ScrollTo(selected, position: ScrollToPosition.Center, animate: false);
|
|
|
-
|
|
|
- if (scrollToLast)
|
|
|
- {
|
|
|
- Items.ScrollTo(_models.Count);
|
|
|
- }
|
|
|
-
|
|
|
- CheckSaveButton();
|
|
|
- }
|
|
|
-
|
|
|
- void CheckSaveButton()
|
|
|
- {
|
|
|
- Save.IsEnabled = !String.IsNullOrEmpty(_notes)
|
|
|
- && _photos.Any()
|
|
|
- //&& _movements.Any();
|
|
|
- //&& (_type == StockMovementBatchType.Stocktake ? _movements.Count == _models.Count : true);
|
|
|
- && (_type == StockMovementBatchType.Stocktake ? true : _movements.Any());
|
|
|
-
|
|
|
- }
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region Create / Load a movement (stockmovement page)
|
|
|
- protected void EditMovement(StockHolding holding)
|
|
|
- {
|
|
|
- StockItemModel model = _models.FirstOrDefault(x => x.Holding == holding);
|
|
|
-
|
|
|
- StockMovement movement = CreateMovement(holding, "");
|
|
|
-
|
|
|
- _movementpage = new StockMovementPage(holding, movement, model.Image, _type);
|
|
|
- _movementpage.OnSaveMovement += (m) =>
|
|
|
- {
|
|
|
- double qty = m.Received - m.Issued;
|
|
|
-
|
|
|
- bool bSave = true;
|
|
|
-
|
|
|
- if ((_type != StockMovementBatchType.Stocktake) && (qty == 0.0F))
|
|
|
- bSave = false;
|
|
|
-
|
|
|
- if ((_type == StockMovementBatchType.Transfer) && (movement.Location.ID == holding.Location.ID) && (movement.Job.ID == holding.Job.ID) && (movement.Style.ID == holding.Style.ID))
|
|
|
- bSave = false;
|
|
|
-
|
|
|
- if (bSave)
|
|
|
- {
|
|
|
- if (!_movements.ContainsKey(holding))
|
|
|
- _movements[holding] = movement;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (_movements.ContainsKey(holding))
|
|
|
- _movements.Remove(holding);
|
|
|
- }
|
|
|
- };
|
|
|
- Device.BeginInvokeOnMainThread(() =>
|
|
|
- {
|
|
|
- Navigation.PushAsync(_movementpage);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- private StockMovement CreateMovement(StockHolding holding, String note)
|
|
|
- {
|
|
|
- StockMovement movement = _movements.ContainsKey(holding) ? _movements[holding] : null;
|
|
|
- //var movement = _movements.FirstOrDefault(x => x.Product.ID.Equals(holding.Product.ID) && x.Style.ID.Equals(holding.Style.ID) && x.Job.ID.Equals(holding.Job.ID) && x.UnitSize.Equals(holding.UnitSize));
|
|
|
- if (movement == null)
|
|
|
- {
|
|
|
- movement = new StockMovement();
|
|
|
-
|
|
|
- movement.Product.ID = holding.Product.ID;
|
|
|
- movement.Product.Code = holding.Product.Code;
|
|
|
- movement.Product.Name = holding.Product.Name;
|
|
|
-
|
|
|
- movement.Style.ID = holding.Style.ID;
|
|
|
- movement.Style.Code = holding.Style.Code;
|
|
|
- movement.Style.Description = holding.Style.Description;
|
|
|
-
|
|
|
- movement.Job.ID = holding.Job.ID;
|
|
|
- movement.Job.JobNumber = holding.Job.JobNumber;
|
|
|
- movement.Job.Name = holding.Job.Name;
|
|
|
-
|
|
|
- movement.Location.ID = holding.Location.ID;
|
|
|
- movement.Location.Code = holding.Location.Code;
|
|
|
- movement.Location.Description = holding.Location.Description;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- movement.IsTransfer = _type == StockMovementBatchType.Transfer;
|
|
|
-
|
|
|
- movement.Notes = note;
|
|
|
- }
|
|
|
-
|
|
|
- return movement;
|
|
|
- }
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region Add / Display photos
|
|
|
- async void ChooseImage_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
- var file = await MediaPicker.PickPhotoAsync();
|
|
|
-
|
|
|
- if (file == null)
|
|
|
- return;
|
|
|
-
|
|
|
- using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving Photo"))
|
|
|
- {
|
|
|
- DisplayImage(file);
|
|
|
- }
|
|
|
-
|
|
|
- CheckSaveButton();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- async void TakePhoto_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
- var file = await MediaPicker.CapturePhotoAsync();
|
|
|
- if (file == null)
|
|
|
- return;
|
|
|
-
|
|
|
- using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving Photo"))
|
|
|
- {
|
|
|
- DisplayImage(file);
|
|
|
- }
|
|
|
-
|
|
|
- CheckSaveButton();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private async void DisplayImage(FileResult file)
|
|
|
- {
|
|
|
- var memoryStream = new MemoryStream();
|
|
|
- using (var stream = await file.OpenReadAsync())
|
|
|
- await stream.CopyToAsync(memoryStream);
|
|
|
- //file.GetStream().CopyTo(memoryStream);
|
|
|
- var data = memoryStream.ToArray();
|
|
|
-
|
|
|
- ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
|
|
|
- var img = new Image();
|
|
|
- img.HeightRequest = 150;
|
|
|
- img.WidthRequest = 150;
|
|
|
- img.Aspect = Aspect.AspectFit;
|
|
|
- img.Source = src;
|
|
|
- img.GestureRecognizers.Add(new TapGestureRecognizer
|
|
|
- {
|
|
|
- Command = new Command(OnTap),
|
|
|
- CommandParameter = src,
|
|
|
- NumberOfTapsRequired = 1
|
|
|
- });
|
|
|
-
|
|
|
- if (img != null)
|
|
|
- {
|
|
|
- _photos[Path.GetFileName(file.FileName)] = data;
|
|
|
- Device.BeginInvokeOnMainThread(() =>
|
|
|
- {
|
|
|
- ImageScroller.IsVisible = true;
|
|
|
- Images.Children.Add(img);
|
|
|
- });
|
|
|
- }
|
|
|
- //file.Dispose();
|
|
|
- }
|
|
|
-
|
|
|
- private void OnTap(object obj)
|
|
|
- {
|
|
|
- ImageViewerPage viewer = new ImageViewerPage(obj as ImageSource, null);
|
|
|
- Navigation.PushAsync(viewer);
|
|
|
- }
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region Saving
|
|
|
- async void Save_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
- #region Confirmation
|
|
|
- if ((_type == StockMovementBatchType.Stocktake) && (_movements.Count < _models.Count))
|
|
|
- {
|
|
|
- string chosenOption = await DisplayActionSheet("Not all items have been counted. Continue?", "Cancel", null, "Yes", "No");
|
|
|
- switch (chosenOption)
|
|
|
- {
|
|
|
- case "No":
|
|
|
- return;
|
|
|
- case "Cancel":
|
|
|
- return;
|
|
|
- case "Yes":
|
|
|
- foreach (var _model in _models)
|
|
|
- {
|
|
|
- if (!_movements.ContainsKey(_model.Holding))
|
|
|
- _movements[_model.Holding] = CreateMovement(_model.Holding, "** Item Not Confirmed **");
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- bool bClosePack = false;
|
|
|
- bool bAllGone = CheckAllGone();
|
|
|
- if (bAllGone && _istransient)
|
|
|
- {
|
|
|
- bClosePack = await MaterialDialog.Instance.ConfirmAsync(message: "It appears that this location is empty. Do you want to mark it as inactive?",
|
|
|
- title: "Close Location?",
|
|
|
- confirmingText: "Yes",
|
|
|
- dismissiveText: "No") == true;
|
|
|
- }
|
|
|
- if (_type == StockMovementBatchType.Issue)
|
|
|
- {
|
|
|
- foreach (var holding in _movements.Keys)
|
|
|
- {
|
|
|
- var movement = _movements[holding];
|
|
|
- if (movement.Job.ID == Guid.Empty)
|
|
|
- {
|
|
|
- DisplayAlert("Alert", "Job Number not present for Issue. Please address before saving", "OK");
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving"))
|
|
|
- {
|
|
|
- await Task.Run(() =>
|
|
|
- {
|
|
|
- // Create a Stock Movement Batch - wait for batch return
|
|
|
- StockMovementBatch batch = new StockMovementBatch()
|
|
|
- {
|
|
|
- Type = _type,
|
|
|
- Notes = _notes
|
|
|
- };
|
|
|
- new Client<StockMovementBatch>().Save(batch, "");
|
|
|
-
|
|
|
- // Save photos - async, no wait needed
|
|
|
- SavePhotos(batch.ID);
|
|
|
-
|
|
|
- // Now link the movements to the batch - async, no wait need
|
|
|
- LinkMovementsToBatch(batch);
|
|
|
- });
|
|
|
- }
|
|
|
- Navigation.PopAsync();
|
|
|
- }
|
|
|
-
|
|
|
- private async void SavePhotos(Guid batchID)
|
|
|
- {
|
|
|
- await Task.Run(() =>
|
|
|
- {
|
|
|
- List<Document> docs = new List<Document>();
|
|
|
- foreach (var filename in _photos.Keys)
|
|
|
- {
|
|
|
- Document doc = new Document()
|
|
|
- {
|
|
|
- FileName = filename,
|
|
|
- Data = _photos[filename],
|
|
|
- CRC = CoreUtils.CalculateCRC(_photos[filename]),
|
|
|
- TimeStamp = DateTime.Now
|
|
|
- };
|
|
|
- docs.Add(doc);
|
|
|
- }
|
|
|
- new Client<Document>().Save(docs, "");
|
|
|
-
|
|
|
- // Link the photos to the batch
|
|
|
- List<StockMovementBatchDocument> smds = new List<StockMovementBatchDocument>();
|
|
|
- foreach (var doc in docs)
|
|
|
- {
|
|
|
-
|
|
|
- var smd = new StockMovementBatchDocument();
|
|
|
- smd.EntityLink.ID = batchID;
|
|
|
- smd.DocumentLink.ID = doc.ID;
|
|
|
- smd.DocumentLink.FileName = doc.FileName;
|
|
|
- smds.Add(smd);
|
|
|
- }
|
|
|
- new Client<StockMovementBatchDocument>().Save(smds, "");
|
|
|
- });
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private bool CheckAllGone()
|
|
|
- {
|
|
|
- foreach (var holding in _holdings)
|
|
|
- {
|
|
|
- if (holding.Units != 0)
|
|
|
- {
|
|
|
- if (!_movements.ContainsKey(holding))
|
|
|
- return false;
|
|
|
- var movement = _movements[holding];
|
|
|
- if ((holding.Units + movement.Received - movement.Issued) != 0.00)
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- private async void LinkMovementsToBatch(StockMovementBatch batch)
|
|
|
- {
|
|
|
- await Task.Run(() =>
|
|
|
- {
|
|
|
- List<StockMovement> updates = new List<StockMovement>();
|
|
|
- foreach (var holding in _movements.Keys)
|
|
|
- {
|
|
|
- var movement = _movements[holding];
|
|
|
-
|
|
|
- bool bValid = true;
|
|
|
-
|
|
|
- if (_type == StockMovementBatchType.Transfer)
|
|
|
- {
|
|
|
- if ((movement.Location.ID != holding.Location.ID) || (movement.Style.ID != holding.Style.ID) || (movement.Job.ID != holding.Job.ID))
|
|
|
- {
|
|
|
- var xferout = new StockMovement();
|
|
|
- xferout.Product.ID = holding.Product.ID;
|
|
|
- xferout.Style.ID = holding.Style.ID;
|
|
|
- xferout.Job.ID = holding.Job.ID;
|
|
|
- xferout.Issued = movement.Received;
|
|
|
- xferout.IsTransfer = true;
|
|
|
-
|
|
|
- xferout.Batch.ID = batch.ID;
|
|
|
- xferout.Date = batch.Created;
|
|
|
- xferout.Location.ID = _locationid;
|
|
|
- xferout.Notes = String.IsNullOrWhiteSpace(xferout.Notes) ? _notes : String.Format("{0}\n{1}", xferout.Notes, _notes);
|
|
|
- xferout.Employee.ID = App.Data.Me.ID;
|
|
|
- updates.Add(xferout);
|
|
|
-
|
|
|
- movement.Batch.ID = batch.ID;
|
|
|
- movement.Date = batch.Created;
|
|
|
- movement.Notes = String.IsNullOrWhiteSpace(movement.Notes) ? _notes : String.Format("{0}\n{1}", movement.Notes, _notes);
|
|
|
- movement.Employee.ID = App.Data.Me.ID;
|
|
|
- }
|
|
|
- else
|
|
|
- bValid = false;
|
|
|
- }
|
|
|
- else if (_type == StockMovementBatchType.Issue)
|
|
|
- {
|
|
|
- if (movement.Job.ID != holding.Job.ID)
|
|
|
- {
|
|
|
- var xferout = new StockMovement();
|
|
|
- xferout.Product.ID = holding.Product.ID;
|
|
|
- xferout.Style.ID = holding.Style.ID;
|
|
|
- xferout.Job.ID = holding.Job.ID;
|
|
|
- xferout.Issued = movement.Issued;
|
|
|
- xferout.IsTransfer = true;
|
|
|
- updates.Add(xferout);
|
|
|
-
|
|
|
- var xferin = new StockMovement();
|
|
|
- xferin.Product.ID = holding.Product.ID;
|
|
|
- xferin.Style.ID = holding.Style.ID;
|
|
|
- xferin.Job.ID = movement.Job.ID;
|
|
|
- xferin.Received = movement.Issued;
|
|
|
- xferin.IsTransfer = true;
|
|
|
- updates.Add(xferin);
|
|
|
- }
|
|
|
- }
|
|
|
- if (bValid)
|
|
|
- updates.Add(movement);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if (_type != StockMovementBatchType.Transfer)
|
|
|
- {
|
|
|
- foreach (var update in updates)
|
|
|
- {
|
|
|
- update.Batch.ID = batch.ID;
|
|
|
- update.Date = batch.Created;
|
|
|
- update.Location.ID = _locationid;
|
|
|
- update.Notes = String.IsNullOrWhiteSpace(update.Notes) ? _notes : String.Format("{0}\n{1}", update.Notes, _notes);
|
|
|
- update.Employee.ID = App.Data.Me.ID;
|
|
|
- }
|
|
|
- }
|
|
|
- new Client<StockMovement>().Save(updates, "");
|
|
|
- Device.BeginInvokeOnMainThread(() =>
|
|
|
- {
|
|
|
- DisplayAlert("Success", "Updates saved", "OK");
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region Note / New Product / All clicked
|
|
|
- void AddNote_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
- _notespage = new NotesPage("Stock Movement Notes", _notes);
|
|
|
- _notespage.TextChanged += (o, t) =>
|
|
|
- {
|
|
|
- _notes = t;
|
|
|
- };
|
|
|
- Navigation.PushAsync(_notespage);
|
|
|
- }
|
|
|
-
|
|
|
- async void NewProduct_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
- _newpage = new NewHoldingPage(job);
|
|
|
- _newpage.OnSaveHolding += async (holding, image) =>
|
|
|
- {
|
|
|
- Items.ItemsSource = null;
|
|
|
- if (image != null)
|
|
|
- _images.Add(image);
|
|
|
- _holdings.Add(holding);
|
|
|
- RefreshScreen(true);
|
|
|
- await Task.Run(() =>
|
|
|
- {
|
|
|
- EditMovement(holding);
|
|
|
- });
|
|
|
- };
|
|
|
- Navigation.PushAsync(_newpage);
|
|
|
- }
|
|
|
-
|
|
|
- async void All_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
-
|
|
|
- GenericSelectionPage page = null;
|
|
|
-
|
|
|
- if (_type == StockMovementBatchType.Transfer)
|
|
|
- {
|
|
|
-
|
|
|
- var options = new MaterialRadioButtonGroup()
|
|
|
- {
|
|
|
- Choices = new string[]
|
|
|
- {
|
|
|
- "Transfer to Another Job",
|
|
|
- "Transfer to Another Location"
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- bool? wasConfirmed = await MaterialDialog.Instance.ShowCustomContentAsync(options, "What type of transfer do you want to create?", "Select Transfer Type");
|
|
|
-
|
|
|
-
|
|
|
- if (wasConfirmed == true)
|
|
|
- {
|
|
|
- page = options.SelectedIndex == 0 ? CreateJobPage() : CreateLocationPage();
|
|
|
-
|
|
|
- await Navigation.PushAsync(page);
|
|
|
- }
|
|
|
- }
|
|
|
- else if (_type == StockMovementBatchType.Issue)
|
|
|
- {
|
|
|
-
|
|
|
- var options = new MaterialRadioButtonGroup()
|
|
|
- {
|
|
|
- Choices = new string[]
|
|
|
- {
|
|
|
- "Issue all items to a selected Job",
|
|
|
- "Issue each item to its allocated Job"
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- bool? wasConfirmed = await MaterialDialog.Instance.ShowCustomContentAsync(options, "Where do you want to issue these items to?", "Select Issue Type");
|
|
|
-
|
|
|
-
|
|
|
- if (wasConfirmed == true)
|
|
|
- {
|
|
|
- if (options.SelectedIndex == 0)
|
|
|
- {
|
|
|
- page = CreateJobPage();
|
|
|
- await Navigation.PushAsync(page);
|
|
|
- }
|
|
|
- else if (options.SelectedIndex == 1)
|
|
|
- {
|
|
|
- IssueToJob(_holdings, null);
|
|
|
- Device.BeginInvokeOnMainThread(() => { RefreshScreen(false); });
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private GenericSelectionPage CreateJobPage()
|
|
|
- {
|
|
|
- GenericSelectionPage page = new GenericSelectionPage(
|
|
|
- "Select Job",
|
|
|
- new SelectionViewModel<Job>(
|
|
|
- new Filter<Job>(X => X.JobStatus.Active).IsEqualTo(true),
|
|
|
- new Expression<Func<Job, object>>[] { X => X.JobNumber, X => X.Name },
|
|
|
- new Expression<Func<Job, object>>[] { },
|
|
|
- new SortOrder<Job>(x => x.JobNumber)
|
|
|
- )
|
|
|
- );
|
|
|
- page.OnItemSelected += (o,e) =>
|
|
|
- {
|
|
|
-
|
|
|
- var job = e.Row.ToObject<Job>();
|
|
|
- _movements.Clear();
|
|
|
- IssueToJob(_holdings, job);
|
|
|
- Device.BeginInvokeOnMainThread(() => { RefreshScreen(false); });
|
|
|
- };
|
|
|
- return page;
|
|
|
- }
|
|
|
-
|
|
|
- private void IssueToJob(IEnumerable<StockHolding> holdings, Job job)
|
|
|
- {
|
|
|
- foreach (var holding in holdings)
|
|
|
- {
|
|
|
-
|
|
|
- var movement = new StockMovement();
|
|
|
-
|
|
|
- movement.Product.ID = holding.Product.ID;
|
|
|
- movement.Product.Code = holding.Product.Code;
|
|
|
- movement.Product.Name = holding.Product.Name;
|
|
|
-
|
|
|
- movement.Style.ID = holding.Style.ID;
|
|
|
- movement.Style.Code = holding.Style.Code;
|
|
|
- movement.Style.Description = holding.Style.Description;
|
|
|
-
|
|
|
- if (job != null)
|
|
|
- {
|
|
|
- movement.Job.ID = job.ID;
|
|
|
- movement.Job.Synchronise(job);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- movement.Job.ID = holding.Job.ID;
|
|
|
- movement.Job.JobNumber = holding.Job.JobNumber;
|
|
|
- movement.Job.Name = holding.Job.Name;
|
|
|
- }
|
|
|
-
|
|
|
- movement.Location.ID = holding.Location.ID;
|
|
|
- movement.Location.Code = holding.Location.Code;
|
|
|
- movement.Location.Description = holding.Location.Description;
|
|
|
-
|
|
|
-
|
|
|
- movement.Issued = holding.Units;
|
|
|
-
|
|
|
- movement.IsTransfer = _type == StockMovementBatchType.Issue;
|
|
|
-
|
|
|
- _movements[holding] = movement;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private GenericSelectionPage CreateLocationPage()
|
|
|
- {
|
|
|
- GenericSelectionPage page = new GenericSelectionPage(
|
|
|
- "Select Location",
|
|
|
- new SelectionViewModel<StockLocation>(
|
|
|
- new Filter<StockLocation>(X => X.Active).IsEqualTo(true),
|
|
|
- new Expression<Func<StockLocation, object>>[] { X => X.Code, X => X.Description },
|
|
|
- new Expression<Func<StockLocation, object>>[] { },
|
|
|
- new SortOrder<StockLocation>(x => x.Code)
|
|
|
- )
|
|
|
- );
|
|
|
- page.OnItemSelected += (o,e) =>
|
|
|
- {
|
|
|
-
|
|
|
- var location = e.Row.ToObject<StockLocation>();
|
|
|
- foreach (var holding in _holdings)
|
|
|
- {
|
|
|
- var movement = new StockMovement();
|
|
|
-
|
|
|
- movement.Product.ID = holding.Product.ID;
|
|
|
- movement.Product.Code = holding.Product.Code;
|
|
|
- movement.Product.Name = holding.Product.Name;
|
|
|
-
|
|
|
- movement.Style.ID = holding.Style.ID;
|
|
|
- movement.Style.Code = holding.Style.Code;
|
|
|
- movement.Style.Description = holding.Style.Description;
|
|
|
-
|
|
|
- movement.Job.ID = holding.Job.ID;
|
|
|
- movement.Job.JobNumber = holding.Job.JobNumber;
|
|
|
- movement.Job.Name = holding.Job.Name;
|
|
|
-
|
|
|
- movement.Location.ID = location.ID;
|
|
|
- movement.Location.Synchronise(location);
|
|
|
-
|
|
|
-
|
|
|
- movement.Issued = holding.Units;
|
|
|
-
|
|
|
- movement.IsTransfer = _type == StockMovementBatchType.Transfer;
|
|
|
-
|
|
|
- _movements[holding] = movement;
|
|
|
- }
|
|
|
- Device.BeginInvokeOnMainThread(() => { RefreshScreen(false); });
|
|
|
- };
|
|
|
- return page;
|
|
|
- }
|
|
|
- #endregion
|
|
|
-
|
|
|
- void ShowItems_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
- Completion.IsVisible = false;
|
|
|
- Contents.IsVisible = true;
|
|
|
-
|
|
|
- ShowItems.Background = new SolidColorBrush(Color.FromHex("#7F0864"));
|
|
|
- //ShowItems.CornerRadius = 5;
|
|
|
- //ShowItems.Margin = new Thickness(5,5,0,5);
|
|
|
-
|
|
|
- ShowCompletion.Background = new SolidColorBrush(Color.FromHex("#087f23"));
|
|
|
- //ShowCompletion.CornerRadius = 5;
|
|
|
- //ShowCompletion.Margin = new Thickness(0,5,5,5);
|
|
|
- ForceLayout();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- void ShowCompletion_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
- Contents.IsVisible = false;
|
|
|
- Completion.IsVisible = true;
|
|
|
-
|
|
|
- ShowItems.Background = new SolidColorBrush(Color.FromHex("#087f23"));
|
|
|
- //ShowItems.CornerRadius = 5;
|
|
|
- //ShowItems.Margin = new Thickness(5, 5, 0, 5);
|
|
|
-
|
|
|
- ShowCompletion.Background = new SolidColorBrush(Color.FromHex("#7F0864"));
|
|
|
- //ShowCompletion.CornerRadius = 5;
|
|
|
- //ShowCompletion.Margin = new Thickness(0, 5, 5, 5);
|
|
|
- ForceLayout();
|
|
|
- }
|
|
|
-
|
|
|
- //void Items_ItemSelected(System.Object sender, Xamarin.Forms.SelectedItemChangedEventArgs e)
|
|
|
- //{
|
|
|
- // StockItemModel model = e.SelectedItem as StockItemModel;
|
|
|
- // EditMovement(model.Holding);
|
|
|
- //}
|
|
|
-
|
|
|
- //void Edit_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- //{
|
|
|
- // StockItemModel model = Items.SelectedItem as StockItemModel;
|
|
|
- // EditMovement(model.Holding);
|
|
|
- //}
|
|
|
-
|
|
|
-
|
|
|
- void Card_Clicked(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
- var model = ((MobileCard)sender).BindingContext as StockItemModel;
|
|
|
- EditMovement(model.Holding);
|
|
|
- }
|
|
|
-
|
|
|
- void Card_Focused(System.Object sender, Xamarin.Forms.FocusEventArgs e)
|
|
|
- {
|
|
|
- var model = ((MobileCard)sender).BindingContext as StockItemModel;
|
|
|
- EditMovement(model.Holding);
|
|
|
- }
|
|
|
-
|
|
|
- void Items_ItemTapped(System.Object sender, Xamarin.Forms.ItemTappedEventArgs e)
|
|
|
- {
|
|
|
- var model = e.Item as StockItemModel;
|
|
|
- EditMovement(model.Holding);
|
|
|
- }
|
|
|
-
|
|
|
- void TapGestureRecognizer_Tapped(System.Object sender, System.EventArgs e)
|
|
|
- {
|
|
|
- var model = ((Frame)sender).BindingContext as StockItemModel;
|
|
|
- EditMovement(model.Holding);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-}
|