Compare commits

..

2 Commits

Author SHA1 Message Date
37f6a68cd9 WinForms and Console 2024-03-14 15:30:40 -07:00
127634f5ab Delete self contained Thunder Tests
Back to .net8.0
api/v4/InfinityQS
ApiExplorerSettings
Wafer Counter
Color Sorting
2024-03-13 13:15:56 -07:00
1836 changed files with 3122 additions and 5491 deletions

View File

@ -101,7 +101,6 @@ dotnet_diagnostic.CA1860.severity = error # CA1860: Prefer comparing 'Count' to
dotnet_diagnostic.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase' dotnet_diagnostic.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'
dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead.
dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template should not vary between calls to 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])' dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template should not vary between calls to 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])'
dotnet_diagnostic.CS8936.severity = error # Feature 'collection expressions' is not available in C# 10.0. Please use language version 12.0 or greater.
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name
dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2"); dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2");
dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant. dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant.

4
.gitignore vendored
View File

@ -343,6 +343,4 @@ ASALocalRun/
/wwwroot/lib/* /wwwroot/lib/*
.kanbn .kanbn
Tests/.kanbn Tests/.kanbn
/Wafer-Counter/.vscode/.UserSecrets/secrets.json

6
.vscode/tasks.json vendored
View File

@ -217,6 +217,12 @@
"endsPattern": "^.*Application started.*" "endsPattern": "^.*Application started.*"
} }
} }
},
{
"label": "File-Folder-Helper AOT s M Self .Kanbn Tasks",
"type": "shell",
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s M '.kanbn/tasks'",
"problemMatcher": []
} }
] ]
} }

View File

@ -29,23 +29,6 @@ public class AppSettings
return result; return result;
} }
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
{
if (appSettings?.ApiLoggingContentTypes is null)
{
List<string> paths = [];
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
{
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
continue;
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
continue;
paths.Add(physicalFileProvider.Root);
}
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
}
}
private static Models.AppSettings Get(AppSettings? appSettings) private static Models.AppSettings Get(AppSettings? appSettings)
{ {
Models.AppSettings result; Models.AppSettings result;
@ -90,7 +73,20 @@ public class AppSettings
#pragma warning disable IL3050, IL2026 #pragma warning disable IL3050, IL2026
AppSettings? appSettings = configurationRoot.Get<AppSettings>(); AppSettings? appSettings = configurationRoot.Get<AppSettings>();
#pragma warning restore IL3050, IL2026 #pragma warning restore IL3050, IL2026
PreVerify(configurationRoot, appSettings); if (appSettings?.ApiLoggingContentTypes is null)
{
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
{
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
continue;
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
continue;
if (!physicalFileProvider.Root.Contains("UserSecrets"))
continue;
throw new NotSupportedException(physicalFileProvider.Root);
}
throw new NotSupportedException("Not found!");
}
result = Get(appSettings); result = Get(appSettings);
return result; return result;
} }

30
Console/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,30 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/OI.Metrology.Console.dll",
"args": [
"s",
"M",
"L:/Git/Notes-EC-Documentation/.EC-Documentation",
"-s",
"L:/Git/Notes-EC-Documentation/.EC-Documentation/port"
],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

4
Console/.vscode/mklink.md vendored Normal file
View File

@ -0,0 +1,4 @@
# mklink
```bash
```

37
Console/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,37 @@
{
"[markdown]": {
"editor.wordWrap": "off"
},
"files.exclude": {
"**/.git": false,
"**/node_modules": true
},
"files.watcherExclude": {
"**/node_modules": true
},
"cSpell.words": [
"ASPNETCORE",
"BIRT",
"CHIL",
"DEAT",
"endianness",
"FAMC",
"FAMS",
"GIVN",
"HUSB",
"INDI",
"Infineon",
"Kanban",
"kanbn",
"Kofax",
"NSFX",
"OBJE",
"onenote",
"pged",
"Phares",
"Serilog",
"SUBM",
"SURN",
"SYSLIB"
]
}

99
Console/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,99 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "User Secrets Init",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/OI.Metrology.Console.csproj",
"init"
],
"problemMatcher": "$msCompile"
},
{
"label": "User Secrets Set",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/OI.Metrology.Console.csproj",
"set",
"asdf",
"123"
],
"problemMatcher": "$msCompile"
},
{
"label": "Format",
"command": "dotnet",
"type": "process",
"args": [
"format",
"--report",
".vscode",
"--verbosity",
"detailed",
"--severity",
"warn"
],
"problemMatcher": "$msCompile"
},
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/OI.Metrology.Console.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/OI.Metrology.Console.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/OI.Metrology.Console.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "Publish AOT",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"-r",
"win-x64",
"-c",
"Release",
"-p:PublishAot=true",
"${workspaceFolder}/OI.Metrology.Console.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -0,0 +1,21 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace OI.Metrology.Console.Models;
public record AppSettings(string Company)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(AppSettings))]
internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,61 @@
using Microsoft.Extensions.Configuration;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace OI.Metrology.Console.Models.Binder;
public class AppSettings
{
public string? Company { get; set; }
public override string ToString()
{
string result = JsonSerializer.Serialize(this, BinderAppSettingsSourceGenerationContext.Default.AppSettings);
return result;
}
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
{
if (appSettings?.Company is null)
{
List<string> paths = [];
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
{
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
continue;
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
continue;
paths.Add(physicalFileProvider.Root);
}
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
}
}
private static Models.AppSettings Get(AppSettings? appSettings)
{
Models.AppSettings result;
if (appSettings is null) throw new NullReferenceException(nameof(appSettings));
if (appSettings.Company is null) throw new NullReferenceException(nameof(Company));
result = new(appSettings.Company);
return result;
}
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
{
Models.AppSettings result;
#pragma warning disable IL3050, IL2026
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
#pragma warning restore IL3050, IL2026
PreVerify(configurationRoot, appSettings);
result = Get(appSettings);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(AppSettings))]
internal partial class BinderAppSettingsSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,50 @@
namespace OI.Metrology.Console.Models;
internal abstract class WorkingDirectory
{
internal static string GetWorkingDirectory(string? executingAssemblyName, string subDirectoryName)
{
string result = string.Empty;
if (executingAssemblyName is null)
throw new Exception();
string traceFile;
List<string> directories = [];
Environment.SpecialFolder[] specialFolders =
[
Environment.SpecialFolder.LocalApplicationData,
Environment.SpecialFolder.ApplicationData,
Environment.SpecialFolder.History,
Environment.SpecialFolder.CommonApplicationData,
Environment.SpecialFolder.InternetCache
];
foreach (Environment.SpecialFolder specialFolder in specialFolders)
directories.Add(Path.Combine(Environment.GetFolderPath(specialFolder), subDirectoryName, executingAssemblyName));
foreach (string directory in directories)
{
for (int i = 1; i < 3; i++)
{
if (i == 1)
result = directory;
else
result = string.Concat("D", directory[1..]);
try
{
if (!Directory.Exists(result))
_ = Directory.CreateDirectory(result);
traceFile = string.Concat(result, @"\", DateTime.Now.Ticks, ".txt");
File.WriteAllText(traceFile, traceFile);
File.Delete(traceFile);
break;
}
catch (Exception) { result = string.Empty; }
}
if (!string.IsNullOrEmpty(result))
break;
}
if (string.IsNullOrEmpty(result))
throw new Exception("Unable to set working directory!");
return result;
}
}

View File

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>d9488860-fd41-4dd8-9448-19f1dde7a0f7</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.3" />
<PackageReference Include="System.Text.Json" Version="8.0.3" />
</ItemGroup>
</Project>

29
Console/Program.cs Normal file
View File

@ -0,0 +1,29 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OI.Metrology.Console.Models;
namespace OI.Metrology.Console;
internal class Program
{
public static void Main(string[] args)
{
#pragma warning disable IL3050
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
#pragma warning restore IL3050
_ = builder.Configuration.AddEnvironmentVariables();
_ = builder.Configuration.AddUserSecrets<Program>();
_ = builder.Services.AddSingleton(args.ToList());
AppSettings appSettings = Models.Binder.AppSettings.Get(builder.Configuration);
_ = builder.Services.AddSingleton(appSettings);
_ = builder.Services.AddHostedService<Worker>();
using IHost host = builder.Build();
ILogger<Program> logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogCritical("{appSettings.Company}", appSettings.Company);
host.Run();
}
}

67
Console/Worker.cs Normal file
View File

@ -0,0 +1,67 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OI.Metrology.Console.Models;
using System.Diagnostics;
namespace OI.Metrology.Console;
public class Worker : BackgroundService
{
private readonly List<string> _Args;
private readonly ILogger<Worker> _Logger;
private readonly AppSettings _AppSettings;
private readonly IHostApplicationLifetime _Lifetime;
public Worker(ILogger<Worker> logger, IHostApplicationLifetime lifetime, List<string> args, AppSettings appSettings)
{
_Args = args;
_Logger = logger;
_Lifetime = lifetime;
_AppSettings = appSettings;
}
public override Task StartAsync(CancellationToken cancellationToken) =>
base.StartAsync(cancellationToken);
public override Task StopAsync(CancellationToken cancellationToken) =>
base.StopAsync(cancellationToken);
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (!stoppingToken.IsCancellationRequested)
await Task.Delay(500, stoppingToken);
if (_AppSettings is null)
throw new NullReferenceException(nameof(_AppSettings));
try
{
_Logger.LogInformation("BaseDirectory: <{BaseDirectory}>", AppContext.BaseDirectory);
_Logger.LogInformation("CurrentDirectory: <{CurrentDirectory}>", Environment.CurrentDirectory);
_Logger.LogInformation("Press Escape key to get -1, Enter key to get 0, y key to get 1 and n key to get 2 exit code");
ConsoleKeyInfo consoleKeyInfo = System.Console.ReadKey();
if (consoleKeyInfo.Key == ConsoleKey.W)
{
Process process = Process.Start("L:/DevOps/Mesa_FI/OI-Metrology/WinForms/bin/Debug/net8.0-windows/win-x64/OI.Metrology.WinForms.exe", "Mike");
process.WaitForExit();
_Logger.LogInformation("ExitCode: <{ExitCode}>", process.ExitCode);
}
else
{
Environment.ExitCode = consoleKeyInfo.Key switch
{
ConsoleKey.Escape => -1,
ConsoleKey.Enter => 0,
ConsoleKey.Y => 1,
ConsoleKey.N => 2,
_ => 9
};
}
}
catch (Exception ex)
{ _Logger.LogError("{Message}{NewLine}{StackTrace}", ex.Message, Environment.NewLine, ex.StackTrace); }
_Logger.LogInformation("Done. Press 'Enter' to end");
_ = System.Console.ReadLine();
_Lifetime.StopApplication();
}
}

3
Console/secrets.json Normal file
View File

@ -0,0 +1,3 @@
{
"Company": "Infineon Technologies Americas Corp."
}

View File

@ -13,44 +13,6 @@
], ],
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },
{
"label": "buildTests",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/../Tests/OI.Metrology.Tests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "testDebug",
"command": "dotnet",
"type": "process",
"args": [
"test",
"${workspaceFolder}/../Tests/OI.Metrology.Tests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "testRelease",
"command": "dotnet",
"type": "process",
"args": [
"test",
"${workspaceFolder}/../Tests/OI.Metrology.Tests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"-c",
"Release"
],
"problemMatcher": "$msCompile"
},
{ {
"label": "Format", "label": "Format",
"command": "dotnet", "command": "dotnet",
@ -66,16 +28,6 @@
], ],
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },
{
"label": "Format-Whitespace",
"command": "dotnet",
"type": "process",
"args": [
"format",
"whitespace"
],
"problemMatcher": "$msCompile"
},
{ {
"label": "publish", "label": "publish",
"command": "dotnet", "command": "dotnet",
@ -84,32 +36,7 @@
"publish", "publish",
"${workspaceFolder}/OI.Metrology.Server.csproj", "${workspaceFolder}/OI.Metrology.Server.csproj",
"/property:GenerateFullPaths=true", "/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary", "/consoleloggerparameters:NoSummary"
"--configuration",
"Release",
"--runtime",
"win-x64",
"--self-contained",
"-o",
"D:/web-sites/OI-Metrology/hh-3498d1da-_______-OI-Metrology-Release/Server"
],
"problemMatcher": "$msCompile"
},
{
"label": "Publish AOT",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/OI.Metrology.Server.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"--configuration",
"Release",
"--runtime",
"win-x64",
"-p:PublishAot=true",
"/property:GenerateFullPaths=true"
], ],
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },
@ -160,14 +87,9 @@
} }
}, },
{ {
"label": "File-Folder-Helper AOT s X Server", "label": "File-Folder-Helper AOT s V Repositories",
"type": "shell", "type": "shell",
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe", "command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s V Repositories",
"args": [
"s",
"X",
"L:/DevOps/Mesa_FI/OI-Metrology Day-Helper-2024-01-08 L:/DevOps/Mesa_FI/OI-Metrology/Server"
],
"problemMatcher": [] "problemMatcher": []
} }
] ]

View File

@ -38,10 +38,4 @@ public class AwaitingDispoController : Controller, IAwaitingDispoController<IAct
else else
return StatusCode(444); return StatusCode(444);
} }
// this endpoint is used to clear the ReviewDate column, causing the header to show up again
[HttpGet("/api/awaitingdispo/{toolTypeId}/header-attachment-id")]
public IActionResult GetHeaderAttachmentID(int toolTypeId, [FromQuery] long headerid) =>
Content(_MetrologyRepository.GetHeaderAttachmentID(toolTypeId, headerid).ToString());
} }

View File

@ -4,7 +4,6 @@ namespace OI.Metrology.Server.ApiControllers;
using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using System.Data;
using System.Text.Json; using System.Text.Json;
[Route("api/[controller]")] [Route("api/[controller]")]
@ -12,13 +11,9 @@ public class ExportController : Controller, IExportController<IActionResult>
{ {
private readonly IExportRepository _ExportRepository; private readonly IExportRepository _ExportRepository;
private readonly IMetrologyRepository _MetrologyRepository;
public ExportController(IExportRepository exportRepository, IMetrologyRepository metrologyRepository) public ExportController(IExportRepository exportRepository) =>
{
_ExportRepository = exportRepository; _ExportRepository = exportRepository;
_MetrologyRepository = metrologyRepository;
}
private static string? GetJson(Stream stream) private static string? GetJson(Stream stream)
{ {
@ -84,21 +79,4 @@ public class ExportController : Controller, IExportController<IActionResult>
public IActionResult PostProcessDataStandardFormat() => public IActionResult PostProcessDataStandardFormat() =>
Content(_ExportRepository.GetProcessDataStandardFormat(GetHeaderCommon(Request.Body))); Content(_ExportRepository.GetProcessDataStandardFormat(GetHeaderCommon(Request.Body)));
[HttpGet]
[Route("{toolTypeId}/export")]
public IActionResult GetExportData(int toolTypeId, [FromQuery] string? datebegin, [FromQuery] string? dateend)
{
Result<DataTable> r = _ExportRepository.GetExportData(_MetrologyRepository, toolTypeId, datebegin, dateend);
string json = Newtonsoft.Json.JsonConvert.SerializeObject(r);
return Content(json);
}
[HttpGet]
[Route("{toolTypeId}/csv")]
public IActionResult GetCSVExport(int toolTypeId, [FromQuery] string? datebegin, [FromQuery] string? dateend, [FromQuery] string? filename)
{
string r = _ExportRepository.GetCSVExport(_MetrologyRepository, toolTypeId, datebegin, dateend);
return Content(r);
}
} }

View File

@ -1,36 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using OI.Metrology.Shared.Models.Stateless;
namespace OI.Metrology.Server.ApiControllers;
[Route("api/v1/file-share")]
public class FileShareController : Controller, IFileShareController<IResult>
{
private readonly IFileShareRepository _FileShareRepository;
public FileShareController(IFileShareRepository fileShareRepository) =>
_FileShareRepository = fileShareRepository;
[HttpGet("copy-file")]
public IResult CopyFile(string from, string to)
{
_FileShareRepository.CopyFile(from, to);
return Results.Ok();
}
[HttpGet("move-file")]
public IResult MoveFile(string from, string to)
{
_FileShareRepository.MoveFile(from, to);
return Results.Ok();
}
[HttpGet("file-write")]
public IResult FileWrite(string path, string contents)
{
_FileShareRepository.FileWrite(path, contents);
return Results.Ok();
}
}

View File

@ -4,7 +4,6 @@ using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Services; using OI.Metrology.Shared.Services;
using System.Net; using System.Net;
using System.Text.Json;
namespace OI.Metrology.Server.ApiControllers; namespace OI.Metrology.Server.ApiControllers;
@ -30,9 +29,22 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
_MetrologyRepository = metrologyRepository; _MetrologyRepository = metrologyRepository;
} }
private static string? GetJson(Stream stream)
{
string? result;
if (!stream.CanRead)
result = null;
else
{
Task<string> task = new StreamReader(stream).ReadToEndAsync();
result = task.Result;
}
return result;
}
[HttpPost] [HttpPost]
[Route("{tooltype}")] [Route("{tooltype}")]
public IActionResult Post(string tooltype, JsonElement? jsonElement) public IActionResult Post(string tooltype)
{ {
IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress; IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress;
if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP)) if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP))
@ -42,7 +54,8 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
} }
else else
{ {
DataResponse dataResponse = _InboundRepository.Data(_MetrologyRepository, _InboundDataService, tooltype, jsonElement); string? json = GetJson(Request.Body);
DataResponse dataResponse = _InboundRepository.Data(_MetrologyRepository, _InboundDataService, tooltype, json);
if (dataResponse.Errors.Count == 0) if (dataResponse.Errors.Count == 0)
return Ok(dataResponse); return Ok(dataResponse);
else else
@ -52,7 +65,7 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
[HttpPost] [HttpPost]
[Route("{tooltype}/attachment")] [Route("{tooltype}/attachment")]
public IActionResult AttachFile(string tooltype, Attachment? attachment) public IActionResult AttachFile(string tooltype, [FromQuery] long headerid, [FromQuery] string datauniqueid = "")
{ {
IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress; IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress;
if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP)) if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP))
@ -62,8 +75,16 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
} }
else else
{ {
_InboundRepository.AttachFile(_MetrologyRepository, _AttachmentsService, tooltype, attachment); if (Request.Form is null)
return Ok(); return BadRequest($"Invalid form");
if (Request.Form.Files.Count != 1)
return BadRequest($"Invalid file count");
IFormFile formFile = Request.Form.Files[0];
string? message = _InboundRepository.AttachFile(_MetrologyRepository, _AttachmentsService, tooltype, headerid, datauniqueid, formFile.FileName, formFile);
if (message is null)
return Ok();
else
return BadRequest(message);
} }
} }

View File

@ -79,8 +79,12 @@ public class InfinityQSV4Controller : Controller, IInfinityQSV4Controller<IActio
public IActionResult GetProductionSpecification(string part) => public IActionResult GetProductionSpecification(string part) =>
Content(_InfinityQSRepositoryV4.GetProductionSpecification(part)); Content(_InfinityQSRepositoryV4.GetProductionSpecification(part));
[HttpGet("{process}/last-group-id-with-value")] [HttpGet("engineering-spc-review")]
public IActionResult GetLastGroupIdWithValue(string process, string? part, int? test) => public IActionResult GetEngineeringSpcReview()
Content(_InfinityQSRepositoryV4.GetLastGroupIdWithValue(process, part, test)); {
Dictionary<string, List<string>> results = _InfinityQSRepositoryV4.GetEngineeringSpcReview();
string json = JsonSerializer.Serialize(results);
return Content(json, "application/json", System.Text.Encoding.UTF8);
}
} }

View File

@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Mvc;
using OI.Metrology.Shared.Models.Stateless;
using System.Text.Json;
namespace OI.Metrology.Server.ApiControllers;
[Route("api/[controller]")]
public class ReactorsController : Controller, IReactorsController<IActionResult>
{
private readonly IReactorsRepository _ReactorsRepository;
public ReactorsController(IReactorsRepository reactorsRepository) =>
_ReactorsRepository = reactorsRepository;
[HttpGet("{even}")]
public IActionResult Get(bool even) =>
Json(even ? _ReactorsRepository.EvenReactors() : _ReactorsRepository.OddReactors(), new JsonSerializerOptions { PropertyNamingPolicy = null, WriteIndented = true });
[HttpPost()]
public IActionResult Post(Shared.DataModels.WorkMaterialOut workMaterialOut) =>
Ok(_ReactorsRepository.GetKey(workMaterialOut, save: true));
}

View File

