using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Comal.Classes;
using InABox.Clients;
using InABox.Core;
using InABox.DynamicGrid;
using InABox.WPF;
using Motorola.Snapi;
using Motorola.Snapi.Constants.Enums;
using Motorola.Snapi.EventArguments;
//using RestSharp;
namespace PRSDesktop
{
///
/// Interaction logic for RequisitionPanel.xaml
///
public partial class RequisitionPanel : UserControl, IPanel
{
private Requisition _requisition;
public List Scanners = new();
public RequisitionPanel()
{
InitializeComponent();
PickImage.Source = PRSDesktop.Resources.tick.AsBitmapImage(Color.White);
StockImage.Source = PRSDesktop.Resources.forklift.AsBitmapImage(Color.White);
TruckImage.Source = PRSDesktop.Resources.truck.AsBitmapImage();
}
//DateTime lastselection = DateTime.MaxValue;
//DispatcherTimer timer = new DispatcherTimer();
public event DataModelUpdateEvent OnUpdateDataModel;
public bool IsReady { get; set; }
public Dictionary Selected()
{
return new Dictionary
{
{ typeof(Requisition).EntityName(), Requisitions.SelectedRows },
{ typeof(RequisitionItem).EntityName(), Items.SelectedRows }
};
}
public void Setup()
{
//Requisitions.OnSelectItem += Requisitions_OnSelectItem;
//Requisitions.OnRequisitionFillStateChanged += Requisitions_OnRequisitionFillStateChanged;
//Requisitions.OnRequisitionBoxesChanged += Requisitions_OnRequisitionBoxesChanged;
SetupScanner();
Requisitions.Refresh(true, false);
Items.Refresh(true, false);
UpdateLayout();
}
public void Shutdown()
{
ShutdownScanner();
}
public void CreateToolbarButtons(IPanelHost host)
{
//host.CreatePanelAction(new PanelAction() { Caption = "Archive Requisition", Image = PRSDesktop.Resources.delete, OnExecute = ArchiveRequisition });
}
public string SectionName => "Requisitions";
public DataModel DataModel(Selection selection)
{
var ids = Requisitions.ExtractValues(x => x.ID, selection).ToArray();
return new BaseDataModel(new Filter(x => x.ID).InList(ids));
}
public void Refresh()
{
Requisitions.Refresh(false, true);
//lastselection = DateTime.MinValue;
//Items.Refresh(true, false);
}
public void Heartbeat(TimeSpan time)
{
// Nothing to do here
}
private void ShutdownScanner()
{
try
{
foreach (var scanner in Scanners) scanner.Actions.ToggleLed(LedMode.GreenOff);
BarcodeScannerManager.Instance.DataReceived -= Instance_DataReceived;
BarcodeScannerManager.Instance.Close();
}
catch (Exception e)
{
MessageBox.Show("Error Shutting down Scanner!\n\n" + e.Message);
}
}
private void SetupScanner()
{
Scanners.Clear();
BarcodeScannerManager.Instance.Open();
BarcodeScannerManager.Instance.RegisterForEvents(EventType.Barcode, EventType.Pnp, EventType.Image, EventType.Other, EventType.Rmd);
BarcodeScannerManager.Instance.GetDevices();
foreach (var scanner in BarcodeScannerManager.Instance.GetDevices())
{
Scanners.Add(scanner);
scanner.Actions.ToggleLed(LedMode.RedOn);
scanner.Actions.SoundBeeper(BeepPattern.FastWarble);
}
BarcodeScannerManager.Instance.DataReceived += Instance_DataReceived;
}
private void Instance_DataReceived(object sender, BarcodeScanEventArgs e)
{
Dispatcher.Invoke(() => { ProcessCode(Scanners[(int)e.ScannerId], e.Data); });
}
private void ProcessCode(IMotorolaBarcodeScanner scanner, string code)
{
try
{
var iRow = Requisitions.SelectedRows.First().Index;
if (iRow == -1)
throw new Exception("Please select a Requsition First");
var row = Requisitions.Data.Rows[iRow];
var filled = row.Get(x => x.Filled);
if (!filled.IsEmpty())
throw new Exception("Cannot Add Items to a completed Requisition");
var reqid = row.Get(x => x.ID);
var boxes = row.Get(x => x.Boxes);
var sCode = code;
var iQty = 1;
if (sCode.Contains("*"))
{
var comps = sCode.Split('*');
sCode = comps[0];
iQty = int.Parse(comps[1].Trim());
}
RequisitionItem item = null;
CoreRow itemrow = null;
try
{
itemrow = Items.Data.Rows.FirstOrDefault(r => /* r.Get(x => x.BoxNumber).Equals(boxes) && */
r.Get(x => x.BarCode).Equals(sCode));
//itemrow = Items.Data.Rows.FirstOrDefault(r => r.Get(x => x.BarCode).Equals(sCode));
}
catch (Exception e)
{
Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
}
if (itemrow != null)
item = new Client()
.Load(new Filter(x => x.ID).IsEqualTo(itemrow.Get(x => x.ID))).FirstOrDefault();
if (item != null)
{
item.Quantity += iQty;
new Client().Save(item, "Quantity Updated by Barcode Scanner");
if (scanner != null)
scanner.Actions.SoundBeeper(BeepPattern.LowHigh);
Refresh();
}
else
{
var product = new Client().Load(new Filter(x => x.Code).IsEqualTo(sCode)).FirstOrDefault();
if (product != null)
{
item = new RequisitionItem
{
RequisitionLink = new RequisitionLink { ID = reqid },
//BoxNumber = boxes,
Code = product.Code,
Description = product.Name,
BarCode = sCode,
Quantity = iQty
};
new Client().Save(item, "Scanned by Barcode Reader");
if (scanner != null)
scanner.Actions.SoundBeeper(BeepPattern.LowHigh);
Refresh();
}
else
{
if (scanner != null)
scanner.Actions.SoundBeeper(BeepPattern.FourLowLong);
}
}
}
catch (Exception e)
{
if (scanner != null)
scanner.Actions.SoundBeeper(BeepPattern.FourLowShort);
}
}
private void ArchiveRequisition(PanelAction obj)
{
var bClosed = false;
var iRow = Requisitions.SelectedRows.First().Index;
if (iRow > -1)
{
var row = Requisitions.Data.Rows[iRow];
var id = row.Get(x => x.ID);
var filled = row.Get(x => x.Filled);
if (filled.IsEmpty())
{
MessageBox.Show("Please complete this requisition before Archiving it!");
}
else
{
var req = new Client().Load(new Filter(x => x.ID).IsEqualTo(id)).FirstOrDefault();
if (req != null)
{
req.Archived = DateTime.Now;
new Client().Save(req, "Requisition Archived");
bClosed = true;
}
}
}
else
{
MessageBox.Show("Please select a requisition first!");
}
if (bClosed)
Refresh();
}
public Dictionary DataEnvironment()
{
var env = new Dictionary();
env[typeof(Requisition)] = Requisitions.Data;
env[typeof(RequisitionItem)] = Items.Data;
return env;
}
//private void Timer_Tick(object sender, EventArgs e)
//{
// if (lastselection < DateTime.Now.AddMilliseconds(-500))
// {
// lastselection = DateTime.MaxValue;
// LoadRequisition();
// }
//}
private void LoadRequisition()
{
foreach (var scanner in Scanners)
scanner.Actions.ToggleLed(_requisition != null ? LedMode.GreenOn : LedMode.RedOn);
Title.Text = _requisition != null ? _requisition.Title : "";
RequestedBy.Content = _requisition != null ? _requisition.RequestedBy.Name : "";
DueDate.Content = _requisition != null ? string.Format("{0:dddd, dd MMM yyyy}", _requisition.Due) : "";
var notes = _requisition != null ? _requisition.Notes : new string[] { };
var request = _requisition != null ? CoreUtils.StripHTML(_requisition.Request) : "";
Request.Text = string.Join("\n===============================\n", Utility.ProcessNotes(notes, request));
MarkAsFilled.IsEnabled = _requisition != null && _requisition.Archived.IsEmpty() && _requisition.StockUpdated.IsEmpty();
MarkAsFilledDescription.Content = _requisition == null || _requisition.Filled.IsEmpty() ? "Mark As Filled" : "Clear Filled Flag";
Items.Options.BeginUpdate();
if (_requisition != null)
{
if (_requisition.Filled.IsEmpty())
{
Items.Options.Add(DynamicGridOption.AddRows);
Items.Options.Add(DynamicGridOption.DeleteRows);
}
else
{
Items.Options.Remove(DynamicGridOption.AddRows);
Items.Options.Remove(DynamicGridOption.DeleteRows);
}
}
Items.Options.EndUpdate();
UpdateStock.IsEnabled = Security.IsAllowed() && _requisition != null &&
!_requisition.Filled.IsEmpty();
UpdateStockDescription.Content =
_requisition == null || _requisition.StockUpdated.IsEmpty() ? "Update Stock Holdings" : "Clear Stock Movements";
TakenBy.IsEnabled = _requisition != null && !_requisition.Filled.IsEmpty() && _requisition.Archived.IsEmpty() &&
!_requisition.Delivery.IsValid();
TakenByDescription.Content = _requisition == null
? "Select Employee"
: _requisition.Delivery.IsValid()
? _requisition.Delivery.Completed.IsEmpty()
? string.Format("Booked On Delivery #{0}", _requisition.Delivery.Number)
: string.Format("Delivered on {0:dd MMM yy} (#{1})", _requisition.Delivery.Completed, _requisition.Delivery.Number)
: _requisition.TakenBy.IsValid()
? string.Format("{0} ({1:dd MMM yy})", _requisition.TakenBy.Name, _requisition.Archived)
: "Select Employee";
}
private void Requisitions_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
{
_requisition = e.Rows?.FirstOrDefault()?.ToObject();
LoadRequisition();
Items.Requisition = _requisition;
Items.Refresh(false, true);
//lastselection = DateTime.Now;
//Dispatcher.Invoke(() => { LoadRequisition(); });
}
private void TakenBy_Click(object sender, RoutedEventArgs e)
{
if (_requisition == null || _requisition.ID == Guid.Empty)
return;
var dlg = new MultiSelectDialog(
LookupFactory.DefineFilter(),
LookupFactory.DefineColumns(),
false);
if (!dlg.ShowDialog())
return;
if (!_requisition.Filled.IsEmpty() && !_requisition.StockUpdated.IsEmpty())
if (MessageBox.Show("This will remove this requisition from this list.\nAre you sure you wish to continue?", "Close Requisition?",
MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
return;
if (_requisition.Archived.IsEmpty())
_requisition.Archived = DateTime.Now;
var emp = dlg.Data()?.Rows.FirstOrDefault();
_requisition.TakenBy.ID = emp != null ? emp.Get(x => x.ID) : Guid.Empty;
_requisition.TakenBy.Name = emp != null ? emp.Get(x => x.Name) : "";
Progress.Show("Updating Requisition Delivery Status");
new Client().Save(_requisition, "Updated [TakenBy] Flag");
if (!_requisition.Filled.IsEmpty() && !_requisition.StockUpdated.IsEmpty() && !_requisition.Archived.IsEmpty())
{
Refresh();
}
else
{
Requisitions.UpdateRow(Requisitions.SelectedRows.First(), x => x.TakenBy.ID, _requisition.TakenBy.ID, false);
Requisitions.UpdateRow(Requisitions.SelectedRows.First(), x => x.TakenBy.Name, _requisition.TakenBy.Name, false);
Requisitions.UpdateRow(Requisitions.SelectedRows.First(), x => x.Archived, _requisition.Archived);
LoadRequisition();
}
Progress.Close();
}
private void MarkAsFilled_Click(object sender, RoutedEventArgs e)
{
if (_requisition == null)
{
MessageBox.Show("Please select a Requisition first!");
return;
}
DateTime filltime = DateTime.Now;
var unpickeditems = Items.Data.Rows.Where(r =>
_requisition.Filled.IsEmpty()
&& (r.Get(x => x.Product.ID) != Guid.Empty)
&& (r.Get(x => x.Product.NonStock) != true)
&& (r.Get(x => x.Picked).IsEmpty())
);
if (unpickeditems.Any())
{
var confirm = MessageBox.Show("Unpicked items exist on this requisition!\n\nDo you want to mark them as picked now?",
"Unpicked Items", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
if (confirm == MessageBoxResult.Cancel)
return;
filltime = DateTime.Now;
if (confirm == MessageBoxResult.Yes)
{
List updates = new List();
foreach (var row in unpickeditems)
{
var item = row.ToObject();
item.Picked = filltime;
updates.Add(item);
}
new Client().Save(updates, "Marked as Picked because Requisition was marked as filled");
}
}
_requisition.Filled = _requisition.Filled.IsEmpty() ? filltime : DateTime.MinValue;
Progress.Show(_requisition.Filled.IsEmpty() ? "Clearing Delivery Items" : "Creating Delivery Items");
new Client().Save(_requisition, "Updated Filled Flag");
Requisitions.UpdateRow(Requisitions.SelectedRows.First(), x => x.Filled, _requisition.Filled);
LoadRequisition();
Items.Refresh(false, true);
Progress.Close();
}
private void UpdateStock_Click(object sender, RoutedEventArgs e)
{
if (_requisition == null)
{
MessageBox.Show("Please select a Requisition first!");
return;
}
if (_requisition.StockUpdated.IsEmpty())
{
var emptyrows = Items.Data.Rows.Where(r =>
!Entity.IsEntityLinkValid(x => x.Location, r) &&
r.Get(c => c.Product.NonStock).Equals(false));
if (emptyrows.Any())
{
MessageBox.Show("You must select a Holding for each non-stock Item on this Requisition!", "Missing Holdings", MessageBoxButton.OK,
MessageBoxImage.Error);
return;
}
if (!_requisition.Filled.IsEmpty() && !_requisition.Archived.IsEmpty())
{
if (MessageBox.Show("This will remove this requisition from this list.\nAre you sure you wish to continue?", "Close Requisition?",
MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
return;
}
else
{
if (MessageBox.Show("Update Stock Movements?", "Confirm", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
return;
}
_requisition.StockUpdated = DateTime.Now;
}
else
{
if (MessageBox.Show("Clear Stock Movements?", "Confirm", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
return;
_requisition.StockUpdated = DateTime.MinValue;
}
Progress.Show("Updating Stock Holdings");
new Client().Save(_requisition, "Updated Stock Flag");
if (!_requisition.Filled.IsEmpty() && !_requisition.StockUpdated.IsEmpty() && !_requisition.Archived.IsEmpty())
{
Refresh();
}
else
{
Requisitions.UpdateRow(Requisitions.SelectedRows.First(), x => x.StockUpdated, _requisition.StockUpdated);
LoadRequisition();
}
Progress.Close();
}
}
}