using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Threading;
using AvalonDock.Layout;
using Comal.Classes;
using Comal.Stores;
using Comal.TaskScheduler.Shared;
using H.Pipes;
using InABox.Clients;
using InABox.Configuration;
using InABox.Core;
using InABox.Database;
using InABox.Database.SQLite;
using InABox.DynamicGrid;
using InABox.Mail;
using InABox.Core.Reports;
using InABox.IPC;
using InABox.Rpc;
using InABox.Scripting;
using InABox.Wpf;
using InABox.Wpf.Console;
using InABox.WPF;
using NAudio.Wave;
using PRS.Shared;
using InABox.WPF.Themes;
using PRSDesktop.Configuration;
using PRSDesktop.Forms;
using PRSServer;
using SharpAvi.Codecs;
using SharpAvi.Output;
using Syncfusion.Windows.Shared;
using Syncfusion.Windows.Tools;
using Syncfusion.Windows.Tools.Controls;
using Activity = Comal.Classes.Activity;
using Application = System.Windows.Application;
using ButtonBase = System.Windows.Controls.Primitives.ButtonBase;
using Color = System.Windows.Media.Color;
using ColorConverter = System.Windows.Media.ColorConverter;
using Control = System.Windows.Controls.Control;
using Image = System.Drawing.Image;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using MessageBox = System.Windows.MessageBox;
using Pen = System.Drawing.Pen;
using PixelFormat = System.Drawing.Imaging.PixelFormat;
using Role = Comal.Classes.Role;
using SortDirection = InABox.Core.SortDirection;
using PRSDesktop.Components.Spreadsheet;
using InABox.Wpf.Reports;
using Comal.Classes.SecurityDescriptors;
using System.Threading;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using H.Formatters;
using PRSDesktop.Panels;
using Syncfusion.SfSkinManager;
namespace PRSDesktop;
///
/// Interaction logic for Main.xaml
///
public partial class MainWindow : IPanelHostControl
{
//private const int WM_LBUTTONDOWN = 0x201;
private static PipeServer? _client;
private IRpcClientTransport? _transport;
private WaveIn? _audio;
private bool _audioMuted;
private MemoryStream? _audioStream;
private readonly Dictionary _bitmaps = new();
private DesktopConsole? _console;
private Dictionary> _notes = new();
private DispatcherTimer? _recorder;
private Process? _recordingnotes;
private int _screenheight = 720;
private int _screenleft;
private int _screentop;
private int _screenwidth = 1280;
private readonly Dictionary SecondaryWindows = new();
private CoreTable? _timesheets;
private DailyActivityHistory? ActivityHistory;
private readonly List CurrentModules = new();
private Fluent.RibbonTabItem? CurrentTab;
private Fluent.Button? CurrentButton;
private readonly int FRAMES_PER_SECOND = 10;
private DatabaseType DatabaseType;
private readonly Dictionary messages = new();
private readonly DispatcherTimer NotificationsWatchDog;
private DateTime pausestarted = DateTime.MinValue;
private readonly Scheduler scheduler = new() { Interval = new TimeSpan(0, 5, 0) };
// We use a Guid for the StationID rather than an IP or Mac address
// because we want true single-instance restriction. Using either of
// the above allows for two instances on the once machine, and thus
// double-counting in the Heartbeat() function
private Login station = new() { StationID = Guid.NewGuid().ToString() };
private TimeSpan totalpauses = new(0);
private readonly int VIDEO_HEIGHT = 1080;
private readonly int VIDEO_WIDTH = 1920;
private PanelHost PanelHost;
public MainWindow()
{
PanelHost = new PanelHost(this);
NotificationsWatchDog = new DispatcherTimer { IsEnabled = false };
NotificationsWatchDog.Tick += Notifications_Tick;
NotificationsWatchDog.Interval = new TimeSpan(0, 2, 0);
ClientFactory.PushHandlers.AddHandler(ReceiveNotification);
ClientFactory.RegisterMailer(EmailType.IMAP, typeof(IMAPMailer));
ClientFactory.RegisterMailer(EmailType.Exchange, typeof(ExchangeMailer));
ClientFactory.OnLog += (type, userid, message, parameters) => Logger.Send(LogType.Information, ClientFactory.UserID, message, parameters);
ClientFactory.OnRequestError += ClientFactory_OnRequestError;
HotKeyManager.Initialize();
HotKeyManager.RegisterHotKey(Key.F1, ShowHelp);
//HotKeyManager.RegisterHotKey(Key.F5, ToggleRecording);
//HotKeyManager.RegisterHotKey(Key.F6, ShowRecordingNotes);
//HotKeyManager.RegisterHotKey(Key.F4, ToggleRecordingAudio);
Logger.Send(LogType.Information, "", "Connecting to server");
var settings = App.DatabaseSettings;
bool dbConnected;
DatabaseType = settings.DatabaseType;
switch (DatabaseType)
{
case DatabaseType.Standalone:
ClientFactory.SetClientType(typeof(LocalClient<>), Platform.Wpf, CoreUtils.GetVersion());
DbFactory.ColorScheme = App.DatabaseSettings.ColorScheme;
DbFactory.Logo = App.DatabaseSettings.Logo;
dbConnected = true;
break;
case DatabaseType.Networked:
if (App.DatabaseSettings.Protocol == SerializerProtocol.RPC)
{
_transport = new RpcClientSocketTransport(App.DatabaseSettings.URLs);
_transport.OnClose += TransportConnectionLost;
_transport.OnException += Transport_OnException;
_transport.OnOpen += Transport_OnOpen; ;
dbConnected = _transport.Connect();
ClientFactory.SetClientType(typeof(RpcClient<>), Platform.Wpf, CoreUtils.GetVersion(),
_transport);
}
else
{
var url = RestClient.Ping(App.DatabaseSettings.URLs, out DatabaseInfo info);
ClientFactory.SetClientType(typeof(RestClient<>), Platform.Wpf, CoreUtils.GetVersion(), url, true);
dbConnected = true;
}
break;
case DatabaseType.Local:
//new RPC stuff (temporary disabled - for enabling when RPC is ready)
var pipename = DatabaseServerProperties.GetPipeName(App.DatabaseSettings.LocalServerName, true);
_transport = new RpcClientPipeTransport(pipename);
_transport.OnClose += TransportConnectionLost;
dbConnected = _transport.Connect();
ClientFactory.SetClientType(typeof(RpcClient<>), Platform.Wpf, CoreUtils.GetVersion(), _transport );
//ClientFactory.SetClientType(typeof(IPCClient<>), Platform.Wpf, CoreUtils.GetVersion(),
// DatabaseServerProperties.GetPipeName(App.DatabaseSettings.LocalServerName, false));
//dbConnected = true;
break;
default:
throw new Exception($"Invalid database type {DatabaseType}");
}
InitializeComponent();
if (!dbConnected)
{
switch (DoConnectionFailed())
{
case ConnectionFailedResult.Quit:
Close();
return;
case ConnectionFailedResult.Restart:
App.ShouldRestart = true;
Close();
return;
case ConnectionFailedResult.Ok:
// Do nothing
break;
}
}
ThemeManager.BaseColor = Colors.CornflowerBlue;
Progress.DisplayImage = PRSDesktop.Resources.splash_small.AsBitmapImage();
try
{
var dbInfo = new Client().Info();
ClientFactory.DatabaseID = dbInfo.DatabaseID;
ThemeManager.BaseColor = (Color)ColorConverter.ConvertFromString(dbInfo.ColorScheme);
if (dbInfo.Logo?.Any() == true)
using (var ms = new MemoryStream(dbInfo.Logo))
{
Progress.DisplayImage = new Bitmap(ms).AsBitmapImage();
}
}
catch
{
}
VideoRecordingStatus.Source = PRSDesktop.Resources.videorecording.AsGrayScale().AsBitmapImage();
AudioRecordingStatus.Source = PRSDesktop.Resources.audiorecording.AsGrayScale().AsBitmapImage();
SecondaryWindowStatus.Source = PRSDesktop.Resources.target.AsGrayScale().AsBitmapImage();
ConsoleStatus.Source = PRSDesktop.Resources.view.AsGrayScale().AsBitmapImage();
SelectTask.Source = PRSDesktop.Resources.uparrow.Invert().AsBitmapImage();
Title = $"{(String.Equals(App.Profile?.ToUpper(), "DEFAULT") ? "PRS Desktop" : App.Profile)} (Release {CoreUtils.GetVersion()})";
Logger.Send(LogType.Information, "", "Checking for updates");
CheckForUpdates();
Exception? startupException = null;
ValidationStatus? loginStatus = null;
Progress.ShowModal("Loading PRS", progress =>
{
DynamicGridUtils.PreviewReport = (t, m) => { ReportUtils.PreviewReport(t, m, false, Security.IsAllowed()); };
DynamicGridUtils.PrintMenu = (e, s, m, p) => { ReportUtils.PrintMenu(e, s, m, Security.IsAllowed(), p); };
ImportFactory.Register(typeof(ExcelImporter<>), "Excel File", "Excel Files (*.xls;*.xlsx;*.xlsm)|*.xls;*.xlsx;*.xlsm");
ImportFactory.Register(typeof(CustomImporter<>), "Custom", "All Files (*.*)|*.*");
FormUtils.Register();
DigitalFormDocumentFactory.Init(
new WpfDigitalFormDocumentHandler(
b => Dispatcher.BeginInvoke(() =>
{
BackgroundUploadStatus.Visibility = b
? Visibility.Visible
: Visibility.Hidden;
}
),
() => _transport?.IsConnected() ?? false
)
);
DigitalFormDocumentFactory.Run();
Logger.Send(LogType.Information, "", "Registering Classes");
progress.Report("Registering Classes");
var tasks = new List
{
Task.Run(() =>
{
CoreUtils.RegisterClasses(typeof(TaskGrid).Assembly);
CoreUtils.RegisterClasses();
ComalUtils.RegisterClasses();
PRSSharedUtils.RegisterClasses();
ReportUtils.RegisterClasses();
ConfigurationUtils.RegisterClasses();
DynamicGridUtils.RegisterClasses();
}),
Task.Run(() =>
{
ScriptDocument.DefaultAssemblies.AddRange(
Assembly.Load("RoslynPad.Roslyn.Windows"),
Assembly.Load("RoslynPad.Editor.Windows"),
typeof(Control).Assembly,
typeof(MessageBox).Assembly,
typeof(SolidColorBrush).Assembly
);
ScriptDocument.Initialize();
}),
Task.Run(() => DatabaseUpdateScripts.RegisterScripts())
};
Task.WaitAll(tasks.ToArray());
Logger.Send(LogType.Information, "", "Configuring Application");
progress.Report("Configuring Application");
RegisterModules(progress);
if (DatabaseType == DatabaseType.Standalone)
{
progress.Report("Starting local database...");
try
{
StartLocalDatabase(progress);
}
catch (Exception err)
{
startupException = new Exception(
string.Format(
"Unable to open database ({0})\n\n{1}\n\n{2}",
App.DatabaseSettings.FileName,
err.Message,
err.StackTrace
)
);
}
}
if (startupException is null && App.DatabaseSettings.Autologin)
{
try
{
Logger.Send(LogType.Information, "", "Logging in");
progress.Report("Logging in");
Dispatcher.Invoke(() =>
{
loginStatus = TryAutoLogin();
});
if(loginStatus == ValidationStatus.VALID)
{
// Do the AfterLogin() here so that we aren't opening and closing progress windows again and again.
AfterLogin(progress);
}
}
catch(Exception e)
{
startupException = e;
}
}
});
if (startupException != null)
{
MessageWindow.ShowError("Error during startup.", startupException);
}
// If the login status is valid, then we've already loaded everything, so we don't here.
if(loginStatus != ValidationStatus.VALID)
{
Logger.Send(LogType.Information, "", "Logging in");
if (DoLogin() == ValidationStatus.VALID)
{
AfterLogin(null);
}
}
ProfileName.Content = App.Profile;
URL.Content = GetDatabaseConnectionDescription();
if (loginStatus == ValidationStatus.VALID && DatabaseType == DatabaseType.Standalone)
{
Progress.ShowModal("Starting Scheduler", progress =>
{
scheduler.Start();
});
}
}
#region Connection Management
private string GetDatabaseConnectionDescription()
{
return DatabaseType switch
{
#if RPC
DatabaseType.Networked => (ClientFactory.Parameters?.FirstOrDefault() as RpcClientSocketTransport)?.Host,
#else
DatabaseType.Networked => ClientFactory.Parameters?.FirstOrDefault() as string,
#endif
DatabaseType.Standalone => App.DatabaseSettings?.FileName,
DatabaseType.Local => App.DatabaseSettings?.LocalServerName,
_ => ""
} ?? "";
}
///
/// Reconnect to the server.
///
/// if connection was successful.
private bool Reconnect()
{
if (_transport != null)
{
return _transport.Connect();
}
Logger.Send(LogType.Error, ClientFactory.UserID, "Trying to reconnect without a transport set.");
return true; // Returning true so we don't get stuck in infinite loops in exceptional circumstances.
}
private enum ConnectionFailedResult
{
Quit,
Restart,
Ok
}
///
/// To be called when initial connection to the server has failed; asks the user if they want to retry,
/// change the database settings, or simply quit PRS.
///
/// The action to take next.
///
private ConnectionFailedResult DoConnectionFailed()
{
bool connected = false;
while (!connected)
{
var connectionFailedWindow = new ConnectionFailed();
connectionFailedWindow.ShowDialog();
var reconnect = false;
switch (connectionFailedWindow.Result)
{
case ConnectionFailedWindowResult.OpenDatabaseConfiguration:
var result = ShowDatabaseConfiguration();
switch (result)
{
case DatabaseConfigurationResult.RestartRequired:
var shouldRestart = MessageBox.Show(
"A restart is required to apply these changes. Do you wish to restart now?",
"Restart?",
MessageBoxButton.YesNo);
if (shouldRestart == MessageBoxResult.Yes)
{
return ConnectionFailedResult.Restart;
}
else
{
reconnect = true;
}
break;
case DatabaseConfigurationResult.RestartNotRequired:
reconnect = true;
break;
case DatabaseConfigurationResult.Cancel:
reconnect = true;
break;
default:
throw new Exception($"Invalid enum result {result}");
}
break;
case ConnectionFailedWindowResult.RetryConnection:
reconnect = true;
break;
case ConnectionFailedWindowResult.Quit:
return ConnectionFailedResult.Quit;
default:
throw new Exception($"Invalid enum result {connectionFailedWindow.Result}");
}
if (!reconnect)
{
return ConnectionFailedResult.Quit;
}
connected = Reconnect();
}
return ConnectionFailedResult.Ok;
}
private void Transport_OnOpen(IRpcTransport transport, RpcTransportOpenArgs e)
{
Logger.Send(LogType.Information, ClientFactory.UserID, "Connection opened");
}
private void Transport_OnException(IRpcTransport transport, RpcTransportExceptionArgs e)
{
Logger.Send(LogType.Error, ClientFactory.UserID, $"Error in connection: {CoreUtils.FormatException(e.Exception)}");
}
private void TransportConnectionLost(IRpcTransport transport, RpcTransportCloseArgs e)
{
Logger.Send(LogType.Information, ClientFactory.UserID, "Connection lost");
if (transport is IRpcClientTransport client)
{
Dispatcher.Invoke(() =>
{
var reconnection = new ReconnectionWindow();
var cancellationTokenSource = new CancellationTokenSource();
reconnection.OnCancelled = () => cancellationTokenSource.Cancel();
var ct = cancellationTokenSource.Token;
var work = () =>
{
try
{
DateTime lost = DateTime.Now;
while (!client.IsConnected() && !ct.IsCancellationRequested)
{
try
{
Logger.Send(LogType.Error, ClientFactory.UserID, $"Reconnecting - ({DateTime.Now - lost:hh\\:mm})");
if (client.Connect(ct))
{
break;
}
}
catch (System.Exception e1)
{
Logger.Send(LogType.Error, ClientFactory.UserID, $"Reconnect Failed: {e1.Message}");
// TODO: Remove this suppression
if (e1.Message.StartsWith("The socket is connected, you needn't connect again!"))
{
break;
}
}
}
if (client.IsConnected())
{
Logger.Send(LogType.Information, ClientFactory.UserID, "Reconnected");
ClientFactory.Validate(ClientFactory.SessionID);
Logger.Send(LogType.Information, ClientFactory.UserID, "Validated");
return true;
}
}
catch (Exception e)
{
Logger.Send(LogType.Error, ClientFactory.UserID, $"Reconnect Failed: {e.Message}");
}
return false;
};
var task = Task.Run(() =>
{
var result = work();
Dispatcher.Invoke(() =>
{
reconnection.Close();
});
return result;
}, ct);
reconnection.ShowDialog();
if (!task.Result)
{
Close();
}
});
}
}
#endregion
private bool _loggingOut = false;
private void ClientFactory_OnRequestError(RequestException e)
{
if (e.Status == StatusCode.Unauthenticated)
{
switch (e.Method)
{
case RequestMethod.Query:
case RequestMethod.Save:
case RequestMethod.Delete:
case RequestMethod.MultiQuery:
case RequestMethod.MultiSave:
case RequestMethod.MultiDelete:
if (!_loggingOut)
{
Dispatcher.InvokeAsync(() =>
{
_loggingOut = true;
try
{
Logout(null, true);
}
finally
{
_loggingOut = false;
}
});
}
break;
default:
break;
}
}
}
private void ApplyColorScheme()
{
Color baseColor;
try
{
baseColor = (Color)ColorConverter.ConvertFromString(App.DatabaseSettings.ColorScheme);
}
catch
{
baseColor = Colors.CornflowerBlue;
}
ThemeManager.BaseColor = baseColor;
DynamicGridUtils.SelectionBackground = ThemeManager.SelectionBackgroundBrush;
DynamicGridUtils.SelectionForeground = ThemeManager.SelectionForegroundBrush;
DynamicGridUtils.FilterBackground = ThemeManager.FilterBackgroundBrush;
//_ribbon.Background = new SolidColorBrush(Colors.White);
//_ribbon.BackStageColor = ThemeConverter.GetBrush(ElementType.Ribbon, BrushType.Background);
////_ribbon.BackStage.Background = ThemeConverter.GetBrush(ElementType.Ribbon, BrushType.Background);
////_ribbon.BackStage.Foreground = ThemeConverter.GetBrush(ElementType.Ribbon, BrushType.Foreground);
UpdateRibbonColors();
PanelHost.Refresh();
}
#region Configuration
/*
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
var source = PresentationSource.FromVisual(this) as HwndSource;
source?.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
var message = (App.Message)msg;
switch (message)
{
case App.Message.Maximise:
WindowState = WindowState.Maximized;
break;
}
return IntPtr.Zero;
}*/
private void ConfigureMainScreen(IProgress? progress)
{
var bMaps = Security.CanView()
|| Security.CanView()
|| Security.CanView()
|| Security.CanView();
var sections = new[]
{
new ProgressSection("Configuring Main Screen", SetupMainScreen),
new ProgressSection("Configuring Projects", () => SetupProjectsTab(bMaps)),
new ProgressSection("Configuring Manufacturing", () => SetupManufacturingTab(bMaps)),
new ProgressSection("Configuring Logistics", () => SetupLogisticsTab(bMaps)),
new ProgressSection("Configuring Products", () => SetupProductsTab(bMaps)),
new ProgressSection("Configuring Human Resources", () => SetupHumanResourcesTab(bMaps)),
new ProgressSection("Configuring Accounts", () => SetupAccountsTab(bMaps)),
new ProgressSection("Configuring Equipment", () => SetupEquipmentTab(bMaps)),
new ProgressSection("Configuring DigitalForms", () => SetupDigitalFormsTab(bMaps)),
new ProgressSection("Configuring Dashboards", () => SetupDashboardsTab(bMaps)),
new ProgressSection("Configuring System Modules", SetupSystemModules)
};
if(progress is not null)
{
Dispatcher.Invoke(SetupScreen);
foreach(var section in sections)
{
progress.Report(section.Message);
Dispatcher.Invoke(section.Action);
}
}
else
{
SetupScreen();
Progress.ShowModal(sections);
}
}
private void SetupScreen()
{
var button = _ribbon.FindVisualChildren().FirstOrDefault();
if (button != null)
button.Visibility = Visibility.Collapsed;
if (ClientFactory.UserGuid == Guid.Empty)
_ribbonRow.Height = new GridLength(30, GridUnitType.Pixel);
else
_ribbonRow.Height = new GridLength(1, GridUnitType.Auto);
}
private void SetupMainScreen()
{
//DockManager.SidePanelSize = OutstandingDailyReports(false) ? 0.00F : 30.00F;
// Notifications Area
SetVisibility(SendNotification, Security.CanView());
SetVisibility(Notifications, Security.CanView());
SetVisibility(TaskTracking, Security.IsAllowed());
UserID.Content = ClientFactory.UserID;
if (ClientFactory.PasswordExpiration != DateTime.MinValue)
{
var timeUntilExpiration = ClientFactory.PasswordExpiration - DateTime.Now;
if (timeUntilExpiration.Days < 14)
{
PasswordExpiryNotice.Content = $"Password will expire in {timeUntilExpiration.Days} days!";
PasswordExpiryNotice.Visibility = Visibility.Visible;
}
else
{
PasswordExpiryNotice.Visibility = Visibility.Collapsed;
}
}
}
private void SetupSystemModules()
{
SetVisibility(CompanyInformation, Security.CanView());
SetVisibleIfAny(BackstageSeparator0, CompanyInformation);
SetVisibility(SecurityDefaultsButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibleIfAny(BackstageSeparator1, SecurityDefaultsButton);
BackstageSeparator1a.Visibility = Visibility.Visible;
SystemLogsButton.Visibility = Visibility.Visible;
SetVisibility(DocumentTypeList, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibleIfAny(BackstageSeparator2, DocumentTypeList);
SetVisibility(VideoRecordingButton, Security.IsAllowed());
LogoutButton.Visibility = ClientFactory.UserGuid == Guid.Empty ? Visibility.Collapsed : Visibility.Visible;
LoginButton.Visibility = ClientFactory.UserGuid != Guid.Empty ? Visibility.Collapsed : Visibility.Visible;
EditDetailsButton.Visibility = ClientFactory.UserGuid == Guid.Empty ? Visibility.Collapsed : Visibility.Visible;
SetupDock(ContactDock, Contacts);
SetupDock(JobDock, Jobs);
SetupDock(ConsignmentDock, Consignments);
SetupDock(DeliveryDock, Deliveries);
SetupDock(ProductLookupDock, ProductLookup);
SetupDock(DigitalFormsDock, DigitalForms);
SetupDock(RequisitionsDock, Requisitions);
_ribbon.InvalidateArrange();
}
private void SetupDashboardsTab(bool bMaps)
{
if (!Security.IsAllowed())
return;
SetVisibility(DashboardsDashboardButton, Security.IsAllowed());
SetVisibility(DashboardMessagesButton, Security.CanView());
SetVisibility(DashboardsTaskButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(DashboardsAttendanceButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(DashboardsMapButton, bMaps);
SetVisibility(DashboardsDailyReportButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(FactoryProductivityButton,
ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
SetVisibility(TemplateAnalysisButton,
ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
SetVisibility(FactoryAnalysisButton,
ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
SetVisibility(DatabaseActivityButton,
ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
SetVisibility(UserActivityButton, ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
SetVisibility(QuickStatusButton, Security.IsAllowed() && Security.IsAllowed());
SetVisibleIfEither(DashboardsTaskSeparator,
new FrameworkElement[]
{
DashboardsDashboardButton, DashboardMessagesButton, DashboardsTaskButton, DashboardsAttendanceButton,
DashboardsMapButton,
DashboardsDailyReportButton
},
new FrameworkElement[]
{
FactoryProductivityButton, TemplateAnalysisButton, FactoryAnalysisButton, DatabaseActivityButton, UserActivityButton, QuickStatusButton
});
SetVisibleIfAny(DashboardsActions, DashboardsDashboardButton, DashboardMessagesButton, DashboardsTaskButton,
DashboardsAttendanceButton, DashboardsDailyReportButton, FactoryProductivityButton, TemplateAnalysisButton,
FactoryAnalysisButton, DatabaseActivityButton, UserActivityButton, QuickStatusButton);
//DashboardsActions.IsLauncherButtonVisible = Security.IsAllowed();
//DashboardsReports.IsLauncherButtonVisible = Security.IsAllowed();
SetVisibleIfAny(DashboardsTab, FactoryProductivityButton, TemplateAnalysisButton, FactoryAnalysisButton,
DatabaseActivityButton,
UserActivityButton, QuickStatusButton);
}
private void SetupDigitalFormsTab(bool bMaps)
{
if (!Security.IsAllowed())
return;
SetVisibility(DigitalFormsDashboardButton, Security.IsAllowed());
SetVisibility(DigitalFormsMessagesButton, Security.CanView());
SetVisibility(DigitalFormsTaskButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(DigitalFormsAttendanceButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(DigitalFormsMapButton, bMaps);
SetVisibility(DigitalFormsDailyReportButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(DigitalFormsFormsLibraryButton, ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(DigitalFormsCompletedFormsButton, Security.IsAllowed() && Security.IsAllowed());
SetVisibleIfEither(DigitalFormsTaskSeparator,
new FrameworkElement[]
{
DigitalFormsDashboardButton, DigitalFormsMessagesButton, DigitalFormsTaskButton, DigitalFormsAttendanceButton, DigitalFormsMapButton,
DigitalFormsDailyReportButton
}, new FrameworkElement[] { DigitalFormsFormsLibraryButton, DigitalFormsCompletedFormsButton });
SetVisibleIfAny(DigitalFormsActions, DigitalFormsDashboardButton, DigitalFormsMessagesButton, DigitalFormsTaskButton,
DigitalFormsAttendanceButton, DigitalFormsDailyReportButton, DigitalFormsFormsLibraryButton, DigitalFormsCompletedFormsButton);
SetTabVisibleIfAny(DigitalFormsTab, DigitalFormsFormsLibraryButton, DigitalFormsCompletedFormsButton);
}
private void SetupEquipmentTab(bool bMaps)
{
if (!Security.IsAllowed())
return;
SetVisibility(EquipmentDashboardButton, Security.IsAllowed());
SetVisibility(EquipmentMessagesButton, Security.CanView());
SetVisibility(EquipmentTaskButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(EquipmentAttendanceButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(EquipmentMapButton, bMaps);
SetVisibility(EquipmentDailyReportButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(EquipmentButton, ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(EquipmentPlannerButton,
ClientFactory.IsSupported()
&& Security.CanView()
&& ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibleIfEither(EquipmentTaskSeparator,
new FrameworkElement[]
{
EquipmentDashboardButton, EquipmentMessagesButton, EquipmentTaskButton, EquipmentAttendanceButton, EquipmentMapButton,
EquipmentDailyReportButton
}, new FrameworkElement[] { EquipmentButton, EquipmentPlannerButton });
SetVisibleIfAny(EquipmentActions, EquipmentDashboardButton, EquipmentMessagesButton, EquipmentTaskButton,
EquipmentAttendanceButton, EquipmentDailyReportButton, EquipmentButton, EquipmentPlannerButton);
SetVisibility(TrackersMasterList, Security.CanView() && Security.IsAllowed());
SetTabVisibleIfAny(EquipmentTab, EquipmentButton, TrackersMasterList);
}
private void SetupAccountsTab(bool bMaps)
{
if (!Security.IsAllowed())
return;
SetVisibility(AccountsDashboardButton, Security.IsAllowed());
SetVisibility(AccountsMessagesButton, Security.CanView());
SetVisibility(AccountsTaskButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(AccountsAttendanceButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(AccountsMapButton, bMaps);
SetVisibility(AccountsDailyReportButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(CustomerList, ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(InvoiceList, ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(ReceiptList, ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(SupplierList, ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(AccountsDataButton, Security.IsAllowed());
SetVisibility(PurchasesList, ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(BillsList, ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(PaymentsList, ClientFactory.IsSupported()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibleIfEither(AccountsTaskSeparator1,
new FrameworkElement[]
{
AccountsDashboardButton, AccountsMessagesButton, AccountsTaskButton, AccountsAttendanceButton, AccountsMapButton,
AccountsDailyReportButton
}, new FrameworkElement[] { CustomerList, InvoiceList, ReceiptList });
SetVisibleIfEither(AccountsTaskSeparator2, new FrameworkElement[] { CustomerList, InvoiceList, ReceiptList },
new FrameworkElement[] { SupplierList, AccountsDataButton, PurchasesList, BillsList, PaymentsList });
SetVisibleIfAny(AccountsActions, AccountsDashboardButton, AccountsMessagesButton, AccountsTaskButton,
AccountsAttendanceButton,
AccountsDailyReportButton, CustomerList, InvoiceList, ReceiptList, SupplierList, PurchasesList, BillsList, PaymentsList);
SetTabVisibleIfAny(AccountsTab, CustomerList, InvoiceList, ReceiptList, SupplierList, AccountsDataButton, PurchasesList, BillsList, PaymentsList);
}
private void SetupHumanResourcesTab(bool bMaps)
{
if (!Security.IsAllowed())
return;
SetVisibility(HumanResourcesDashboardButton, Security.IsAllowed());
SetVisibility(HumanResourcesMessagesButton, Security.CanView());
SetVisibility(HumanResourcesTaskButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(HumanResourcesAttendanceButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(HumanResourcesMapButton, bMaps);
SetVisibility(HumanResourcesDailyReportButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(CalendarButton, Security.CanView() && Security.IsAllowed());
SetVisibility(EmployeePlannerButton, Security.CanView() && Security.IsAllowed());
SetVisibility(TimesheetsButton, Security.CanView() && Security.IsAllowed());
SetVisibility(LeaveRequestsButton, Security.CanView() && Security.IsAllowed());
SetVisibility(OrgChartButton,
ClientFactory.IsSupported()
&&
Security.IsAllowed()
);
SetVisibility(MeetingsButton, Security.IsAllowed());
SetVisibleIfEither(HumanResourcesTaskSeparator,
new FrameworkElement[]
{
HumanResourcesDashboardButton, HumanResourcesMessagesButton, HumanResourcesTaskButton, HumanResourcesAttendanceButton,
HumanResourcesMapButton, HumanResourcesDailyReportButton
}, new FrameworkElement[] { CalendarButton, EmployeePlannerButton, TimesheetsButton, LeaveRequestsButton, OrgChartButton });
SetVisibleIfAny(HumanResourcesActions, HumanResourcesDashboardButton, HumanResourcesTaskButton,
HumanResourcesAttendanceButton,
HumanResourcesDailyReportButton, CalendarButton, EmployeePlannerButton, TimesheetsButton, LeaveRequestsButton, OrgChartButton);
SetVisibility(UsersButton, Security.CanView() && Security.IsAllowed());
SetVisibility(EmployeesButton, Security.CanView() && Security.IsAllowed());
SetVisibleIfEither(HumanResourcesSetupSeparator1,
new FrameworkElement[] { CalendarButton, TimesheetsButton, LeaveRequestsButton, OrgChartButton },
new FrameworkElement[] { UsersButton, EmployeesButton });
SetTabVisibleIfAny(HumanResourcesTab, CalendarButton, TimesheetsButton, LeaveRequestsButton, OrgChartButton, UsersButton, EmployeesButton);
}
private void SetupProductsTab(bool bMaps)
{
if (!Security.IsAllowed())
return;
SetVisibility(ProductsDashboardButton, Security.IsAllowed());
SetVisibility(ProductsMessagesButton, Security.CanView());
SetVisibility(ProductsTaskButton, Security.CanView());
SetVisibility(ProductsAttendanceButton, Security.IsAllowed());
SetVisibility(ProductsMapButton, bMaps);
SetVisibility(ProductsDailyReportButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(ProductsMasterList, Security.CanView() && Security.IsAllowed());
SetVisibility(StockLocationList, Security.CanView() && Security.IsAllowed());
SetVisibility(StockMovementList, Security.CanView() && Security.IsAllowed());
SetVisibility(StockForecastButton, Security.CanView()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(ReservationManagementButton, Security.IsAllowed());
SetVisibleIfEither(ProductsTaskSeparator,
new FrameworkElement[]
{
ProductsDashboardButton, ProductsMessagesButton, ProductsTaskButton, ProductsAttendanceButton, ProductsMapButton,
ProductsDailyReportButton
}, new FrameworkElement[] { ProductsMasterList, StockLocationList, StockMovementList, StockForecastButton });
SetVisibleIfAny(ProductActions, ProductsMasterList, StockLocationList, StockMovementList, StockForecastButton);
SetTabVisibleIfAny(ProductTab, ProductActions);
}
private void SetupLogisticsTab(bool bMaps)
{
if (!Security.IsAllowed())
return;
SetVisibility(LogisticsDashboardButton, Security.IsAllowed());
SetVisibility(LogisticsMessagesButton, Security.CanView());
SetVisibility(LogisticsTaskButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(LogisticsAttendanceButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(LogisticsMapButton, bMaps);
SetVisibility(LogisticsDailyReportButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(ReadyToGoItemsButton,
ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
SetVisibility(DispatchButton, Security.CanView()
&& Security.CanView()
&& Security.IsAllowed());
SetVisibility(RequisitionsButton, Security.CanView() && Security.IsAllowed());
SetVisibility(DeliveriesButton, Security.IsAllowed() && Security.IsAllowed());
SetVisibility(DeliveredItemsButton,
ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
SetVisibility(ConsignmentButton, Security.CanView() && Security.IsAllowed());
SetVisibleIfEither(LogisticsTaskSeparator1,
new FrameworkElement[]
{
LogisticsDashboardButton, LogisticsMessagesButton, LogisticsTaskButton, LogisticsAttendanceButton, LogisticsMapButton,
LogisticsDailyReportButton
},
new FrameworkElement[]
{ ReadyToGoItemsButton, DispatchButton, RequisitionsButton, DeliveriesButton, DeliveredItemsButton });
SetVisibleIfEither(LogisticsTaskSeparator2,
new FrameworkElement[]
{ ReadyToGoItemsButton, DispatchButton, RequisitionsButton, DeliveriesButton, DeliveredItemsButton },
new FrameworkElement[] { ConsignmentButton });
SetTabVisibleIfAny(LogisticsTab, DispatchButton, RequisitionsButton, DeliveriesButton, ReadyToGoItemsButton,
DeliveredItemsButton,
ConsignmentButton);
}
private void SetupManufacturingTab(bool bMaps)
{
if (!Security.IsAllowed())
return;
SetVisibility(ManufacturingDashboardButton, Security.IsAllowed());
SetVisibility(ManufacturingMessagesButton, Security.CanView());
SetVisibility(ManufacturingTaskButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(ManufacturingAttendanceButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(ManufacturingMapButton, bMaps);
SetVisibility(ManufacturingDailyReportButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibleIfAny(ManufacturingTaskSeparator,
new FrameworkElement[]
{
ManufacturingDashboardButton, ManufacturingMessagesButton, ManufacturingTaskButton, ManufacturingAttendanceButton,
ManufacturingMapButton, ManufacturingDailyReportButton
});
SetVisibility(DesignManagementButton, Security.CanView() && Security.IsAllowed());
SetVisibility(ManufacturingDesignSeparator, Security.CanView() && Security.IsAllowed());
SetVisibility(FactoryStatusButton,
ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
SetVisibility(FactoryAllocationButton,
ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
//SetVisibility(FactoryScheduleButton, ClientFactory.IsSupported() && ClientFactory.IsEnabled<>());
SetVisibility(FactoryFloorButton,
ClientFactory.IsSupported()
&& Security.IsAllowed()
&& Security.IsAllowed());
//SetVisibility(FactoryReadyButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibleIfAny(ManufacturingActionSeparator,
new FrameworkElement[]
{
FactoryStatusButton, FactoryAllocationButton, FactoryFloorButton
});
SetVisibleIfAny(ManufacturingActions, ManufacturingDashboardButton, ManufacturingMessagesButton, ManufacturingTaskButton,
ManufacturingAttendanceButton, ManufacturingDailyReportButton, FactoryStatusButton, FactoryAllocationButton,
FactoryFloorButton);
SetTabVisibleIfAny(ManufacturingTab, FactoryStatusButton, FactoryAllocationButton, FactoryFloorButton);
}
private void SetupProjectsTab(bool bMaps)
{
if (!Security.IsAllowed())
return;
SetVisibility(ProjectsDashboardButton, Security.IsAllowed());
SetVisibility(ProjectMessagesButton, Security.CanView());
SetVisibility(ProjectTaskButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(ProjectAttendanceButton, ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(ProjectsMapButton, bMaps);
SetVisibility(ProjectDailyReportButton,
ClientFactory.IsSupported() && Security.IsAllowed());
SetVisibility(ProjectsButton, Security.CanView() && Security.IsAllowed());
//SetVisibility(ServiceButton, Security.CanView() && Security.IsAllowed());
SetVisibility(ProjectPlannerButton, Security.CanView() && Security.IsAllowed());
SetVisibleIfEither(ProjectTaskSeparator,
new FrameworkElement[]
{
ProjectsDashboardButton, ProjectMessagesButton, ProjectTaskButton, ProjectAttendanceButton, ProjectsMapButton,
ProjectDailyReportButton
}, new FrameworkElement[] { QuotesButton, ProjectsButton, ProjectPlannerButton });
SetVisibility(QuotesButton, Security.CanView() && Security.IsAllowed());
SetVisibility(KitsMasterList, Security.CanView() && Security.IsAllowed());
SetVisibility(CostSheetsMasterList, Security.CanView() && Security.IsAllowed());
SetVisibleIfAny(ProjectsSetup, KitsMasterList, CostSheetsMasterList);
//ProjectsActions.IsLauncherButtonVisible = Security.IsAllowed();
//ProjectReports.IsLauncherButtonVisible = Security.IsAllowed();
SetTabVisibleIfAny(ProjectsTab, QuotesButton, ProjectsButton, ProjectPlannerButton, CostSheetsMasterList, KitsMasterList);
}
private void SetupDock(LayoutAnchorable layout, IDockPanel dock)
where TSecurityDescriptor : ISecurityDescriptor, new()
{
if (Security.IsAllowed())
{
if (!DockGroup.Children.Any(x => x == layout))
{
DockGroup.Children.Add(layout);
}
if (layout.IsVisible && (ClientFactory.UserGuid != Guid.Empty))
dock.Setup();
}
else
{
DockGroup.RemoveChild(layout);
}
}
private void LoadApplicationState()
{
if (ClientFactory.UserGuid != Guid.Empty)
{
_ribbon.IsCollapsed = false;
if (OutstandingDailyReports(false))
{
MessageWindow.ShowMessage("There are outstanding Daily Reports that must be filled out before continuing!"
+ "\n\nAccess to PRS is restricted until this is corrected.",
"Outstanding Reports");
var dailyReportPanel = LoadWindow(ProjectDailyReportButton);
if(dailyReportPanel is not null)
{
dailyReportPanel.OnTimeSheetConfirmed += e =>
{
if (!OutstandingDailyReports(true))
{
ConfigureMainScreen(null);
LoadApplicationState();
}
};
}
return;
}
using (new WaitCursor())
{
_ribbon.IsCollapsed = false;
LoadInitialWindow();
}
}
}
private void LoadInitialWindow()
{
var app = new LocalConfiguration().Load();
if (app.Settings.ContainsKey("CurrentPanel"))
{
try
{
var bFound = false;
var module = app.Settings["CurrentPanel"].Split(new[] { " / " }, StringSplitOptions.None);
if (module.Length == 2)
foreach (Fluent.RibbonTabItem tab in _ribbon.Tabs)
{
if (String.Equals(tab.Header, module.First()))
{
_ribbon.SelectedTabItem = tab;
foreach (Fluent.RibbonGroupBox bar in tab.Groups)
{
foreach (var item in bar.Items)
{
var button = item as Fluent.Button;
if (button != null && String.Equals(button.Header, module.Last()))
{
bFound = true;
button.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
break;
}
}
if (bFound)
break;
}
}
if (bFound)
break;
}
}
catch (Exception e)
{
MessageWindow.ShowError($"Unable to load {app.Settings["CurrentPanel"]}", e);
}
}
}
private void _ribbon_OnLoaded(object sender, RoutedEventArgs e)
{
_ribbon.SelectedTabItem = CurrentTab;
}
private void LoadSecondaryWindows()
{
if (ClientFactory.UserGuid != Guid.Empty)
{
var windows = App.DatabaseSettings.SecondaryWindows;
foreach (var key in windows.Keys.ToArray())
{
SecondaryWindows[key] = new SecondaryWindow(
key,
windows[key].Item1,
windows[key].Item2,
windows[key].Item3,
windows[key].Item4,
windows[key].Item5,
windows[key].Item6
);
SecondaryWindows[key].Closed += (o, e) => { SecondaryWindows.Remove(key); };
SecondaryWindows[key].Show();
}
}
else
{
foreach (var key in SecondaryWindows.Keys.ToArray())
{
App.IsClosing = true;
SecondaryWindows[key].Close();
App.IsClosing = false;
}
}
}
private Fluent.RibbonTabItem GetTabItem(FrameworkElement? sender)
{
if (sender == null)
throw new Exception("No Tab Found!");
if (sender is Fluent.RibbonTabItem)
return (Fluent.RibbonTabItem)sender;
return GetTabItem(sender.Parent as FrameworkElement);
}
private IEnumerable Panels
{
get
{
if(PanelHost.CurrentPanel is not null)
{
yield return PanelHost.CurrentPanel;
}
foreach(var window in SecondaryWindows.Values)
{
yield return window.Panel;
}
}
}
private T? LoadWindow(Fluent.Button sender) where T : class, IBasePanel, new()
{
return LoadWindow(sender, new CancelEventArgs());
}
private T? LoadWindow(Fluent.Button sender, CancelEventArgs cancel) where T : class, IBasePanel, new()
{
using (new WaitCursor())
{
UnloadWindow(cancel);
if (cancel.Cancel)
{
return null;
}
CurrentTab = GetTabItem(sender);
CurrentButton = sender;
//CurrentButton.IsSelected = true;
UpdateRibbonColors();
var moduleName = sender.Header?.ToString() ?? "";
var panel = PanelHost.LoadPanel(moduleName);
ContentControl.Content = panel;
Title =
$"{moduleName} - {(String.Equals(App.Profile?.ToUpper(), "DEFAULT") ? "PRS Desktop" : App.Profile)} (Release {CoreUtils.GetVersion()})";
PanelHost.Refresh();
if (panel is NotificationPanel)
{
Logger.Send(LogType.Information, ClientFactory.UserID, "Disabling Heartbeat");
NotificationsWatchDog.IsEnabled = false;
Notifications.Visibility = Visibility.Collapsed;
DockingGrid.ColumnDefinitions[1].Width = new GridLength(0, GridUnitType.Pixel);
DockingGrid.ColumnDefinitions[2].Width = new GridLength(0, GridUnitType.Pixel);
}
else
{
ReloadNotifications();
}
if (sender != null)
{
var settings = new LocalConfiguration().Load();
var module = string.Format("{0} / {1}", CurrentTab?.Header, sender.Header);
if (!settings.Settings.ContainsKey("CurrentPanel") || module != settings.Settings["CurrentPanel"])
{
settings.Settings["CurrentPanel"] = module;
try
{
new LocalConfiguration().Save(settings);
}
catch (Exception e)
{
Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
}
}
}
return panel;
}
}
private void UpdateRibbonColors()
{
foreach (var tab in _ribbon.Tabs)
{
bool bFound = false;
foreach (var grp in tab.Groups)
{
foreach (var btn in grp.Items)
{
if (btn is Fluent.Button fluentbutton)
{
bFound = bFound || (btn == CurrentButton);
fluentbutton.Background = (btn == CurrentButton) ? ThemeManager.SelectedTabItemBackgroundBrush : new SolidColorBrush(Colors.White);
fluentbutton.Foreground = (btn == CurrentButton) ? ThemeManager.SelectedTabItemForegroundBrush : new SolidColorBrush(Colors.Black);
}
}
tab.Background = bFound ? ThemeManager.SelectedTabItemBackgroundBrush : new SolidColorBrush(Colors.White);
tab.Foreground = bFound ? ThemeManager.SelectedTabItemForegroundBrush : new SolidColorBrush(Colors.Black);
}
}
}
private static void StartLocalDatabase(IProgress progress)
{
var dirName = Path.GetDirectoryName(App.DatabaseSettings.FileName);
if (!Directory.Exists(dirName) && dirName != null)
Directory.CreateDirectory(dirName);
var FileName = App.DatabaseSettings.FileName;
var Exists = File.Exists(FileName);
progress.Report("Configuring Stores");
DbFactory.Stores = CoreUtils.TypeList(
new[]
{
typeof(Store<>).Assembly,
typeof(EquipmentStore).Assembly
},
myType =>
myType.IsClass
&& !myType.IsAbstract
&& !myType.IsGenericType
&& myType.GetInterfaces().Contains(typeof(IStore))
).ToArray();
DbFactory.ProviderFactory = new SQLiteProviderFactory(App.DatabaseSettings.FileName);
DbFactory.ColorScheme = App.DatabaseSettings.ColorScheme;
DbFactory.Logo = App.DatabaseSettings.Logo;
progress.Report("Starting Local Database");
DbFactory.Start();
ClientFactory.DatabaseID = DbFactory.ID;
progress.Report("Checking Database");
var users = DbFactory.NewProvider(Logger.Main).Load();
if (!users.Any())
{
var user = new User { UserID = "ADMIN", Password = "admin" };
DbFactory.NewProvider(Logger.Main).Save(user);
var employee = DbFactory.NewProvider(Logger.Main).Load(new Filter(x => x.Code).IsEqualTo("ADMIN")).FirstOrDefault();
employee ??= new Employee { Code = "ADMIN", Name = "Administrator Account" };
employee.UserLink.ID = user.ID;
DbFactory.NewProvider(Logger.Main).Save(employee);
}
StoreUtils.GoogleAPIKey = App.DatabaseSettings.GoogleAPIKey;
Job.JobNumberPrefix = App.DatabaseSettings.JobPrefix;
PurchaseOrder.PONumberPrefix = App.DatabaseSettings.PurchaseOrderPrefix;
}
#endregion
#region Login Management
private ValidationStatus? TryAutoLogin()
{
ValidationStatus? result = null;
if (App.DatabaseSettings.LoginType == LoginType.UserID)
{
try
{
result = ClientFactory.Validate(App.DatabaseSettings.UserID, App.DatabaseSettings.Password);
}
catch (Exception e)
{
MessageWindow.ShowError("Error connecting to server.\nPlease check the server URL and port number.", e);
result = null;
}
if (result == ValidationStatus.INVALID)
{
MessageWindow.ShowMessage("Unable to Login with User ID: " + App.DatabaseSettings.UserID, "Login failed");
}
}
return result;
}
private ValidationStatus? DoLogin()
{
ValidationStatus? result = null;
if (result != ValidationStatus.VALID)
{
var login = new PinLogin(CoreUtils.GetVersion(), result ?? ValidationStatus.INVALID);
if (login.ShowDialog() == true)
{
result = ValidationStatus.VALID;
}
}
return result ?? ValidationStatus.INVALID;
}
///
/// To be called after