@ -66,6 +66,23 @@ public class ToolTypesController : Controller, IToolTypesController<IActionResul
return Content(json); return Content(json);
} }
[HttpGet]
[Route("{toolTypeId}/export")]
public IActionResult GetExportData(int toolTypeId, [FromQuery] string? datebegin, [FromQuery] string? dateend)
{
Shared.DataModels.Result<DataTable> r = _ToolTypesRepository.GetExportData(_MetrologyRepo, toolTypeId, datebegin, dateend);
string json = JsonConvert.SerializeObject(r);
return Content(json);
}
[HttpGet]
[Route("{toolTypeId}/csv")]
public IActionResult GetCSVExport(int toolTypeId, [FromQuery] string? datebegin, [FromQuery] string? dateend, [FromQuery] string? filename)
{
byte[] r = _ToolTypesRepository.GetCSVExport(_MetrologyRepo, toolTypeId, datebegin, dateend);
return File(r, "application/octet-stream", filename);
}
[HttpGet] [HttpGet]
[Route("{toolTypeId}/{tabletype}/files/{attachmentId}/{filename}")] [Route("{toolTypeId}/{tabletype}/files/{attachmentId}/{filename}")]
public IActionResult GetAttachment(int toolTypeId, string tabletype, string attachmentId, string filename) public IActionResult GetAttachment(int toolTypeId, string tabletype, string attachmentId, string filename)
@ -83,7 +100,7 @@ public class ToolTypesController : Controller, IToolTypesController<IActionResul
[Route("{toolTypeId}/headers/{headerid}/oiexport")] [Route("{toolTypeId}/headers/{headerid}/oiexport")]
public IActionResult OIExport(int toolTypeId, long headerid) public IActionResult OIExport(int toolTypeId, long headerid)
{ {
string? message = _ToolTypesRepository.OIExport(_MetrologyRepo, _AttachmentsService, toolTypeId, headerid); string? message = _ToolTypesRepository.OIExport(_MetrologyRepo, _AttachmentsService, _AppSettings.AttachmentPath, _AppSettings.TableToPath, toolTypeId, headerid);
if (message is null) if (message is null)
return Ok(new { Message = "OK" }); return Ok(new { Message = "OK" });
else else

View File

@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Mvc;
using OI.Metrology.Shared.Models.Stateless;
namespace OI.Metrology.Server.ApiControllers;
[Route("api/v1/WaferCounter")]
public class WaferCounterController : Controller, IWaferCounterController<IActionResult>
{
private readonly IWaferCounterRepository _WaferCounterRepository;
public WaferCounterController(IWaferCounterRepository waferCounterRepository) =>
_WaferCounterRepository = waferCounterRepository;
[HttpGet("{waferSize}/last-quantity-and-slot-map")]
public IActionResult GetLastQuantityAndSlotMap(string area, string waferSize) =>
Json(_WaferCounterRepository.GetLastQuantityAndSlotMap(area, waferSize));
[HttpGet("{waferSize}/last-quantity-and-slot-map-with-text")]
public IActionResult GetLastQuantityAndSlotMapWithText(string area, string waferSize, string text) =>
Json(_WaferCounterRepository.GetLastQuantityAndSlotMapWithText(area, waferSize, text));
}

View File

@ -0,0 +1,160 @@
using Infineon.Monitoring.MonA;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.ViewModels;
using System.Text;
namespace OI.Metrology.Server.Controllers;
public class ExportController : Controller
{
private readonly ILogger _Logger;
private readonly AppSettings _AppSettings;
private readonly bool _IsTestDatabase;
private readonly IMetrologyRepository _MetrologyRepository;
public ExportController(AppSettings appSettings, ILogger<ExportController> logger, IMetrologyRepository metrologyRepository)
{
_Logger = logger;
_AppSettings = appSettings;
_MetrologyRepository = metrologyRepository;
_IsTestDatabase = appSettings.ConnectionString.Contains("test", StringComparison.InvariantCultureIgnoreCase);
}
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
ViewBag.IsTestDatabase = _IsTestDatabase;
}
private string GetApiUrl() => string.IsNullOrEmpty(_AppSettings.ApiUrl) ? Url.Content("~/") : _AppSettings.ApiUrl[0] == '~' ? Url.Content(_AppSettings.ApiUrl) : _AppSettings.ApiUrl;
[HttpGet]
[Route("/Export")]
public ActionResult Index()
{
Export model = new()
{
StartTime = DateTime.Now.AddMonths(-1),
EndTime = DateTime.Now
};
MonIn monIn = MonIn.GetInstance();
_ = monIn.SendStatus(_AppSettings.MonASite, _AppSettings.MonAResource, "Heartbeat", State.Up);
ViewBag.ApiUrl = GetApiUrl();
return View(model);
}
[HttpPost]
[Route("/ExportData")]
public ActionResult ExportData(Export model)
{
ToolType? toolType = null;
if (string.IsNullOrEmpty(model.ToolType))
ModelState.AddModelError("Exception", "Invalid selection");
else
{
if (model.StartTime > model.EndTime)
ModelState.AddModelError("EndTime", "End time must be after start time");
IEnumerable<ToolType> toolTypes = _MetrologyRepository.GetToolTypes();
toolType = toolTypes.Where(tt => tt.ID.ToString() == model.ToolType).SingleOrDefault();
if (toolType is null)
ModelState.AddModelError("ToolType", "Invalid selection");
else if (string.IsNullOrWhiteSpace(toolType.ExportSPName))
ModelState.AddModelError("ToolType", "Tool type is not exportable");
}
if (ModelState.IsValid)
{
try
{
DateTime startDT = model.StartDate.Date.Add(model.StartTime.TimeOfDay);
DateTime endDT = model.EndDate.Date.Add(model.EndTime.TimeOfDay);
return DoCSVExport(toolType?.ToolTypeName, toolType?.ExportSPName, startDT, endDT);
}
catch (Exception ex)
{
ModelState.AddModelError("Exception", "Error exporting data");
ModelState.AddModelError("Exception", ex.Message);
string errorMessage = $"Error exporting: {ex}";
_Logger.LogError(message: errorMessage);
MonIn monIn = MonIn.GetInstance();
_ = monIn.SendStatus(_AppSettings.MonASite, _AppSettings.MonAResource, "Heartbeat", State.Warning);
}
}
ViewBag.ApiUrl = GetApiUrl();
return View("Index", model);
}
protected ActionResult DoCSVExport(string? toolTypeName, string? spName, DateTime startTime, DateTime endTime)
{
string fileName = string.Format("Export_{0}_{1:yyyyMMddHHmm}_to_{2:yyyyMMddHHmm}.csv", toolTypeName, startTime, endTime);
StringBuilder sb = new();
if (spName is null)
throw new NullReferenceException(nameof(spName));
System.Data.DataTable dt = _MetrologyRepository.ExportData(spName, startTime, endTime);
_ = sb.AppendLine(GetColumnHeaders(dt));
foreach (System.Data.DataRow dr in dt.Rows)
_ = sb.AppendLine(GetRowData(dr));
byte[] contents = Encoding.UTF8.GetBytes(sb.ToString());
return File(contents, "application/octet-stream", fileName);
}
protected static string GetRowData(System.Data.DataRow dr)
{
StringBuilder r = new();
for (int i = 0; i < dr.Table.Columns.Count; i++)
{
if (i > 0)
_ = r.Append(',');
object v = dr[i];
if (!Convert.IsDBNull(v))
{
string? c = Convert.ToString(v);
if (c is not null)
_ = r.Append(FormatForCSV(c));
}
}
return r.ToString();
}
protected static string GetColumnHeaders(System.Data.DataTable dt)
{
StringBuilder r = new();
for (int i = 0; i < dt.Columns.Count; i++)
{
if (i > 0)
_ = r.Append(',');
_ = r.Append(FormatForCSV(dt.Columns[i].ColumnName.TrimEnd('_')));
}
return r.ToString();
}
protected static string FormatForCSV(string v)
{
bool doubleQuoted = false;
StringBuilder r = new(v.Length + 2);
if (v.StartsWith(' ') || v.EndsWith(' ') || v.Contains(',') || v.Contains('"'))
{
_ = r.Append('"');
doubleQuoted = true;
}
foreach (char c in v)
{
_ = c switch
{
'\r' or '\n' => r.Append(' '),
'"' => r.Append("\"\""),
_ => r.Append(c),
};
}
if (doubleQuoted)
_ = r.Append('"');
return r.ToString();
}
}

View File

@ -0,0 +1,79 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.ViewModels;
namespace OI.Metrology.Server.Controllers;
public class PagesController : Controller
{
private readonly bool _IsTestDatabase;
private readonly AppSettings _AppSettings;
private readonly IMetrologyRepository _MetrologyRepository;
public PagesController(AppSettings appSettings, IMetrologyRepository metrologyRepository)
{
_AppSettings = appSettings;
_MetrologyRepository = metrologyRepository;
_IsTestDatabase = appSettings.ConnectionString.Contains("test", StringComparison.InvariantCultureIgnoreCase);
}
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
ViewBag.IsTestDatabase = _IsTestDatabase;
}
private string GetApiUrl() => string.IsNullOrEmpty(_AppSettings.ApiUrl) ? Url.Content("~/") : _AppSettings.ApiUrl[0] == '~' ? Url.Content(_AppSettings.ApiUrl) : _AppSettings.ApiUrl;
[HttpGet]
[Route("/")]
public IActionResult Index()
{
ViewBag.ApiUrl = GetApiUrl();
return View("AwaitingDispo");
}
[HttpGet]
[Route("/AwaitingDispo")]
[Route("/Metrology/AwaitingDispo")]
public IActionResult AwaitingDispo()
{
ViewBag.ApiUrl = GetApiUrl();
return View();
}
[HttpGet]
[Route("/RunInfo")]
[Route("/Metrology/RunInfo")]
public IActionResult RunInfo([FromQuery] int tooltypeid = 1, [FromQuery] int headerid = 0)
{
RunInfo m = new()
{
ToolTypeID = tooltypeid,
HeaderID = headerid,
HeaderAttachmentID = Guid.Empty,
};
if (headerid > 0)
{
m.HeaderAttachmentID = _MetrologyRepository.GetHeaderAttachmentID(tooltypeid, headerid);
}
ViewBag.ApiUrl = GetApiUrl();
return View(m);
}
[HttpGet]
[Route("/RunHeaders")]
[Route("/Metrology/RunHeaders")]
public IActionResult RunHeaders()
{
ViewBag.ApiUrl = GetApiUrl();
return View();
}
[HttpGet]
[Route("/Crash")]
public IActionResult Crash() => throw new Exception("Test unhandled exception");
}

View File

@ -0,0 +1,82 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.ViewModels;
namespace OI.Metrology.Server.Controllers;
public class ReactorsController : Controller
{
private readonly bool _IsTestDatabase;
private readonly AppSettings _AppSettings;
public ReactorsController(AppSettings appSettings)
{
_AppSettings = appSettings;
_IsTestDatabase = appSettings.ConnectionString.Contains("test", StringComparison.InvariantCultureIgnoreCase);
}
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
ViewBag.IsTestDatabase = _IsTestDatabase;
}
private string GetApiUrl() => string.IsNullOrEmpty(_AppSettings.ApiUrl) ? Url.Content("~/") : _AppSettings.ApiUrl[0] == '~' ? Url.Content(_AppSettings.ApiUrl) : _AppSettings.ApiUrl;
[HttpGet]
[Route("/Step1")]
[Route("/Metrology/Step1")]
public IActionResult Step1(string mod = "", string equipment = "", string layer = "", string zone = "", string rds = "", string initials = "")
{
string directory = "D:/Tmp/Metrology";
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
string[] model = new string[] { mod, equipment, layer, zone, rds, initials };
if (!string.IsNullOrEmpty(initials))
System.IO.File.WriteAllLines(Path.Combine(directory, $"{DateTime.Now.Ticks}-{initials}.rsv"), model);
return View(model);
}
[HttpGet]
[Route("/Step2")]
[Route("/Metrology/Step2")]
public IActionResult Step2(string mod) =>
View(new string[] { mod });
[HttpGet]
[Route("/Step3")]
[Route("/Metrology/Step3")]
public IActionResult Step3(string mod, string equipment) =>
View(new string[] { mod, equipment });
[HttpGet]
[Route("/Step4")]
[Route("/Metrology/Step4")]
public IActionResult Step4(string mod, string equipment, string layer) =>
View(new string[] { mod, equipment, layer });
[HttpGet]
[Route("/Step5")]
[Route("/Metrology/Step5")]
public IActionResult Step5(string mod, string equipment, string layer, string zone) =>
View(new string[] { mod, equipment, layer, zone });
[HttpGet]
[Route("/Step6")]
[Route("/Metrology/Step6")]
public IActionResult Step6(string mod, string equipment, string layer, string zone, string rds) =>
View(new string[] { mod, equipment, layer, zone, rds });
[HttpGet]
[Route("/Reactor")]
[Route("/Metrology/Reactor")]
public IActionResult Reactor() => View(new RunInfo());
[HttpGet]
[Route("/WorkMaterial")]
[Route("/Metrology/WorkMaterial")]
public IActionResult WorkMaterial() => View();
}

View File

@ -2,22 +2,19 @@ using System.Text.Json;
namespace OI.Metrology.Server.Models; namespace OI.Metrology.Server.Models;
public record AppSettings(string ApiFileShare, public record AppSettings(string ApiExportPath,
string ApiLoggingContentTypes, string ApiLoggingContentTypes,
string ApiLoggingPathPrefixes, string ApiLoggingPathPrefixes,
string ApiLogPath, string ApiLogPath,
string ApiUrl, string ApiUrl,
string AttachmentPath,
string BuildNumber, string BuildNumber,
string Company, string Company,
string ConnectionString, string ConnectionString,
string EcCharacterizationSi,
string EcMesaFileShareCharacterizationSi,
string EcMesaFileShareMetrologySi,
string EcMetrologySi,
string GitCommitSeven, string GitCommitSeven,
string InboundApiAllowedIPList, string InboundApiAllowedIPList,
string IqsColumns, string IqsColumns,
string[] IqsFileSegments, string IqsFile,
string IqsKey, string IqsKey,
string IqsRed, string IqsRed,
string IqsYellow, string IqsYellow,
@ -30,7 +27,7 @@ public record AppSettings(string ApiFileShare,
Dictionary<string, string> TableToPath, Dictionary<string, string> TableToPath,
string URLs, string URLs,
string WaferCounterDestinationDirectory, string WaferCounterDestinationDirectory,
int WaferCounterTwoFileSecondsWait, string WaferCounterRootDirectory,
string WorkingDirectoryName) string WorkingDirectoryName)
{ {

View File

@ -6,22 +6,19 @@ namespace OI.Metrology.Server.Models.Binder;
public class AppSettings public class AppSettings
{ {
public string? ApiFileShare { get; set; } public string? ApiExportPath { get; set; }
public string? ApiLoggingContentTypes { get; set; } public string? ApiLoggingContentTypes { get; set; }
public string? ApiLoggingPathPrefixes { get; set; } public string? ApiLoggingPathPrefixes { get; set; }
public string? ApiLogPath { get; set; } public string? ApiLogPath { get; set; }
public string? ApiUrl { get; set; } public string? ApiUrl { get; set; }
public string? AttachmentPath { get; set; }
public string? BuildNumber { get; set; } public string? BuildNumber { get; set; }
public string? Company { get; set; } public string? Company { get; set; }
public string? ConnectionString { get; set; } public string? ConnectionString { get; set; }
public string? EcCharacterizationSi { get; set; }
public string? EcMesaFileShareCharacterizationSi { get; set; }
public string? EcMesaFileShareMetrologySi { get; set; }
public string? EcMetrologySi { get; set; }
public string? GitCommitSeven { get; set; } public string? GitCommitSeven { get; set; }
public string? InboundApiAllowedIPList { get; set; } public string? InboundApiAllowedIPList { get; set; }
public string? IqsColumns { get; set; } public string? IqsColumns { get; set; }
public string[]? IqsFileSegments { get; set; } public string? IqsFile { get; set; }
public string? IqsKey { get; set; } public string? IqsKey { get; set; }
public string? IqsRed { get; set; } public string? IqsRed { get; set; }
public string? IqsYellow { get; set; } public string? IqsYellow { get; set; }
@ -34,7 +31,7 @@ public class AppSettings
public Dictionary<string, string>? TableToPath { get; set; } public Dictionary<string, string>? TableToPath { get; set; }
public string? URLs { get; set; } public string? URLs { get; set; }
public string? WaferCounterDestinationDirectory { get; set; } public string? WaferCounterDestinationDirectory { get; set; }
public int? WaferCounterTwoFileSecondsWait { get; set; } public string? WaferCounterRootDirectory { get; set; }
public string? WorkingDirectoryName { get; set; } public string? WorkingDirectoryName { get; set; }
public override string ToString() public override string ToString()
@ -43,43 +40,23 @@ public class AppSettings
return result; return result;
} }
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
{
if (appSettings?.ApiFileShare is null)
{
List<string> paths = new();
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
{
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
continue;
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
continue;
paths.Add(physicalFileProvider.Root);
}
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
}
}
private static Models.AppSettings Get(AppSettings? appSettings) private static Models.AppSettings Get(AppSettings? appSettings)
{ {
Models.AppSettings result; Models.AppSettings result;
if (appSettings is null) throw new NullReferenceException(nameof(appSettings)); if (appSettings is null) throw new NullReferenceException(nameof(appSettings));
if (appSettings.ApiFileShare is null) throw new NullReferenceException(nameof(ApiFileShare)); if (appSettings.ApiExportPath is null) throw new NullReferenceException(nameof(ApiExportPath));
if (appSettings.ApiLoggingContentTypes is null) throw new NullReferenceException(nameof(ApiLoggingContentTypes)); if (appSettings.ApiLoggingContentTypes is null) throw new NullReferenceException(nameof(ApiLoggingContentTypes));
if (appSettings.ApiLoggingPathPrefixes is null) throw new NullReferenceException(nameof(ApiLoggingPathPrefixes)); if (appSettings.ApiLoggingPathPrefixes is null) throw new NullReferenceException(nameof(ApiLoggingPathPrefixes));
if (appSettings.ApiLogPath is null) throw new NullReferenceException(nameof(ApiLogPath)); if (appSettings.ApiLogPath is null) throw new NullReferenceException(nameof(ApiLogPath));
if (appSettings.ApiUrl is null) throw new NullReferenceException(nameof(ApiUrl)); if (appSettings.ApiUrl is null) throw new NullReferenceException(nameof(ApiUrl));
if (appSettings.AttachmentPath is null) throw new NullReferenceException(nameof(AttachmentPath));
if (appSettings.BuildNumber is null) throw new NullReferenceException(nameof(BuildNumber)); if (appSettings.BuildNumber is null) throw new NullReferenceException(nameof(BuildNumber));
if (appSettings.Company is null) throw new NullReferenceException(nameof(Company)); if (appSettings.Company is null) throw new NullReferenceException(nameof(Company));
if (appSettings.ConnectionString is null) throw new NullReferenceException(nameof(ConnectionString)); if (appSettings.ConnectionString is null) throw new NullReferenceException(nameof(ConnectionString));
if (appSettings.EcCharacterizationSi is null) throw new NullReferenceException(nameof(EcCharacterizationSi));
if (appSettings.EcMesaFileShareCharacterizationSi is null) throw new NullReferenceException(nameof(EcMesaFileShareCharacterizationSi));
if (appSettings.EcMesaFileShareMetrologySi is null) throw new NullReferenceException(nameof(EcMesaFileShareMetrologySi));
if (appSettings.EcMetrologySi is null) throw new NullReferenceException(nameof(EcMetrologySi));
if (appSettings.GitCommitSeven is null) throw new NullReferenceException(nameof(GitCommitSeven)); if (appSettings.GitCommitSeven is null) throw new NullReferenceException(nameof(GitCommitSeven));
if (appSettings.InboundApiAllowedIPList is null) throw new NullReferenceException(nameof(InboundApiAllowedIPList)); if (appSettings.InboundApiAllowedIPList is null) throw new NullReferenceException(nameof(InboundApiAllowedIPList));
if (appSettings.IqsColumns is null) throw new NullReferenceException(nameof(IqsColumns)); if (appSettings.IqsColumns is null) throw new NullReferenceException(nameof(IqsColumns));
if (appSettings.IqsFileSegments is null) throw new NullReferenceException(nameof(IqsFileSegments)); if (appSettings.IqsFile is null) throw new NullReferenceException(nameof(IqsFile));
if (appSettings.IqsKey is null) throw new NullReferenceException(nameof(IqsKey)); if (appSettings.IqsKey is null) throw new NullReferenceException(nameof(IqsKey));
if (appSettings.IqsRed is null) throw new NullReferenceException(nameof(IqsRed)); if (appSettings.IqsRed is null) throw new NullReferenceException(nameof(IqsRed));
if (appSettings.IqsYellow is null) throw new NullReferenceException(nameof(IqsYellow)); if (appSettings.IqsYellow is null) throw new NullReferenceException(nameof(IqsYellow));
@ -92,25 +69,22 @@ public class AppSettings
if (appSettings.URLs is null) throw new NullReferenceException(nameof(URLs)); if (appSettings.URLs is null) throw new NullReferenceException(nameof(URLs));
if (appSettings.TableToPath is null) throw new NullReferenceException(nameof(TableToPath)); if (appSettings.TableToPath is null) throw new NullReferenceException(nameof(TableToPath));
if (appSettings.WaferCounterDestinationDirectory is null) throw new NullReferenceException(nameof(WaferCounterDestinationDirectory)); if (appSettings.WaferCounterDestinationDirectory is null) throw new NullReferenceException(nameof(WaferCounterDestinationDirectory));
if (appSettings.WaferCounterTwoFileSecondsWait is null) throw new NullReferenceException(nameof(WaferCounterTwoFileSecondsWait)); if (appSettings.WaferCounterRootDirectory is null) throw new NullReferenceException(nameof(WaferCounterRootDirectory));
if (appSettings.WorkingDirectoryName is null) throw new NullReferenceException(nameof(WorkingDirectoryName)); if (appSettings.WorkingDirectoryName is null) throw new NullReferenceException(nameof(WorkingDirectoryName));
result = new( result = new(
appSettings.ApiFileShare, appSettings.ApiExportPath,
appSettings.ApiLoggingContentTypes, appSettings.ApiLoggingContentTypes,
appSettings.ApiLoggingPathPrefixes, appSettings.ApiLoggingPathPrefixes,
appSettings.ApiLogPath, appSettings.ApiLogPath,
appSettings.ApiUrl, appSettings.ApiUrl,
appSettings.AttachmentPath,
appSettings.BuildNumber, appSettings.BuildNumber,
appSettings.Company, appSettings.Company,
appSettings.ConnectionString, appSettings.ConnectionString,
appSettings.EcCharacterizationSi,
appSettings.EcMesaFileShareCharacterizationSi,
appSettings.EcMesaFileShareMetrologySi,
appSettings.EcMetrologySi,
appSettings.GitCommitSeven, appSettings.GitCommitSeven,
appSettings.InboundApiAllowedIPList, appSettings.InboundApiAllowedIPList,
appSettings.IqsColumns, appSettings.IqsColumns,
appSettings.IqsFileSegments, appSettings.IqsFile,
appSettings.IqsKey, appSettings.IqsKey,
appSettings.IqsRed, appSettings.IqsRed,
appSettings.IqsYellow, appSettings.IqsYellow,
@ -123,7 +97,7 @@ public class AppSettings
appSettings.TableToPath, appSettings.TableToPath,
appSettings.URLs, appSettings.URLs,
appSettings.WaferCounterDestinationDirectory, appSettings.WaferCounterDestinationDirectory,
appSettings.WaferCounterTwoFileSecondsWait.Value, appSettings.WaferCounterRootDirectory,
appSettings.WorkingDirectoryName); appSettings.WorkingDirectoryName);
return result; return result;
} }
@ -134,7 +108,22 @@ public class AppSettings
#pragma warning disable IL3050, IL2026 #pragma warning disable IL3050, IL2026
AppSettings? appSettings = configurationRoot.Get<AppSettings>(); AppSettings? appSettings = configurationRoot.Get<AppSettings>();
#pragma warning restore IL3050, IL2026 #pragma warning restore IL3050, IL2026
PreVerify(configurationRoot, appSettings); if (appSettings?.ApiExportPath is null)
{
List<string> paths = new();
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
{
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
continue;
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
continue;
paths.Add(physicalFileProvider.Root);
if (!physicalFileProvider.Root.Contains("UserSecrets"))
continue;
throw new NotSupportedException(physicalFileProvider.Root);
}
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths)}");
}
result = Get(appSettings); result = Get(appSettings);
return result; return result;
} }

