using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Comal.Classes;
using InABox.Clients;
using InABox.Configuration;
using InABox.Core;
using InABox.DynamicGrid;
using InABox.Core.Reports;
using InABox.Wpf.Reports;
using InABox.WPF;
using Motorola.Snapi;
using Motorola.Snapi.Constants.Enums;
using Motorola.Snapi.EventArguments;
using BarcodeType = Comal.Classes.BarcodeType;
using Color = System.Drawing.Color;
using Image = System.Windows.Controls.Image;
using InABox.Wpf;
using System.ComponentModel;
namespace PRSDesktop
{
///
/// Interaction logic for FactoryPanel.xaml
///
public partial class FactoryPanel : IPanel
{
private readonly BitmapImage barcode = PRSDesktop.Resources.barcode.AsBitmapImage();
private readonly BitmapImage disabled = PRSDesktop.Resources.disabled.AsBitmapImage();
private readonly BitmapImage speechbubble = PRSDesktop.Resources.speechbubble.AsBitmapImage();
private readonly BitmapImage starred = PRSDesktop.Resources.report.AsBitmapImage(48, 48);
private readonly BitmapImage grouped = PRSDesktop.Resources.grouped.AsBitmapImage();
private SetoutDocument[] documents = Array.Empty();
private readonly List _scanners = new List();
private readonly string NEARLYDUE_COLOR = "Orange";
private readonly string NOTYETDUE_COLOR = "PaleGreen";
private readonly string OVERDUE_COLOR = "Salmon";
private readonly string PRIORITY_COLOR = "Red";
private readonly string QA_COLOR = "Silver";
private readonly string SELECTED_COLOR = "Yellow";
private readonly string SHARED_COLOR = "Lime";
private readonly string TREATED_COLOR = "DarkOrchid";
private Button? _currentButton;
private PDFEditorControl? PDFEditor;
private QAGrid? QAGrid;
private readonly FactoryFloorLocalSettings _settings;
private readonly PanelAction _togglePackPanel;
public FactoryPanel()
{
_settings = new LocalConfiguration().Load();
if (_settings.Section.Equals(CoreUtils.FullGuid) && _settings.Station.Equals(-1))
{
var user = new UserConfiguration().Load();
_settings.Section = user.Section;
_settings.Station = user.Station;
new LocalConfiguration().Save(_settings);
}
InitializeComponent();
var CanConfigure = Security.IsAllowed();
Section.IsEnabled = CanConfigure;
Station.IsEnabled = CanConfigure;
PendingVisible = Security.IsAllowed();
Kanbans = new ObservableCollection();
RackContents.ItemsSource = rackcontents;
RackPanel.Visibility = _settings.SidePanel == FactorySidePanel.Racks
? Visibility.Visible
: Visibility.Collapsed;
PackPanel.Visibility = _settings.SidePanel == FactorySidePanel.Packs
? Visibility.Visible
: Visibility.Collapsed;
}
public bool IsReady { get; set; }
public void Setup()
{
var setups = new MultiQuery();
setups.Add();
setups.Add(
new Filter(x => x.Hidden).IsEqualTo(false),
null,
new SortOrder(x => x.Factory.Sequence).ThenBy(x => x.Sequence)
);
setups.Add();
setups.Add(
LookupFactory.DefineFilter(),
new Columns(x => x.ID, x => x.Name, x => x.UserLink.ID),
new SortOrder(x => x.Name)
);
setups.Add(
LookupFactory.DefineFilter(),
new Columns(x => x.ID, x => x.Code, x => x.Description, x => x.BarCode)
);
if (_settings.AreaID != Guid.Empty)
setups.Add(
new Filter(x=>x.ID).IsEqualTo(_settings.AreaID),
new Columns(x=>x.ID).Add(x=>x.Code).Add(x=>x.Description)
);
setups.Query();
Factories = setups.Get().Rows.Select(x => x.ToObject()).ToArray();
Sections = setups.Get().Rows.Select(x => x.ToObject()).ToArray();
Trolleys = setups.Get().Rows.Select(x => x.ToObject()).ToArray();
Shipments = setups.Get();
CurrentSection = Sections.FirstOrDefault(x => x.ID.Equals(_settings.Section))
?? Sections.FirstOrDefault();
var iSection = 0;
var iCount = 0;
foreach (var section in Sections)
{
if (section == CurrentSection)
{
iSection = Section.Items.Count;
iCount = section.Stations; //Sections[id].Item2;
}
Section.Items.Add($"{section.Factory.Name}: {section.Name}");
}
Section.SelectedIndex = iSection;
Station.Items.Clear();
for (var i = 1; i <= (CurrentSection?.Stations ?? 0); i++)
Station.Items.Add($"Station #{i}");
CurrentStation = _settings.Station + 1;
if (CurrentStation < 1)
CurrentStation = 1;
if (CurrentStation > iCount)
CurrentStation = iCount;
Station.SelectedIndex = CurrentStation - 1;
if (_settings.AreaID != Guid.Empty)
{
var area = setups.Get().ToObjects().FirstOrDefault();
if (area != null)
{
_packGrid.Area = area;
_areaDescription.Text = $"{area.Code}";
_addPack.IsEnabled = true;
}
else
{
_packGrid.Area = null;
_areaDescription.Text = "Set\r\nArea";
_settings.AreaID = Guid.Empty;
new LocalConfiguration().Save(_settings);
_addPack.IsEnabled = false;
}
}
else
{
_packGrid.Area = null;
_areaDescription.Text = "Set\r\nArea";
}
_packGrid.Refresh(true,true);
SetupScanner();
}
public void Shutdown(CancelEventArgs? cancel)
{
ShutdownScanner();
//UpdateTimeTracking(true);
LoadDrawing(null);
}
public void CreateToolbarButtons(IPanelHost host)
{
ManufacturingSetupActions.Standard(host);
//if (Security.IsAllowed())
// host.CreatePanelAction(new PanelAction() { Caption = "Self Assessment", Image = PRSDesktop.Resources.star, OnExecute = DoSelfAssessment });
host.CreatePanelAction(new PanelAction { Caption = "Lost Time", Image = PRSDesktop.Resources.smiley, OnExecute = DoSelectLostTime });
host.CreatePanelAction(new PanelAction
{ Caption = "Treament PO", Image = PRSDesktop.Resources.purchase, OnExecute = DoCreatePurchaseOrder });
host.CreatePanelAction(new PanelAction
{ Caption = "Treatment Delivery", Image = PRSDesktop.Resources.barcode, OnExecute = DoScanDeliveryItems });
host.CreatePanelAction(new PanelAction { Caption = "Select Rack", Image = PRSDesktop.Resources.forklift, OnExecute = DoSelectRack });
host.CreatePanelAction(new PanelAction { Caption = "Close Rack", Image = PRSDesktop.Resources.forklift, OnExecute = DoCloseRack });
host.CreatePanelAction(new PanelAction { Caption = "Scan Barcode", Image = PRSDesktop.Resources.product, OnExecute = DoScanBarcode });
host.CreatePanelAction(new PanelAction { Caption = _settings.SidePanel == FactorySidePanel.Packs ? "Hide Stock" : "Show Stock", Image = PRSDesktop.Resources.trolley, OnExecute = TogglePackPanel});
}
private void TogglePackPanel(PanelAction pa)
{
RackPanel.Visibility = Visibility.Collapsed;
PackPanel.Visibility = _settings.SidePanel == FactorySidePanel.Packs
? Visibility.Collapsed
: Visibility.Visible;
_settings.SidePanel = PackPanel.Visibility == Visibility.Visible
? FactorySidePanel.Packs
: FactorySidePanel.None;
new LocalConfiguration().Save(_settings);
pa.Caption = _settings.SidePanel == FactorySidePanel.Packs
? "Hide Stock"
: "Show Stock";
_addPack.IsEnabled = _settings.AreaID != Guid.Empty;
}
public Dictionary Selected()
{
var rows = Packets.Rows.Where(p => Kanbans.Any(k => k.Checked && p.Get(c => c.ID).ToString().Equals(k.ID)));
var pkts = rows.ToArray().Select(r => r.ToObject());
return new Dictionary { { typeof(ManufacturingPacket).EntityName(), pkts.ToArray() } };
}
public string SectionName => "Factory";
public DataModel DataModel(Selection selection)
{
var rows = (Packets == null) || (selection == Selection.None)
? new CoreRow[] { }
: selection == Selection.Selected
? Packets.Rows.Where(p => Kanbans.Any(k => k.Checked && p.Get(c => c.ID).ToString().Equals(k.ID)))
: Packets.Rows;
var ids = rows.Any() ? rows.Select(r => r.Get(x => x.ID)).ToArray() : new[] { CoreUtils.FullGuid };
return new ManufacturingPacketDataModel(new Filter(x => x.ID).InList(ids));
}
public event DataModelUpdateEvent? OnUpdateDataModel;
public void Heartbeat(TimeSpan time)
{
// Security Descriptor should be disabled for non-manufacturing staff
if (!Security.IsAllowed() || CurrentSection == null)
return;
// If Lost Time is Active, let's record that
if (LostTime != null)
{
var history = new ManufacturingHistory();
history.Date = DateTime.Today;
history.Employee.ID = App.EmployeeID;
history.Packet.ID = Guid.Empty;
history.LostTime.ID = LostTime.ID;
history.Description = LostTime.Description;
//history.Setout.ID = CheckedPackets[id].Item3;
//history.Job.ID = CheckedPackets[id].Item4;
history.Section.ID = CurrentSection.ID;
history.Station = CurrentStation;
history.Activity.ID = LostTime.Activity.ID;
history.WorkDuration = new TimeSpan(time.Ticks);
history.QACompleted = 0;
history.WorkCompleted = 0;
history.Window = time;
new Client().Save(history, "", (o, e) => { });
}
else
{
var CheckedPackets = new Dictionary>();
foreach (var kanban in Kanbans.Where(x => x.Checked))
{
var packet = KanbanToPacket(kanban);
if (packet != null)
{
var stagerow = Stages.Rows.FirstOrDefault(r => r.Get(c => c.Parent.ID).Equals(packet.ID)
&& r.Get(c => c.ManufacturingSectionLink.ID)
.Equals(_settings.Section));
if (stagerow != null)
{
var stage = stagerow.ToObject();
if (stage.Station != 0)
CheckedPackets[packet.ID] = new Tuple(stage.Started, stage.Completed,
packet.SetoutLink.ID, packet.SetoutLink.JobLink.ID, packet.Serial);
}
}
}
if (!CheckedPackets.Any())
CheckedPackets[Guid.Empty] =
new Tuple(DateTime.MinValue, DateTime.MinValue, Guid.Empty, Guid.Empty, "No Packet");
var updates = new List();
var slice = time.Ticks / CheckedPackets.Count;
foreach (var id in CheckedPackets.Keys)
{
var history = new ManufacturingHistory();
history.Date = DateTime.Today;
history.Employee.ID = App.EmployeeID;
history.Packet.ID = id;
history.Description = CheckedPackets[id].Item5;
//history.Setout.ID = CheckedPackets[id].Item3;
//history.Job.ID = CheckedPackets[id].Item4;
history.Section.ID = CurrentSection.ID;
history.Activity.ID = CurrentSection.Activity.ID;
history.Station = CurrentStation;
if (CheckedPackets[id].Item1.Equals(DateTime.MinValue))
history.QADuration = new TimeSpan(slice);
else
history.WorkDuration = new TimeSpan(slice);
history.QACompleted = CheckedPackets[id].Item1.Equals(DateTime.MinValue) ? 0 : 0;
history.WorkCompleted = CheckedPackets[id].Item2.Equals(DateTime.MinValue) ? 0 : 1;
history.Window = time;
updates.Add(history);
}
if (updates.Any())
new Client().Save(updates, "", (o, e) => { });
}
}
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 isGuid = Guid.TryParse(code, out var guid);
if (isGuid)
{
if (Sections.Any(x => x.ID.Equals(guid)))
{
IsReady = false;
CurrentSection = Sections.First(x => x.ID.Equals(guid));
Section.SelectedIndex = Array.IndexOf(Sections, CurrentSection);
IsReady = true;
Progress.Show("Changing Sections");
DoRefresh(true);
Progress.Close();
scanner?.Actions.SoundBeeper(BeepPattern.FastWarble);
}
else if (Trolleys.Any(x => x.ID.Equals(guid)))
{
var trolley = Trolleys.First().Code;
var updates = new List();
foreach (var kanban in Kanbans.Where(x => x.Checked))
{
var packet = KanbanToPacket(kanban);
packet.Trolleys = trolley;
updates.Add(packet);
var pktrow = Packets.Rows.FirstOrDefault(r => r.Get(c => c.ID).Equals(Guid.Parse(kanban.ID)));
var stagerow = Stages.Rows.FirstOrDefault(r => r.Get(c => c.Parent.ID).Equals(packet.ID)
&& r.Get(
c => c.ManufacturingSectionLink.ID)
.Equals(_settings.Section));
pktrow.Set(x => x.Trolleys, packet.Trolleys);
LoadModel(kanban, pktrow, stagerow, true);
UpdateSelectedKanban(false);
}
if (updates.Any())
new Client().Save(updates, "Set Trolley to " + trolley, (o, e) => { });
scanner?.Actions.SoundBeeper(BeepPattern.LowHigh);
}
else
{
scanner?.Actions.SoundBeeper(BeepPattern.FourLowShort);
}
}
else
{
var shiprow = Shipments.Rows.FirstOrDefault(r => r.Get(c => c.BarCode).Equals(code));
if (shiprow != null)
{
if (string.Equals(code, rackbarcode))
{
RackPanel.Visibility = Visibility.Collapsed;
_settings.SidePanel = FactorySidePanel.None;
new LocalConfiguration().Save(_settings);
RackContents.ItemsSource = null;
rackid = Guid.Empty;
rackbarcode = "";
scanner?.Actions.SoundBeeper(BeepPattern.ThreeLowShort);
}
else
{
RackContents.ItemsSource = null;
rackid = shiprow.Get(c => c.ID);
rackbarcode = code;
var rows = DeliveryItems.Rows.Where(r => r.Get(c => c.ShipmentLink.ID).Equals(rackid)).ToArray();
rackcontents.Clear();
rackcontents.AddRange(rows.Select(x => x.ToObject()));
RackContents.ItemsSource = rackcontents;
RackName.Content = $"Rack {shiprow.Get(c => c.Code)}";
RackCount.Content = rows.Length.ToString();
PackPanel.Visibility = Visibility.Collapsed;
RackPanel.Visibility = Visibility.Visible;
_settings.SidePanel = FactorySidePanel.Racks;
new LocalConfiguration().Save(_settings);
scanner?.Actions.SoundBeeper(BeepPattern.ThreeHighShort);
}
}
else
{
if (RackPanel.Visibility == Visibility.Visible)
{
var row = DeliveryItems.Rows.FirstOrDefault(r => r.Get(c => c.Barcode).Equals(code));
if (row != null)
{
var delitem = rackcontents.FirstOrDefault(x => string.Equals(x.Barcode, code));
if (delitem != null)
{
rackcontents.Remove(delitem);
delitem.ShipmentLink.ID = Guid.Empty;
new Client().Save(delitem, "Item Removed From Rack", (o, e) => { });
row.Set(x => x.ShipmentLink.ID, Guid.Empty);
scanner?.Actions.SoundBeeper(BeepPattern.HighLow);
}
else
{
delitem = row.ToObject();
delitem.ShipmentLink.ID = rackid;
rackcontents.Add(delitem);
new Client().Save(delitem, "Item Added to " + RackName.Content, (o, e) => { });
row.Set(x => x.ShipmentLink.ID, rackid);
if (Kanbans.Any(x => string.Equals(x.ID, delitem.ManufacturingPacketLink.ID.ToString())))
ReloadPackets(true);
scanner?.Actions.SoundBeeper(BeepPattern.LowHigh);
}
RackContents.ItemsSource = null;
RackContents.ItemsSource = rackcontents;
RackCount.Content = rackcontents.Count.ToString();
}
}
else
{
var id = new Client().Query(
new Filter(x => x.Barcode).IsEqualTo(code),
new Columns(x => x.ManufacturingPacketLink.ID)
).Rows.FirstOrDefault()?.Get(x => x.ManufacturingPacketLink.ID);
if (!id.HasValue)
{
scanner?.Actions.SoundBeeper(BeepPattern.FourLowShort);
return;
}
var kanban = Kanbans.FirstOrDefault(x => string.Equals(x.ID, id.Value.ToString()));
if (kanban == null)
{
// Error - packet not visible from this station
scanner?.Actions.SoundBeeper(BeepPattern.FourLowShort);
return;
}
var stage = Stages.Rows.FirstOrDefault(r => r.Get(c => c.Parent.ID).Equals(id)
&& r.Get(c => c.ManufacturingSectionLink.ID)
.Equals(_settings.Section))?.ToObject();
if (stage == null)
scanner?.Actions.SoundBeeper(BeepPattern.FourHighShort);
if (stage.Station == 0) AddPacketToCurrentWorkload(stage);
if (kanban != CurrentKanban)
{
CurrentKanban = kanban;
UpdateSelectedKanban(false);
}
scanner?.Actions.SoundBeeper(BeepPattern.LowHigh);
}
}
}
}
catch (Exception)
{
scanner?.Actions.SoundBeeper(BeepPattern.FourLowShort);
}
}
private void LoadDrawing(Guid? id)
{
if (PDFEditor != null)
{
PDFEditor.Document = null;
// Unload PDF Annotations
PDFEditor = null;
}
else if (QAGrid != null)
{
Editor.Content = null;
// Unload QA Answers
QAGrid = null;
}
if (id.HasValue)
{
var pktid = CurrentKanban != null ? Guid.Parse(CurrentKanban.ID) : Guid.Empty;
var row = Packets.Rows.FirstOrDefault(r => r.Get(c => c.ID).Equals(pktid));
var stagerow = Stages.Rows.FirstOrDefault(r => r.Get(c => c.Parent.ID).Equals(pktid)
&& r.Get(c => c.ManufacturingSectionLink.ID)
.Equals(_settings.Section));
var packet = row.ToObject();
if (id.Value == Guid.Empty)
{
QAGrid = new QAGrid();
var qadata = stagerow != null ? stagerow.Get(c => c.FormData) : "";
var values = string.IsNullOrWhiteSpace(qadata)
? new Dictionary()
: Serialization.Deserialize>(qadata);
if (CurrentSection != null && row != null)
{
var genquestions = LoadQAQuestions(packet, true, false);
QAGrid.LoadChecks("Global Checks for " + CurrentSection.Name, genquestions, values);
//var specquestions = LoadQAQuestions(packet, false, true);
//QAGrid.LoadChecks(String.Format("Specific Checks for {0} [{1}] template", packet.ManufacturingTemplateLink.Name, packet.ManufacturingTemplateLink.Code), specquestions, values);
}
QAGrid.OnChanged += QAGridChanged;
Editor.Content = QAGrid;
}
else
{
PDFEditor = new PDFEditorControl();
PDFEditor.LineColor = _settings.LineColor;
PDFEditor.TextSize = _settings.FontSize;
//PDFEditor.PrintAllowed = Security.IsAllowed();
PDFEditor.SaveAllowed = Security.IsAllowed();
var document = documents.FirstOrDefault(x => x.DocumentLink.ID.Equals(id));
PDFEditor.Watermark = packet.WaterMark;
PDFEditor.Document = document;
PDFEditor.PDFSettingsChanged += PDFEditorSettingsChanged;
Editor.Content = PDFEditor;
}
}
}
private void DoSelectRack(PanelAction obj)
{
var dlg = new MultiSelectDialog(
null,
new Columns(x => x.ID, x => x.Code, x => x.Description, x => x.BarCode),
false
);
if (dlg.ShowDialog())
{
var id = dlg.IDs().FirstOrDefault();
var barcode = dlg.Data().Rows.FirstOrDefault(r => r.Get(c => c.ID).Equals(id))?.Get(x => x.BarCode);
ProcessCode(_scanners.FirstOrDefault(), barcode);
}
}
private void DoCloseRack(PanelAction obj)
{
if (!string.IsNullOrWhiteSpace(rackbarcode))
ProcessCode(_scanners.FirstOrDefault(), rackbarcode);
}
private void DoScanBarcode(PanelAction obj)
{
var dlg = new MultiSelectDialog(
new Filter(x => x.DeliveredDate).IsEqualTo(DateTime.MinValue)
.And(x => x.ManufacturingPacketLink).LinkValid(),
new Columns(x => x.ID, x => x.Barcode, x => x.Description),
false
);
if (dlg.ShowDialog())
{
var id = dlg.IDs().FirstOrDefault();
var barcode = dlg.Data().Rows.FirstOrDefault(r => r.Get(c => c.ID).Equals(id))
?.Get(x => x.Barcode);
ProcessCode(_scanners.FirstOrDefault(), barcode);
}
}
private void DoScanDeliveryItems(PanelAction obj)
{
new DeliveryBuilder(Guid.Empty, Guid.Empty).ShowDialog();
}
private void DoCreatePurchaseOrder(PanelAction obj)
{
//Guid section = CurrentSection != null ? CurrentSection.ID : CoreUtils.FullGuid;
//var stages = Stages.Rows.Where(row => row.Get(col => col.ManufacturingSectionLink.ID).Equals(section) && row.Get(col => col.Station).Equals(CurrentStation));
//var ids = stages.Select(row => row.Get(col => col.ManufacturingPacketLink.ID)).ToArray();
var ids = Kanbans.Where(x => !x.ColorKey.Equals(QA_COLOR)).Select(x => Guid.Parse(x.ID)).ToArray();
var treatments = new Client().Query(new Filter(x => x.Packet.ID).InList(ids));
var window = new ManufacturingTreatmentWindow(treatments);
if (window.ShowDialog() != true)
return;
Progress.Show("Creating Purchase Order");
var order = new PurchaseOrder();
//Supplier supplier = new Client().Query(
// new Filter(x => x.ID).IsEqualTo(window.SupplierID),
// new Columns(x=>x.ID
//).Rows.FirstOrDefault()?.ToObject());
order.SupplierLink.ID = window.SupplierID;
order.SupplierLink.Name = window.SupplierName; //supplier != null ? supplier.Name : "Unknown Supplier";
order.Description = string.Format("Materials Processing Request raised by {0} from Factory Floor", App.EmployeeName);
order.RaisedBy.ID = App.EmployeeID;
order.IssuedBy.ID = App.EmployeeID;
order.IssuedDate = DateTime.Today;
order.DueDate = DateTime.Today.AddDays(7);
new Client().Save(order, "Created Treatment Purchase Order");
Progress.SetMessage("Processing Order");
var orderitems = new List();
var packetupdates = new List();
var query = new MultiQuery();
query.Add(
new Filter(x => x.Product.ID).IsEqualTo(window.ProductID).And(x => x.SupplierLink.ID)
.IsEqualTo(window.SupplierID),
new Columns(x => x.Job.ID).Add(x => x.CostPrice).Add(x => x.Product.NettCost)
);
query.Add(
new Filter(x => x.ID).IsEqualTo(window.ProductID),
LookupFactory.DefineLookupColumns(x => x.Product).Add(x => x.NettCost)
);
query.Query();
var supprods = query.Get().Rows.Select(x => x.ToObject()).ToArray();
var supprice = supprods.FirstOrDefault(x => Equals(x.Job.ID, Guid.Empty));
var product = query.Get().Rows.FirstOrDefault()?.ToObject();
var stdcost = supprice != null
? supprice.CostPrice
: product != null
? product.NettCost
: 0.0F;
foreach (var row in window.Selected)
{
var treatment = row.ToObject();
var packet = Packets.Rows.First(p => p.Get(c => c.ID).Equals(treatment.Packet.ID))
.ToObject();
packetupdates.Add(packet);
var item = new PurchaseOrderItem();
item.PurchaseOrderLink.ID = order.ID;
item.Job.ID = treatment.Packet.SetoutLink.JobLink.ID;
item.Packet.ID = packet.ID;
item.Product.ID = window.ProductID;
if(product is not null)
{
item.Product.Synchronise(product);
}
item.Qty = packet.BarcodeQty;
item.Dimensions.Length = treatment.Parameter == 0.0F ? 1.0F : treatment.Parameter;
var jobprice = supprods.FirstOrDefault(x => x.Job.ID.Equals(item.Job.ID));
item.Cost = (jobprice != null ? jobprice.CostPrice : stdcost) * treatment.Parameter;
var description = new List();
description.Add(string.Format("{0} x {1} - {2}", packet.BarcodeQty, packet.Serial, packet.Title));
var dimensions = new List();
if (packet.Height > 0.0F)
dimensions.Add(string.Format("H:{0:F2}mm", packet.Height));
if (packet.Width > 0.0F)
dimensions.Add(string.Format("W:{0:F2}mm", packet.Width));
if (packet.Length > 0.0F)
dimensions.Add(string.Format("L:{0:F2}mm", packet.Length));
dimensions.Add(string.Format("Param:{0:F4}", treatment.Parameter));
if (dimensions.Any())
description.Add(string.Format("Dimensions: {0}", string.Join(" ", dimensions)));
item.Description = string.Join("\n", description);
orderitems.Add(item);
}
new Client().Save(orderitems, "Created by Factory Floor Purchase");
Progress.SetMessage("Updating Packets");
foreach (var orderitem in orderitems)
{
var packet = packetupdates.FirstOrDefault(x => x.ID.Equals(orderitem.Packet.ID));
if (packet != null)
packet.OrderItem.ID = orderitem.ID;
}
new Client().Save(packetupdates.Where(x => x.IsChanged()), "");
Progress.SetMessage("Creating Delivery");
var delivery = new Delivery();
delivery.Date = DateTime.Today;
delivery.Due = DateTime.Today;
delivery.Employee.ID = App.EmployeeID;
var sb = new StringBuilder();
sb.Append("Serial # ");
sb.AppendLine();
sb.AppendLine();
delivery.Notes = string.Format("Delivery of Items for processing to {0}\nOrder #{1} (raised on {2:dd MMM yy} by {3})\nItems: {4}",
order.SupplierLink.Name,
order.PONumber,
delivery.Date,
App.EmployeeName,
string.Join(", ",
orderitems.Select(x =>
string.Format("{0}{1}", x.Description.Split('\n').FirstOrDefault(), x.Qty > 1 ? " (x" + x.Qty.ToString("F0") + ")" : "")))
);
new Client().Save(delivery, "Created by Factory Floor Purchase");
Progress.Close();
PrintDeliveryBarcode(delivery, order);
PrintOrderItemBarcodes(delivery, order);
SendPurchaseNotification(order.PONumber);
MessageBox.Show("All Done");
new DeliveryBuilder(delivery.ID, order.ID).ShowDialog();
Refresh();
}
private void SendPurchaseNotification(string PONumber)
{
var updates = new List();
var roles = new Client().Query(new Filter(x => x.RoleLink.Code).IsEqualTo("PURCHASES"));
foreach (var role in roles.Rows)
{
var notification = new Notification
{
Title = string.Format("Treatment PO #{0} has been raised", PONumber),
Description = "The above Purchase Order has been created, and is ready to be checked and issued to the relevant supplier."
};
notification.Sender.ID = App.EmployeeID;
notification.Employee.ID = role.Get(x => x.EmployeeLink.ID);
updates.Add(notification);
}
new Client().Save(updates, "Sent Notification");
}
private void PrintDeliveryBarcode(Delivery delivery, PurchaseOrder order)
{
var model = new ManufacturingTreatmentDataModel(order, delivery);
var templatename = "Print Treatment Delivery Bar Code";
var sectionName = "Treatment Delivery Bar Code";
var template = new Client()
.Load(
new Filter(x => x.Name).IsEqualTo(templatename)
.And(x => x.DataModel).IsEqualTo(model.Name)
.And(x => x.Section).IsEqualTo(sectionName)
).FirstOrDefault();
if (template == null)
{
template = new ReportTemplate
{
DataModel = model.Name,
Section = sectionName,
Name = templatename
};
new Client().Save(template, "Auto Created Report Template");
}
ReportUtils.PreviewReport(template, model, !Security.IsAllowed(), Security.IsAllowed());
}
private void PrintOrderItemBarcodes(Delivery delivery, PurchaseOrder order)
{
var model = new ManufacturingTreatmentDataModel(order, delivery);
var templatename = "Print Treatment Item Bar Codes";
var sectionName = "Treatment Item Bar Code";
var template = new Client()
.Load(
new Filter(x => x.Name).IsEqualTo(templatename)
.And(x => x.DataModel).IsEqualTo(model.Name)
.And(x => x.Section).IsEqualTo(sectionName)
).FirstOrDefault();
if (template == null)
{
template = new ReportTemplate
{
DataModel = model.Name,
Section = sectionName,
Name = templatename
};
new Client().Save(template, "Auto Created Report Template");
}
ReportUtils.PreviewReport(template, model, !Security.IsAllowed(), Security.IsAllowed());
}
private CoreTable POItemTable(IEnumerable items)
{
var result = new CoreTable();
result.LoadColumns(typeof(PurchaseOrderItem));
result.LoadRows(items);
return result;
}
private void DoSelectLostTime(PanelAction obj)
{
var chooser = new FactoryLostTimeChooser();
if (chooser.ShowDialog() == true)
{
LostTime = chooser.SelectedLostTime;
LostTimeDescription.Content = LostTime.Description;
LostTimeActive.Visibility = Visibility.Visible;
}
}
private void CancelLostTime_Click(object sender, RoutedEventArgs e)
{
LostTime = null;
LostTimeActive.Visibility = Visibility.Collapsed;
}
//private void Current_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
//{
// MessageBox.Show("Exception!\n\n" + e.Exception.Message + "\n\n" + e.Exception.StackTrace);
// e.Handled = true;
//}
private void Section_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!IsReady)
return;
CurrentSection = Sections[Section.SelectedIndex];
//Kanban.Columns.Clear();
//Kanban.Columns.Add(new KanbanColumn() { Title = CurrentSection, Categories = CurrentSection.ID.ToString() });
//Kanban.Columns[0].AllowDrag = false;
//Kanban.Columns[0].PreviewMouseWheel += CardBorder_PreviewMouseWheel;
IsReady = false;
Station.Items.Clear();
for (var i = 1; i <= CurrentSection.Stations; i++)
Station.Items.Add(string.Format("Station #{0}", i));
IsReady = true;
Station.SelectedIndex = 0;
}
private void Station_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!IsReady)
return;
SelectSectionAndStation(CurrentSection.ID, Station.SelectedIndex + 1);
}
private void SelectSectionAndStation(Guid section, int station)
{
CurrentKanban = null;
CurrentStation = station;
_settings.Section = section;
_settings.Station = CurrentStation - 1;
new LocalConfiguration().Save(_settings);
DoRefresh(true);
}
private void LoadKanban()
{
using (new WaitCursor())
{
if (CurrentKanban == null)
{
ButtonStack.Children.Clear();
LoadDrawing(null);
_packGrid.CurrentPacket = null;
}
else if (true) // Kanban has changed - how do we figure this out
{
var packet = KanbanToPacket(CurrentKanban);
_packGrid.CurrentPacket = packet;
//SetoutStage stage = packet.GetCurrentStage();
var row = Stages.Rows.FirstOrDefault(r => r.Get(c => c.Parent.ID).Equals(packet.ID)
&& r.Get(c => c.ManufacturingSectionLink.ID)
.Equals(_settings.Section));
var station = row != null ? row.Get(c => c.Station) : 0;
var quality = row != null ? row.Get(c => c.QualityStatus) : QualityStatus.NotChecked;
var percentage = row != null ? row.Get(c => c.PercentageComplete) : 0.00F;
var Pending = station == 0; //packet.StageLink.Station == 0;
// Set the Proper Button Set for this type of Packet
MfgRow.Height = Pending ? new GridLength(00) : new GridLength(50);
foreach (var btn in ButtonGrid.FindVisualChildren