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:
Executable
+18
@@ -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; }
|
||||
}
|
||||
}
|
||||
Executable
+40
@@ -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; }
|
||||
}
|
||||
}
|
||||
Executable
+60
@@ -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; }
|
||||
}
|
||||
}
|
||||
Executable
+28
@@ -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; }
|
||||
}
|
||||
}
|
||||
Executable
+26
@@ -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; }
|
||||
}
|
||||
}
|
||||
Executable
+28
@@ -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; }
|
||||
}
|
||||
}
|
||||
Executable
+30
@@ -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
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
Executable
+44
@@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user