View File

@ -6,7 +6,6 @@
<SccLocalPath>SAK</SccLocalPath> <SccLocalPath>SAK</SccLocalPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@ -25,10 +24,10 @@
<Content Remove="compilerconfig.json" /> <Content Remove="compilerconfig.json" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Dapper" Version="2.1.44" /> <PackageReference Include="Dapper" Version="2.1.24" />
<PackageReference Include="EntityFramework" Version="6.5.1" /> <PackageReference Include="EntityFramework" Version="6.4.4" />
<PackageReference Include="jQuery" Version="3.7.1" /> <PackageReference Include="jQuery" Version="3.7.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.7" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
@ -38,9 +37,9 @@
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" /> <PackageReference Include="System.Drawing.Common" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\OI.Metrology.Shared.csproj" /> <ProjectReference Include="..\Shared\OI.Metrology.Shared.csproj" />

View File

@ -4,6 +4,7 @@ using OI.Metrology.Server.Models;
using OI.Metrology.Server.Repositories; using OI.Metrology.Server.Repositories;
using OI.Metrology.Server.Repository; using OI.Metrology.Server.Repository;
using OI.Metrology.Server.Services; using OI.Metrology.Server.Services;
using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Repositories; using OI.Metrology.Shared.Repositories;
using OI.Metrology.Shared.Services; using OI.Metrology.Shared.Services;
@ -48,6 +49,8 @@ public class Program
throw new Exception("Company name must have a value!"); throw new Exception("Company name must have a value!");
if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName)) if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName))
throw new Exception("Working directory name must have a value!"); throw new Exception("Working directory name must have a value!");
string workingDirectory = IWorkingDirectory.GetWorkingDirectory(assemblyName, appSettings.WorkingDirectoryName);
Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
try try
{ {
_ = webApplicationBuilder.Services.AddMemoryCache(); _ = webApplicationBuilder.Services.AddMemoryCache();
@ -67,13 +70,14 @@ public class Program
_ = webApplicationBuilder.Services.AddScoped<IInboundDataService, InboundDataService>(); _ = webApplicationBuilder.Services.AddScoped<IInboundDataService, InboundDataService>();
_ = webApplicationBuilder.Services.AddSingleton<IInboundRepository, InboundRepository>(); _ = webApplicationBuilder.Services.AddSingleton<IInboundRepository, InboundRepository>();
_ = webApplicationBuilder.Services.AddScoped<IMetrologyRepository, MetrologyRepository>(); _ = webApplicationBuilder.Services.AddScoped<IMetrologyRepository, MetrologyRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IFileShareRepository, FileShareRepository>(); _ = webApplicationBuilder.Services.AddSingleton<IReactorsRepository, ReactorsRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IToolTypesRepository, ToolTypesRepository>(); _ = webApplicationBuilder.Services.AddSingleton<IToolTypesRepository, ToolTypesRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSRepository, InfinityQSRepository>(); _ = webApplicationBuilder.Services.AddSingleton<IInfinityQSRepository, InfinityQSRepository>();
_ = webApplicationBuilder.Services.AddScoped<IOpenInsightV1Repository, OpenInsightV1Repository>(); _ = webApplicationBuilder.Services.AddScoped<IOpenInsightV1Repository, OpenInsightV1Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV2Repository, InfinityQSV2Repository>(); _ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV2Repository, InfinityQSV2Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV3Repository, InfinityQSV3Repository>(); _ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV3Repository, InfinityQSV3Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV4Repository, InfinityQSV4Repository>(); _ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV4Repository, InfinityQSV4Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IWaferCounterRepository, WaferCounterRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IClientSettingsRepository>(_ => clientSettingsRepository); _ = webApplicationBuilder.Services.AddSingleton<IClientSettingsRepository>(_ => clientSettingsRepository);
_ = webApplicationBuilder.Services.AddSingleton<IServiceShopOrderRepository, ServiceShopOrderRepository>(); _ = webApplicationBuilder.Services.AddSingleton<IServiceShopOrderRepository, ServiceShopOrderRepository>();
_ = webApplicationBuilder.Services.AddSingleton<ISpreadingResistanceProfileService, SpreadingResistanceProfileService>(); _ = webApplicationBuilder.Services.AddSingleton<ISpreadingResistanceProfileService, SpreadingResistanceProfileService>();

View File

@ -1,10 +1,7 @@
using OI.Metrology.Server.Models; using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using System.Data;
using System.Globalization; using System.Globalization;
using System.Text;
using System.Text.Json; using System.Text.Json;
namespace OI.Metrology.Server.Repository; namespace OI.Metrology.Server.Repository;
@ -15,17 +12,13 @@ public class ExportRepository : IExportRepository
private readonly string _RepositoryName; private readonly string _RepositoryName;
private readonly AppSettings _AppSettings; private readonly AppSettings _AppSettings;
private readonly ILogger<ExportRepository> _Logger; private readonly ILogger<ExportRepository> _Logger;
private readonly IHttpClientFactory _HttpClientFactory;
private readonly IFileShareRepository _FileShareRepository;
private readonly Dictionary<string, Dictionary<long, HeaderCommon>> _RdsToHeaderCommonCollection; private readonly Dictionary<string, Dictionary<long, HeaderCommon>> _RdsToHeaderCommonCollection;
public ExportRepository(ILogger<ExportRepository> logger, AppSettings appSettings, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository) public ExportRepository(ILogger<ExportRepository> logger, AppSettings appSettings)
{ {
_Logger = logger; _Logger = logger;
_AppSettings = appSettings; _AppSettings = appSettings;
_RdsToHeaderCommonCollection = new(); _RdsToHeaderCommonCollection = new();
_HttpClientFactory = httpClientFactory;
_FileShareRepository = fileShareRepository;
_RepositoryName = nameof(ExportRepository)[..^10]; _RepositoryName = nameof(ExportRepository)[..^10];
} }
@ -39,47 +32,32 @@ public class ExportRepository : IExportRepository
return new string[] { weekOfYear, lastWeekOfYear }; return new string[] { weekOfYear, lastWeekOfYear };
} }
private NginxFileSystemSortable[] GetNginxFileSystemSortableCollection(HeaderCommon headerCommon, HttpClient httpClient, string endsWith) private List<string> GetFiles(HeaderCommon headerCommon, string searchPattern)
{ {
List<NginxFileSystemSortable> results = new(); List<string> results = new();
Uri uri; string directory;
string[] weeks = Get(); string[] weeks = Get();
List<NginxFileSystemSortable> nginxFileSystemSortableCollection;
foreach (string weekYear in weeks) foreach (string weekYear in weeks)
{ {
if (headerCommon.ID < 1) if (headerCommon.ID < 1)
uri = _FileShareRepository.Append(new Uri(_AppSettings.EcMesaFileShareMetrologySi), "Archive", "API", weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}"); directory = Path.Combine(_AppSettings.ApiExportPath, "Archive", "API", weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}");
else else
uri = _FileShareRepository.Append(new Uri(_AppSettings.EcMesaFileShareMetrologySi), "Archive", "API", weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}", $"-{headerCommon.ID}"); directory = Path.Combine(_AppSettings.ApiExportPath, "Archive", "API", weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}", $"-{headerCommon.ID}");
nginxFileSystemSortableCollection = _FileShareRepository.GetNginxFileSystemSortableCollection(httpClient, uri, endsWith); if (!Directory.Exists(directory))
results.AddRange(nginxFileSystemSortableCollection); continue;
results.AddRange(Directory.GetFiles(directory, searchPattern, SearchOption.AllDirectories));
} }
return results.OrderByDescending(l => l.DateTime).ToArray(); return results;
}
private string GetLines(HttpClient httpClient, NginxFileSystemSortable[] nginxFileSystemSortableCollection)
{
string result;
if (nginxFileSystemSortableCollection.Length != 1)
result = string.Empty;
else
{
HttpResponseMessage httpResponseMessage = _FileShareRepository.ReadFile(httpClient, nginxFileSystemSortableCollection.First().Uri);
if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception("File not found!");
Task<string> lines = httpResponseMessage.Content.ReadAsStringAsync();
lines.Wait();
result = lines.Result;
}
return result;
} }
string IExportRepository.GetExport(HeaderCommon headerCommon) string IExportRepository.GetExport(HeaderCommon headerCommon)
{ {
string result; string result;
HttpClient httpClient = _HttpClientFactory.CreateClient(); List<string> files = GetFiles(headerCommon, "*.txt");
NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".txt"); if (files.Count != 1)
result = GetLines(httpClient, nginxFileSystemSortableCollection); result = string.Empty;
else
result = File.ReadAllText(files.First());
return result; return result;
} }
@ -94,17 +72,16 @@ public class ExportRepository : IExportRepository
JsonElement? jsonElement; JsonElement? jsonElement;
const string ticks = "Ticks"; const string ticks = "Ticks";
JsonProperty[] jsonProperties; JsonProperty[] jsonProperties;
HttpClient httpClient = _HttpClientFactory.CreateClient(); List<string> files = GetFiles(headerCommon, "*.json");
NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".json"); foreach (string file in files)
foreach (NginxFileSystemSortable nginxFileSystemSortable in nginxFileSystemSortableCollection)
{ {
json = GetLines(httpClient, nginxFileSystemSortableCollection); json = File.ReadAllText(file);
hc = JsonSerializer.Deserialize<HeaderCommon>(json); hc = JsonSerializer.Deserialize<HeaderCommon>(json);
if (hc is null) if (hc is null)
continue; continue;
if (hc.ID < 1) if (hc.ID < 1)
{ {
directory = Path.GetDirectoryName(nginxFileSystemSortable.Uri.OriginalString); directory = Path.GetDirectoryName(file);
if (directory is null) if (directory is null)
continue; continue;
directoryName = Path.GetFileName(directory); directoryName = Path.GetFileName(directory);
@ -135,11 +112,10 @@ public class ExportRepository : IExportRepository
List<HeaderCommon> results = new(); List<HeaderCommon> results = new();
string json; string json;
HeaderCommon? hc; HeaderCommon? hc;
HttpClient httpClient = _HttpClientFactory.CreateClient(); List<string> files = GetFiles(headerCommon, "*.json");
NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".json"); foreach (string file in files)
foreach (NginxFileSystemSortable nginxFileSystemSortable in nginxFileSystemSortableCollection)
{ {
json = GetLines(httpClient, nginxFileSystemSortableCollection); json = File.ReadAllText(file);
hc = JsonSerializer.Deserialize<HeaderCommon>(json); hc = JsonSerializer.Deserialize<HeaderCommon>(json);
if (hc is null) if (hc is null)
continue; continue;
@ -156,92 +132,12 @@ public class ExportRepository : IExportRepository
string IExportRepository.GetProcessDataStandardFormat(HeaderCommon headerCommon) string IExportRepository.GetProcessDataStandardFormat(HeaderCommon headerCommon)
{ {
string result; string result;
HttpClient httpClient = _HttpClientFactory.CreateClient(); List<string> files = GetFiles(headerCommon, "*.pdsf");
NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".pdsf"); if (files.Count != 1)
result = GetLines(httpClient, nginxFileSystemSortableCollection); result = string.Empty;
else
result = File.ReadAllText(files.First());
return result; return result;
} }
Result<DataTable> IExportRepository.GetExportData(IMetrologyRepository metrologyRepository, int toolTypeId, string? datebegin, string? dateend)
{
Result<DataTable>? r;
DateTime dateEnd = dateend is null ? DateTime.Now : DateTime.Parse(dateend);
DateTime dateBegin = datebegin is null ? dateEnd.AddMonths(-1) : DateTime.Parse(datebegin);
ToolType tt = metrologyRepository.GetToolTypeByID(toolTypeId);
if (string.IsNullOrEmpty(tt.ExportSPName))
throw new NullReferenceException(nameof(tt.ExportSPName));
DataTable dataTable = metrologyRepository.ExportData(tt.ExportSPName, dateBegin, dateEnd);
r = new()
{
Results = dataTable,
TotalRows = dataTable.Rows.Count,
};
return r;
}
protected static string FormatForCSV(string v)
{
StringBuilder result = new(v.Length + 2);
bool doubleQuoted = false;
if (v.StartsWith(' ') || v.EndsWith(' ') || v.Contains(',') || v.Contains('"'))
{
_ = result.Append('"');
doubleQuoted = true;
}
foreach (char c in v)
{
_ = c switch
{
'\r' or '\n' => result.Append(' '),
'"' => result.Append("\"\""),
_ => result.Append(c),
};
}
if (doubleQuoted)
_ = result.Append('"');
return result.ToString();
}
protected static string GetColumnHeaders(DataTable dataTable)
{
StringBuilder result = new();
for (int i = 0; i < dataTable.Columns.Count; i++)
{
if (i > 0)
_ = result.Append(',');
_ = result.Append(FormatForCSV(dataTable.Columns[i].ColumnName.TrimEnd('_')));
}
return result.ToString();
}
protected static string GetRowData(DataRow dr)
{
StringBuilder result = new();
for (int i = 0; i < dr.Table.Columns.Count; i++)
{
if (i > 0)
_ = result.Append(',');
object v = dr[i];
if (v is not null && !Convert.IsDBNull(v))
_ = result.Append(FormatForCSV(string.Concat(Convert.ToString(v))));
}
return result.ToString();
}
string IExportRepository.GetCSVExport(IMetrologyRepository metrologyRepository, int toolTypeId, string? datebegin, string? dateend)
{
string results;
Result<DataTable> result;
IExportRepository repository = this;
result = repository.GetExportData(metrologyRepository, toolTypeId, datebegin, dateend);
if (result.Results is null)
throw new NullReferenceException(nameof(result.Results));
StringBuilder stringBuilder = new();
_ = stringBuilder.AppendLine(GetColumnHeaders(result.Results));
foreach (DataRow dr in result.Results.Rows)
_ = stringBuilder.AppendLine(GetRowData(dr));
results = stringBuilder.ToString();
return results;
}
} }

View File

@ -1,106 +0,0 @@
using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless;
using System.Text.Json;
using System.Web;
namespace OI.Metrology.Server.Repository;
public class FileShareRepository : IFileShareRepository
{
Uri IFileShareRepository.Append(Uri uri, params string[] paths) =>
new(paths.Aggregate(uri.AbsoluteUri, (current, path) => string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/'))));
private Uri GetEndPoint(HttpClient httpClient, string method)
{
Uri result;
if (httpClient.BaseAddress is null)
throw new NullReferenceException(nameof(httpClient.BaseAddress));
IFileShareRepository fileShareRepository = this;
result = fileShareRepository.Append(httpClient.BaseAddress, "api", "v1", "file-share", method);
return result;
}
void IFileShareRepository.CopyFile(string from, string to)
{
string directory = Path.GetDirectoryName(to) ?? throw new NullReferenceException();
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
File.Copy(from, to);
}
void IFileShareRepository.MoveFile(string from, string to)
{
string directory = Path.GetDirectoryName(to) ?? throw new NullReferenceException();
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
if (File.Exists(to))
File.Move(to, $"{to}.{DateTime.Now.Ticks}.old");
File.Move(from, to);
}
void IFileShareRepository.FileWrite(string path, string contents)
{
string directory = Path.GetDirectoryName(path) ?? throw new NullReferenceException();
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
File.WriteAllText(path, contents);
}
void IFileShareRepository.CopyFile(HttpClient httpClient, string from, string to)
{
Uri uri = GetEndPoint(httpClient, "copy-file");
string encodedTo = HttpUtility.UrlEncode(to);
string encodedFrom = HttpUtility.UrlEncode(from);
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync($"{uri.OriginalString}?from={encodedFrom}&to={encodedTo}");
httpResponseMessage.Wait();
if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(httpResponseMessage.Result.StatusCode.ToString());
}
void IFileShareRepository.MoveFile(HttpClient httpClient, string from, string to)
{
Uri uri = GetEndPoint(httpClient, "move-file");
string encodedTo = HttpUtility.UrlEncode(to);
string encodedFrom = HttpUtility.UrlEncode(from);
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync($"{uri.OriginalString}?from={encodedFrom}&to={encodedTo}");
httpResponseMessage.Wait();
if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(httpResponseMessage.Result.StatusCode.ToString());
}
HttpResponseMessage IFileShareRepository.ReadFile(HttpClient httpClient, Uri uri)
{
HttpResponseMessage result;
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(uri);
httpResponseMessage.Wait();
result = httpResponseMessage.Result;
return result;
}
List<NginxFileSystemSortable> IFileShareRepository.GetNginxFileSystemSortableCollection(HttpClient httpClient, Uri uri, string? endsWith)
{
List<NginxFileSystemSortable> results = new();
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(uri);
httpResponseMessage.Wait();
if (httpResponseMessage.Result.StatusCode == System.Net.HttpStatusCode.OK)
{
FileShareRepository fileShareRepository = this;
Task<string> json = httpResponseMessage.Result.Content.ReadAsStringAsync();
json.Wait();
NginxFileSystem[]? nginxFileSystemCollection = JsonSerializer.Deserialize(json.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
List<NginxFileSystemSortable> nginxFileSystemSortableCollection = NginxFileSystemSortable.Convert(fileShareRepository, uri, nginxFileSystemCollection);
foreach (NginxFileSystemSortable nginxFileSystemSortable in nginxFileSystemSortableCollection.OrderByDescending(l => l.DateTime))
{
if (!string.IsNullOrEmpty(endsWith) && !nginxFileSystemSortable.Name.EndsWith(endsWith))
continue;
results.Add(nginxFileSystemSortable);
}
}
return results;
}
List<CharacterizationInfo> IFileShareRepository.GetArchiveData(CharacterizationParameters archiveParameters) =>
throw new NotImplementedException();
}

View File

@ -31,42 +31,76 @@ public class InboundRepository : IInboundRepository
return false; return false;
} }
DataResponse IInboundRepository.Data(IMetrologyRepository metrologyRepository, IInboundDataService inboundDataService, string toolTypeName, JsonElement? jsonElement) // this is the main endpoint, it accepts a JSON message that contains both the header and data records together
// tooltype is the ToolTypeName column from the ToolType table
// JToken is how you can accept a JSON message without deserialization.
// Using "string" doesn't work because ASP.NET Core will expect a json encoded string, not give you the actual string.
DataResponse IInboundRepository.Data(IMetrologyRepository metrologyRepository, IInboundDataService inboundDataService, string tooltype, string? json)
{ {
DataResponse result = new(); DataResponse result = new();
if (jsonElement is null || jsonElement.Value.ValueKind != JsonValueKind.Object) ToolType? toolType = metrologyRepository.GetToolTypeByName(tooltype);
throw new Exception("Invalid body!"); if (toolType is null)
string? json = jsonElement.ToString(); result.Errors.Add($"Invalid tool type: {tooltype}");
JToken jToken = (string.IsNullOrEmpty(json) ? JToken.Parse("{}") : JToken.Parse(json)) ?? else
throw new Exception($"Invalid body: {json}");
ToolType toolType = metrologyRepository.GetToolTypeByName(toolTypeName) ??
throw new Exception($"Invalid tool type: {toolTypeName}");
List<ToolTypeMetadata> metaData = metrologyRepository.GetToolTypeMetadataByToolTypeID(toolType.ID).ToList();
inboundDataService.ValidateJSONFields(jToken, 0, metaData, result.Errors, result.Warnings);
if (result.Errors.Count == 0)
{ {
try InboundCommon? inboundCommon = string.IsNullOrEmpty(json) ? null : JsonSerializer.Deserialize<InboundCommon>(json);
if (inboundCommon is null || string.IsNullOrEmpty(inboundCommon.ProcessDataStandardFormat))
result.Errors.Add($"Invalid body: {json}");
else
{ {
result.HeaderID = inboundDataService.DoSQLInsert(jToken, toolType, metaData); string? sourceDirectory = Path.GetDirectoryName(inboundCommon.ProcessDataStandardFormat);
result.Success = result.HeaderID > 0; string? parentDirectory = Path.GetDirectoryName(sourceDirectory);
if (string.IsNullOrEmpty(sourceDirectory) || string.IsNullOrEmpty(parentDirectory) || !Directory.Exists(parentDirectory))
result.Errors.Add($"Invalid body:path: <{inboundCommon.ProcessDataStandardFormat}>");
else
{
JToken jToken = string.IsNullOrEmpty(json) ? JToken.Parse("{}") : JToken.Parse(json);
if (jToken is null)
result.Errors.Add($"Invalid body: {json}");
else
{
List<ToolTypeMetadata> metaData = metrologyRepository.GetToolTypeMetadataByToolTypeID(toolType.ID).ToList();
if (metaData is null)
result.Errors.Add($"Invalid metadata for tool type: {tooltype}");
else
{
inboundDataService.ValidateJSONFields(jToken, 0, metaData, result.Errors, result.Warnings);
if (result.Errors.Count == 0)
{
try
{
result.HeaderID = inboundDataService.DoSQLInsert(jToken, toolType, metaData);
result.Success = result.HeaderID > 0;
string? destinationDirectory = Path.Combine(parentDirectory, result.HeaderID.ToString());
Directory.Move(sourceDirectory, destinationDirectory);
}
catch (Exception ex) { result.Errors.Add(ex.Message); }
}
}
}
}
} }
catch (Exception ex) { result.Errors.Add(ex.Message); }
} }
return result; return result;
} }
void IInboundRepository.AttachFile(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, string toolTypeName, Attachment? attachment) // this is the endpoint for attaching a field. It is not JSON, it is form-data/multipart like an HTML form because that's the normal way.
// header ID is the ID value from the Header table
// datauniqueid is the Title value from the Data/Detail table
string? IInboundRepository.AttachFile(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, string tooltype, long headerid, string datauniqueid, string fileName, object uploadedFile)
{ {
if (attachment is null) string? result = null;
throw new Exception("Invalid body!"); ToolType toolType = metrologyRepository.GetToolTypeByName(tooltype);
ToolType toolType = metrologyRepository.GetToolTypeByName(toolTypeName) ?? if (toolType is null)
throw new Exception($"Invalid tool type: {toolTypeName}"); result = $"Invalid tool type: {tooltype}";
if (string.IsNullOrWhiteSpace(attachment.DestinationFileName)) string filename = Path.GetFileName(fileName);
throw new Exception("Empty filename"); if (string.IsNullOrWhiteSpace(filename))
if (attachment.DestinationFileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) result = "Empty filename";
throw new Exception("Invalid filename"); if (filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
attachmentsService.SaveAttachment(toolType, attachment); result = "Invalid filename";
if (result is null && toolType is not null)
attachmentsService.SaveAttachment(toolType, headerid, datauniqueid, filename, uploadedFile);
return result;
} }
} }

View File

@ -6,6 +6,7 @@ using OI.Metrology.Shared.Repositories;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Data; using System.Data;
using System.Data.Common; using System.Data.Common;
using System.Reflection;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
@ -21,155 +22,138 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
private readonly AppSettings _AppSettings; private readonly AppSettings _AppSettings;
private readonly IHttpClientFactory _HttpClientFactory; private readonly IHttpClientFactory _HttpClientFactory;
private readonly IDbConnectionFactory _DBConnectionFactory; private readonly IDbConnectionFactory _DBConnectionFactory;
private readonly IFileShareRepository _FileShareRepository;
private readonly string _OpenInsightApplicationProgrammingInterface; private readonly string _OpenInsightApplicationProgrammingInterface;
public InfinityQSV4Repository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository) public InfinityQSV4Repository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory, IHttpClientFactory httpClientFactory)
{ {
_AppSettings = appSettings; _AppSettings = appSettings;
_MockRoot = appSettings.MockRoot; _MockRoot = appSettings.MockRoot;
_HttpClientFactory = httpClientFactory; _HttpClientFactory = httpClientFactory;
_DBConnectionFactory = dbConnectionFactory; _DBConnectionFactory = dbConnectionFactory;
_FileShareRepository = fileShareRepository;
_RepositoryName = nameof(InfinityQSV4Repository)[..^10]; _RepositoryName = nameof(InfinityQSV4Repository)[..^10];
_OpenInsightApplicationProgrammingInterface = appSettings.OpenInsightApplicationProgrammingInterface; _OpenInsightApplicationProgrammingInterface = appSettings.OpenInsightApplicationProgrammingInterface;
} }
string IInfinityQSV4Repository.GetCommandText(string subGroupId) string IInfinityQSV4Repository.GetCommandText(string subGroupId)
{ // cSpell:disable { // cSpell:disable
List<string> results = []; StringBuilder result = new();
if (string.IsNullOrEmpty(subGroupId)) if (string.IsNullOrEmpty(subGroupId))
throw new ArgumentException(null, nameof(subGroupId)); throw new ArgumentException(null, nameof(subGroupId));
results.Add(" select "); _ = result
results.Add(" sd.f_sgrp sd_sgrp, "); .AppendLine(" select ")
results.Add(" sd.f_tsno sd_tsno, "); .AppendLine(" sd.f_sgrp sd_sgrp, ")
results.Add(" dd.f_dsgp dd_dsgp, "); .AppendLine(" sd.f_tsno sd_tsno, ")
results.Add(" dg.f_name gd_name, "); .AppendLine(" dd.f_dsgp dd_dsgp, ")
results.Add(" dd.f_name dd_name "); .AppendLine(" dg.f_name gd_name, ")
results.Add(" from [SPCEPIWORLD].[dbo].[SGRP_DSC] sd "); .AppendLine(" dd.f_name dd_name ")
results.Add(" join [SPCEPIWORLD].[dbo].[DESC_DAT] dd "); .AppendLine(" from [SPCEPIWORLD].[dbo].[SGRP_DSC] sd ")
results.Add(" on sd.f_dsgp = dd.f_dsgp "); .AppendLine(" join [SPCEPIWORLD].[dbo].[DESC_DAT] dd ")
results.Add(" and sd.f_desc = dd.f_desc "); .AppendLine(" on sd.f_dsgp = dd.f_dsgp ")
results.Add(" join [SPCEPIWORLD].[dbo].[DESC_GRP] dg "); .AppendLine(" and sd.f_desc = dd.f_desc ")
results.Add(" on dd.f_dsgp = dg.f_dsgp "); .AppendLine(" join [SPCEPIWORLD].[dbo].[DESC_GRP] dg ")
results.Add($" where sd.f_sgrp = {subGroupId} "); .AppendLine(" on dd.f_dsgp = dg.f_dsgp ");
results.Add(" for json path "); _ = result.Append(" where sd.f_sgrp = ").Append(subGroupId).AppendLine(" ");
return string.Join(' ', results); _ = result.AppendLine(" for json path ");
return result.ToString();
} // cSpell:enable } // cSpell:enable
string IInfinityQSV4Repository.GetCommandText(string? subGroupId, string? process, string? job, string? part, string? lot, string? dateTime) string IInfinityQSV4Repository.GetCommandText(string? subGroupId, string? process, string? job, string? part, string? lot, string? dateTime)
{ // cSpell:disable { // cSpell:disable
List<string> results = []; StringBuilder result = new();
const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss"; const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')) && dateTime.Length != dateTimeFormat.Length) if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')) && dateTime.Length != dateTimeFormat.Length)
throw new ArgumentException(null, nameof(dateTime)); throw new ArgumentException(null, nameof(dateTime));
results.Add(" select case when iq.sl_loos is null then 0 else iq.sl_loos end + "); _ = result
results.Add(" case when iq.sl_uoos is null then 0 else iq.sl_uoos end + "); .AppendLine(" select case when iq.sl_loos is null then 0 else iq.sl_loos end + ")
results.Add(" iq.ev_count as iq_sum, "); .AppendLine(" case when iq.sl_uoos is null then 0 else iq.sl_uoos end + ")
results.Add(" iq.sl_aflag, "); .AppendLine(" iq.ev_count as iq_sum, ")
results.Add(" iq.sl_loos, "); .AppendLine(" iq.sl_aflag, ")
results.Add(" iq.sl_uoos, "); .AppendLine(" iq.sl_loos, ")
results.Add(" iq.se_sgrp, "); .AppendLine(" iq.sl_uoos, ")
results.Add(" iq.se_sgtm, "); .AppendLine(" iq.se_sgrp, ")
results.Add(" iq.se_tsno, "); .AppendLine(" iq.se_sgtm, ")
results.Add(" iq.td_test, "); .AppendLine(" iq.se_tsno, ")
results.Add(" iq.pr_name, "); .AppendLine(" iq.td_test, ")
results.Add(" iq.jd_name, "); .AppendLine(" iq.pr_name, ")
results.Add(" iq.pl_name, "); .AppendLine(" iq.jd_name, ")
results.Add(" iq.pd_name, "); .AppendLine(" iq.pl_name, ")
results.Add(" iq.td_name, "); .AppendLine(" iq.pd_name, ")
results.Add(" iq.se_val, "); .AppendLine(" iq.td_name, ")
results.Add(" iq.sl_eflag, "); .AppendLine(" iq.se_val, ")
results.Add(" iq.sl_scal, "); .AppendLine(" iq.sl_eflag, ")
results.Add(" iq.sl_sls, "); .AppendLine(" iq.sl_scal, ")
results.Add(" iq.sl_usl "); .AppendLine(" iq.sl_sls, ")
results.Add(" from ( "); .AppendLine(" iq.sl_usl ")
results.Add(" select "); .AppendLine(" from ( ")
results.Add(" se.f_sgrp se_sgrp, "); .AppendLine(" select ")
results.Add(" se.f_sgtm se_sgtm, "); .AppendLine(" se.f_sgrp se_sgrp, ")
results.Add(" se.f_tsno se_tsno, "); .AppendLine(" se.f_sgtm se_sgtm, ")
results.Add(" se.f_val se_val, "); .AppendLine(" se.f_tsno se_tsno, ")
results.Add(" pr.f_name pr_name, "); .AppendLine(" se.f_val se_val, ")
results.Add(" jd.f_name jd_name, "); .AppendLine(" pr.f_name pr_name, ")
results.Add(" pl.f_name pl_name, "); .AppendLine(" jd.f_name jd_name, ")
results.Add(" pd.f_name pd_name, "); .AppendLine(" pl.f_name pl_name, ")
results.Add(" td.f_test td_test, "); .AppendLine(" pd.f_name pd_name, ")
results.Add(" td.f_name td_name, "); .AppendLine(" td.f_test td_test, ")
results.Add(" sl.f_eflag sl_eflag, "); .AppendLine(" td.f_name td_name, ")
results.Add(" sl.f_aflag sl_aflag, "); .AppendLine(" sl.f_eflag sl_eflag, ")
results.Add(" sl.f_scal sl_scal, "); .AppendLine(" sl.f_aflag sl_aflag, ")
results.Add(" sl.f_lsl sl_sls, "); .AppendLine(" sl.f_scal sl_scal, ")
results.Add(" sl.f_usl sl_usl, "); .AppendLine(" sl.f_lsl sl_sls, ")
results.Add(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else "); .AppendLine(" sl.f_usl sl_usl, ")
results.Add(" case when round(se.f_val, sl.F_scal, 1) < sl.f_lsl then 1 else 0 end "); .AppendLine(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ")
results.Add(" end as sl_loos, "); .AppendLine(" case when round(se.f_val, sl.F_scal, 1) < sl.f_lsl then 1 else 0 end ")
results.Add(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else "); .AppendLine(" end as sl_loos, ")
results.Add(" case when round(se.f_val, sl.F_scal, 1) > sl.f_usl then 1 else 0 end "); .AppendLine(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ")
results.Add(" end as sl_uoos, "); .AppendLine(" case when round(se.f_val, sl.F_scal, 1) > sl.f_usl then 1 else 0 end ")
results.Add(" (select count(ev.f_evnt) "); .AppendLine(" end as sl_uoos, ")
results.Add(" from [spcepiworld].[dbo].[evnt_inf] ev "); .AppendLine(" (select count(ev.f_evnt) ")
results.Add(" where ev.f_prcs = pr.f_prcs "); .AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
results.Add(" and ev.f_part = pd.f_part "); .AppendLine(" where ev.f_prcs = pr.f_prcs ")
results.Add(" and ev.f_sgtm = se.f_sgtm "); .AppendLine(" and ev.f_part = pd.f_part ")
results.Add(" ) ev_count "); .AppendLine(" and ev.f_sgtm = se.f_sgtm ")
results.Add(" from [spcepiworld].[dbo].[sgrp_ext] se "); .AppendLine(" ) ev_count ")
results.Add(" join [spcepiworld].[dbo].[prcs_dat] pr "); .AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ")
results.Add(" on se.f_prcs = pr.f_prcs "); .AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
results.Add(" join [spcepiworld].[dbo].[job_dat] jd "); .AppendLine(" on se.f_prcs = pr.f_prcs ")
results.Add(" on se.f_job = jd.f_job "); .AppendLine(" join [spcepiworld].[dbo].[job_dat] jd ")
results.Add(" join [spcepiworld].[dbo].[part_lot] pl "); .AppendLine(" on se.f_job = jd.f_job ")
results.Add(" on se.f_lot = pl.f_lot "); .AppendLine(" join [spcepiworld].[dbo].[part_lot] pl ")
results.Add(" join [spcepiworld].[dbo].[part_dat] pd "); .AppendLine(" on se.f_lot = pl.f_lot ")
results.Add(" on se.f_part = pd.f_part "); .AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
results.Add(" join [spcepiworld].[dbo].[test_dat] td "); .AppendLine(" on se.f_part = pd.f_part ")
results.Add(" on se.f_test = td.f_test "); .AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
results.Add(" left join [spcepiworld].[dbo].[spec_lim] sl "); .AppendLine(" on se.f_test = td.f_test ")
results.Add(" on se.f_part = sl.f_part "); .AppendLine(" left join [spcepiworld].[dbo].[spec_lim] sl ")
results.Add(" and se.f_test = sl.f_test "); .AppendLine(" on se.f_part = sl.f_part ")
results.Add(" where se.f_flag = 0 "); .AppendLine(" and se.f_test = sl.f_test ")
results.Add(" and (sl.f_prcs is null or se.f_prcs = sl.f_prcs or sl.f_prcs = 0) "); .AppendLine(" where se.f_flag = 0 ")
.AppendLine(" and (sl.f_prcs is null or se.f_prcs = sl.f_prcs or sl.f_prcs = 0) ");
if (!string.IsNullOrEmpty(subGroupId)) if (!string.IsNullOrEmpty(subGroupId))
results.Add($" and se.f_sgrp = {subGroupId.Split(" ")[0]} "); _ = result.Append(" and se.f_sgrp = ").Append(subGroupId.Split(" ")[0]).AppendLine(" ");
if (!string.IsNullOrEmpty(process)) if (!string.IsNullOrEmpty(process))
results.Add($" and pr.f_name = '{process}' "); _ = result.Append(" and pr.f_name = '").Append(process).AppendLine("' ");
if (!string.IsNullOrEmpty(part)) if (!string.IsNullOrEmpty(part))
results.Add($" and pd.f_name = '{part}' "); _ = result.Append(" and pd.f_name = '").Append(part).AppendLine("' ");
if (!string.IsNullOrEmpty(job)) if (!string.IsNullOrEmpty(job))
results.Add($" and jd.f_name = '{job}' "); _ = result.Append(" and jd.f_name = '").Append(job).AppendLine("' ");
if (!string.IsNullOrEmpty(lot)) if (!string.IsNullOrEmpty(lot))
results.Add($" and pl.f_name = '{lot}' "); _ = result.Append(" and pl.f_name = '").Append(lot).AppendLine("' ");
if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':'))) if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')))
results.Add($" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '{dateTime}' "); _ = result.Append(" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '").Append(dateTime).AppendLine("' ");
results.Add(" ) as iq "); _ = result.AppendLine(" ) as iq ")
results.Add(" order by iq.sl_loos + iq.sl_uoos + iq.ev_count desc, "); .AppendLine(" order by iq.sl_loos + iq.sl_uoos + iq.ev_count desc, ")
results.Add(" iq.sl_aflag desc, "); .AppendLine(" iq.sl_aflag desc, ")
results.Add(" iq.se_sgrp, "); .AppendLine(" iq.se_sgrp, ")
results.Add(" iq.se_tsno, "); .AppendLine(" iq.se_tsno, ")
results.Add(" iq.td_test "); .AppendLine(" iq.td_test ")
results.Add(" for json path "); .AppendLine(" for json path ");
return string.Join(' ', results); return result.ToString();
} // cSpell:enable } // cSpell:enable
private JsonElement[] GetAllReactorsAsJsonElementElement()
{
JsonElement[]? results;
HttpClient httpClient = _HttpClientFactory.CreateClient();
Task<string> task = httpClient.GetStringAsync($"{_OpenInsightApplicationProgrammingInterface}/reactors");
task.Wait();
JsonElement? jsonElement = JsonSerializer.Deserialize<JsonElement>(task.Result);
if (jsonElement is null)
throw new NullReferenceException(nameof(jsonElement));
string json = jsonElement.Value.EnumerateObject().First().Value.ToString();
results = JsonSerializer.Deserialize<JsonElement[]>(json);
if (results is null)
throw new NullReferenceException(nameof(results));
return results;
}
private static StringBuilder GetForJsonPath(IDbConnectionFactory dbConnectionFactory, string commandText, bool useIqsConnection) private static StringBuilder GetForJsonPath(IDbConnectionFactory dbConnectionFactory, string commandText, bool useIqsConnection)
{ {
StringBuilder stringBuilder = new(); StringBuilder stringBuilder = new();
File.WriteAllText("../../.sql", commandText);
using DbConnection dbConnection = dbConnectionFactory.GetDbConnection(useIqsConnection); using DbConnection dbConnection = dbConnectionFactory.GetDbConnection(useIqsConnection);
DbCommand dbCommand = dbConnection.CreateCommand(); DbCommand dbCommand = dbConnection.CreateCommand();
dbCommand.CommandText = commandText; dbCommand.CommandText = commandText;
@ -179,50 +163,6 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
return stringBuilder; return stringBuilder;
} }
private void GetOI(InfinityQSV4 infinityQSV4)
{
IInfinityQSV4Repository infinityQSV4Repository = this;
if (string.IsNullOrEmpty(infinityQSV4.Part))
throw new ArgumentException(nameof(infinityQSV4.Part));
string json = infinityQSV4Repository.GetProductionSpecification(infinityQSV4.Part);
File.WriteAllText("../../.json", json);
ProdSpecRoot? prodSpec = JsonSerializer.Deserialize(json, ProdSpecRootSourceGenerationContext.Default.ProdSpecRoot);
if (prodSpec is null)
{
if (prodSpec is null)
{ }
}
}
private static List<string> Convert(int[] night)
{
List<string> results = new();
foreach (int reactor in night)
results.Add(reactor.ToString());
return results;
}
private ReadOnlyDictionary<int, Reactor> GetReactorsMatchingType(string? reactTypeFilter)
{
Dictionary<int, Reactor> results = new();
string json;
Reactor? reactor;
JsonElement[]? jsonElements = GetAllReactorsAsJsonElementElement();
foreach (JsonElement jsonElement in jsonElements)
{
json = jsonElement.EnumerateObject().First().Value.ToString();
if (reactTypeFilter is not null && !json.Contains(reactTypeFilter))
continue;
try
{ reactor = JsonSerializer.Deserialize(json, ReactorSourceGenerationContext.Default.Reactor); }
catch (Exception) { reactor = null; }
if (reactor is null || (reactTypeFilter is not null && reactor.ReactType != reactTypeFilter))
continue;
results.Add(reactor.ReactorNo, reactor);
}
return new(results);
}
private static InfinityQSV4 GetInfinityQSV4(IDbConnectionFactory dbConnectionFactory, IInfinityQSV4Repository infinityQSV4Repository, string subGroupId) private static InfinityQSV4 GetInfinityQSV4(IDbConnectionFactory dbConnectionFactory, IInfinityQSV4Repository infinityQSV4Repository, string subGroupId)
{ {
InfinityQSV4 result; InfinityQSV4 result;
@ -293,32 +233,33 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
string IInfinityQSV4Repository.GetCommandText(InfinityQSV4 infinityQSV4) string IInfinityQSV4Repository.GetCommandText(InfinityQSV4 infinityQSV4)
{ // cSpell:disable { // cSpell:disable
List<string> results = []; StringBuilder result = new();
if (string.IsNullOrEmpty(infinityQSV4.Process)) if (string.IsNullOrEmpty(infinityQSV4.Process))
throw new ArgumentException(nameof(infinityQSV4.Process)); throw new ArgumentException(nameof(infinityQSV4.Process));
if (string.IsNullOrEmpty(infinityQSV4.Part)) if (string.IsNullOrEmpty(infinityQSV4.Part))
throw new ArgumentException(nameof(infinityQSV4.Part)); throw new ArgumentException(nameof(infinityQSV4.Part));
results.Add(" select "); _ = result
results.Add(" ev.f_evnt [ev_evnt], "); .AppendLine(" select ")
results.Add(" ev.f_sgtm [ev_sgtm], "); .AppendLine(" ev.f_evnt [ev_evnt], ")
results.Add(" dateadd(HH, -7, (dateadd(SS, convert(bigint, ev.f_sgtm), '19700101'))) [ev_utc7], "); .AppendLine(" ev.f_sgtm [ev_sgtm], ")
results.Add(" pr.f_name [pr_name], "); .AppendLine(" dateadd(HH, -7, (dateadd(SS, convert(bigint, ev.f_sgtm), '19700101'))) [ev_utc7], ")
results.Add(" pd.f_name [pd_name], "); .AppendLine(" pr.f_name [pr_name], ")
results.Add(" td.f_test [td_test], "); .AppendLine(" pd.f_name [pd_name], ")
results.Add(" td.f_name [td_name], "); .AppendLine(" td.f_test [td_test], ")
results.Add(" ev.f_name [ev_name] "); .AppendLine(" td.f_name [td_name], ")
results.Add(" from [spcepiworld].[dbo].[evnt_inf] ev "); .AppendLine(" ev.f_name [ev_name] ")
results.Add(" join [spcepiworld].[dbo].[prcs_dat] pr "); .AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
results.Add(" on ev.f_prcs = pr.f_prcs "); .AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
results.Add(" join [spcepiworld].[dbo].[part_dat] pd "); .AppendLine(" on ev.f_prcs = pr.f_prcs ")
results.Add(" on ev.f_part = pd.f_part "); .AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
results.Add(" join [spcepiworld].[dbo].[test_dat] td "); .AppendLine(" on ev.f_part = pd.f_part ")
results.Add(" on ev.f_test = td.f_test "); .AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
results.Add($" where pr.f_name = '{infinityQSV4.Process}' "); .AppendLine(" on ev.f_test = td.f_test ")
results.Add($" and pd.f_name = '{infinityQSV4.Part}' "); .Append(" where pr.f_name = '").Append(infinityQSV4.Process).AppendLine("' ")
results.Add($" and ev.f_sgtm = {infinityQSV4.SubGroupDateTime} "); .Append(" and pd.f_name = '").Append(infinityQSV4.Part).AppendLine("' ")
results.Add(" for json path "); .Append(" and ev.f_sgtm = ").Append(infinityQSV4.SubGroupDateTime).AppendLine(" ")
return string.Join(' ', results); .AppendLine(" for json path ");
return result.ToString();
} // cSpell:enable } // cSpell:enable
Result<InfinityQSV4[]> IInfinityQSV4Repository.GetHeader(string subGroupId) Result<InfinityQSV4[]> IInfinityQSV4Repository.GetHeader(string subGroupId)
@ -347,27 +288,28 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
string IInfinityQSV4Repository.GetCommandText(string process, string? part) string IInfinityQSV4Repository.GetCommandText(string process, string? part)
{ // cSpell:disable { // cSpell:disable
List<string> results = []; StringBuilder result = new();
if (string.IsNullOrEmpty(process)) if (string.IsNullOrEmpty(process))
throw new ArgumentException(null, nameof(process)); throw new ArgumentException(null, nameof(process));
if (string.IsNullOrEmpty(part)) if (string.IsNullOrEmpty(part))
throw new ArgumentException(null, nameof(part)); throw new ArgumentException(null, nameof(part));
results.Add(" select [f_mean] as ProcessMean, "); _ = result
results.Add(" [f_sp] as ProcessSigma "); .AppendLine(" select [f_mean] as ProcessMean, ")
results.Add(" from [spcepiworld].[dbo].[test_dat] test "); .AppendLine(" [f_sp] as ProcessSigma ")
results.Add(" join [spcepiworld].[dbo].[ctrl_lim] ctrl "); .AppendLine(" from [spcepiworld].[dbo].[test_dat] test ")
results.Add(" on test.f_test = ctrl.f_test "); .AppendLine(" join [spcepiworld].[dbo].[ctrl_lim] ctrl ")
results.Add(" and test.f_tsgp = 1104848523 /* Product Data */ "); .AppendLine(" on test.f_test = ctrl.f_test ")
results.Add(" join [spcepiworld].[dbo].[part_dat] part "); .AppendLine(" and test.f_tsgp = 1104848523 /* Product Data */ ")
results.Add(" on part.f_part = ctrl.f_part "); .AppendLine(" join [spcepiworld].[dbo].[part_dat] part ")
results.Add(" and ctrl.f_test = 1125073605 /* Average Sum of Defects */ "); .AppendLine(" on part.f_part = ctrl.f_part ")
results.Add(" join [spcepiworld].[dbo].[prcs_dat] process "); .AppendLine(" and ctrl.f_test = 1125073605 /* Average Sum of Defects */ ")
results.Add(" on process.f_prcs = ctrl.f_prcs "); .AppendLine(" join [spcepiworld].[dbo].[prcs_dat] process ")
results.Add(" where test.f_name = 'Average Sum of Defects' "); .AppendLine(" on process.f_prcs = ctrl.f_prcs ")
results.Add($" and process.f_name = '{process}' "); .AppendLine(" where test.f_name = 'Average Sum of Defects' ")
results.Add($" and part.f_name = '{part}' "); .Append(" and process.f_name = '").Append(process).AppendLine("' ")
results.Add(" for json path; "); .Append(" and part.f_name = '").Append(part).AppendLine("' ")
return string.Join(' ', results); .AppendLine(" for json path; ");
return result.ToString();
} // cSpell:enable } // cSpell:enable
string IInfinityQSV4Repository.GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(string process, string? recipe) string IInfinityQSV4Repository.GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(string process, string? recipe)
@ -389,56 +331,102 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
return result.ToString(); return result.ToString();
} }
private JsonElement[] GetAllReactorsAsJsonElementElement()
{
JsonElement[]? results;
HttpClient httpClient = _HttpClientFactory.CreateClient();
Task<string> task = httpClient.GetStringAsync($"{_OpenInsightApplicationProgrammingInterface}/reactors");
task.Wait();
JsonElement? jsonElement = JsonSerializer.Deserialize<JsonElement>(task.Result);
if (jsonElement is null)
throw new NullReferenceException(nameof(jsonElement));
string json = jsonElement.Value.EnumerateObject().First().Value.ToString();
results = JsonSerializer.Deserialize<JsonElement[]>(json);
if (results is null)
throw new NullReferenceException(nameof(results));
return results;
}
private ReadOnlyDictionary<int, Reactor> GetReactorsMatchingType(string? reactTypeFilter)
{
Dictionary<int, Reactor> results = new();
string json;
Reactor? reactor;
JsonElement[]? jsonElements = GetAllReactorsAsJsonElementElement();
foreach (JsonElement jsonElement in jsonElements)
{
json = jsonElement.EnumerateObject().First().Value.ToString();
if (reactTypeFilter is not null && !json.Contains(reactTypeFilter))
continue;
try
{ reactor = JsonSerializer.Deserialize(json, ReactorSourceGenerationContext.Default.Reactor); }
catch (Exception) { reactor = null; }
if (reactor is null || (reactTypeFilter is not null && reactor.ReactType != reactTypeFilter))
continue;
results.Add(reactor.ReactorNo, reactor);
}
return new(results);
}
string IInfinityQSV4Repository.GetCommandText(List<string> eppReactorNumbers) string IInfinityQSV4Repository.GetCommandText(List<string> eppReactorNumbers)
{ // cSpell:disable { // cSpell:disable
List<string> results = []; StringBuilder result = new();
results.Add(" select se.f_sgrp, "); _ = result
results.Add(" dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgrp), '19700101'))) date_time, "); .AppendLine(" select se.f_sgrp, ")
results.Add(" iq.pr_name, "); .AppendLine(" dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgrp), '19700101'))) date_time, ")
results.Add(" iq.pd_name, "); .AppendLine(" iq.pr_name, ")
results.Add(" max(case "); .AppendLine(" iq.pd_name, ")
results.Add(" when td.f_test = 1104769646 "); .AppendLine(" max(case ")
results.Add(" then se.f_val "); .AppendLine(" when td.f_test = 1104769646 ")
results.Add(" else null "); .AppendLine(" then se.f_val ")
results.Add(" end) as iq_value, "); .AppendLine(" else null ")
results.Add(" max(case "); .AppendLine(" end) as iq_value, ")
results.Add(" when td.f_test = 1312288843 "); .AppendLine(" max(case ")
results.Add(" then se.f_val else null "); .AppendLine(" when td.f_test = 1312288843 ")
results.Add(" end) as iq_temp_offset_percent "); .AppendLine(" then se.f_val else null ")
results.Add(" from ( "); .AppendLine(" end) as iq_temp_offset_percent ")
results.Add(" select "); .AppendLine(" from ( ")
results.Add(" max(se.f_sgrp) se_max_sgrp, "); .AppendLine(" select ")
results.Add(" se.f_test se_test, "); .AppendLine(" max(se.f_sgrp) se_max_sgrp, ")
results.Add(" pr.f_name pr_name, "); .AppendLine(" se.f_test se_test, ")
results.Add(" pd.f_name pd_name "); .AppendLine(" pr.f_name pr_name, ")
results.Add(" from [spcepiworld].[dbo].[sgrp_ext] se "); .AppendLine(" pd.f_name pd_name ")
results.Add(" join [spcepiworld].[dbo].[prcs_dat] pr "); .AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ")
results.Add(" on se.f_prcs = pr.f_prcs "); .AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
results.Add(" join [spcepiworld].[dbo].[part_dat] pd "); .AppendLine(" on se.f_prcs = pr.f_prcs ")
results.Add(" on se.f_part = pd.f_part "); .AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
results.Add(" where se.f_flag = 0 "); .AppendLine(" on se.f_part = pd.f_part ")
results.Add($" and pr.f_name in ({string.Join(',', eppReactorNumbers)}) "); .AppendLine(" where se.f_flag = 0 ")
results.Add(" and pd.f_name = '1090 - Full Load' "); .Append(" and pr.f_name in (").Append(string.Join(',', eppReactorNumbers)).AppendLine(") ")
results.Add(" and se.f_test in (1104769646, 1312288843) "); .AppendLine(" and pd.f_name = '1090 - Full Load' ")
results.Add(" group by se.f_test, "); .AppendLine(" and se.f_test in (1104769646, 1312288843) ")
results.Add(" pr.f_name, "); .AppendLine(" group by se.f_test, ")
results.Add(" pd.f_name "); .AppendLine(" pr.f_name, ")
results.Add(" ) as iq "); .AppendLine(" pd.f_name ")
results.Add(" join [spcepiworld].[dbo].[sgrp_ext] se "); .AppendLine(" ) as iq ")
results.Add(" on iq.se_max_sgrp = se.f_sgrp "); .AppendLine(" join [spcepiworld].[dbo].[sgrp_ext] se ")
results.Add(" join [spcepiworld].[dbo].[test_dat] td "); .AppendLine(" on iq.se_max_sgrp = se.f_sgrp ")
results.Add(" on iq.se_test = td.f_test "); .AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
results.Add(" and se.f_test = td.f_test "); .AppendLine(" on iq.se_test = td.f_test ")
results.Add(" where se.f_flag = 0 "); .AppendLine(" and se.f_test = td.f_test ")
results.Add(" and td.f_test in (1104769646, 1312288843) "); .AppendLine(" where se.f_flag = 0 ")
results.Add(" group by se.f_sgrp, "); .AppendLine(" and td.f_test in (1104769646, 1312288843) ")
results.Add(" iq.pr_name, "); .AppendLine(" group by se.f_sgrp, ")
results.Add(" iq.pd_name "); .AppendLine(" iq.pr_name, ")
results.Add(" order by iq.pr_name "); .AppendLine(" iq.pd_name ")
results.Add(" for json path; "); .AppendLine(" order by iq.pr_name ")
return string.Join(' ', results); .AppendLine(" for json path; ");
return result.ToString();
} // cSpell:enable } // cSpell:enable
private static List<string> Convert(int[] night)
{
List<string> results = new();
foreach (int reactor in night)
results.Add(reactor.ToString());
return results;
}
List<string[]> IInfinityQSV4Repository.GetEpiProTempVerificationRows(int[] night) List<string[]> IInfinityQSV4Repository.GetEpiProTempVerificationRows(int[] night)
{ {
List<string[]>? results; List<string[]>? results;
@ -603,10 +591,7 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
{ {
List<string> lines = new(); List<string> lines = new();
foreach (char ch in runDataSheetRoot.RunDataSheet.PSN) foreach (char ch in runDataSheetRoot.RunDataSheet.PSN)
{ { }
if (ch is '1')
continue;
}
result = string.Join(Environment.NewLine, lines); result = string.Join(Environment.NewLine, lines);
} }
} }
@ -648,55 +633,151 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
return result; return result;
} }
private static string GetCommandText(string process, string? part, int? test) private void GetOI(InfinityQSV4 infinityQSV4)
{ // cSpell:disable
List<string> results = [];
if (string.IsNullOrEmpty(process))
throw new ArgumentException(null, nameof(process));
if (string.IsNullOrEmpty(part))
throw new ArgumentException(null, nameof(part));
if (test is null)
throw new ArgumentException(null, nameof(test));
results.Add(" select se_max_sgrp, se.f_val se_value ");
results.Add(" from ( ");
results.Add(" select ");
results.Add(" max(se.f_sgrp) se_max_sgrp ");
results.Add(" from [spcepiworld].[dbo].[sgrp_ext] se ");
results.Add(" join [spcepiworld].[dbo].[prcs_dat] pr ");
results.Add(" on se.f_prcs = pr.f_prcs ");
results.Add(" join [spcepiworld].[dbo].[part_dat] pd ");
results.Add(" on se.f_part = pd.f_part ");
results.Add(" where se.f_flag = 0 ");
results.Add(" and se.f_tsno = 1 ");
results.Add($" and pr.f_name = '{process}' ");
results.Add($" and pd.f_name = '{part}' ");
results.Add($" and se.f_test = {test.Value} ");
results.Add(" ) as iq ");
results.Add(" join [spcepiworld].[dbo].[sgrp_ext] se ");
results.Add(" on se_max_sgrp = se.f_sgrp ");
results.Add(" where se.f_flag = 0 ");
results.Add(" and se.f_tsno = 1 ");
results.Add($" and se.f_test = {test.Value} ");
results.Add(" for json path ");
return string.Join(' ', results);
} // cSpell:enable
string IInfinityQSV4Repository.GetLastGroupIdWithValue(string process, string? part, int? test)
{ {
StringBuilder result; IInfinityQSV4Repository infinityQSV4Repository = this;
if (string.IsNullOrEmpty(infinityQSV4.Part))
throw new ArgumentException(nameof(infinityQSV4.Part));
string json = infinityQSV4Repository.GetProductionSpecification(infinityQSV4.Part);
ProdSpecRoot? prodSpec = JsonSerializer.Deserialize(json, ProdSpecRootSourceGenerationContext.Default.ProdSpecRoot);
if (prodSpec is null)
{
if (prodSpec is null)
{ }
}
}
private static Record? GetValue(AppSettings appSettings, string line)
{
Record? result;
string[] attributes = line.Split('>');
if (attributes.Length != 3)
result = null;
else
{
string[] text = attributes[1].Replace(appSettings.IqsRed, "red").Replace(appSettings.IqsYellow, "Yellow").Split($"</{line[1]}{line[2]}");
if (text.Length != 2)
result = null;
else
{
string[] attributeValues = attributes[0].Split('"');
if (attributeValues.Length != 3)
result = new(null, text[0]);
else
{
result = new(attributeValues[1], text[0]);
}
}
}
return result;
}
private static ReadOnlyCollection<Record> GetRecords(AppSettings appSettings, string file)
{
Record? record;
List<Record> results = new();
List<string> checkColumns = new();
string[] lines = File.ReadAllLines(file);
foreach (string line in lines)
{
if (line.StartsWith("<th"))
{
record = GetValue(appSettings, line);
if (record is null)
continue;
checkColumns.Add(record.Text);
}
if (line.StartsWith("<td"))
{
record = GetValue(appSettings, line);
if (record is null)
continue;
results.Add(record);
}
}
if (string.Join(',', checkColumns) != appSettings.IqsColumns)
throw new NotSupportedException("Columns don't match!");
return new(results);
}
private static List<Dictionary<string, Record>> GetCollection(string columns, ReadOnlyCollection<Record> records)
{
string[] columnNames = columns.Split(',');
List<Dictionary<string, Record>> collection = new();
Dictionary<string, Record> keyValuePairs;
for (int i = 0; i < records.Count; i++)
{
keyValuePairs = new();
for (int j = 0; j < columnNames.Length; j++)
{
keyValuePairs.Add(columnNames[j], records[i]);
i++;
}
i--;
collection.Add(keyValuePairs);
}
return collection;
}
private static Dictionary<string, List<string>> GetResults(AppSettings appSettings, List<Dictionary<string, Record>> collection)
{
Dictionary<string, List<string>> results = new();
Record record;
List<string>? colors;
foreach (Dictionary<string, Record> keyValuePairs in collection)
{
record = keyValuePairs[appSettings.IqsKey];
if (!results.TryGetValue(record.Text, out colors))
{
results.Add(record.Text, new());
if (!results.TryGetValue(record.Text, out colors))
throw new Exception();
}
if (record.Color is null)
continue;
colors.Add(record.Color.Replace(appSettings.IqsRed, "red").Replace(appSettings.IqsYellow, "Yellow"));
}
foreach (KeyValuePair<string, List<string>> keyValuePair in results)
keyValuePair.Value.Sort();
return results;
}
private static void FileFindReplaceAndSave(AppSettings appSettings, string iqsFile, FileInfo fileInfo)
{
string lines = File.ReadAllText(iqsFile).Replace(appSettings.IqsRed, "red").Replace(appSettings.IqsYellow, "Yellow");
File.WriteAllText(fileInfo.FullName, lines);
}
Dictionary<string, List<string>> IInfinityQSV4Repository.GetEngineeringSpcReview()
{
Dictionary<string, List<string>>? results;
if (!string.IsNullOrEmpty(_MockRoot)) if (!string.IsNullOrEmpty(_MockRoot))
{ {
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV4Repository.GetLastGroupIdWithValue)}.json")); string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV4Repository.GetEngineeringSpcReview)}.json"));
result = new(json); results = JsonSerializer.Deserialize<Dictionary<string, List<string>>>(json);
if (results is null)
throw new NullReferenceException(nameof(results));
} }
else else
{ {
string commandText = GetCommandText(process, part, test); FileInfo iqsFileInfo = new(_AppSettings.IqsFile);
result = GetForJsonPath(_DBConnectionFactory, commandText, useIqsConnection: false); Assembly assembly = Assembly.GetExecutingAssembly();
if (result.Length == 0) string? assemblyName = assembly.GetName()?.Name;
result = new("{}"); if (string.IsNullOrEmpty(assemblyName))
throw new Exception();
FileInfo localFileInfo = new(Path.Combine(AppContext.BaseDirectory, "wwwroot", iqsFileInfo.Name));
if (!localFileInfo.Exists && (!iqsFileInfo.Exists || iqsFileInfo.Length == 0))
results = new();
else
{
if (!localFileInfo.Exists || localFileInfo.LastWriteTime != iqsFileInfo.LastWriteTime)
FileFindReplaceAndSave(_AppSettings, iqsFileInfo.FullName, localFileInfo);
ReadOnlyCollection<Record> records = !iqsFileInfo.Exists || iqsFileInfo.Length == 0 ? GetRecords(_AppSettings, localFileInfo.FullName) : GetRecords(_AppSettings, iqsFileInfo.FullName);
List<Dictionary<string, Record>> collection = GetCollection(_AppSettings.IqsColumns, records);
results = GetResults(_AppSettings, collection);
}
} }
return result.ToString(); return results;
} }
} }

