Index: ActiviteitenOpvolging/ProductiePitching/My Project/Settings.settings =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/My Project/Settings.settings (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/My Project/Settings.settings (revision 1759) @@ -0,0 +1,7 @@ + + + + + + + Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/IActivityActions.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/IActivityActions.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/IActivityActions.vb (revision 1759) @@ -0,0 +1,17 @@ +Public Interface IActivityActions + ''' + ''' The employee starts the activity. + ''' + ''' + Sub StartActivity(employee As IEmployee) + + ''' + ''' The employee stops the activity. + ''' + Sub StopActivity() + + ''' + ''' The employee finishes the activity. + ''' + Sub FinishActivity() +End Interface Index: ActiviteitenOpvolging/ProductiePitching/ProductiePitchingForm.Designer.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ProductiePitchingForm.Designer.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ProductiePitchingForm.Designer.vb (revision 1759) @@ -0,0 +1,114 @@ + _ +Partial Class ProductiePitchingForm + Inherits System.Windows.Forms.Form + + 'Form overrides dispose to clean up the component list. + _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + _ + Private Sub InitializeComponent() + Me.components = New System.ComponentModel.Container() + Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(ProductiePitchingForm)) + Me.DatagridViewControlsFlowLayoutPanel = New System.Windows.Forms.FlowLayoutPanel() + Me.GridLabel = New System.Windows.Forms.Label() + Me.RefreshTimeLabel = New System.Windows.Forms.Label() + Me.RefreshFailedLabel = New System.Windows.Forms.Label() + Me.EmployeesControlsFlowLayoutPanel = New System.Windows.Forms.FlowLayoutPanel() + Me.RefreshTimer = New System.Windows.Forms.Timer(Me.components) + Me.SuspendLayout() + ' + 'DatagridViewControlsFlowLayoutPanel + ' + Me.DatagridViewControlsFlowLayoutPanel.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ + Or System.Windows.Forms.AnchorStyles.Left) _ + Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) + Me.DatagridViewControlsFlowLayoutPanel.Location = New System.Drawing.Point(12, 46) + Me.DatagridViewControlsFlowLayoutPanel.Name = "DatagridViewControlsFlowLayoutPanel" + Me.DatagridViewControlsFlowLayoutPanel.Size = New System.Drawing.Size(1240, 590) + Me.DatagridViewControlsFlowLayoutPanel.TabIndex = 0 + ' + 'GridLabel + ' + Me.GridLabel.AutoSize = True + Me.GridLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 15.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) + Me.GridLabel.ForeColor = System.Drawing.Color.Firebrick + Me.GridLabel.Location = New System.Drawing.Point(12, 9) + Me.GridLabel.Name = "GridLabel" + Me.GridLabel.Size = New System.Drawing.Size(94, 25) + Me.GridLabel.TabIndex = 2 + Me.GridLabel.Text = "Grid label" + ' + 'RefreshTimeLabel + ' + Me.RefreshTimeLabel.AutoSize = True + Me.RefreshTimeLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) + Me.RefreshTimeLabel.Location = New System.Drawing.Point(1174, 18) + Me.RefreshTimeLabel.Name = "RefreshTimeLabel" + Me.RefreshTimeLabel.Size = New System.Drawing.Size(0, 20) + Me.RefreshTimeLabel.TabIndex = 4 + ' + 'RefreshFailedLabel + ' + Me.RefreshFailedLabel.AutoSize = True + Me.RefreshFailedLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) + Me.RefreshFailedLabel.ForeColor = System.Drawing.Color.Maroon + Me.RefreshFailedLabel.Location = New System.Drawing.Point(807, 18) + Me.RefreshFailedLabel.Name = "RefreshFailedLabel" + Me.RefreshFailedLabel.Size = New System.Drawing.Size(361, 20) + Me.RefreshFailedLabel.TabIndex = 5 + Me.RefreshFailedLabel.Text = "Refresh failed. Latest successful refresh at:" + Me.RefreshFailedLabel.Visible = False + ' + 'EmployeesControlsFlowLayoutPanel + ' + Me.EmployeesControlsFlowLayoutPanel.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ + Or System.Windows.Forms.AnchorStyles.Left) _ + Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) + Me.EmployeesControlsFlowLayoutPanel.Location = New System.Drawing.Point(12, 664) + Me.EmployeesControlsFlowLayoutPanel.Name = "EmployeesControlsFlowLayoutPanel" + Me.EmployeesControlsFlowLayoutPanel.Size = New System.Drawing.Size(1240, 310) + Me.EmployeesControlsFlowLayoutPanel.TabIndex = 6 + ' + 'RefreshTimer + ' + ' + 'ProductiePitchingForm + ' + Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) + Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font + Me.ClientSize = New System.Drawing.Size(1264, 986) + Me.Controls.Add(Me.EmployeesControlsFlowLayoutPanel) + Me.Controls.Add(Me.RefreshFailedLabel) + Me.Controls.Add(Me.RefreshTimeLabel) + Me.Controls.Add(Me.GridLabel) + Me.Controls.Add(Me.DatagridViewControlsFlowLayoutPanel) + Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) + Me.Name = "ProductiePitchingForm" + Me.Text = "Productie pitching Form" + Me.ResumeLayout(false) + Me.PerformLayout + +End Sub + + Friend WithEvents DatagridViewControlsFlowLayoutPanel As FlowLayoutPanel + Friend WithEvents GridLabel As Label + Friend WithEvents RefreshTimeLabel As Label + Friend WithEvents RefreshFailedLabel As Label + Friend WithEvents EmployeesControlsFlowLayoutPanel As FlowLayoutPanel + Friend WithEvents RefreshTimer As Timer +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/details/IEmployeeDetailParentUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/details/IEmployeeDetailParentUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/details/IEmployeeDetailParentUserControl.vb (revision 1759) @@ -0,0 +1,19 @@ +Public Interface IEmployeeDetailParentUserControl + + Function GetCurrentlySelectedActivity() As IActivity + + ''' + ''' Get the employee. + ''' + ''' + Function FetchEmployee() As IEmployee + + ''' + ''' Removes the selection of the current employee. + ''' + sub DeselectEmployee() + + Sub StartActivity() + Sub FinishActivity() + Sub StopActivity() +End Interface Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/details/IEmployeeDetailUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/details/IEmployeeDetailUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/details/IEmployeeDetailUserControl.vb (revision 1759) @@ -0,0 +1,4 @@ +Public Interface IEmployeeDetailUserControl + inherits IRefreshableUserControl + +End Interface Index: ActiviteitenOpvolging/ProductiePitching/ProductiePitchingForm.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ProductiePitchingForm.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ProductiePitchingForm.vb (revision 1759) @@ -0,0 +1,229 @@ +Imports ProductiePitching.configs + +Public Class ProductiePitchingForm + Implements IWorkItemsMainForm, IEmployeesMainForm + + Private _datagridViewUserControls As List(Of IDataGridUserControl) + Private _employeeUserControls As List(Of IEmployeeUserControl) + Private _domainController As IDomainController + + Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load + Try + 'Variable initialisation, putting this in a constructor breaks 'DatagridViewControlsFlowLayoutPanel.Controls.Add' -> null reference exception. + _datagridViewUserControls = New List(Of IDataGridUserControl) + _employeeUserControls = New List(Of IEmployeeUserControl) + _domainController = DomainController.GetInstance() + + 'Set the color of the form. + BackColor = Color.White + ForeColor = Color.Black + 'Update size and set center position. + Size = New System.Drawing.Size(ConfigsLoader.AppWidth, ConfigsLoader.AppHeight) + StartPosition = FormStartPosition.CenterScreen + 'Set the title name of the form from the config. + Text = $"RDB - Productie pitching - {ConfigsLoader.AppName}" + GridLabel.Text = ConfigsLoader.AppName + + 'Load the user controls with the data grids. + LoadDataGridUserControls() + + 'Load the user controls with the employees. + LoadEmployeeUserControls() + + PauseActivitiesFromApp() + + 'Load all the data. Not done with the general method, because we want to catch the exceptions. + RefreshAllData() + + 'Set the timer's value in miliseconds. + RefreshTimer.Interval = ConfigsLoader.RefreshIntervalSeconds * 1000 + 'Start the times. + RefreshTimer.Start() + Catch ex As Exception + MessageBox.Show(ex.Message, "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + Application.Exit() + End Try + End Sub + + Private Sub PauseActivitiesFromApp() + _domainController.PauseActivitiesFromApp() + End Sub + + 'Refreshes all data. If fails, updates label with last timestamp of refresh. + Private Sub RefreshAllData() + Dim allSuccessfulRefresh = RefreshUserGridsData() + allSuccessfulRefresh = allSuccessfulRefresh And RefreshEmployeesData() + 'Check if refresh was successful. + If allSuccessfulRefresh Then + 'Update latest refresh time label with current time. + RefreshTimeLabel.Text = TimeOfDay.ToString("HH:mm") + RefreshFailedLabel.Visible = False + Else + RefreshFailedLabel.Visible = True + End If + End Sub + + 'Refreshes at specified interval. + Private Sub RefreshTimer_Tick(sender As Object, e As EventArgs) Handles RefreshTimer.Tick + 'Refresh all the data. + RefreshAllData() + End Sub + +#Region "Data grids" + + ''' + ''' Loads the user controls with the data grid. + ''' + Private Sub LoadDataGridUserControls() + Try + 'Loop for every data grid view, number of grids gotten from config. + For gridNumber = 0 To ConfigsLoader.NumberOfGrids - 1 + 'Initialise the user control and set parent form and grid number. + Dim userControl As New DataGridViewUserControl(Me, gridNumber) + 'Set other parameters. + With userControl + .Size = New System.Drawing.Size(ConfigsLoader.GridWidths(gridNumber), ConfigsLoader.GridHeights(gridNumber)) + End With + + 'Add to list of user controls. + _datagridViewUserControls.Add(userControl) + 'Add to layout panel. + DatagridViewControlsFlowLayoutPanel.Controls.Add(userControl) + Next + Catch ex As Exception + Throw New Exception($"Could not load data grid user controls.{vbNewLine}{ex.Message}") + End Try + End Sub + + ''' + Public Function GetWorkItems(gridNumber As Integer) As List(Of IWorkItem) Implements IWorkItemsMainForm.GetWorkItems + Return _domainController.GiveWorkItems(gridNumber) + End Function + + Private _selectedActivity As IActivity + ''' + Public Sub ChangeSelectedActivity(activity As IActivity, gridNumber As Integer) Implements IWorkItemsMainForm.ChangeSelectedActivity + 'Store the activity. + _selectedActivity = activity + 'If the activity is Nothing, no activity was selected, meaning that everything should be cleared. + If activity Is Nothing Then + 'Clear selection for every grid user control. + _datagridViewUserControls.ForEach(Sub(userControl) userControl.RemoveSelection()) + Else + 'Clear selection of every grid except the one with the grid number. + For Each control In _datagridViewUserControls + 'Remove selection from every other grid. + If Not control.GridNumber = gridNumber Then control.RemoveSelection() + Next + End If + 'Update employee user controls. + _employeeUserControls.ForEach(Sub(employeeUserControl) employeeUserControl.SelectedActivityChanged()) + End Sub + + ''' + Public Function GetCurrentlySelectedActivity() As IActivity Implements IActivityMainForm.GetCurrentlySelectedActivity + Return _selectedActivity + End Function + + ''' + ''' Try to refresh all user grids and register time of latest refresh. + ''' + Private Function RefreshUserGridsData() As Boolean + Try + 'Reset selected activity because none will be selected after refresh. + _selectedActivity = Nothing + 'Refresh every user control. Register whether or not all refreshes were successful. + Return _datagridViewUserControls.All(Function(userControl) userControl.RefreshData()) + Catch ex As Exception + Return False + End Try + End Function +#End Region + +#Region "Employees" + ''' + ''' Loads the user controls with the employee data. + ''' + Private Sub LoadEmployeeUserControls() + Try + 'Loop for every employee, number of grids gotten from config. + For employeeIndex = 0 To ConfigsLoader.NumberOfEmployees - 1 + 'Initialise the user control and set parent form and grid number. + Dim userControl As New EmployeeUserControl(Me, employeeIndex) + 'Set other parameters. + With userControl + .Size = New System.Drawing.Size(250, 300) 'todo make configurable + End With + + 'Add to list of user controls. + _employeeUserControls.Add(userControl) + 'Add to layout panel. + EmployeesControlsFlowLayoutPanel.Controls.Add(userControl) + Next + Catch ex As Exception + Throw New Exception($"Could not load the employee user controls.{vbNewLine}{ex.Message}") + End Try + End Sub + + ''' + ''' Refresh the employee controls with employee data. + ''' + ''' + Private Function RefreshEmployeesData() As Boolean + Try + 'Refresh every user control. Register whether or not all refreshes were successful. + Return _employeeUserControls.All(Function(userControl) userControl.RefreshData()) + Catch ex As Exception + Return False + End Try + End Function + + ''' + Public Function GetAllEmployees() As ICollection(Of IEmployee) Implements IEmployeesMainForm.GetAllEmployees + Return _domainController.GetAvailableEmployees() + End Function + + ''' + Public Sub SelectEmployee(employeeIndex As Integer, employee As IEmployee) Implements IEmployeesMainForm.SelectEmployee + 'Call function in dc. + _domainController.SelectEmployee(employeeIndex, employee) + 'Send message that the selected employee changed to all user controls. + _employeeUserControls.ForEach(Sub(employeeUserControl) employeeUserControl.SelectedEmployeeChanged()) + 'Refresh all the grids, so data grid can recolor. This removes the selection, so the employee controls also need to be updated. + RefreshAllData() + End Sub + + ''' + Public Sub DeselectEmployee(employeeIndex As Integer) Implements IEmployeesMainForm.DeselectEmployee + _domainController.DeselectEmployee(employeeIndex) + 'Send message that the selected employee changed to all user controls. + _employeeUserControls.ForEach(Sub(employeeUserControl) employeeUserControl.SelectedEmployeeChanged()) + 'Refresh the grids, so one can recolor. This removes the selection, so the employee controls also need to be updated. + RefreshAllData() + End Sub + + ''' + Public Function GetSelectedEmployee(employeeIndex As Integer) As IEmployee Implements IEmployeesMainForm.GetSelectedEmployee + Return _domainController.GetSelectedEmployee(employeeIndex) + End Function + + Public Sub StartActivity(employeeIndex As Integer) Implements IEmployeesMainForm.StartActivity + _domainController.StartActivity(_selectedActivity, employeeIndex) + 'Refresh all the data. + RefreshAllData() + End Sub + + Public Sub FinishActivity(employeeIndex As Integer) Implements IEmployeesMainForm.FinishActivity + _domainController.FinishActivity(employeeIndex) + 'Refresh all the data. + RefreshAllData() + End Sub + + Public Sub StopActivity(employeeIndex As Integer) Implements IEmployeesMainForm.StopActivity + _domainController.StopActivity(employeeIndex) + 'Refresh all the data. + RefreshAllData() + End Sub + +#End Region +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/IEmployeePickerUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/IEmployeePickerUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/IEmployeePickerUserControl.vb (revision 1759) @@ -0,0 +1,3 @@ +Public Interface IEmployeePickerUserControl + +End Interface Index: ActiviteitenOpvolging/ProductiePitching/Resources/remove_user.png =================================================================== diff -u Binary files differ Index: ActiviteitenOpvolging/ProductiePitching/screens/custom controls/BorderCell.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/custom controls/BorderCell.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/custom controls/BorderCell.vb (revision 1759) @@ -0,0 +1,31 @@ +Public Class BorderCell + Inherits DataGridViewTextBoxCell + + Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle, rowIndex As Integer, cellState As DataGridViewElementStates, value As Object, formattedValue As Object, errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle, paintParts As DataGridViewPaintParts) + MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts) + + 'Ignore if thickness is too small. + if _borderThickness = 0 Then Return + + 'Specify size and position of the border. + Dim borderRect = New Rectangle(cellBounds.X + 1, cellBounds.Y + 1, cellBounds.Width - 4, cellBounds.Height - 4) + 'Draw border with specified thickness. + graphics.DrawRectangle(New Pen(BorderColor, _borderThickness), borderRect) + + 'Create spacing between text and border. + Me.Style.Padding = New Padding(1) + End Sub + + Private _borderThickness As Integer = 1 + Property BorderThickness As Integer + Set(thickness As Integer) + If thickness < 0 Then Throw New Exception($"Border thickness of {Me.GetType().Name} can't be smaller than 0.") + _borderThickness = thickness + End Set + Get + Return _borderThickness + End Get + End Property + + Public Property BorderColor As Color = Drawing.Color.Black +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/EmployeePickerUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/EmployeePickerUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/EmployeePickerUserControl.vb (revision 1759) @@ -0,0 +1,71 @@ +Public Class EmployeePickerUserControl + Implements IRefreshableUserControl + + Private ReadOnly _parentUserControl As IEmployeePickerParentUserControl + Private _employees As List(Of IEmployee) + + Private Sub New() + ' This call is required by the designer. + InitializeComponent() + End Sub + + ''' + ''' Initialises the user form. + ''' + ''' The form containing this user control + Sub New(parentForm As IEmployeePickerParentUserControl) + 'Call base constructor. + Me.New() + 'Set parameters. + + 'Parent form. + 'Value can't be Nothing. + If parentForm Is Nothing Then Throw New InternalException($"The parent user control can't be 'Nothing' in a {Me.Name}.") + _parentUserControl = parentForm + End Sub + + ''' + Public Function RefreshData() As Boolean Implements IRefreshableUserControl.RefreshData + Try + LoadData() + 'Refresh succeeded. + Return True + Catch ex As Exception + 'Refresh failed. + Return False + End Try + End Function + + Private Sub EmployeePickerUserControl_Load(sender As Object, e As EventArgs) Handles MyBase.Load + Try + LoadData() + Catch ex As Exception + MessageBox.Show($"Could not load {Me.Name}.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + + ''' + ''' Load the employees into the combo box. + ''' + Private Sub LoadData() + 'Fetch the employees. + _employees = _parentUserControl.GetAllEmployees().OrderBy( Function(employee1) employee1.FirstName).ToList() + 'Check if data is correct. + If _employees Is Nothing OrElse _employees.Count = 0 Then + 'No items in collection + _employees = Nothing + End If + 'Fill the combobox with names. + EmployeesComboBox.DataSource = _employees.Select(Function(employee) $"{employee.FirstName} {employee.LastName} ({employee.Initials})").ToArray() + End Sub + + Private Sub EmployeesComboBox_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles EmployeesComboBox.SelectionChangeCommitted + 'Skip if no employees were loaded. + If _employees Is Nothing Then Return + + 'Fetch the right employee. + Dim employee = _employees.Item(EmployeesComboBox.SelectedIndex) + 'Send message to parent. + _parentUserControl.SelectEmployee(employee) + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/ServiceAgents/Implementations/ActiviteitPerBatchServiceAgent.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ServiceAgents/Implementations/ActiviteitPerBatchServiceAgent.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ServiceAgents/Implementations/ActiviteitPerBatchServiceAgent.vb (revision 1759) @@ -0,0 +1,55 @@ +Imports System.ServiceModel +Imports ProductiePitching +Imports ProductiePitching.configs + +Namespace ServiceAgents.Implementations + + Public Class ActiviteitPerBatchServiceAgent + Implements IActiviteitPerBatchServiceAgent + + Private Sub SetActivityState(activity As IActivity, employee As IEmployee) Implements IActiviteitPerBatchServiceAgent.SetActivityState + Try + Dim stateLetter = ActivityStateEnumMapper.GetLetterFromActivityState(activity.Status) + SoapClient().RegistreerActieByKey(activity.Id, stateLetter, employee.Initials, ConfigsLoader.AppName, System.Net.Dns.GetHostName()) + Catch ex As Exception + Throw New Exception($"Can't reach the Caché webservice: {vbNewLine}{ex.Message}") + End Try + End Sub + + Private Sub SetActivityState(activity As IActivity) Implements IActiviteitPerBatchServiceAgent.SetActivityState + SetActivityState(activity, activity.CurrentEmployee) + End Sub + + Public Sub PauseActionsFromApp() Implements IActiviteitPerBatchServiceAgent.PauseActionsFromApp + Try + SoapClient().PauzeerActiesVanApp(ConfigsLoader.AppName, System.Net.Dns.GetHostName()) + Catch ex As Exception + Throw New Exception($"Can't reach the Caché webservice: {vbNewLine}{ex.Message}") + End Try + End Sub + + Private Function SoapClient() As ActiviteitPerBatchClient + Dim binding = New BasicHttpBinding() + Dim address = New EndpointAddress(ConfigsLoader.CacheWebserviceUrl.Value) + Dim activiteitPerBatchClient = New ActiviteitPerBatchClient(binding, address) + Return activiteitPerBatchClient + End Function + + Public Function GeefDataSetVoorQuery(QueryNaam As String) As DataSet Implements IActiviteitPerBatchServiceAgent.GeefDataSetVoorQuery + Try + Return SoapClient().GeefDataSetVoorQuery(ConfigsLoader.AppName, System.Net.Dns.GetHostName(), QueryNaam) + Catch ex As Exception + Throw New Exception($"Can't reach the Caché webservice: {vbNewLine}{ex.Message}") + End Try + End Function + + Public Function GeefWerknemers() As DataSet Implements IActiviteitPerBatchServiceAgent.GeefWerknemers + Try + Return SoapClient().GeefWerknemers(ConfigsLoader.AppName, System.Net.Dns.GetHostName()) + Catch ex As Exception + Throw New Exception($"Can't reach the Caché webservice: {vbNewLine}{ex.Message}") + End Try + End Function + + End Class +End NameSpace \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/domain/controllers/IDomainController.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/controllers/IDomainController.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/controllers/IDomainController.vb (revision 1759) @@ -0,0 +1,55 @@ +Public Interface IDomainController +#Region "Employees" + + ''' + ''' Gets a collection of all the available employees. + ''' + ''' + Function GetAvailableEmployees() As ICollection(Of IEmployee) + + ''' + ''' Get a selected employee corresponding to an employee number. This is merely the pre-defined index for each possible employee. + ''' If no employee was selected, 'Nothing' will be returned. + ''' + ''' The number (index) of the employee, 0 based + ''' The employee + Function GetSelectedEmployee(employeeNumber As Integer) As IEmployee + + ''' + ''' Gets a collection of all the selected employees. + ''' + ''' + Function GetSelectedEmployees() As ICollection(Of IEmployee) + + ''' + ''' Select and store the chosen employee. + ''' + ''' The number (index) for the employee + ''' + Sub SelectEmployee(employeeNumber As Integer, employee As IEmployee) + + ''' + ''' Deselect an employee. + ''' + ''' The number (index) of an employee, 0 based + Sub DeselectEmployee(employeeNumber As Integer) +#End Region + +#Region "Work items" + ''' + ''' Fetches the work items for a certain work post. + ''' + ''' The index of the work post, 0 based + ''' Collection of the work items + Function GiveWorkItems(workPostIndex As Integer) As ICollection(Of IWorkItem) + + Sub StartActivity(activity As IActivity, employeeNumber As Integer) + + Sub FinishActivity(employeeNumber As Integer) + + Sub StopActivity(employeeNumber As Integer) + + Sub PauseActivitiesFromApp() + +#End Region +End Interface Index: ActiviteitenOpvolging/ProductiePitching/My Project/AssemblyInfo.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/My Project/AssemblyInfo.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/My Project/AssemblyInfo.vb (revision 1759) @@ -0,0 +1,35 @@ +Imports System +Imports System.Reflection +Imports System.Runtime.InteropServices + +' General Information about an assembly is controlled through the following +' set of attributes. Change these attribute values to modify the information +' associated with an assembly. + +' Review the values of the assembly attributes + + + + + + + + + + +'The following GUID is for the ID of the typelib if this project is exposed to COM + + +' Version information for an assembly consists of the following four values: +' +' Major Version +' Minor Version +' Build Number +' Revision +' +' You can specify all the values or you can default the Build and Revision Numbers +' by using the '*' as shown below: +' + + + Index: ActiviteitenOpvolging/ProductiePitching/My Project/Settings.Designer.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/My Project/Settings.Designer.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/My Project/Settings.Designer.vb (revision 1759) @@ -0,0 +1,73 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.42000 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + + +Namespace My + + _ + Partial Friend NotInheritable Class MySettings + Inherits Global.System.Configuration.ApplicationSettingsBase + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) + +#Region "My.Settings Auto-Save Functionality" +#If _MyType = "WindowsForms" Then + Private Shared addedHandler As Boolean + + Private Shared addedHandlerLockObject As New Object + + _ + Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs) + If My.Application.SaveMySettingsOnExit Then + My.Settings.Save() + End If + End Sub +#End If +#End Region + + Public Shared ReadOnly Property [Default]() As MySettings + Get + +#If _MyType = "WindowsForms" Then + If Not addedHandler Then + SyncLock addedHandlerLockObject + If Not addedHandler Then + AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings + addedHandler = True + End If + End SyncLock + End If +#End If + Return defaultInstance + End Get + End Property + End Class +End Namespace + +Namespace My + + _ + Friend Module MySettingsProperty + + _ + Friend ReadOnly Property Settings() As Global.ProductiePitching.My.MySettings + Get + Return Global.ProductiePitching.My.MySettings.Default + End Get + End Property + End Module +End Namespace Index: ActiviteitenOpvolging/ProductiePitching/ServiceAgents/Implementations/ActiviteitPerBatch.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ServiceAgents/Implementations/ActiviteitPerBatch.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ServiceAgents/Implementations/ActiviteitPerBatch.vb (revision 1759) @@ -0,0 +1,137 @@ +'------------------------------------------------------------------------------ +' +' Deze code is gegenereerd met een hulpprogramma. +' Runtime-versie:4.0.30319.42000 +' +' Als u wijzigingen aanbrengt in dit bestand, kan dit onjuist gedrag veroorzaken wanneer +' de code wordt gegenereerd. +' +'------------------------------------------------------------------------------ + +Option Strict Off +Option Explicit On + +Imports System.Data + + + +Public Interface ActiviteitPerBatch + + + Function GeefActies(ByVal Werkpost As String) As System.Data.DataSet + + + Function GeefActiesAsync(ByVal Werkpost As String) As System.Threading.Tasks.Task(Of System.Data.DataSet) + + + Function GeefDataSetVoorQuery(ByVal AppNaam As String, ByVal ComputerNaam As String, ByVal QueryNaam As String) As System.Data.DataSet + + + Function GeefDataSetVoorQueryAsync(ByVal AppNaam As String, ByVal ComputerNaam As String, ByVal QueryNaam As String) As System.Threading.Tasks.Task(Of System.Data.DataSet) + + + Function GeefWerknemers(ByVal AppNaam As String, ByVal ComputerNaam As String) As System.Data.DataSet + + + Function GeefWerknemersAsync(ByVal AppNaam As String, ByVal ComputerNaam As String) As System.Threading.Tasks.Task(Of System.Data.DataSet) + + + Function PauzeerActiesVanApp(ByVal AppNaam As String, ByVal ComputerNaam As String) As String + + + Function PauzeerActiesVanAppAsync(ByVal AppNaam As String, ByVal ComputerNaam As String) As System.Threading.Tasks.Task(Of String) + + + Function RegistreerActieByKey(ByVal BatchResActKey As String, ByVal Status As String, ByVal Gebruiker As String, ByVal AppNaam As String, ByVal ComputerNaam As String) As String + + + Function RegistreerActieByKeyAsync(ByVal BatchResActKey As String, ByVal Status As String, ByVal Gebruiker As String, ByVal AppNaam As String, ByVal ComputerNaam As String) As System.Threading.Tasks.Task(Of String) +End Interface + + +Public Interface ActiviteitPerBatchSoapChannel + Inherits ActiviteitPerBatch, System.ServiceModel.IClientChannel +End Interface + + +Partial Public Class ActiviteitPerBatchClient + Inherits System.ServiceModel.ClientBase(Of ActiviteitPerBatch) + Implements ActiviteitPerBatch + + Public Sub New() + MyBase.New + End Sub + + Public Sub New(ByVal endpointConfigurationName As String) + MyBase.New(endpointConfigurationName) + End Sub + + Public Sub New(ByVal endpointConfigurationName As String, ByVal remoteAddress As String) + MyBase.New(endpointConfigurationName, remoteAddress) + End Sub + + Public Sub New(ByVal endpointConfigurationName As String, ByVal remoteAddress As System.ServiceModel.EndpointAddress) + MyBase.New(endpointConfigurationName, remoteAddress) + End Sub + + Public Sub New(ByVal binding As System.ServiceModel.Channels.Binding, ByVal remoteAddress As System.ServiceModel.EndpointAddress) + MyBase.New(binding, remoteAddress) + End Sub + + Public Function GeefActies(ByVal Werkpost As String) As System.Data.DataSet Implements ActiviteitPerBatch.GeefActies + Return MyBase.Channel.GeefActies(Werkpost) + End Function + + Public Function GeefActiesAsync(ByVal Werkpost As String) As System.Threading.Tasks.Task(Of System.Data.DataSet) Implements ActiviteitPerBatch.GeefActiesAsync + Return MyBase.Channel.GeefActiesAsync(Werkpost) + End Function + + Public Function GeefDataSetVoorQuery(ByVal AppNaam As String, ByVal ComputerNaam As String, ByVal QueryNaam As String) As System.Data.DataSet Implements ActiviteitPerBatch.GeefDataSetVoorQuery + Return MyBase.Channel.GeefDataSetVoorQuery(AppNaam, ComputerNaam, QueryNaam) + End Function + + Public Function GeefDataSetVoorQueryAsync(ByVal AppNaam As String, ByVal ComputerNaam As String, ByVal QueryNaam As String) As System.Threading.Tasks.Task(Of System.Data.DataSet) Implements ActiviteitPerBatch.GeefDataSetVoorQueryAsync + Return MyBase.Channel.GeefDataSetVoorQueryAsync(AppNaam, ComputerNaam, QueryNaam) + End Function + + Public Function GeefWerknemers(ByVal AppNaam As String, ByVal ComputerNaam As String) As System.Data.DataSet Implements ActiviteitPerBatch.GeefWerknemers + Return MyBase.Channel.GeefWerknemers(AppNaam, ComputerNaam) + End Function + + Public Function GeefWerknemersAsync(ByVal AppNaam As String, ByVal ComputerNaam As String) As System.Threading.Tasks.Task(Of System.Data.DataSet) Implements ActiviteitPerBatch.GeefWerknemersAsync + Return MyBase.Channel.GeefWerknemersAsync(AppNaam, ComputerNaam) + End Function + + Public Function PauzeerActiesVanApp(ByVal AppNaam As String, ByVal ComputerNaam As String) As String Implements ActiviteitPerBatch.PauzeerActiesVanApp + Return MyBase.Channel.PauzeerActiesVanApp(AppNaam, ComputerNaam) + End Function + + Public Function PauzeerActiesVanAppAsync(ByVal AppNaam As String, ByVal ComputerNaam As String) As System.Threading.Tasks.Task(Of String) Implements ActiviteitPerBatch.PauzeerActiesVanAppAsync + Return MyBase.Channel.PauzeerActiesVanAppAsync(AppNaam, ComputerNaam) + End Function + + Public Function RegistreerActieByKey(ByVal BatchResActKey As String, ByVal Status As String, ByVal Gebruiker As String, ByVal AppNaam As String, ByVal ComputerNaam As String) As String Implements ActiviteitPerBatch.RegistreerActieByKey + Return MyBase.Channel.RegistreerActieByKey(BatchResActKey, Status, Gebruiker, AppNaam, ComputerNaam) + End Function + + Public Function RegistreerActieByKeyAsync(ByVal BatchResActKey As String, ByVal Status As String, ByVal Gebruiker As String, ByVal AppNaam As String, ByVal ComputerNaam As String) As System.Threading.Tasks.Task(Of String) Implements ActiviteitPerBatch.RegistreerActieByKeyAsync + Return MyBase.Channel.RegistreerActieByKeyAsync(BatchResActKey, Status, Gebruiker, AppNaam, ComputerNaam) + End Function +End Class Index: ActiviteitenOpvolging/ProductiePitching/My Project/Application.Designer.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/My Project/Application.Designer.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/My Project/Application.Designer.vb (revision 1759) @@ -0,0 +1,38 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.42000 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + + +Namespace My + + 'NOTE: This file is auto-generated; do not modify it directly. To make changes, + ' or if you encounter build errors in this file, go to the Project Designer + ' (go to Project Properties or double-click the My Project node in + ' Solution Explorer), and make changes on the Application tab. + ' + Partial Friend Class MyApplication + + _ + Public Sub New() + MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows) + Me.IsSingleInstance = false + Me.EnableVisualStyles = true + Me.SaveMySettingsOnExit = true + Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses + End Sub + + _ + Protected Overrides Sub OnCreateMainForm() + Me.MainForm = Global.ProductiePitching.ProductiePitchingForm + End Sub + End Class +End Namespace Index: ActiviteitenOpvolging/ProductiePitching/domain/managers/IworkItemManager.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/managers/IworkItemManager.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/managers/IworkItemManager.vb (revision 1759) @@ -0,0 +1,17 @@ +Public Interface IWorkItemManager + ''' + ''' Fetches the work items for a certain work post. + ''' + ''' The index of the work post, 0 based + ''' Collection of the work items + Function GiveWorkItems(workPostIndex As Integer, employees As List(Of IEmployee)) As ICollection(Of IWorkItem) + + Sub StartActivity(activity As IActivity, employee As IEmployee) + + Sub FinishActivity(activity As IActivity) + + Sub StopActivity(activity As IActivity) + + Sub PauseActivities() + +End Interface Index: ActiviteitenOpvolging/ProductiePitching/mappers/EmployeesDatabaseMapper.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/mappers/EmployeesDatabaseMapper.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/mappers/EmployeesDatabaseMapper.vb (revision 1759) @@ -0,0 +1,113 @@ +Imports System.Data.SqlClient +Imports ProductiePitching.ServiceAgents +Imports ProductiePitching.ServiceAgents.Implementations + +Module EmployeesDatabaseMapper + Private _sqlConnection As SqlConnection + +#Region "Help functions" + + Private ReadOnly _activiteitPerBatchServiceAgent As IActiviteitPerBatchServiceAgent + + Sub New() + _activiteitPerBatchServiceAgent = New ActiviteitPerBatchServiceAgent + End Sub + + ''' + ''' Execution of a query into a data reader. + ''' + ''' The query + ''' The SQL data reader + Private Function ExecuteIntoDataSet() As DataSet + + Try + Return _activiteitPerBatchServiceAgent.GeefWerknemers() + Catch ex As Exception + Throw New Exception($"Could not get dataset from the Caché webservice.{vbNewLine}{ex.Message}") + End Try + End Function + + ''' + ''' Tries to extract a value from a datareader with a key. + ''' If the value is not present, but not required, a default value van be specified. + ''' If the value is not present, but required, an exception will be thrown. + ''' The value will be converted to the specifief type. + ''' + ''' The target type of the value + ''' The datareader + ''' The key, identification of the value + ''' Whether or not the value is required + ''' Optional default value of the value. Standard 'Nothing' or the default value of the type + ''' The value converted to the type of + Private Function ExtractItemFromDataReader(Of T)(ByRef dr As DataTableReader, key As String, isRequired As Boolean, Optional defaultValue As T = Nothing) As T + Dim value As Object + Try + 'Extract the value with the key. Column will always be present. + value = dr.Item(key) + 'Check if the value is DBNull or Nothing. + If IsDBNull(value) Or value Is Nothing Then + 'If so, check if value was required. + If isRequired Then + 'Value was required. + Throw New Exception($"A required value with key '{key}' was empty.") + End If + 'Value was not required, return default value. + Return defaultValue + End If + Catch ex As Exception + Throw New Exception($"A value for a work item can't be fetched from the data reader. The key is '{key}'.") + End Try + Try + 'Do the conversion explicitly, so exceptions can be caught. + Return CType(value, T) + Catch ex As Exception + Throw New Exception($"A value for a work item can't be converted to the specified type. The key is '{key}', the type is {GetType(T).Name}, the value is {value}.") + End Try + End Function + +#End Region + + ''' + ''' Fetches the employees. + ''' + ''' A collection of employees + Public Function FetchEmployees() As ICollection(Of IEmployee) + 'Define the query. + + 'Initialise the list with employees. + Dim employees As New List(Of IEmployee) + + 'Declare SQL data reader. + Dim dataReader As DataTableReader = Nothing + + Try + 'Fetch the data reader with the query. + Dim CacheDataSet As DataSet = ExecuteIntoDataSet() + dataReader = CacheDataSet.CreateDataReader() + + While dataReader.Read() + 'Initialise new Employee. + Dim employee As New Employee + With employee + .PersonelNumber = ExtractItemFromDataReader(Of Integer)(dataReader, "PersNr", True) + .Picture = ExtractItemFromDataReader(Of String)(dataReader, "Foto", True, String.Empty) + .FirstName = ExtractItemFromDataReader(Of String)(dataReader, "Voornaam", False, String.Empty) + .LastName = ExtractItemFromDataReader(Of String)(dataReader, "Achternaam", False, String.Empty) + .Initials = ExtractItemFromDataReader(Of String)(dataReader, "Initialen", True) + End With + + 'Add new employee to list. + employees.Add(employee) + End While + 'Return the employees. + Return employees + Catch ex As Exception + Throw New Exception($"An error occured while fetching the employees.{vbNewLine}{ex.Message}") + Finally + 'Close connection if datareader is not nothing. + If Not IsNothing(dataReader) Then + dataReader.Close() + End If + End Try + End Function +End Module Index: ActiviteitenOpvolging/ProductiePitching/domain/managers/implementations/EmployeeManager.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/managers/implementations/EmployeeManager.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/managers/implementations/EmployeeManager.vb (revision 1759) @@ -0,0 +1,93 @@ +Imports ProductiePitching.configs + +Public Class EmployeeManager + Implements IEmployeeManager + + Private ReadOnly _employees As ICollection(Of IEmployee) + ''' + Public ReadOnly Property Employees As ICollection(Of IEmployee) Implements IEmployeeManager.Employees + Get + Return New HashSet(Of IEmployee)(_employees) + End Get + End Property + + ''' + Public ReadOnly Property AvailableEmployees As ICollection(Of IEmployee) Implements IEmployeeManager.AvailableEmployees + Get + 'Select the employees from the collection of all employees, which are not selected yet. + 'The employees are compared on their initials in lowercase. + Return New HashSet(Of IEmployee)(_employees.Where(Function(employee) _ + Not _selectedEmployeesDictionary.Values.Any(Function(selectedEmployee) _ + employee.Equals(selectedEmployee)))) + End Get + End Property + + Private ReadOnly _selectedEmployeesDictionary As new Dictionary(Of Integer, IEmployee) + ''' + Public ReadOnly Property SelectedEmployees As ICollection(Of IEmployee) Implements IEmployeeManager.SelectedEmployees + Get + Return New HashSet(Of IEmployee)(_selectedEmployeesDictionary.Values) + End Get + End Property + + Sub New() + 'Initial fetching of employees, then stored. + _employees = EmployeesDatabaseMapper.FetchEmployees() + 'Filling the selected employees dictionary with the employee number (an index) and 'Nothing' as value. Indicating no selected employee. + For i = 0 To ConfigsLoader.NumberOfEmployees - 1 + _selectedEmployeesDictionary.Add(i, Nothing) + Next + End Sub + + ''' + Public Function GetSelectedEmployee(employeeNumber As Integer) As IEmployee Implements IEmployeeManager.GetSelectedEmployee + If not _selectedEmployeesDictionary.ContainsKey(employeeNumber) Then + Throw New InternalException($"Employee number for getting the selected value is invalid, key value: {employeeNumber}.") + End If + 'Get the value. + Return _selectedEmployeesDictionary.Item(employeeNumber) + End Function + + ''' + Public Sub SelectEmployee(employeeNumber As Integer, employee As IEmployee) Implements IEmployeeManager.SelectEmployee + 'Employee number must be valid: exist in the dictionary. + If not _selectedEmployeesDictionary.ContainsKey(employeeNumber) Then + Throw New InternalException($"Employee number for selecting an employee is invalid, key value: {employeeNumber}.") + End If + 'Employee can't be nothing. + If employee Is Nothing Then + Throw New InternalException($"The soon-to-be selected Employee can't be nothing.") + End If + 'Check whether or not that employee is already picked. The selected employees can be 'Nothing'. + If _selectedEmployeesDictionary.Values.Any(Function(selectedEmployee) Not IsNothing(selectedEmployee) AndAlso selectedEmployee.Equals(employee)) Then + 'Employee was picked already. + Throw New Exception("Employee was already chosen.") + End If + 'No employee can already be selected for that number. + If _selectedEmployeesDictionary.Item(employeeNumber) IsNot Nothing Then + Throw New Exception($"An employee was already chosen for number (index): {employeeNumber}.") + End If + + 'Update the employeeNumber in the employee. + employee.Number = employeeNumber + + 'Add employee to dictionary of selected employees -> set the value according to an employee number. + _selectedEmployeesDictionary.Item(employeeNumber) = employee + End Sub + + ''' + Public Sub RemoveEmployeeSelection(employeeNumber As Integer) Implements IEmployeeManager.RemoveEmployeeSelection + 'Find the employee to remove. + Dim employeeToRemove = _selectedEmployeesDictionary.Item(employeeNumber) + If employeeToRemove Is Nothing Then + 'The employee was not selected, thus can't be deselected. + Throw New Exception("Cannot remove the selection of a non-selected employee.") + End If + + 'Update the employee number of the employee. + _selectedEmployeesDictionary.Item(employeeNumber).Number = -1 + + 'Remove the employee -> set the value back to 'Nothing'. + _selectedEmployeesDictionary.Item(employeeNumber) = Nothing + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/GeneralConfigs.txt =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/GeneralConfigs.txt (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/GeneralConfigs.txt (revision 1759) @@ -0,0 +1,47 @@ +% Refresh frequentie in sec +RefreshFrequence=60 + +% De applicatie moet zich alleen instellen als er geproduceerd wordt van 6 tot 22u +RefreshTimeStart=06 +RefreshTimeEnd=22 + +% URL naar de webservice van Cache +CacheWebserviceURL=http://cache01:57772/csp/admin1/WS.Halux.Planning.ActiviteitPerBatchService.CLS + +% Start vooraf tijdstip drempel (in minuten) +StartBeforeTimeThreshold=15 +% Start bijna tijdstip drempel (in minuten) +StartAlmostTimeThreshold=10 + +% Kleur codes +AgColorBatch=#FFFFFF +AgColorProductGroup=#FFFFFF +AgColorTo=#FFFFFF + +% Pad naar afbeeldingen voor en bijna status activiteit +ImageBefore=Images\warning.png +ImageAlmost=Images\danger.png +ImageLate=Images\late.png + +% Kleur activiteit +AgColorActivityDefaulted=#FFFFFF +AgColorActivityStopped=#AE76A3 +AgColorActivityStarted=#F1932D +AgColorActivityFinished=#40B265 +AgColorActivityZero=#dbf5d7 + +% Kleur activiteit Read Only +AgColorActivityReadOnlyDefaulted=#CCCCCC +AgColorActivityReadOnlyStopped=#CAE0AB +AgColorActivityReadOnlyStarted=#F6C141 +AgColorActivityReadOnlyFinished=#5de389 +AgColorActivityReadOnlyZero=#dbf5d7 + +% Kleur activiteit specials +ColorActivityAllFinished=#90C987 + +% Kleur gebruiker +ColorEmployee1=#72190E +ColorEmployee2=#4EB625 +ColorEmployee3=#1965B0 +ColorEmployee4=#882E72 \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/My Project/Application.myapp =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/My Project/Application.myapp (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/My Project/Application.myapp (revision 1759) @@ -0,0 +1,10 @@ + + + true + ProductiePitchingForm + false + 0 + true + 0 + true + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/details/EmployeeDetailUserControl.Designer.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/details/EmployeeDetailUserControl.Designer.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/details/EmployeeDetailUserControl.Designer.vb (revision 1759) @@ -0,0 +1,244 @@ + _ +Partial Class EmployeeDetailUserControl + Inherits System.Windows.Forms.UserControl + + 'UserControl overrides dispose to clean up the component list. + _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + _ + Private Sub InitializeComponent() + Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(EmployeeDetailUserControl)) + Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel() + Me.ActivityNameLabel = New System.Windows.Forms.Label() + Me.ActivityVisualLabel = New System.Windows.Forms.Label() + Me.ImagePictureBox = New System.Windows.Forms.PictureBox() + Me.StartButton = New System.Windows.Forms.Button() + Me.StopButton = New System.Windows.Forms.Button() + Me.FinishButton = New System.Windows.Forms.Button() + Me.NameLabel = New System.Windows.Forms.Label() + Me.StatusLabel = New System.Windows.Forms.Label() + Me.BatchVisualLabel = New System.Windows.Forms.Label() + Me.BatchLabel = New System.Windows.Forms.Label() + Me.RemoveEmployeeButton = New System.Windows.Forms.Button() + Me.TableLayoutPanel1.SuspendLayout + CType(Me.ImagePictureBox,System.ComponentModel.ISupportInitialize).BeginInit + Me.SuspendLayout + ' + 'TableLayoutPanel1 + ' + Me.TableLayoutPanel1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ + Or System.Windows.Forms.AnchorStyles.Left) _ + Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles) + Me.TableLayoutPanel1.ColumnCount = 3 + Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33332!)) + Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334!)) + Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334!)) + Me.TableLayoutPanel1.Controls.Add(Me.ActivityNameLabel, 1, 5) + Me.TableLayoutPanel1.Controls.Add(Me.ActivityVisualLabel, 0, 5) + Me.TableLayoutPanel1.Controls.Add(Me.ImagePictureBox, 2, 0) + Me.TableLayoutPanel1.Controls.Add(Me.StartButton, 1, 7) + Me.TableLayoutPanel1.Controls.Add(Me.StopButton, 1, 9) + Me.TableLayoutPanel1.Controls.Add(Me.FinishButton, 1, 11) + Me.TableLayoutPanel1.Controls.Add(Me.NameLabel, 0, 1) + Me.TableLayoutPanel1.Controls.Add(Me.StatusLabel, 0, 3) + Me.TableLayoutPanel1.Controls.Add(Me.BatchVisualLabel, 0, 4) + Me.TableLayoutPanel1.Controls.Add(Me.BatchLabel, 1, 4) + Me.TableLayoutPanel1.Controls.Add(Me.RemoveEmployeeButton, 2, 3) + Me.TableLayoutPanel1.Location = New System.Drawing.Point(3, 3) + Me.TableLayoutPanel1.Name = "TableLayoutPanel1" + Me.TableLayoutPanel1.RowCount = 13 + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 9.810695!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 9.810695!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 9.810695!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 9.810695!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 9.810695!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 9.810695!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 2.026642!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10.6677!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 3.039962!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10.6677!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 3.039962!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10.6677!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 1.026197!)) + Me.TableLayoutPanel1.Size = New System.Drawing.Size(494, 594) + Me.TableLayoutPanel1.TabIndex = 0 + ' + 'ActivityNameLabel + ' + Me.ActivityNameLabel.AutoSize = true + Me.ActivityNameLabel.Dock = System.Windows.Forms.DockStyle.Fill + Me.ActivityNameLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.ActivityNameLabel.Location = New System.Drawing.Point(167, 290) + Me.ActivityNameLabel.Name = "ActivityNameLabel" + Me.ActivityNameLabel.Size = New System.Drawing.Size(158, 58) + Me.ActivityNameLabel.TabIndex = 11 + Me.ActivityNameLabel.Text = "activity" + Me.ActivityNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter + ' + 'ActivityVisualLabel + ' + Me.ActivityVisualLabel.AutoSize = true + Me.ActivityVisualLabel.Dock = System.Windows.Forms.DockStyle.Right + Me.ActivityVisualLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.ActivityVisualLabel.Location = New System.Drawing.Point(104, 290) + Me.ActivityVisualLabel.Name = "ActivityVisualLabel" + Me.ActivityVisualLabel.Size = New System.Drawing.Size(57, 58) + Me.ActivityVisualLabel.TabIndex = 9 + Me.ActivityVisualLabel.Text = "Activiteit" + Me.ActivityVisualLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight + ' + 'ImagePictureBox + ' + Me.ImagePictureBox.Dock = System.Windows.Forms.DockStyle.Fill + Me.ImagePictureBox.Image = Global.ProductiePitching.My.Resources.Resources.user + Me.ImagePictureBox.InitialImage = Nothing + Me.ImagePictureBox.Location = New System.Drawing.Point(331, 3) + Me.ImagePictureBox.Name = "ImagePictureBox" + Me.TableLayoutPanel1.SetRowSpan(Me.ImagePictureBox, 3) + Me.ImagePictureBox.Size = New System.Drawing.Size(160, 168) + Me.ImagePictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom + Me.ImagePictureBox.TabIndex = 0 + Me.ImagePictureBox.TabStop = false + ' + 'StartButton + ' + Me.StartButton.Dock = System.Windows.Forms.DockStyle.Fill + Me.StartButton.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.StartButton.Location = New System.Drawing.Point(155, 363) + Me.StartButton.Name = "StartButton" + Me.StartButton.Size = New System.Drawing.Size(178, 62) + Me.StartButton.TabIndex = 2 + Me.StartButton.Text = "START" + Me.StartButton.UseVisualStyleBackColor = true + ' + 'StopButton + ' + Me.StopButton.Dock = System.Windows.Forms.DockStyle.Fill + Me.StopButton.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.StopButton.Location = New System.Drawing.Point(155, 444) + Me.StopButton.Name = "StopButton" + Me.StopButton.Size = New System.Drawing.Size(178, 62) + Me.StopButton.TabIndex = 5 + Me.StopButton.TabStop = false + Me.StopButton.Text = "X" + Me.StopButton.UseVisualStyleBackColor = true + ' + 'FinishButton + ' + Me.FinishButton.Dock = System.Windows.Forms.DockStyle.Fill + Me.FinishButton.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.FinishButton.Location = New System.Drawing.Point(155, 525) + Me.FinishButton.Name = "FinishButton" + Me.FinishButton.Size = New System.Drawing.Size(178, 62) + Me.FinishButton.TabIndex = 4 + Me.FinishButton.Text = "AFGEWERKT" + Me.FinishButton.UseVisualStyleBackColor = true + ' + 'NameLabel + ' + Me.NameLabel.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _ + Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles) + Me.NameLabel.AutoSize = true + Me.TableLayoutPanel1.SetColumnSpan(Me.NameLabel, 2) + Me.NameLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.NameLabel.Location = New System.Drawing.Point(3, 58) + Me.NameLabel.Name = "NameLabel" + Me.TableLayoutPanel1.SetRowSpan(Me.NameLabel, 2) + Me.NameLabel.Size = New System.Drawing.Size(322, 16) + Me.NameLabel.TabIndex = 6 + Me.NameLabel.Text = "Name" + Me.NameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft + ' + 'StatusLabel + ' + Me.StatusLabel.AutoSize = true + Me.TableLayoutPanel1.SetColumnSpan(Me.StatusLabel, 2) + Me.StatusLabel.Dock = System.Windows.Forms.DockStyle.Left + Me.StatusLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.StatusLabel.Location = New System.Drawing.Point(3, 174) + Me.StatusLabel.Name = "StatusLabel" + Me.StatusLabel.Size = New System.Drawing.Size(45, 58) + Me.StatusLabel.TabIndex = 7 + Me.StatusLabel.Text = "Status" + Me.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft + ' + 'BatchVisualLabel + ' + Me.BatchVisualLabel.AutoSize = true + Me.BatchVisualLabel.Dock = System.Windows.Forms.DockStyle.Right + Me.BatchVisualLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.BatchVisualLabel.Location = New System.Drawing.Point(119, 232) + Me.BatchVisualLabel.Name = "BatchVisualLabel" + Me.BatchVisualLabel.Size = New System.Drawing.Size(42, 58) + Me.BatchVisualLabel.TabIndex = 8 + Me.BatchVisualLabel.Text = "Batch" + Me.BatchVisualLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight + ' + 'BatchLabel + ' + Me.BatchLabel.AutoSize = true + Me.BatchLabel.Dock = System.Windows.Forms.DockStyle.Fill + Me.BatchLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.BatchLabel.Location = New System.Drawing.Point(167, 232) + Me.BatchLabel.Name = "BatchLabel" + Me.BatchLabel.Size = New System.Drawing.Size(158, 58) + Me.BatchLabel.TabIndex = 10 + Me.BatchLabel.Text = "batch" + Me.BatchLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter + ' + 'RemoveEmployeeButton + ' + Me.RemoveEmployeeButton.BackColor = System.Drawing.Color.White + Me.RemoveEmployeeButton.BackgroundImage = CType(resources.GetObject("RemoveEmployeeButton.BackgroundImage"),System.Drawing.Image) + Me.RemoveEmployeeButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom + Me.RemoveEmployeeButton.Dock = System.Windows.Forms.DockStyle.Fill + Me.RemoveEmployeeButton.Location = New System.Drawing.Point(343, 177) + Me.RemoveEmployeeButton.Margin = New System.Windows.Forms.Padding(15, 3, 15, 3) + Me.RemoveEmployeeButton.Name = "RemoveEmployeeButton" + Me.RemoveEmployeeButton.Size = New System.Drawing.Size(136, 52) + Me.RemoveEmployeeButton.TabIndex = 12 + Me.RemoveEmployeeButton.UseVisualStyleBackColor = false + ' + 'EmployeeDetailUserControl + ' + Me.AutoScaleDimensions = New System.Drawing.SizeF(6!, 13!) + Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font + Me.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle + Me.Controls.Add(Me.TableLayoutPanel1) + Me.Name = "EmployeeDetailUserControl" + Me.Size = New System.Drawing.Size(500, 600) + Me.TableLayoutPanel1.ResumeLayout(false) + Me.TableLayoutPanel1.PerformLayout + CType(Me.ImagePictureBox,System.ComponentModel.ISupportInitialize).EndInit + Me.ResumeLayout(false) + +End Sub + + Friend WithEvents TableLayoutPanel1 As TableLayoutPanel + Friend WithEvents ImagePictureBox As PictureBox + Friend WithEvents StartButton As Button + Friend WithEvents FinishButton As Button + Friend WithEvents StopButton As Button + Friend WithEvents NameLabel As Label + Friend WithEvents StatusLabel As Label + Friend WithEvents BatchVisualLabel As Label + Friend WithEvents ActivityVisualLabel As Label + Friend WithEvents BatchLabel As Label + Friend WithEvents ActivityNameLabel As Label + Friend WithEvents RemoveEmployeeButton As Button +End Class Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityZeroState.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityZeroState.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityZeroState.vb (revision 1759) @@ -0,0 +1,13 @@ +Public Class ActivityZeroState + Inherits ActivityState + + 'Can't go from another state into this one. + Public Sub New(activity As IActivity) + Me.Activity = activity + End Sub + + ''' + Public Overrides Function ActivityStateEnum() As ActivityStateEnum + Return ProductiePitching.ActivityStateEnum.Zero + End Function +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/EmployeeUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/EmployeeUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/EmployeeUserControl.vb (revision 1759) @@ -0,0 +1,172 @@ +Imports ProductiePitching.configs + +Public Class EmployeeUserControl + Implements IEmployeeUserControl, IEmployeeDetailParentUserControl, IEmployeePickerParentUserControl + + Private ReadOnly _parentForm As IEmployeesMainForm + Private _currentUserControl As IRefreshableUserControl + + Private ReadOnly Property EmployeeIndex As Integer + + Private Sub New() + ' This call is required by the designer. + InitializeComponent() + End Sub + + ''' + ''' Initialises the user form. + ''' + ''' The form containing this user control + ''' The index of the employee, 0 based + Sub New(parentForm As IEmployeesMainForm, employeeIndex As Integer) + 'Call base constructor. + Me.New() + 'Set parameters. + + 'Parent form. + 'Value can't be Nothing. + If parentForm Is Nothing Then Throw New InternalException($"The parent form can't be 'Nothing' in a {Me.Name}.") + _parentForm = parentForm + + 'Grid number. + Me.EmployeeIndex = employeeIndex + End Sub + + Private Sub EmployeeUserControl_Load(sender As Object, e As EventArgs) Handles MyBase.Load + Try + 'Set back color corresponding to the employee index. + BackColor = Color.White + ForeColor = Color.Black + 'Set border style. + BorderStyle = BorderStyle.FixedSingle + + 'Show the Employee picker user control. + SwitchUserControl(New EmployeePickerUserControl(Me)) + Catch ex As Exception + MessageBox.Show($"Could not load {Me.Name}.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + + ''' + ''' Update border of the user control. + ''' + Private Sub EmployeeUserControl_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint + 'Border color. + Dim borderColor = ConfigsLoader.ColorsEmployees(EmployeeIndex) + 'Border thickness. + Const borderThickness As Integer = 5I + 'Border rectangle. + Dim borderRectangle = Me.ClientRectangle + 'Draw the border. + e.Graphics.DrawRectangle(New Pen(borderColor, borderThickness), borderRectangle) + End Sub + + ''' + ''' Switch to another user control on the screen. + ''' + ''' Must be a refreshable user control + ''' + Private Sub SwitchUserControl(Of T As {IRefreshableUserControl, UserControl})(userControl As T) + 'Set current user control. + _currentUserControl = userControl + 'Remove the current user control from the screen. + UserControlPanel.Controls.Clear() + 'Make it exactly as big as the panel it will go into. + userControl.Size = UserControlPanel.Size + 'Add it onto the panel. + UserControlPanel.Controls.Add(userControl) + End Sub + + ''' + Public Function RefreshData() As Boolean Implements IRefreshableUserControl.RefreshData + 'Update the current user control. + Return _currentUserControl.RefreshData() + End Function + +#Region "Employee picking" + ''' + Public Function GetAllEmployees() As ICollection(Of IEmployee) Implements IEmployeePickerParentUserControl.GetAllEmployees + Return _parentForm.GetAllEmployees() + End Function + + ''' + Public Sub SelectEmployee(employee As IEmployee) Implements IEmployeePickerParentUserControl.SelectEmployee + Try + 'Call parent to select employee. + _parentForm.SelectEmployee(EmployeeIndex, employee) + 'Load detail user control. + SwitchUserControl(New EmployeeDetailUserControl(Me)) + Catch ex As Exception + MessageBox.Show($"Could not select employee.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + + ''' + Public Sub SelectedEmployeeChanged() Implements IEmployeeUserControl.SelectedEmployeeChanged + Try + 'If the current user control is to select the employee, make it refresh. + If TypeOf _currentUserControl Is EmployeePickerUserControl Then + _currentUserControl.RefreshData() + End If + Catch ex As Exception + MessageBox.Show($"Could not update after employee selection changed.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + +#End Region + +#Region "Employee details" + + ''' + Public Function FetchEmployee() As IEmployee Implements IEmployeeDetailParentUserControl.FetchEmployee + Return _parentForm.GetSelectedEmployee(EmployeeIndex) + End Function + + ''' + Public Sub DeselectEmployee() Implements IEmployeeDetailParentUserControl.DeselectEmployee + Try + 'Call parent to deselect employee. + _parentForm.DeselectEmployee(EmployeeIndex) + + 'Switch to employee picker user control. + SwitchUserControl(New EmployeePickerUserControl(Me)) + Catch ex As Exception + MessageBox.Show($"Could not deselect employee.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + + ''' + Public Sub SelectedActivityChanged() Implements IEmployeeUserControl.SelectedActivityChanged + Try + 'If the current user control is to select the employee, make it refresh. + If TypeOf _currentUserControl Is EmployeeDetailUserControl Then + _currentUserControl.RefreshData() + End If + Catch ex As Exception + MessageBox.Show($"Could not update after activity selection changed.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + + ''' + Public Function GetCurrentlySelectedActivity() As IActivity Implements IEmployeeDetailParentUserControl.GetCurrentlySelectedActivity + Return _parentForm.GetCurrentlySelectedActivity() + End Function + + ''' + Public Sub StartActivity() Implements IEmployeeDetailParentUserControl.StartActivity + 'Start activity with correct employee. + _parentForm.StartActivity(EmployeeIndex) + End Sub + + ''' + Public Sub FinishActivity() Implements IEmployeeDetailParentUserControl.FinishActivity + _parentForm.FinishActivity(EmployeeIndex) + End Sub + + ''' + Public Sub StopActivity() Implements IEmployeeDetailParentUserControl.StopActivity + _parentForm.StopActivity(EmployeeIndex) + End Sub +#End Region + +End Class Index: ActiviteitenOpvolging/ProductiePitching/domain/controllers/DomainController.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/controllers/DomainController.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/controllers/DomainController.vb (revision 1759) @@ -0,0 +1,96 @@ +Public Class DomainController + Implements IDomainController + + Private ReadOnly _employeeManager As IEmployeeManager + Private ReadOnly _workItemManager As IWorkItemManager + +#Region "Singleton pattern" + + Private Shared _instance As DomainController + + Private Sub New() + 'Initialise managers. + _employeeManager = New EmployeeManager + _workItemManager = New WorkItemManager + End Sub + + ''' + ''' Gets an instance of the domain controller. Only one instance exists. + ''' + ''' The instance of the domain controller + Public Shared Function GetInstance() As IDomainController + 'If no instance is present, initialise. + If _instance Is Nothing Then + _instance = New DomainController() + End If + 'Return instance. + Return _instance + End Function +#End Region + +#Region "Employees" + + ''' + Public Function GetAvailableEmployees() As ICollection(Of IEmployee) Implements IDomainController.GetAvailableEmployees + Return _employeeManager.AvailableEmployees + End Function + + ''' + Public Function GetSelectedEmployee(employeeNumber As Integer) As IEmployee Implements IDomainController.GetSelectedEmployee + Return _employeeManager.GetSelectedEmployee(employeeNumber) + End Function + + ''' + Public Function GetSelectedEmployees() As ICollection(Of IEmployee) Implements IDomainController.GetSelectedEmployees + Return _employeeManager.SelectedEmployees + End Function + + ''' + Public Sub SelectEmployee(employeeNumber As Integer, employee As IEmployee) Implements IDomainController.SelectEmployee + _employeeManager.SelectEmployee(employeeNumber, employee) + End Sub + + ''' + Public Sub DeselectEmployee(employeeNumber As Integer) Implements IDomainController.DeselectEmployee + _employeeManager.RemoveEmployeeSelection(employeeNumber) + End Sub +#End Region + +#Region "Work items" + + ''' + Function GiveWorkItems(workPostIndex As Integer) As ICollection(Of IWorkItem) Implements IDomainController.GiveWorkItems + Return _workItemManager.GiveWorkItems(workPostIndex, _employeeManager.Employees.ToList()) + End Function + + Public Sub StartActivity(activity As IActivity, employeeNumber As Integer) Implements IDomainController.StartActivity + Dim employee = _employeeManager.GetSelectedEmployee(employeeNumber) + 'Employee can't be nothing. + If IsNothing(employee) Then Throw New Exception($"No employee found for employee number: {employeeNumber}.") + 'Finish the activity. + _workItemManager.StartActivity(activity, employee) + End Sub + + Public Sub FinishActivity(employeeNumber As Integer) Implements IDomainController.FinishActivity + Dim employee = _employeeManager.GetSelectedEmployee(employeeNumber) + 'Employee can't be nothing. + If IsNothing(employee) Then Throw New Exception($"No employee found for employee number: {employeeNumber}.") + 'Finish the activity. + _workItemManager.FinishActivity(employee.CurrentActivity) + End Sub + + Public Sub StopActivity(employeeNumber As Integer) Implements IDomainController.StopActivity + Dim employee = _employeeManager.GetSelectedEmployee(employeeNumber) + 'Employee can't be nothing. + If IsNothing(employee) Then Throw New Exception($"No employee found for employee number: {employeeNumber}.") + 'Stop the activity. + _workItemManager.StopActivity(employee.CurrentActivity) + End Sub + + Public Sub PauseActivitiesFromApp() Implements IDomainController.PauseActivitiesFromApp + _workItemManager.PauseActivities() + End Sub + +#End Region + +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/details/EmployeeDetailUserControl.resx =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/details/EmployeeDetailUserControl.resx (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/details/EmployeeDetailUserControl.resx (revision 1759) @@ -0,0 +1,469 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA3TAAAN0wG91RxqAAAAAmJL + R0QAAKqNIzIAAAAHdElNRQfjBx8NGQ0LNx6jAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE5LTA3LTMxVDEx + OjI1OjEzKzAyOjAwyknErwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOS0wNy0zMVQxMToyNToxMyswMjow + MLsUfBMAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAABPM0lEQVR4Xu29Cfju1by/ + 75xjjETRSIMoQgihyDx0kiFDKVKG1K8cU4YyVsZMmUqIdMxCohJKMqYSISWUEBFJGc9x/v/XnR7tdmvv + /R2eYa31ue/ruq/Lldr7+32ez/qs6T1cS0Sa5dpxvXj3+ND4hLhXfFl8c3x//HT8fPxiPDmeFk+PZ8Wf + XOl3r/xnp8YvxS/E4+In4mHxwLhPfEZ8XHxA3DSuGUVERGTMXDcywTPh7hqZ2A+Nx8Qz42/jH+If42Xx + 8vin+Of41/i3+Pcr/Z8r/d8l/MeVLvnP+HdG/w3y5/wl8mfyZ/N38PddGvm7L4ynRBYLb4l7xx3iveLq + 8d+jiIiIFGCSvEW8f9wtvj4eFb8TfxaZZJnsL4lM9EzITNT/F/+/GcvPwEKBBQILg9/H38RfRk4Xvhk/ + EF8ed4qcVqwWRUREBgWT/crxrvHJkaN6juiZ7M+Nv4gXR3bb7MhLk24rjhYHLAwuiixmzo7fjpxi8Lvz + GfBZ3DD+WxQREemC/4hrR+7onx/fE0+I3MUz4bOz56i+ht38tOR35RSD353PgM/i2MgVwu6R64ObRhcE + IiLSFKvEzeITIwF0BOJ9K54XuTsf0mQ/V7nS4OTjnPjV+LH46shneOd4oygiIlIV7FQJ1ts2vii+OxJF + z7E+u9zWj/JnIVcHXBvwGXJd8PZIhsN946pRRERkJnCXv0Z8UHxefG9k50rAHpNXaVLThUuQ4Y/j8fFt + 8VmRz/5m0asCERGZKNeJROs/JO4Z3xTJmSfqnXS60sSl45cTFRZafPZcsewSt4icDJh2KCIiY4HdJXf6 + 3ENTaIcJ56RIultpctLpSjzF+ZG0yRfHR8XbRbIKRERE5s31I/f63Dmz2yeX/afRAL565WTg+5FiSZwK + kE2wTqSgkoiIyHK5SdwkspN8TSR6n5S10oSj9UrRpC9HChBxZbNBvEEUERH5FxzzM/FvHNk5cpxM9H5p + YtG2JDaD9MuD4zbxVpFCTCIiMmAo0kPBmVvHPeI3ItHmpYlE25caDKRnUpKYYE4WAmYQiIgMCCLFV4pM + /K+N1K03V384UnmRcsTEdpBGSLyHCwERkc5h109gGHfDdLMrTRA6HOlP8F/R0sMiIp1C73zSw2hAw1Fw + aTLQ4XpBpN3yLaMLARGRDmDipy4/1ePotEd/e1P5dGkJFiT+48xI0yZSQEVEpEHYxd02HhDJDaclrdX6 + dEXSlIgiT1+P9B6gk6OIiDQCd/zUiv9SpEwvL/XSy151WRIoSHDo0ZGsAapBiohIpfCS3j7SSpbcb477 + Sy931bl6eTwrvidSUIh+ECIiUgmk9T0gvjPSPvayWHqZqy5EYka4FqDb436RqyUREZkxHPfTjveLkbQ+ + A/x0UnKVxLUAJ0xUjLxRFBGRKXO9SKOed0VyuS3ko9Py75FsgVdHMkyoLSEiIhOGzm4bxWfGY6MTv85C + Tpq4avpopE306tGFgIjIBCCtjyC/B0Uau1wUSy9m1WlLmilFhO4WKTEtIiJjgsjr9eOu8QvRfH6tTYoI + fSjSRprTAAJTRURkERBoxc6K3vxU8iu9fFVr8bvx2ZFrKuJURERknrCDolPbI+InI4VZSi9c1dokZfCQ + uGW8cRQRkTlC/f5144vij2LpJatas1xTfTnuEOk06JWAiMgKYPK/fXxvtF2vtu758aXRLAERkRXwwHhy + tH6/9iLpgh+JG0cREVkKdkf/FanhX3qJqrYs9SrOiMS0iIjIlawR/zvSuc8UP+1VFgEscIlt4apLRGTQ + kC5FHf9Lo5O/9i6LgAsjJazNEBCRQcIOaPN4SqSIik18dCiy0P1d/ERcK5ohICKDgXKpj45M/gb76RBl + wXt5PDreKVLtUkSka1aNT4/fjh7569D9S/xcpMeFfQREpEto5nOL+ML4vVh6GaoOUU7BvhQfE28SRUS6 + gcn/VpGOaT+JpZegjldOV9hdctdMDwU+93MinevoZU/Neq5gTrvyf/PPzopUXvxpJFCNQkz0vi/9+Tpe + uRL4atwprhZFRJqHACci/feL5viPRyYLJncm9h/Er0eOkT8WD4tvja+Lr4gviM+Mu8WnxCdFJpkd43bx + cVf+b/7Zk+NT4zPis+I+8YD4hviOeHj8VDwhnhpZUJC6aRzH+OS73CVSOVBEpFko7nO7+Kp4QSy98HT5 + sgP/bfxhZHI4JlIz4c2R6xQmdVrQbhXvENeJK8dxlZ3l9Oa6kXr268XNIvfVj4+7R8rcHhw/Gj8fWRhw + 2mBa58LlZIY4GTIERESagwlok3hg/GUsvej0mhIZ/vP4nXhipIQsu3km220iEeO1HRHzXbPwuEfkHvu5 + 8W2R0wKOtbla+HW0o+PcJUj2/8W1o4hIM3DsT91zdqkXxdILTv8phWFoH3tu/Eb8YGRX/djIjp7dfItw + ckA753tGjrRZxBwVvxn5XfmdPSFYvsRrcBVDpUwRkerhxc9R8Zsiu77Si23Icn/PTpi7cwLu2CEfGneN + t4kct/fK9eJtI78rv/O3IgGHl0QWQqXPa+hyekKPDK5gRESqhcl/zcjO38n/Kpn0uctnoiMWgkmfAL0t + 41BrwvOsUAqX+AViCMhC+FX8Y3QxcHVJmyWI84ZRRKRKOK5+Y3Ty/6cccf81ctxNYNfLI/fkNoK5Jjw7 + xDiwGDg70kKXRROLp9JnOzS5Dtg59nxCJCKNQiDYa6KT/1WSpvee+IB4/Shzg+NuUhQ/GVk8lT7bIUom + CGmbIiLVwHEuO/+LY+nFNSTJzydVb4doLvfiIJj01nHveHoc+mkAvz8plvTREBGpAl7Q7PyH/IKm4h67 + /ftE+h1wVMvCSBYHiwBOT8iJf0T8eORapfQdDEHiI7giuXcUEZkpFIQhz3+oKV1EsVPi+M7x5tGJfzKw + ELhBJC/+/pF++gQMlr6T3iWLhBLOZI2IiEwd7vzvGsnpHtrkzy7s/EiFQwrzMPEb2DcdWFyRTnjLSPVD + 0gmJExja6ROnIBSK4prJBaeITA0mu9vHL8chTf5EpVP//tWRyYfqd758Zwc99GkytW18X6S2wpCeRxYB + XDtx5eRzKCITh50/gVk0nhlKpzgmFRoZUd5267hu5Eha6oATAcpOPzGSOTCkYFROP2i0ZaEgEZko7DLY + 9RLxT8360gupN9lVfiJSzpbyxiyApE5WipvH58QvRNoZl77T3qS4FNUVbxJFRCYCd917RXrFl15EPUmA + GXesL4rUs2dykTZgN/zASCOq78YhtCumC+NDo9UCRWTsULaVTm90qSu9gHqRYDLu+Q+JHPd7tNomnFbR + k4KTG1IHe+9IyXN7ZLx7tFqgiIwN7ljvGz8TSy+fXuQ+lZ72dGAjzsF7/vbh2d0sHhDZJfdcQ4AiVPTh + 2Cj67IrIouHO+47xnbHXoD92T3TmY9e/RfS4vz9Wi5TR/VTsuVw17bcpzEXhJBGRRUHQH4Vueq3J/ufI + znDPSIyD6VT9Qvoqu2OCWKmr32vXQboH7hRvFEVEFgQ7YaKLfxBLL5qWZddPuhh1++8VvTcdDjzXj40s + /P4UeywidHTk2s4CVSIybzj6v19kgiy9YFqWnR9BYW+IRE276x8e3JFvGD8bOd3qrYAQ5YLfGtePIiLz + gqN/7sR5kZReMK1KHAP3/ZxsiBAk+NpIXEBviwDSdZ8f6aEgIjIn2P3vE3tLnSIC/OR4lyiyJLRv/nHs + bRHw9fioKCIyJ7aP9F8vvVBalYp+lPKlbrpIiU3jcZHA0NIz1KLENxwVKZUsIrJciJLmXrSn6mns7F4Q + KWbkfb8sC06+uDN/d+wp6+WSyOLXqwARWSZEDL8pkktcepG0KJHeVINbJTr5y4pgEUD8Cw12fhZLz1Rr + cq1xZtw5iogU2S5S6reH/Gh+h8/FR0Ymf5G5QobAmvHZ8fux9Hy1JlUCj423iSIiV4PKYeQO99Dlj8mf + trA0R1k5iswXTovWiE+J34il56w1Odkj9dXaACLyL3jZvTT+KrZeFIU0v49EusFZCU0Wy80iVfW+EkvP + W0sS10OVwG2iiMgVbBVpm9p6rX+OOY+I/D62RZVxQR8B0gS/FEvPXUtywkdWAFccIjJw2CWzY6YkaumF + 0Yrk+B8eKetrtLOMG9pC00yo9UUAJ3ykxD4nisjAoSY6NfFbPvrnaPOjkV7oVHYTmQQEkxIo+9VYeg5b + kZM+gn1J+RWRAcK9P0ebVMZrOeefn53gxXtEJ3+ZNASVchLABFp6HluR67IDI2mPIjIw6H5HfnzLpU/5 + 2b8Y2fnbzU+mBfEl5NSfHUvPZQty4kdWwB2jiwCRAcGApxMagX+ll0MLkurHLmzzaFqTTBtOm3aLNNxp + eRF9aCS+wSJZIgPhJnHfWHohtCCT/7lx2ygyK5g0D4i/ja0uAgj+vX/0+kxkALBbphteq53+eNFeEHeP + IrOGq6f3RerttxpIS1og5Y89BRDpHPJ/XxdLL4La5QVL33b6t/uyklrgRO0zsdUqmpyocZq2UhSRTuHu + nztz8oBLL4LapUPbe+J1okhNrBtJD2y1mNYx8VZRRDplvfiWWHoB1C5pSxxV3jyK1AiLa7pPtngVwM/8 + hGjvDJEO4e7/QZF6/6UXQM1y708FNtL9PPqXWmGM0TzorFh6jmv3+EhaoIh0Bm1A3x5bjFb+VqT4irn+ + UjvsoF8RCVQtPcs1yynb0yIxDSLSCdyZPzr+PJYGfs3+JL4g3jiKtABXbcSqXBZLz3TNHhfvFkWkE9j9 + vzUS7Vsa9LVKVPUh0eAkaQmCbe8dPxtbO3G7NFLgyAW3SAf8e3xk/EEsDfhaJSiJyGSKlFiqVFqDcsHE + A7RYbZPuoJtFEWmcW8RXRdrllgZ7rfLi3DUalSytcstIpcDW0m5/ERl7148i0jBbx9bal/4u7hd5gYq0 + ChkrZK58KLbUcZNri3fF20URaZRV48viH2JpoNcoR/9HRnKqTfmT1rlBJIOltasAUhl3ijbaEmmUrSL3 + 6KUBXqs/ijvEG0WRHuAkq7WFOBUND4qewok0CN299o60Ky0N8BqlMxnxCqRRifQCJ1mk1tEvoKUqgd+I + j4oi0hik/n0wlgZ2rX458qIkc0GkJ8gKeGxsqRbHH+Mro6dxIg3BjmPn2NK9I/nHO0bzj6VXaBj0xthS + QOCno4WBRBqC3QZlf/8cS4O6NjkW/XD06F96hnoWTKbEuZTGQY2eG/eKnsqJNMJ94omxNKBrlKNGfmbi + FkR6ZrX43NhKVU5+zsMjGUUi0gAviS3dNb4p+oKRoUBk/bdjaSzU6NfjNlFEKmfNSA3yVqKNaU9MtUKP + GGUoUGGPCbU0Hmr0kvjmKCKV84R4ZiwN5Bql0x/FUkSGAkG6tNz9YiyNidpkM3F83CiKSMUQ/Ecp3dJA + rknKjf46rh6t+CdDgxbdD46tnNTRTOzJUUQqhbvFL8UWAoz+El8RPfqXIcKid6V4UmwhLZAqhvQHcLEu + Uinbx7NjaQDXJAsUUqHWjyJDZrtIFkxpnNQkJ3YU6towikiFHBJbOP5nN/Hq6O5fhg6xAKTsttCum0X7 + k6KIVMbakXSd2o8T2UnwIrljFJFrXevp8bexNF5qkmyA90YX7iKVwVHiebE0cGuS3f9hkSAoEbnWtdaJ + 34x/i6UxU4tc3X0rUtJYRCribfH3sTRwa5GI53PiQ6KIXAUBsRfF0ripSTYZNDUSkUogmpjWnfTwLg3a + Wrw8HhntLiZydTaNp8faM3iIMTooikgl3CW2UPr3x/GpUUSuDvfqh8baT/G4pvhqtHiXSCU8O9Ye/U9w + 4gnR1D+RMo+KFNwpjZ+aZLNhEK9IBVCY45Ox9ta/3G++PopIGRpi0cej9mDAi+OeUURmDPfprMhJrysN + 1lo8JRr8J7J89o0XxNIYqsU/xY9GqwKKzJgHxctiaaDWIjuaD0WD/0SWz+bx5FhzjwA2GyxSjAMQmTEH + ROrqlwZqLRL8R5yCiCyfa0eK7dQ+pilfvGUUkRlC85/aq//RSpSdjYismN3iWbE0lmqRmCNaeYvIjKCa + 3qWx5uNCjv/pUeBxocjcuHM8NpbGUy1Sc+QTUURmwH/EO8Xa+4lT+W+PaMCQyNy4XqTYDsF2pTFVg8QB + /CI6rkVmAC8JiuqUBmdNktZ0rygic4exXXtNAK4eN4g2BxKZMpT/fXcsDcxapKzpW+NNo4jMnXtGFs+l + cVWT9AW4bhSRKXLjeGYsDcpa5IjwWdEdgsj8oCgQDb5q7w1AcS/je0SmCBPqerHmO0Ikn3mbKCLzgzH+ + nHhhLI2tWjwxrhxFZEpw/3+/WBqQNUnf/42iiMyfbSONd0pjqxZ/FTmtEJEpQUW9Z8TSgKxF8oRfHG8Y + RWT+3C4eHkvjqxa5orhtJCtJRKYAK+43x9KArMWfxCdGEVkYLPRfHmtvDsRJhXEAIlNizXhcLA3GWvxC + fEAUkYVDOuAvY2mM1eLzI0HJIjIF1o0/jaXBWIvvihwNisjC+c/4tVgaY7X4nnizKCIThru2O8Sa6/9T + JYy2pjeJIrJwKAv8gVgaZ7VIoOLaUUQmDAWASK0rDcRavCQ+KVomVGRxrBHp+Flzye+L4vpRRCYMu+rd + Y2kg1uLp8WFRRBYHJ35Pj3+NpbFWgyxOOJW04JfIhFk9siMoDcRa/FS0/a/IeNgu1h7z85B4/SgiE+SW + 8X2xNAhr8S3x1lFEFg9Fv06KpbFWi7vGVaKITJAN4/GxNAhrce+4WhSRxUPb79oDAV8Sbx5FZIJQHex7 + sTQIa5DshB3jtaOILB7Sfl8TS+OtFg+O60QRmSDsBn4XS4OwBukAuHUUkfFAkZ29Ymm81eJRcYMoIhOC + iOB7x5pbhJ4Wt4oiMh4Y9zvEv8fSmKvBU+PGUUQmBPW2qbtdGoC1eGy8WxSR8fHw+JtYGnM1eF4kFVBE + JgRHgRTYKQ3AWqR72SZRRMbH/eP3Y2nM1SDFv7ieFJEJQWR97XeBB0argomMl3vEE2JpzNUgwb/U/rD6 + p8iEoAsgNfZLA7AWSQGkWJGIjI87xg/H0pirRbp/XieKyAS4RXxtLA2+WnxKtDWoyHi5TXxHLI25WnxU + pFeJiEwA0mwOiaXBV4uPjdeLIjI+1ou1L/6fHK0GKDIhNoofjKXBV4O0AaYJkE1BRMbLWrH2679nRiuA + ikwIous/HUuDrwYvj9QtF5HxwsTKBFsad7XIAoU4JRGZAOTZfi6WBl8N/jJuGUVkvKwcd4mlcVeL+8W1 + o4hMgE1jzalAZ0fSlURkvBBXQ3xNadzV4qsjgcoiMgEotPHlWBp8NfjdePcoIuOF5lqPiKVxV4vUAKFd + uYhMgLvEb8TS4KvB0+Ndo4iMFwJrCbAtjbtafHMkW0FEJgCTK003SoOvBlmcsEgRkfHz4Ph/sTT2avDt + 0SqgIhOCJjvfiaXBV4NfiXeOIjJ+HhgpuVsaezV4aLxVFJEJQK3tmhuCfCnaEERkMtAQ6E+xNPZq8L3x + 1lFEJoALAJHhwgLgz7E09mrwsLhhFJEJwBXAGbE0+Grw5OgVgMhkoNnO32Np7NWgVwAiE2SzeEosDb4a + NAhQZHI8KBoEKDJQ2F0TaFcafDV4WjQNUGT8tJAGeFA0DVBkQtReCdBCQCKTgUJA28bSuKvF10cLAYlM + CHoBHBdLg68GLQUsMhksBSwycGrvBvjzaDMgkfFzo7hzLI27WrQZkMgEuW38eCwNvhq8NNoOWGT8rBr3 + jKVxV4u2AxaZIBvFD8bS4KvBf8SHRgKWRGR8MLHuE0vjrhafFW8WRWQCUGSDYhulwVeL20XuK0VkfKwb + uWMvjbla3DWuEkVkAvASeGMsDb5a3CWuHEVkfFBilzz70pirxUfHlaKITACOAV8cS4OvFp8TPQYUGS9k + AH0glsZcLVKo6LpRRCYAgUC7x9Lgq8XXRouBiIwX+oB8MZbGXA0S/0MNkH+LIjIBSAV6fCwNwFqkI9jt + ooiMDxoBnRlLY64G/xDtAyIyQThe45itNABr8ZhoOWCR8bJN/HUsjbkaPD9yTSEiE4LjNY7Z/hZLg7AG + vxXvE0VkPJBWy8lfzZ0AT40bRxGZIPQDuCiWBmENUg2QpiUiMh7Iqqm9CNDRcYMoIhOEcsBnxdIgrMG/ + xh3jdaKILB4a7NReA+CdcZ0oIhPkNvHLsTQIa/F5kYwFEVk8nPodEUtjrRZfFm8eRWSCUAyo5nLA+OZI + 1UIRWTz3jSfG0lirxadGqwCKTJg14qtiaRDW4pHxblFEFg8V9s6NpbFWi1vHG0QRmSCssp8WS4OwFk+J + D4kisjiuHRnvl8XSWKvB/43UAPiPKCIT5PrxgbE0EGuRfOWdol0BRRbHapH79dI4q8WL4/pRRCYMkyqV + 9v4SS4OxBv8vviDaFEhkcdwxvi+WxlktcuK3dhSRKUBa0E9iaTDW4jsiGQsisnC4Sqs96+f90QwAkSlB + V8AvxNJgrMXjItHLIrIwqPxJj/2fxdIYq8V9oxkAIlOCe0EKb5QGYy2eHZ8QRWRhXC/S/psgu9IYq8Xt + ohkAIlPixnHvWBqMtUhFQOIAiGIWkflz6/juWBpfNXn76DgXmRLsDGrPBEBeXrzERGT+0AHw5FgaW7X4 + u3iTKCJTgrvBtWLNmQB4UqRAiIjMn2fFC2NpbNXiV6LZPiJThmsAWu+WBmUt0hlwrygi84OguoNi7ff/ + b4re/4tMmZUiqXalQVmL/xPpC2CEsMj8oJT2p2NpXNXkDvG6UUSmCINul1galDX5mXiPKCJz5ynx+7E0 + pmqRgl+3ilb8FJky1N3eJJYGZk3+MO4WRWRucKTOyVnN9f//ES+I7v5FZgCBgLwoqMPNSrw0SGvw8vi2 + aKCQyNy4U/xsrHlc/z0eFUVkhlAmlLv20iCtxc9F2wOLzA26//0glsZSLf457hNFZIa8NtaeDkhVwD2i + iCwfTvUOjpfG0liqxT/G+0cRmSEPizXfFSI/32GR1EURWTabxhNjzcf/3P/Tn+BmUURmCH0BCMZhUJYG + ay1+Ld47isiyeXasvdMnJ45k94hIBTAYa78G+EV8RTRlSKQM9TKOjNyvl8ZQLVL+93lRRCrguZFBWRqs + tUig4vFx9Sgi1+TB8cxYGj81SYXPzaOIVAAR9gzK0mCtSYIBt48icnWo60FZ3d/E0tipRRbyZ0QakolI + BdCK8/RYezogkcMfjLYOFbk660TGcO2xPJfEQ6OIVMTb4+9jadDWJKcAHh+KXB3u1H8VS2OmJgk43jmK + SEU8Lp4fS4O2Jt1BiFwdcv+/HWs/wcPvRk4rRKQi1ozczdWcP4z8fD+ONBERkX829ar97h8pTvT+aCaP + SGUQRPTu2MI1AKcA+0WRocO4pZz332JprNQkC3e6FIpIhewYz4mlwVuT/xv5OT1KlKHz6EgKbwsnd1+P + G0YRqRAmVMqIMsGWBnFN/im+JIoMFbJhTogt3P1zascJo+1/RSqllVxiJN2JI8W1o3eKMjSuE+njQbvs + 2nf/+MPo8b9I5WwXCQYsDeLa5MVHFcPrR5Gh8G/xJpES3qVxUZuM08/H20YRqRiuAT4V/x5Lg7k2vxd5 + sVgcSIYCaX+PihTGKo2J2iRG4c3RhbpI5XCcvn9soagIsrsgI4AdkUjvMD43iMfF0nio0VPjY6OINMDW + kfa7pcFco+dFWgVbX1x6h4Xu02Lt3TtHkp74gbhuFJEGWCMSsVt7W9ElPTjykuF+VKRHCPyjcdc3Y2kM + 1Cilf/eOjkuRhnh6JHK3NKhrlHtGcqJvGEV6ZK1I6msLUf8juaq4TxSRhrh9/HBsoSbASIIX7xxJZxTp + CQLotomkvpae/RrlBPHAeOMoIg3BJPqC2EJNgJEURKEr2upRpBcI/Ns0HhFLz32tkk68QxSRBrlfbCna + GH8U2SmZFii9QODfXrGVwD+kUNch0aZdIo1yo/jy2EKp0SV9X7xDFOmBh8bTYulZr9WfRyr/Gfwn0jDb + xpaijpGdEtcX1gaQ1mEhy4K29JzX7HsjcUQi0jC3jK+PpUFeq0RJk8FAd0P7BEir3DS+NNJHv/Sc1yot + xdn9k7YoIg1DMCBVvFpoE7ykXFscFSkQJNIaLFx3id+PLaX94ZHx7lFEOoAe3tTyLg32mv1DPChyiiHS + ElvFoyOV9ErPdq1y/bZHNPVPpBMosUvzkZZykEfyM9MxkAYqIi2wXqSyJUfppWe6Zo+P94xevYl0BOk8 + LZ4C0NXwG5F8ZCOSpXbIvNk3/jSWnueaHe3+V40i0hGjSmQ03ikN/pq9PNI7fcsoUivsmneO346tpd7i + F+Jm0d2/SIesH98WS4O/di+Oh0XiGURq5AHxhNhSE66R/Mz0DyFzQUQ6hFOAh8RfxNJLoHb5ufePHlFK + bWwSPxoJXC09u7V7YuR3cPcv0jHrxHfG0kugdilP+pP4jLhSFKkBxhTZKpxSlZ7b2mX3v2tcJYpIx3AK + cN9In+/Sy6B2uVs9O24XLVQis4ZJc5/I5N9avv/IkyKZCwbZigwA7vleF1tqFbykLAIosEJQoC8tmQU8 + dyymnxTpuNnq5P/H+LjoiZrIQKA64K0jx+mll0ILsgj4arxN5PcRmRajyZ+gv4tiq5M/fjquHEVkQFAc + 6L9ii+lKS3pspMaBiwCZFkz+94rnxtIz2YIsWkivvUe09bbIwBjtYs6KrV4FjPx45A7TCGaZNNeNd43f + i6VnsRX/Gg+PIjJgto/sBEoviZbkZWbPAJkknDLdKZ4aS89gK7L7/3WkLoiIDBhOAo6JlAEtvSxakkUA + sQ0i44Zj8vvE02Pp2WtJehSQuSAicsU9IGmBLQczIZ3XPhQ3jSLjgmP/reNpsfXrMo7+Sfsz519EroAX + 3AGRdKbSS6Mluc74ZCRF0JgAWSx0oXxsZPKnMVXpmWtJMn8eHk2fFZF/cYv4udhiHfOlvSweFUnTMjtA + FgrpcU+OHPu31te/JCmLb4p0LBQR+Rfslh8RiW5u/SoAL42fj+ze2MWJzIebxb3iGbGHyZ/f4Yvx9lFE + 5BpwL/jq+MtYeom05p/i1yJdzm4SReYCKaUviT+IPRz7I+m+T4mWzxaRZXLH+KnYw1UAEvREf/bnxDWi + yPIggPQNkbvy1gP+RhLbQxvwNaOIyDLhzvwJkXvPHq4CkGqHP4z7RY9ApQTPPU2y3hN/FXt59lkAfyYS + FCsiskK4/3xl7OUqAHmhXxhphbxVNDhQRhDs9/hIXfxLYun5aVVOv3aOZPqIiMyJu8UPRCLqSy+WVuX3 + OTo+Mt4wyrChl/8e8Tuxh2C/JWUB/4ro1ZeIzItRVgBFQ1pvGLS0BHadGZ8a143WCxgeVPbjOohrIe7I + /xFLz0qrEgBLZcy7RBGRecMOebf4o1h6ybQsVwIUDXpVpL47jZEsjtI/LPbICLlfPCL2NvEjvxOtsreN + Lm5FZMHQYIcqgX+IpZdND342PjiuFo0N6BdS4GiAs0skKLT0LPQgZb1ZuN84iogsis0iNfZ7uyNdUl6a + z4w0E/I0oC/YBXOaRRvft8ReUlxLEuPCtYadMUVkLPACvX/sKTWwJL/b8fGhkchwj0/bh7t+guAo6Uug + X+l770XqFrw/muoqImNlpfi42PNVwEiCwkiD3CBKu7CA2zySzdJDu+sVeWrk9/X0SkTGDnfke8ZeKqSt + SHKonxYtI9weG8bXxZ5qWSxPihdRyMh8fxGZCOwsyJt+TSy9hHqThQ4nHnRJfFT05Vo/FLGi7DNNfNj1 + 9xjlv7TE5uwUDfoTkYlClPyt4odj6WXUm8QFMJGcF/873jt6xFofBG7uGOl4xxVOL018ViTP54vj6tHn + UkQmDoFVm8STY+ml1KPsJGkxTLtk6sWTR+4Ld/aQ2vfweGSkgQ+LtZ4DVZeW0tacyhmwKiJTgxfvvSIv + 3SEcs47kd6VePBkRdFi7Z2RBJNOFHf828aORRRlFnYY08VOd88TIaZyTv4hMHSY+jl1psjOkRQAy2fwu + UnHtjXHruEr0VGByMNFx1P3YyCnMaZGc/iFN/MidPxH/XEeJiMyMG8UXxF/Hob2IR7IQ+FqkyAyT09rR + ioLj43rxtpHqdtS3Z+Jnx1/6Lnp31MeCoFSfMRGZOWtGqo/9Ig7tJGBJ/xhPiYdEJis6KhqZvTA4SSGi + n9bNRPV/MJ4VhxLcV5Jjfz6Dp0cWRSIiVUAg0oGRvOuhngSMZJI6N3487hO5q+aulrgJWT6U7L1j3CHS + qOmY+PM45IUljib/Z0cXlSJSHdTR5xicmIChLwJGUkfgG/Gg+JRISWUqDLoYuAqqTHLE/7BIPwaO+WnW + M4TqfXORehRnR67aLEolItXCi/zgSExA6WU2VNnB/j5+Ob4hssMli2K9eIM4pOBBgvkImNwosiCi2iLX + JkO+21+WPDecJr003jyKiFTNppEo7Ytj6aU2dDkdYaJjMfDauH3cIm4ceclTcbCnBQETPrt8giPvEJn0 + iZEgh52ANo63S5/T0GXypwAV8TXE2YiINAGtVznKJWe+9HLTq2RBwC6P6orPjQ+O3IPTu54FAZNnS7ne + pIdyT71W5FqIZ4Go9f3jcfGiWPoc9CqZ/Il9OCASXyMi0hSjRQDR8aWXnJYliPDH8ZPxZfGRkRavt4i0 + tr1pJFhu1icFpKERjU7rZBpFsUtdN5L98KRIfQRK89KoxpiQucvkT0YNx/6cmoiINAklg4kJ+FMsvex0 + blLwhkCwoyLXBrvELSMTBIFh7LipycBpAVXymJhZIBBsyETNCQKyYBg5Ysl/xr/Dv88unv+WP4M/izgF + /mz+Dv4uFiHs7h8U94pvj0z2TFxDTtVbrCyUWDA9L3rnLyLNw1E2rVmdGCYjzW8IoOPE4K2R5jC7x8dH + JujN4m0iu/NVIwsGJvQRowmdKnsEJRLISV95ovKp9EhkPvfQh0Y6I5KOdlks/Sy6OH8bnxGN9heRbmA3 + 86zoSYBqWdJnWbRxyiIi0g0cL7MIIPqb3PjSC1B1qBIESldD4imWvJ4REekC7pcp7/rEyFFn6UWoOjQp + FEXJYwI7nfxFpFtYBHDfvG38QSy9EFWH4tGRGA0CN538RaR7eNGx22HXc3K0EIwOzb/GIyJZMmRciIgM + Cl58VMD7QDSqXIcgaX5UyKRxFrUdREQGzV3i6yNR0BRBKb04VVuXk65z4gsj3SFFRCTwQnxRJC7AegHa + m/R+4LqLxkfUWxARkSUgQ4AiKDTJsXyw9iK9Dz4SKelMNUURESlAcOCjI41xuBKwhry2Kn38ye8/KN4j + GuUvIrICeFGSGkX5YK4EiJguvWBVa5Uj/1PjC+IGUURE5gGVA58aT4pWD9QW5MSK3gyfiY+J9FkQEZEF + QDe6+0RSBemSZpaA1irBq+dFjvw3jRS9EhGRRUB72o3jGyJtcUsvX9VZSpOrb0fKXNNxUUREFgi7J3b/ + dEbbKD49fjZyt1p6AavOQk6keCY/FK3qJyIyBtaM28ePRdKoSi9f1VlLpgq7frJXRERkgbDb3y4y6RNI + VXrhqtYgV1FvjwT5md4nIrJA7hD3j9+Pl8a/RfP/tUZJST0lbh0p6uPkLyIyD7jfpxzqU+Lx8WeRND+7 + AmqtUtTnR5Fy1etH2veKiMgcYcdERbRXxW/Fn8e/RHf7WrM8p++IpKNSrtpdv4jIHOBluUakKMq74unR + fH5twd9Gavg/LlLNj6wUERFZAdeLtPl9XiSo7zvx97H0olWtycvicfH/RQr6EJwqIiIrgHSoe8Z94tHx + p5GgvtKLVrUmKeZD2el9I8f9FvQREZkD1O3/z7hfpA4696YETpVetKo1SUrfVyKZKA+LPMuW8RURWQFr + R9r3vibSx59ofoP6tHZ5Rpn4eWZfG7eNq0UnfhGR5UBtfiZ+dku8PKmB7jG/tiCnUhfHk+NbI6dW3PEb + 2S8ishyuE28RHxRfEU+LpZesam2yQP1F/FJ8fXxIJFBVRESWA+lP68QHRu74z4ill6xqTXLMT6Oen8TP + R55dAlQ5wRIRkeVAZzMKn2wRD4hnx9KLVrUm6cvPMf8P4yfibpE8fhERWQEEQtHkhBxo0vnOjAb2ac2O + gvpoInVqPDBuGe3SJyIyBwiE4l6UWufPid+NVuzTmmW3T/4+Ez+7/SdE+kyIiMg8YNe/V6Qrnzn8WrtM + /lTs44ifGBXv9kVE5gl3/eycCO4znU9rlWP+P0Y6SO4R6TEhIiILhMj+E+Ml0V2/1ib998+Kh8YdI8F8 + 5O1zVWXRHhGReUI+/x3i+yKd+XjJGuSnNchzeEH8ZNw7bhXXjVTpo520k76IyALg5XnLSLMTIvsvjaWX + sOq05NSJHf7H48vidnGzSCAqk77FekREFgn5/DvEUaMed/w6bYkvYXdPGd7DIq2iKcV7j3jbuFZ0ly8i + MibIg75vfFtk1/+XWHo5q45LnjHK7p4Sj4wHRY7zucOnf8S9IhM+XfeM3BcRGTPsom4X2WV9MVIZrfSy + Vp2r1ISg2M5v43mROhEnRI7vCdJ7dWSif1p8fKTe/t3ihpHjfGJPRERkgqwaHxnfE38cLebTt/8Tief4 + dWRiPjf+IHLi851I0yZ249+I9L0/KdIUhxz6Y+NnI0F3FNL5aPxg/EB8b3xHpHkOdfRfFJ8dnxF3jo+J + NIa6e9w4coTPiZNH+CIiU4Z8/rvEF8avRhqhlCYMrVsWbFS3I0PjnMgETt/6z8Wj4ocjk/PB8Y3xlZHA + Tqo37h7ZgTNB7xSp7/C4SHDdo+LD49aRo/j7Ra6H7hO5h988EoBHCeg7RiZ1IvCJH+Fu3uN6EZEKoSgK + L/j3RyYOg/zqle+GCf7CyAR/emSCPyayA+fk5g2RSZ0JffvIpE1K3F0j9+dkc9w00qlRREQGCLuy28fn + x+9FK/nVIxM9NRa4M/9p5Dieif7o+K7IsfqekQn+AZGd99rx+pG+DCIiIteACWKVeP/Irp8SqaVJSKcj + +ex/iKRY0oaWY3vu2QmQIwr+ufGxkSN2m9WIiMiC4K6fI+Bd4s+iQX7TlZ09jWiY8El34xifALvDI4Fy + BMcx0RP5bkCciIgsGiYToqwJ0HpLJPq7NEHpeB2lv9EvgUh7jvO/Ft8diYgngI7vxWN7EREZO0z+o2p+ + Z8fSRKXjkR0+R/oUtOFqhQn/0/Glkcp13NOLiIhMhfUihVas5Dd5+YyJzD8w0i2RaHsREZGpQjMUcrc5 + ci5NVjoeKZ5zSKSCHTt87+5FRGRmsOvfPxJZ7n3/+OSIn8p5FNXZI5JGyS6fYjfk1Tv5i4jITGACosQq + pVl/H43yX7x8hhRIIi3v6ZE+CRRPWjmSVSEiIjJTbhSp/saR/2WxNJnp3GSnT5oekz6fKaVu6TN/k+gu + X0REqmGD+NpIIRkqyJUmNV2+7PRpgERDG6rsUWGP0rk0SLKWvYiIVMeWkYp+v4ykoJUmN122FOWh7fFL + IkGTd4hO+iIiUi1E+T8x0giGwDSOrUsTnF5TdvtnRKL3udenWc6a0Tt9mTZcKW0RaYns9ZLMF95Z947E + JVlQbACMavlTI/7b0SY+c5PTkd9EdvuvirS53SjaFU9mBWOZU6cjI62ZCTD15EnmCs8KLbs/GV8Wbx1d + RHYMq70NI8fVBKkZ5b9iCYhkofS++Lz44Egwn8gsYfJ/WGRBSotnSkXTypnUUhcBsiJ4Rmjj/tVIATJS + vllEsqlxEdAhtHq9e6RDnB38li/XIRdHGu28I+4YCZT0iExqgOeQSpEnxiWDdkk3dREgK4IJntLivN+W + PAG+ILoI6BByznlhEKFuYZ9lyzE/L9GvRBZKHK/SWU+kFq4T7xm/HEtjebQI8DpASnBled94aiwFfY8W + AbeJLgIahy/w5pF+8MfHpb9s/accgZ0X6aP/mkhQDF32RGqCwF06QH4hlp7jkVwHvCm6k5Ml4RT4PvHr + sfTcjOQ6gDinW0VPPRuF1T+15SlEYxe/srTaPT+yOHpm5IF31yQ1wuRPQanPx9KzvLQXRVp380y7CJAb + RCb/ufZ2IUaM2jC3jC4CGoNJbN24b+RIsPQFD1nuvYjoPy7ShMegPqmZ0eQ/31O838a3x1tEX+LDZbTz + J+Cv9Jwsywvj66Mpgg3B5M+qny+OIjWlL3aocudFACTBLztEBoZIzXDnz7H/XHf+S/u7eGi8WfQlPjy4 + 85/Pzn9pOUl6c3ST1AhEAB8RLel7dfk8SOd7cvSYX1qACZuAvxXd+a/ISyJprMa1DAuufgj4W9Gd/4ok + I4qTJE6ipGLICz45WtXvKi+P5Eo/IjrxSysw+ZO5Q7R/6bmer9SzoGAQTb+kf3jXkepHtH/peZivVIs9 + PLoIqBRy1U+Ppvn9U476j41U7OP4iqNUkRZg8mcxT57/uMYzmwLGhIuA/mHyp8gPV53j6u/C88OVsouA + yuCYZ494Zvx7LH15Q5LPgGCXp0UCIYl+FWkFxjP1Jzi1Gvc13pKLAK4DjAnoDyZ/yvvyDhx3mXcXAZVB + ad8XRNr4Dr2mPw/nd+ML410iu35fcNISTP6PjNz5U9639JwvVsYJ1wHEBBgY2BdM/gQ3cw1MbZPS979Y + eX64DiAmwHfsDCGC/RXx3Dj0nT+5/GQ9cGdKyopd+aQ1mPw5tiXanwm69JyPUwIDyQ4gRZC/W9qGyf8J + kZiRSS0el5TAQLIDTBGcMnzY3OEdGH8Wx3XH06K8xDiOotIhtfo9lpIWYQJ+dJzW5D+SFEF2chYLaptp + T/4jSRFk42WxoCnBIKW0L7WaKWTDcUzpi+ldTjyOiVQ53DSazy+tMu2d/9JSLIiKgZQNZiKRthgd+097 + 8h9JsSAqBrqInDB8uJT23S+y8ip9Gb1LRPSP4uviVpEAP1ee0io8u9tG7vxJVy0989OQ9wm9A2wg1BZ8 + VwT8cec/i8l/JGWD6R1gA6EJwRe9Xnx5HOLk/4/IndOnI9H9q0eRlmHy3zqeEGf58h5JAyFbCbcD39GS + /fxL3+k0pYGQrYQnAAFtt45Dnfx5OZ4RuWvaIrrjl9bhGSZgle6TNVXsHLUSdhFQN0ywpX7+s3bUSthF + wJhg8udYZf/IDrj0ofcqx/0cLX0i7hytRS09MOrnz7FtjUW7RosArwPqZEX9/GftaBHgdcAiYfARWMGd + P9G6pQ+7VwmGom7/AZHdiEgPkKVCYx+K/JSe+1rkOoCYAHdydTHXfv6zlusAYgKYvzyxXQAMOlIrXhKH + dOzPipYdyKci91srRZEeGE3+C+3qN21575AdYHR3Hcy3n/+s5fSW7ABTBOcJHxbFFV4ch9TLn7tQIvxf + FCnhK9ILrU3+I0kRpE4AxYJ8ic+Ohfbzn7WkCBK7ZbGgecBd9z6RFVTpQ+1RolhPikRFW7tfemKx/fxn + LdePVAy0bPBsWGw//1nLSRIVA43hmgN82dT2p8Jf6cPsUXb+VDV01y+9wYRJwF/td/4rkoqb9A6ggZBM + D65extHPf9YSwM5JkpValwMR/xz7D2nyp4nRg6K7fukNJn9S/Yj2Lz37rUlgrq2EpwdB4OPs5z9raSBk + F8FlwErv+fHHkaI3pQ+wJylh/M5IgAhHpB4tSk/wPHOdRZ5/jal+C5ExO2ol7CJgsoyK/Iyzn/+s5fmx + lXABJv+94zmxl5fFsuRhpnPfk+Jq0ehi6ZGHxeNjTUV+xuFoEfCxSIaOC/fxw0nw4yPH/r21eOf54Trp + kCiBAbRX5Ci895a+VPTjLpQ7rRtHkV7ZJL4n9vYCR17iXAcQE2Bg4Hhh509jn6/EGsr7jtvRKcCuUcKO + 8Xux98mfdKJ3x80igY4iPUPa1pbxv2OPiwBkJ0d2ACmCnuQtHib/WbT0nZZM/nSw5aqbjraD537xtNjr + CwKJZzg7EtxIaVFfFDIUCGy9dzwi9jrGSREkuttiQYtjCJM/ae3UeFkzDhq+bEps0gK0550/R1hEQNO9 + j12CyNAYLQJ6PgngdI+KgbzTeLfJ/Bgd+/c8+Z8X2QSuEwcNXzZtfbkf7CW6syRHPR+Jj4gWgJAhwyKA + 64APxl4XARR7oXeADYTmB59VDf38JyWTP5ltL41kfA0ajsjWjq+Of46lD6wH+cIPihRAIcVPZOgQE8B4 + +GjsdRFAAyFbCc8dPqOa+vmPWyb/cyNt7Nn0DhoiZVePz469dvbjvv/MuG+kFaTRwSJXQe7z3eMnY69X + f6NWwi4Clg+bwRr7+Y9LJ/+luGmkpz13IaUPrHV5oVGx6hlxrSgi14QTsbvEY2KvNT9GiwCvA8rU3s9/ + sY6O/Z38r2Tl+Oh4Rix9YK3L8RWNKh4TV4kismyYFNkhE/TVW6GgkVwHEBNAYKDZAVfRSj//hToK+OPO + 38k/EAD04HhCLH1grXt55HfbKlrPX2Tu3ClS8IV4IF6cpfHVsgQGkh1giuA/4f3Ycle/FckzTKof0f6D + D/gDSjqOAn9KH1jrMvkfHTeO/K4iMj/uHEeLgNIYa11SBKkTQBrwkGOCWu3nP1eZ/Mn8Is9/8Kl+wMN+ + 6/jW2GNzH44uKXBCPX+D/UQWzmgR0Ot1AEHPVAwcatng1vv5z0U6/VHhb/BFfkZw789qiLrHpQ+sZXlR + cbTnsZ7IeOA6gJiAXgMDKRtM74AbxiHBO7KHfv7LkwBwstss73slHIfT4KfHvv4c6e0RRWS8EBhIdkCv + KYI0EBpSK2GCPXvq51+SFManR4u9LcFjI/mdvR39/zyS5mcvZ5Hxw4RBiiB1AnrNDaeV8BAWAXyXvfXz + X1qeUcq8M/l7DXwld4tHxZ7u8xi4NPTZJQ5l9S4yC6gTQLGgXisGLrkI4Dqgx4mDyZ/yvgT89fgdIqdU + o52/k/+VEP1Iy1vuu0ofWotyivHtuFM0x19k8nDCRvZQr70DWARwHUBMQG+BgUz+NPahtn+v5X0J+OPO + 38l/Ccjx3D9eEPmQSh9eazL5c4S1Y/SOR2R6kDZGA6GeuwiyUSI7gBTBHgKKmfzt5z9AWAXtGr8Xe4ni + 5fc4KW4fKWMsItOFTQWthEm37XURQIogdQJaLxY0hMnffv7L4P6RL76XYh68bD4XKe3rzl9kdowWAT2f + BJBZRFoxZYOZSFtjdOzf8+RvP/9lsH4koIU7rdKH15rs/Jn8iWC9cRSR2cIigOuAXmMCkLLB9A5orYEQ + P6v9/AcKwToHxF6C/khXOTFuF538ReqBmIBRWfFeFwE0EGqplTA/o/38B8zDI0F/PeT78ztQrYrVrMf+ + IvXBhoMUQeoE9FosaNRKuPZFAPEK9vMfKHz5fCis/HoI+uPLplUxQSwG/InUC3UCKBZExcBeywaPFgG1 + XgfYz3/AEPHPDvmVsfThteg58UnRyV+kfpgU2SETdNZrAyGuA4gJIDCwpuwA+/kPHAJyto4UQyh9gK3J + FcZTo8f+Im1BA6FRK2Fe3KXx3bIEBpIdUEuKIO9++/kPGJr8bBJ7ae5A+g21nC3vK9Imo1bCvaQgLy3v + KOoEUCxollXn7Oc/cHj4WBW9LZY+wJbkyyZqla5+NvYRaZvRIqDX6wCKBVExcFZlg+3nL1f096ckbg/R + t0z+B0YR6QOuA4gJ6DUwkFRregfQQGiacPVgP/+BQ9AN1f4Ijih9gC15eTw81hRYIyKLh8BAsgN6TRGk + 2No0Wwnz3refv1yxuv5YbD3fn8n/6LhqFJG+YMIiRZA6Ab3mpo9aCU96EcBnaT9/udbqce/I5Fn6EFuR + Y3+q/N02+mWL9Al1AigW1GvFwCUXAVwHTOJdxuRvP3+54kHYNn4nlj7EVuTLJoCFQBYyGUSkXwjspWxw + r70DWARwHUBMwLgDA3nn289frmDTeFhsObqWa4vTIitaUllEpH8Y6zQQ6rmLIIGBZAeQIjiOmCYmf/v5 + yxWwOnpu/GUsfZit+L24ezTIQ2RYjFoJHxF7XQSQIkidgMUWCxrC5G8//znCsQjRn1+KfHClD7QFqee8 + b1wrisjwGC0Cej4JoFgQFQMpG8xEPl9Gx/7285cr2DAeHFsu9zsaFLeJIjJcWARwHdBrTABSNpjeAfNt + IMS/az9/+Rfcne0ZfxhLH2gLUhaUtMUtokEeIsJ7jcDAXrMDkAZC82klzL9jP3+5GveKx8ZWK2oR9MdR + 1iMiJSxFRIDsAFIEqRPQa7GgUSvhFS0CiBewn79cDSIjD4pESpY+1BY8O9rdT0RKUCeAYkFUDOy1bPBo + EbCs6wD7+cs14EHZKRI1X/pQW5CFC0F/pMWIiJTgXccOmZPCXhsIcR1ATACBgUtmB4y6+tnPX67G+vG4 + 2OqA4N7/kLhxFBFZEZQ4H7USZuIovVdalsBAAqFHKYL285ciVMdjxcSHV/pga5djLMr8bhbHURBDRIYB + rYQJgmMRUHq3tC7ZUNQJILOr937+LHjs578A2DV/N7a6Cj4/cqdl0J+IzBc2DkyMvV4HXBw56fjmEv+s + N/8QKVy3RpR58s5IWcnSB1u7LFp2jatEEZGFwHUAMQG9Bgb2rP38FwFVsi6MpQ+2Bd8WV4siIouBwECy + A3pNEexRUhjt579AuC8n57/VIhBnxXWj9/4isljIDiBFkDoBvRYL6km+I/v5LwJKQNJMosW7f+7rHhjJ + 6xURGQe8TygW1HPFwB60n/8i4ANbKdImt8VCEJxYvCaS1uKXLyLjhIqBlA3uuXdAq7JZtZ//IuEB5+ik + xahXfma6FJrnKSKTgoI5NBDquYtgazL5289/kXBfToWkM2LpQ65ZTiuo7/ywKCIySUathI+ILgJmK5O/ + /fzHAOlyfIgtprtQ43qfyMAUEZk0o0WAJwGzk8nffv5jYNQIo8VWv9z70OKXqH8RkWnBIoDrAGMCpi+T + v/38xwT3JnyQfKilD7tWOfo/PW4TRUSmDTEBBAaaHTA9mads6Tsm2P3T6/8HsfRh1yx3P6+MZC6IiMwC + gqdJEaROgMWCJquT/5ghcOIlsbXd/5/iJ+ImUURkloyuUakYaNngyTg69nfyHxN0+9sq0vCn9IHX6j8i + 2Qo7RxGRGqBiIGWD6R3QawOhWcnkbz//MbNWJIKytd0/XawOjDb6EZHaoIHQVyKthFt7t9Yon6H9/McM + q9UHxdby/jle+1S8RxQRqZE7x9EioPQe07nJ5E+RH/v5j5lW7/4JAKHWs6UeRaRmRosArwMWLmneVPiz + yM+YoWret2PpQ69Vdv8c/a8eRURqh+sAYgIMDJy/9vOfEKymSJ9rbfdPhO19oohIKxAYyLvLFMG5S00F + +/lPiEfH1nb/v4+7R8v9ikhLEG9FiiB1AiwWtGL5jOznPyHY/b8+tvYgHh43jT4QItIa1AmgWJAVA5ev + /fwnzLbxq7H04dfqz+LjImU3RURahIqBlA22d8A15Trafv4T5kbxgMgHXfoSapQH4w1xgygi0jJsYmgg + ZBfBqxyl+tnPf8IQQHdsbCn4j2Y/D4isnkVEWmfUSviIOPRFAHOR/fynAGV/6ZnPh136ImqU+6C9o2l/ + ItITo0XAkE8CmPzt5z8laJpD85yW8lFPjOTRsngREekJFgFcBwwxJoDJ337+U4KAij3jObH0ZdToH+OT + 4o2jiEiPEBNAYOCQsgOY/G3pO0W4W/lQbKkuNbEKt4hGg4pIzxDfRIogdQJ6Lxbk5D8DHh9bavlLr//t + okV/RGQIXDduHi+IpXdiL14eD4m3ijIFbhgPi3+IpS+kRrn7v2l09y8iQ4CrgPvGM2PpndiLtHJ/a9wo + /nuUCbNFbKnsL52zHhGpnCUi0jucdJKi/bVYeif25kXxLZFTABcBE4QPlyI6fOClL6I2yVA4JVI7W0Sk + d9j5M/m3Vp11sf42vj0a5zVByJ8/Lf4jlr6E2qRC4WOiiEjvcO8/pJ3/0v4uHhpvFl0ETIBdYytBJaTA + fD16JCQivcN7jjt/3nml9+FQvCS+LxKrJmPms7GV1L9fRxoViYj0DFec/xlPjaV34dC8LB4Z6VUjY4IK + enTRI++y9KHX5F/i56P1/kWkZ5j8HxW/Ef83lt6HQ5M5isJvLgLGyP6xldS/8yO1CkREeoXJn7bmBPwN + vQnQ0i65COA6wJiARcBO+ozYQt1/0v7Y/dMDWkSkR5j8d4gnR048S+/CocsigOsAYgIMDFwED40EV7Rw + /E83qGdGv2wR6REm/yfEL0eqnJbeg3qVzF1kB5AiaFD4Ajg8tnDExAkFVf8sCykiPeLkvzBJEaROgMWC + 5gG7aI5OLowt5P7/PNIUwna/ItIbo2N/J/+FSbEgKgZSNpjPUlYAhSV44EofZm1yPXFSpAGGiEhPMGER + 8Medv5P/wqWK7Zvi7aKLgBVA7/zPxNIHWZus7t4Y7fgnIj3BREWqH9H+BvwtXmrEUNL+9tFFwDLgGP0O + kQCK0odYm5S/3DqKiPQC99UU+SHP31S/8fmr6CJgOawc94ylD682SfUgwGO1KCLSA1zBUt6XCn8W+Rm/ + o0WA1wEF1oytHP/TnpjIWBGRHhh19Rt6bf9Jy3UAMQEEBpodcCWshu4YWzj+J/XvvXGDKCLSOkPr5z9r + CQwkO8AUwStZJT49lj6s2iRF8dnRwj8i0jpD7ec/awki5xqZYkGDn0vWix+NpQ+qNo+JW0URkZYZej// + WUuxICoGDrpsML/4nSPHIqUPqSYpTnRAJF1RRKRVOHq2n//s5dqb3gE0EBokN42tHP/ToGi7KCLSKsRc + 2c+/HskqG2wrYaIhPxBLH0xtHhz5eUVEWoTJ337+dblkK+FBLQI4/t8y/iyWPpia5KjmaZF7MxGR1mDy + t59/nS65COA6YBAxAfTQ3y220Pf/uMhiRUSkNZj87edftywCuA4gJmAQgYFURDoslj6MmuSL2TeuEUVE + WoLJ35a+7chpM9kBpAh2XSfg/vF7sfQh1OSP48OjbX9FpCWc/NuUFEHqBHRbLIjqU0+OLTyUBCnSqEhE + pBXYsDD599rSl5PZv19p6f9vXYoFHRS7LBu8bnx1LP3iNUmkLE2KVo0iIi2wZMDfn2Pp3dayTP6czL4r + fij2GtRI7wDaznfXQOie8ehY+qVr8vzIVUVXH76IdAvvqp77+TP5nxtfHjeOzCVUku15EdBVK2GiGymo + wwqu9AvXJKtLc/9FpAU4Ku65n/+Skz8l5OF68e7xk7HX64BRK+EuFgEUO3hOrP0BpfTvMyLVCkVEaqb3 + fv6jY/8lJ/8R14l3ifRqaSGtfCGOFgHNXwdwbPPOWPola5IPfPPo8b+I1Ezv/fyZ/M+LL41LT/4jeE+z + Qybj4a+x9Oe0LtcBb4pNBwY+OH4pln7BmvxYXNbDJiJSA73382fy/0V8cbxlXBF3il+JBD/y35b+zJal + cd5bYpMpgtz/U1L3l7H0y9UiDw5NilaJIiI10ns/f97Dv4kviuvEuUKH2dEioPTnti4pgtQJoFhQUxUD + V4601K19ZXZp3CR2WYRBRJpnCP38eQ8/P64Z58toEdDrdQDFgqgY2FTZYL6UD8fSL1STR0VL/4pIjbAx + 6b2fPxH9z443jwuF6wBiAnoNDKRsML0DaCDUBI+Pp8fSL1OTe0ROK0REaoJgt977+ZMhxhUsDeMWC4GB + ZAf0miJIA6FmWgm/MP4+ln6RWuR6gofG2v8iUhNM/r3382fyJ06MyX8cR9t8ZqQIUieg19oIo1bCVS8C + +ELfFsmvL/0itUiDInP/RaQmmMh67+fPLn208x/nvTZ1AigW1GvFwCUXAVwHVBkTsGnkByz9AjX51rhS + FBGpASb/nvv5M4ER8Med/7gn/xFUDKRs8Adjr4sArgOICagyMPARsYWI1W0jK0YRkVnD5N9zS18mLlL9 + iPZfTMDfXCBtcsv437HXUxQCA8kOIEWwqiy2/4o/iaUfugZ5EC+Pq8cqj1BEZFAMYfKnyA95/gtJ9VsI + FE66dzwi9roIIEWQOgHVFAsioI46xhxRlH7gGiRVhPs1c/9FZNaMjv17nvwp70uFv/kU+RkHo0VAzycB + FAuiYiBlg3mWZgqrOzrr8aWXftga5G5t/ygiMkt4YRPwx51/r5M/jX2o7T+X8r6TgEUA1wG9xgQgZYPp + HTDzBkJbxC/G0g9Zi0RRUlxDRGRW8KIeSj//WfdaISaAwMBeswOQBkIzbyW8c/xuLP2ANUhOLfEJ4yg8 + ISKyELh+HFo//1lDdgApgtQJ6LVY0KiV8MwWAfvFC2Pph6tBmkZQ/ldEZBYMuZ//rCHri2JBVAzstWzw + aBEw9esAVljvjzU3ZSB14iVRRGTa2M9/9jApskMm6LLXBkJcBxATQGDg1ILdN4jHx9IPVIusjraOIiLT + xH7+dUEDoVErYX720u/UsgQGkh0wtRTBh8ZvxdIPU4N8yT+Na0cRkWlhP/86GbUSZhFQ+r1alxRB6gRQ + LGjiNW+eEc+JpR+kBgm24csWEZkW9vOvm9EioNfrAIoFUTFw4mWDXxVrDgCkOyH1/0VEpgFHr/bzrx+u + A4gJ6DUwkNg3egfQQGhiUACo5mIWF8QnRxGRSUOwmf3824HAQLIDek0RpDrvxFoJs7I4IdYcTPHDyHGP + iMgkYfK3n39b8J2RIkidgF5rM4xaCY99EcDq6ZRY+otrkEHIMRyRuCIik4KJxH7+bUKdAIoF9VoxcMlF + AJv2sX1328Tvx9JfWoN/iIfHnh5WEakLJn/7+bcN9WwoG9xr7wC+Q64DiAkYW2DgXpECEKW/sAZ/Hl8Y + RUQmAZO//fz7gLRNGgj13EWQwECyA0gRXHSdgDdGHo7SX1SD3P8/JoqIjJshTP7T7uc/a0athI+IvS4C + SBGkTsCiiwV9Itb84BOJS4CHiMg4GR3728+/P0aLgJ5PAigWRMVAygbzLM8bIgprjnblAT4xrhpFRMYF + L0z7+fcNiwCuA3qNCUDKBtM7YEENhDaOP4ilP7gGKfP4kTi1pggi0j28KO3nPwyICSAwsNfsAKSB0IJa + CVPsgh77pT+0BlndHBhFRMYBmwn7+Q8LsgNIEaROQK/FgkathOe1CNg9EiBS+gNrkAd5zygisljs5z9c + qBNALBkVA3stGzxaBMz5OmD/WHMGwGmROgUiIovBfv7CpMgOmaDPXhsIcR1ATACBgSu8On93pNBO6Q+q + QQIA7xBFRBaK/fxlSWggNGolzGdX+kxblqtzsgNWmCL42VhrP2W+mE/FVaKIyEKwn7+UGLUSrnX+W6yk + CFIngGJBxYqB/MPTY633IXwx74oiIgvBfv6yPEaLgF6vAygWRMXAYtngleJPY+k/rMEL435RRGS+cPRp + P39ZEVwHEBPQa2AgZYPpHUADoatx20id/dJ/VIPnRDMARGS+EOxlP3+ZKwQGkh3Qa4ogDYSu0Ur4gZG0 + gdJ/UINcT2wfRUTmCpO//fxlPvDMkCJInYBea0OMWgn/axGwc6w5BZBjmQdEEZG58vBI9lCvVd/4vZ4S + nfzHC3UC7hE/HntdBBAvwnXAFewTfx9L/3INciSzaRQRmSvkPx8ce4vuHr3AufMnM8rJf/xQMfBescfe + ATw/F0eaX13BOyLHAqV/uQap3bx2FBGZK6Oyr9Q46WURMEr1G0I//1lD2igNhHrqIsjzQ1A9MXU3jVdw + VKx1gPwjvifyZYiIzAcWAZvHHhYBvLyH1s9/1oxaCR8RW18EMJeeH58VSQf8F9+MtUY90p6TmsYec4nI + QmDz0PoigMl/qP38Z81oEdDySQCTP/10nhfXiFeD/6PWKFmyE/aNIiILZXQd8N7Y2iKAyX/o/fxnDYsA + rgNajAlg8j87FotEkfZAvWAestJ/PGupAUCnQhGRxcAiYLP4/thK73/ey7b0rQNOku4ZiUlrZRHA5P/D + +MK4VrwGN45UCCr9xzVIAQ9rAIjIOKAkMBlFH461LwKc/OtjdJJEnYDaiwUtOfkvM4h+/VhzF8CT4tZR + RGQcXDvSJ/0Tsdad3OjY38m/PqgTQLEg0tNrLRs8OvZf7uQPHImRU1r6Q2rwc5EmHiIi44L+ABvGz0di + Amq6AuVnsZ9/3XB1TtlgitTV1kBoFPDHnX/x2H9JKANccw0A2gCzSBERGTcUC/pivDzWsAjgZ7CffzvQ + QGjUSriW54dUP6L955Qq+rjIw1/6w2qQu7qNo4jIJOD9UsMigL/bfv7tMWolPOvsEp4fivyQ53+NVL9l + sVsk1770B9YgaTuuhEVkkowWAbN8idvPv11Gi4BZXQcw+dPznwp/VyvysyJYbdacF0st73+VLBQRmRBc + BxATMIvAQPv5tw/XAcQEzCIwkDmcltDznisPjDWnw1AFkKhLEZFJQ2Ag2QHTfCey4LCffx8QGEh2wDRT + BJn8nxBXjvOGOvu1RTGOZCX1yigiMg3IDiBFcFp1Apj87effD2QHkCJInYBpnCQx+dPVj3o+C3p+WO3W + WtCAOzHLAIvINKFOAMWCqBg4yetR3rujnb+Tfz9wYk2xoElWDOTOf7TzX/DkD+TZ17oAoA8A92IiItOE + ioGkH0+idwAv71E/fyf/PqFiIGWDJ9E7YBTwx+KRY/9FPT8nxlqrGVEMwz4AIjILRmVfx9lFkJe3/fyH + Ab0DaCA0zi6CPD/X6Oe/GL4aa10A0AjoKVFEZBawCBhXK2Fe3vbzHxajVsJHxMUuAqjwV+znvxi+FWtd + AJwVnxxFRGYFO7nFLgKY/O3nP0xGi4DFnASMyvsW+/kvhu/E/42lv3TWnhl3iiIis2R0HbCQmAAmf/v5 + DxsWAVwHLCQmYNTYZyJFothl17oAOCOS4iAiMmtYBBAYSHbAXFMEmfxt6SvASRKBgfPJDmDyX24//8XC + w8lfUvrLZ+1pkV4FIiI1QHYAKYJzqRPg5C9LMzpJok7AirLvlpz8l9vSdzH8LNa6ADglbhdFRGqBOgEU + C6KGyrJ2cqNjfyd/WRrqBFAsiIqBy4q/Gx37T3TyB3Lta10AfD0+MoqI1AQVAykbTO8AYgKY8EfvLf63 + /fxleVAxkLLB9A5YuhIv8/Gc+/kvlovjkg9vTdJd6eFRRKRGaCC0ZCthtJ+/zBUaCDHPjRaROK9+/ovl + j7HWBcBJcesoIlIro1bCLAIuivbzl/kwaiVMW/5fxnn1818s/KVkAXDsUJtfiA+OIiI1wyKAO11e3hb5 + kfnCIuD4uFscW5GfucBdw08qlXSbLaKISO2Q5sXdrshCmPLzc61r/f83S4WxfCbJgQAAAABJRU5ErkJg + gg== + + + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/domain/managers/IEmployeeManager.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/managers/IEmployeeManager.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/managers/IEmployeeManager.vb (revision 1759) @@ -0,0 +1,40 @@ +Public Interface IEmployeeManager + ''' + ''' A collection of all the employees. + ''' + ''' + ReadOnly Property Employees As ICollection(Of IEmployee) + + ''' + ''' All the non-selected employees. + ''' + ''' + ReadOnly Property AvailableEmployees As ICollection(Of IEmployee) + + ''' + ''' The selected employees. + ''' + ''' + ReadOnly Property SelectedEmployees As ICollection(Of IEmployee) + + ''' + ''' Get a selected employee corresponding to an employee number. This is merely the pre-defined index for each possible employee. + ''' If no employee was selected, 'Nothing' will be returned. + ''' + ''' The number (index) of the employee, 0 based + ''' The employee + Function GetSelectedEmployee(employeeNumber As Integer) As IEmployee + + ''' + ''' Select and store the chosen employee. + ''' + ''' The number (index) for the employee + ''' + Sub SelectEmployee(employeeNumber As Integer, employee As IEmployee) + + ''' + ''' Deselect an employee. + ''' + ''' The number (index) of an employee, 0 based + Sub RemoveEmployeeSelection(employeeNumber As Integer) +End Interface Index: ActiviteitenOpvolging/ProductiePitching/Images/danger.png =================================================================== diff -u Binary files differ Index: ActiviteitenOpvolging/ProductiePitching/ProductiePitching.vbproj.DotSettings =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ProductiePitching.vbproj.DotSettings (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ProductiePitching.vbproj.DotSettings (revision 1759) @@ -0,0 +1,19 @@ + + False + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/IWorkItem.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/IWorkItem.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/IWorkItem.vb (revision 1759) @@ -0,0 +1,16 @@ +Public Interface IWorkItem + 'Fixed fields. + Property BatchVisual As Integer + 'Optional fields. + Property DeliverToResource As String + Property ProductGroup As String + Property Remark As String + Property EndTimeStamp As DateTime + Property Activities As List(Of IActivity) + + ''' + ''' Get whether or not all non-read only activities have status finished. + ''' + ''' + Function AreAllActivatableActivitiesFinished As boolean +End Interface Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/details/EmployeeDetailUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/details/EmployeeDetailUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/details/EmployeeDetailUserControl.vb (revision 1759) @@ -0,0 +1,155 @@ +Imports System.Windows.Navigation +Imports ProductiePitching.configs + +Public Class EmployeeDetailUserControl + Implements IEmployeeDetailUserControl + + Private ReadOnly _parentUserControl As IEmployeeDetailParentUserControl + + Private Sub New() + ' This call is required by the designer. + InitializeComponent() + End Sub + + ''' + ''' Initialises the user form. + ''' + ''' The form containing this user control + Sub New(parentForm As IEmployeeUserControl) + 'Call base constructor. + Me.New() + 'Set parameters. + + 'Parent form. + 'Value can't be Nothing. + If parentForm Is Nothing Then Throw New InternalException($"The parent user control can't be 'Nothing' in a {Me.Name}.") + _parentUserControl = parentForm + End Sub + + Private Sub EmployeeUserControl_Load(sender As Object, e As EventArgs) Handles MyBase.Load + Try + 'Set back color corresponding to the employee index. + BackColor = Color.White + ForeColor = Color.Black + + 'Set border colors of the buttons. + StartButton.BackColor = ConfigsLoader.ColorsActivities(ActivityStateEnum.Started) + StopButton.BackColor = ConfigsLoader.ColorsActivities(ActivityStateEnum.Stopped) + FinishButton.BackColor = ConfigsLoader.ColorsActivities(ActivityStateEnum.Finished) + + 'Fetch and show the employee. + LoadEmployee() + Catch ex As Exception + MessageBox.Show($"Could not load {Me.Name}.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + + ''' + Public Function RefreshData() As Boolean Implements IEmployeeDetailUserControl.RefreshData + Try + LoadEmployee() + Return True + Catch ex As Exception + Return False + End Try + End Function + + ''' + ''' Load the employee + ''' + Private Sub LoadEmployee() + 'Fetch the employee. + Dim employee = _parentUserControl.FetchEmployee() + + 'If employee is nothing, do nothing. + if employee is Nothing then Return + + 'Show all information on screen. + NameLabel.Text = $"{employee.FirstName} {employee.LastName}" + + Try + ImagePictureBox.Load(employee.Picture) + Catch ex As Exception + 'Default image. + ImagePictureBox.Image = My.Resources.user + End Try + + 'If activity is Nothing, empty the labels. + If IsNothing(employee.CurrentActivity) Then + 'Nothing, empty or hide labels. + BatchVisualLabel.Visible = False + ActivityVisualLabel.Visible = False + StatusLabel.Text = String.Empty + BatchLabel.Text = String.Empty + ActivityNameLabel.Text = String.Empty + Else + 'Show visual labels. + BatchVisualLabel.Visible = True + ActivityVisualLabel.Visible = True + + Dim activity = employee.CurrentActivity + 'Set activity status according to state. + Select Case activity.Status + Case ActivityStateEnum.Started + StatusLabel.Text = "Gestart" + Case ActivityStateEnum.Finished + StatusLabel.Text = "Afgewerkt" + Case ActivityStateEnum.Stopped + StatusLabel.Text = "Onderbroken" + Case ActivityStateEnum.Defaulted + StatusLabel.Text = "Beschikbaar" + End Select + BatchLabel.Text = activity.WorkItem.BatchVisual + ActivityNameLabel.Text = activity.Label + End If + + 'Get the activity selected in one of the grids. + Dim currentlySelectedActivity = _parentUserControl.GetCurrentlySelectedActivity() + + 'Update enable status of buttons. + If IsNothing(employee.CurrentActivity) Then + 'No current activity. + StopButton.visible = False + FinishButton.visible = False + 'Start button visible when the selected activity can be started (you shouldn't be able to select an activity that can't be started). + StartButton.visible = Not IsNothing(currentlySelectedActivity) + Else + 'An activity in progress can be stopped or finished. + StartButton.visible = False + StopButton.visible = True + FinishButton.visible = True + End If + End Sub + + Private Sub RemoveEmployeeButton_Click(sender As Object, e As EventArgs) Handles RemoveEmployeeButton.Click + Try + _parentUserControl.DeselectEmployee() + Catch ex As Exception + MessageBox.Show($"Could not remove user.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + + Private Sub StartButton_Click(sender As Object, e As EventArgs) Handles StartButton.Click + Try + _parentUserControl.StartActivity() + Catch ex As Exception + MessageBox.Show($"Could not start activity.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + + Private Sub StopButton_Click(sender As Object, e As EventArgs) Handles StopButton.Click + Try + _parentUserControl.StopActivity() + Catch ex As Exception + MessageBox.Show($"Could not stop activity.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub + + Private Sub FinishButton_Click(sender As Object, e As EventArgs) Handles FinishButton.Click + Try + _parentUserControl.FinishActivity() + Catch ex As Exception + MessageBox.Show($"Could not stop activity.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + End Try + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/exceptions/InternalException.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/exceptions/InternalException.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/exceptions/InternalException.vb (revision 1759) @@ -0,0 +1,16 @@ +''' +''' An error for when a problem is solely the result of a programming error (bad parameters, etc...) +''' +Public Class InternalException + Inherits System.ApplicationException + + ''' + Sub New(message As String) + MyBase.New($"This error occured due to a programming mistake: {vbNewLine}{message}") + End Sub + + ''' + Sub New(message As String, innerException As Exception) + MyBase.New($"This error occured due to a programming mistake: {vbNewLine}{message}", innerException) + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/ProductiePitching.sln =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ProductiePitching.sln (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ProductiePitching.sln (revision 1759) @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29020.237 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ProductiePitching", "ProductiePitching.vbproj", "{ECE397C7-CC25-48F3-93B4-32DBD159D111}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ECE397C7-CC25-48F3-93B4-32DBD159D111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ECE397C7-CC25-48F3-93B4-32DBD159D111}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ECE397C7-CC25-48F3-93B4-32DBD159D111}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ECE397C7-CC25-48F3-93B4-32DBD159D111}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C9D2B7AE-8449-4878-B851-24273F157259} + EndGlobalSection +EndGlobal Index: ActiviteitenOpvolging/ProductiePitching/My Project/Resources.Designer.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/My Project/Resources.Designer.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/My Project/Resources.Designer.vb (revision 1759) @@ -0,0 +1,164 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.42000 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + +Imports System + +Namespace My.Resources + + 'This class was auto-generated by the StronglyTypedResourceBuilder + 'class via a tool like ResGen or Visual Studio. + 'To add or remove a member, edit your .ResX file then rerun ResGen + 'with the /str option, or rebuild your VS project. + ''' + ''' A strongly-typed resource class, for looking up localized strings, etc. + ''' + _ + Friend Module Resources + + Private resourceMan As Global.System.Resources.ResourceManager + + Private resourceCulture As Global.System.Globalization.CultureInfo + + ''' + ''' Returns the cached ResourceManager instance used by this class. + ''' + _ + Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager + Get + If Object.ReferenceEquals(resourceMan, Nothing) Then + Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("ProductiePitching.Resources", GetType(Resources).Assembly) + resourceMan = temp + End If + Return resourceMan + End Get + End Property + + ''' + ''' Overrides the current thread's CurrentUICulture property for all + ''' resource lookups using this strongly typed resource class. + ''' + _ + Friend Property Culture() As Global.System.Globalization.CultureInfo + Get + Return resourceCulture + End Get + Set + resourceCulture = value + End Set + End Property + + ''' + ''' Looks up a localized string similar to ADMIN1. + ''' + Friend ReadOnly Property CacheDatabase() As String + Get + Return ResourceManager.GetString("CacheDatabase", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to Cache01Admin1. + ''' + Friend ReadOnly Property CacheDSN() As String + Get + Return ResourceManager.GetString("CacheDSN", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to fixed. + ''' + Friend ReadOnly Property CachePassword() As String + Get + Return ResourceManager.GetString("CachePassword", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to CACHE01. + ''' + Friend ReadOnly Property CacheServerName() As String + Get + Return ResourceManager.GetString("CacheServerName", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to ICT_READONLY. + ''' + Friend ReadOnly Property CacheUsername() As String + Get + Return ResourceManager.GetString("CacheUsername", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to WieIsWie. + ''' + Friend ReadOnly Property EmployeesDatabase() As String + Get + Return ResourceManager.GetString("EmployeesDatabase", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to SQLr3*d. + ''' + Friend ReadOnly Property EmployeesDatabasePassword() As String + Get + Return ResourceManager.GetString("EmployeesDatabasePassword", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to SQL02. + ''' + Friend ReadOnly Property EmployeesDatabaseServerName() As String + Get + Return ResourceManager.GetString("EmployeesDatabaseServerName", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to VH_ReadOnly. + ''' + Friend ReadOnly Property EmployeesDatabaseUsername() As String + Get + Return ResourceManager.GetString("EmployeesDatabaseUsername", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized resource of type System.Drawing.Bitmap. + ''' + Friend ReadOnly Property remove_user() As System.Drawing.Bitmap + Get + Dim obj As Object = ResourceManager.GetObject("remove_user", resourceCulture) + Return CType(obj,System.Drawing.Bitmap) + End Get + End Property + + ''' + ''' Looks up a localized resource of type System.Drawing.Bitmap. + ''' + Friend ReadOnly Property user() As System.Drawing.Bitmap + Get + Dim obj As Object = ResourceManager.GetObject("user", resourceCulture) + Return CType(obj,System.Drawing.Bitmap) + End Get + End Property + End Module +End Namespace Index: ActiviteitenOpvolging/ProductiePitching/screens/custom controls/BorderedTextFigureCell.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/custom controls/BorderedTextFigureCell.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/custom controls/BorderedTextFigureCell.vb (revision 1759) @@ -0,0 +1,15 @@ +Public Class BorderedTextFigureCell + Inherits BorderCell + + Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle, rowIndex As Integer, elementState As DataGridViewElementStates, value As Object, formattedValue As Object, errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle, paintParts As DataGridViewPaintParts) + MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts) + + If Figure IsNot Nothing Then + Dim imageSize = cellBounds.Height - BorderThickness - 3 + Dim imagePos As New Rectangle(cellBounds.Right - BorderThickness - imageSize - 2, cellBounds.Y + BorderThickness, imageSize, imageSize) + graphics.DrawImage(Figure, imagePos) + End If + End Sub + + Property Figure As Image +End Class Index: ActiviteitenOpvolging/ProductiePitching/ProductiePitchingForm.resx =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ProductiePitchingForm.resx (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ProductiePitchingForm.resx (revision 1759) @@ -0,0 +1,1949 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAUAAAAGQAAABQAAAAM + AAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAATBQUFNxYWFooAAADE + AAAAkQAAAFQAAAA8AAAAJwAAABQAAAAHAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAARBQUFMBUVFYccHBzR + IiIi+jg4OP8NDQ3/AAAA/AAAALIAAABtAAAAUgAAADgAAAAhAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAPBQUFLxYWFoEZGRnL + ICAg+DIyMv9SUlL/b29v/3R0dP8sLCz/AAAA/wEBAf4AAADAAAAAdwAAAFwAAABDAAAAKwAAABcAAAAJ + AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAANAAAAKBcXF3kfHx/F + IiIi9jExMf9OTk7/bGxs/3Jycv9dXV3/Q0ND/zIyMv8uLi7/Dw8P/wICAv8DAwP/AwMDzAAAAH0AAABj + AAAASgAAADMAAAAdAAAADgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAALAAAAJRcXF3EeHh7D + Jycn9TQ0NP9OTk7/bGxs/3Nzc/9fX1//RERE/zAwMP8pKSn/KSkp/01NTf98fHz/Jycn/xQUFP8FBQX/ + BgYG/wUFBdYAAACDAAAAZwAAAE4AAAA4AAAAIgAAABEAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAKAAAAIRUVFWwdHR2/ + JCQk8TMzM/9OTk7/bGxs/3Jycv9fX1//RERE/zExMf8tLS3/LS0t/21tbf97e3v/wcHB/4CAgP/Hx8f/ + t7e3/yIiIv8XFxf/CQkJ/woKCv8HBwffAAAAhwAAAGcAAABOAAAAOAAAACIAAAARAAAABgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHRQUFGYcHBy4 + ISEh7jIyMv9NTU3/bGxs/3Jycv9fX1//RUVF/zAwMP8nJyf/Kysr/3V1df8nJyf/r6+v/7W1tf+Tk5P/ + jo6O/6mpqf9/f3//kJCQ/5OTk/8hISH/Ghoa/w4ODv8PDw//CQkJ6AICAokAAABhAAAARwAAADAAAAAb + AAAADAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAGxMTE1wbGxuy + JCQk7DExMf9JSUn/aWlp/3Jycv9gYGD/Q0ND/y8vL/8kJCT/JiYm/3p6ev+UlJT/urq6/4KCgv9ERET/ + HR0d/4aGhv+Wlpb/fHx8/6ioqP+Xl5f/kJCQ/6Wlpf/c3Nz/IiIi/xoaGv8SEhL/EhIS/wsLC+8CAgJ+ + AAAATQAAADMAAAAcAAAADQAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAGBISElQcHByw + IyMj6TAwMP5JSUn/aGho/3Nzc/9jY2P/RkZG/zAwMP8hISH/UVFR/2NjY//Ozs7/a2tr/0VFRf9CQkL/ + RERE/7S0tP8iIiL/IyMj/xYWFv9dXV3/qamp/3d3d/+1tbX/dXV1/6+vr/96enr/z8/P/yQkJP8aGhr/ + FhYW/xQUFP8JCQmkAAAAPAAAACEAAAAQAAAABQAAAAAAAAAAAAAAAAAAAAAAAAADAAAAFhAQEFEgICCq + Jycn5TMzM/5KSkr/aGho/3Nzc/9iYmL/RERE/y4uLv8dHR3/YGBg/3BwcP/Hx8f/ioqK/5qamv+goKD/ + 09PT/5qamv85OTn/Hx8f/xsbG/81NTX/bm5u/6qqqv9dXV3/ODg4/62trf+IiIj/ubm5/1lZWf9FRUX/ + FBQU/xoaGv8aGhr/Gxsb/xYWFv8MDAx7AAAADgAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFhY6 + Jycn3zMzM/5JSUn/aGho/3Nzc/9iYmL/RERE/ywsLP8tLS3/bm5u/7Gxsf/S0tL/g4OD/62trf+bm5v/ + iYmJ/5KSkv+jo6P/m5ub/4uLi//MzMz/eHh4/0tLS/+1tbX/oKCg/62trf+lpaX/UlJS/xYWFv8jIyP/ + FBQU/xgYGP8ZGRn/GRkZ/xkZGf8VFRX/EhIS/w8PD/MMDAxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAABCQkKfYGBg/3Nzc/9hYWH/RERE/ywsLP8tLS3/cnJy/7S0tP/FxcX/rq6u/6SkpP+kpKT/ + pKSk/5iYmP+enp7/oaGh/52dnf+Tk5P/n5+f/7a2tv+FhYX/0tLS/5ubm/8iIiL/YGBg/zc3N/9YWFj/ + hISE/7a2tv8ZGRn/GRkZ/xYWFv8TExP+Dw8P8g0NDb8ODg6ADAwMQAAAAAkAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAABISEhfOTk5/jQ0NP9NTU3/bGxs/7S0tP+srKz/mpqa/6enp/+ZmZn/ + ra2t/5aWlv+bm5v/mpqa/6ysrP+VlZX/m5ub/6mpqf+6urr/mJiY/3d3d/9VVVX/QkJC/19fX/+cnJz/ + PDw8/3x8fP9NTU3/Jycn/woKCv8ODg74BgYG/wICAv8CAgL3AAAAigAAAA4AAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAISEhVR0dHd85OTn/i4uL/6ysrP+0tLT/ + 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 + AAAAAAAAAAAAAAAAFxcXyicqK/9YGQ3/vUYv/8FONv/FTjX/x1A0/8pRNP/MUTP/z1Iz/9FSMv/TUzL/ + 1FMx/9VTMf/WVDD/1lIv/9VRLv/VUC3/zTcP/9BLKP/NRSL/xTIO/8IwDf/CPBz/wUEl/8RAI/9hJxv/ + ISQl/wUFBf8EBAR9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFxcXtCMmJv9MGxH/xEgu/8ZWPP/IVTr/y1Y6/85XOv/RWDr/ + 1Fk5/9ZZOf/YWjj/2lo4/9taN//bWjb/21k1/9xaNv/VRBv/1EUe/9dYNf/OPBb/yTQP/8UyDf/KSiv/ + xkgq/8dHK/9wKBn/ISUm/wcHB/8FBQWZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMTnyEjI/8+GxT/yEku/8lbQ//MW0H/ + 0FxB/9NdQP/WXkD/2l8//9tgP//dYD7/32E+/+BhPf/gYDz/4GI+/99XMf/ZOxH/3l06/9pWMv/ROA// + zTcP/8s4E//PUzX/zFAx/8xOMP+CLRr/HiMk/woKCv8GBga1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMTiR0eHv8tGRX/ + yUYq/85iSf/QYkf/02JG/9ZkRv/aZUb/3WZG/99mRf/iZ0X/5GdE/+VoRP/mZ0T/52hD/+BAEv/hVy3/ + 42ZD/9tLIv/VOxH/0TkQ/9FGIf/SWTr/zlU2/89UN/+YNB3/HiQm/w8PD/8GBgbOAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + EhISbxscHP8XFxf/zEQn/9FoT//TZ03/12hN/9pqTP/da0z/4GxM/+NtS//mbUv/6G5K/+puSv/scUz/ + 51Mm/+VIGv/qb0r/52tG/90+EP/ZPRH/1ToO/9dUMf/WXj//0lo9/9BaPf+uPCL/ICcp/xQUFP8HBwfq + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAMzMzCjk5ORI5OTkSOTk5Ejk5ORI5OTkSOTk5Ejk5ORI5OTkSOTk5Ejk5ORI5OTkS + OTk5Ejk5ORI5OTkSOTk5Ejk5ORI5OTkSOTk5Ejk5ORI5OTkSOTk5Ejk5ORI5OTkSOTk5Ejk5ORIAAAAG + AAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP////j//wAA////wF//AAD///4AN/8AAP//8AAL/wAA + ///AAAf/AAD//gAAAf8AAP/wAAABfwAA/4AAAAC/AAD8AAAAAP8AAOAAAAAA/wAAgAAAAAH/AAAAAAAA + B/8AAIAAAAAf/wAAwAAADA//AADwAAD4B/8AAPwAD+AD/wAA/gAAAAH/AAD/jgAAAP8AAP/+AAAB/wAA + //8AAABvAAD//8AAAD8AAP//+AAAPwAA///AAAAvAAD//AAAADcAAP/4AAAAPwAA//gAAAA/AAD/+AAA + AD8AAP/4AAAAHwAA//gAAAAfAAD/+AAAAB8AAP/4AAAAHwAA//wAAAAfAAD//AAAAB8AAP/8AAAAHwAA + //wAAAAfAAD//AAAAB8AAP/8AAAAHwAA//wAAAAPAAD//AAAAA8AAP/8AAAADwAA//wAAAAPAAD//AAA + AA8AAP/+AAAADwAA//4AAAAPAAD//gAAAA8AAP/+AAAAHwAA////////AAAoAAAAIAAAAEAAAAABACAA + AAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAABMAAAA5AAAAKAAAABUAAAAH + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAERMTE10ZGRm5IiIi8QAAAP0AAAC3 + AAAAXAAAADYAAAAXAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + 8AAAAPAAAADwAAAA8AEAAA== + + + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityFinishedState.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityFinishedState.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityFinishedState.vb (revision 1759) @@ -0,0 +1,27 @@ +Imports ProductiePitching + +Public Class ActivityFinishedState + Inherits ActivityState + + 'Not from other state. + Public Sub New(activity As IActivity, employee As IEmployee) + Me.Activity = activity + CurrentEmployee = employee + End Sub + + 'From other state. + Public Sub New(state As ActivityState) + Activity = state.Activity + CurrentEmployee = state.GetEmployee() + End Sub + + ''' + Public Overrides Function ActivityStateEnum() As ActivityStateEnum + Return ProductiePitching.ActivityStateEnum.Finished + End Function + + ''' + Public Overrides Function GetEmployee() As IEmployee + Return CurrentEmployee + End Function +End Class Index: ActiviteitenOpvolging/ProductiePitching/configs/ConfigsTextmapper.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/configs/ConfigsTextmapper.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/configs/ConfigsTextmapper.vb (revision 1759) @@ -0,0 +1,90 @@ +Imports System.IO +Imports System.Text.RegularExpressions + +Namespace configs + + ''' + ''' Used to read the lines from a specified config file. + ''' + Public Class ConfigsTextmapper + + ''' + ''' Get all configs from a specified file. + ''' + ''' List of every line from the config. + Public Function GetAllValues(configFilePath As String) As List(Of String) + If configFilePath Is Nothing OrElse configFilePath.Equals(String.Empty) Then + 'Empty path is not allowed. + Throw New InternalException("The path to the config file can't be empty for fetching all the lines of the config file.") + End If + + 'Check if file exist. + If Not File.Exists(configFilePath) Then + 'File doesn't exist. + Throw New ConfigurationException($"The file '{configFilePath}' was not found.") + End If + Try + 'File exists, read all text. + Dim allText As String = My.Computer.FileSystem.ReadAllText(configFilePath) + + 'Text between two 'µ' gets converted to one line. + allText = ConvertMultiLineToSingleLine(allText) + + 'Seperate into lines. + Dim lines As String() = allText.Split(New String() {Environment.NewLine}, StringSplitOptions.None) + + 'Iterate every line, only the important configs. + + Dim correctLines As New List(Of String) + 'Extract the lines which are not comment lines (doesn't start with '%') and are not empty. + For Each line As String In lines + line = line.Trim() + 'Check if line is valid. + If Not line.StartsWith("%") And Not line.Equals(String.Empty) Then + correctLines.Add(line) + End If + Next + 'Return the correct lines. + Return correctLines + Catch ex As ReadOnlyException + Throw New ConfigurationException($"File is readonly: '{configFilePath}'") + Catch ex As PathTooLongException + Throw New ConfigurationException($"Path is too long: '{configFilePath}'") + Catch ex As IOException + Throw New ConfigurationException($"File is unreachable: '{configFilePath}'") + Catch ex As Exception + Throw New ConfigurationException($"File could not be read: '{configFilePath}'{vbNewLine}{ex.Message}") + End Try + End Function + + ''' + ''' Text between two 'µ' gets converted to one line. + ''' + ''' + ''' + Private Function ConvertMultiLineToSingleLine(allText As String) As String + 'Check if it's necessary to run other code. + If Not allText.Contains("__") Then + Return allText + End If + + 'Invoke the Match method, all text between and including the 'µ'. + Dim matchCollection = Regex.Matches(allText, "__[\S\s]*?__") + + If (matchCollection IsNot Nothing AndAlso matchCollection.Count > 0) Then + 'If successful, overwrite each multiline from the groups as one line, without the seperator symbols 'µ'. + For Each match In matchCollection + 'Remove newLines, replace by space. + Dim onelineString = match.Value.Replace(vbCr, " ").Replace(vbLf, " ") + 'Remove special characters. + onelineString = onelineString.Replace("__", String.Empty) + 'Overwrite multiline entry in text. + allText = allText.Replace(match.Value, onelineString) + Next + End If + + 'Return the probably changed text. + Return allText + End Function + End Class +End Namespace \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/Activity.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/Activity.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/Activity.vb (revision 1759) @@ -0,0 +1,45 @@ +Public Class Activity + Implements IActivity + + Public Property Id As String Implements IActivity.Id + Public Property QuantityToProduce As Integer Implements IActivity.QuantityToProduce + Public Property Label As String Implements IActivity.Label + Public ReadOnly Property Status As ActivityStateEnum Implements IActivity.Status + Get + Return State.ActivityStateEnum() + End Get + End Property + Public Property IsReadOnly As Boolean Implements IActivity.IsReadOnly + Public Property StartBeforeTimestamp As DateTime Implements IActivity.StartBeforeTimestamp + Public Property StartAlmostTimeStamp As DateTime Implements IActivity.StartAlmostTimeStamp + Public Property StartTimeStamp As DateTime Implements IActivity.StartTimeStamp + + Public Property EmployeeInitials As String Implements IActivity.EmployeeInitials + + Public Property WorkItem As IWorkItem Implements IActivity.WorkItem + + Public Property State As ActivityState Implements IActivity.State + + Public ReadOnly Property CurrentEmployee As IEmployee Implements IActivity.CurrentEmployee + Get + Return State.GetEmployee() + End Get + End Property + + ''' + Public Sub StartActivity(employee As IEmployee) Implements IActivityActions.StartActivity + State.StartActivity(employee) + End Sub + + ''' + Public Sub StopActivity() Implements IActivityActions.StopActivity + State.StopActivity() + CurrentEmployee.CurrentActivity = Nothing + End Sub + + ''' + Public Sub FinishActivity() Implements IActivityActions.FinishActivity + State.FinishActivity() + CurrentEmployee.CurrentActivity = Nothing + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/IEmployeePickerParentUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/IEmployeePickerParentUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/IEmployeePickerParentUserControl.vb (revision 1759) @@ -0,0 +1,13 @@ +Public Interface IEmployeePickerParentUserControl + ''' + ''' Gets all the employees. + ''' + ''' + Function GetAllEmployees() As ICollection(Of IEmployee) + + ''' + ''' Selects an employee. + ''' + ''' + Sub SelectEmployee(employee As IEmployee) +End Interface Index: ActiviteitenOpvolging/ProductiePitching/MBL-W7_DynamicConfigs.txt =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/MBL-W7_DynamicConfigs.txt (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/MBL-W7_DynamicConfigs.txt (revision 1759) @@ -0,0 +1,35 @@ +% Zichtbare naam van de applicatie (Voormontage, Matten, Karton, Zijkanten, Onderdelen, ...) +AppName=Voormontage + +% Gebruikt voor webservice (Voormontage, Matten, Karton, Zijkanten, Onderdelen, ...) +AppID=Voormontage LBX&TBX + +% Grootte scherm van de applicatie breedte x hoogte (in pixels) +AppDimension=1280x1024 + +% Aantal grids +NumberOfGrids=2 + +% Zichtbare naam voor grid 1 tot AantalGrid +GridLabel1=Lijn +GridLabel2=Klantorder + +% Afmetingen grids breedte x hoogte (in pixels) +DimensionsGrid1=725x550 +DimensionsGrid2=500x550 + +% Kolom header namen voor elke grid. '-' betekent onzichtbaar. +% De kolommen zijn: Batch, DueOut, Product, Naar, Opmerking +ColumnHeaderGrid1=Batch,DueOut,Product,Naar,- +ColumnHeaderGrid2=Batch,Tijd,Product,Naar,- + +% Aantal activiteiten per grid +NumberOfActivitiesGrid1=5 +NumberOfActivitiesGrid2=2 + +% Definitie van de SQL query voor grid 1 tot AantalGrid +SQL1=SQL1 +SQL2=SQL2 + +% Aantal gebruikers die acties kunnen uitvoeren +NumberOfEmployees=2 \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/mappers/CacheMapper.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/mappers/CacheMapper.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/mappers/CacheMapper.vb (revision 1759) @@ -0,0 +1,221 @@ +Imports ProductiePitching.configs +Imports ProductiePitching.ServiceAgents +Imports ProductiePitching.ServiceAgents.Implementations + +Module CacheMapper + +#Region "Help functions" + + Private ReadOnly _activiteitPerBatchServiceAgent As IActiviteitPerBatchServiceAgent + + Sub New() + _activiteitPerBatchServiceAgent = New ActiviteitPerBatchServiceAgent + End Sub + + ''' + ''' Execution of a query into a data reader. + ''' + ''' The query + Private Function ExecuteIntoDataSet(query As String) As DataSet + Try + Return _activiteitPerBatchServiceAgent.GeefDataSetVoorQuery(query) + Catch ex As Exception + Throw New Exception($"Could not get dataset from the Caché webservice.{vbNewLine}{ex.Message}") + End Try + End Function + + Private Function ExtractItemFromDataReader(Of T)(ByRef dr As DataTableReader, key As String, Optional defaultValue As T = Nothing) As T + Dim value As Object + Try + 'Check if the column name is not present. If not present, return default value. + If Not HasColumn(dr, key) Then Return defaultValue + + 'Extract the value with the key. + value = dr.Item(key) + 'Check if the value is DBNull or Nothing. + If IsDBNull(value) Or value Is Nothing Then + 'If so, return default value. + Return defaultValue + End If + Catch ex As Exception + Throw New Exception($"A value for a work item can't be fetched from the data reader. The key is '{key}'.") + End Try + Try + 'Do the conversion explicitly, so exceptions can be caught. + Return CType(value, T) + Catch ex As Exception + Throw New Exception($"A value for a work item can't be converted to the specified type. The key is '{key}', the type is {GetType(T).Name}, the value is {value}.") + End Try + End Function + + ''' + ''' Check if the data reader has a column with that name. + ''' + ''' + ''' + ''' + Private Function HasColumn(ByRef dr As DataTableReader, columnName As String) As Boolean + 'Loop through each row. + For Each row As DataRow In dr.GetSchemaTable().Rows + 'Check if column name matches defined one. + If row("ColumnName").ToString() = columnName Then Return True + Next + 'Column name was not found. + Return False + End Function + +#End Region + + ''' + ''' Get the correct query. + ''' + ''' + ''' + Private Function FetchQuery(workPostIndex As Integer) As String + 'Fetch queries from config. + Dim sqlQueries = ConfigsLoader.SqlQueries() + 'Check if index is valid. + If workPostIndex >= sqlQueries.Count Or workPostIndex < 0 Then + Throw New InternalException($"Can't fetch a Caché query with this work post index: {workPostIndex}") + End If + 'If so, return correct query. + Return sqlQueries.Item(workPostIndex) + End Function + + ''' + ''' Fetch all the work items for a workpost. + ''' The corresponding query will get fetched in here. + ''' + ''' The index of the workpost, 0 based + ''' A list of all the work items with their activities + Public Function GetData(workPostIndex As Integer, employees As List(Of IEmployee)) As List(Of IWorkItem) + 'Fetch the query. + Dim queryName As String = FetchQuery(workPostIndex) + + 'Initialise the list with work items. + Dim workItems As New List(Of IWorkItem) + + 'Declare datareader. + Dim CacheDataReader As DataTableReader = Nothing + Try + 'Execute query and store datareader. + Dim CacheDataSet As DataSet = ExecuteIntoDataSet(queryName) + CacheDataReader = CacheDataSet.CreateDataReader() + + 'Fetch amount of activities. + Dim activityAmount = FetchNumberOfActivities(workPostIndex) + + 'Loop through every (result) record. + While CacheDataReader.Read() + 'Values of one result (line/record). + + Dim workItem As New WorkItem + 'Fill with values. + With workItem + .BatchVisual = ExtractItemFromDataReader(CacheDataReader, "BatchVisual", 0) + .DeliverToResource = ExtractItemFromDataReader(CacheDataReader, "Naar", String.Empty) + .ProductGroup = ExtractItemFromDataReader(CacheDataReader, "Productgroep", String.Empty) + .Remark = ExtractItemFromDataReader(CacheDataReader, "Opmerking", String.Empty) + .EndTimeStamp = ExtractItemFromDataReader(CacheDataReader, "EindTijdstip", DateTime.MinValue) + .Activities = ExtractActivities(CacheDataReader, activityAmount, workItem, employees) + End With + + 'Add to the result list. + workItems.Add(workItem) + End While + + 'Return the list. + Return workItems + Catch ex As Exception + Throw New Exception($"An error occured while fetching the work items from Caché.{vbNewLine}{ex.Message}") + Finally + 'Close connection if datareader is not nothing. + If Not IsNothing(CacheDataReader) Then + CacheDataReader.Close() + End If + End Try + End Function + +#Region "Activities" + ''' + ''' Extract all activities for one work item from the data reader. + ''' + ''' + ''' + Private Function ExtractActivities(dr As DataTableReader, numberOfActivities As Integer, workItem As IWorkItem, employees As List(Of IEmployee)) As List(Of IActivity) + 'Declare result list. + Dim activities As New List(Of IActivity) + + 'Loop for every activity. + For i = 1 To numberOfActivities + 'Initialise activity and fill with values. + Dim activity As New Activity + With activity + .Id = ExtractItemFromDataReader(dr, $"ActiviteitID_{i}", String.Empty) + .QuantityToProduce = ExtractItemFromDataReader(dr, $"Aantal_{i}", 0) + .Label = ExtractItemFromDataReader(dr, $"Label_{i}", String.Empty) + .IsReadOnly = ExtractItemFromDataReader(dr, $"ReadOnly_{i}", False) + .StartTimeStamp = ExtractItemFromDataReader(dr, $"StartTijdstip_{i}", DateTime.MinValue) + 'Subtract time when date was specified. Time is gotten from config. + .StartBeforeTimestamp = If(.StartTimeStamp = DateTime.MinValue, DateTime.MinValue, .StartTimeStamp.Subtract(ConfigsLoader.StartBeforeTimeThreshold)) + .StartAlmostTimeStamp = If(.StartTimeStamp = DateTime.MinValue, DateTime.MinValue, .StartTimeStamp.Subtract(ConfigsLoader.StartAlmostTimeThreshold)) + 'Set parent work item. + .WorkItem = workItem + + 'Fetch the employee if defined. + Dim employeeInitials = ExtractItemFromDataReader(dr, $"Gebruiker_{i}", String.Empty) + Dim employee As IEmployee = If(employeeInitials.Equals(String.Empty), Nothing, employees.FirstOrDefault(Function(employeeToCheck) employeeToCheck.Initials.Equals(employeeInitials))) + 'Set the current state based on the enum value. If the quantity is 0, the status is automatically zero. + .State = ConvertEnumValueToActivityState(If(.QuantityToProduce = 0, ActivityStateEnum.Zero, ActivityStateEnumMapper.GetActivityStateFromLetter(ExtractItemFromDataReader(Of Char)(dr, $"Status_{i}"))), activity, employee) + End With + 'Add to collection of activities. + activities.Add(activity) + Next + + 'Return list. + Return activities + End Function + + ''' + ''' Get the correct amount of activities. + ''' + ''' + ''' + Private Function FetchNumberOfActivities(workPostIndex As Integer) As String + 'Fetch queries from config. + Dim activityAmounts = ConfigsLoader.NumbersOfActivities() + 'Check if index is valid. + If workPostIndex >= activityAmounts.Count Or workPostIndex < 0 Then + Throw New InternalException($"Can't fetch the amount of activities with this work post index: {workPostIndex}") + End If + 'If so, return correct amount. + Return activityAmounts.Item(workPostIndex) + End Function + + ''' + ''' Produces an activity state based on the state enum value. The activity becomes part of the state. + ''' + ''' + ''' + ''' + Private Function ConvertEnumValueToActivityState(stateEnumValue As ActivityStateEnum, activity As IActivity, employee As IEmployee) As ActivityState + 'Get employee if any. + Select Case stateEnumValue + Case ActivityStateEnum.Zero + Return New ActivityZeroState(activity) + Case ActivityStateEnum.Defaulted + Return New ActivityDefaultedState(activity) + Case ActivityStateEnum.Stopped + Return New ActivityStoppedState(activity, employee) + Case ActivityStateEnum.Started + Return New ActivityStartedState(activity, employee) + Case ActivityStateEnum.Finished + Return New ActivityFinishedState(activity, employee) + Case Else + Throw New InternalException($"Activity state enum value '{stateEnumValue}' cannot be used to map to an activity state.") + End Select + End Function + +#End Region + +End Module Index: ActiviteitenOpvolging/ProductiePitching/ProductiePitching.vbproj.user =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ProductiePitching.vbproj.user (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ProductiePitching.vbproj.user (revision 1759) @@ -0,0 +1,13 @@ + + + + publish\ + + + + + + en-US + false + + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/screens/IActivityMainForm.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/IActivityMainForm.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/IActivityMainForm.vb (revision 1759) @@ -0,0 +1,7 @@ +Public Interface IActivityMainForm + ''' + ''' Gets the currently selected activity. + ''' + ''' + Function GetCurrentlySelectedActivity As IActivity +End Interface Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityDefaultedState.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityDefaultedState.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityDefaultedState.vb (revision 1759) @@ -0,0 +1,26 @@ +Public Class ActivityDefaultedState + Inherits ActivityState + + 'Not from other state. + Public Sub New(activity As IActivity) + Me.Activity = activity + End Sub + + ''' + Public Overrides Function ActivityStateEnum() As ActivityStateEnum + Return ProductiePitching.ActivityStateEnum.Defaulted + End Function + + ''' + Public Overrides Sub StartActivity(employee As IEmployee) + If IsNothing(employee) Then + 'Nothing employee. + Throw New Exception($"The employee can't be nothing when starting an activity from defaulted state.") + End If + 'Update employee. + employee.CurrentActivity = me.Activity + 'Change state. + Activity.State = New ActivityStartedState(Me, employee) + End Sub + +End Class Index: ActiviteitenOpvolging/ProductiePitching/App.config =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/App.config (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/App.config (revision 1759) @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/Employee.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/Employee.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/Employee.vb (revision 1759) @@ -0,0 +1,30 @@ +Imports ProductiePitching + +Public Class Employee + Implements IEmployee + + Public Property PersonelNumber As Integer Implements IEmployee.PersonelNumber + Public Property Picture As String Implements IEmployee.Picture + Public Property FirstName As String Implements IEmployee.FirstName + Public Property LastName As String Implements IEmployee.LastName + Public Property Initials As String Implements IEmployee.Initials + Public Property CurrentActivity As IActivity Implements IEmployee.CurrentActivity + + ''' + Public Property Number As Integer = -1 Implements IEmployee.Number + + Public Overrides Function Equals(obj As Object) As Boolean Implements IEmployee.Equals + If Not TypeOf obj Is IEmployee Then + 'Not the right type. + Return False + End If + 'Cast to IEmployee. + Dim employee As IEmployee = obj + 'Compare the initials. + Return employee.Initials.Equals(Initials, StringComparison.CurrentCultureIgnoreCase) + End Function + + Public Overrides Function ToString() As String Implements IEmployee.ToString + Return $"Employee: {FirstName} {LastName} ({Initials})" + End Function +End Class Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityState.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityState.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityState.vb (revision 1759) @@ -0,0 +1,32 @@ +Public MustInherit Class ActivityState + Implements IActivityActions + + Public Activity As IActivity + + Protected Property CurrentEmployee As IEmployee + + ''' + ''' The for the current state. + ''' + ''' + Public MustOverride Function ActivityStateEnum() As ActivityStateEnum + + Public Overridable Function GetEmployee() As IEmployee + Throw New Exception("No employee present.") + End Function + + ''' + Public Overridable Sub StartActivity(employee As IEmployee) Implements IActivityActions.StartActivity + Throw New Exception("Can't start the activity in this state.") + End Sub + + ''' + Public Overridable Sub StopActivity() Implements IActivityActions.StopActivity + Throw New Exception("Can't stop the activity in this state.") + End Sub + + ''' + Public Overridable Sub FinishActivity() Implements IActivityActions.FinishActivity + Throw New Exception("Can't finish the activity in this state.") + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/ServiceAgents/IActiviteitPerBatchServiceAgent.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ServiceAgents/IActiviteitPerBatchServiceAgent.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ServiceAgents/IActiviteitPerBatchServiceAgent.vb (revision 1759) @@ -0,0 +1,14 @@ +Namespace ServiceAgents + Public Interface IActiviteitPerBatchServiceAgent + + Sub SetActivityState(activity As IActivity, employee As IEmployee) + + Sub SetActivityState(activity As IActivity) + + Sub PauseActionsFromApp() + + Function GeefDataSetVoorQuery(ByVal QueryNaam As String) As DataSet + Function GeefWerknemers() As DataSet + + End Interface +End NameSpace \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/screens/DataGridViewUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/DataGridViewUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/DataGridViewUserControl.vb (revision 1759) @@ -0,0 +1,394 @@ +Imports ProductiePitching.configs + +Public Class DataGridViewUserControl + Implements IDataGridUserControl + Private ReadOnly _parentForm As IWorkItemsMainForm + Public ReadOnly Property GridNumber As Integer Implements IDataGridUserControl.GridNumber + + + Sub New() + ' This call is required by the designer. + InitializeComponent() + End Sub + + ''' + ''' Initialises the user form. + ''' + ''' The form containing this user control + ''' The index of the grid, 0 based + Sub New(parentForm As IWorkItemsMainForm, gridNumber As Integer) + 'Call base constructor. + Me.New() + 'Set parameters. + + 'Parent form. + 'Value can't be Nothing. + If parentForm Is Nothing Then Throw New InternalException($"The parent form can't be 'Nothing' in a {Me.Name}.") + _parentForm = parentForm + + 'Grid number. + Me.GridNumber = gridNumber + End Sub + + ''' + Public Sub RemoveSelection() Implements IDataGridUserControl.RemoveSelection + _WorkItemsDataGridView.ClearSelection() + End Sub + + ''' + Public Function RefreshData() As Boolean Implements IDataGridUserControl.RefreshData + Try + 'Ignore selection changed event. + _skipSelectionChanged = True + 'Call helper method. + + LoadGrid() + + 'Refresh succesfull. + Return True + Catch ex As Exception + 'Failed to retrieve update with data. + Return False + Finally + _skipSelectionChanged = False + End Try + End Function + + Private Sub DataGridViewUserControl_Load(sender As Object, e As EventArgs) Handles MyBase.Load + Try + 'Set back color and fore color. + BackColor = Color.White + ForeColor = Color.Black + + 'Set properties of datagrid view. + + 'Background color. + WorkItemsDataGridView.BackgroundColor = Color.White + + 'Cell makeup. + 'Center header cells. + WorkItemsDataGridView.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.TopCenter + 'Make header text bigger. + WorkItemsDataGridView.ColumnHeadersDefaultCellStyle.Font = New Font("Microsoft Sans Serif", 10) 'todo configureerbaar maken + 'Center normal cells. + WorkItemsDataGridView.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter + 'DueOut column is right aligned. + DueOut.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight + 'Make text bigger of normal cells. + WorkItemsDataGridView.DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 9.5) 'todo configureerbaar maken + + 'Disable autogeneration of columns. + WorkItemsDataGridView.AutoGenerateColumns = False + 'Disable resizing of rows and columns. + WorkItemsDataGridView.AllowUserToResizeColumns = False + WorkItemsDataGridView.AllowUserToResizeRows = False + 'Make columns fill space -> removes horizontal scrollbar. + WorkItemsDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill + 'Disable multiselect cells. + WorkItemsDataGridView.MultiSelect = False + 'Remove empty row at the bottom. + WorkItemsDataGridView.AllowUserToAddRows = False + 'Hide the selectors in front of a row. + WorkItemsDataGridView.RowHeadersVisible = False + 'Edit row height before generating new rows. + WorkItemsDataGridView.RowTemplate.Height = 30 'todo configureerbaar maken + + 'Set label. + GridLabel.Text = ConfigsLoader.GridLabelNames(GridNumber) + Catch ex As Exception + MessageBox.Show($"Could not load {Me.Name}.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + Finally + _skipSelectionChanged = False + End Try + End Sub + + Private _isInitialLoad As Boolean = True + ''' + ''' Fetch the data and fill the data grid view with it. + ''' + Private Sub LoadGrid() + 'Load all work items. + + LoadWorkItems() + + If _isInitialLoad Then + 'Update headers and visibility of static columns. This only happens once. + UpdateStaticColumns() + + 'Generate grid columns for the activities of the work items. This only happens once. + GenerateActivityColumns(_workItems) + + _isInitialLoad = False + End If + + 'Clear grid. + WorkItemsDataGridView.DataSource = Nothing + WorkItemsDataGridView.Rows.Clear() + + 'Changes to data grid can trigger selectio changed event, ignores it for now. + _skipSelectionChanged = True + + 'Show the work items. + ShowWorkItems(_workItems) + + 'Color the work items. + ColorWorkItems(_workItems) + + 'Done here because extra columns got generated. + For Each column In WorkItemsDataGridView.Columns + 'Disable sort mode for every header. + column.SortMode = DataGridViewColumnSortMode.NotSortable + 'Make every cell not editable. + column.ReadOnly = True + Next + WorkItemsDataGridView.ClearSelection() + WorkItemsDataGridView.Refresh() + End Sub + + ''' + ''' Update the header text and visibility of the static columns. + ''' + Private Sub UpdateStaticColumns() + Dim names = ConfigsLoader.GridColumnHeaderNames().Item(GridNumber) + For i = 0 To names.Count() - 1 + 'Fetch name. + Dim headerText = names(i) + 'Check if it's not hidden. + If Not headerText = "-" Then + 'Visible, set header text. + WorkItemsDataGridView.Columns.Item(i).HeaderText = headerText + Else + 'It needs to be hidden. + WorkItemsDataGridView.Columns.Item(i).Visible = False + End If + Next + End Sub + + ''' + ''' Store work items. + ''' + Private _workItems As List(Of IWorkItem) + ''' + ''' Load work items. + ''' + Private Sub LoadWorkItems() + Try + _workItems = _parentForm.GetWorkItems(GridNumber) + Catch ex As Exception + Throw New Exception($"Could not load work items.{vbNewLine}{ex.Message}") + End Try + End Sub + + ''' + ''' Generate the columns for the activities. + ''' + ''' + Private Sub GenerateActivityColumns(workItems As List(Of IWorkItem)) + Try + 'No work items need no extra columns. + If workItems.Count = 0 Then Return + + 'Register amount of already present columns. + Dim presentColumns As Integer = WorkItemsDataGridView.Columns.Count + + 'Get the first work item as this will provide all the necessary info. + Dim workItem = workItems.Item(0) + + 'Loop through every activity. + For i = 0 To workItem.Activities.Count - 1 + Dim activity = workItem.Activities(i) + 'Make a column for every activity with the necessary header text. + Dim column As New DataGridViewTextBoxColumn With { + .CellTemplate = New BorderedTextFigureCell(), + .Name = $"{activity.Label}ActivityColumn", + .HeaderText = activity.Label, + .DisplayIndex = presentColumns + i - 3 'Update the display index. Up the index for every column. -3 because of the other columns present. + } + 'Add column to data grid view. + WorkItemsDataGridView.Columns.Add(column) + Next + Catch ex As Exception + Throw New Exception($"Could not generate activity columns.{vbNewLine}{ex.Message}") + End Try + End Sub + + ''' + ''' Visualize work items in grid. + ''' + ''' + Private Sub ShowWorkItems(workItems As List(Of IWorkItem)) + Try + 'Loop through each work item. + For Each workItem In workItems + 'Load normal parameters. + Dim data As New List(Of String) From { + workItem.BatchVisual, + workItem.EndTimeStamp.ToString("d/MM HH:mm"), + workItem.ProductGroup, + workItem.DeliverToResource, + workItem.Remark + } + 'Add data from activities to end of list. 0 gets replaced by empty string. + data.AddRange(workItem.Activities.Select( + Function(activity) If(activity.QuantityToProduce = 0, String.Empty, activity.QuantityToProduce.ToString()))) + 'Add as a row to the data grid view. + WorkItemsDataGridView.Rows.Add(data.ToArray()) + Next + Catch ex As Exception + Throw New Exception($"Could not show work items.{vbNewLine}{ex.Message}") + End Try + End Sub + + ''' + ''' Set all the right colors for the work items. + ''' + ''' + Private Sub ColorWorkItems(workItems As List(Of IWorkItem)) + 'Loop for every work item (need access to index because of row index in data grid) + For Each row As DataGridViewRow In WorkItemsDataGridView.Rows + 'Get the work item. + Dim workItem = workItems.Item(row.Index) + 'Update the colors of the activities. + UpdateActivityCells(workItem, row) + Next + End Sub + + ''' + ''' Update the color of the cells for each activity. + ''' + Private Sub UpdateActivityCells(workItem As IWorkItem, row As DataGridViewRow) + 'Calculate the index of the first activity column. + Dim firstActivityCellIndex = row.Cells.Count - workItem.Activities.Count + 'Loop for every activity. + For activityIndex As Integer = 0 To workItem.Activities.Count - 1 + Dim activity = workItem.Activities.Item(activityIndex) + 'Fetch the right cell. Based on the activity, the offset is the index of the first activity. + Dim cell = row.Cells.Item(activityIndex + firstActivityCellIndex) + 'Update time related warning image. + UpdateActivityCellTimeStatusIndication(activity, cell) + 'Update background color. + UpdateActivityCellBackground(workItem, activity, cell) + 'Update border based on employee. + UpdateActivityCellBorder(workItem, activity, cell) + Next + End Sub + + ''' + ''' Update the image of the cell of an activity. + ''' + ''' + ''' + Private Sub UpdateActivityCellTimeStatusIndication(activity As IActivity, dataGridViewCell As DataGridViewCell) + 'Only this type of cell is supported. + If Not TypeOf dataGridViewCell Is BorderedTextFigureCell Then Throw New InternalException($"Only cells of type {TypeName(New BorderedTextFigureCell)} are supported when updating the cell for an activity.") + + 'Cast cell as right type. + Dim cell As BorderedTextFigureCell = dataGridViewCell + + 'Remove border. + cell.BorderThickness = 0 + + 'Undefined start timestamp is ignored. + If activity.StartTimeStamp = DateTime.MinValue Then + cell.Figure = Nothing + Return + End If + + 'Set status image based on timestamps. + If activity.StartBeforeTimestamp < DateTime.Now Then + cell.Figure = ConfigsLoader.ActivityBeforeStatusImage + ElseIf activity.StartAlmostTimeStamp < DateTime.Now Then + cell.Figure = ConfigsLoader.ActivityAlmostStatusImage + ElseIf activity.StartTimeStamp < DateTime.Now Then + cell.Figure = ConfigsLoader.ActivityLateStatusImage + Else + 'Default. + cell.Figure = Nothing + End If + End Sub + + ''' + ''' Update the background of the cell based on the activity status. + ''' + ''' + ''' + Private Sub UpdateActivityCellBackground(workItem As IWorkItem, activity As IActivity, dataGridViewCell As DataGridViewCell) + 'Check if readonly. + If activity.IsReadOnly Then + 'It's read only. + dataGridViewCell.Style.BackColor = ConfigsLoader.ColorsActivitiesReadOnly(activity.Status) + Else + 'It's not read only, check if not all activities have status finished. + If Not workItem.AreAllActivatableActivitiesFinished() Then + 'Not all activities are finished. + dataGridViewCell.Style.BackColor = ConfigsLoader.ColorsActivities(activity.Status) + Else + 'All activities are finished. + dataGridViewCell.Style.BackColor = ConfigsLoader.AllFinishedActivitiesColor + End If + End If + End Sub + + ''' + ''' Update the border of the cell. Depends on the state and the employee. + ''' + ''' + ''' + ''' + Private Sub UpdateActivityCellBorder(workItem As IWorkItem, activity As IActivity, dataGridViewCell As DataGridViewCell) + If activity.Status = ActivityStateEnum.Started AndAlso activity.CurrentEmployee.Number <> -1 Then + 'The employee is selected for this activity in the started state. + 'Only this type of cell is supported. + If Not TypeOf dataGridViewCell Is BorderedTextFigureCell Then Throw New InternalException($"Only cells of type {TypeName(New BorderedTextFigureCell)} are supported when updating the cell for an activity.") + + 'Cast cell as right type. + Dim cell As BorderedTextFigureCell = dataGridViewCell + + cell.BorderColor = ConfigsLoader.ColorsEmployees(activity.CurrentEmployee.Number) + cell.BorderThickness = 3 'todo Configureerbaar maken + End If + End Sub + + ''' + ''' Disable the selection changed event, useful for ignoring triggers by adding new rows. + ''' + Private _skipSelectionChanged = False + ''' + ''' Decide if a cell can be selected or not. + ''' + Private Sub WorkItemsDataGridView_SelectionChanged(sender As Object, e As EventArgs) Handles WorkItemsDataGridView.SelectionChanged + Try + 'If new items are being added or selected index is smaller than 0, it indicates nothing valueable was selected. The function was triggered because new values were added or the headers were clicked. + If _skipSelectionChanged Or WorkItemsDataGridView.CurrentCell.ColumnIndex < 0 Or WorkItemsDataGridView.CurrentCell.RowIndex < 0 Then Return + + 'Disable click on columns or cell that should not be clicked on. + 'Check columns, only activity columns should be able to be clicked on. + If Not WorkItemsDataGridView.Columns(WorkItemsDataGridView.CurrentCell.ColumnIndex).Name.Contains("ActivityColumn") Then + 'Column is not that of an activity + _parentForm.ChangeSelectedActivity(Nothing, GridNumber) + Return + End If + + 'Fetch the right activity + Dim workItem = _workItems.Item(WorkItemsDataGridView.CurrentCell.RowIndex) + 'Calculate index of the activity => activity columns are placed at end, so activity column index - amount of static columns = activity index. + Dim activityIndex = WorkItemsDataGridView.CurrentCell.ColumnIndex - ConfigsLoader.GridColumnAmount + Dim activity = workItem.Activities.Item(activityIndex) + + 'Check if activity is finished, zero or read only. + If activity.Status = ActivityStateEnum.Finished Or + activity.Status = ActivityStateEnum.Zero Or + activity.IsReadOnly Then + 'If equal to one of those, the selection is not valid. + _parentForm.ChangeSelectedActivity(Nothing, GridNumber) + Else + 'Selection was valid. + _parentForm.ChangeSelectedActivity(activity, GridNumber) + End If + Catch ex As Exception + MessageBox.Show($"Could not select a cell in {Me.Name}.{vbNewLine}{ex.Message}", "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + 'Remove selection. + WorkItemsDataGridView.ClearSelection() + End Try + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/Resources/user.png =================================================================== diff -u Binary files differ Index: ActiviteitenOpvolging/ProductiePitching/screens/IEmployeesMainForm.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/IEmployeesMainForm.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/IEmployeesMainForm.vb (revision 1759) @@ -0,0 +1,31 @@ +Public Interface IEmployeesMainForm + Inherits IActivityMainForm + ''' + ''' Gets all the employees. + ''' + ''' + Function GetAllEmployees() As ICollection(Of IEmployee) + + ''' + ''' Selects an employee. + ''' + ''' + ''' + Sub SelectEmployee(employeeIndex As Integer, employee As IEmployee) + + ''' + ''' Removes the selection of the current employee. + ''' + Sub DeselectEmployee(employeeIndex As Integer) + + ''' + ''' Gets the selected employee for this index. This function still works if no employee was selected yet. + ''' + ''' + ''' The selected employee if there is one. 'Nothing' if there wasn't one. + Function GetSelectedEmployee(employeeIndex As Integer) As IEmployee + + Sub StartActivity(employeeIndex As integer) + Sub FinishActivity(employeeIndex As integer) + Sub StopActivity(employeeIndex As integer) +End Interface Index: ActiviteitenOpvolging/ProductiePitching/enums/ActivityStateEnum.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/enums/ActivityStateEnum.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/enums/ActivityStateEnum.vb (revision 1759) @@ -0,0 +1,68 @@ +Public Enum ActivityStateEnum + Defaulted + Stopped + Started + Finished + Zero +End Enum + +Public Module ActivityStateEnumMapper + ''' + ''' Gets the corresponding enum value from the with a string value. + ''' + ''' The string value + ''' + Public Function GetEnumValueFromString(activityStateValue As String) As ActivityStateEnum + Select Case activityStateValue.ToLower() + Case "defaulted" + Return ActivityStateEnum.Defaulted + Case "stopped" + Return ActivityStateEnum.Stopped + Case "started" + Return ActivityStateEnum.Started + Case "finished" + Return ActivityStateEnum.Finished + Case "zero" + Return ActivityStateEnum.Zero + Case Else + Throw New Exception($"The activity state value is unknown for getting a corresponding enum value: '{activityStateValue}'.") + End Select + End Function + + ''' + ''' Gets the corresponding enum value from with a char value. + ''' + ''' + ''' + public Function GetActivityStateFromLetter(letter As Char) As ActivityStateEnum + 'If Nothing return default. + if letter = nothing Then Return ActivityStateEnum.Defaulted + 'Check for type and return enum value. + Select Case Char.ToUpper(letter) + Case "S"C + Return ActivityStateEnum.Started + Case "P"C + Return ActivityStateEnum.Stopped + Case "F"C + Return ActivityStateEnum.Finished + Case Else + Throw New Exception($"The activity state value letter is unknown for getting a corresponding enum value: '{letter}'.") + End Select + End Function + + public Function GetLetterFromActivityState(activityState As ActivityStateEnum) As Char + Select Case activityState + Case ActivityStateEnum.Finished + Return "F"C + Case ActivityStateEnum.Stopped + Return "P"C + Case ActivityStateEnum.Started + Return "S"C + Case ActivityStateEnum.Defaulted + Return "D"C + Case Else + Return "" + End Select + End Function + +End Module Index: ActiviteitenOpvolging/ProductiePitching/screens/DataGridViewUserControl.Designer.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/DataGridViewUserControl.Designer.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/DataGridViewUserControl.Designer.vb (revision 1759) @@ -0,0 +1,105 @@ + _ +Partial Class DataGridViewUserControl + Inherits System.Windows.Forms.UserControl + + 'UserControl overrides dispose to clean up the component list. + _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + _ + Private Sub InitializeComponent() + Me.WorkItemsDataGridView = New System.Windows.Forms.DataGridView() + Me.BatchColumn = New System.Windows.Forms.DataGridViewTextBoxColumn() + Me.DueOut = New System.Windows.Forms.DataGridViewTextBoxColumn() + Me.ProductGroup = New System.Windows.Forms.DataGridViewTextBoxColumn() + Me.DeliverToResource = New System.Windows.Forms.DataGridViewTextBoxColumn() + Me.Remark = New System.Windows.Forms.DataGridViewTextBoxColumn() + Me.GridLabel = New System.Windows.Forms.Label() + CType(Me.WorkItemsDataGridView,System.ComponentModel.ISupportInitialize).BeginInit + Me.SuspendLayout + ' + 'WorkItemsDataGridView + ' + Me.WorkItemsDataGridView.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ + Or System.Windows.Forms.AnchorStyles.Left) _ + Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles) + Me.WorkItemsDataGridView.BorderStyle = System.Windows.Forms.BorderStyle.None + Me.WorkItemsDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize + Me.WorkItemsDataGridView.Columns.AddRange(New System.Windows.Forms.DataGridViewColumn() {Me.BatchColumn, Me.DueOut, Me.ProductGroup, Me.DeliverToResource, Me.Remark}) + Me.WorkItemsDataGridView.Location = New System.Drawing.Point(0, 29) + Me.WorkItemsDataGridView.Name = "WorkItemsDataGridView" + Me.WorkItemsDataGridView.Size = New System.Drawing.Size(798, 534) + Me.WorkItemsDataGridView.TabIndex = 0 + ' + 'BatchColumn + ' + Me.BatchColumn.HeaderText = "Batch" + Me.BatchColumn.Name = "BatchColumn" + ' + 'DueOut + ' + Me.DueOut.HeaderText = "DueOut" + Me.DueOut.Name = "DueOut" + ' + 'ProductGroup + ' + Me.ProductGroup.HeaderText = "Product" + Me.ProductGroup.Name = "ProductGroup" + ' + 'DeliverToResource + ' + Me.DeliverToResource.HeaderText = "Naar" + Me.DeliverToResource.Name = "DeliverToResource" + ' + 'Remark + ' + Me.Remark.HeaderText = "Opmerking" + Me.Remark.Name = "Remark" + ' + 'GridLabel + ' + Me.GridLabel.AutoSize = true + Me.GridLabel.Font = New System.Drawing.Font("Microsoft Sans Serif", 13!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0,Byte)) + Me.GridLabel.ForeColor = System.Drawing.Color.Firebrick + Me.GridLabel.Location = New System.Drawing.Point(3, 4) + Me.GridLabel.Name = "GridLabel" + Me.GridLabel.Size = New System.Drawing.Size(87, 22) + Me.GridLabel.TabIndex = 1 + Me.GridLabel.Text = "Grid label" + ' + 'DataGridViewUserControl + ' + Me.AutoScaleDimensions = New System.Drawing.SizeF(6!, 13!) + Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font + Me.Controls.Add(Me.GridLabel) + Me.Controls.Add(Me.WorkItemsDataGridView) + Me.Name = "DataGridViewUserControl" + Me.Size = New System.Drawing.Size(798, 563) + CType(Me.WorkItemsDataGridView,System.ComponentModel.ISupportInitialize).EndInit + Me.ResumeLayout(false) + Me.PerformLayout + +End Sub + + Friend WithEvents WorkItemsDataGridView As DataGridView + Friend WithEvents GridLabel As Label + Friend WithEvents BatchColumn As DataGridViewTextBoxColumn + Friend WithEvents DueOut As DataGridViewTextBoxColumn + Friend WithEvents ProductGroup As DataGridViewTextBoxColumn + Friend WithEvents DeliverToResource As DataGridViewTextBoxColumn + Friend WithEvents Remark As DataGridViewTextBoxColumn +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/EmployeeUserControl.resx =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/EmployeeUserControl.resx (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/EmployeeUserControl.resx (revision 1759) @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityStoppedState.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityStoppedState.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityStoppedState.vb (revision 1759) @@ -0,0 +1,37 @@ +Public Class ActivityStoppedState + inherits ActivityState + + 'Not from other state. + Public Sub New(activity As IActivity, employee As IEmployee) + Me.Activity = activity + CurrentEmployee = employee + End Sub + + 'From other state. + Public Sub New(state As ActivityState) + Activity = state.Activity + CurrentEmployee = state.GetEmployee() + End Sub + + ''' + Public Overrides Function ActivityStateEnum() As ActivityStateEnum + Return ProductiePitching.ActivityStateEnum.Stopped + End Function + + ''' + Public Overrides Function GetEmployee() As IEmployee + Return CurrentEmployee + End Function + + ''' + Public Overrides Sub StartActivity(employee As IEmployee) + If IsNothing(employee) Then + 'Nothing employee. + Throw New Exception($"The employee can't be nothing when starting an activity from stopped state.") + End If + 'Update employee. + employee.CurrentActivity = me.Activity + 'Everyone can start this activity. + Activity.State = New ActivityStartedState(Me, employee) + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/DataGridViewUserControl.resx =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/DataGridViewUserControl.resx (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/DataGridViewUserControl.resx (revision 1759) @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/EmployeeUserControl.Designer.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/EmployeeUserControl.Designer.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/EmployeeUserControl.Designer.vb (revision 1759) @@ -0,0 +1,50 @@ + _ +Partial Class EmployeeUserControl + Inherits System.Windows.Forms.UserControl + + 'UserControl overrides dispose to clean up the component list. + _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + _ + Private Sub InitializeComponent() + Me.UserControlPanel = New System.Windows.Forms.Panel() + Me.SuspendLayout + ' + 'UserControlPanel + ' + Me.UserControlPanel.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ + Or System.Windows.Forms.AnchorStyles.Left) _ + Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles) + Me.UserControlPanel.Location = New System.Drawing.Point(3, 3) + Me.UserControlPanel.Name = "UserControlPanel" + Me.UserControlPanel.Size = New System.Drawing.Size(494, 594) + Me.UserControlPanel.TabIndex = 0 + ' + 'EmployeeUserControl + ' + Me.AutoScaleDimensions = New System.Drawing.SizeF(6!, 13!) + Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font + Me.Controls.Add(Me.UserControlPanel) + Me.Name = "EmployeeUserControl" + Me.Size = New System.Drawing.Size(500, 600) + Me.ResumeLayout(false) + +End Sub + + Friend WithEvents UserControlPanel As Panel +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/IWorkItemsMainForm.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/IWorkItemsMainForm.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/IWorkItemsMainForm.vb (revision 1759) @@ -0,0 +1,16 @@ +Public Interface IWorkItemsMainForm + + ''' + ''' Fetch the work items for a specific grid. + ''' + ''' The index of the grid, 0 based + ''' A list containing all work items + Function GetWorkItems(gridNumber As Integer) As List(Of IWorkItem) + + ''' + ''' A different activity was selected in the grid. + ''' + ''' The activity. Nothing means no activity was selected. + ''' The number of the grid + sub ChangeSelectedActivity(activity As IActivity, gridNumber As Integer) +End Interface Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/IEmployee.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/IEmployee.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/IEmployee.vb (revision 1759) @@ -0,0 +1,18 @@ +Public Interface IEmployee + Property PersonelNumber As Integer + Property Picture As String + Property FirstName As String + Property LastName As String + Property Initials As String + + Property CurrentActivity As IActivity + + ''' + ''' If an employee gets selected, it receives a number. + ''' + ''' + Property Number As Integer + + Function Equals(obj As Object) As Boolean + Function ToString() As String +End Interface Index: ActiviteitenOpvolging/ProductiePitching/KCA-W10_DynamicConfigs.txt =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/KCA-W10_DynamicConfigs.txt (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/KCA-W10_DynamicConfigs.txt (revision 1759) @@ -0,0 +1,35 @@ +% Zichtbare naam van de applicatie (Voormontage, Matten, Karton, Zijkanten, Onderdelen, ...) +AppName=Voormontage + +% Gebruikt voor webservice (Voormontage, Matten, Karton, Zijkanten, Onderdelen, ...) +AppID=Voormontage LBX&TBX + +% Grootte scherm van de applicatie breedte x hoogte (in pixels) +AppDimension=1280x1024 + +% Aantal grids +NumberOfGrids=2 + +% Zichtbare naam voor grid 1 tot AantalGrid +GridLabel1=Lijn +GridLabel2=Klantorder + +% Afmetingen grids breedte x hoogte (in pixels) +DimensionsGrid1=725x550 +DimensionsGrid2=500x550 + +% Kolom header namen voor elke grid. '-' betekent onzichtbaar. +% De kolommen zijn: Batch, DueOut, Product, Naar, Opmerking +ColumnHeaderGrid1=Batch,DueOut,Product,Naar,- +ColumnHeaderGrid2=Batch,Tijd,Product,Naar,- + +% Aantal activiteiten per grid +NumberOfActivitiesGrid1=5 +NumberOfActivitiesGrid2=2 + +% Definitie van de SQL query voor grid 1 tot AantalGrid +SQL1=SQL1 +SQL2=SQL2 + +% Aantal gebruikers die acties kunnen uitvoeren +NumberOfEmployees=2 \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityStartedState.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityStartedState.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/activity state/ActivityStartedState.vb (revision 1759) @@ -0,0 +1,42 @@ +Public Class ActivityStartedState + Inherits ActivityState + + 'Not from other state. + Public Sub New(activity As IActivity, employee As IEmployee) + 'Set the current activity of the employee, only happens in this state. + employee.CurrentActivity = Activity + + Me.Activity = activity + Me.CurrentEmployee = employee + End Sub + + 'From other state. + Public Sub New(state As ActivityState, employee As IEmployee) + 'Set the current activity of the employee, only happens in this state. + employee.CurrentActivity = Activity + + Activity = state.Activity + Me.CurrentEmployee = employee + End Sub + + ''' + Public Overrides Function ActivityStateEnum() As ActivityStateEnum + Return ProductiePitching.ActivityStateEnum.Started + End Function + + ''' + Public Overrides Function GetEmployee() As IEmployee + Return CurrentEmployee + End Function + + ''' + Public Overrides Sub StopActivity() + Activity.State = New ActivityStoppedState(Me) + End Sub + + ''' + Public Overrides Sub FinishActivity() + 'Update state. + Activity.State = New ActivityFinishedState(Me) + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/IDataGridUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/IDataGridUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/IDataGridUserControl.vb (revision 1759) @@ -0,0 +1,18 @@ +Public Interface IDataGridUserControl + ''' + ''' Access to the grid number. + ''' + ''' + ReadOnly Property GridNumber As Integer + + ''' + ''' Clears the selection from the datagrid. + ''' + Sub RemoveSelection() + + ''' + ''' Refresh the data of the grid. + ''' + ''' Whether or not it was successful + Function RefreshData() As Boolean +End Interface Index: ActiviteitenOpvolging/ProductiePitching/My Project/Resources.resx =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/My Project/Resources.resx (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/My Project/Resources.resx (revision 1759) @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ICT_READONLY + The username for the Caché database + + + SQL02 + The server name for the employees database + + + fixed + The password for the Caché database + + + CACHE01 + The name of the server for the Caché database + + + ADMIN1 + The name of the Caché database + + + WieIsWie + The name of the Employees database + + + Cache01Admin1 + The name of the DSN for the Caché database + + + VH_ReadOnly + The username for the employees database + + + SQLr3*d + The password for the employee database + + + + ..\Resources\user.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\remove_user.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/domain/managers/implementations/WorkItemManager.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/managers/implementations/WorkItemManager.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/managers/implementations/WorkItemManager.vb (revision 1759) @@ -0,0 +1,37 @@ +Imports ProductiePitching.ServiceAgents +Imports ProductiePitching.ServiceAgents.Implementations + +Public Class WorkItemManager + Implements IWorkItemManager + + Private ReadOnly _activiteitPerBatchServiceAgent As IActiviteitPerBatchServiceAgent + + Public Sub New() + _ActiviteitPerBatchServiceAgent = New ActiviteitPerBatchServiceAgent + End Sub + + ''' + Public Function GiveWorkItems(workPostIndex As Integer, employees As List(Of IEmployee)) As ICollection(Of IWorkItem) Implements IWorkItemManager.GiveWorkItems + Return CacheMapper.GetData(workPostIndex, employees) + End Function + + Public Sub StartActivity(activity As IActivity, employee As IEmployee) Implements IWorkItemManager.StartActivity + activity.StartActivity(employee) + _ActiviteitPerBatchServiceAgent.SetActivityState(activity, employee) + End Sub + + Public Sub FinishActivity(activity As IActivity) Implements IWorkItemManager.FinishActivity + activity.FinishActivity() + _ActiviteitPerBatchServiceAgent.SetActivityState(activity) + End Sub + + Public Sub StopActivity(activity As IActivity) Implements IWorkItemManager.StopActivity + activity.StopActivity() + _ActiviteitPerBatchServiceAgent.SetActivityState(activity) + End Sub + + Public Sub PauseActivities() Implements IWorkItemManager.PauseActivities + _activiteitPerBatchServiceAgent.PauseActionsFromApp() + End Sub + +End Class Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/EmployeePickerUserControl.resx =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/EmployeePickerUserControl.resx (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/EmployeePickerUserControl.resx (revision 1759) @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/workplace.ico =================================================================== diff -u Binary files differ Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/IEmployeeUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/IEmployeeUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/IEmployeeUserControl.vb (revision 1759) @@ -0,0 +1,12 @@ +Public Interface IEmployeeUserControl + inherits IRefreshableUserControl + ''' + ''' Triggered when the selected activity changes. + ''' + Sub SelectedActivityChanged() + + ''' + ''' Triggered when the amount of selected user changes. + ''' + Sub SelectedEmployeeChanged() +End Interface Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/IActivity.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/IActivity.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/IActivity.vb (revision 1759) @@ -0,0 +1,18 @@ +Public Interface IActivity + Inherits IActivityActions + + Property Id As String + Property QuantityToProduce As Integer + Property Label As String + ReadOnly Property Status As ActivityStateEnum + Property EmployeeInitials As String + Property IsReadOnly As Boolean + Property StartBeforeTimestamp As DateTime + Property StartAlmostTimeStamp As DateTime + Property StartTimeStamp As DateTime + + Property WorkItem As IWorkItem + + Property State As ActivityState + ReadOnly Property CurrentEmployee As IEmployee +End Interface Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/IRefreshableUserControl.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/IRefreshableUserControl.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/IRefreshableUserControl.vb (revision 1759) @@ -0,0 +1,7 @@ +Public Interface IRefreshableUserControl + ''' + ''' Refresh the data of the user control. + ''' + ''' Whether or not the refresh succeeded. + Function RefreshData() As Boolean +End Interface Index: ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/EmployeePickerUserControl.Designer.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/EmployeePickerUserControl.Designer.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/screens/employee/picker/EmployeePickerUserControl.Designer.vb (revision 1759) @@ -0,0 +1,93 @@ + _ +Partial Class EmployeePickerUserControl + Inherits System.Windows.Forms.UserControl + + 'UserControl overrides dispose to clean up the component list. + _ + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Required by the Windows Form Designer + Private components As System.ComponentModel.IContainer + + 'NOTE: The following procedure is required by the Windows Form Designer + 'It can be modified using the Windows Form Designer. + 'Do not modify it using the code editor. + _ + Private Sub InitializeComponent() + Me.EmployeesComboBox = New System.Windows.Forms.ComboBox() + Me.PictureBox1 = New System.Windows.Forms.PictureBox() + Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel() + CType(Me.PictureBox1,System.ComponentModel.ISupportInitialize).BeginInit + Me.TableLayoutPanel1.SuspendLayout + Me.SuspendLayout + ' + 'EmployeesComboBox + ' + Me.TableLayoutPanel1.SetColumnSpan(Me.EmployeesComboBox, 3) + Me.EmployeesComboBox.Dock = System.Windows.Forms.DockStyle.Top + Me.EmployeesComboBox.FormattingEnabled = true + Me.EmployeesComboBox.Location = New System.Drawing.Point(53, 303) + Me.EmployeesComboBox.Name = "EmployeesComboBox" + Me.EmployeesComboBox.Size = New System.Drawing.Size(394, 21) + Me.EmployeesComboBox.TabIndex = 0 + ' + 'PictureBox1 + ' + Me.PictureBox1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ + Or System.Windows.Forms.AnchorStyles.Left) _ + Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles) + Me.PictureBox1.Image = Global.ProductiePitching.My.Resources.Resources.user + Me.PictureBox1.Location = New System.Drawing.Point(128, 3) + Me.PictureBox1.Name = "PictureBox1" + Me.PictureBox1.Size = New System.Drawing.Size(244, 294) + Me.PictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom + Me.PictureBox1.TabIndex = 1 + Me.PictureBox1.TabStop = false + ' + 'TableLayoutPanel1 + ' + Me.TableLayoutPanel1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ + Or System.Windows.Forms.AnchorStyles.Left) _ + Or System.Windows.Forms.AnchorStyles.Right),System.Windows.Forms.AnchorStyles) + Me.TableLayoutPanel1.ColumnCount = 5 + Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10!)) + Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15!)) + Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50!)) + Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15!)) + Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10!)) + Me.TableLayoutPanel1.Controls.Add(Me.EmployeesComboBox, 1, 1) + Me.TableLayoutPanel1.Controls.Add(Me.PictureBox1, 2, 0) + Me.TableLayoutPanel1.Location = New System.Drawing.Point(0, 0) + Me.TableLayoutPanel1.Name = "TableLayoutPanel1" + Me.TableLayoutPanel1.RowCount = 2 + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50!)) + Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20!)) + Me.TableLayoutPanel1.Size = New System.Drawing.Size(500, 600) + Me.TableLayoutPanel1.TabIndex = 2 + ' + 'EmployeePickerUserControl + ' + Me.AutoScaleDimensions = New System.Drawing.SizeF(6!, 13!) + Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font + Me.Controls.Add(Me.TableLayoutPanel1) + Me.Name = "EmployeePickerUserControl" + Me.Size = New System.Drawing.Size(500, 600) + CType(Me.PictureBox1,System.ComponentModel.ISupportInitialize).EndInit + Me.TableLayoutPanel1.ResumeLayout(false) + Me.ResumeLayout(false) + +End Sub + + Friend WithEvents EmployeesComboBox As ComboBox + Friend WithEvents PictureBox1 As PictureBox + Friend WithEvents TableLayoutPanel1 As TableLayoutPanel +End Class Index: ActiviteitenOpvolging/ProductiePitching/Images/warning.png =================================================================== diff -u Binary files differ Index: ActiviteitenOpvolging/ProductiePitching/configs/ConfigsLoader.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/configs/ConfigsLoader.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/configs/ConfigsLoader.vb (revision 1759) @@ -0,0 +1,458 @@ +Imports System.IO +Imports System.Security.Policy +Imports System.Text.RegularExpressions + +Namespace configs + Public Module ConfigsLoader + Const MaxIntervalSeconds As Integer = 3600 'Max of 6 hours + Public Const GridColumnAmount As Integer = 5 'Batch, DueOut, Product, Naar, Opmerking + + Sub New() + Try + Dim configsTextMapper As New ConfigsTextmapper + + 'Load the configs that change for every work post. + Dim dynamicConfigFileName = System.Net.Dns.GetHostName() + "_DynamicConfigs.txt" + LoadDynamicConfigLines(configsTextMapper.GetAllValues(Path.Combine(My.Application.Info.DirectoryPath, dynamicConfigFileName))) + ValidateDynamicConfigs() + 'Load the general configs. + LoadGeneralConfigLines(configsTextMapper.GetAllValues(Path.Combine(My.Application.Info.DirectoryPath, "GeneralConfigs.txt"))) + ValidateGeneralConfigs() + Catch ex As Exception + 'Show error message, it's just easier to handle it here. + MessageBox.Show(ex.Message, "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error) + Application.Exit() + End Try + End Sub + +#Region "Help functions" + ''' + ''' Extract the identification of the config from the line. Example => 'identification'=600 + ''' + ''' + ''' The identifier + Private Function ExtractConfigIdentifier(configLine As String) As String + Try + 'Everything in front of the '='. + Return configLine.Substring(0, configLine.IndexOf("=", StringComparison.Ordinal)).Trim() + Catch ex As Exception + Throw New Exception($"Invalid configuration entry. Can't extract the identifier for the config (the part before the '='): '{configLine}'.") + End Try + End Function + + ''' + ''' Extract the value of the config from the line. Example => RefreshFrequence='value' + ''' + ''' + ''' The identifier + Private Function ExtractConfigValue(configLine As String) As String + Try + 'Everything after the '='. + Return configLine.Substring(configLine.IndexOf("=", StringComparison.Ordinal) + 1).Trim() + Catch ex As Exception + Throw New Exception($"Invalid configuration entry. Can't extract the value for the config (the part after the '='): '{configLine}'.") + End Try + End Function + + ''' + ''' Get the color corresponding to the hexadecimal string code. In seperate function for error handling. + ''' + ''' + ''' + Private Function GetColorFromHexStringValue(hexadecimalColorCode As String) As Color + Try + 'Convert to color and return. + Return ColorTranslator.FromHtml(hexadecimalColorCode) + Catch ex As Exception + Throw New ConfigurationException($"The value '{hexadecimalColorCode}' cannot be converted to a color.") + End Try + End Function +#End Region + +#Region "Dynamic configs" +#Region "Properties" + Public ReadOnly Property AppName As String + Public ReadOnly Property AppId As String + Public ReadOnly Property AppWidth As Integer + Public ReadOnly Property AppHeight As Integer + Public ReadOnly Property NumberOfGrids As Integer + Private ReadOnly _gridLabelNames As New List(Of String) + Public ReadOnly Property GridLabelNames As List(Of String) + Get + Return New List(Of String)(_gridLabelNames) + End Get + End Property + Private ReadOnly _gridWidths As New List(Of Integer) + Public ReadOnly Property GridWidths As List(Of Integer) + Get + Return New List(Of Integer)(_gridWidths) + End Get + End Property + Private ReadOnly _gridHeights As New List(Of Integer) + Public ReadOnly Property GridHeights As List(Of Integer) + Get + Return New List(Of Integer)(_gridHeights) + End Get + End Property + Private ReadOnly _gridsColumnHeaderNames As New List(Of String()) + Public ReadOnly Property GridColumnHeaderNames As List(Of String()) + Get + Return New List(Of String())(_gridsColumnHeaderNames) + End Get + End Property + Private ReadOnly _numbersOfActivities As New List(Of Integer) + Public ReadOnly Property NumbersOfActivities As List(Of Integer) + Get + Return New List(Of Integer)(_numbersOfActivities) + End Get + End Property + Private ReadOnly _sqlQueries As New List(Of String) + Public ReadOnly Property SqlQueries As List(Of String) + Get + Return New List(Of String)(_sqlQueries) + End Get + End Property + Public ReadOnly Property NumberOfEmployees As Integer +#End Region + + ''' + ''' Loads in all the present configs specific for a work post. + ''' + ''' + Private Sub LoadDynamicConfigLines(dynamicConfigLines As IReadOnlyCollection(Of String)) + Try + 'Loop through each line. + For Each line In dynamicConfigLines + 'Get key and value of a config entry. + Dim identifier = ExtractConfigIdentifier(line) + Dim value = ExtractConfigValue(line) + + If identifier.Equals("AppName") Then + _AppName = value + ElseIf identifier.Equals("AppID") Then + _AppId = value + ElseIf identifier.Equals("AppDimension") Then + 'Split into width and height. + Dim values = value.Split("x") + 'Check if there are two values. + If values.Count() <> 2 Then Throw New ConfigurationException("The dimensions of the program have an invalid format.") + 'Save values. + _AppWidth = values(0) 'Width + _AppHeight = values(1) 'Height + ElseIf identifier.Equals("NumberOfGrids") Then + _NumberOfGrids = value + ElseIf identifier.Contains("GridLabel") Then + _gridLabelNames.Add(value) + ElseIf identifier.Contains("DimensionsGrid") Then + 'Split into width and height. + Dim values = value.Split("x") + 'Check if there are two values. + If values.Count() <> 2 Then Throw New ConfigurationException("The dimensions of a grid have an invalid format.") + 'Save values. + _gridWidths.Add(values(0)) 'Width + _gridHeights.Add(values(1)) 'Height + ElseIf identifier.Contains("ColumnHeaderGrid") Then + _gridsColumnHeaderNames.Add(value.Split(",")) + ElseIf identifier.Contains("NumberOfActivitiesGrid") Then + _numbersOfActivities.Add(value) + ElseIf identifier.Contains("SQL") Then + _sqlQueries.Add(value) + ElseIf identifier.Equals("NumberOfEmployees") Then + _NumberOfEmployees = value + Else + Throw New Exception($"Unknown configuration: '{line}'.") + End If + Next + Catch ex As InvalidCastException + Throw New ConfigurationException($"One of the dynamic config values has an invalid type.{vbNewLine}{ex.Message}") + End Try + End Sub + + ''' + ''' Validate that all the required fields were present. + ''' + Private Sub ValidateDynamicConfigs() + 'App name. + If AppName Is Nothing OrElse AppName.Equals(String.Empty) Then + Throw New ConfigurationException("App name is not defined or invalid.") + End If + 'App id. + If AppId Is Nothing OrElse AppId.Equals(String.Empty) Then + Throw New ConfigurationException("App id is not defined or invalid.") + End If + 'App width. + If AppWidth = 0 Then + Throw New ConfigurationException("The app width is not defined or too small.") + ElseIf AppWidth < 0 Then + Throw New ConfigurationException("The app width is too small.") + End If + 'App height. + If AppHeight = 0 Then + Throw New ConfigurationException("The app height is not defined or too small.") + ElseIf AppHeight < 0 Then + Throw New ConfigurationException("The app height is too small.") + End If + 'Number of grids. + If _NumberOfGrids <= 0 Then + Throw New ConfigurationException("Number of grids is not defined or invalid.") + End If + 'Grid label names. + If _gridLabelNames.Count = 0 Then + Throw New ConfigurationException("There are no grid labels defined.") + ElseIf _gridLabelNames.Count <> NumberOfGrids Then + Throw New ConfigurationException("The amount of 'grid labels' is not equal to the 'number of grids'.") + End If + 'Grid dimensions. + If _gridWidths.Count = 0 Or _gridHeights.Count = 0 Then + Throw New ConfigurationException("There are no grid dimensions defined.") + ElseIf _gridWidths.Count <> NumberOfGrids Or _gridHeights.Count <> NumberOfGrids Then + Throw New ConfigurationException("The amount of 'grid dimensions' is not equal to the 'number of grids'.") + ElseIf _gridWidths.Any(Function(width) width <= 0) Then + Throw New ConfigurationException("One or more of the 'grid dimensions' has a width that is too small.") + ElseIf _gridHeights.Any(Function(height) height <= 0) Then + Throw New ConfigurationException("One or more of the 'grid dimensions' has a height that is too small.") + End If + 'Column headers of grids. + If _gridsColumnHeaderNames.Count = 0 Then + Throw New ConfigurationException("There are no grid column header collections defined.") + ElseIf _gridsColumnHeaderNames.Count <> NumberOfGrids Then + Throw New ConfigurationException("The amount of 'grid column header collections' is not equal to the 'number of grids'.") + ElseIf Not _gridsColumnHeaderNames.All(Function(headerNameCollection) headerNameCollection.Count() = GridColumnAmount) Then + Throw New ConfigurationException($"The amount of 'grid column headers' is not equal to the number of headers: {GridColumnAmount}.") + End If + 'Numbers of activities. + If _numbersOfActivities.Count = 0 Then + Throw New ConfigurationException("There are no numbers of activities defined.") + ElseIf _numbersOfActivities.Count <> NumberOfGrids Then + Throw New ConfigurationException("The amount of 'activity numbers' is not equal to the 'number of grids'.") + End If + 'SQL queries. + If _sqlQueries.Count = 0 Then + Throw New ConfigurationException("There are no SQL queries defined.") + ElseIf _sqlQueries.Count <> NumberOfGrids Then + Throw New ConfigurationException("The amount of 'SQL queries' is not equal to the 'number of grids'.") + End If + 'Number of users. + If NumberOfEmployees < 0 Then + Throw New ConfigurationException("Number of users is not defined or invalid.") + End If + End Sub +#End Region + +#Region "General configs" +#Region "Properties" + Public ReadOnly Property RefreshIntervalSeconds As Integer + Public ReadOnly Property RefreshTimeStart As TimeSpan + Public ReadOnly Property RefreshTimeEnd As TimeSpan + Public ReadOnly Property CacheWebserviceUrl As Url + Public ReadOnly Property StartBeforeTimeThreshold As TimeSpan + Public ReadOnly Property StartAlmostTimeThreshold As TimeSpan +#Region "Colors and images" + Public ReadOnly Property AgColorBatch As Color + Public ReadOnly Property AgColorProductGroup As Color + Public ReadOnly Property AgColorTo As Color + Public ReadOnly Property ActivityBeforeStatusImage As Image + Public ReadOnly Property ActivityAlmostStatusImage As Image + Public ReadOnly Property ActivityLateStatusImage As Image + Private ReadOnly Property _colorsActivities As New Dictionary(Of ActivityStateEnum, Color) + Public ReadOnly Property ColorsActivities As Dictionary(Of ActivityStateEnum, Color) + Get + Return New Dictionary(Of ActivityStateEnum, Color)(_colorsActivities) + End Get + End Property + Private ReadOnly Property _colorsActivityReadOnly As New Dictionary(Of ActivityStateEnum, Color) + Public ReadOnly Property ColorsActivitiesReadOnly As Dictionary(Of ActivityStateEnum, Color) + Get + Return New Dictionary(Of ActivityStateEnum, Color)(_colorsActivityReadOnly) + End Get + End Property + Public ReadOnly Property AllFinishedActivitiesColor As color + Private ReadOnly _colorsEmployees As New List(Of Color) + Public ReadOnly Property ColorsEmployees As List(Of Color) + Get + Return New List(Of Color)(_colorsEmployees) + End Get + End Property +#End Region +#End Region + ''' + ''' Loads in all the general configs. + ''' + ''' + Private Sub LoadGeneralConfigLines(generalConfigLines As IReadOnlyCollection(Of String)) + Try + 'Loop through each line. + For Each line In generalConfigLines + 'Get key and value of a config entry. + Dim identifier = ExtractConfigIdentifier(line) + Dim value = ExtractConfigValue(line) + + If identifier.Equals("RefreshFrequence") Then + _RefreshIntervalSeconds = value + ElseIf identifier.Equals("RefreshTimeStart") Then + _RefreshTimeStart = TimeSpan.FromHours(value) + ElseIf identifier.Equals("RefreshTimeEnd") Then + _RefreshTimeEnd = TimeSpan.FromHours(value) + ElseIf identifier.Equals("CacheWebserviceURL") Then + _CacheWebserviceUrl = New Url(value) + ElseIf identifier.Equals("StartBeforeTimeThreshold") Then + _StartBeforeTimeThreshold = TimeSpan.FromMinutes(value) + ElseIf identifier.Equals("StartAlmostTimeThreshold") Then + _StartAlmostTimeThreshold = TimeSpan.FromMinutes(value) + ElseIf identifier.Equals("AgColorBatch") Then + _AgColorBatch = GetColorFromHexStringValue(value) + ElseIf identifier.Equals("AgColorProductGroup") Then + _AgColorProductGroup = GetColorFromHexStringValue(value) + ElseIf identifier.Equals("AgColorTo") Then + _AgColorTo = GetColorFromHexStringValue(value) + ElseIf identifier.Equals("ImageBefore") Then + If File.Exists(value) Then + _ActivityBeforeStatusImage = Image.FromFile(value) + End If + ElseIf identifier.Equals("ImageAlmost") Then + If File.Exists(value) Then + _ActivityAlmostStatusImage = Image.FromFile(value) + End If + ElseIf identifier.Equals("ImageLate") Then + If File.Exists(value) Then + _ActivityLateStatusImage = Image.FromFile(value) + End If + ElseIf identifier.Contains("AgColorActivityReadOnly") Then + AddColorActivity(identifier, value, True) + ElseIf identifier.Contains("AgColorActivity") Then + AddColorActivity(identifier, value, False) + ElseIf identifier.Equals("ColorActivityAllFinished") Then + _AllFinishedActivitiesColor = GetColorFromHexStringValue(value) + ElseIf identifier.Contains("ColorEmployee") Then + _colorsEmployees.Add(GetColorFromHexStringValue(value)) + Else + Throw New Exception($"Unknown configuration: '{line}'.") + End If + Next + Catch ex As InvalidCastException + Throw New ConfigurationException($"One of the general config values has an invalid type.{vbNewLine}{ex.Message}") + Catch ex As Exception + Throw New ConfigurationException($"One of the general config values is invalid.{vbNewLine}{ex.Message}") + End Try + End Sub + + ''' + ''' Add a color for a due out state to the dictionary. + ''' + ''' The identifier of the state + ''' The hexadecimal string value of the color + ''' Whether or not the activity is readonly + Private Sub AddColorActivity(identifier As String, value As String, isReadOnly As Boolean) + Try + 'Extract the state name. + 'Invoke the Match method, all text after AgColorDueOut. + Dim m As Match = Regex.Match(identifier, If(isReadOnly, "AgColorActivityReadOnly(.*)", "AgColorActivity(.*)")) + + If Not m.Success Then + 'No results. + Throw New ConfigurationException($"Could not get the state for assigning a color for an activity. Identifier is '{identifier}'.") + End If + + 'If successful, extract the state name. + Dim stateName = m.Groups(1).Value + + 'Convert string value to enum value. + Dim enumValue = ActivityStateEnumMapper.GetEnumValueFromString(stateName) + + 'Add to library, key is the enum value, value is the color. + If isReadOnly Then + 'It's readonly. + _colorsActivityReadOnly.Add(enumValue, GetColorFromHexStringValue(value)) + Else + 'It's not. + _colorsActivities.Add(enumValue, GetColorFromHexStringValue(value)) + End If + Catch ex As Exception + Throw New ConfigurationException($"Color activity with name: '{identifier}' and value '{value}' is invalid.{vbNewLine}{ex.Message}") + End Try + End Sub + + ''' + ''' Validate that all the required fields are present. + ''' + Private Sub ValidateGeneralConfigs() + 'Refresh interval. + If RefreshIntervalSeconds <= 0 Then + Throw New ConfigurationException("The refresh interval is too low.") + ElseIf RefreshIntervalSeconds > MaxIntervalSeconds Then + Throw New ConfigurationException($"Refresh interval is above the maximum of {MaxIntervalSeconds} seconds.") + End If + + 'Refresh time start. + If RefreshTimeStart = TimeSpan.Zero Then + Throw New ConfigurationException("Refresh time start is not defined.") + End If + + 'Refresh time end. + If RefreshTimeEnd = TimeSpan.Zero Then + Throw New ConfigurationException("Refresh time end is not defined.") + End If + + 'Caché webservice URL. + If CacheWebserviceUrl Is Nothing Then + Throw New ConfigurationException("The Caché webservice URL is not defined.") + End If + + 'Ag color batch. + If AgColorBatch = Color.Empty Then + Throw New ConfigurationException("The Ag color batch is not defined.") + End If + + 'Ag color production group. + If AgColorProductGroup = Color.Empty Then + Throw New ConfigurationException("The Ag color production group is not defined.") + End If + + 'Caché webservice URL. + If AgColorTo = Color.Empty Then + Throw New ConfigurationException("The Ag color to is not defined.") + End If + + 'Before activity status image. + If _ActivityBeforeStatusImage Is Nothing Then + Throw New ConfigurationException("The activity before status image is not correctly defined.") + End If + + 'Almost activity status image. + If _ActivityAlmostStatusImage Is Nothing Then + Throw New ConfigurationException("The activity almost status image is not correctly defined.") + End If + + 'Late activity status image. + If _ActivityLateStatusImage Is Nothing Then + Throw New ConfigurationException("The activity late status image is not correctly defined.") + End If + + 'Colors activities. + If _colorsActivities.Keys.Count <> [Enum].GetValues(GetType(ActivityStateEnum)).Length Then + 'Amount of enum values and entries in the dictionary differ. + Throw New ConfigurationException($"The amount of colors defined for the different states of activities differs from the amount of states. + There are {[Enum].GetValues(GetType(ActivityStateEnum)).Length} total states and {_colorsActivities.Keys.Count} colors are defined.") + End If + + 'Colors activities readonly. + If _colorsActivityReadOnly.Keys.Count <> ([Enum].GetValues(GetType(ActivityStateEnum)).Length) Then + 'Amount of enum values and entries in the dictionary differ. ReadOnly doesn't have a color value for the 2 special activities. + Throw New ConfigurationException($"The amount of colors defined for the different states of readonly activities differs from the amount of states. + There are {[Enum].GetValues(GetType(ActivityStateEnum)).Length} total states and {_colorsActivityReadOnly.Keys.Count} colors are defined.") + End If + + 'All finished activity color. + If AllFinishedActivitiesColor = Color.Empty Then + Throw New ConfigurationException("The color for all finished activities is not defined.") + End If + + 'Colors users. + If _colorsEmployees.Count < NumberOfEmployees Then + Throw New ConfigurationException($"The colors for the employees are not defined or are fewer than the amount of users {NumberOfEmployees}.") + End If + End Sub + +#End Region + End Module +End Namespace \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/exceptions/ConfigurationException.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/exceptions/ConfigurationException.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/exceptions/ConfigurationException.vb (revision 1759) @@ -0,0 +1,16 @@ +''' +''' An error for when a configuration is erronous. +''' +Public Class ConfigurationException + Inherits System.ApplicationException + + ''' + Sub New(message As String) + MyBase.New($"There is a problem with the configuration file(s) or other configuration: {vbNewLine}{message}") + End Sub + + ''' + Sub New(message As String, innerException As Exception) + MyBase.New($"There is a problem with the configuration file(s) or other configuration: {vbNewLine}{message}", innerException) + End Sub +End Class Index: ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/WorkItem.vb =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/WorkItem.vb (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/domain/classes/implementations/WorkItem.vb (revision 1759) @@ -0,0 +1,15 @@ +Public Class WorkItem + implements IWorkItem + + Public Property BatchVisual As Integer Implements IWorkItem.BatchVisual + Public Property DeliverToResource As String Implements IWorkItem.DeliverToResource + Public Property ProductGroup As String Implements IWorkItem.ProductGroup + Public Property Remark As String Implements IWorkItem.Remark + Public Property EndTimeStamp As DateTime Implements IWorkItem.EndTimeStamp + Public Property Activities As List(Of IActivity) Implements IWorkItem.Activities + + ''' + Public Function AreAllActivatableActivitiesFinished() As Boolean Implements IWorkItem.AreAllActivatableActivitiesFinished + Return Activities.All(Function(activity) Not activity.IsReadOnly And activity.Status = ActivityStateEnum.Finished) + End Function +End Class Index: ActiviteitenOpvolging/ProductiePitching/ProductiePitching.vbproj =================================================================== diff -u --- ActiviteitenOpvolging/ProductiePitching/ProductiePitching.vbproj (revision 0) +++ ActiviteitenOpvolging/ProductiePitching/ProductiePitching.vbproj (revision 1759) @@ -0,0 +1,263 @@ + + + + + Debug + AnyCPU + {ECE397C7-CC25-48F3-93B4-32DBD159D111} + WinExe + ProductiePitching.My.MyApplication + ProductiePitching + ProductiePitching + 512 + WindowsForms + v4.7.2 + true + true + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + AnyCPU + true + full + true + true + bin\Debug\ + ProductiePitching.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + AnyCPU + pdbonly + false + true + true + bin\Release\ + ProductiePitching.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + On + + + Binary + + + Off + + + On + + + workplace.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Form + + + ProductiePitchingForm.vb + Form + + + + + + EmployeePickerUserControl.vb + + + UserControl + + + EmployeeUserControl.vb + + + UserControl + + + EmployeeDetailUserControl.vb + + + UserControl + + + + + + + + + + + + + + + + True + Application.myapp + + + True + True + Resources.resx + + + True + Settings.settings + True + + + DataGridViewUserControl.vb + + + UserControl + + + + + + + + ProductiePitchingForm.vb + + + VbMyResourcesResXFileCodeGenerator + Resources.Designer.vb + My.Resources + Designer + + + DataGridViewUserControl.vb + + + EmployeePickerUserControl.vb + + + EmployeeUserControl.vb + + + EmployeeDetailUserControl.vb + + + + + MyApplicationCodeGenerator + Application.Designer.vb + + + SettingsSingleFileGenerator + My + Settings.Designer.vb + + + + + + + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + + + + \ No newline at end of file Index: ActiviteitenOpvolging/ProductiePitching/Images/late.png =================================================================== diff -u Binary files differ