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:
@@ -0,0 +1,43 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using JdeScoping.Core.Interfaces;
|
||||
using JdeScoping.Core.Models;
|
||||
using JdeScoping.Core.Models.Quality;
|
||||
using JdeScoping.Core.Options;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace JdeScoping.Infrastructure.Sources.Cms;
|
||||
|
||||
/// <summary>
|
||||
/// File-based CMS data source for development/testing.
|
||||
/// </summary>
|
||||
public class CmsFileDataSource : ICmsDataSource
|
||||
{
|
||||
private readonly string _dataDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CmsFileDataSource"/> class.
|
||||
/// </summary>
|
||||
public CmsFileDataSource(IOptions<DataSourceOptions> options)
|
||||
{
|
||||
_dataDirectory = options.Value.FileDirectory;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<MisData> GetMisDataAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var filePath = Path.Combine(_dataDirectory, "misdata.json");
|
||||
if (!File.Exists(filePath))
|
||||
yield break;
|
||||
|
||||
var json = await File.ReadAllTextAsync(filePath, cancellationToken);
|
||||
var items = JsonSerializer.Deserialize<List<MisData>>(json) ?? [];
|
||||
|
||||
foreach (var item in items.Where(m => !minimumDt.HasValue || (m.ReleaseDate.HasValue && m.ReleaseDate.Value >= minimumDt)))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using Dapper;
|
||||
using JdeScoping.Core.Interfaces;
|
||||
using JdeScoping.Core.Models;
|
||||
using JdeScoping.Core.Models.Quality;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Oracle.ManagedDataAccess.Client;
|
||||
|
||||
namespace JdeScoping.Infrastructure.Sources.Cms;
|
||||
|
||||
/// <summary>
|
||||
/// Oracle-based CMS data source for production use.
|
||||
/// </summary>
|
||||
public class CmsOracleDataSource : ICmsDataSource
|
||||
{
|
||||
private readonly string _connectionString;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CmsOracleDataSource"/> class.
|
||||
/// </summary>
|
||||
public CmsOracleDataSource(IConfiguration configuration)
|
||||
{
|
||||
_connectionString = configuration.GetConnectionString("CMS")
|
||||
?? throw new InvalidOperationException("CMS connection string not configured");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<MisData> GetMisDataAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new OracleConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
// TODO: Implement actual CMS query for MIS data
|
||||
var sql = minimumDt.HasValue
|
||||
? "SELECT * FROM MISDATA WHERE RELEASE_DATE >= :MinDate"
|
||||
: "SELECT * FROM MISDATA";
|
||||
|
||||
var results = await connection.QueryAsync<MisData>(sql, new { MinDate = minimumDt });
|
||||
foreach (var item in results)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using JdeScoping.Core.Interfaces;
|
||||
using JdeScoping.Core.Models;
|
||||
using JdeScoping.Core.Models.Inventory;
|
||||
using JdeScoping.Core.Models.Organization;
|
||||
using JdeScoping.Core.Models.WorkOrders;
|
||||
using JdeScoping.Core.Options;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace JdeScoping.Infrastructure.Sources.Jde;
|
||||
|
||||
/// <summary>
|
||||
/// File-based JDE data source for development/testing.
|
||||
/// </summary>
|
||||
public class JdeFileDataSource : IJdeDataSource
|
||||
{
|
||||
private readonly string _dataDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JdeFileDataSource"/> class.
|
||||
/// </summary>
|
||||
public JdeFileDataSource(IOptions<DataSourceOptions> options)
|
||||
{
|
||||
_dataDirectory = options.Value.FileDirectory;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<WorkOrder> GetWorkOrdersAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var items = await LoadFromFileAsync<WorkOrder>("workorders.json", cancellationToken);
|
||||
foreach (var item in items.Where(wo => !minimumDt.HasValue || (wo.LastUpdateDt.HasValue && wo.LastUpdateDt.Value >= minimumDt)))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<LotUsage> GetLotUsagesAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var items = await LoadFromFileAsync<LotUsage>("lotusages.json", cancellationToken);
|
||||
foreach (var item in items.Where(lu => !minimumDt.HasValue || (lu.LastUpdateDt.HasValue && lu.LastUpdateDt.Value >= minimumDt)))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<Lot> GetLotsAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var items = await LoadFromFileAsync<Lot>("lots.json", cancellationToken);
|
||||
foreach (var item in items.Where(l => !minimumDt.HasValue || (l.LastUpdateDt.HasValue && l.LastUpdateDt.Value >= minimumDt)))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<Item> GetItemsAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var items = await LoadFromFileAsync<Item>("items.json", cancellationToken);
|
||||
foreach (var item in items.Where(i => !minimumDt.HasValue || (i.LastUpdateDt.HasValue && i.LastUpdateDt.Value >= minimumDt)))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<WorkCenter> GetWorkCentersAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var items = await LoadFromFileAsync<WorkCenter>("workcenters.json", cancellationToken);
|
||||
foreach (var item in items.Where(wc => !minimumDt.HasValue || (wc.LastUpdateDt.HasValue && wc.LastUpdateDt.Value >= minimumDt)))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<ProfitCenter> GetProfitCentersAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var items = await LoadFromFileAsync<ProfitCenter>("profitcenters.json", cancellationToken);
|
||||
foreach (var item in items.Where(pc => !minimumDt.HasValue || (pc.LastUpdateDt.HasValue && pc.LastUpdateDt.Value >= minimumDt)))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<JdeUser> GetUsersAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var items = await LoadFromFileAsync<JdeUser>("users.json", cancellationToken);
|
||||
foreach (var item in items.Where(u => !minimumDt.HasValue || (u.LastUpdateDt.HasValue && u.LastUpdateDt.Value >= minimumDt)))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<Branch> GetBranchesAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
var items = await LoadFromFileAsync<Branch>("branches.json", cancellationToken);
|
||||
foreach (var item in items)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<T>> LoadFromFileAsync<T>(string fileName, CancellationToken cancellationToken)
|
||||
{
|
||||
var filePath = Path.Combine(_dataDirectory, fileName);
|
||||
if (!File.Exists(filePath))
|
||||
return [];
|
||||
|
||||
var json = await File.ReadAllTextAsync(filePath, cancellationToken);
|
||||
return JsonSerializer.Deserialize<List<T>>(json) ?? [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using Dapper;
|
||||
using JdeScoping.Core.Interfaces;
|
||||
using JdeScoping.Core.Models;
|
||||
using JdeScoping.Core.Models.Inventory;
|
||||
using JdeScoping.Core.Models.Organization;
|
||||
using JdeScoping.Core.Models.WorkOrders;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Oracle.ManagedDataAccess.Client;
|
||||
|
||||
namespace JdeScoping.Infrastructure.Sources.Jde;
|
||||
|
||||
/// <summary>
|
||||
/// Oracle-based JDE data source for production use.
|
||||
/// </summary>
|
||||
public class JdeOracleDataSource : IJdeDataSource
|
||||
{
|
||||
private readonly string _connectionString;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JdeOracleDataSource"/> class.
|
||||
/// </summary>
|
||||
public JdeOracleDataSource(IConfiguration configuration)
|
||||
{
|
||||
_connectionString = configuration.GetConnectionString("JDE")
|
||||
?? throw new InvalidOperationException("JDE connection string not configured");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<WorkOrder> GetWorkOrdersAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new OracleConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
// TODO: Implement actual JDE query with proper column mapping
|
||||
var sql = minimumDt.HasValue
|
||||
? "SELECT * FROM F4801 WHERE UPMJ >= :MinDate"
|
||||
: "SELECT * FROM F4801";
|
||||
|
||||
var results = await connection.QueryAsync<WorkOrder>(sql, new { MinDate = minimumDt });
|
||||
foreach (var item in results)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<LotUsage> GetLotUsagesAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new OracleConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
// TODO: Implement actual JDE query
|
||||
var sql = minimumDt.HasValue
|
||||
? "SELECT * FROM F4111 WHERE UPMJ >= :MinDate"
|
||||
: "SELECT * FROM F4111";
|
||||
|
||||
var results = await connection.QueryAsync<LotUsage>(sql, new { MinDate = minimumDt });
|
||||
foreach (var item in results)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<Lot> GetLotsAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new OracleConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
var sql = minimumDt.HasValue
|
||||
? "SELECT * FROM F4108 WHERE UPMJ >= :MinDate"
|
||||
: "SELECT * FROM F4108";
|
||||
|
||||
var results = await connection.QueryAsync<Lot>(sql, new { MinDate = minimumDt });
|
||||
foreach (var item in results)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<Item> GetItemsAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new OracleConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
var sql = minimumDt.HasValue
|
||||
? "SELECT * FROM F4101 WHERE UPMJ >= :MinDate"
|
||||
: "SELECT * FROM F4101";
|
||||
|
||||
var results = await connection.QueryAsync<Item>(sql, new { MinDate = minimumDt });
|
||||
foreach (var item in results)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<WorkCenter> GetWorkCentersAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new OracleConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
var sql = minimumDt.HasValue
|
||||
? "SELECT * FROM F30006 WHERE UPMJ >= :MinDate"
|
||||
: "SELECT * FROM F30006";
|
||||
|
||||
var results = await connection.QueryAsync<WorkCenter>(sql, new { MinDate = minimumDt });
|
||||
foreach (var item in results)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<ProfitCenter> GetProfitCentersAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new OracleConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
// TODO: Implement actual query for profit centers
|
||||
var sql = "SELECT * FROM F0006";
|
||||
|
||||
var results = await connection.QueryAsync<ProfitCenter>(sql);
|
||||
foreach (var item in results)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<JdeUser> GetUsersAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new OracleConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
var sql = minimumDt.HasValue
|
||||
? "SELECT * FROM F0092 WHERE UPMJ >= :MinDate"
|
||||
: "SELECT * FROM F0092";
|
||||
|
||||
var results = await connection.QueryAsync<JdeUser>(sql, new { MinDate = minimumDt });
|
||||
foreach (var item in results)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async IAsyncEnumerable<Branch> GetBranchesAsync(
|
||||
DateTime? minimumDt = null,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new OracleConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
// TODO: Implement actual query for branches
|
||||
var sql = "SELECT * FROM F0101";
|
||||
|
||||
var results = await connection.QueryAsync<Branch>(sql);
|
||||
foreach (var item in results)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user