View File

@ -16,7 +16,6 @@ namespace OI.Metrology.Server.Repositories;
public class MetrologyRepository : IMetrologyRepository public class MetrologyRepository : IMetrologyRepository
{ {
private readonly string _MockRoot; private readonly string _MockRoot;
private readonly string _RepositoryName; private readonly string _RepositoryName;
private readonly IMemoryCache _MemoryCache; private readonly IMemoryCache _MemoryCache;
@ -33,8 +32,7 @@ public class MetrologyRepository : IMetrologyRepository
protected DbProviderFactory GetDbProviderFactory(IDbConnection conn) => protected DbProviderFactory GetDbProviderFactory(IDbConnection conn) =>
DbProviderFactories.GetFactory(conn.GetType().Namespace); DbProviderFactories.GetFactory(conn.GetType().Namespace);
internal static TransactionScope StartTransaction() => internal static TransactionScope StartTransaction() => new();
new();
protected void CacheItem(string key, object v) protected void CacheItem(string key, object v)
{ {
@ -58,7 +56,7 @@ public class MetrologyRepository : IMetrologyRepository
return r; return r;
} }
ToolType IMetrologyRepository.GetToolTypeByName(string name) internal ToolType GetToolTypeByName(string name)
{ {
ToolType cached; ToolType cached;
string cacheKey = "GetToolTypeByName_" + name; string cacheKey = "GetToolTypeByName_" + name;
@ -109,7 +107,7 @@ public class MetrologyRepository : IMetrologyRepository
return r; return r;
} }
long IMetrologyRepository.InsertToolDataJSON(JToken jsonrow, long headerId, List<ToolTypeMetadata> metaData, string tableName) internal long InsertToolDataJSON(JToken jsonrow, long headerId, List<ToolTypeMetadata> metaData, string tableName)
{ {
long r = -1; long r = -1;
using (DbConnection conn = _DBConnectionFactory.GetDbConnection()) using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
@ -117,8 +115,7 @@ public class MetrologyRepository : IMetrologyRepository
bool isHeader = headerId <= 0; bool isHeader = headerId <= 0;
// get fields from metadata // get fields from metadata
List<ToolTypeMetadata> fields = metaData.Where(md => List<ToolTypeMetadata> fields = metaData.Where(md => md.Header == isHeader).ToList();
md.Header == isHeader).ToList();
// maps ApiName to ColumnName // maps ApiName to ColumnName
Dictionary<string, string> fieldmap = new(); Dictionary<string, string> fieldmap = new();
@ -158,8 +155,7 @@ public class MetrologyRepository : IMetrologyRepository
else else
{ {
// Find the container field in the json // Find the container field in the json
JProperty contJP = jsonrow.Children<JProperty>().Where(c => JProperty contJP = jsonrow.Children<JProperty>().Where(c => string.Equals(c.Name.Trim(), containerField, StringComparison.OrdinalIgnoreCase)).SingleOrDefault();
string.Equals(c.Name.Trim(), containerField, StringComparison.OrdinalIgnoreCase)).SingleOrDefault();
if ((contJP is not null) && (contJP.Value is JArray array)) if ((contJP is not null) && (contJP.Value is JArray array))
{ {
@ -186,7 +182,7 @@ public class MetrologyRepository : IMetrologyRepository
_ = cmd.Parameters.Add(p); _ = cmd.Parameters.Add(p);
} }
private long InsertRowFromJSON( protected long InsertRowFromJSON(
IDbConnection conn, IDbConnection conn,
string tableName, string tableName,
JToken jsonrow, JToken jsonrow,
@ -266,7 +262,7 @@ public class MetrologyRepository : IMetrologyRepository
return Convert.ToInt64(o); return Convert.ToInt64(o);
} }
DataTable IMetrologyRepository.ExportData(string spName, DateTime startTime, DateTime endTime) internal DataTable ExportData(string spName, DateTime startTime, DateTime endTime)
{ {
DataTable dt = new(); DataTable dt = new();
DateTime endTimeLocal = endTime.ToLocalTime(); DateTime endTimeLocal = endTime.ToLocalTime();
@ -316,7 +312,7 @@ public class MetrologyRepository : IMetrologyRepository
return sb.ToString(); return sb.ToString();
} }
DataTable IMetrologyRepository.GetHeaders(int toolTypeId, string? startTime, string? endTime, int? pageNo, int? pageSize, long? headerId, out long totalRecords) internal DataTable GetHeaders(int toolTypeId, string? startTime, string? endTime, int? pageNo, int? pageSize, long? headerId, out long totalRecords)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -328,8 +324,7 @@ public class MetrologyRepository : IMetrologyRepository
StringBuilder sb = new(); StringBuilder sb = new();
_ = sb.Append( _ = sb.Append(
FormDynamicSelectQuery( FormDynamicSelectQuery(
md.Where(m => md.Where(m => m.Header == true).ToList(),
m.Header == true).ToList(),
tt.HeaderTableName) tt.HeaderTableName)
); );
@ -406,7 +401,7 @@ public class MetrologyRepository : IMetrologyRepository
return dt; return dt;
} }
DataTable IMetrologyRepository.GetData(int toolTypeId, long headerid) internal DataTable GetData(int toolTypeId, long headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -418,9 +413,7 @@ public class MetrologyRepository : IMetrologyRepository
StringBuilder sb = new(); StringBuilder sb = new();
_ = sb.Append( _ = sb.Append(
FormDynamicSelectQuery( FormDynamicSelectQuery(
md.Where(m => md.Where(m => m.Header == false).OrderBy(m => m.GridDisplayOrder).ToList(),
m.Header == false).OrderBy(m =>
m.GridDisplayOrder).ToList(),
tt.DataTableName) tt.DataTableName)
); );
@ -499,32 +492,17 @@ public class MetrologyRepository : IMetrologyRepository
return dt; return dt;
} }
Guid IMetrologyRepository.GetHeaderAttachmentID(int toolTypeId, long headerId) internal Guid GetHeaderAttachmentID(int toolTypeId, long headerId)
{
Guid result;
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
$"SELECT AttachmentID FROM [{tt.HeaderTableName}] WHERE ID = @HeaderID";
result = conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId });
return result;
}
void IMetrologyRepository.SetHeaderAttachmentID(int toolTypeId, long headerId, string attachmentId)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = string sql =
$"UPDATE [{tt.HeaderTableName}] SET AttachmentID = @AttachmentID WHERE ID = @HeaderID AND AttachmentID IS NULL; " + $"UPDATE [{tt.HeaderTableName}] SET AttachmentID = NEWID() WHERE ID = @HeaderID AND AttachmentID IS NULL; " +
$"SELECT AttachmentID FROM [{tt.HeaderTableName}] WHERE ID = @HeaderID"; $"SELECT AttachmentID FROM [{tt.HeaderTableName}] WHERE ID = @HeaderID";
Guid guid = conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId, AttachmentID = attachmentId }); return conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId });
if (attachmentId != guid.ToString())
throw new NotSupportedException($"{attachmentId} != {guid}");
} }
internal string GetHeaderInsertDate(int toolTypeId, long headerId)
string IMetrologyRepository.GetHeaderInsertDate(int toolTypeId, long headerId)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -533,8 +511,7 @@ public class MetrologyRepository : IMetrologyRepository
$"SELECT CONVERT(varchar, case when [InsertDate] < [Date] or [Date] is null then [InsertDate] else [Date] end, 120) d FROM[{tt.HeaderTableName}] where ID = @HeaderID"; $"SELECT CONVERT(varchar, case when [InsertDate] < [Date] or [Date] is null then [InsertDate] else [Date] end, 120) d FROM[{tt.HeaderTableName}] where ID = @HeaderID";
return conn.ExecuteScalar<string>(sql, param: new { HeaderID = headerId }); return conn.ExecuteScalar<string>(sql, param: new { HeaderID = headerId });
} }
internal string GetAttachmentInsertDateByGUID(string tableName, Guid attachmentId)
string IMetrologyRepository.GetAttachmentInsertDateByGUID(string tableName, Guid attachmentId)
{ {
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = ""; string sql = "";
@ -549,27 +526,24 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<string>(sql, param: new { AttachmentID = attachmentId }); return conn.ExecuteScalar<string>(sql, param: new { AttachmentID = attachmentId });
} }
internal void SetHeaderDirName(string tableName, long headerId, string dateDir)
void IMetrologyRepository.SetHeaderDirName(string tableName, long headerId, string dateDir)
{ {
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
_ = conn.Execute($"UPDATE [{tableName}] SET AttachDirName = @AttachDirName WHERE ID = @HeaderID;", new { HeaderID = headerId, AttachDirName = dateDir }); _ = conn.Execute($"UPDATE [{tableName}] SET AttachDirName = @AttachDirName WHERE ID = @HeaderID;", new { HeaderID = headerId, AttachDirName = dateDir });
} }
void IMetrologyRepository.SetDataAttachmentID(int toolTypeId, long headerId, string title, string attachmentId) internal Guid GetDataAttachmentID(int toolTypeId, long headerId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = string sql =
$"UPDATE [{tt.DataTableName}] SET AttachmentID = @AttachmentID WHERE HeaderID = @HeaderID AND Title = @Title AND AttachmentID IS NULL; " + $"UPDATE [{tt.DataTableName}] SET AttachmentID = NEWID() WHERE HeaderID = @HeaderID AND Title = @Title AND AttachmentID IS NULL; " +
$"SELECT AttachmentID FROM [{tt.DataTableName}] WHERE HeaderID = @HeaderID AND Title = @Title"; $"SELECT AttachmentID FROM [{tt.DataTableName}] WHERE HeaderID = @HeaderID AND Title = @Title";
Guid guid = conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId, AttachmentID = attachmentId, Title = title }); return conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId, Title = title });
if (attachmentId != guid.ToString())
throw new NotSupportedException($"{attachmentId} != {guid}");
} }
// J Ouellette Added
string IMetrologyRepository.GetDataInsertDate(int toolTypeId, long headerId, string title) internal string GetDataInsertDate(int toolTypeId, long headerId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -586,8 +560,7 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<string>(sql, param: new { HeaderID = headerId, Title = title }); return conn.ExecuteScalar<string>(sql, param: new { HeaderID = headerId, Title = title });
} }
internal void SetDataDirName(string tableName, long headerId, string title, string dateDir)
void IMetrologyRepository.SetDataDirName(string tableName, long headerId, string title, string dateDir)
{ {
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = string sql =
@ -595,13 +568,13 @@ public class MetrologyRepository : IMetrologyRepository
_ = conn.Execute(sql, param: new { HeaderID = headerId, Title = title, AttachDirName = dateDir }); _ = conn.Execute(sql, param: new { HeaderID = headerId, Title = title, AttachDirName = dateDir });
} }
void IMetrologyRepository.PurgeExistingData(int toolTypeId, string title) internal void PurgeExistingData(int toolTypeId, string title)
{ {
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
_ = conn.Execute("PurgeExistingData", param: new { ToolTypeID = toolTypeId, Title = title }, commandType: CommandType.StoredProcedure); _ = conn.Execute("PurgeExistingData", param: new { ToolTypeID = toolTypeId, Title = title }, commandType: CommandType.StoredProcedure);
} }
DataSet IMetrologyRepository.GetOIExportData(int toolTypeId, long headerid) internal DataSet GetOIExportData(int toolTypeId, long headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -653,7 +626,7 @@ public class MetrologyRepository : IMetrologyRepository
return results.ToArray(); return results.ToArray();
} }
HeaderCommon[] IMetrologyRepository.GetHeaderTitles(int? toolTypeId, int? pageNo, int? pageSize, out long totalRecords) internal HeaderCommon[] GetHeaderTitles(int? toolTypeId, int? pageNo, int? pageSize, out long totalRecords)
{ {
HeaderCommon[] headers; HeaderCommon[] headers;
if (toolTypeId is not null && (pageNo is not null || pageSize is not null)) if (toolTypeId is not null && (pageNo is not null || pageSize is not null))
@ -689,7 +662,7 @@ public class MetrologyRepository : IMetrologyRepository
return headers; return headers;
} }
IEnumerable<KeyValuePair<string, string>> IMetrologyRepository.GetHeaderFields(int toolTypeId, long headerid) internal IEnumerable<KeyValuePair<string, string>> GetHeaderFields(int toolTypeId, long headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -716,9 +689,7 @@ public class MetrologyRepository : IMetrologyRepository
if (dt.Rows.Count > 0) if (dt.Rows.Count > 0)
dr = dt.Rows[0]; dr = dt.Rows[0];
foreach (ToolTypeMetadata m in md.Where(m => foreach (ToolTypeMetadata m in md.Where(m => m.Header == true && m.TableDisplayOrder > 0).OrderBy(m => m.TableDisplayOrder))
m.Header == true && m.TableDisplayOrder > 0).OrderBy(m =>
m.TableDisplayOrder))
{ {
string v = ""; string v = "";
if (dr is not null) if (dr is not null)
@ -734,7 +705,7 @@ public class MetrologyRepository : IMetrologyRepository
return r; return r;
} }
IEnumerable<AwaitingDisposition> IMetrologyRepository.GetAwaitingDisposition() internal IEnumerable<AwaitingDisposition> GetAwaitingDisposition()
{ {
IEnumerable<AwaitingDisposition>? r; IEnumerable<AwaitingDisposition>? r;
if (!string.IsNullOrEmpty(_MockRoot)) if (!string.IsNullOrEmpty(_MockRoot))
@ -752,7 +723,7 @@ public class MetrologyRepository : IMetrologyRepository
return r; return r;
} }
int IMetrologyRepository.UpdateReviewDate(int toolTypeId, long headerId, bool clearDate) internal int UpdateReviewDate(int toolTypeId, long headerId, bool clearDate)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -772,7 +743,7 @@ public class MetrologyRepository : IMetrologyRepository
} }
} }
Guid IMetrologyRepository.GetHeaderAttachmentIDByTitle(int toolTypeId, string title) internal Guid GetHeaderAttachmentIDByTitle(int toolTypeId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -782,7 +753,7 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<Guid>(sql, param: new { Title = title }); return conn.ExecuteScalar<Guid>(sql, param: new { Title = title });
} }
Guid IMetrologyRepository.GetDataAttachmentIDByTitle(int toolTypeId, string title) internal Guid GetDataAttachmentIDByTitle(int toolTypeId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -792,13 +763,31 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<Guid>(sql, param: new { Title = title }); return conn.ExecuteScalar<Guid>(sql, param: new { Title = title });
} }
IEnumerable<ToolType> IMetrologyRepository.GetToolTypes() => DataTable IMetrologyRepository.GetDataSharePoint(int toolTypeId, string headerId) => throw new NotImplementedException();
GetToolTypes();
ToolType IMetrologyRepository.GetToolTypeByID(int id) => IEnumerable<ToolType> IMetrologyRepository.GetToolTypes() => GetToolTypes();
GetToolTypeByID(id); ToolType IMetrologyRepository.GetToolTypeByName(string name) => GetToolTypeByName(name);
TransactionScope IMetrologyRepository.StartTransaction() => ToolType IMetrologyRepository.GetToolTypeByID(int id) => GetToolTypeByID(id);
StartTransaction(); IEnumerable<ToolTypeMetadata> IMetrologyRepository.GetToolTypeMetadataByToolTypeID(int id) => GetToolTypeMetadataByToolTypeID(id);
IEnumerable<ToolTypeMetadata> IMetrologyRepository.GetToolTypeMetadataByToolTypeID(int id) => TransactionScope IMetrologyRepository.StartTransaction() => StartTransaction();
GetToolTypeMetadataByToolTypeID(id); void IMetrologyRepository.PurgeExistingData(int toolTypeId, string title) => PurgeExistingData(toolTypeId, title);
long IMetrologyRepository.InsertToolDataJSON(JToken jsonbody, long headerId, List<ToolTypeMetadata> metaData, string tableName) => InsertToolDataJSON(jsonbody, headerId, metaData, tableName);
DataTable IMetrologyRepository.ExportData(string spName, DateTime startTime, DateTime endTime) => ExportData(spName, startTime, endTime);
DataTable IMetrologyRepository.GetHeaders(int toolTypeId, string? startTime, string? endTime, int? pageNo, int? pageSize, long? headerid, out long totalRecords) => GetHeaders(toolTypeId, startTime, endTime, pageNo, pageSize, headerid, out totalRecords);
DataTable IMetrologyRepository.GetData(int toolTypeId, long headerId) => GetData(toolTypeId, headerId);
HeaderCommon[] IMetrologyRepository.GetHeaderTitles(int? toolTypeId, int? pageNo, int? pageSize, out long totalRecords) => GetHeaderTitles(toolTypeId, pageNo, pageSize, out totalRecords);
Guid IMetrologyRepository.GetHeaderAttachmentIDByTitle(int toolTypeId, string title) => GetHeaderAttachmentIDByTitle(toolTypeId, title);
Guid IMetrologyRepository.GetDataAttachmentIDByTitle(int toolTypeId, string title) => GetDataAttachmentIDByTitle(toolTypeId, title);
Guid IMetrologyRepository.GetHeaderAttachmentID(int toolTypeId, long headerId) => GetHeaderAttachmentID(toolTypeId, headerId);
string IMetrologyRepository.GetHeaderInsertDate(int toolTypeId, long headerId) => GetHeaderInsertDate(toolTypeId, headerId);
string IMetrologyRepository.GetAttachmentInsertDateByGUID(string tableName, Guid attachmentId) => GetAttachmentInsertDateByGUID(tableName, attachmentId);
void IMetrologyRepository.SetHeaderDirName(string tableName, long headerId, string dateDir) => SetHeaderDirName(tableName, headerId, dateDir);
Guid IMetrologyRepository.GetDataAttachmentID(int toolTypeId, long headerId, string title) => GetDataAttachmentID(toolTypeId, headerId, title);
string IMetrologyRepository.GetDataInsertDate(int toolTypeId, long headerId, string title) => GetDataInsertDate(toolTypeId, headerId, title);
void IMetrologyRepository.SetDataDirName(string tableName, long headerId, string title, string dateDir) => SetDataDirName(tableName, headerId, title, dateDir);
DataSet IMetrologyRepository.GetOIExportData(int toolTypeId, long headerid) => GetOIExportData(toolTypeId, headerid);
IEnumerable<KeyValuePair<string, string>> IMetrologyRepository.GetHeaderFields(int toolTypeId, long headerid) => GetHeaderFields(toolTypeId, headerid);
IEnumerable<AwaitingDisposition> IMetrologyRepository.GetAwaitingDisposition() => GetAwaitingDisposition();
int IMetrologyRepository.UpdateReviewDate(int toolTypeId, long headerId, bool clearDate) => UpdateReviewDate(toolTypeId, headerId, clearDate);
} }

