Initial commit: JDE Scoping Tool migration project

Set up repository with legacy .NET Framework 4.8 source (OLD/),
new .NET 10 Blazor solution (NEW/), OpenSpec specifications,
documentation, and project configuration.
This commit is contained in:
Joseph Doherty
2026-01-02 07:43:29 -05:00
commit 26ff8d9b4f
1761 changed files with 596509 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
namespace WorkerService.Models
{
/// <summary>
/// Database column specification
/// </summary>
public class ColumnSpec
{
/// <summary>
/// Column name
/// </summary>
public string Name { get; set; }
/// <summary>
/// Column definition
/// </summary>
public string Definition { get; set; }
}
}
+40
View File
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WorkerService.Models
{
public class DataSource
{
public int DataSourceID { get; set; }
public string Name { get; set; }
public string HostName { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
public class DataLoad
{
public int DataLoadID { get; set; }
public string Name { get; set; }
public int DataSourceID { get; set; }
public bool IsEnabled { get; set; }
public List<DataLoadSchedule> Schedules { get; set; }
}
public class DataLoadSchedule
{
public int DataLoadScheduleID { get; set; }
public int DataLoadID { get; set; }
public string Name { get; set; }
public bool PurgeBeforeLoad { get; set; }
public bool ReIndexAfterLoad { get; set; }
public bool IsDaily { get; set; }
}
}
+60
View File
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using WorkerService.Process;
namespace WorkerService.Models
{
/// <summary>
/// Database update configuration
/// </summary>
public class DataSourceConfig
{
/// <summary>
/// Name of source data system
/// </summary>
public string SourceSystem { get; set; }
/// <summary>
/// Name of source data set
/// </summary>
public string SourceData { get; set; }
/// <summary>
/// Name of table being updated
/// </summary>
public string TableName { get; set; }
/// <summary>
/// Whether or not the data source is enabled
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// Source data fetch function
/// </summary>
[JsonConverter(typeof(FunctionConverter<DateTime?, IEnumerable<dynamic>>))]
public Func<DateTime?, IEnumerable<dynamic>> DataFetchFunction { get; set; }
/// <summary>
/// Post data update processing action
/// </summary>
[JsonConverter(typeof(ActionConverter))]
public Action PostProcessingAction { get; set; }
/// <summary>
/// Data update entry for mass update typ
/// </summary>
public DataUpdateConfig MassUpdateConfig { get; set; }
/// <summary>
/// Data update entry for daily update typ
/// </summary>
public DataUpdateConfig DailyUpdateConfig { get; set; }
/// <summary>
/// Data update entry for hourly update typ
/// </summary>
public DataUpdateConfig HourlyUpdateConfig { get; set; }
}
}
+28
View File
@@ -0,0 +1,28 @@
namespace WorkerService.Models
{
/// <summary>
/// Database update entry
/// </summary>
public class DataUpdateConfig
{
/// <summary>
/// Whether or not the update config is enabled
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// Interval (in minutes) between updates
/// </summary>
public int Interval { get; set; }
/// <summary>
/// Whether or not the table should be purged prior to update
/// </summary>
public bool PrepurgeData { get; set; }
/// <summary>
/// Whether or not the table should be re-indexed after update
/// </summary>
public bool ReIndexData { get; set; }
}
}
+26
View File
@@ -0,0 +1,26 @@
using System;
using DataModel.Models;
namespace WorkerService.Models
{
/// <summary>
/// Cached data update task
/// </summary>
public class DataUpdateTask
{
/// <summary>
/// Data update configuration
/// </summary>
public DataSourceConfig Configuration { get; set; }
/// <summary>
/// Type of update needed
/// </summary>
public UpdateTypes UpdateType { get; set; }
/// <summary>
/// Minimum timestamp to import changeset from
/// </summary>
public DateTime? MinimumDT { get; set; }
}
}
+28
View File
@@ -0,0 +1,28 @@
namespace WorkerService.Models
{
/// <summary>
/// Table index
/// </summary>
public class Index
{
/// <summary>
/// Name of index
/// </summary>
public string Name { get; set; }
/// <summary>
/// Whether or not the index is a primary key
/// </summary>
public bool IsPrimaryKey { get; set; }
/// <summary>
/// Whether or not the index is unique
/// </summary>
public bool IsUnique { get; set; }
/// <summary>
/// Whether or not the index is unique constraint
/// </summary>
public bool IsUniqueConstraint { get; set; }
}
}
+30
View File
@@ -0,0 +1,30 @@
using System;
namespace WorkerService.Models
{
/// <summary>
/// Set of last successful data updates for table
/// </summary>
public class LastDataUpdate
{
/// <summary>
/// Data table name
/// </summary>
public string TableName { get; set; }
/// <summary>
/// Timestamp of last successful mass data update
/// </summary>
public DateTime MassUpdateDT { get; set; }
/// <summary>
/// Timestamp of last successful daily data update
/// </summary>
public DateTime DailyUpdateDT { get; set; }
/// <summary>
/// Timestamp of last successful hourly data update
/// </summary>
public DateTime HourlyUpdateDT { get; set; }
}
}
@@ -0,0 +1,32 @@
using DataModel.ViewModels;
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Component lot search filter entry
/// </summary>
[OutputTable(TabName = "Component Lot Filter", ShowHeader = true, TableName = "Component_Lot_Filter")]
public class ComponentLotFilterEntry
{
/// <summary>
/// Component lot number
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Lot Number")]
public string LotNumber { get; set; }
/// <summary>
/// Component lot item number
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Item Number")]
public string ItemNumber { get; set; }
/// <summary>
/// Implicit view model conversion
/// </summary>
/// <param name="lotViewModel">View model to convert</param>
public static implicit operator ComponentLotFilterEntry(LotViewModel lotViewModel)
{
return new ComponentLotFilterEntry() { LotNumber = lotViewModel.LotNumber, ItemNumber = lotViewModel.ItemNumber };
}
}
}
@@ -0,0 +1,21 @@
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Item number search filter entry
/// </summary>
[OutputTable(TabName = "Item Number Filter", ShowHeader = true, TableName = "Item_Number_Filter")]
public class ItemNumberFilterEntry
{
/// <summary>
/// Item number
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Item Number")]
public string ItemNumber { get; set; }
/// <summary>
/// Item description
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Item Description")]
public string ItemDescription { get; set; }
}
}
@@ -0,0 +1,33 @@
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Item/operation/MIS search filter entry
/// </summary>
[OutputTable(TabName = "Item/Operation/MIS Filter", ShowHeader = true, TableName = "Item_Operation_MIS_Filter")]
public class ItemOperationMisFilterEntry
{
/// <summary>
/// Part's item number
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Item Number")]
public string ItemNumber { get; set; }
/// <summary>
/// Operation's job step number
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Operation Number")]
public string OperationNumber { get; set; }
/// <summary>
/// MIS number
/// </summary>
[OutputColumn(Order = 30, HeaderText = "MIS Number")]
public string MisNumber { get; set; }
/// <summary>
/// MIS revision
/// </summary>
[OutputColumn(Order = 40, HeaderText = "MIS Revision")]
public string MisRevision { get; set; }
}
}
@@ -0,0 +1,83 @@
using System;
namespace WorkerService.Models.Reporting
{
/// <summary>
/// MIS non-match reporting model
/// </summary>
[OutputTable(TabName = "Investigation", TableName = "Investigation")]
public class MisNonMatchSearchResult
{
/// <summary>
/// Work order job step work center code
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Work Center Code")]
public string WorkCenterCode { get; set; }
/// <summary>
/// Work order unique number
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Work Order Number")]
public long WorkOrderNumber { get; set; }
/// <summary>
/// Work order start date
/// </summary>
[OutputColumn(Order = 30, HeaderText = "Work Order Start Date", Format = OutputColumnAttribute.DATE_FORMAT)]
public DateTime WorkOrderStartDate { get; set; }
/// <summary>
/// Work order job step number
/// </summary>
[OutputColumn(Order = 40, HeaderText = "Job Step Number")]
public decimal JobStepNumber { get; set; }
/// <summary>
/// Work order job step description
/// </summary>
[OutputColumn(Order = 50, HeaderText = "Function Operation Description")]
public string JobStepDescription { get; set; }
/// <summary>
/// Work order job step completion date
/// </summary>
[OutputColumn(Order = 60, HeaderText = "Job Step End Date", Format = OutputColumnAttribute.DATE_FORMAT)]
public DateTime? JobStepEndDate { get; set; }
/// <summary>
/// Work order job step function code
/// </summary>
[OutputColumn(Order = 70, HeaderText = "Function Code")]
public string FunctionCode { get; set; }
/// <summary>
/// Work order job step function code
/// </summary>
[OutputColumn(Order = 75, HeaderText = "Was Job Step Added?")]
public bool WasJobStepAdded { get; set; }
/// <summary>
/// Matched work order job step number (match to original router by work order number, work center code, and function code)
/// </summary>
[OutputColumn(Order = 76, HeaderText = "Matched Job Step Number")]
public decimal? MatchedJobStepNumber { get; set; }
/// <summary>
/// Work order item number
/// </summary>
[OutputColumn(Order = 80, HeaderText = "Item Number")]
public string ItemNumber { get; set; }
/// <summary>
/// Work order item description
/// </summary>
[OutputColumn(Order = 90, HeaderText = "Item Description")]
public string ItemDescription { get; set; }
/// <summary>
/// Work order router type
/// </summary>
[OutputColumn(Order = 100, HeaderText = "Routing Type")]
public string RoutingType { get; set; }
}
}
+125
View File
@@ -0,0 +1,125 @@
using System;
namespace WorkerService.Models.Reporting
{
/// <summary>
/// MIS data reporting model
/// </summary>
[OutputTable(TabName = "MIS Info", TableName = "MIS_Info")]
public class MisSearchResult
{
/// <summary>
/// Item unique number
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Item Number")]
public string ItemNumber { get; set; }
/// <summary>
/// Item description
/// </summary>
[OutputColumn(Order = 50, HeaderText = "Item Description")]
public string ItemDescription { get; set; }
/// <summary>
/// Operation job step number
/// </summary>
[OutputColumn(Order = 20, HeaderText = "MIS Job Step Sequence Number")]
public string SequenceNumber { get; set; }
/// <summary>
/// MIS unique number
/// </summary>
[OutputColumn(Order = 30, HeaderText = "MIS Number")]
public string MisNumber { get; set; }
/// <summary>
/// MIS revision ID
/// </summary>
[OutputColumn(Order = 40, HeaderText = "MIS Revision")]
public string RevID { get; set; }
/// <summary>
/// MIS release status
/// </summary>
[OutputColumn(Order = 60, HeaderText = "MIS Release Status")]
public string Status { get; set; }
/// <summary>
/// MIS release date
/// </summary>
[OutputColumn(Order = 70, HeaderText = "MIS Release Date", Format = OutputColumnAttribute.TIMESTAMP_FORMAT)]
public DateTime? ReleaseDate { get; set; }
/// <summary>
/// Branch unique code
/// </summary>
[OutputColumn(Order = 80, HeaderText = "Branch Code")]
public string BranchCode { get; set; }
/// <summary>
/// Job step number
/// </summary>
[OutputColumn(Order =90, HeaderText = "Job Step Sequence Number")]
public decimal JobStepSequenceNumber { get; set; }
/// <summary>
/// Job step number for matched F3112Z1 / F3111 record
/// </summary>
[OutputColumn(Order = 100, HeaderText = "Matched Sequence Number")]
public decimal? MatchedSequenceNumber { get; set; }
/// <summary>
/// Whether or not the job step was matched to F3112Z1 record
/// </summary>
[OutputColumn(Order = 110, HeaderText = "Matched to F3112Z1?")]
public bool RoutingMatch { get; set; }
/// <summary>
/// Whether or not the job step was matched to F3111 record
/// </summary>
[OutputColumn(Order = 120, HeaderText = "Matched to F3003?")]
public bool MasterMatch { get; set; }
/// <summary>
/// Job step function description
/// </summary>
[OutputColumn(Order = 130, HeaderText = "Function Operation Description")]
public string FunctionOperationDescription { get; set; }
/// <summary>
/// Characteristic number
/// </summary>
[OutputColumn(Order = 140, HeaderText = "Char Number")]
public string CharNumber { get; set; }
/// <summary>
/// Test description
/// </summary>
[OutputColumn(Order = 150, HeaderText = "Test Description", AutoWidth = false, Width = OutputColumnAttribute.WRAPPED_COLUMN_WIDTH, WrapText = true)]
public string TestDescription { get; set; }
/// <summary>
/// Type of sampling
/// </summary>
[OutputColumn(Order = 160, HeaderText = "Sampling Type")]
public string SamplingType { get; set; }
/// <summary>
/// Sampling selection value
/// </summary>
[OutputColumn(Order = 170, HeaderText = "Sampling Value")]
public string SamplingValue { get; set; }
/// <summary>
/// Tools & gauges for MIS
/// </summary>
[OutputColumn(Order = 180, HeaderText = "Tools & Gauges", AutoWidth = false, Width = OutputColumnAttribute.WRAPPED_COLUMN_WIDTH, WrapText = true)]
public string ToolsGauges { get; set; }
/// <summary>
/// Instructions for MIS
/// </summary>
[OutputColumn(Order = 190, HeaderText = "Work Instructions", AutoWidth = false, Width = OutputColumnAttribute.WRAPPED_COLUMN_WIDTH, WrapText = true)]
public string WorkInstructions { get; set; }
}
}
+26
View File
@@ -0,0 +1,26 @@
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Operator search filter entry
/// </summary>
[OutputTable(TabName = "Operator Filter", ShowHeader = true, TableName = "Operator_Filter")]
public class OperatorFilterEntry
{
/// <summary>
/// Operator unique JDE address number
/// </summary>
public long AddressNumber { get; set; }
/// <summary>
/// Operator login user ID
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Username")]
public string UserID { get; set; }
/// <summary>
/// Operator full name (FIRST + LAST)
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Name")]
public string FullName { get; set; }
}
}
+25
View File
@@ -0,0 +1,25 @@
using System.Reflection;
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Report output column setting
/// </summary>
public class OutputColumn
{
/// <summary>
/// Column name
/// </summary>
public string Name { get; set; }
/// <summary>
/// Property to bind to column
/// </summary>
public PropertyInfo Property { get; set; }
/// <summary>
/// Output column settings attribute
/// </summary>
public OutputColumnAttribute Attribute { get; set; }
}
}
@@ -0,0 +1,60 @@
using System;
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Excel output column specification
/// </summary>
public class OutputColumnAttribute : Attribute
{
/// <summary>
/// Order to display column
/// </summary>
public int Order { get; set; }
/// <summary>
/// Override text to display for column
/// </summary>
public string HeaderText { get; set; }
/// <summary>
/// Column format (Excel formatting string)
/// </summary>
public string Format { get; set; } = STD_FORMAT;
/// <summary>
/// Standard format
/// </summary>
public const string STD_FORMAT = "@";
/// <summary>
/// Standard date format
/// </summary>
public const string DATE_FORMAT = "[$-409]MM/dd/yyyy;@";
/// <summary>
/// Standard timestamp format
/// </summary>
public const string TIMESTAMP_FORMAT = "[$-409]m/d/yy h:mm AM/PM;@";
/// <summary>
/// Whether or not width should be set automatically
/// </summary>
public bool AutoWidth { get; set; } = true;
/// <summary>
/// Manually set width (only used if AutoWidth = FALSE)
/// </summary>
public double Width { get;set; }
/// <summary>
/// Wrapped text column default width
/// </summary>
public const double WRAPPED_COLUMN_WIDTH = 65;
/// <summary>
/// Whether or not text should be wrapped
/// </summary>
public bool WrapText { get; set; }
}
}
+25
View File
@@ -0,0 +1,25 @@
using System;
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Excel output table specification
/// </summary>
public class OutputTableAttribute : Attribute
{
/// <summary>
/// Output tab name
/// </summary>
public string TabName { get; set; }
/// <summary>
/// Table name
/// </summary>
public string TableName { get; set; }
/// <summary>
/// Whether or not merged header should be shown
/// </summary>
public bool ShowHeader { get; set; }
}
}
@@ -0,0 +1,21 @@
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Profit center search filter entry
/// </summary>
[OutputTable(TabName = "Profit Center Filter", ShowHeader = true, TableName = "Profit_Center_Filter")]
public class ProfitCenterFilterEntry
{
/// <summary>
/// Profit center code
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Profit Center")]
public string Code { get; set; }
/// <summary>
/// Profit center description
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Description")]
public string Description { get; set; }
}
}
+147
View File
@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Reporting search data model
/// </summary>
public class SearchModel
{
/// <summary>
/// PK ID of search
/// </summary>
public int ID { get; set; }
/// <summary>
/// User name of user that created search
/// </summary>
public string UserName { get; set; }
/// <summary>
/// User-friendly name for search
/// </summary>
public string Name { get; set; }
/// <summary>
/// Timestamp search was submitted
/// </summary>
public DateTime? SubmitDT { get; set; }
/// <summary>
/// Timestamp search was started
/// </summary>
public DateTime? StartDT { get; set; }
/// <summary>
/// Timestamp search was completed
/// </summary>
public DateTime? EndDT { get; set; }
/// <summary>
/// Minimum timestamp to include
/// </summary>
public DateTime? MinimumDT { get; set; }
/// <summary>
/// Maxmimum timestamp to include
/// </summary>
public DateTime? MaximumDT { get; set; }
/// <summary>
/// Whether or not timespan filter is enabled
/// </summary>
public bool TimespanFilterEnabled => (MinimumDT.HasValue || MaximumDT.HasValue);
/// <summary>
/// Collection of workorder numbers to include
/// </summary>
public List<WorkOrderFilterEntry> WorkOrderFilter { get; set; } = new List<WorkOrderFilterEntry>();
/// <summary>
/// Whether or not work order filter is enabled
/// </summary>
public bool WorkOrderFilterEnabled => WorkOrderFilter != null && WorkOrderFilter.Any();
/// <summary>
/// Collection of item numbers to include
/// </summary>
public List<ItemNumberFilterEntry> ItemNumberFilter { get; set; } = new List<ItemNumberFilterEntry>();
/// <summary>
/// Whether or not item number filter is enabled
/// </summary>
public bool ItemNumberFilterEnabled => ItemNumberFilter != null && ItemNumberFilter.Any();
/// <summary>
/// Collection of included profit centers
/// </summary>
public List<ProfitCenterFilterEntry> ProfitCenterFilter { get; set; } = new List<ProfitCenterFilterEntry>();
/// <summary>
/// Whether or not profit center filter is enabled
/// </summary>
public bool ProfitCenterFilterEnabled => ProfitCenterFilter != null && ProfitCenterFilter.Any();
/// <summary>
/// Collection of included work centers
/// </summary>
public List<WorkCenterFilterEntry> WorkCenterFilter { get; set; } = new List<WorkCenterFilterEntry>();
/// <summary>
/// Whether or not work center filter is enabled
/// </summary>
public bool WorkCenterFilterEnabled => WorkCenterFilter != null && WorkCenterFilter.Any();
/// <summary>
/// Collection of included operator IDs
/// </summary>
public List<OperatorFilterEntry> OperatorFilter { get; set; } = new List<OperatorFilterEntry>();
/// <summary>
/// Whether or not operator filter is enabled
/// </summary>
public bool OperatorFilterEnabled => OperatorFilter != null && OperatorFilter.Any();
/// <summary>
/// Collection of included upper level lot numbers
/// </summary>
public List<ComponentLotFilterEntry> ComponentLotFilter { get; set; } = new List<ComponentLotFilterEntry>();
/// <summary>
/// Whether or not component lot filter is enabled
/// </summary>
public bool ComponentLotFilterEnabled => ComponentLotFilter != null && ComponentLotFilter.Any();
/// <summary>
/// List of part/operation combinations for MIS filtering
/// </summary>
public List<ItemOperationMisFilterEntry> ItemOperationMisFilter { get; set; } = new List<ItemOperationMisFilterEntry>();
/// <summary>
/// Whether or not item/operation/mis filter is enabled
/// </summary>
public bool ItemOperationMisFilterEnabled => ItemOperationMisFilter != null && ItemOperationMisFilter.Any();
/// <summary>
/// Whether or not to extract MIS data
/// </summary>
public bool ExtractMisData { get; set; }
/// <summary>
/// Work order search results
/// </summary>
public List<SearchResult> Results { get; set; } = new List<SearchResult>();
/// <summary>
/// MIS results
/// </summary>
public List<MisSearchResult> MisResults { get; set; } = new List<MisSearchResult>();
/// <summary>
/// MIS no match found results
/// </summary>
public List<MisNonMatchSearchResult> MisNonMatchResults { get; set; } = new List<MisNonMatchSearchResult>();
}
}
+180
View File
@@ -0,0 +1,180 @@
using System;
namespace WorkerService.Models.Reporting
{
/// <summary>
/// JDE search result reporting model
/// </summary>
[OutputTable(TabName = "Search Results", TableName = "Search_Results")]
public class SearchResult
{
/// <summary>
/// Order unique number
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Work Order Number")]
public long WorkOrderNumber { get; set; }
/// <summary>
/// Order branch code
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Work Order Branch Code")]
public string WorkOrderBranchCode { get; set; }
/// <summary>
/// Order lot number
/// </summary>
[OutputColumn(Order = 30, HeaderText = "Lot Number")]
public string LotNumber { get; set; }
/// <summary>
/// Order item number
/// </summary>
[OutputColumn(Order = 40, HeaderText = "Item Number")]
public string ItemNumber { get; set; }
/// <summary>
/// Item master planning family
/// </summary>
[OutputColumn(Order = 50, HeaderText = "Planning Family")]
public string PlanningFamily { get; set; }
/// <summary>
/// Item master stocking type
/// </summary>
[OutputColumn(Order = 55, HeaderText = "Stocking Type")]
public string StockingType { get; set; }
/// <summary>
/// Order quantity
/// </summary>
[OutputColumn(Order = 60, HeaderText = "Order Quantity")]
public decimal OrderQuantity { get; set; }
/// <summary>
/// Quantity on hold
/// </summary>
[OutputColumn(Order = 70, HeaderText = "Held Quantity")]
public decimal HeldQuantity { get; set; }
/// <summary>
/// Quantity scrapped/cancelled
/// </summary>
[OutputColumn(Order = 80, HeaderText = "Scrapped Quantity")]
public decimal ScrappedQuantity { get; set; }
/// <summary>
/// Quantity shipped
/// </summary>
[OutputColumn(Order = 90, HeaderText = "Shipped Quantity")]
public decimal ShippedQuantity { get; set; }
/// <summary>
/// Operation branch code
/// </summary>
[OutputColumn(Order = 100, HeaderText = "Operation Step Branch Code")]
public string StepBranchCode { get; set; }
/// <summary>
/// Operation step number
/// </summary>
[OutputColumn(Order = 110, HeaderText = "Operation Step")]
public decimal StepNumber { get; set; }
/// <summary>
/// Operation step description
/// </summary>
[OutputColumn(Order = 120, HeaderText = "Operation Step Description")]
public string StepDescription { get; set; }
/// <summary>
/// Function operation description (long text)
/// </summary>
[OutputColumn(Order = 130, HeaderText = "Function Operation Description")]
public string FunctionOperationDescription { get; set; }
/// <summary>
/// Timestamp of last update to operation step number
/// </summary>
[OutputColumn(Order = 140, HeaderText = "Operation Step Update Timestamp", Format = OutputColumnAttribute.TIMESTAMP_FORMAT)]
public DateTime StepUpdateDT { get; set; }
/// <summary>
/// Order status code
/// </summary>
[OutputColumn(Order = 150, HeaderText = "Status Code")]
public string StatusCode { get; set; }
/// <summary>
/// Order status description
/// </summary>
[OutputColumn(Order = 160, HeaderText = "Status Description")]
public string StatusDescription { get; set; }
/// <summary>
/// Timestam of last update to order status
/// </summary>
[OutputColumn(Order = 170, HeaderText = "Status Update Timestamp", Format = OutputColumnAttribute.DATE_FORMAT)]
public DateTime? StatusUpdateDT { get; set; }
/// <summary>
/// Work order was included because it was manually specified
/// </summary>
public bool ManuallySpecified { get; set; }
/// <summary>
/// Work order was included because it was split from a from flagged work order
/// </summary>
public bool SplitOrder { get; set; }
/// <summary>
/// Work order was included because it received parts from a flagged work order (CARDEX / F4111)
/// </summary>
public bool CARDEX { get; set; }
/// <summary>
/// Work order was included because it received parts from a flagged work order (parts list / F3111)
/// </summary>
public bool PartsList { get; set; }
/// <summary>
/// Work order was included because it met the filter criteria
/// </summary>
public bool Flagged { get; set; }
/// <summary>
/// Reason work order was included in results
/// </summary>
[OutputColumn(Order = 180, HeaderText = "Inclusion Reason")]
public string InclusionReason
{
get
{
if (ManuallySpecified)
{
return "ManuallySpecified";
}
if (Flagged)
{
return "Flagged";
}
if (CARDEX && PartsList)
{
return "ComponentUsage (CARDEX + Parts List)";
}
if (CARDEX && !PartsList)
{
return "ComponentUsage (CARDEX)";
}
if (!CARDEX && PartsList)
{
return "ComponentUsage (Parts List)";
}
if (SplitOrder)
{
return "Split order";
}
return "UNKNOWN";
}
}
}
}
+23
View File
@@ -0,0 +1,23 @@
using System;
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Timespan search filter
/// </summary>
[OutputTable(TabName = "Timespan Filter", ShowHeader = true, TableName = "Timespan_Filter")]
public class TimespanFilter
{
/// <summary>
/// Minimum date for timespan search filter
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Minimum Date", Format = OutputColumnAttribute.DATE_FORMAT)]
public DateTime? MinimumDT { get; set; }
/// <summary>
/// Maximum date for timespan search filter
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Maximum Date", Format = OutputColumnAttribute.DATE_FORMAT)]
public DateTime? MaximumDT { get; set; }
}
}
@@ -0,0 +1,21 @@
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Work center search filter entry
/// </summary>
[OutputTable(TabName = "Work Center Filter", ShowHeader = true, TableName = "Work_Center_Filter")]
public class WorkCenterFilterEntry
{
/// <summary>
/// Work center code
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Work Center")]
public string Code { get; set; }
/// <summary>
/// Work center description
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Description")]
public string Description { get; set; }
}
}
+21
View File
@@ -0,0 +1,21 @@
namespace WorkerService.Models.Reporting
{
/// <summary>
/// Work order search filter entry
/// </summary>
[OutputTable(TabName = "Work Order Filter", ShowHeader = true, TableName = "Work_Order_Filter")]
public class WorkOrderFilterEntry
{
/// <summary>
/// Work order number
/// </summary>
[OutputColumn(Order = 10, HeaderText = "Work Order Number")]
public long WorkOrderNumber { get; set; }
/// <summary>
/// Work order item number
/// </summary>
[OutputColumn(Order = 20, HeaderText = "Item Number")]
public string ItemNumber { get; set; }
}
}
+44
View File
@@ -0,0 +1,44 @@
using System.Collections.Generic;
namespace WorkerService.Models
{
/// <summary>
/// Database table specification
/// </summary>
public class TableSpec
{
/// <summary>
/// Table name
/// </summary>
public string Name { get; set; }
/// <summary>
/// Data staging table name
/// </summary>
public string StagingTableName => $"#Staging{Name}";
/// <summary>
/// Temporary table name
/// </summary>
public string TempTableName => $"#{Name}";
/// <summary>
/// Table columns
/// </summary>
public List<ColumnSpec> Columns { get; set; }
/// <summary>
/// Table columns that form the primary key
/// </summary>
public List<ColumnSpec> PrimaryKey { get; set; }
/// <summary>
/// Constructor
/// </summary>
public TableSpec()
{
Columns = new List<ColumnSpec>();
PrimaryKey = new List<ColumnSpec>();
}
}
}