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.Reports; using InABox.Core.Reports; using InABox.Wpf.Reports; using InABox.WPF; using Motorola.Snapi; using Motorola.Snapi.Constants.Enums; using Motorola.Snapi.EventArguments; using org.apache.commons.io.comparator; using BarcodeType = Comal.Classes.BarcodeType; using Color = System.Drawing.Color; using Image = System.Windows.Controls.Image; namespace PRSDesktop { /// /// Interaction logic for FactoryPanel.xaml /// public partial class FactoryPanel : UserControl, IPanel { private Button _currentButton; private readonly BitmapImage barcode = PRSDesktop.Resources.barcode.AsBitmapImage(); private readonly BitmapImage disabled = PRSDesktop.Resources.disabled.AsBitmapImage(); //private Document document = null; private SetoutDocument[] documents = { }; private readonly BitmapImage grouped = PRSDesktop.Resources.grouped.AsBitmapImage(); private readonly string NEARLYDUE_COLOR = "Orange"; private readonly string NOTYETDUE_COLOR = "PaleGreen"; private readonly string OVERDUE_COLOR = "Salmon"; private PDFEditorControl PDFEditor; private readonly string PRIORITY_COLOR = "Red"; private readonly string QA_COLOR = "Silver"; private QAGrid QAGrid; public List Scanners = new(); private readonly string SELECTED_COLOR = "Yellow"; private FactoryFloorLocalSettings settings; private readonly string SHARED_COLOR = "Lime"; private readonly BitmapImage speechbubble = PRSDesktop.Resources.speechbubble.AsBitmapImage(); private readonly BitmapImage starred = PRSDesktop.Resources.report.AsBitmapImage(48, 48); private readonly string TREATED_COLOR = "DarkOrchid"; public FactoryPanel() { InitializeComponent(); var CanConfigure = Security.IsAllowed(); Section.IsEnabled = CanConfigure; Station.IsEnabled = CanConfigure; PendingVisible = Security.IsAllowed(); Kanbans = new ObservableCollection(); RackContents.ItemsSource = rackcontents; } public bool IsReady { get; set; } public void Setup() { 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; settings.LineColor = ColorTranslator.ToHtml(Color.Red); settings.FontSize = 16; new LocalConfiguration().Save(settings); } var setups = Client.QueryMultiple( new KeyedQueryDef(), new KeyedQueryDef( new Filter(x => x.Hidden).IsEqualTo(false), null, new SortOrder(x => x.Factory.Sequence).ThenBy(x => x.Sequence)), new KeyedQueryDef(), new KeyedQueryDef( LookupFactory.DefineFilter(), new Columns(x => x.ID, x => x.Name, x => x.UserLink.ID), new SortOrder(x => x.Name)), new KeyedQueryDef( LookupFactory.DefineFilter(), new Columns(x => x.ID, x => x.Code, x => x.Description, x => x.BarCode), null)); Factories = setups[nameof(ManufacturingFactory)].Rows.Select(x => x.ToObject()).ToArray(); Sections = setups[nameof(ManufacturingSection)].Rows.Select(x => x.ToObject()).ToArray(); Trolleys = setups[nameof(ManufacturingTrolley)].Rows.Select(x => x.ToObject()).ToArray(); Employees = setups[nameof(Employee)].ToDictionary(x => x.ID, x => x.Name); var myRow = setups[nameof(Employee)].Rows.FirstOrDefault(r => r.Get(c => c.UserLink.ID).Equals(ClientFactory.UserGuid)); myID = myRow != null ? myRow.Get(c => c.ID) : Guid.Empty; myName = myRow != null ? myRow.Get(c => c.Name) : "(Unknown Employee)"; Shipments = setups[nameof(Shipment)]; CurrentSection = Sections.FirstOrDefault(x => x.ID.Equals(settings.Section)); if (CurrentSection == null) CurrentSection = 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(string.Format("{0}: {1}", section.Factory.Name, section.Name)); } Section.SelectedIndex = iSection; Station.Items.Clear(); for (var i = 1; i <= (CurrentSection != null ? CurrentSection.Stations : 0); i++) Station.Items.Add(string.Format("Station #{0}", i)); CurrentStation = settings.Station + 1; if (CurrentStation < 1) CurrentStation = 1; if (CurrentStation > iCount) CurrentStation = iCount; Station.SelectedIndex = CurrentStation - 1; SetupScanner(); } public void Shutdown() { ShutdownScanner(); //UpdateTimeTracking(true); LoadDrawing(null); } public void CreateToolbarButtons(IPanelHost 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 }); } 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 = myID; 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 = myID; 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) => { }); } } public static IEnumerable FindVisualChildren(DependencyObject depObj) where T : DependencyObject { if (depObj != null) for (var i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) { var child = VisualTreeHelper.GetChild(depObj, i); if (child != null && child is T) yield return (T)child; foreach (var childOfChild in FindVisualChildren(child)) yield return childOfChild; } } 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(); if (scanner != null) 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) => { }); if (scanner != null) scanner.Actions.SoundBeeper(BeepPattern.LowHigh); } else { if (scanner != null) 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; RackContents.ItemsSource = null; rackid = Guid.Empty; rackbarcode = ""; if (scanner != null) 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 = string.Format("Rack {0}", shiprow.Get(c => c.Code)); RackCount.Content = rows.Length.ToString(); RackPanel.Visibility = Visibility.Visible; if (scanner != null) 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); if (scanner != null) 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); if (scanner != null) 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) { if (scanner != null) 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 if (scanner != null) 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) if (scanner != null) scanner.Actions.SoundBeeper(BeepPattern.FourHighShort); if (stage.Station == 0) AddPacketToCurrentWorkload(stage); if (kanban != CurrentKanban) { CurrentKanban = kanban; UpdateSelectedKanban(false); } if (scanner != null) scanner.Actions.SoundBeeper(BeepPattern.LowHigh); } } } } catch (Exception e) { if (scanner != null) 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.Notes = string.Format("Materials Processing Request raised by {0} from Factory Floor", Employees[myID]); order.RaisedBy.ID = myID; order.IssuedBy.ID = myID; order.IssuedDate = DateTime.Today; order.DueDate = DateTime.Today.AddDays(7); new Client().Save(order, "Created Treatment Purchase Order"); Progress.SetMessage("Creating Consignment"); var consignment = new Consignment(); consignment.Number = string.Format("MFG PO {0}", order.PONumber); consignment.Supplier.ID = order.SupplierLink.ID; consignment.EstimatedDispatchDate = order.IssuedDate; consignment.EstimatedWarehouseArrival = order.DueDate; consignment.Description = string.Format("{0} #{1} - {2}", CurrentSection.Name, CurrentStation, Employees.ContainsKey(myID) ? Employees[myID] : "(unknown)"); new Client().Save(consignment, "Created by Factory Floor Purchase"); 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), new Columns(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 prodprice = query.Get().Rows.FirstOrDefault()?.ToObject(); var stdcost = supprice != null ? supprice.CostPrice : prodprice != null ? prodprice.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.Consignment.ID = consignment.ID; item.Product.ID = window.ProductID; 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; 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 = myID; var sb = new StringBuilder(); sb.Append("Serial # "); sb.AppendLine(); if (Employees.ContainsKey(myID)) 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, myName, 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, consignment); PrintOrderItemBarcodes(delivery, order, consignment); 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 = myID; 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, Consignment consignment) { var model = new ManufacturingTreatmentDataModel(order, delivery, consignment); 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, Consignment consignment) { var model = new ManufacturingTreatmentDataModel(order, delivery, consignment); 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); } else if (true) // Kanban has changed - how do we figure this out { var packet = KanbanToPacket(CurrentKanban); //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 FindVisualChildren