View File

@ -0,0 +1,146 @@
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless;
using System.Globalization;
using System.Text.Json;
namespace OI.Metrology.Server.Repository;
public class ReactorsRepository : IReactorsRepository
{
private readonly AppSettings _AppSettings;
private readonly Dictionary<int, char> _SecondsToAlpha;
public ReactorsRepository(AppSettings appSettings)
{
_AppSettings = appSettings;
_SecondsToAlpha = new();
for (int i = 65; i < 91; i++)
{
if (i is 73 or 79)
continue;
_SecondsToAlpha.Add(i - 65, (char)i);
}
}
Result<int[]> IReactorsRepository.EvenReactors()
{
Result<int[]> results;
int[] collection = new int[] {
20,
22,
24,
26,
28,
30,
32,
34,
36,
38,
40,
42,
44,
46,
48,
50,
52,
54,
56,
58,
60,
62,
64,
66,
68,
70,
72,
74
};
results = new()
{
Results = collection,
TotalRows = collection.Length,
};
return results;
}
Result<int[]> IReactorsRepository.OddReactors()
{
Result<int[]> results;
int[] collection = new int[] {
21,
23,
25,
27,
29,
31,
33,
35,
37,
39,
41,
43,
45,
47,
49,
51,
53,
55,
57,
59,
61,
63,
65,
73,
75,
77,
79
};
results = new()
{
Results = collection,
TotalRows = collection.Length,
};
return results;
}
string? IReactorsRepository.GetKey(WorkMaterialOut workMaterialOut, bool save)
{
if (workMaterialOut is null)
throw new Exception();
if (workMaterialOut.Username is null || workMaterialOut.Username.Length < 2)
throw new ArgumentException(nameof(workMaterialOut.Username));
if (workMaterialOut.RunDataSheet is null || workMaterialOut.RunDataSheet.Length < 2)
throw new ArgumentException(nameof(workMaterialOut.RunDataSheet));
string? result = null;
char c;
string? fileName = null;
DateTime dateTime = DateTime.Now;
Calendar calendar = new CultureInfo("en-US").Calendar;
string json = JsonSerializer.Serialize(workMaterialOut, new JsonSerializerOptions { WriteIndented = true });
string weekOfYear = $"{dateTime:yyyy}_Week_{calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
string directory = Path.Combine(_AppSettings.ApiExportPath, "WorkMaterialOut", "API", weekOfYear, dateTime.ToString("yyyy-MM-dd_HH"));
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
for (int i = 0; i < int.MaxValue; i++)
{
dateTime = dateTime.AddSeconds(i);
if (!_SecondsToAlpha.TryGetValue(dateTime.Second, out c))
continue;
fileName = Path.Combine(directory, $"WMO-{dateTime:mm}{c}.json");
if (!File.Exists(fileName))
{
result = $"{c}{dateTime:mm}";
break;
}
}
if (fileName is null)
throw new Exception();
if (save)
File.WriteAllText(fileName, json);
return result;
}
}

View File

@ -3,6 +3,7 @@ using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Services; using OI.Metrology.Shared.Services;
using System.Data; using System.Data;
using System.Text;
using System.Text.Json; using System.Text.Json;
namespace OI.Metrology.Server.Repository; namespace OI.Metrology.Server.Repository;
@ -12,16 +13,10 @@ public class ToolTypesRepository : IToolTypesRepository
private readonly string _MockRoot; private readonly string _MockRoot;
private readonly string _RepositoryName; private readonly string _RepositoryName;
private readonly AppSettings _AppSettings;
private readonly IHttpClientFactory _HttpClientFactory;
private readonly IFileShareRepository _FileShareRepository;
public ToolTypesRepository(AppSettings appSettings, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository) public ToolTypesRepository(AppSettings appSettings)
{ {
_AppSettings = appSettings;
_MockRoot = appSettings.MockRoot; _MockRoot = appSettings.MockRoot;
_HttpClientFactory = httpClientFactory;
_FileShareRepository = fileShareRepository;
_RepositoryName = nameof(ToolTypesRepository)[..^10]; _RepositoryName = nameof(ToolTypesRepository)[..^10];
} }
@ -208,7 +203,7 @@ public class ToolTypesRepository : IToolTypesRepository
return new(message, contentType, stream); return new(message, contentType, stream);
} }
string? IToolTypesRepository.OIExport(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, int toolTypeId, long headerid) string? IToolTypesRepository.OIExport(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, string attachmentPath, Dictionary<string, string> tableToPath, int toolTypeId, long headerid)
{ {
string? result; string? result;
ToolType toolType = metrologyRepository.GetToolTypeByID(toolTypeId); ToolType toolType = metrologyRepository.GetToolTypeByID(toolTypeId);
@ -216,18 +211,16 @@ public class ToolTypesRepository : IToolTypesRepository
result = $"Invalid tool id [{toolTypeId}] [{headerid}]!"; result = $"Invalid tool id [{toolTypeId}] [{headerid}]!";
else else
{ {
string? processDataStandardFormat = attachmentsService.GetProcessDataStandardFormat(metrologyRepository, toolTypeId, headerid); string? processDataStandardFormat = attachmentsService.GetProcessDataStandardFormat(metrologyRepository, attachmentPath, toolTypeId, headerid);
if (processDataStandardFormat is null) if (processDataStandardFormat is null)
result = $"Export file doesn't exist for [{toolTypeId}] [{headerid}] at <{_AppSettings.EcMesaFileShareMetrologySi}>!"; result = $"Export file doesn't exist for [{toolTypeId}] [{headerid}] at <{attachmentPath}>!";
else if (!_AppSettings.TableToPath.TryGetValue(toolType.HeaderTableName, out string? directly)) else if (!tableToPath.TryGetValue(toolType.HeaderTableName, out string? directly))
result = $"Export file doesn't exist for [{toolTypeId}] [{headerid}] at <{_AppSettings.EcMesaFileShareMetrologySi}>!"; result = $"Export file doesn't exist for [{toolTypeId}] [{headerid}] at <{attachmentPath}>!";
else else
{ {
try try
{ {
HttpClient httpClient = _HttpClientFactory.CreateClient(); File.Copy(processDataStandardFormat, Path.Combine(directly, $"Viewer_{Path.GetFileName(processDataStandardFormat)}"));
httpClient.BaseAddress = new(_AppSettings.ApiFileShare);
_FileShareRepository.CopyFile(httpClient, processDataStandardFormat, Path.Combine(directly, $"Viewer_{Path.GetFileName(processDataStandardFormat)}"));
result = null; result = null;
} }
catch (Exception ex) { result = ex.Message; } catch (Exception ex) { result = ex.Message; }
@ -236,4 +229,96 @@ public class ToolTypesRepository : IToolTypesRepository
return result; return result;
} }
Result<DataTable> IToolTypesRepository.GetExportData(IMetrologyRepository metrologyRepository, int toolTypeId, string? datebegin, string? dateend)
{
Result<DataTable>? r;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IToolTypesRepository.GetExportData)}.json"));
r = Newtonsoft.Json.JsonConvert.DeserializeObject<Result<DataTable>>(json);
if (r is null)
throw new NullReferenceException(nameof(r));
}
else
{
DateTime dateEnd = dateend is null ? DateTime.Now : DateTime.Parse(dateend);
DateTime dateBegin = datebegin is null ? dateEnd.AddMonths(-1) : DateTime.Parse(datebegin);
ToolType tt = metrologyRepository.GetToolTypeByID(toolTypeId);
if (string.IsNullOrEmpty(tt.ExportSPName))
throw new NullReferenceException(nameof(tt.ExportSPName));
DataTable dataTable = metrologyRepository.ExportData(tt.ExportSPName, dateBegin, dateEnd);
r = new()
{
Results = dataTable,
TotalRows = dataTable.Rows.Count,
};
}
return r;
}
protected static string FormatForCSV(string v)
{
StringBuilder result = new(v.Length + 2);
bool doubleQuoted = false;
if (v.StartsWith(' ') || v.EndsWith(' ') || v.Contains(',') || v.Contains('"'))
{
_ = result.Append('"');
doubleQuoted = true;
}
foreach (char c in v)
{
_ = c switch
{
'\r' or '\n' => result.Append(' '),
'"' => result.Append("\"\""),
_ => result.Append(c),
};
}
if (doubleQuoted)
_ = result.Append('"');
return result.ToString();
}
protected static string GetColumnHeaders(DataTable dataTable)
{
StringBuilder result = new();
for (int i = 0; i < dataTable.Columns.Count; i++)
{
if (i > 0)
_ = result.Append(',');
_ = result.Append(FormatForCSV(dataTable.Columns[i].ColumnName.TrimEnd('_')));
}
return result.ToString();
}
protected static string GetRowData(DataRow dr)
{
StringBuilder result = new();
for (int i = 0; i < dr.Table.Columns.Count; i++)
{
if (i > 0)
_ = result.Append(',');
object v = dr[i];
if (v is not null && !Convert.IsDBNull(v))
_ = result.Append(FormatForCSV(string.Concat(Convert.ToString(v))));
}
return result.ToString();
}
byte[] IToolTypesRepository.GetCSVExport(IMetrologyRepository metrologyRepository, int toolTypeId, string? datebegin, string? dateend)
{
byte[] results;
Result<DataTable> result;
IToolTypesRepository repository = this;
result = repository.GetExportData(metrologyRepository, toolTypeId, datebegin, dateend);
if (result.Results is null)
throw new NullReferenceException(nameof(result.Results));
StringBuilder stringBuilder = new();
_ = stringBuilder.AppendLine(GetColumnHeaders(result.Results));
foreach (DataRow dr in result.Results.Rows)
_ = stringBuilder.AppendLine(GetRowData(dr));
results = Encoding.UTF8.GetBytes(stringBuilder.ToString());
return results;
}
} }

View File

@ -0,0 +1,228 @@
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Repositories;
using System.Globalization;
using System.Text.Json;
namespace OI.Metrology.Server.Repository;
public class WaferCounterRepository : IWaferCounterRepository
{
private record Record(int Check,
int Total,
string? SlotMap);
private readonly string _MockRoot;
private readonly string _RepositoryName;
private readonly AppSettings _AppSettings;
private readonly IHttpClientFactory _HttpClientFactory;
private readonly IDbConnectionFactory _DBConnectionFactory;
private readonly string _OpenInsightApplicationProgrammingInterface;
public WaferCounterRepository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory, IHttpClientFactory httpClientFactory)
{
_AppSettings = appSettings;
_MockRoot = appSettings.MockRoot;
_HttpClientFactory = httpClientFactory;
_DBConnectionFactory = dbConnectionFactory;
_RepositoryName = nameof(WaferCounterRepository)[..^10];
_OpenInsightApplicationProgrammingInterface = appSettings.OpenInsightApplicationProgrammingInterface;
}
private static void MoveFile(string waferSizeDirectory, FileInfo fileInfo)
{
Calendar calendar = new CultureInfo("en-US").Calendar;
string weekOfYear = $"{fileInfo.LastWriteTime:yyyy}_Week_{calendar.GetWeekOfYear(fileInfo.LastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
string checkDirectory = Path.Combine(waferSizeDirectory, "Archive", weekOfYear);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
string checkFile = Path.Combine(checkDirectory, fileInfo.Name);
if (!File.Exists(checkFile))
File.Move(fileInfo.FullName, checkFile);
}
private static Record GetRecord(string line1, string line2)
{
Record result;
string? waferMap = string.IsNullOrEmpty(line2) || line2.Length != 8 ? null : line2.Substring(1, 1);
int check = waferMap == "1" ? 1 : 0;
int total = int.Parse(line1[1..]);
// string wafers = Array.from(line2[2..]);
foreach (char item in line2[2..])
{
switch (item)
{
case '0':
check += 0;
waferMap += "0000";
break;
case '1':
check += 1;
waferMap += "0001";
break;
case '2':
check += 1;
waferMap += "0010";
break;
case '3':
check += 2;
waferMap += "0011";
break;
case '4':
check += 1;
waferMap += "0100";
break;
case '5':
check += 2;
waferMap += "0101";
break;
case '6':
check += 2;
waferMap += "0110";
break;
case '7':
check += 3;
waferMap += "0111";
break;
case '8':
check += 1;
waferMap += "1000";
break;
case '9':
check += 2;
waferMap += "1001";
break;
case 'A':
check += 2;
waferMap += "1010";
break;
case 'B':
check += 3;
waferMap += "1011";
break;
case 'C':
check += 2;
waferMap += "1100";
break;
case 'D':
check += 3;
waferMap += "1101";
break;
case 'E':
check += 3;
waferMap += "1110";
break;
case 'F':
check += 4;
waferMap += "1111";
break;
default:
break;
}
}
result = new(check, total, waferMap);
return result;
}
private string GetWaferSizeDirectory(string area, string waferSize, bool destination) =>
destination ? Path.Combine(_AppSettings.WaferCounterDestinationDirectory, area, waferSize) : Path.Combine(_AppSettings.WaferCounterRootDirectory, area, waferSize);
string? IWaferCounterRepository.GetSlotMap(string line1, string line2) =>
GetRecord(line1, line2).SlotMap;
private static FileInfo[] GetFileInfoCollection(string waferSizeDirectory)
{
List<FileInfo> results = new();
FileInfo[] fileInfoCollection;
string[] files = !Directory.Exists(waferSizeDirectory) ? Array.Empty<string>() : Directory.GetFiles(waferSizeDirectory, "*.wc", SearchOption.TopDirectoryOnly);
fileInfoCollection = (from l in files select new FileInfo(l)).OrderByDescending(l => l.LastWriteTime).ToArray();
if (fileInfoCollection.Length > 0)
results.Add(fileInfoCollection[0]);
for (int i = 1; i < fileInfoCollection.Length; i++)
MoveFile(waferSizeDirectory, fileInfoCollection[i]);
return fileInfoCollection;
}
private static WaferCounter? GetLastQuantityAndSlotMapWithText(string waferSize, string text, FileInfo fileInfo)
{
WaferCounter? result;
string[] lines = File.ReadAllLines(fileInfo.FullName);
if (lines.Length < 2)
result = null;
else
{
string[] segments = fileInfo.Name.Split('-');
Record record = GetRecord(lines[0], lines[1]);
string equipmentId = segments.Length < 2 ? fileInfo.Name : segments[1].Split('.')[0];
if (string.IsNullOrEmpty(record.SlotMap) || record.SlotMap.Length != 25)
result = null; // Wrong length!
else if (record.Total != record.Check)
result = null; // Invalid!
else
result = new(fileInfo.LastWriteTime, fileInfo.LastWriteTime.ToString("yyyy-MM-dd hh:mm tt"), $"WC{waferSize}{equipmentId}", text, record.Total, record.SlotMap);
}
return result;
}
WaferCounter? IWaferCounterRepository.GetLastQuantityAndSlotMap(string area, string waferSize)
{
WaferCounter? result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IWaferCounterRepository.GetLastQuantityAndSlotMap)}.json"));
result = JsonSerializer.Deserialize<WaferCounter>(json);
if (result is null)
throw new NullReferenceException(nameof(result));
}
else
{
string waferSizeDirectory = GetWaferSizeDirectory(area, waferSize, destination: false);
FileInfo[] fileInfoCollection = GetFileInfoCollection(waferSizeDirectory);
if (fileInfoCollection.Length == 0)
result = null;
else
{
string text = string.Empty;
result = GetLastQuantityAndSlotMapWithText(waferSize, text, fileInfoCollection[0]);
}
}
return result;
}
private static void Save(string waferSizeDestinationDirectory, string area, string waferSize, string text, FileInfo fileInfo, WaferCounter result) =>
File.WriteAllText(Path.Combine(waferSizeDestinationDirectory, $"{fileInfo.Name}.csv"), $"100,{waferSize},{area},{fileInfo.LastWriteTime},{text},{result.Total:00},{result.SlotMap} ");
WaferCounter? IWaferCounterRepository.GetLastQuantityAndSlotMapWithText(string area, string waferSize, string text)
{
WaferCounter? result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IWaferCounterRepository.GetLastQuantityAndSlotMapWithText)}.json"));
result = JsonSerializer.Deserialize<WaferCounter>(json);
if (result is null)
throw new NullReferenceException(nameof(result));
}
else
{
string waferSizeDirectory = GetWaferSizeDirectory(area, waferSize, destination: false);
FileInfo[] fileInfoCollection = GetFileInfoCollection(waferSizeDirectory);
if (fileInfoCollection.Length == 0)
result = null;
else
{
result = GetLastQuantityAndSlotMapWithText(waferSize, text, fileInfoCollection[0]);
if (result is not null)
{
string waferSizeDestinationDirectory = _AppSettings.WaferCounterDestinationDirectory;
// string waferSizeDestinationDirectory = GetWaferSizeDirectory(area, waferSize, destination: true);
Save(waferSizeDestinationDirectory, area, waferSize, text, fileInfoCollection[0], result);
}
}
}
return result;
}
}

View File

@ -4,24 +4,17 @@ namespace OI.Metrology.Server.Services;
using OI.Metrology.Server.Models; using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Services; using OI.Metrology.Shared.Services;
using System.Text.Json;
public class AttachmentsService : IAttachmentsService public class AttachmentsService : IAttachmentsService
{ {
private readonly AppSettings _AppSettings; private readonly AppSettings _AppSettings;
private readonly IHttpClientFactory _HttpClientFactory;
private readonly IFileShareRepository _FileShareRepository;
private readonly IMetrologyRepository _MetrologyRepository; private readonly IMetrologyRepository _MetrologyRepository;
public AttachmentsService(AppSettings appSettings, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository, IMetrologyRepository metrologyRepository) public AttachmentsService(AppSettings appSettings, IMetrologyRepository metrologyRepository)
{ {
_AppSettings = appSettings; _AppSettings = appSettings;
_HttpClientFactory = httpClientFactory;
_FileShareRepository = fileShareRepository;
_MetrologyRepository = metrologyRepository; _MetrologyRepository = metrologyRepository;
} }
@ -34,16 +27,23 @@ public class AttachmentsService : IAttachmentsService
throw new NullReferenceException(nameof(tableName)); throw new NullReferenceException(nameof(tableName));
DateTime insertDate = Convert.ToDateTime(_MetrologyRepository.GetAttachmentInsertDateByGUID(tableName, attachmentId)); DateTime insertDate = Convert.ToDateTime(_MetrologyRepository.GetAttachmentInsertDateByGUID(tableName, attachmentId));
string year = insertDate.Year.ToString(); string year = insertDate.Year.ToString();
HttpClient httpClient = _HttpClientFactory.CreateClient();
Uri mesaFileShareMetrologySi = new(_AppSettings.EcMesaFileShareMetrologySi);
int weekNum = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(insertDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday); int weekNum = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(insertDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
Uri uri = _FileShareRepository.Append(mesaFileShareMetrologySi, "MetrologyAttachments", $"{tableName}_", year, $"WW{weekNum:00}", attachmentId.ToString(), filename); string directory = Path.Combine(_AppSettings.AttachmentPath, tableName + "_", year, $"WW{weekNum:00}", attachmentId.ToString());
HttpResponseMessage httpResponseMessage = _FileShareRepository.ReadFile(httpClient, uri); if (!Directory.Exists(directory))
if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK) _ = Directory.CreateDirectory(directory);
throw new Exception("File not found!"); string fullPath = Path.Combine(directory, filename);
return httpResponseMessage.Content.ReadAsStream();
// Check to see if file exists in the "New" directory structure, if not change the path back to the old. and check there
if (!File.Exists(fullPath))
{
fullPath = Path.Combine(_AppSettings.AttachmentPath, tableName, attachmentId.ToString(), filename);
}
if (!File.Exists(fullPath))
throw new Exception("File not found");
return new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
} }
Stream IAttachmentsService.GetAttachmentStreamByTitle(ToolType toolType, bool header, string title, string filename) Stream IAttachmentsService.GetAttachmentStreamByTitle(ToolType toolType, bool header, string title, string filename)
@ -77,70 +77,72 @@ public class AttachmentsService : IAttachmentsService
return GetAttachmentStream(tableName, attachmentId, filename); return GetAttachmentStream(tableName, attachmentId, filename);
} }
void IAttachmentsService.SaveAttachment(ToolType toolType, Attachment attachment) private void SaveAttachment(ToolType toolType, long headerId, string dataUniqueId, string filename, IFormFile uploadedFile)
{ {
if (toolType is null) if (toolType is null)
throw new Exception("Invalid tool type"); throw new Exception("Invalid tool type");
if (attachment.HeaderId is null)
throw new NullReferenceException($"{nameof(attachment.HeaderId)}"); using System.Transactions.TransactionScope trans = _MetrologyRepository.StartTransaction();
if (attachment.AttachmentId is null) Guid attachmentId = Guid.Empty;
throw new NullReferenceException($"{nameof(attachment.AttachmentId)}"); DateTime insertDate = new();
if (attachment.DestinationFileName is null) string? tableName = "";
throw new NullReferenceException($"{nameof(attachment.DestinationFileName)}");
if (string.IsNullOrWhiteSpace(attachment.UniqueId)) if (string.IsNullOrWhiteSpace(dataUniqueId))
throw new NullReferenceException($"{nameof(attachment.UniqueId)}"); {
if (attachment.DestinationFileName != "Image.pdf") attachmentId = _MetrologyRepository.GetHeaderAttachmentID(toolType.ID, headerId);
_MetrologyRepository.SetHeaderAttachmentID(toolType.ID, attachment.HeaderId.Value, attachment.AttachmentId); insertDate = Convert.ToDateTime(_MetrologyRepository.GetHeaderInsertDate(toolType.ID, headerId));
tableName = toolType.HeaderTableName;
}
else else
_MetrologyRepository.SetDataAttachmentID(toolType.ID, attachment.HeaderId.Value, attachment.UniqueId, attachment.AttachmentId); {
attachmentId = _MetrologyRepository.GetDataAttachmentID(toolType.ID, headerId, dataUniqueId);
insertDate = Convert.ToDateTime(_MetrologyRepository.GetDataInsertDate(toolType.ID, headerId, dataUniqueId));
// Get Date for new directory name
tableName = toolType.DataTableName;
}
if (Equals(attachmentId, Guid.Empty))
throw new Exception("Invalid attachment ID");
string year = insertDate.Year.ToString();
int weekNum = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(insertDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
string directory = Path.Combine(_AppSettings.AttachmentPath, $"{tableName}_", year, $"WW{weekNum:00}", attachmentId.ToString());
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
string fullPath = Path.Combine(directory, filename);
using (FileStream fileStream = new(fullPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
uploadedFile.CopyTo(fileStream);
trans.Complete();
} }
string? IAttachmentsService.GetProcessDataStandardFormat(IMetrologyRepository metrologyRepository, int toolTypeId, long headerId) void IAttachmentsService.SaveAttachment(ToolType toolType, long headerId, string dataUniqueId, string filename, object uploadedFile)
{
IFormFile formFile = (IFormFile)uploadedFile;
SaveAttachment(toolType, headerId, dataUniqueId, filename, formFile);
}
string? IAttachmentsService.GetProcessDataStandardFormat(IMetrologyRepository metrologyRepository, string attachmentPath, int toolTypeId, long headerId)
{ {
string? result; string? result;
int weekNum;
string file;
string year; string year;
int weekNum;
string directory; string directory;
Task<string> json; string checkDirectory;
Uri weekDirectory;
Uri checkDirectory;
List<string> files = new(); List<string> files = new();
string[] collection = ["-", string.Empty];
NginxFileSystem[]? nginxFileSystemCollection;
Task<HttpResponseMessage> httpResponseMessage;
HttpClient httpClient = _HttpClientFactory.CreateClient();
Uri mesaFileShareMetrologySi = new(_AppSettings.EcMesaFileShareMetrologySi);
DateTime[] dateTimes = new DateTime[] { DateTime.Now, DateTime.Now.AddDays(-6.66) }; DateTime[] dateTimes = new DateTime[] { DateTime.Now, DateTime.Now.AddDays(-6.66) };
ToolType toolType = metrologyRepository.GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID"); ToolType toolType = metrologyRepository.GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
foreach (DateTime dateTime in dateTimes) foreach (DateTime dateTime in dateTimes)
{ {
foreach (string item in collection) year = dateTime.Year.ToString();
{ weekNum = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
year = dateTime.Year.ToString(); directory = Path.Combine(_AppSettings.AttachmentPath, $"{toolType.HeaderTableName}_", year, $"WW{weekNum:00}");
weekNum = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday); if (!Directory.Exists(directory))
weekDirectory = _FileShareRepository.Append(mesaFileShareMetrologySi, "MetrologyAttachments", $"{toolType.HeaderTableName}_", year, $"WW{weekNum:00}"); _ = Directory.CreateDirectory(directory);
checkDirectory = _FileShareRepository.Append(weekDirectory, $"{item}{headerId}"); checkDirectory = Path.Combine(directory, headerId.ToString());
directory = Path.Combine(_AppSettings.EcMetrologySi, "MetrologyAttachments", $"{toolType.HeaderTableName}_", year, $"WW{weekNum:00}", $"{item}{headerId}"); if (!Directory.Exists(checkDirectory))
httpResponseMessage = httpClient.GetAsync(checkDirectory); continue;
httpResponseMessage.Wait(); files.AddRange(Directory.GetFiles(checkDirectory));
if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK)
continue;
json = httpResponseMessage.Result.Content.ReadAsStringAsync();
json.Wait();
nginxFileSystemCollection = JsonSerializer.Deserialize(json.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (nginxFileSystemCollection is null)
continue;
foreach (NginxFileSystem nginxFileSystem in nginxFileSystemCollection)
{
if (!nginxFileSystem.Name.EndsWith(".pdsf"))
continue;
file = Path.Combine(directory, nginxFileSystem.Name);
files.Add(file);
}
if (files.Count != 0)
break;
}
if (files.Count != 0) if (files.Count != 0)
break; break;
} }

View File

@ -0,0 +1,96 @@
@using OI.Metrology.Shared.ViewModels
@model OI.Metrology.Shared.ViewModels.Export
@{
ViewData["Title"] = "Export Data";
}
<style>
td {
padding-bottom: 2em;
padding-right: 1em;
}
</style>
<h3>Export Data</h3>
<hr />
<form asp-controller="Export" asp-action="ExportData" method="post" class="form-inline">
<div class="form-group">
<label for="ToolType">Tool Type</label>
<div class="form-control" id="ToolType" name="ToolType"></div>
@Html.ValidationMessage("ToolType", new { @class = "text-danger" })
</div>
<div class="form-group">
<label for="StartDate">Start Time</label>
<div class="form-control mb-2 mr-sm-2" id="StartDateControl"></div>
<div class="form-control mb-2 mr-sm-2" id="StartTimeControl"></div>
@Html.ValidationMessage("StartDate", new { @class = "text-danger" })
</div>
<div class="form-group">
<label for="EndDate">End Time</label>
<div class="form-control mb-2 mr-sm-2" id="EndDateControl"></div>
<div class="form-control mb-2 mr-sm-2" id="EndTimeControl"></div>
@Html.ValidationMessage("EndDate", new { @class = "text-danger" })
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Export Data</button>
</div>
<div class="form-group">
@Html.ValidationMessage("Exception", new { @class = "text-danger" })
</div>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
</form>
<script>
$(document).ready(function () {
var apiUrl = "@ViewBag.ApiUrl";
$("#ToolType").igCombo({
dataSource: apiUrl + '/tooltypes',
responseDataKey: "Results",
textKey: "ToolTypeName",
valueKey: "ID",
mode: "dropdown",
width: 150
});
var startTime = new Date("@Model.StartTime.ToString("yyyy-MM-ddTHH:mm")");
$("#StartDateControl").igDatePicker({
dateInputFormat: "date",
value: startTime,
width: 125,
inputName: "StartDate",
});
$("#StartTimeControl").igTimePicker({
dateInputFormat: "time",
value: startTime,
width: 110,
inputName: "StartTime",
});
var endTime = new Date("@Model.EndTime.ToString("yyyy-MM-ddTHH:mm")");
$("#EndDateControl").igDatePicker({
dateInputFormat: "date",
value: endTime,
width: 125,
inputName: "EndDate",
});
$("#EndTimeControl").igTimePicker({
dateInputFormat: "time",
value: endTime,
width: 110,
inputName: "EndTime",
});
});
</script>

View File

@ -0,0 +1,28 @@
@{
ViewData["Title"] = "Awaiting Disposition";
}
<h4>Awaiting Disposition</h4>
<div style="height: 450px;">
<table id="grid"></table>
</div>
<div class="row" style="margin-top: 10px; margin-bottom: 20px;">
<div class="col-xs-1">
<input type="button" id="OpenButton" value="Open" />
</div>
<div class="col-xs-1">
<input type="button" id="RefreshButton" value="Refresh" />
</div>
</div>
<script>
$(document).ready(function () {
initAwaitingDisposition("@ViewBag.ApiUrl");
});
</script>

View File

@ -0,0 +1,3 @@
@{
ViewData["Title"] = "Metrology Home Page";
}

View File

@ -0,0 +1,57 @@
@{
ViewData["Title"] = "Run Headers";
}
<style>
html,
body {
height: 100%;
}
div.container-fluid {
height: 90%;
}
#HeaderGrid,
#FieldsGrid {
font-size: 12px;
}
.FieldTitle {
font-weight: bold;
}
</style>
<h4>Run Headers</h4>
<table>
<tr>
<td>
<label for="ToolType">Tool Type:</label>
</td>
<td>
<div id="ToolType"></div>
</td>
</tr>
</table>
<table width="100%" height="80%">
<tr>
<td width="50%">
<table id="HeaderGrid"></table>
</td>
<td width="50%">
<table id="FieldsGrid"></table>
</td>
</tr>
</table>
<script>
$(document).ready(function () {
initRunHeaders("@ViewBag.ApiUrl");
});
</script>

View File

@ -0,0 +1,104 @@
@model OI.Metrology.Shared.ViewModels.RunInfo
@{
ViewData["Title"] = "Run Information";
}
<style>
#HeaderGridDiv,
#DetailsGridDiv {
font-size: 12px;
}
</style>
<h4>Run Information</h4>
<form class="form-inline mb-4">
<div class="form-group">
<label for="ToolType">Tool Type</label>
<div class="form-control" id="ToolType"></div>
</div>
<div class="form-group">
<label for="StartDate">Start Time</label>
<div class="form-control mb-2 mr-sm-2" id="StartDate"></div>
<div class="form-control mb-2 mr-sm-2" id="StartTime"></div>
</div>
<div class="form-group">
<label for="EndDate">End Time</label>
<div class="form-control mb-2 mr-sm-2" id="EndDate"></div>
<div class="form-control mb-2 mr-sm-2" id="EndTime"></div>
</div>&nbsp;&nbsp;
<div class="form-group">
<input class="btn btn-primary" type="button" value="Load Headers" id="LoadHeadersButton" />
</div>&nbsp;&nbsp;
<div class="form-group">
<label class="form-check-label" for="chkAutoRefresh">
Auto-Refresh
</label>
<input class="form-check-input" type="checkbox" id="chkAutoRefresh">
</div>
<div class="form-group">
<label class="form-check-label" for="chkCopyOnGet">
Copy-On-Get
</label>
<input class="form-check-input" type="checkbox" id="chkCopyOnGet">
</div>
</form>
<div style="height: 300px;" id="HeaderGridDiv">
<span id="ToolTypeID" hidden></span>
<table id="HeaderGrid"></table>
</div>
<div class="row" style="margin-top: 10px; margin-bottom: 20px;">
<div class="col-xs-1">
<input type="button" class="btn" id="GetDataButton" value="Get Data" disabled />
</div>
<div class="col-xs-1">
<input type="button" class="btn" id="ReviewButton" value="Review" disabled />
</div>
<div class="col-xs-1">
<input type="button" class="btn" id="RecipeParametersButton" value="Parameters" disabled />
</div>
<div class="col-xs-1">
<input type="button" class="btn" id="ViewButton" value="View" disabled />
</div>
<div class="col-xs-1">
<input type="button" class="btn" id="PinButton" value="Pin" disabled />
</div>
</div>
<div id="DetailsDiv" hidden>
<span id="HeaderId" hidden></span>
<span id="HeaderAttachmentId" hidden></span>
<div style="padding-bottom: 20px;" id="DetailsGridDiv">
<table id="DetailsGrid"></table>
</div>
<div id="ExportDiv" style="margin-top: 10px;" hidden>
<input type="button" value="Send to OpenInsight" id="OIExportButton" />
<span id="OIExportResult" style="margin-left: 10px; font-weight: bold; color: #366b02;"></span>
</div>
<p style="margin-top: 20px;">
<iframe id="DataAttachmentFrame" style="height:900px; border-width:thin; margin-right: 10px;" hidden></iframe>
<iframe id="HeaderAttachmentFrame" style="height:900px; border-width:thin;" hidden></iframe>
&nbsp;
<div id="DataAttachmentDiv" hidden>
<canvas id="DataAttachmentCanvas"></canvas>
</div>
<div id="HeaderAttachmentDiv" hidden>
<canvas id="HeaderAttachmentCanvas"></canvas>
</div>
</p>
</div>
<script>
$(document).ready(function () {
initRunInfo("@ViewBag.ApiUrl", "@Model.ToolTypeID", "@Model.HeaderID", "@Model.HeaderAttachmentID");
});
</script>

View File

@ -103,6 +103,6 @@
$("#runDataSheet5").click(function () { runDataSheet(5, $(this).val()) }); $("#runDataSheet5").click(function () { runDataSheet(5, $(this).val()) });
$("#runDataSheet6").click(function () { runDataSheet(6, $(this).val()) }); $("#runDataSheet6").click(function () { runDataSheet(6, $(this).val()) });
$("#restartButton").click(function () { restartButton() }); $("#restartButton").click(function () { restartButton() });
initWorkMaterial("@ViewBag.ApiUrl", ""); initWorkMaterial("@ViewBag.ApiUrl");
}); });
</script> </script>

View File

@ -6,42 +6,36 @@
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title> <title>@ViewBag.Title</title>
<script src="https://oi-metrology-viewer-prod.mes.infineon.com/js/modernizr-3.6.0-custom.js?no-cache=2024-06-18-10-54" <script src="~/js/modernizr-3.6.0-custom.js" type="text/javascript" asp-append-version="true"></script>
type="text/javascript"></script>
<link href="https://oi-metrology-viewer-prod.mes.infineon.com/styles/bootstrap.min.css?no-cache=2024-06-18-10-54" <link href="~/styles/bootstrap.min.css" rel="stylesheet" asp-append-version="true" />
rel="stylesheet" /> <link href="~/igniteui/css/themes/bootstrap3/default/infragistics.theme.css" rel="stylesheet"
<link asp-append-version="true" />
href="https://oi-metrology-viewer-prod.mes.infineon.com/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?no-cache=2024-06-18-10-54" <link href="~/igniteui/css/structure/infragistics.css" rel="stylesheet" asp-append-version="true" />
rel="stylesheet" /> <link href="~/styles/site.css" rel="stylesheet" asp-append-version="true" />
<link
href="https://oi-metrology-viewer-prod.mes.infineon.com/igniteui/css/structure/infragistics.css?no-cache=2024-06-18-10-54"
rel="stylesheet" />
<link href="https://oi-metrology-viewer-prod.mes.infineon.com/styles/site-server.css?no-cache=2024-06-18-10-54"
rel="stylesheet" />
<link href="https://oi-metrology-viewer-prod.mes.infineon.com/styles/index.css?no-cache=2024-06-18-10-54"
rel="stylesheet" />
<script src="https://oi-metrology-viewer-prod.mes.infineon.com/js/jquery-3.6.0.min.js?no-cache=2024-06-18-10-54" <script src="~/js/jquery-3.6.0.min.js" type="text/javascript" asp-append-version="true"></script>
type="text/javascript"></script> <script src="~/js/jquery-ui.min.js" type="text/javascript" asp-append-version="true"></script>
<script src="https://oi-metrology-viewer-prod.mes.infineon.com/js/jquery-ui.min.js?no-cache=2024-06-18-10-54" <script src="~/igniteui/js/infragistics.core.js" type="text/javascript" asp-append-version="true"></script>
type="text/javascript"></script> <script src="~/igniteui/js/infragistics.lob.js" type="text/javascript" asp-append-version="true"></script>
<script <script src="~/igniteui/js/infragistics.dv.js" type="text/javascript" asp-append-version="true"></script>
src="https://oi-metrology-viewer-prod.mes.infineon.com/igniteui/js/infragistics.core.js?no-cache=2024-06-18-10-54"
type="text/javascript"></script>
<script
src="https://oi-metrology-viewer-prod.mes.infineon.com/igniteui/js/infragistics.lob.js?no-cache=2024-06-18-10-54"
type="text/javascript"></script>
<script
src="https://oi-metrology-viewer-prod.mes.infineon.com/igniteui/js/infragistics.dv.js?no-cache=2024-06-18-10-54"
type="text/javascript"></script>
<script src="https://oi-metrology-viewer-prod.mes.infineon.com/js/chart-4.3.0.min.js" type="module"></script> <script src="~/js/chart-4.3.0.min.js" type="module"></script>
<script src="https://oi-metrology-viewer-prod.mes.infineon.com/js/common.js?no-cache=2024-06-18-10-54" <script src="~/js/common.js" type="text/javascript" asp-append-version="true"></script>
type="text/javascript"></script> <script src="~/js/site.js" type="text/javascript" asp-append-version="true"></script>
<script src="https://oi-metrology-viewer-prod.mes.infineon.com/js/site-server.js?no-cache=2024-06-18-10-54" <script>
type="text/javascript"></script> $(document).ready(function () {
if (location.pathname == "/") {
route = "/AwaitingDispo";
}
else {
route = location.pathname;
}
$('ul.nav.navbar-nav').find('a[href="' + route + '"]')
.closest('li').addClass('alert-info');
});
</script>
</head> </head>
<body> <body>
@ -63,9 +57,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<div class="navbar-brand"> <div class="navbar-brand">
<a href="https://oi-metrology-viewer-prod.mes.infineon.com"><img <a href="/"><img src="~/images/IFX_LOGO_RGB.png" height="20" /></a>
src="https://oi-metrology-viewer-prod.mes.infineon.com/images/IFX_LOGO_RGB.png"
height="20" /></a>
OI Metrology Viewer OI Metrology Viewer
</div> </div>
</div> </div>
@ -99,10 +91,8 @@
<div id="MessageModal"></div> <div id="MessageModal"></div>
<script src="https://oi-metrology-viewer-prod.mes.infineon.com/js/bootstrap.min.js?no-cache=2024-06-18-10-54" <script src="~/js/bootstrap.min.js" type="text/javascript" asp-append-version="true"></script>
type="text/javascript"></script> <script src="~/js/respond.min.js" type="text/javascript" asp-append-version="true"></script>
<script src="https://oi-metrology-viewer-prod.mes.infineon.com/js/respond.min.js?no-cache=2024-06-18-10-54"
type="text/javascript"></script>
@RenderSection("scripts", required: false) @RenderSection("scripts", required: false)
</body> </body>

View File

Before

Width:  |  Height:  |  Size: 272 KiB

After

Width:  |  Height:  |  Size: 272 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 210 B

View File

Before

Width:  |  Height:  |  Size: 964 B

After

Width:  |  Height:  |  Size: 964 B

View File

Before

Width:  |  Height:  |  Size: 486 B

After

Width:  |  Height:  |  Size: 486 B

View File

Before

Width:  |  Height:  |  Size: 483 B

After

Width:  |  Height:  |  Size: 483 B

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 986 B

After

Width:  |  Height:  |  Size: 986 B

View File

Before

Width:  |  Height:  |  Size: 1011 B

After

Width:  |  Height:  |  Size: 1011 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1009 B

After

Width:  |  Height:  |  Size: 1009 B

View File

Before

Width:  |  Height:  |  Size: 1017 B

After

Width:  |  Height:  |  Size: 1017 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 995 B

After

Width:  |  Height:  |  Size: 995 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show More