Compare commits

...

29 Commits

Author SHA1 Message Date
4c2bef71ec Characterization Data
FI Backlog with Ignore Tag
2024-09-19 10:13:10 -07:00
b824c4ba36 Get text from OI 2024-08-28 15:58:20 -07:00
1ad6246b8d Bug fix for export 2024-07-30 11:36:27 -07:00
478aecf2c8 Link to OI Wizard and new files page 2024-07-17 10:58:48 -07:00
fe3292133e Expose error message using ProducesResponseType 2024-06-18 13:36:30 -07:00
e7b721fdb3 awaiting-disposition-header-attachment-id 2024-06-18 10:55:12 -07:00
da3e839a48 Host from Windows 2024-06-17 17:11:36 -07:00
6737ddfb59 Static Site 2024-06-14 16:51:30 -07:00
3aed250488 Bug fix: Missing Singleton 2024-05-25 10:27:10 -07:00
f53ae8c1c8 Bug fix: Attachment 2024-05-23 17:08:44 -07:00
6317c385f6 Separated Wafer-Counter
JsonElement instead of Request body
Attachment Class
Bump
Ready to test GetLastGroupIdWithValue
Changed to v4
2024-05-21 12:40:20 -07:00
5c9f0d1aff Remove with Text
Remove GetEngineeringSpcReview
Better error message
EnforceCodeStyleInBuild
NginxFileSystem
Remove Reactors and Working Directory
AppSettings
Delete self contained Thunder Tests
Back to .net8.0
api/v4/InfinityQS
ApiExplorerSettings
Wafer Counter
2024-04-15 13:13:55 -07:00
7e16ee7f98 Layer with EpiProTempVerificationRows 2023-11-14 10:27:21 -07:00
cff2e06f68 Delete Work Material
Added InfinityQSV3-GetEpiProTempVerification
Added nigth shift
2023-11-13 09:44:37 -07:00
03bd20fc8c Archive 2023-11-02 14:41:32 -07:00
3dd4034a84 Tests passed using Mock 2023-11-01 08:27:25 -07:00
f684c4b7ef ec.local => infineon.com
New UserSecretsId
2023-10-31 21:40:11 -07:00
4cc5219409 PDSF (Process Data Standard Format) to use EAF for
pushing to OI
2023-07-24 13:29:13 -07:00
6668806432 log 0 2023-05-16 13:12:43 -07:00
e084fdd58f Spreading Resistance Profile with ChartJS,
Copy-On-Get and nuget bump (Serilog)
2023-05-16 08:20:35 -07:00
6b409294e4 Task 353201 2023-05-03 09:50:44 -07:00
9774b0cc53 Changed to use both wm in and out 2023-04-24 12:31:45 -07:00
c82a8790e7 SQL Bug II 2023-04-19 14:00:50 -07:00
c68b853c64 SQL Bug 2023-04-19 08:48:01 -07:00
2f3f1b7947 Changed path and Changed seconds to Alpha 2023-04-19 08:33:17 -07:00
c655ed5c6b Add link to WorkMaterial
Add new columns OC and OS count
2023-04-18 11:43:52 -07:00
70c1e1a52a Updated azure-pipelines-server.yml
Changed to thunderclient to messa017
Nuget Bump
Scan Helper
2023-04-17 14:23:46 -07:00
72b648589e Multiple Stages
IFX Nuget
IIS Development and Windows Service plus IIS
Flop logic on conditional compile
2023-04-06 16:43:22 -07:00
66f38fcf33 nuget bump and userSecrets tasks and query update for event
Allow multiple ids are present
2023-04-05 13:15:24 -07:00
1957 changed files with 384098 additions and 142070 deletions

View File

@ -1,3 +1,19 @@
[*.md]
end_of_line = crlf
file_header_template = unset
indent_size = 2
indent_style = space
insert_final_newline = false
root = true
tab_width = 2
[*.csproj]
end_of_line = crlf
file_header_template = unset
indent_size = 2
indent_style = space
insert_final_newline = false
root = true
tab_width = 2
[*.cs] [*.cs]
csharp_indent_block_contents = true csharp_indent_block_contents = true
csharp_indent_braces = false csharp_indent_braces = false
@ -13,6 +29,7 @@ csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true csharp_new_line_between_query_expression_clauses = true
csharp_prefer_braces = false csharp_prefer_braces = false
csharp_prefer_qualified_reference = true:error
csharp_prefer_simple_default_expression = true:warning csharp_prefer_simple_default_expression = true:warning
csharp_prefer_simple_using_statement = true:warning csharp_prefer_simple_using_statement = true:warning
csharp_prefer_static_local_function = true:warning csharp_prefer_static_local_function = true:warning
@ -76,17 +93,28 @@ csharp_using_directive_placement = outside_namespace
dotnet_code_quality_unused_parameters = all dotnet_code_quality_unused_parameters = all
dotnet_code_quality_unused_parameters = non_public # IDE0060: Remove unused parameter dotnet_code_quality_unused_parameters = non_public # IDE0060: Remove unused parameter
dotnet_code_quality.CAXXXX.api_surface = private, internal dotnet_code_quality.CAXXXX.api_surface = private, internal
dotnet_diagnostic.CA1511.severity = none # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1825.severity = warning # CA1823: Avoid zero-length array allocations dotnet_diagnostic.CA1825.severity = warning # CA1823: Avoid zero-length array allocations
dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available
dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
dotnet_diagnostic.CA1860.severity = error # CA1860: Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
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.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.IDE0004.severity = warning # IDE0004: Cast is redundant.
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.IDE0005.severity = warning # Using directive is unnecessary dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary
dotnet_diagnostic.IDE0028.severity = none # IDE0028: Collection initialization can be simplified
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031) dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049) dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
dotnet_diagnostic.IDE0060.severity = warning # IDE0060: Remove unused parameter dotnet_diagnostic.IDE0060.severity = warning # IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]csharp(IDE0290)
dotnet_diagnostic.IDE0300.severity = none # IDE0300: Collection initialization can be simplified
dotnet_diagnostic.IDE0301.severity = none #IDE0301: Collection initialization can be simplified
dotnet_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified
dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning
dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method

7
.gitignore vendored
View File

@ -340,4 +340,9 @@ ASALocalRun/
!.vscode/thunder-tests/ !.vscode/thunder-tests/
# Libman.json # Libman.json
/wwwroot/lib/* /wwwroot/lib/*
.kanbn
Tests/.kanbn
/Wafer-Counter/.vscode/.UserSecrets/secrets.json

2
.vscode/launch.json vendored
View File

@ -10,7 +10,7 @@
"request": "launch", "request": "launch",
"preLaunchTask": "buildServer", "preLaunchTask": "buildServer",
// If you have changed target frameworks, make sure to update the program path. // If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/Server/bin/Debug/net7.0/win-x64/OI.Metrology.Server.dll", "program": "${workspaceFolder}/Server/bin/Debug/net8.0/win-x64/OI.Metrology.Server.dll",
"args": [], "args": [],
"cwd": "${workspaceFolder}/Server", "cwd": "${workspaceFolder}/Server",
"stopAtEntry": false, "stopAtEntry": false,

View File

@ -3,7 +3,7 @@
"files.exclude": { "files.exclude": {
"**/.git": false "**/.git": false
}, },
"thunder-client.saveToWorkspace": true, "thunder-client.saveToWorkspace": false,
"thunder-client.workspaceRelativePath": ".vscode", "thunder-client.workspaceRelativePath": ".vscode",
"coverage-gutters.coverageBaseDir": "../.vscode/TestResults/*" "coverage-gutters.coverageBaseDir": "../.vscode/TestResults/*"
} }

52
.vscode/tasks.json vendored
View File

@ -1,6 +1,32 @@
{ {
"version": "2.0.0", "version": "2.0.0",
"tasks": [ "tasks": [
{
"label": "User Secrets Init",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/Server/OI.Metrology.Server.csproj",
"init"
],
"problemMatcher": "$msCompile"
},
{
"label": "User Secrets Set",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/Server/OI.Metrology.Server.csproj",
"set",
"_Application",
"oi-metrology-viewer.Server"
],
"problemMatcher": "$msCompile"
},
{ {
"label": "buildServer", "label": "buildServer",
"command": "dotnet", "command": "dotnet",
@ -13,6 +39,30 @@
], ],
"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": "buildShared",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Shared/OI.Metrology.Shared.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{ {
"label": "publishServer", "label": "publishServer",
"command": "dotnet", "command": "dotnet",
@ -50,7 +100,7 @@
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },
{ {
"label": "format", "label": "Format",
"command": "dotnet", "command": "dotnet",
"type": "process", "type": "process",
"args": [ "args": [

View File

@ -1,198 +0,0 @@
[
{
"_id": "646e3a9b-8fe9-4eb3-a532-f94270f752ac",
"colId": "history",
"containerId": "",
"name": "http://localhost:5126/api/inbound/cde",
"url": "http://localhost:5126/api/inbound/cde",
"method": "POST",
"sortNum": 0,
"created": "2023-02-28T14:41:33.596Z",
"modified": "2023-02-28T15:19:48.924Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"SentToMetrology\": false,\n \"SentToSPC\": false,\n \"AutoOptimizeGain\": \"YES\",\n \"AutoProbeHeightSet\": \"NO\",\n \"Avg\": \"1824.053\",\n \"CellName\": \"CDE2\",\n \"DLRatio\": \"0.9680\",\n \"DataReject\": \"> 3.0Sigma\",\n \"Date\": \"02/27/2023 03:03:00 AM\",\n \"Engineer\": \"Engineer\",\n \"EquipId\": \"CDE2\",\n \"FileName\": \"0 C:\\\\4p_NT\\\\LSL8in.prj\\\\10PT_5mm.rcp\\\\3227D036.RsM 03:03 02/27/23\",\n \"FilePath\": \"\",\n \"Id\": \"-1\",\n \"Layer\": \"\",\n \"LotId\": \"LotID\",\n \"Op\": \"Operator\",\n \"PSN\": \"4628\",\n \"RDS\": \"577845\",\n \"Reactor\": \"20\",\n \"Recipe\": \"LSL8in \\\\ 10PT_5mm\",\n \"ResistivitySpec\": \"\",\n \"Run\": \"20-577845-4628\",\n \"SemiRadial\": \"1.55%\",\n \"StDev\": \"1.33%\",\n \"Temp\": \"19.2\",\n \"UniqueId\": \"21.16;1;95.0;1803.847;270.0_Point-1\",\n \"Zone\": null,\n \"Details\": [\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"21.16\",\n \"Pt\": \"1\",\n \"R\": \"95.0\",\n \"Rs\": \"1803.847\",\n \"T\": \"270.0\",\n \"UniqueId\": \"21.16;1;95.0;1803.847;270.0_Point-1\"\n },\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"22.39\",\n \"Pt\": \"2\",\n \"R\": \"71.0\",\n \"Rs\": \"1858.424\",\n \"T\": \"270.0\",\n \"UniqueId\": \"22.39;2;71.0;1858.424;270.0_Point-2\"\n },\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"21.07\",\n \"Pt\": \"3\",\n \"R\": \"47.0\",\n \"Rs\": \"1834.141\",\n \"T\": \"270.0\",\n \"UniqueId\": \"21.07;3;47.0;1834.141;270.0_Point-3\"\n },\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"22.91\",\n \"Pt\": \"4\",\n \"R\": \"23.0\",\n \"Rs\": \"1803.609\",\n \"T\": \"270.0\",\n \"UniqueId\": \"22.91;4;23.0;1803.609;270.0_Point-4\"\n },\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"21.94\",\n \"Pt\": \"5\",\n \"R\": \"0.0\",\n \"Rs\": \"1801.623\",\n \"T\": \"0.0\",\n \"UniqueId\": \"21.94;5;0.0;1801.623;0.0_Point-5\"\n },\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"25.61\",\n \"Pt\": \"6\",\n \"R\": \"11.0\",\n \"Rs\": \"1803.997\",\n \"T\": \"90.0\",\n \"UniqueId\": \"25.61;6;11.0;1803.997;90.0_Point-6\"\n },\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"24.73\",\n \"Pt\": \"7\",\n \"R\": \"35.0\",\n \"Rs\": \"1819.854\",\n \"T\": \"90.0\",\n \"UniqueId\": \"24.73;7;35.0;1819.854;90.0_Point-7\"\n },\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"23.13\",\n \"Pt\": \"8\",\n \"R\": \"59.0\",\n \"Rs\": \"1855.965\",\n \"T\": \"90.0\",\n \"UniqueId\": \"23.13;8;59.0;1855.965;90.0_Point-8\"\n },\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"23.44\",\n \"Pt\": \"9\",\n \"R\": \"83.0\",\n \"Rs\": \"1853.631\",\n \"T\": \"90.0\",\n \"UniqueId\": \"23.44;9;83.0;1853.631;90.0_Point-9\"\n },\n {\n \"HeaderUniqueId\": \"ResMap_20-577845-4628_20230227030723\",\n \"Merit\": \"21.75\",\n \"Pt\": \"10\",\n \"R\": \"95.0\",\n \"Rs\": \"1805.438\",\n \"T\": \"90.0\",\n \"UniqueId\": \"21.75;10;95.0;1805.438;90.0_Point-10\"\n }\n ]\n}",
"form": []
},
"tests": []
},
{
"_id": "7f723103-2cd6-4d09-b780-28afe34b3cd7",
"colId": "history",
"containerId": "",
"name": "Delete",
"url": "https://tfs.intra.infineon.com/tfs/manufacturingit/APC%20Trend/_apis/test/runs/413094?api-version=6.0",
"method": "DELETE",
"sortNum": 0,
"created": "2023-03-02T15:43:07.175Z",
"modified": "2023-03-02T15:49:54.662Z",
"headers": [
{
"name": "Authorization",
"value": "Basic OmtzZHJveW9xMmJsdGI2N2xzN3NmZGhyYXlrY3l6cGlmemtkZjNndGs1bnl4ZnZmZHBqa2E="
}
],
"params": [
{
"name": "api-version",
"value": "6.0",
"isPath": false
}
],
"tests": []
},
{
"_id": "2874b1ad-b298-48c1-8edb-6fd78ce7d2d9",
"colId": "history",
"containerId": "",
"name": "Get",
"url": "https://tfs.intra.infineon.com/tfs/manufacturingit/Mesa_FI/_apis/test/runs?branchName=amaster&api-version=6.0",
"method": "GET",
"sortNum": 0,
"created": "2023-03-02T15:53:18.138Z",
"modified": "2023-03-02T16:12:27.892Z",
"headers": [
{
"name": "Authorization",
"value": "Basic OmtzZHJveW9xMmJsdGI2N2xzN3NmZGhyYXlrY3l6cGlmemtkZjNndGs1bnl4ZnZmZHBqa2E="
}
],
"params": [
{
"name": "branchName",
"value": "amaster",
"isPath": false
},
{
"name": "api-version",
"value": "6.0",
"isPath": false
}
],
"tests": []
},
{
"_id": "ed8728f5-9afa-4e69-bca3-9c059a9a831b",
"colId": "history",
"containerId": "",
"name": "Patch",
"url": "https://tfs.intra.infineon.com/tfs/manufacturingit/Mesa_FI/_apis/test/runs/410737?api-version=6.0",
"method": "PATCH",
"sortNum": 0,
"created": "2023-03-02T15:53:18.138Z",
"modified": "2023-03-02T15:58:09.720Z",
"headers": [
{
"name": "Authorization",
"value": "Basic OmtzZHJveW9xMmJsdGI2N2xzN3NmZGhyYXlrY3l6cGlmemtkZjNndGs1bnl4ZnZmZHBqa2E="
}
],
"params": [
{
"name": "api-version",
"value": "6.0",
"isPath": false
}
],
"body": {
"type": "json",
"raw": "{\n \"name\": \"MET08RESIHGCV\",\n \"comment\": \"40 passed\"\n}",
"form": []
},
"tests": []
},
{
"_id": "727621f0-63a3-4df2-9cfc-2610c532670d",
"colId": "history",
"containerId": "",
"name": "OI-RDS",
"url": "http://messa020ec.ec.local/api/oiWizard/materials/rds/578941",
"method": "GET",
"sortNum": 0,
"created": "2023-03-02T18:20:01.561Z",
"modified": "2023-03-06T18:40:43.162Z",
"headers": [],
"params": [],
"tests": [
{
"type": "json-query",
"custom": "json.rds.rdsLayers",
"action": "count",
"value": "1"
}
]
},
{
"_id": "4eafe190-e59e-4a3e-af76-356f62fde842",
"colId": "history",
"containerId": "",
"name": "https://oi-metrology-viewer-prod.mes.infineon.com/api/tooltypes",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/tooltypes",
"method": "GET",
"sortNum": 0,
"created": "2023-03-07T17:20:54.044Z",
"modified": "2023-03-07T17:20:54.044Z",
"headers": [],
"params": [],
"tests": []
},
{
"_id": "280ea9be-50e3-4813-8eb0-ffff739fe196",
"colId": "history",
"containerId": "",
"name": "GetHeaders",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/export/headers",
"method": "GET",
"sortNum": 0,
"created": "2023-03-07T17:21:05.219Z",
"modified": "2023-03-07T19:35:11.146Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
},
{
"_id": "6d8098aa-eb50-422e-b38d-32709d985e8e",
"colId": "history",
"containerId": "",
"name": "GetHeaders-Dev",
"url": "http://mestsa008/api/export/headers",
"method": "POST",
"sortNum": 0,
"created": "2023-03-07T17:21:05.219Z",
"modified": "2023-03-08T18:18:04.054Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
},
{
"_id": "61383ad6-ceb4-4d98-86c1-bf00c0e4204d",
"colId": "history",
"containerId": "",
"name": "GetHeaders-localhost",
"url": "http://localhost:5126/api/export/headers",
"method": "GET",
"sortNum": 0,
"created": "2023-03-07T17:21:05.219Z",
"modified": "2023-03-08T19:05:54.744Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": -1678296039\n}",
"form": []
},
"tests": []
}
]

View File

@ -1,23 +0,0 @@
[
{
"_id": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"colName": "InfinityQS",
"created": "2023-02-27T20:07:11.913Z",
"sortNum": 10000,
"folders": []
},
{
"_id": "fb96b15a-0cc4-48c7-8767-34f1242750e8",
"colName": "Export EC",
"created": "2023-03-08T17:16:29.420Z",
"sortNum": 20000,
"folders": []
},
{
"_id": "5bfd00bc-b58c-49d3-9f27-5acadd060a51",
"colName": "Export IFX",
"created": "2023-03-08T17:31:19.468Z",
"sortNum": 30000,
"folders": []
}
]

View File

@ -1,421 +0,0 @@
[
{
"_id": "acbbcc8d-3daf-43be-9081-f4be2f8a95b9",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetCommandText",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQS/commandText/?sub_group_id=1677273357&process=61&job=CDE5&part=5012&lot=575908&date_time=2023-02-24 14:15:00",
"method": "GET",
"sortNum": 20000,
"created": "2023-02-27T20:07:11.921Z",
"modified": "2023-02-27T20:07:11.921Z",
"headers": [],
"params": [
{
"name": "sub_group_id",
"value": "1677273357",
"isPath": false
},
{
"name": "process",
"value": "61",
"isPath": false
},
{
"name": "job",
"value": "CDE5",
"isPath": false
},
{
"name": "part",
"value": "5012",
"isPath": false
},
{
"name": "lot",
"value": "575908",
"isPath": false
},
{
"name": "date_time",
"value": "2023-02-24 14:15:00",
"isPath": false
}
],
"tests": [
{
"type": "Content-Length",
"custom": "",
"action": ">",
"value": "100"
}
]
},
{
"_id": "29e56599-0093-481e-9386-9e6c1bb828a8",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetCommandTextV2",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQSV2/1677273357/commandText/?process=61&job=CDE5&part=5012&lot=575908&date_time=2023-02-24 14:15:00",
"method": "GET",
"sortNum": 30000,
"created": "2023-02-27T20:07:11.923Z",
"modified": "2023-02-27T20:07:11.923Z",
"headers": [],
"params": [
{
"name": "process",
"value": "61",
"isPath": false
},
{
"name": "job",
"value": "CDE5",
"isPath": false
},
{
"name": "part",
"value": "5012",
"isPath": false
},
{
"name": "lot",
"value": "575908",
"isPath": false
},
{
"name": "date_time",
"value": "2023-02-24 14:15:00",
"isPath": false
}
],
"tests": [
{
"type": "Content-Length",
"custom": "",
"action": ">",
"value": "100"
}
]
},
{
"_id": "2810520f-7a8b-4282-a593-92da3043e491",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetData",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQS/1677273357/data",
"method": "GET",
"sortNum": 40000,
"created": "2023-02-27T20:07:11.924Z",
"modified": "2023-02-27T20:07:11.924Z",
"headers": [],
"params": [],
"tests": [
{
"type": "json-query",
"custom": "json.",
"action": "count",
"value": "2"
}
]
},
{
"_id": "8628d1b1-cedb-45e3-9958-0ba4e233a2ac",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetDataV2",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQSV2/1677273357/data",
"method": "GET",
"sortNum": 41250,
"created": "2023-02-27T20:07:11.925Z",
"modified": "2023-02-27T20:07:11.925Z",
"headers": [],
"params": [],
"tests": [
{
"type": "json-query",
"custom": "json.",
"action": "count",
"value": "2"
}
]
},
{
"_id": "55c863ce-b828-4cdb-8a72-26da369c44ee",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetDescriptors",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQS/1677273357/descriptors",
"method": "GET",
"sortNum": 41875,
"created": "2023-02-27T20:07:11.926Z",
"modified": "2023-02-27T20:07:11.926Z",
"headers": [],
"params": [],
"tests": [
{
"type": "json-query",
"custom": "json.",
"action": "count",
"value": "2"
}
]
},
{
"_id": "b25fade2-44b5-4897-94a6-e31062c27e58",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetDescriptorsV2",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQSV2/1677273357/descriptors",
"method": "GET",
"sortNum": 42187.5,
"created": "2023-02-27T20:07:11.927Z",
"modified": "2023-02-27T20:07:11.927Z",
"headers": [],
"params": [],
"tests": [
{
"type": "json-query",
"custom": "json.",
"action": "count",
"value": "2"
}
]
},
{
"_id": "f24e826e-578c-45fe-a80a-ce31f0a13dfc",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetEvents",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQS/1677273357/events",
"method": "GET",
"sortNum": 42500,
"created": "2023-02-27T20:07:11.928Z",
"modified": "2023-02-27T20:07:11.928Z",
"headers": [],
"params": [],
"tests": [
{
"type": "json-query",
"custom": "json.",
"action": "count",
"value": "2"
}
]
},
{
"_id": "81118bd8-5919-4501-aa34-eaa2f4baeabf",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetEventsV2",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQSV2/1677273357/events",
"method": "GET",
"sortNum": 43750,
"created": "2023-02-27T20:07:11.929Z",
"modified": "2023-02-27T20:07:11.929Z",
"headers": [],
"params": [],
"tests": [
{
"type": "json-query",
"custom": "json.",
"action": "count",
"value": "2"
}
]
},
{
"_id": "26ded486-79ad-4fc8-b526-98187b8fde91",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetHeader",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQS/1677273357/header",
"method": "GET",
"sortNum": 45000,
"created": "2023-02-27T20:07:11.930Z",
"modified": "2023-02-27T20:07:11.930Z",
"headers": [],
"params": [],
"tests": [
{
"type": "json-query",
"custom": "json.",
"action": "count",
"value": "2"
}
]
},
{
"_id": "b8ee8160-6ca2-4276-be91-d1f6f2dd90dc",
"colId": "3743bec1-1f73-492a-9b9f-5889f239b5fc",
"containerId": "",
"name": "GetHeaderV2",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/InfinityQSV2/1677273357/header",
"method": "GET",
"sortNum": 55000,
"created": "2023-02-27T20:07:11.931Z",
"modified": "2023-02-27T20:07:11.931Z",
"headers": [],
"params": [],
"tests": [
{
"type": "json-query",
"custom": "json.",
"action": "count",
"value": "2"
}
]
},
{
"_id": "0aafd6ed-26a6-4a07-825c-8c1fee603b6a",
"colId": "fb96b15a-0cc4-48c7-8767-34f1242750e8",
"containerId": "",
"name": "GetHeaders",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/export/headers",
"method": "GET",
"sortNum": 10000,
"created": "2023-03-08T17:16:56.561Z",
"modified": "2023-03-08T17:17:39.783Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
},
{
"_id": "af298148-482d-4822-80ba-1abb86e1f9c2",
"colId": "fb96b15a-0cc4-48c7-8767-34f1242750e8",
"containerId": "",
"name": "GetExport",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/export/export",
"method": "GET",
"sortNum": 15000,
"created": "2023-03-08T17:17:47.597Z",
"modified": "2023-03-08T17:19:13.764Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
},
{
"_id": "a787c81d-381e-451d-9d96-e607f06efdaf",
"colId": "fb96b15a-0cc4-48c7-8767-34f1242750e8",
"containerId": "",
"name": "GetLogistics",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/export/logistics",
"method": "GET",
"sortNum": 30000,
"created": "2023-03-08T17:18:38.179Z",
"modified": "2023-03-08T17:19:21.874Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
},
{
"_id": "7e19c7d4-2d93-46e1-88fd-ba5312885713",
"colId": "fb96b15a-0cc4-48c7-8767-34f1242750e8",
"containerId": "",
"name": "GetProcessDataStandardFormat",
"url": "https://oi-metrology-viewer-prod.mes.infineon.com/api/export/pdsf",
"method": "GET",
"sortNum": 40000,
"created": "2023-03-08T17:18:49.042Z",
"modified": "2023-03-08T17:19:27.119Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
},
{
"_id": "25eb571f-064c-4b3f-8c20-666c66c1b123",
"colId": "5bfd00bc-b58c-49d3-9f27-5acadd060a51",
"containerId": "",
"name": "GetHeaders",
"url": "https://mestsa008.infineon.com:50302/api/export/headers",
"method": "GET",
"sortNum": 10000,
"created": "2023-03-08T17:31:19.471Z",
"modified": "2023-03-08T18:48:51.819Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
},
{
"_id": "f5feb8e3-0e82-4b47-a15e-97ef069a1539",
"colId": "5bfd00bc-b58c-49d3-9f27-5acadd060a51",
"containerId": "",
"name": "GetExport",
"url": "https://mestsa008.infineon.com:50302/api/export/export",
"method": "GET",
"sortNum": 15000,
"created": "2023-03-08T17:31:19.472Z",
"modified": "2023-03-08T17:31:19.472Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
},
{
"_id": "7fddba99-14a2-4c6a-bf4a-4b94391929cf",
"colId": "5bfd00bc-b58c-49d3-9f27-5acadd060a51",
"containerId": "",
"name": "GetLogistics",
"url": "https://mestsa008.infineon.com:50302/api/export/logistics",
"method": "GET",
"sortNum": 30000,
"created": "2023-03-08T17:31:19.473Z",
"modified": "2023-03-08T17:31:19.473Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
},
{
"_id": "07d5b0c3-684a-4cad-8a48-b164e8da87b0",
"colId": "5bfd00bc-b58c-49d3-9f27-5acadd060a51",
"containerId": "",
"name": "GetProcessDataStandardFormat",
"url": "https://mestsa008.infineon.com:50302/api/export/pdsf",
"method": "GET",
"sortNum": 40000,
"created": "2023-03-08T17:31:19.474Z",
"modified": "2023-03-08T17:31:19.474Z",
"headers": [],
"params": [],
"body": {
"type": "json",
"raw": "{\n \"PSN\": \"4698\",\n \"RDS\": \"578824\",\n \"Reactor\": \"62\",\n \"ID\": 1678296039\n}",
"form": []
},
"tests": []
}
]

View File

@ -35,8 +35,8 @@ public class InboundController : ControllerBase
{ {
public bool Success { get; set; } public bool Success { get; set; }
public long HeaderID { get; set; } public long HeaderID { get; set; }
public List<string> Errors { get; set; } public List<string>? Errors { get; set; }
public List<string> Warnings { get; set; } public List<string>? Warnings { get; set; }
} }
// this is the main endpoint, it accepts a JSON message that contains both the header and data records together // this is the main endpoint, it accepts a JSON message that contains both the header and data records together
@ -86,7 +86,7 @@ public class InboundController : ControllerBase
else else
r.Errors.Add("Invalid json"); r.Errors.Add("Invalid json");
if (r.Errors.Count == 0) if (r.Errors.Count == 0 && jsonbody is not null)
{ {
try try
{ {
@ -147,14 +147,14 @@ public class InboundController : ControllerBase
if (string.IsNullOrWhiteSpace(_AppSettings.InboundApiAllowedIPList)) if (string.IsNullOrWhiteSpace(_AppSettings.InboundApiAllowedIPList))
return true; return true;
System.Net.IPAddress remoteIP = HttpContext.Connection.RemoteIpAddress; System.Net.IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress;
byte[] remoteIPBytes = remoteIP.GetAddressBytes(); byte[]? remoteIPBytes = remoteIP?.GetAddressBytes();
string[] allowedIPs = _AppSettings.InboundApiAllowedIPList.Split(';'); string[] allowedIPs = _AppSettings.InboundApiAllowedIPList.Split(';');
foreach (string ip in allowedIPs) foreach (string ip in allowedIPs)
{ {
System.Net.IPAddress parsedIP; System.Net.IPAddress? parsedIP;
if (System.Net.IPAddress.TryParse(ip, out parsedIP)) if (remoteIPBytes is not null && System.Net.IPAddress.TryParse(ip, out parsedIP))
{ {
if (parsedIP.GetAddressBytes().SequenceEqual(remoteIPBytes)) if (parsedIP.GetAddressBytes().SequenceEqual(remoteIPBytes))
return true; return true;

View File

@ -1,99 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using System.Linq;
namespace OI.Metrology.Archive.ApiControllers;
using OI.Metrology.Archive.Models;
using OI.Metrology.Shared.Models.Stateless;
using System.Text.Json;
public class ReactorsController : Controller
{
private readonly AppSettings _AppSettings;
private readonly IMetrologyRepository _MetrologyRepository;
public ReactorsController(AppSettings appSettings, IMetrologyRepository metrologyRepository)
{
_AppSettings = appSettings;
_MetrologyRepository = metrologyRepository;
}
private static int[] EvenReactors()
{
int[] results = 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
};
return results;
}
private static int[] OddReactors()
{
int[] results = 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
};
return results;
}
[HttpGet("/api/reactors/{even}")]
public IActionResult Index(bool even)
{
int[] n = even ? EvenReactors() : OddReactors();
var r = n.Select(l => new { Name = $"R{l}", Id = l });
return Json(r, new JsonSerializerOptions { PropertyNamingPolicy = null, WriteIndented = true });
}
}

View File

@ -203,7 +203,7 @@ public class ToolTypesController : Controller
if (ds.Tables[0].Rows.Count != 1) if (ds.Tables[0].Rows.Count != 1)
throw new Exception("Error exporting, invalid filename"); throw new Exception("Error exporting, invalid filename");
string filename = Convert.ToString(ds.Tables[0].Rows[0][0]); string? filename = Convert.ToString(ds.Tables[0].Rows[0][0]);
// The second table has the header data // The second table has the header data
if (ds.Tables[1].Rows.Count != 1) if (ds.Tables[1].Rows.Count != 1)
@ -211,7 +211,7 @@ public class ToolTypesController : Controller
System.Text.StringBuilder sb = new(); System.Text.StringBuilder sb = new();
foreach (object o in ds.Tables[1].Rows[0].ItemArray) foreach (object? o in ds.Tables[1].Rows[0].ItemArray)
{ {
if ((o is not null) && (!Convert.IsDBNull(o))) if ((o is not null) && (!Convert.IsDBNull(o)))
_ = sb.Append(Convert.ToString(o)); _ = sb.Append(Convert.ToString(o));
@ -221,7 +221,7 @@ public class ToolTypesController : Controller
// The third table has the detail data // The third table has the detail data
foreach (System.Data.DataRow dr in ds.Tables[2].Rows) foreach (System.Data.DataRow dr in ds.Tables[2].Rows)
{ {
foreach (object o in dr.ItemArray) foreach (object? o in dr.ItemArray)
{ {
if ((o is not null) && (!Convert.IsDBNull(o))) if ((o is not null) && (!Convert.IsDBNull(o)))
_ = sb.Append(Convert.ToString(o)); _ = sb.Append(Convert.ToString(o));

View File

@ -43,7 +43,8 @@ public class ApiLoggingMiddleware
else else
{ {
// if there are content type filters configured, only log is the request begins with one of them // if there are content type filters configured, only log is the request begins with one of them
doLogging = _AppSettings.ApiLoggingContentTypes.Split(';').Any(ct => httpContext.Request.ContentType.StartsWith(ct)); string? contentType = httpContext.Request.ContentType;
doLogging = contentType is not null && _AppSettings.ApiLoggingContentTypes.Split(';').Any(ct => contentType.StartsWith(ct));
} }
} }
} }

View File

@ -14,7 +14,7 @@ public class ErrorHandlerController : Controller
public IActionResult Index() public IActionResult Index()
{ {
IExceptionHandlerFeature error = HttpContext.Features.Get<IExceptionHandlerFeature>(); IExceptionHandlerFeature? error = HttpContext.Features.Get<IExceptionHandlerFeature>();
if (error is null) if (error is null)
{ {
return Redirect("~/"); return Redirect("~/");

View File

@ -52,7 +52,7 @@ public class ExportController : Controller
[Route("/ExportData")] [Route("/ExportData")]
public ActionResult ExportData(Export model) public ActionResult ExportData(Export model)
{ {
ToolType toolType = null; ToolType? toolType = null;
if (string.IsNullOrEmpty(model.ToolType)) if (string.IsNullOrEmpty(model.ToolType))
ModelState.AddModelError("Exception", "Invalid selection"); ModelState.AddModelError("Exception", "Invalid selection");
else else
@ -66,7 +66,7 @@ public class ExportController : Controller
else if (string.IsNullOrWhiteSpace(toolType.ExportSPName)) else if (string.IsNullOrWhiteSpace(toolType.ExportSPName))
ModelState.AddModelError("ToolType", "Tool type is not exportable"); ModelState.AddModelError("ToolType", "Tool type is not exportable");
} }
if (ModelState.IsValid) if (ModelState.IsValid && toolType?.ToolTypeName is not null && toolType.ExportSPName is not null)
{ {
try try
{ {
@ -114,10 +114,13 @@ public class ExportController : Controller
{ {
if (i > 0) if (i > 0)
_ = r.Append(','); _ = r.Append(',');
object v = dr[i]; object v = dr[i];
if (!Convert.IsDBNull(v)) if (!Convert.IsDBNull(v))
_ = r.Append(FormatForCSV(Convert.ToString(v))); {
string? c = Convert.ToString(v);
if (c is not null)
_ = r.Append(FormatForCSV(c));
}
} }
return r.ToString(); return r.ToString();
} }

View File

@ -6,7 +6,6 @@ using OI.Metrology.Shared.Repositories;
using OI.Metrology.Shared.ViewModels; using OI.Metrology.Shared.ViewModels;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using IO = System.IO;
namespace OI.Metrology.Archive.Controllers; namespace OI.Metrology.Archive.Controllers;
@ -69,50 +68,6 @@ public class PagesController : Controller
public IActionResult Crash() => public IActionResult Crash() =>
throw new Exception("Test unhandled exception"); throw new Exception("Test unhandled exception");
[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 (!IO.Directory.Exists(directory))
_ = IO.Directory.CreateDirectory(directory);
string[] model = new string[] { mod, equipment, layer, zone, rds, initials };
if (!string.IsNullOrEmpty(initials))
IO.File.WriteAllLines(IO.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] [HttpGet]
[Route("/RdsMax")] [Route("/RdsMax")]
[Route("/Metrology/RdsMax")] [Route("/Metrology/RdsMax")]
@ -123,9 +78,4 @@ public class PagesController : Controller
return View(results); return View(results);
} }
[HttpGet]
[Route("/Reactor")]
[Route("/Metrology/Reactor")]
public IActionResult Reactor() => View(new RunInfo());
} }

View File

@ -0,0 +1,2 @@
[*.cs]
csharp_preserve_single_line_statements = true

View File

@ -1,6 +1,5 @@
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System; using System;
using System.ComponentModel.DataAnnotations;
using System.Text.Json; using System.Text.Json;
namespace OI.Metrology.Archive.Models.Binder; namespace OI.Metrology.Archive.Models.Binder;
@ -8,25 +7,21 @@ namespace OI.Metrology.Archive.Models.Binder;
public class AppSettings public class AppSettings
{ {
#nullable disable public string? ApiLoggingContentTypes { get; set; }
public string? ApiLoggingPathPrefixes { get; set; }
[Display(Name = "Api Logging Content Types"), Required] public string ApiLoggingContentTypes { get; set; } public string? ApiLogPath { get; set; }
[Display(Name = "Api Logging Path Prefixes"), Required] public string ApiLoggingPathPrefixes { get; set; } public string? AttachmentPath { get; set; }
[Display(Name = "Api Log Path"), Required] public string ApiLogPath { get; set; } public string? BuildNumber { get; set; }
[Display(Name = "Attachment Path"), Required] public string AttachmentPath { get; set; } public string? Company { get; set; }
[Display(Name = "Build Number"), Required] public string BuildNumber { get; set; } public string? ConnectionString { get; set; }
[Display(Name = "Company"), Required] public string Company { get; set; } public string? GitCommitSeven { get; set; }
[Display(Name = "Connection String"), Required] public string ConnectionString { get; set; } public string? InboundApiAllowedIPList { get; set; }
[Display(Name = "Git Commit Seven"), Required] public string GitCommitSeven { get; set; } public string? MonAResource { get; set; }
[Display(Name = "Inbound Api Allowed IP List"), Required] public string InboundApiAllowedIPList { get; set; } public string? MonASite { get; set; }
[Display(Name = "MonA Resource"), Required] public string MonAResource { get; set; } public string? Oi2SqlConnectionString { get; set; }
[Display(Name = "MonA Site"), Required] public string MonASite { get; set; } public string? OIExportPath { get; set; }
[Display(Name = "Oi 2 Sql Connection String"), Required] public string Oi2SqlConnectionString { get; set; } public string? URLs { get; set; }
[Display(Name = "OI Export Path"), Required] public string OIExportPath { get; set; } public string? WorkingDirectoryName { get; set; }
[Display(Name = "URLs"), Required] public string URLs { get; set; }
[Display(Name = "Working Directory Name"), Required] public string WorkingDirectoryName { get; set; }
#nullable restore
public override string ToString() public override string ToString()
{ {
@ -34,41 +29,42 @@ public class AppSettings
return result; return result;
} }
private static Models.AppSettings Get(AppSettings appSettings) 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)
{ {
Models.AppSettings result; Models.AppSettings result;
if (appSettings is null) if (appSettings is null) throw new NullReferenceException(nameof(appSettings));
throw new NullReferenceException(nameof(appSettings)); if (appSettings.ApiLoggingContentTypes is null) throw new NullReferenceException(nameof(ApiLoggingContentTypes));
if (appSettings.ApiLoggingContentTypes is null) if (appSettings.ApiLoggingPathPrefixes is null) throw new NullReferenceException(nameof(ApiLoggingPathPrefixes));
throw new NullReferenceException(nameof(ApiLoggingContentTypes)); if (appSettings.ApiLogPath is null) throw new NullReferenceException(nameof(ApiLogPath));
if (appSettings.ApiLoggingPathPrefixes is null) if (appSettings.AttachmentPath is null) throw new NullReferenceException(nameof(AttachmentPath));
throw new NullReferenceException(nameof(ApiLoggingPathPrefixes)); if (appSettings.BuildNumber is null) throw new NullReferenceException(nameof(BuildNumber));
if (appSettings.ApiLogPath is null) if (appSettings.Company is null) throw new NullReferenceException(nameof(Company));
throw new NullReferenceException(nameof(ApiLogPath)); if (appSettings.ConnectionString is null) throw new NullReferenceException(nameof(ConnectionString));
if (appSettings.AttachmentPath is null) if (appSettings.GitCommitSeven is null) throw new NullReferenceException(nameof(GitCommitSeven));
throw new NullReferenceException(nameof(AttachmentPath)); if (appSettings.InboundApiAllowedIPList is null) throw new NullReferenceException(nameof(InboundApiAllowedIPList));
if (appSettings.BuildNumber is null) if (appSettings.MonAResource is null) throw new NullReferenceException(nameof(MonAResource));
throw new NullReferenceException(nameof(BuildNumber)); if (appSettings.MonASite is null) throw new NullReferenceException(nameof(MonASite));
if (appSettings.Company is null) if (appSettings.Oi2SqlConnectionString is null) throw new NullReferenceException(nameof(Oi2SqlConnectionString));
throw new NullReferenceException(nameof(Company)); if (appSettings.OIExportPath is null) throw new NullReferenceException(nameof(OIExportPath));
if (appSettings.ConnectionString is null) if (appSettings.URLs is null) throw new NullReferenceException(nameof(URLs));
throw new NullReferenceException(nameof(ConnectionString)); if (appSettings.WorkingDirectoryName is null) throw new NullReferenceException(nameof(WorkingDirectoryName));
if (appSettings.GitCommitSeven is null)
throw new NullReferenceException(nameof(GitCommitSeven));
if (appSettings.InboundApiAllowedIPList is null)
throw new NullReferenceException(nameof(InboundApiAllowedIPList));
if (appSettings.MonAResource is null)
throw new NullReferenceException(nameof(MonAResource));
if (appSettings.MonASite is null)
throw new NullReferenceException(nameof(MonASite));
if (appSettings.Oi2SqlConnectionString is null)
throw new NullReferenceException(nameof(Oi2SqlConnectionString));
if (appSettings.OIExportPath is null)
throw new NullReferenceException(nameof(OIExportPath));
if (appSettings.URLs is null)
throw new NullReferenceException(nameof(URLs));
if (appSettings.WorkingDirectoryName is null)
throw new NullReferenceException(nameof(WorkingDirectoryName));
result = new( result = new(
appSettings.ApiLoggingContentTypes, appSettings.ApiLoggingContentTypes,
appSettings.ApiLoggingPathPrefixes, appSettings.ApiLoggingPathPrefixes,
@ -91,7 +87,10 @@ public class AppSettings
public static Models.AppSettings Get(IConfigurationRoot configurationRoot) public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
{ {
Models.AppSettings result; Models.AppSettings result;
AppSettings appSettings = configurationRoot.Get<AppSettings>(); #pragma warning disable IL3050, IL2026
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
#pragma warning restore IL3050, IL2026
PreVerify(configurationRoot, appSettings);
result = Get(appSettings); result = Get(appSettings);
return result; return result;
} }

View File

@ -8,8 +8,7 @@
<PropertyGroup> <PropertyGroup>
<ImplicitUsings>disable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<LangVersion>10.0</LangVersion> <Nullable>enable</Nullable>
<Nullable>disable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
@ -27,19 +26,14 @@
<Content Remove="compilerconfig.json" /> <Content Remove="compilerconfig.json" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Dapper" Version="2.0.123" /> <PackageReference Include="Dapper" Version="2.1.24" />
<PackageReference Include="EntityFramework" Version="6.4.4" /> <PackageReference Include="EntityFramework" Version="6.4.4" />
<PackageReference Include="jQuery" Version="3.6.3" /> <PackageReference Include="jQuery" Version="3.7.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="6.1.0" />
<PackageReference Include="Serilog.AspNetCore.Ingestion" Version="1.0.0-dev-00032" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
</ItemGroup> </ItemGroup>

View File

@ -12,7 +12,6 @@ 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;
using Serilog;
using System; using System;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
@ -22,13 +21,11 @@ namespace OI.Metrology.Archive;
public class Program public class Program
{ {
internal readonly AppSettings _AppSettings;
private static (string, WebApplicationOptions) Get(string[] args) private static (string, WebApplicationOptions) Get(string[] args)
{ {
string webRootPath; string webRootPath;
Assembly assembly = Assembly.GetExecutingAssembly(); Assembly assembly = Assembly.GetExecutingAssembly();
string assemblyName = assembly.GetName()?.Name; string? assemblyName = assembly.GetName()?.Name;
if (string.IsNullOrEmpty(assemblyName)) if (string.IsNullOrEmpty(assemblyName))
throw new Exception(); throw new Exception();
string baseAssemblyName = assemblyName.Split('.')[0]; string baseAssemblyName = assemblyName.Split('.')[0];
@ -49,7 +46,7 @@ public class Program
public static int Main(string[] args) public static int Main(string[] args)
{ {
LoggerConfiguration loggerConfiguration = new(); ILogger<Program>? logger = null;
(string assemblyName, WebApplicationOptions _) = Get(args); (string assemblyName, WebApplicationOptions _) = Get(args);
WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args); WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args);
_ = webApplicationBuilder.Configuration.AddUserSecrets<Program>(); _ = webApplicationBuilder.Configuration.AddUserSecrets<Program>();
@ -58,10 +55,6 @@ public class Program
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); string workingDirectory = IWorkingDirectory.GetWorkingDirectory(assemblyName, _AppSettings.WorkingDirectoryName);
Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory); Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
_ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, webApplicationBuilder.Configuration);
_ = SerilogHostBuilderExtensions.UseSerilog(webApplicationBuilder.Host);
Log.Logger = loggerConfiguration.CreateLogger();
Serilog.ILogger log = Log.ForContext<Program>();
try try
{ {
_ = webApplicationBuilder.Services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true); _ = webApplicationBuilder.Services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);
@ -86,15 +79,16 @@ public class Program
if (WindowsServiceHelpers.IsWindowsService()) if (WindowsServiceHelpers.IsWindowsService())
{ {
_ = webApplicationBuilder.Services.AddSingleton<IHostLifetime, WindowsServiceLifetime>(); _ = webApplicationBuilder.Services.AddSingleton<IHostLifetime, WindowsServiceLifetime>();
#pragma warning disable CA1416
_ = webApplicationBuilder.Logging.AddEventLog(settings => _ = webApplicationBuilder.Logging.AddEventLog(settings =>
{ {
#pragma warning disable CA1416
if (string.IsNullOrEmpty(settings.SourceName)) if (string.IsNullOrEmpty(settings.SourceName))
settings.SourceName = webApplicationBuilder.Environment.ApplicationName; settings.SourceName = webApplicationBuilder.Environment.ApplicationName;
#pragma warning restore
}); });
#pragma warning restore
} }
WebApplication webApplication = webApplicationBuilder.Build(); WebApplication webApplication = webApplicationBuilder.Build();
logger = webApplication.Services.GetRequiredService<ILogger<Program>>();
if (!webApplicationBuilder.Environment.IsDevelopment()) if (!webApplicationBuilder.Environment.IsDevelopment())
{ {
_ = webApplication.UseExceptionHandler("/Error"); _ = webApplication.UseExceptionHandler("/Error");
@ -110,27 +104,22 @@ public class Program
_ = webApplication.UseSwagger(); _ = webApplication.UseSwagger();
_ = webApplication.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Archive V1")); _ = webApplication.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Archive V1"));
} }
_ = webApplication.Lifetime.ApplicationStopped.Register(Log.CloseAndFlush);
_ = ApplicationBuilderSerilogClientExtensions.UseSerilogIngestion(webApplication);
_ = SerilogApplicationBuilderExtensions.UseSerilogRequestLogging(webApplication);
_ = webApplication.UseFileServer(enableDirectoryBrowsing: true); _ = webApplication.UseFileServer(enableDirectoryBrowsing: true);
_ = webApplication.UseStaticFiles(); _ = webApplication.UseStaticFiles();
_ = webApplication.UseSession(); _ = webApplication.UseSession();
_ = webApplication.UseHttpsRedirection(); _ = webApplication.UseHttpsRedirection();
_ = webApplication.UseMiddleware<ApiLoggingMiddleware>(); _ = webApplication.UseMiddleware<ApiLoggingMiddleware>();
_ = webApplication.MapControllers(); _ = webApplication.MapControllers();
log.Information("Starting Web Application"); logger.LogInformation("Starting Web Application");
webApplication.Run(); webApplication.Run();
return 0; return 0;
} }
catch (Exception ex) catch (Exception ex)
{ {
log.Fatal(ex, "Host terminated unexpectedly"); try
return 1; { logger?.LogCritical(ex, "Host terminated unexpectedly"); }
} catch (Exception) { }
finally throw;
{
Log.CloseAndFlush();
} }
} }

View File

@ -13,6 +13,8 @@ using System.Transactions;
namespace OI.Metrology.Archive.Repositories; namespace OI.Metrology.Archive.Repositories;
#nullable disable
public class MetrologyRepository : IMetrologyRepository public class MetrologyRepository : IMetrologyRepository
{ {
private readonly IDbConnectionFactory _DBConnectionFactory; private readonly IDbConnectionFactory _DBConnectionFactory;
@ -308,13 +310,9 @@ public class MetrologyRepository : IMetrologyRepository
public DataTable GetHeaders(int toolTypeId, DateTime? startTime, DateTime? endTime, int? pageNo, int? pageSize, long? headerId, out long totalRecords) public DataTable GetHeaders(int toolTypeId, DateTime? startTime, DateTime? endTime, int? pageNo, int? pageSize, long? headerId, out long totalRecords)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId); IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
if (md is null)
throw new Exception("Invalid tool type metadata");
DataTable dt = new(); DataTable dt = new();
@ -404,13 +402,9 @@ public class MetrologyRepository : IMetrologyRepository
// Go Here Next // Go Here Next
public DataTable GetData(int toolTypeId, long headerid) public DataTable GetData(int toolTypeId, long headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId); IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
if (md is null)
throw new Exception("Invalid tool type metadata");
DataTable dt = new(); DataTable dt = new();
@ -515,13 +509,9 @@ public class MetrologyRepository : IMetrologyRepository
} }
public DataTable GetDataSharePoint(int toolTypeId, string headerid) public DataTable GetDataSharePoint(int toolTypeId, string headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId); IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
if (md is null)
throw new Exception("Invalid tool type metadata");
DataTable dt = new(); DataTable dt = new();
@ -610,9 +600,7 @@ public class MetrologyRepository : IMetrologyRepository
} }
public Guid GetHeaderAttachmentID(int toolTypeId, long headerId) public Guid GetHeaderAttachmentID(int toolTypeId, long headerId)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = GetDbConnection(); using DbConnection conn = GetDbConnection();
string sql = string sql =
@ -623,9 +611,7 @@ public class MetrologyRepository : IMetrologyRepository
public Guid GetDataAttachmentID(int toolTypeId, long headerId, string title) public Guid GetDataAttachmentID(int toolTypeId, long headerId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = GetDbConnection(); using DbConnection conn = GetDbConnection();
string sql = string sql =
@ -642,9 +628,7 @@ public class MetrologyRepository : IMetrologyRepository
public DataSet GetOIExportData(int toolTypeId, long headerid) public DataSet GetOIExportData(int toolTypeId, long headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
if (string.IsNullOrWhiteSpace(tt.OIExportSPName)) if (string.IsNullOrWhiteSpace(tt.OIExportSPName))
throw new Exception("OpenInsight export not available for " + tt.ToolTypeName); throw new Exception("OpenInsight export not available for " + tt.ToolTypeName);
@ -674,9 +658,7 @@ public class MetrologyRepository : IMetrologyRepository
if (toolTypeId is null) if (toolTypeId is null)
throw new Exception("Invalid tool type ID"); throw new Exception("Invalid tool type ID");
ToolType tt = GetToolTypeByID(toolTypeId.Value); ToolType tt = GetToolTypeByID(toolTypeId.Value) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
DbConnection conn = GetDbConnection(); DbConnection conn = GetDbConnection();
using (conn) using (conn)
@ -706,13 +688,9 @@ public class MetrologyRepository : IMetrologyRepository
public IEnumerable<KeyValuePair<string, string>> GetHeaderFields(int toolTypeId, long headerid) public IEnumerable<KeyValuePair<string, string>> GetHeaderFields(int toolTypeId, long headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId); IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
if (md is null)
throw new Exception("Invalid tool type metadata");
List<KeyValuePair<string, string>> r = new(); List<KeyValuePair<string, string>> r = new();
@ -760,9 +738,7 @@ public class MetrologyRepository : IMetrologyRepository
// Jonathan changed this to remove the reviewDate update on the database. // Jonathan changed this to remove the reviewDate update on the database.
public int UpdateReviewDate(int toolTypeId, long headerId, bool clearDate) public int UpdateReviewDate(int toolTypeId, long headerId, bool clearDate)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = GetDbConnection(); using DbConnection conn = GetDbConnection();
if (clearDate) if (clearDate)
@ -781,9 +757,7 @@ public class MetrologyRepository : IMetrologyRepository
public Guid GetHeaderAttachmentIDByTitle(int toolTypeId, string title) public Guid GetHeaderAttachmentIDByTitle(int toolTypeId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = GetDbConnection(); using DbConnection conn = GetDbConnection();
string sql = string sql =
@ -793,9 +767,7 @@ public class MetrologyRepository : IMetrologyRepository
public Guid GetDataAttachmentIDByTitle(int toolTypeId, string title) public Guid GetDataAttachmentIDByTitle(int toolTypeId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = GetDbConnection(); using DbConnection conn = GetDbConnection();
string sql = string sql =

View File

@ -11,6 +11,8 @@ using System.Text;
namespace OI.Metrology.Archive.Repositories; namespace OI.Metrology.Archive.Repositories;
#nullable disable
public class RdsMaxRepo : IRdsMaxRepo public class RdsMaxRepo : IRdsMaxRepo
{ {

View File

@ -6,13 +6,15 @@ using System.Data.SqlClient;
namespace OI.Metrology.Archive.Repositories; namespace OI.Metrology.Archive.Repositories;
#nullable disable
public class SQLDbConnectionFactory : IDbConnectionFactory public class SQLDbConnectionFactory : IDbConnectionFactory
{ {
private readonly AppSettings _AppSettings; private readonly AppSettings _AppSettings;
public SQLDbConnectionFactory(AppSettings appSettings) => _AppSettings = appSettings; public SQLDbConnectionFactory(AppSettings appSettings) => _AppSettings = appSettings;
public DbConnection GetDbConnection() public DbConnection GetDbConnection(bool? useOI2Sql = null)
{ {
DbProviderFactories.RegisterFactory( DbProviderFactories.RegisterFactory(
typeof(SqlConnection).Namespace, typeof(SqlConnection).Namespace,

View File

@ -4,6 +4,8 @@ using System.IO;
namespace OI.Metrology.Archive.Services; namespace OI.Metrology.Archive.Services;
#nullable disable
using OI.Metrology.Archive.Models; using OI.Metrology.Archive.Models;
using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
@ -72,7 +74,7 @@ public class AttachmentsService : IAttachmentsService
queryString = "SELECT * FROM " + toolType.HeaderTableName + " WHERE AttachmentId = '" + title + "'"; queryString = "SELECT * FROM " + toolType.HeaderTableName + " WHERE AttachmentId = '" + title + "'";
} }
DateTime SearchDate = new(); DateTime SearchDate = new();
string connectionString = @"Server=messv01ec.ec.local\PROD1,53959;Database=Metrology_Archive;Integrated Security=True"; string connectionString = @"Server=messqlec1.infineon.com\PROD1,53959;Database=Metrology_Archive;Integrated Security=True";
using (SqlConnection connection = new(connectionString)) using (SqlConnection connection = new(connectionString))
{ {
SqlCommand command = new(queryString, connection); SqlCommand command = new(queryString, connection);
@ -175,4 +177,7 @@ public class AttachmentsService : IAttachmentsService
SaveAttachment(toolType, headerId, dataUniqueId, filename, formFile); SaveAttachment(toolType, headerId, dataUniqueId, filename, formFile);
} }
string IAttachmentsService.GetProcessDataStandardFormat(IMetrologyRepository metrologyRepository, string attachmentPath, int toolTypeId, long headerId) =>
throw new NotImplementedException();
} }

View File

@ -8,6 +8,8 @@ using System.Linq;
namespace OI.Metrology.Archive.Services; namespace OI.Metrology.Archive.Services;
#nullable disable
public class InboundDataService : IInboundDataService public class InboundDataService : IInboundDataService
{ {
private readonly IMetrologyRepository _MetrologyRepository; private readonly IMetrologyRepository _MetrologyRepository;

View File

@ -1,377 +0,0 @@
@model OI.Metrology.Shared.ViewModels.RunInfo
@{
ViewData["Title"] = "Reactor";
}
<style>
#RunGridDiv,
#DetailsGridDiv {
font-size: 12px;
}
</style>
<h4>Reactor</h4>
<form class="form-inline mb-4">
<div class="form-group" id="EvenReactorDiv">
<button for="EvenReactor">Even Reactor</button>
<label for="EvenReactor">Even Reactor</label>
<div class="form-control" id="EvenReactor" hidden></div>
</div>
<div class="form-group" id="OddReactorDiv">
<button for="OddReactor">Odd Reactor</button>
<label for="OddReactor">Odd Reactor</label>
<div class="form-control" id="OddReactor" hidden></div>
</div>&nbsp;&nbsp;
<div class="form-group">
<input class="btn btn-primary" type="button" value="Load Runs" id="LoadRunsButton" />
</div>&nbsp;&nbsp;
</form>
<div style="height: 300px;" id="RunGridDiv">
<span id="EvenReactorID" hidden></span>
<span id="OddReactorID" hidden></span>
<table id="RunGrid"></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>
<script>
var EvenReactor = null;
var OddReactor = null;
function LoadRunGrid() {
var EvenReactorID = $("#EvenReactor").igCombo("value");
$("#EvenReactorID").text(EvenReactorID);
HideDetailsDiv();
DisableHeaderButtons();
$("#HeaderId").text("");
$("#HeaderAttachmentId").text("");
$("#HeaderDate").text("");
$("#SPHeaderID").text("");
var gridCreated = $("#RunGrid").data("igGrid");
if (gridCreated)
$("#RunGrid").igGrid("destroy");
$.ajax({
type: "GET",
url: "@Url.Content("~/api/EvenReactors/")" + EvenReactorID + "?sortby=grid",
success: function (r) {
if ((r.Results == null) || (r.Results.EvenReactor == null) || (r.Results.Metadata == null))
ShowErrorMessage("Invalid Even Reactor: " + EvenReactorID);
else {
EvenReactor = r.Results.EvenReactor;
EvenReactorMetaData = r.Results.Metadata;
RequestHeaderData();
}
},
error: function (e) {
DisplayWSMessage("error", "There was an error getting EvenReactor info.", e);
}
});
}
function DisableHeaderButtons() {
$("#GetDataButton").prop("disabled", true);
$("#ReviewButton").prop("disabled", true);
}
function EnableHeaderButtons() {
$("#GetDataButton").prop("disabled", false);
$("#ReviewButton").prop("disabled", false);
}
function HideDetailsDiv() {
$("#DetailsDiv").prop("hidden", true);
$("#DataAttachmentFrame").prop("src", "");
}
function ShowDetailsDiv() {
$("#DetailsDiv").prop("hidden", false);
$("#ExportDiv").prop("hidden", true);
if ((EvenReactor != null) && (EvenReactor.OIExportSPName != null) && (EvenReactor.OIExportSPName.length > 0)) {
$("#ExportDiv").prop("hidden", false);
$("#OIExportResult").text('');
}
$("#DataAttachmentFrame").prop("hidden", true);
$("#HeaderAttachmentFrame").prop("hidden", true);
if (EvenReactor != null) {
var visibleFrames = 0;
if (EvenReactor.DisplayDataAttachment && EvenReactor.DisplayDataAttachment.length > 0) {
visibleFrames += 1;
$("#DataAttachmentFrame").prop("hidden", false);
}
if (EvenReactor.DisplayHeaderAttachment && EvenReactor.DisplayHeaderAttachment.length > 0) {
visibleFrames += 1;
$("#HeaderAttachmentFrame").prop("hidden", false);
}
var frameWidth = (98 / visibleFrames) + "%";
$("#DataAttachmentFrame,#HeaderAttachmentFrame").css('width', frameWidth);
}
}
function HeaderSelectionChanged(evt, ui) {
if (ui.row.index >= 0) {
if ($("#HeaderId").text() == ui.row.id) {
EnableHeaderButtons();
return;
}
}
DisableHeaderButtons();
HideDetailsDiv();
if (ui.row.index >= 0) {
EnableHeaderButtons();
$("#HeaderId").text(ui.row.id);
var rowData = ui.owner.grid.dataSource.dataView()[ui.row.index];
$("#HeaderAttachmentId").text(rowData.AttachmentID);
$("#HeaderDate").text(rowData.Date);
$("#SPHeaderID").text(rowData.Title);
}
}
function CancelHandler(evt, ui) {
return false;
}
function DetailSelectionChanged(evt, ui) {
$("#DataAttachmentFrame").prop("src", "");
if (ui.row.index >= 0) {
var rowData = ui.owner.grid.dataSource.dataView()[ui.row.index];
var EvenReactorID = $("#EvenReactorID").text();
var attachmentUrlBase = '@Url.Content("~/api/EvenReactors/")' + EvenReactorID;
var attachmentId = rowData.AttachmentID;
var test = rowData.date
if ((attachmentId == null) || (attachmentId === ''))
return;
if ((EvenReactor.DisplayDataAttachment == null) || (EvenReactor.DisplayDataAttachment === ''))
return;
$("#DataAttachmentFrame").prop("src", attachmentUrlBase + "/data/files/" + attachmentId + "/" + EvenReactor.DisplayDataAttachment);
}
}
function LoadHeaderAttachment() {
var EvenReactorID = $("#EvenReactorID").text();
var attachmentUrlBase = '@Url.Content("~/api/EvenReactors/")' + EvenReactorID;
var attachmentId = $("#HeaderAttachmentId").text();
var dateToUse = new Date($("#HeaderDate").text());
var month = dateToUse.getMonth + 1;
var year = dateToUse.getFullYear;
if ((attachmentId == null) || (attachmentId === '') || (EvenReactor.DisplayHeaderAttachment == null) || (EvenReactor.DisplayHeaderAttachment === '')) {
$("#HeaderAttachmentFrame").prop("src", "");
} else {
$("#HeaderAttachmentFrame").prop("src", attachmentUrlBase + "/header/files/" + attachmentId + "/" + EvenReactor.DisplayHeaderAttachment + "?date=" + dateToUse);
}
$("#DataAttachmentFrame").prop("src", "");
}
function CheckDate() {
var date = new Date($("#HeaderDate").text());
return date;
}
function LoadDetails() {
ShowDetailsDiv();
LoadHeaderAttachment();
var dateToUse = $("#HeaderDate").text();
var gridCreated = $("#DetailsGrid").data("igGrid");
if (gridCreated)
$("#DetailsGrid").igGrid("destroy");
var dateID = Date.parse($("#HeaderDate").text());
var cutoffDt = Date.parse('2019-07-08')
var headerId = $("#HeaderId").text();
var EvenReactorID = $("#EvenReactorID").text();
var spHeaderID = $("#SPHeaderID").text();
if (dateID < cutoffDt) {
detailsURL = "@Url.Content("~/api/EvenReactors/")" + EvenReactorID + "/headers/" + spHeaderID + "/data/isSharePoint";
}
else {
var detailsURL = "@Url.Content("~/api/EvenReactors/")" + EvenReactorID + "/headers/" + headerId + "/data";
}
var gridColumns = [
{ key: "AttachmentID", dataType: "string", hidden: true },
{ key: "Title", dataType: "string", hidden: true },
];
for (var i = 0; i < EvenReactorMetaData.length; i++) {
var f = EvenReactorMetaData[i];
if ((f.Header == false) && (f.GridDisplayOrder > 0)) {
var col = {
key: f.ColumnName,
headerText: f.DisplayTitle,
width: "150px",
};
if (f.GridAttributes != null)
jQuery.extend(col, JSON.parse(f.GridAttributes));
if (col.formatter != null) {
if (col.formatter == "boolToYesNo")
col.formatter = boolToYesNo;
else
col.formatter = null;
}
gridColumns.push(col);
}
}
var date = EvenReactorMetaData[2];
var gridParms = {
autoGenerateColumns: false,
primaryKey: "ID",
features: [
{ name: "Selection", mode: "row", rowSelectionChanging: DetailSelectionChanged },
{ name: "Resizing" },
{ name: "Sorting", type: "local" }
],
columns: gridColumns,
dataSource: detailsURL,
responseDataKey: "Results"
};
if ((EvenReactor != null) && (EvenReactor.DataGridAttributes != null)) {
jQuery.extend(gridParms, JSON.parse(EvenReactor.DataGridAttributes));
}
$("#DetailsGrid").igGrid(gridParms);
}
var initialHeaderId = @Model.HeaderID;
var initialHeaderAttachmentId = "@Model.HeaderAttachmentID";
function RequestHeaderData() {
var startDate = $("#StartDate").igDatePicker("value");
var startTime = $("#StartTime").igTimePicker("value");
var endDate = $("#EndDate").igDatePicker("value");
var endTime = $("#EndTime").igTimePicker("value");
var parms = {
datebegin: new Date(
startDate.getFullYear(), startDate.getMonth(), startDate.getDate(),
startTime.getHours(), startTime.getMinutes(), startTime.getSeconds()).toISOString(),
dateend: new Date(
endDate.getFullYear(), endDate.getMonth(), endDate.getDate(),
endTime.getHours(), endTime.getMinutes(), endTime.getSeconds()).toISOString(),
}
var headerId = 0;
if (initialHeaderId > 0) {
headerId = initialHeaderId;
parms.headerid = headerId;
$("#HeaderId").text(headerId);
$("#HeaderAttachmentId").text(initialHeaderAttachmentId);
initialHeaderId = -1;
}
var headerURL = "@Url.Content("~/api/EvenReactors/")" + EvenReactor.ID + "/headers?" + $.param(parms);
var gridColumns = [
{ key: "ID", dataType: "number", hidden: true },
{ key: "AttachmentID", dataType: "string", hidden: true },
{ key: "Title", dataType: "string", hidden: true },
];
for (var i = 0; i < EvenReactorMetaData.length; i++) {
var f = EvenReactorMetaData[i];
if ((f.Header == true) && (f.GridDisplayOrder > 0)) {
var col = {
key: f.ColumnName,
headerText: f.DisplayTitle,
width: "150px",
};
if (f.GridAttributes != null)
jQuery.extend(col, JSON.parse(f.GridAttributes));
if (col.formatter != null) {
if (col.formatter == "boolToYesNo")
col.formatter = boolToYesNo;
else
col.formatter = null;
}
gridColumns.push(col);
}
}
var gridParms = {
autoGenerateColumns: false,
primaryKey: "ID",
height: "100%",
width: "100%",
features: [
{ name: "Paging", type: "local", recordCountKey: "TotalRows", pageSize: 100, pageSizeList: [50, 100, 250, 500], pageSizeUrlKey: "pageSize", "pageIndexUrlKey": "page" },
{ name: "Selection", mode: "row", rowSelectionChanged: HeaderSelectionChanged },
{ name: "Filtering", type: "local" },
{ name: 'Resizing' },
{ name: "Sorting", type: "local" }
],
columns: gridColumns,
dataSource: headerURL,
responseDataKey: "Results",
};
if ((EvenReactor != null) && (EvenReactor.RunGridAttributes != null)) {
jQuery.extend(gridParms, JSON.parse(EvenReactor.RunGridAttributes));
}
$("#RunGrid").igGrid(gridParms);
if (headerId > 0) {
LoadDetails();
}
}
$(document).ready(function () {
$("#EvenReactor").igCombo({
dataSource: '@Url.Content("~/api/reactors/true")',
responseDataKey: "Results",
textKey: "Name",
valueKey: "Id",
mode: "dropdown",
width: 150,
itemsRendered: function (evt, ui) {
LoadRunGrid();
},
selectionChanged: LoadRunGrid,
initialSelectedItems: [{ value: @Model.HeaderID }]
});
$("#OddReactor").igCombo({
dataSource: '@Url.Content("~/api/reactors/false")',
responseDataKey: "Results",
textKey: "Name",
valueKey: "Id",
mode: "dropdown",
width: 150,
itemsRendered: function (evt, ui) {
LoadRunGrid();
},
selectionChanged: LoadRunGrid,
initialSelectedItems: [{ value: @Model.HeaderID }]
});
$("#EvenReactorDiv").prop("hidden", true);
$("#OddReactorDiv").prop("hidden", true);
$("#RunGrid").on("dblclick", "tr", LoadDetails);
$("#LoadRunsButton").click(LoadRunGrid);
$("#GetDataButton").click(LoadDetails);
});
</script>

View File

@ -71,7 +71,7 @@
<li>@Html.ActionLink("Export", "Index", "Export", new { area = "" }, null)</li> <li>@Html.ActionLink("Export", "Index", "Export", new { area = "" }, null)</li>
</ul> </ul>
<p class="navbar-text navbar-right"> <p class="navbar-text navbar-right">
@User.Identity.Name @User.Identity?.Name
</p> </p>
</div> </div>
</div> </div>

View File

@ -3,10 +3,10 @@
"ApiLoggingContentTypes": "application/json", "ApiLoggingContentTypes": "application/json",
"ApiLoggingPathPrefixes": "/api/inbound", "ApiLoggingPathPrefixes": "/api/inbound",
"ApiLogPath": "D:\\Metrology\\MetrologyAPILogs", "ApiLogPath": "D:\\Metrology\\MetrologyAPILogs",
"AttachmentPath": "\\\\messv02ecc1.ec.local\\EC_Metrology_Si\\MetrologyAttachments", "AttachmentPath": "\\\\mesfs.infineon.com\\EC_Metrology_Si\\MetrologyAttachments",
"BuildNumber": "1", "BuildNumber": "1",
"Company": "Infineon Technologies Americas Corp.", "Company": "Infineon Technologies Americas Corp.",
"ConnectionString": "Data Source=messv01ec.ec.local\\PROD1,53959;Integrated Security=True;Initial Catalog=Metrology_Archive;", "ConnectionString": "Data Source=messqlec1.infineon.com\\PROD1,53959;Integrated Security=True;Initial Catalog=Metrology_Archive;",
"GitCommitSeven": "1234567", "GitCommitSeven": "1234567",
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
@ -19,7 +19,7 @@
"InboundApiAllowedIPList": "", "InboundApiAllowedIPList": "",
"MonAResource": "OI_Metrology_Archive_IFX", "MonAResource": "OI_Metrology_Archive_IFX",
"MonASite": "auc", "MonASite": "auc",
"Oi2SqlConnectionString": "Data Source=messv01ec.ec.local\\PROD1,53959;Initial Catalog=LSL2SQL;Persist Security Info=True;User ID=srpadmin;Password=0okm9ijn;", "Oi2SqlConnectionString": "Data Source=messqlec1.infineon.com\\PROD1,53959;Initial Catalog=LSL2SQL;Persist Security Info=True;User ID=srpadmin;Password=0okm9ijn;",
"OIExportPath": "\\\\openinsight-db-srv.na.infineon.com\\apps\\Metrology\\Data", "OIExportPath": "\\\\openinsight-db-srv.na.infineon.com\\apps\\Metrology\\Data",
"Serilog": { "Serilog": {
"Using": [ "Using": [

View File

@ -3,10 +3,10 @@
"ApiLoggingContentTypes": "application/json", "ApiLoggingContentTypes": "application/json",
"ApiLoggingPathPrefixes": "/api/inbound", "ApiLoggingPathPrefixes": "/api/inbound",
"ApiLogPath": "D:\\Metrology\\MetrologyAPILogs", "ApiLogPath": "D:\\Metrology\\MetrologyAPILogs",
"AttachmentPath": "\\\\messv02ecc1.ec.local\\EC_Metrology_Si\\MetrologyAttachments", "AttachmentPath": "\\\\mesfs.infineon.com\\EC_Metrology_Si\\MetrologyAttachments",
"BuildNumber": "1", "BuildNumber": "1",
"Company": "Infineon Technologies Americas Corp.", "Company": "Infineon Technologies Americas Corp.",
"ConnectionString": "Data Source=messv01ec.ec.local\\PROD1,53959;Integrated Security=True;Initial Catalog=Metrology_Archive;", "ConnectionString": "Data Source=messqlec1.infineon.com\\PROD1,53959;Integrated Security=True;Initial Catalog=Metrology_Archive;",
"GitCommitSeven": "1234567", "GitCommitSeven": "1234567",
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
@ -19,7 +19,7 @@
"InboundApiAllowedIPList": "", "InboundApiAllowedIPList": "",
"MonAResource": "OI_Metrology_Archive_EC", "MonAResource": "OI_Metrology_Archive_EC",
"MonASite": "auc", "MonASite": "auc",
"Oi2SqlConnectionString": "Data Source=messv01ec.ec.local\\PROD1,53959;Initial Catalog=LSL2SQL;Persist Security Info=True;User ID=srpadmin;Password=0okm9ijn;", "Oi2SqlConnectionString": "Data Source=messqlec1.infineon.com\\PROD1,53959;Initial Catalog=LSL2SQL;Persist Security Info=True;User ID=srpadmin;Password=0okm9ijn;",
"OIExportPath": "\\\\openinsight-db-srv.na.infineon.com\\apps\\Metrology\\Data", "OIExportPath": "\\\\openinsight-db-srv.na.infineon.com\\apps\\Metrology\\Data",
"Serilog": { "Serilog": {
"Using": [ "Using": [

View File

@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105 VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Archive", "Archive\OI.Metrology.Archive.csproj", "{D02BA20E-0ACE-4D1C-9132-90773AF3CF5A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\OI.Metrology.Shared.csproj", "{A807EAE3-7DCB-4E5E-BE54-0D7410D18B3E}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\OI.Metrology.Shared.csproj", "{A807EAE3-7DCB-4E5E-BE54-0D7410D18B3E}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\OI.Metrology.Server.csproj", "{25C86DF8-EC1A-4D4B-AD4E-6561174824B9}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\OI.Metrology.Server.csproj", "{25C86DF8-EC1A-4D4B-AD4E-6561174824B9}"

View File

@ -10,7 +10,7 @@
"request": "launch", "request": "launch",
"preLaunchTask": "build", "preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path. // If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/OI.Metrology.Server.dll", "program": "${workspaceFolder}/bin/Debug/net8.0/OI.Metrology.Server.dll",
"args": [], "args": [],
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"stopAtEntry": false, "stopAtEntry": false,

View File

@ -0,0 +1,5 @@
{
"cSpell.words": [
"Infineon"
]
}

View File

@ -13,6 +13,69 @@
], ],
"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",
"command": "dotnet",
"type": "process",
"args": [
"format",
"--report",
".vscode",
"--verbosity",
"detailed",
"--severity",
"warn"
],
"problemMatcher": "$msCompile"
},
{
"label": "Format-Whitespace",
"command": "dotnet",
"type": "process",
"args": [
"format",
"whitespace"
],
"problemMatcher": "$msCompile"
},
{ {
"label": "publish", "label": "publish",
"command": "dotnet", "command": "dotnet",
@ -21,7 +84,32 @@
"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"
}, },
@ -70,6 +158,17 @@
"endsPattern": "^.*Application started.*" "endsPattern": "^.*Application started.*"
} }
} }
},
{
"label": "File-Folder-Helper AOT s X Server",
"type": "shell",
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
"args": [
"s",
"X",
"L:/DevOps/Mesa_FI/OI-Metrology Day-Helper-2024-01-08 L:/DevOps/Mesa_FI/OI-Metrology/Server"
],
"problemMatcher": []
} }
] ]
} }

View File

@ -38,4 +38,10 @@ 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,6 +4,7 @@ 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]")]
@ -11,9 +12,13 @@ public class ExportController : Controller, IExportController<IActionResult>
{ {
private readonly IExportRepository _ExportRepository; private readonly IExportRepository _ExportRepository;
private readonly IMetrologyRepository _MetrologyRepository;
public ExportController(IExportRepository exportRepository) => public ExportController(IExportRepository exportRepository, IMetrologyRepository metrologyRepository)
{
_ExportRepository = exportRepository; _ExportRepository = exportRepository;
_MetrologyRepository = metrologyRepository;
}
private static string? GetJson(Stream stream) private static string? GetJson(Stream stream)
{ {
@ -79,4 +84,21 @@ 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

@ -0,0 +1,36 @@
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

@ -1,10 +1,10 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using OI.Metrology.Server.Models; using OI.Metrology.Server.Models;
using OI.Metrology.Shared.Models; 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,29 +30,9 @@ 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;
}
private static JToken GetJToken(Stream stream)
{
string? json = GetJson(stream);
JToken jsonbody = string.IsNullOrEmpty(json) ? JToken.Parse("{}") : JToken.Parse(json);
return jsonbody;
}
[HttpPost] [HttpPost]
[Route("{tooltype}")] [Route("{tooltype}")]
public IActionResult Post(string tooltype) public IActionResult Post(string tooltype, JsonElement? jsonElement)
{ {
IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress; IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress;
if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP)) if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP))
@ -62,9 +42,8 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
} }
else else
{ {
JToken jsonbody = GetJToken(Request.Body); DataResponse dataResponse = _InboundRepository.Data(_MetrologyRepository, _InboundDataService, tooltype, jsonElement);
DataResponse dataResponse = _InboundRepository.Data(_MetrologyRepository, _InboundDataService, tooltype, jsonbody); if (dataResponse.Errors.Count == 0)
if (!dataResponse.Errors.Any())
return Ok(dataResponse); return Ok(dataResponse);
else else
return BadRequest(dataResponse); return BadRequest(dataResponse);
@ -73,7 +52,7 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
[HttpPost] [HttpPost]
[Route("{tooltype}/attachment")] [Route("{tooltype}/attachment")]
public IActionResult AttachFile(string tooltype, [FromQuery] long headerid, [FromQuery] string datauniqueid = "") public IActionResult AttachFile(string tooltype, Attachment? attachment)
{ {
IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress; IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress;
if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP)) if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP))
@ -83,16 +62,8 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
} }
else else
{ {
if (Request.Form is null) _InboundRepository.AttachFile(_MetrologyRepository, _AttachmentsService, tooltype, attachment);
return BadRequest($"Invalid form"); return Ok();
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

@ -0,0 +1,70 @@
using Microsoft.AspNetCore.Mvc;
namespace OI.Metrology.Server.ApiControllers;
using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless;
using System.Text.Json;
[Route("api/[controller]")]
public class InfinityQSV3Controller : Controller, IInfinityQSV3Controller<IActionResult>
{
private readonly IInfinityQSV3Repository _InfinityQSRepositoryV3;
public InfinityQSV3Controller(IInfinityQSV3Repository InfinityQSRepositoryV3) => _InfinityQSRepositoryV3 = InfinityQSRepositoryV3;
[HttpGet("{sub_group_id}/commandText")]
public IActionResult GetCommandText(string sub_group_id, string process, string job, string part, string lot, string date_time)
{
string commandText = _InfinityQSRepositoryV3.GetCommandText(sub_group_id, process, job, part, lot, date_time);
return Content(commandText, "text/plain; charset=utf-8");
}
[HttpGet("{sub_group_id}/data")]
public IActionResult GetData(string sub_group_id)
{
Result<InfinityQSV3[]> result = _InfinityQSRepositoryV3.GetData(sub_group_id);
string json = JsonSerializer.Serialize(result, ResultInfinityQSV3SourceGenerationContext.Default.ResultInfinityQSV3Array);
return Content(json, "application/json", System.Text.Encoding.UTF8);
}
[HttpGet("{sub_group_id}/descriptors")]
public IActionResult GetDescriptors(string sub_group_id)
{
Result<InfinityQSDescriptorV3[]> result = _InfinityQSRepositoryV3.GetDescriptors(sub_group_id);
string json = JsonSerializer.Serialize(result, ResultInfinityQSDescriptorV3SourceGenerationContext.Default.ResultInfinityQSDescriptorV3Array);
return Content(json, "application/json", System.Text.Encoding.UTF8);
}
[HttpGet("{sub_group_id}/header")]
public IActionResult GetHeader(string sub_group_id)
{
Result<InfinityQSV3[]> result = _InfinityQSRepositoryV3.GetHeader(sub_group_id);
string json = JsonSerializer.Serialize(result, ResultInfinityQSV3SourceGenerationContext.Default.ResultInfinityQSV3Array);
return Content(json, "application/json", System.Text.Encoding.UTF8);
}
[HttpGet("{process}/product-data-average-sum-of-defects-process-mean-process-sigma")]
public IActionResult GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(string process, string? recipe)
{
string result = _InfinityQSRepositoryV3.GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(process, recipe);
return Content(result, "application/json", System.Text.Encoding.UTF8);
}
[HttpGet("epi-pro-temp-verification")]
public IActionResult GetEpiProTempVerification(int[] night)
{
string result = _InfinityQSRepositoryV3.GetEpiProTempVerification(night);
return Content(result, "text/html", System.Text.Encoding.UTF8);
}
[HttpGet("epi-pro-temp-verification-rows")]
public IActionResult GetEpiProTempVerificationRows(int[] night)
{
List<string[]> results = _InfinityQSRepositoryV3.GetEpiProTempVerificationRows(night);
string json = JsonSerializer.Serialize(results);
return Content(json, "application/json", System.Text.Encoding.UTF8);
}
}

View File

@ -0,0 +1,86 @@
using Microsoft.AspNetCore.Mvc;
namespace OI.Metrology.Server.ApiControllers;
using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless;
using System.Text.Json;
[Route("api/v4/InfinityQS")]
public class InfinityQSV4Controller : Controller, IInfinityQSV4Controller<IActionResult>
{
private readonly IInfinityQSV4Repository _InfinityQSRepositoryV4;
public InfinityQSV4Controller(IInfinityQSV4Repository InfinityQSRepositoryV4) => _InfinityQSRepositoryV4 = InfinityQSRepositoryV4;
[HttpGet("{sub_group_id}/commandText")]
public IActionResult GetCommandText(string sub_group_id, string process, string job, string part, string lot, string date_time)
{
string commandText = _InfinityQSRepositoryV4.GetCommandText(sub_group_id, process, job, part, lot, date_time);
return Content(commandText, "text/plain; charset=utf-8");
}
[HttpGet("{sub_group_id}/data")]
public IActionResult GetData(string sub_group_id)
{
Result<InfinityQSV4[]> result = _InfinityQSRepositoryV4.GetData(sub_group_id);
string json = JsonSerializer.Serialize(result, ResultInfinityQSV4SourceGenerationContext.Default.ResultInfinityQSV4Array);
return Content(json, "application/json", System.Text.Encoding.UTF8);
}
[HttpGet("{sub_group_id}/descriptors")]
public IActionResult GetDescriptors(string sub_group_id)
{
Result<InfinityQSDescriptorV4[]> result = _InfinityQSRepositoryV4.GetDescriptors(sub_group_id);
string json = JsonSerializer.Serialize(result, ResultInfinityQSDescriptorV4SourceGenerationContext.Default.ResultInfinityQSDescriptorV4Array);
return Content(json, "application/json", System.Text.Encoding.UTF8);
}
[HttpGet("{sub_group_id}/header")]
public IActionResult GetHeader(string sub_group_id)
{
Result<InfinityQSV4[]> result = _InfinityQSRepositoryV4.GetHeader(sub_group_id);
string json = JsonSerializer.Serialize(result, ResultInfinityQSV4SourceGenerationContext.Default.ResultInfinityQSV4Array);
return Content(json, "application/json", System.Text.Encoding.UTF8);
}
[HttpGet("{process}/product-data-average-sum-of-defects-process-mean-process-sigma")]
public IActionResult GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(string process, string? recipe)
{
string result = _InfinityQSRepositoryV4.GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(process, recipe);
return Content(result, "application/json", System.Text.Encoding.UTF8);
}
[HttpGet("epi-pro-temp-verification")]
public IActionResult GetEpiProTempVerification(int[] night)
{
string result = _InfinityQSRepositoryV4.GetEpiProTempVerification(night);
return Content(result, "text/html", System.Text.Encoding.UTF8);
}
[HttpGet("epi-pro-temp-verification-rows")]
public IActionResult GetEpiProTempVerificationRows(int[] night)
{
List<string[]> results = _InfinityQSRepositoryV4.GetEpiProTempVerificationRows(night);
string json = JsonSerializer.Serialize(results);
return Content(json, "application/json", System.Text.Encoding.UTF8);
}
[HttpGet("reactors")]
public IActionResult GetReactors() =>
Json(_InfinityQSRepositoryV4.GetReactors());
[HttpGet("{rds}/run-data-sheet")]
public IActionResult GetRunDataSheet(string rds) =>
Content(_InfinityQSRepositoryV4.GetRunDataSheet(rds));
[HttpGet("{part}/production-specification")]
public IActionResult GetProductionSpecification(string part) =>
Content(_InfinityQSRepositoryV4.GetProductionSpecification(part));
[HttpGet("{process}/last-group-id-with-value")]
public IActionResult GetLastGroupIdWithValue(string process, string? part, int? test) =>
Content(_InfinityQSRepositoryV4.GetLastGroupIdWithValue(process, part, test));
}

View File

@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Mvc;
namespace OI.Metrology.Server.ApiControllers;
using OI.Metrology.Shared.Models.Stateless;
[Route("api/[controller]")]
public class OpenInsightV1Controller : Controller, IOpenInsightV1Controller<IActionResult>
{
private readonly IOpenInsightV1Repository _OpenInsightRepository;
public OpenInsightV1Controller(IOpenInsightV1Repository openInsightRepository) =>
_OpenInsightRepository = openInsightRepository;
[HttpGet]
[Route("{rds}/tencor-run")]
public IActionResult GetTencorRun(string rds, string? insert_date, string? recipe)
{
string result = _OpenInsightRepository.GetTencorRun(rds, insert_date, recipe);
return Content(result, "application/json", System.Text.Encoding.UTF8);
}
}

View File

@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Mvc;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Services;
namespace OI.Metrology.Server.ApiControllers;
[ApiController]
[Route("api/[controller]")]
public partial class SpreadingResistanceProfileController : ControllerBase, ISpreadingResistanceProfileController<IActionResult>
{
private readonly IAttachmentsService _AttachmentsService;
private readonly IMetrologyRepository _MetrologyRepository;
private readonly IToolTypesRepository _ToolTypesRepository;
private readonly ISpreadingResistanceProfileService _SpreadingResistanceProfileService;
public SpreadingResistanceProfileController(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, IToolTypesRepository toolTypesRepository, ISpreadingResistanceProfileService spreadingResistanceProfileService)
{
_MetrologyRepository = metrologyRepository;
_AttachmentsService = attachmentsService;
_ToolTypesRepository = toolTypesRepository;
_SpreadingResistanceProfileService = spreadingResistanceProfileService;
}
[HttpGet]
[Route("{toolTypeId}/{tabletype}/files/{attachmentId}/{filename}")]
public IActionResult GetAttachment(int toolTypeId, string tabletype, string attachmentId, string filename)
{
(string? message, string? contenttype, Stream? stream) = _ToolTypesRepository.GetAttachment(_MetrologyRepository, _AttachmentsService, toolTypeId, tabletype, attachmentId, filename);
if (message is not null)
return Content(message);
else if (contenttype is not null && stream is not null)
return File(_SpreadingResistanceProfileService.GetImageBytes(stream), "image/jpeg");
else
throw new Exception();
}
}

View File

@ -40,7 +40,7 @@ public class ToolTypesController : Controller, IToolTypesController<IActionResul
[HttpGet] [HttpGet]
[Route("{id}/headers")] [Route("{id}/headers")]
public IActionResult GetHeaders(int id, [FromQuery] DateTime? datebegin, [FromQuery] DateTime? dateend, [FromQuery] int? page, [FromQuery] int? pagesize, [FromQuery] long? headerid) public IActionResult GetHeaders(int id, [FromQuery] string? datebegin, [FromQuery] string? dateend, [FromQuery] int? page, [FromQuery] int? pagesize, [FromQuery] long? headerid)
{ {
Shared.DataModels.Result<DataTable> r = _ToolTypesRepository.GetHeaders(_MetrologyRepo, id, datebegin, dateend, page, pagesize, headerid); Shared.DataModels.Result<DataTable> r = _ToolTypesRepository.GetHeaders(_MetrologyRepo, id, datebegin, dateend, page, pagesize, headerid);
string json = JsonConvert.SerializeObject(r); string json = JsonConvert.SerializeObject(r);
@ -66,23 +66,6 @@ public class ToolTypesController : Controller, IToolTypesController<IActionResul
return Content(json); return Content(json);
} }
[HttpGet]
[Route("{toolTypeId}/export")]
public IActionResult GetExportData(int toolTypeId, [FromQuery] DateTime? datebegin, [FromQuery] DateTime? 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] DateTime? datebegin, [FromQuery] DateTime? 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)
@ -100,11 +83,11 @@ 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)
{ {
Exception? exception = _ToolTypesRepository.OIExport(_MetrologyRepo, _AppSettings.OIExportPath, toolTypeId, headerid); string? message = _ToolTypesRepository.OIExport(_MetrologyRepo, _AttachmentsService, toolTypeId, headerid);
if (exception is null) if (message is null)
return Ok(new { Message = "OK" }); return Ok(new { Message = "OK" });
else else
return BadRequest(JsonConvert.SerializeObject(new { exception.Message })); return BadRequest(JsonConvert.SerializeObject(new { message }));
} }
} }

View File

@ -10,6 +10,7 @@ public class ErrorHandlerController : Controller
public ErrorHandlerController(ILogger<ErrorHandlerController> logger) => _Logger = logger; public ErrorHandlerController(ILogger<ErrorHandlerController> logger) => _Logger = logger;
[ApiExplorerSettings(IgnoreApi = true)]
public IActionResult Index() public IActionResult Index()
{ {
IExceptionHandlerFeature? error = HttpContext.Features.Get<IExceptionHandlerFeature>(); IExceptionHandlerFeature? error = HttpContext.Features.Get<IExceptionHandlerFeature>();

View File

@ -1,160 +0,0 @@
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

@ -1,79 +0,0 @@
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

@ -1 +1 @@
{"apiLoggingContentTypes":null,"apiLoggingPathPrefixes":null,"apiLogPath":null,"apiUrl":null,"attachmentPath":null,"buildNumber":"1","company":"Infineon Technologies Americas Corp.","connectionString":null,"gitCommitSeven":"1234567","inboundApiAllowedIPList":null,"isDevelopment":true,"isStaging":false,"mockRoot":null,"monAResource":null,"monASite":null,"oi2SqlConnectionString":null,"oiExportPath":null,"urLs":null,"workingDirectoryName":null} {"apiExportPath":null,"apiLoggingContentTypes":null,"apiLoggingPathPrefixes":null,"apiLogPath":null,"apiUrl":null,"attachmentPath":null,"buildNumber":"1000014","company":"Infineon Technologies Americas Corp.","connectionString":null,"gitCommitSeven":"6bc0487","inboundApiAllowedIPList":null,"isDevelopment":false,"isStaging":false,"mockRoot":null,"monAResource":null,"monASite":null,"oi2SqlConnectionString":null,"tableToPath":null,"urLs":null,"workingDirectoryName":null}

View File

@ -1 +1 @@
1-1234567 1000014-6bc0487

View File

@ -1 +0,0 @@
asdf

View File

@ -1,4 +1,90 @@
{ {
"Results": [], "Results": [
"TotalRows": 0 {
"ID": 0,
"InsertDate": "0001-01-01T00:00:00",
"AttachmentID": "00000000-0000-0000-0000-000000000000",
"Title": null,
"Date": "0001-01-01T00:00:00",
"ToolTypeID": 0,
"ToolTypeName": null,
"MesEntity": "TENCOR2",
"Employee": "PRE",
"Layer": null,
"PSN": "",
"RDS": "",
"Reactor": "",
"Recipe": "8IN.2QUAL",
"Zone": null
},
{
"ID": 0,
"InsertDate": "0001-01-01T00:00:00",
"AttachmentID": "00000000-0000-0000-0000-000000000000",
"Title": null,
"Date": "0001-01-01T00:00:00",
"ToolTypeID": 0,
"ToolTypeName": null,
"MesEntity": "TENCOR3",
"Employee": "",
"Layer": null,
"PSN": "",
"RDS": "",
"Reactor": "",
"Recipe": "8INCLEAN",
"Zone": null
},
{
"ID": 0,
"InsertDate": "0001-01-01T00:00:00",
"AttachmentID": "00000000-0000-0000-0000-000000000000",
"Title": null,
"Date": "0001-01-01T00:00:00",
"ToolTypeID": 0,
"ToolTypeName": null,
"MesEntity": "TENCOR3",
"Employee": "",
"Layer": null,
"PSN": "",
"RDS": "",
"Reactor": "",
"Recipe": "8IN_THIN ROTR",
"Zone": null
},
{
"ID": 0,
"InsertDate": "0001-01-01T00:00:00",
"AttachmentID": "00000000-0000-0000-0000-000000000000",
"Title": null,
"Date": "0001-01-01T00:00:00",
"ToolTypeID": 0,
"ToolTypeName": null,
"MesEntity": "TENCOR3",
"Employee": "",
"Layer": null,
"PSN": "",
"RDS": "",
"Reactor": "",
"Recipe": "8IN_PTYPE_ROTR",
"Zone": null
},
{
"ID": 0,
"InsertDate": "0001-01-01T00:00:00",
"AttachmentID": "00000000-0000-0000-0000-000000000000",
"Title": null,
"Date": "0001-01-01T00:00:00",
"ToolTypeID": 0,
"ToolTypeName": null,
"MesEntity": "TENCOR3",
"Employee": "",
"Layer": null,
"PSN": "",
"RDS": "",
"Reactor": "",
"Recipe": "AS_IFX_ROTR",
"Zone": null
}
],
"TotalRows": 5
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,19 @@
{ {
"Results": [ "Results": [
{ {
"EV_COUNT": 0,
"CL_COUNT": 0,
"SL_COUNT": 0,
"SE_SGRP": 1677273357, "SE_SGRP": 1677273357,
"SE_SGTM": 1677273300, "SE_SGTM": 1677273300,
"SE_TSNO": 1, "SE_TSNO": 1,
"TD_TEST": 1650647347,
"PR_NAME": "61", "PR_NAME": "61",
"JD_NAME": "CDE5", "JD_NAME": "CDE5",
"PL_NAME": "575908", "PL_NAME": "575908",
"PD_NAME": "5012", "PD_NAME": "5012",
"TD_TEST": 1650647347,
"TD_NAME": "T", "TD_NAME": "T",
"SE_VAL": 270, "SE_VAL": 270
"EV_COUNT": 0
} }
], ],
"TotalRows": 1 "TotalRows": 1

View File

@ -1,22 +1,35 @@
select iq.ev_count, iq.cl_count, iq.sl_count, iq.se_sgrp, iq.se_sgtm, iq.se_tsno, iq.td_test, iq.pr_name, iq.jd_name, iq.pl_name, iq.pd_name, iq.td_name, iq.se_val
from (
select select
se.f_sgrp se_sgrp, se.f_sgrp se_sgrp,
se.f_sgtm se_sgtm, se.f_sgtm se_sgtm,
se.f_tsno se_tsno, se.f_tsno se_tsno,
se.f_val se_val, se.f_val se_val,
rd.f_name rd_name, pr.f_name pr_name,
jd.f_name jd_name, jd.f_name jd_name,
pl.f_name pl_name, pl.f_name pl_name,
pd.f_name pd_name, pd.f_name pd_name,
td.f_test td_test, td.f_test td_test,
td.f_name td_name, td.f_name td_name,
(select count(cl.f_part)
from [spcepiworld].[dbo].[ctrl_lim] cl
where cl.f_part = pd.f_part
and cl.f_test = td.f_test
) cl_count,
(select count(sl.f_part)
from [spcepiworld].[dbo].[spec_lim] sl
where sl.f_part = pd.f_part
and sl.f_test = td.f_test
) sl_count,
(select count(ev.f_evnt) (select count(ev.f_evnt)
from [spcepiworld].[dbo].[evnt_inf] ev from [spcepiworld].[dbo].[evnt_inf] ev
where ev.f_prcs = rd.f_prcs where ev.f_prcs = pr.f_prcs
and ev.f_part = pd.f_part and ev.f_part = pd.f_part
and ev.f_sgtm = se.f_sgtm) ev_count and ev.f_sgtm = se.f_sgtm
) ev_count
from [spcepiworld].[dbo].[sgrp_ext] se from [spcepiworld].[dbo].[sgrp_ext] se
join [spcepiworld].[dbo].[prcs_dat] rd join [spcepiworld].[dbo].[prcs_dat] pr
on se.f_prcs = rd.f_prcs on se.f_prcs = pr.f_prcs
join [spcepiworld].[dbo].[job_dat] jd join [spcepiworld].[dbo].[job_dat] jd
on se.f_job = jd.f_job on se.f_job = jd.f_job
join [spcepiworld].[dbo].[part_lot] pl join [spcepiworld].[dbo].[part_lot] pl
@ -27,9 +40,11 @@
on se.f_test = td.f_test on se.f_test = td.f_test
where se.f_flag = 0 where se.f_flag = 0
and se.f_sgrp = 1677273357 and se.f_sgrp = 1677273357
and rd.f_name = '61' and pr.f_name = '61'
and pd.f_name = '5012' and pd.f_name = '5012'
and jd.f_name = 'CDE5' and jd.f_name = 'CDE5'
and pl.f_name = '575908' and pl.f_name = '575908'
and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '2023-02-24 15:15:00' and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '2023-02-24 15:15:00'
) as iq
order by iq.ev_count desc, iq.cl_count desc, iq.sl_count desc, iq.se_sgrp, iq.se_tsno, iq.td_test
for json path for json path

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,19 @@
{ {
"Results": [ "Results": [
{ {
"EventCount": 0,
"ControlLimitCount": 0,
"SpecLimitCount": 0,
"SubGroupId": 1677273357, "SubGroupId": 1677273357,
"SubGroupDateTime": 1677273300, "SubGroupDateTime": 1677273300,
"SiteNumber": 1, "SiteNumber": 1,
"VariableNumber": 1650647347,
"Process": "61", "Process": "61",
"Job": "CDE5", "Job": "CDE5",
"Lot": "575908", "Lot": "575908",
"Part": "5012", "Part": "5012",
"VariableNumber": 1650647347,
"Variable": "T", "Variable": "T",
"Value": 270, "Value": 270
"EventCount": 0
} }
], ],
"TotalRows": 1 "TotalRows": 1

View File

@ -0,0 +1,78 @@
select case when iq.sl_loos is null then 0 else iq.sl_loos end +
case when iq.sl_uoos is null then 0 else iq.sl_uoos end +
iq.ev_count as iq_sum,
iq.sl_aflag,
iq.sl_loos,
iq.sl_uoos,
iq.se_sgrp,
iq.se_sgtm,
iq.se_tsno,
iq.td_test,
iq.pr_name,
iq.jd_name,
iq.pl_name,
iq.pd_name,
iq.td_name,
iq.se_val,
iq.sl_eflag,
iq.sl_scal,
iq.sl_sls,
iq.sl_usl
from (
select
se.f_sgrp se_sgrp,
se.f_sgtm se_sgtm,
se.f_tsno se_tsno,
se.f_val se_val,
pr.f_name pr_name,
jd.f_name jd_name,
pl.f_name pl_name,
pd.f_name pd_name,
td.f_test td_test,
td.f_name td_name,
sl.f_eflag sl_eflag,
sl.f_aflag sl_aflag,
sl.f_scal sl_scal,
sl.f_lsl sl_sls,
sl.f_usl sl_usl,
case when sl.f_aflag is null or sl.f_aflag = 0 then null else
case when round(se.f_val, sl.F_scal, 1) < sl.f_lsl then 1 else 0 end
end as sl_loos,
case when sl.f_aflag is null or sl.f_aflag = 0 then null else
case when round(se.f_val, sl.F_scal, 1) > sl.f_usl then 1 else 0 end
end as sl_uoos,
(select count(ev.f_evnt)
from [spcepiworld].[dbo].[evnt_inf] ev
where ev.f_prcs = pr.f_prcs
and ev.f_part = pd.f_part
and ev.f_sgtm = se.f_sgtm
) ev_count
from [spcepiworld].[dbo].[sgrp_ext] se
join [spcepiworld].[dbo].[prcs_dat] pr
on se.f_prcs = pr.f_prcs
join [spcepiworld].[dbo].[job_dat] jd
on se.f_job = jd.f_job
join [spcepiworld].[dbo].[part_lot] pl
on se.f_lot = pl.f_lot
join [spcepiworld].[dbo].[part_dat] pd
on se.f_part = pd.f_part
join [spcepiworld].[dbo].[test_dat] td
on se.f_test = td.f_test
left join [spcepiworld].[dbo].[spec_lim] sl
on se.f_part = sl.f_part
and se.f_test = sl.f_test
where se.f_flag = 0
and (sl.f_prcs is null or se.f_prcs = sl.f_prcs or sl.f_prcs = 0)
and se.f_sgrp = 1698497987
and pr.f_name = '61'
and pd.f_name = '5012'
and jd.f_name = 'CDE5'
and pl.f_name = '575908'
and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '2023-02-24 15:15:00'
) as iq
order by iq.sl_loos + iq.sl_uoos + iq.ev_count desc,
iq.sl_aflag desc,
iq.se_sgrp,
iq.se_tsno,
iq.td_test
for json path

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,152 @@
{
"Results": [
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657291789,
"gd_name": "CondType",
"dd_name": "N"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657291789,
"gd_name": "CondType",
"dd_name": "N"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657291790,
"gd_name": "GLimit",
"dd_name": "2000.00 \u00B5"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657291790,
"gd_name": "GLimit",
"dd_name": "2000.00 \u00B5"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657296863,
"gd_name": "Model",
"dd_name": "PARALLEL"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657296863,
"gd_name": "Model",
"dd_name": "PARALLEL"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 0,
"dd_dsgp": 1657296864,
"gd_name": "Pattern",
"dd_name": "ONEPT.PAT"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657296865,
"gd_name": "Phase",
"dd_name": "90.000"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657296865,
"gd_name": "Phase",
"dd_name": "90.000"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657296866,
"gd_name": "Plan",
"dd_name": "5PT MES"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657296866,
"gd_name": "Plan",
"dd_name": "5PT MES"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657296867,
"gd_name": "RampRate",
"dd_name": "2500"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657296867,
"gd_name": "RampRate",
"dd_name": "2500"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657296868,
"gd_name": "RhoMethod",
"dd_name": "ASTM: F723 - 82"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657296868,
"gd_name": "RhoMethod",
"dd_name": "ASTM: F723 - 82"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657296869,
"gd_name": "StartVoltage",
"dd_name": "-5.00"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657296869,
"gd_name": "StartVoltage",
"dd_name": "-5.00"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657296870,
"gd_name": "StopVoltage",
"dd_name": "-20.00"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657296870,
"gd_name": "StopVoltage",
"dd_name": "-20.00"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 1,
"dd_dsgp": 1657296871,
"gd_name": "WaferSize",
"dd_name": "150.00"
},
{
"sd_sgrp": 1698497987,
"sd_tsno": 2,
"dd_dsgp": 1657296871,
"gd_name": "WaferSize",
"dd_name": "150.00"
}
],
"TotalRows": 21
}

View File

@ -0,0 +1 @@
<tr><td>44</td><td class='Productive'>Productive</td><td class='LoadedRDSCount1'>616747</td><td>0</td><td>0</td><td>1/1/0001 12:00:00 AM</td></tr><tr><td>50</td><td class='Productive'>Productive</td><td class='LoadedRDSCount0'></td><td>0</td><td>0</td><td>1/1/0001 12:00:00 AM</td></tr><tr><td>48</td><td class='Unscheduled Down'>Unscheduled Down</td><td class='LoadedRDSCount0'></td><td>0</td><td>0</td><td>1/1/0001 12:00:00 AM</td></tr><tr><td>42</td><td class='Scheduled Down'>Scheduled Down</td><td class='LoadedRDSCount1'>616741</td><td>0</td><td>0</td><td>1/1/0001 12:00:00 AM</td></tr><tr><td>40</td><td class='Unscheduled Down'>Unscheduled Down</td><td class='LoadedRDSCount1'>616740</td><td>0</td><td>0</td><td>1/1/0001 12:00:00 AM</td></tr><tr><td>46</td><td class='Productive'>Productive</td><td class='LoadedRDSCount0'></td><td>0</td><td>0</td><td>1/1/0001 12:00:00 AM</td></tr><tr><td>54</td><td class='Non-Scheduled'>Non-Scheduled</td><td class='LoadedRDSCount0'></td><td>0</td><td>0</td><td>1/1/0001 12:00:00 AM</td></tr>

View File

@ -0,0 +1,70 @@
[
[
"40",
"Unscheduled Down",
"617354",
"1090",
"-3.25",
"11/7/2023 9:53:35 AM",
"168",
"\u0026nbsp;",
"44",
"Productive",
"617355",
"1040",
"-1.75",
"11/14/2023 5:25:07 AM",
"4"
],
[
"42",
"Productive",
"\u0026nbsp;",
"1070",
"2.5",
"11/12/2023 10:38:41 AM",
"47",
"\u0026nbsp;",
"46",
"Productive",
"\u0026nbsp;",
"1069",
"5",
"11/14/2023 5:38:02 AM",
"4"
],
[
"48",
"Productive",
"\u0026nbsp;",
"1075",
"-10.75",
"11/11/2023 6:54:58 AM",
"75",
"\u0026nbsp;",
"54",
"Non-Scheduled",
"\u0026nbsp;",
"1067",
"-5",
"8/17/2023 4:12:20 AM",
"2142"
],
[
"50",
"Productive",
"\u0026nbsp;",
"1078",
"-11",
"11/12/2023 6:47:21 AM",
"51",
"\u0026nbsp;",
"\u0026nbsp;",
"\u0026nbsp;",
"\u0026nbsp;",
"\u0026nbsp;",
"\u0026nbsp;",
"\u0026nbsp;",
"\u0026nbsp;"
]
]

View File

@ -0,0 +1,25 @@
{
"Results": [
{
"iq_sum": 1,
"sl_aflag": 34,
"sl_loos": 0,
"sl_uoos": 1,
"se_sgrp": 1698497987,
"se_sgtm": 1698497973,
"se_tsno": 1,
"td_test": 1657240302,
"pr_name": "HGCV2",
"jd_name": "HGCV2",
"pl_name": "-",
"pd_name": "High",
"td_name": "RhoAvgMean",
"se_val": 12.66,
"sl_eflag": 42,
"sl_scal": 4,
"sl_sls": 12.379,
"sl_usl": 12.561
}
],
"TotalRows": 1
}

View File

@ -0,0 +1 @@
[{"ProcessMean":1.750000000000000e+001,"ProcessSigma":5.800000000000000e+000}]

View File

@ -0,0 +1 @@
[{"RDS":"615071","AttachmentId":"43CA162D-A04B-4A37-90D7-83BABAF2D3AB","Slot":"*01","SumOfDefects":"100","Sort":"FAIL","InsertDate":"2023-10-30T18:48:57.617"},{"RDS":"615071","AttachmentId":"706C7D0E-4EC1-4042-9DAA-3D141532B6E1","Slot":"*04","SumOfDefects":"12","Sort":"PASS","InsertDate":"2023-10-30T18:48:57.623"},{"RDS":"615071","AttachmentId":"4CECFAC9-745E-4235-BAD9-BE57D1FB450E","Slot":"*11","SumOfDefects":"22","Sort":"PASS","InsertDate":"2023-10-30T18:48:57.627"},{"RDS":"615071","AttachmentId":"B62DE99D-2060-4627-A006-C5FA0DC779BE","Slot":"*17","SumOfDefects":"279","Sort":"FAIL","InsertDate":"2023-10-30T18:48:57.630"}]

View File

@ -0,0 +1,33 @@
{
"Results": [
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
],
"TotalRows": 28
}

View File

@ -1,23 +1 @@
{ {"Results":[{"InsertDate":null,"Run Header":null,"Title":null,"AttachmentID":null,"Position":"Average","Thickness":"NaN","ID":-1},{"InsertDate":null,"Run Header":null,"Title":null,"AttachmentID":null,"Position":"Std Dev","Thickness":"NaN","ID":-2}],"TotalRows":2}
"Results": [
{
"InsertDate": null,
"Run Header": null,
"Title": null,
"AttachmentID": null,
"Position": "Average",
"Thickness": "NaN",
"ID": -1
},
{
"InsertDate": null,
"Run Header": null,
"Title": null,
"AttachmentID": null,
"Position": "Std Dev",
"Thickness": "NaN",
"ID": -2
}
],
"TotalRows": 2
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@
"DataTableName": "BioRadRunData", "DataTableName": "BioRadRunData",
"ExportSPName": "Export_BioRad", "ExportSPName": "Export_BioRad",
"HeaderGridAttributes": null, "HeaderGridAttributes": null,
"DataGridAttributes": null, "DataGridAttributes": "{ \u0022pinButton\u0022: true }",
"DataGridSortBy": "LEN(Position), Position", "DataGridSortBy": "LEN(Position), Position",
"DataGridStatsColumn": "Thickness", "DataGridStatsColumn": "Thickness",
"DataGridStatsStdDevType": " ", "DataGridStatsStdDevType": " ",
@ -224,7 +224,7 @@
"ApiName": "SentToMetrology", "ApiName": "SentToMetrology",
"ColumnName": "SentToMetrology", "ColumnName": "SentToMetrology",
"DisplayTitle": "SentToOI", "DisplayTitle": "SentToOI",
"GridDisplayOrder": 9, "GridDisplayOrder": 10,
"GridAttributes": "{ \u0022dataType:\u0022: \u0022bool\u0022, \u0022formatter\u0022: \u0022boolToYesNo\u0022 }", "GridAttributes": "{ \u0022dataType:\u0022: \u0022bool\u0022, \u0022formatter\u0022: \u0022boolToYesNo\u0022 }",
"TableDisplayOrder": 14 "TableDisplayOrder": 14
}, },
@ -274,7 +274,7 @@
"ApiName": "Wafer", "ApiName": "Wafer",
"ColumnName": "Wafer", "ColumnName": "Wafer",
"DisplayTitle": "Wafer", "DisplayTitle": "Wafer",
"GridDisplayOrder": 0, "GridDisplayOrder": 9,
"GridAttributes": null, "GridAttributes": null,
"TableDisplayOrder": 9 "TableDisplayOrder": 9
}, },

View File

@ -23,7 +23,11 @@
{ {
"ToolTypeName": "TencorSP1", "ToolTypeName": "TencorSP1",
"ID": 6 "ID": 6
},
{
"ToolTypeName": "SRP",
"ID": 7
} }
], ],
"TotalRows": 6 "TotalRows": 7
} }

View File

@ -2,25 +2,35 @@ using System.Text.Json;
namespace OI.Metrology.Server.Models; namespace OI.Metrology.Server.Models;
public record AppSettings(string ApiExportPath, public record AppSettings(string ApiFileShare,
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[] IqsFileSegments,
string IqsKey,
string IqsRed,
string IqsYellow,
bool IsDevelopment, bool IsDevelopment,
bool IsStaging, bool IsStaging,
string MockRoot, string MockRoot,
string MonAResource, string MonAResource,
string MonASite, string MonASite,
string OI2SqlConnectionString, string OpenInsightApplicationProgrammingInterface,
string OIExportPath, Dictionary<string, string> TableToPath,
string URLs, string URLs,
string WaferCounterDestinationDirectory,
int WaferCounterTwoFileSecondsWait,
string WorkingDirectoryName) string WorkingDirectoryName)
{ {

View File

@ -0,0 +1,2 @@
[*.cs]
csharp_preserve_single_line_statements = true

View File

@ -1,35 +1,41 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
namespace OI.Metrology.Server.Models.Binder; namespace OI.Metrology.Server.Models.Binder;
public class AppSettings public class AppSettings
{ {
#nullable disable public string? ApiFileShare { get; set; }
public string? ApiLoggingContentTypes { get; set; }
[Display(Name = "Api Export Path"), Required] public string ApiExportPath { get; set; } public string? ApiLoggingPathPrefixes { get; set; }
[Display(Name = "Api Logging Content Types"), Required] public string ApiLoggingContentTypes { get; set; } public string? ApiLogPath { get; set; }
[Display(Name = "Api Logging Path Prefixes"), Required] public string ApiLoggingPathPrefixes { get; set; } public string? ApiUrl { get; set; }
[Display(Name = "Api Log Path"), Required] public string ApiLogPath { get; set; } public string? BuildNumber { get; set; }
[Display(Name = "Api URL"), Required] public string ApiUrl { get; set; } public string? Company { get; set; }
[Display(Name = "Attachment Path"), Required] public string AttachmentPath { get; set; } public string? ConnectionString { get; set; }
[Display(Name = "Build Number"), Required] public string BuildNumber { get; set; } public string? EcCharacterizationSi { get; set; }
[Display(Name = "Company"), Required] public string Company { get; set; } public string? EcMesaFileShareCharacterizationSi { get; set; }
[Display(Name = "Connection String"), Required] public string ConnectionString { get; set; } public string? EcMesaFileShareMetrologySi { get; set; }
[Display(Name = "Git Commit Seven"), Required] public string GitCommitSeven { get; set; } public string? EcMetrologySi { get; set; }
[Display(Name = "Inbound Api Allowed IP List"), Required] public string InboundApiAllowedIPList { get; set; } public string? GitCommitSeven { get; set; }
[Display(Name = "Is Development"), Required] public bool? IsDevelopment { get; set; } public string? InboundApiAllowedIPList { get; set; }
[Display(Name = "Is Staging"), Required] public bool? IsStaging { get; set; } public string? IqsColumns { get; set; }
[Display(Name = "Mock Root"), Required] public string MockRoot { get; set; } public string[]? IqsFileSegments { get; set; }
[Display(Name = "MonA Resource"), Required] public string MonAResource { get; set; } public string? IqsKey { get; set; }
[Display(Name = "MonA Site"), Required] public string MonASite { get; set; } public string? IqsRed { get; set; }
[Display(Name = "Oi 2 Sql Connection String"), Required] public string Oi2SqlConnectionString { get; set; } public string? IqsYellow { get; set; }
[Display(Name = "OI Export Path"), Required] public string OIExportPath { get; set; } public bool? IsDevelopment { get; set; }
[Display(Name = "URLs"), Required] public string URLs { get; set; } public bool? IsStaging { get; set; }
[Display(Name = "Working Directory Name"), Required] public string WorkingDirectoryName { get; set; } public string? MockRoot { get; set; }
public string? MonAResource { get; set; }
#nullable restore public string? MonASite { get; set; }
public string? OpenInsightApplicationProgrammingInterface { get; set; }
public Dictionary<string, string>? TableToPath { get; set; }
public string? URLs { get; set; }
public string? WaferCounterDestinationDirectory { get; set; }
public int? WaferCounterTwoFileSecondsWait { get; set; }
public string? WorkingDirectoryName { get; set; }
public override string ToString() public override string ToString()
{ {
@ -37,71 +43,87 @@ 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) if (appSettings is null) throw new NullReferenceException(nameof(appSettings));
throw new NullReferenceException(nameof(appSettings)); if (appSettings.ApiFileShare is null) throw new NullReferenceException(nameof(ApiFileShare));
if (appSettings.ApiExportPath is null) if (appSettings.ApiLoggingContentTypes is null) throw new NullReferenceException(nameof(ApiLoggingContentTypes));
throw new NullReferenceException(nameof(ApiExportPath)); if (appSettings.ApiLoggingPathPrefixes is null) throw new NullReferenceException(nameof(ApiLoggingPathPrefixes));
if (appSettings.ApiLoggingContentTypes is null) if (appSettings.ApiLogPath is null) throw new NullReferenceException(nameof(ApiLogPath));
throw new NullReferenceException(nameof(ApiLoggingContentTypes)); if (appSettings.ApiUrl is null) throw new NullReferenceException(nameof(ApiUrl));
if (appSettings.ApiLoggingPathPrefixes is null) if (appSettings.BuildNumber is null) throw new NullReferenceException(nameof(BuildNumber));
throw new NullReferenceException(nameof(ApiLoggingPathPrefixes)); if (appSettings.Company is null) throw new NullReferenceException(nameof(Company));
if (appSettings.ApiLogPath is null) if (appSettings.ConnectionString is null) throw new NullReferenceException(nameof(ConnectionString));
throw new NullReferenceException(nameof(ApiLogPath)); if (appSettings.EcCharacterizationSi is null) throw new NullReferenceException(nameof(EcCharacterizationSi));
if (appSettings.ApiUrl is null) if (appSettings.EcMesaFileShareCharacterizationSi is null) throw new NullReferenceException(nameof(EcMesaFileShareCharacterizationSi));
throw new NullReferenceException(nameof(ApiUrl)); if (appSettings.EcMesaFileShareMetrologySi is null) throw new NullReferenceException(nameof(EcMesaFileShareMetrologySi));
if (appSettings.AttachmentPath is null) if (appSettings.EcMetrologySi is null) throw new NullReferenceException(nameof(EcMetrologySi));
throw new NullReferenceException(nameof(AttachmentPath)); if (appSettings.GitCommitSeven is null) throw new NullReferenceException(nameof(GitCommitSeven));
if (appSettings.BuildNumber is null) if (appSettings.InboundApiAllowedIPList is null) throw new NullReferenceException(nameof(InboundApiAllowedIPList));
throw new NullReferenceException(nameof(BuildNumber)); if (appSettings.IqsColumns is null) throw new NullReferenceException(nameof(IqsColumns));
if (appSettings.Company is null) if (appSettings.IqsFileSegments is null) throw new NullReferenceException(nameof(IqsFileSegments));
throw new NullReferenceException(nameof(Company)); if (appSettings.IqsKey is null) throw new NullReferenceException(nameof(IqsKey));
if (appSettings.ConnectionString is null) if (appSettings.IqsRed is null) throw new NullReferenceException(nameof(IqsRed));
throw new NullReferenceException(nameof(ConnectionString)); if (appSettings.IqsYellow is null) throw new NullReferenceException(nameof(IqsYellow));
if (appSettings.GitCommitSeven is null) if (appSettings.IsDevelopment is null) throw new NullReferenceException(nameof(IsDevelopment));
throw new NullReferenceException(nameof(GitCommitSeven)); if (appSettings.IsStaging is null) throw new NullReferenceException(nameof(IsStaging));
if (appSettings.InboundApiAllowedIPList is null) if (appSettings.MockRoot is null) throw new NullReferenceException(nameof(MockRoot));
throw new NullReferenceException(nameof(InboundApiAllowedIPList)); if (appSettings.MonAResource is null) throw new NullReferenceException(nameof(MonAResource));
if (appSettings.IsDevelopment is null) if (appSettings.MonASite is null) throw new NullReferenceException(nameof(MonASite));
throw new NullReferenceException(nameof(IsDevelopment)); if (appSettings.OpenInsightApplicationProgrammingInterface is null) throw new NullReferenceException(nameof(OpenInsightApplicationProgrammingInterface));
if (appSettings.IsStaging is null) if (appSettings.URLs is null) throw new NullReferenceException(nameof(URLs));
throw new NullReferenceException(nameof(IsStaging)); if (appSettings.TableToPath is null) throw new NullReferenceException(nameof(TableToPath));
if (appSettings.MockRoot is null) if (appSettings.WaferCounterDestinationDirectory is null) throw new NullReferenceException(nameof(WaferCounterDestinationDirectory));
throw new NullReferenceException(nameof(MockRoot)); if (appSettings.WaferCounterTwoFileSecondsWait is null) throw new NullReferenceException(nameof(WaferCounterTwoFileSecondsWait));
if (appSettings.MonAResource is null) if (appSettings.WorkingDirectoryName is null) throw new NullReferenceException(nameof(WorkingDirectoryName));
throw new NullReferenceException(nameof(MonAResource));
if (appSettings.MonASite is null)
throw new NullReferenceException(nameof(MonASite));
if (appSettings.Oi2SqlConnectionString is null)
throw new NullReferenceException(nameof(Oi2SqlConnectionString));
if (appSettings.OIExportPath is null)
throw new NullReferenceException(nameof(OIExportPath));
if (appSettings.URLs is null)
throw new NullReferenceException(nameof(URLs));
if (appSettings.WorkingDirectoryName is null)
throw new NullReferenceException(nameof(WorkingDirectoryName));
result = new( result = new(
appSettings.ApiExportPath, appSettings.ApiFileShare,
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.IqsFileSegments,
appSettings.IqsKey,
appSettings.IqsRed,
appSettings.IqsYellow,
appSettings.IsDevelopment.Value, appSettings.IsDevelopment.Value,
appSettings.IsStaging.Value, appSettings.IsStaging.Value,
appSettings.MockRoot, appSettings.MockRoot,
appSettings.MonAResource, appSettings.MonAResource,
appSettings.MonASite, appSettings.MonASite,
appSettings.Oi2SqlConnectionString, appSettings.OpenInsightApplicationProgrammingInterface,
appSettings.OIExportPath, appSettings.TableToPath,
appSettings.URLs, appSettings.URLs,
appSettings.WaferCounterDestinationDirectory,
appSettings.WaferCounterTwoFileSecondsWait.Value,
appSettings.WorkingDirectoryName); appSettings.WorkingDirectoryName);
return result; return result;
} }
@ -109,9 +131,18 @@ public class AppSettings
public static Models.AppSettings Get(IConfigurationRoot configurationRoot) public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
{ {
Models.AppSettings result; Models.AppSettings result;
#pragma warning disable IL3050, IL2026
AppSettings? appSettings = configurationRoot.Get<AppSettings>(); AppSettings? appSettings = configurationRoot.Get<AppSettings>();
#pragma warning restore IL3050, IL2026
PreVerify(configurationRoot, appSettings);
result = Get(appSettings); result = Get(appSettings);
return result; return result;
} }
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(AppSettings))]
internal partial class BinderAppSettingsSourceGenerationContext : JsonSerializerContext
{
} }

View File

@ -6,14 +6,14 @@
<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>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>6501aa0f-8499-4be5-96a9-e99b11323eeb</UserSecretsId> <UserSecretsId>b0a3891c-b775-422c-80ee-63a2f385045d</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="logs\**" /> <Compile Remove="logs\**" />
@ -25,24 +25,22 @@
<Content Remove="compilerconfig.json" /> <Content Remove="compilerconfig.json" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Dapper" Version="2.0.123" /> <PackageReference Include="Dapper" Version="2.1.44" />
<PackageReference Include="EntityFramework" Version="6.4.4" /> <PackageReference Include="EntityFramework" Version="6.5.1" />
<PackageReference Include="jQuery" Version="3.6.3" /> <PackageReference Include="jQuery" Version="3.7.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.3" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Serilog.AspNetCore.Ingestion" Version="1.0.0-dev-00032" /> <PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="8.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="6.1.0" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\OI.Metrology.Shared.csproj" /> <ProjectReference Include="..\Shared\OI.Metrology.Shared.csproj" />
@ -56,12 +54,6 @@
<None Include="compilerconfig.json" /> <None Include="compilerconfig.json" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="appsettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Mike\service-shop.json"> <None Include="Data\Mike\service-shop.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
@ -92,18 +84,6 @@
<None Include="Data\Tests\InfinityQS-GetCommandText.sql"> <None Include="Data\Tests\InfinityQS-GetCommandText.sql">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="Data\Tests\InfinityQS-GetData.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\InfinityQS-GetDescriptors.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\InfinityQS-GetEvents.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\InfinityQS-GetHeader.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\InfinityQSV2-GetCommandText.sql"> <None Include="Data\Tests\InfinityQSV2-GetCommandText.sql">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
@ -119,9 +99,33 @@
<None Include="Data\Tests\InfinityQSV2-GetHeader.json"> <None Include="Data\Tests\InfinityQSV2-GetHeader.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="Data\Tests\InfinityQSV3-GetData.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\InfinityQSV3-GetDescriptors.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\InfinityQSV3-GetEpiProTempVerification.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\InfinityQSV3-GetEpiProTempVerificationRows.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\InfinityQSV3-GetHeader.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\InfinityQSV3-GetProductDataAverageSumOfDefectsProcessMeanProcessSigma.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\OpenInsightV1-GetTencorRun.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\Pin-GetPinnedTable.json"> <None Include="Data\Tests\Pin-GetPinnedTable.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="Data\Tests\Reactors-GetReactors.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Data\Tests\ServiceShopOrder-GetAllServiceShopOrders.json"> <None Include="Data\Tests\ServiceShopOrder-GetAllServiceShopOrders.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
@ -131,10 +135,10 @@
<None Include="Data\Tests\ToolTypes-GetHeaderFields.json"> <None Include="Data\Tests\ToolTypes-GetHeaderFields.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="Data\Tests\ToolTypes-GetHeaderTitles.json"> <None Include="Data\Tests\ToolTypes-GetHeaders.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="Data\Tests\ToolTypes-GetHeaders.json"> <None Include="Data\Tests\ToolTypes-GetHeaderTitles.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="Data\Tests\ToolTypes-GetToolTypeMetadata.json"> <None Include="Data\Tests\ToolTypes-GetToolTypeMetadata.json">

View File

@ -4,11 +4,9 @@ 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;
using Serilog;
using System.Reflection; using System.Reflection;
namespace OI.Metrology.Server; namespace OI.Metrology.Server;
@ -41,19 +39,15 @@ public class Program
public static int Main(string[] args) public static int Main(string[] args)
{ {
LoggerConfiguration loggerConfiguration = new(); ILogger<Program>? logger = null;
(string assemblyName, WebApplicationOptions _) = Get(args); (string assemblyName, WebApplicationOptions _) = Get(args);
WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args); WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args);
_ = webApplicationBuilder.Configuration.AddUserSecrets<Program>(); _ = webApplicationBuilder.Configuration.AddUserSecrets<Program>();
AppSettings appSettings = Models.Binder.AppSettings.Get(webApplicationBuilder.Configuration); AppSettings appSettings = Models.Binder.AppSettings.Get(webApplicationBuilder.Configuration);
if (string.IsNullOrEmpty(appSettings.Company))
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);
_ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, webApplicationBuilder.Configuration);
_ = SerilogHostBuilderExtensions.UseSerilog(webApplicationBuilder.Host);
Log.Logger = loggerConfiguration.CreateLogger();
Serilog.ILogger log = Log.ForContext<Program>();
try try
{ {
_ = webApplicationBuilder.Services.AddMemoryCache(); _ = webApplicationBuilder.Services.AddMemoryCache();
@ -65,21 +59,26 @@ public class Program
SQLDbConnectionFactory sqlDbConnectionFactory = new(appSettings); SQLDbConnectionFactory sqlDbConnectionFactory = new(appSettings);
ClientSettingsRepository clientSettingsRepository = new(appSettings); ClientSettingsRepository clientSettingsRepository = new(appSettings);
_ = webApplicationBuilder.Services.AddHttpClient();
_ = webApplicationBuilder.Services.AddSingleton(_ => appSettings); _ = webApplicationBuilder.Services.AddSingleton(_ => appSettings);
_ = webApplicationBuilder.Services.AddSingleton<IInboundRepository, InboundRepository>(); _ = webApplicationBuilder.Services.AddSingleton<IPinRepository, PinRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IClientSettingsRepository>(_ => clientSettingsRepository);
_ = webApplicationBuilder.Services.AddSingleton<IServiceShopOrderRepository, ServiceShopOrderRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IPinRepository, PinRepository>(_ => new(appSettings.MockRoot));
_ = webApplicationBuilder.Services.AddSingleton<IDbConnectionFactory, SQLDbConnectionFactory>(_ => sqlDbConnectionFactory);
_ = webApplicationBuilder.Services.AddSingleton<IToolTypesRepository, ToolTypesRepository>(_ => new(appSettings.MockRoot));
_ = webApplicationBuilder.Services.AddSingleton<IAppSettingsRepository<Models.Binder.AppSettings>>(_ => appSettingsRepository);
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSRepository, InfinityQSRepository>(_ => new(appSettings.MockRoot, sqlDbConnectionFactory));
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV2Repository, InfinityQSV2Repository>(_ => new(appSettings.MockRoot, sqlDbConnectionFactory));
_ = webApplicationBuilder.Services.AddScoped<IExportRepository, ExportRepository>(); _ = webApplicationBuilder.Services.AddScoped<IExportRepository, ExportRepository>();
_ = webApplicationBuilder.Services.AddScoped<IAttachmentsService, AttachmentsService>(); _ = webApplicationBuilder.Services.AddScoped<IAttachmentsService, AttachmentsService>();
_ = webApplicationBuilder.Services.AddScoped<IInboundDataService, InboundDataService>(); _ = webApplicationBuilder.Services.AddScoped<IInboundDataService, InboundDataService>();
_ = webApplicationBuilder.Services.AddSingleton<IInboundRepository, InboundRepository>();
_ = webApplicationBuilder.Services.AddScoped<IMetrologyRepository, MetrologyRepository>(); _ = webApplicationBuilder.Services.AddScoped<IMetrologyRepository, MetrologyRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IFileShareRepository, FileShareRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IToolTypesRepository, ToolTypesRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSRepository, InfinityQSRepository>();
_ = webApplicationBuilder.Services.AddScoped<IOpenInsightV1Repository, OpenInsightV1Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV2Repository, InfinityQSV2Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV3Repository, InfinityQSV3Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV4Repository, InfinityQSV4Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IClientSettingsRepository>(_ => clientSettingsRepository);
_ = webApplicationBuilder.Services.AddSingleton<IServiceShopOrderRepository, ServiceShopOrderRepository>();
_ = webApplicationBuilder.Services.AddSingleton<ISpreadingResistanceProfileService, SpreadingResistanceProfileService>();
_ = webApplicationBuilder.Services.AddSingleton<IDbConnectionFactory, SQLDbConnectionFactory>(_ => sqlDbConnectionFactory);
_ = webApplicationBuilder.Services.AddSingleton<IAppSettingsRepository<Models.Binder.AppSettings>>(_ => appSettingsRepository);
_ = webApplicationBuilder.Services.AddSwaggerGen(); _ = webApplicationBuilder.Services.AddSwaggerGen();
_ = webApplicationBuilder.Services.AddSession(sessionOptions => _ = webApplicationBuilder.Services.AddSession(sessionOptions =>
@ -101,6 +100,7 @@ public class Program
}); });
} }
WebApplication webApplication = webApplicationBuilder.Build(); WebApplication webApplication = webApplicationBuilder.Build();
logger = webApplication.Services.GetRequiredService<ILogger<Program>>();
_ = webApplication.UseCors(corsPolicyBuilder => corsPolicyBuilder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); _ = webApplication.UseCors(corsPolicyBuilder => corsPolicyBuilder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
if (!webApplicationBuilder.Environment.IsDevelopment()) if (!webApplicationBuilder.Environment.IsDevelopment())
{ {
@ -118,26 +118,21 @@ public class Program
_ = webApplication.UseSwagger(); _ = webApplication.UseSwagger();
_ = webApplication.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Server V1")); _ = webApplication.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Server V1"));
} }
_ = webApplication.Lifetime.ApplicationStopped.Register(Log.CloseAndFlush);
_ = ApplicationBuilderSerilogClientExtensions.UseSerilogIngestion(webApplication);
_ = SerilogApplicationBuilderExtensions.UseSerilogRequestLogging(webApplication);
_ = webApplication.UseFileServer(enableDirectoryBrowsing: true); _ = webApplication.UseFileServer(enableDirectoryBrowsing: true);
_ = webApplication.UseStaticFiles(); _ = webApplication.UseStaticFiles();
_ = webApplication.UseSession(); _ = webApplication.UseSession();
_ = webApplication.UseMiddleware<ApiLoggingMiddleware>(); _ = webApplication.UseMiddleware<ApiLoggingMiddleware>();
_ = webApplication.MapControllers(); _ = webApplication.MapControllers();
log.Information("Starting Web Application"); logger.LogInformation("Starting Web Application");
webApplication.Run(); webApplication.Run();
return 0; return 0;
} }
catch (Exception ex) catch (Exception ex)
{ {
log.Fatal(ex, "Host terminated unexpectedly"); try
return 1; { logger?.LogCritical(ex, "Host terminated unexpectedly"); }
} catch (Exception) { }
finally throw;
{
Log.CloseAndFlush();
} }
} }

View File

@ -28,4 +28,4 @@
} }
} }
} }
} }

View File

@ -31,28 +31,22 @@ public class AppSettingsRepository : IAppSettingsRepository<Models.Binder.AppSet
return result; return result;
} }
string IAppSettingsRepository<Models.Binder.AppSettings>.GetBuildNumberAndGitCommitSeven() => GetBuildNumberAndGitCommitSeven();
internal void VerifyConnectionStrings() internal void VerifyConnectionStrings()
{ {
if (string.IsNullOrEmpty(_AppSettings.ConnectionString)) if (string.IsNullOrEmpty(_AppSettings.ConnectionString))
throw new NotSupportedException(); throw new NotSupportedException();
if (string.IsNullOrEmpty(_AppSettings.OI2SqlConnectionString))
throw new NotSupportedException();
#if DEBUG #if DEBUG
if (!_AppSettings.ConnectionString.Contains("test", StringComparison.CurrentCultureIgnoreCase)) if (!_AppSettings.ConnectionString.Contains("test", StringComparison.CurrentCultureIgnoreCase))
throw new NotSupportedException(); throw new NotSupportedException();
if (!_AppSettings.OI2SqlConnectionString.Contains("test", StringComparison.CurrentCultureIgnoreCase))
throw new NotSupportedException();
#endif #endif
#if !DEBUG #if !DEBUG
if (_AppSettings.ConnectionString.Contains("test", StringComparison.CurrentCultureIgnoreCase)) if (_AppSettings.ConnectionString.Contains("test", StringComparison.CurrentCultureIgnoreCase))
throw new NotSupportedException(); throw new NotSupportedException();
if (_AppSettings.OI2SqlConnectionString.Contains("test", StringComparison.CurrentCultureIgnoreCase))
throw new NotSupportedException();
#endif #endif
} }
string IAppSettingsRepository<Models.Binder.AppSettings>.GetBuildNumberAndGitCommitSeven() => GetBuildNumberAndGitCommitSeven();
void IAppSettingsRepository<Models.Binder.AppSettings>.VerifyConnectionStrings() => VerifyConnectionStrings(); void IAppSettingsRepository<Models.Binder.AppSettings>.VerifyConnectionStrings() => VerifyConnectionStrings();
} }

View File

@ -13,24 +13,20 @@ public class ClientSettingsRepository : IClientSettingsRepository
internal List<string> GetClientSettings(IPAddress? remoteIpAddress) internal List<string> GetClientSettings(IPAddress? remoteIpAddress)
{ {
List<string> results = new(); List<string> results = new() { remoteIpAddress is null ? nameof(remoteIpAddress) : remoteIpAddress.ToString() };
if (remoteIpAddress is null)
results.Add(nameof(remoteIpAddress));
else
results.Add(remoteIpAddress.ToString());
if (!_AppSettings.IsDevelopment) if (!_AppSettings.IsDevelopment)
throw new Exception("Shouldn't expose!"); throw new Exception("Shouldn't expose!");
return results; return results;
} }
List<string> IClientSettingsRepository.GetClientSettings(IPAddress? remoteIpAddress) => GetClientSettings(remoteIpAddress);
internal static string GetIpAddress(IPAddress? remoteIpAddress) internal static string GetIpAddress(IPAddress? remoteIpAddress)
{ {
string result = remoteIpAddress is null ? string.Empty : remoteIpAddress.ToString(); string result = remoteIpAddress is null ? string.Empty : remoteIpAddress.ToString();
return result; return result;
} }
List<string> IClientSettingsRepository.GetClientSettings(IPAddress? remoteIpAddress) => GetClientSettings(remoteIpAddress);
string IClientSettingsRepository.GetIpAddress(IPAddress? remoteIpAddress) => GetIpAddress(remoteIpAddress); string IClientSettingsRepository.GetIpAddress(IPAddress? remoteIpAddress) => GetIpAddress(remoteIpAddress);
} }

View File

@ -1,7 +1,10 @@
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;
@ -9,17 +12,21 @@ namespace OI.Metrology.Server.Repository;
public class ExportRepository : IExportRepository public class ExportRepository : IExportRepository
{ {
private readonly Serilog.ILogger _Log;
private readonly string _RepositoryName; private readonly string _RepositoryName;
private readonly AppSettings _AppSettings; private readonly AppSettings _AppSettings;
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(AppSettings appSettings) public ExportRepository(ILogger<ExportRepository> logger, AppSettings appSettings, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository)
{ {
_Logger = logger;
_AppSettings = appSettings; _AppSettings = appSettings;
_RdsToHeaderCommonCollection = new(); _RdsToHeaderCommonCollection = new();
_HttpClientFactory = httpClientFactory;
_FileShareRepository = fileShareRepository;
_RepositoryName = nameof(ExportRepository)[..^10]; _RepositoryName = nameof(ExportRepository)[..^10];
_Log = Serilog.Log.ForContext<ExportRepository>();
} }
private static string[] Get() private static string[] Get()
@ -32,32 +39,47 @@ public class ExportRepository : IExportRepository
return new string[] { weekOfYear, lastWeekOfYear }; return new string[] { weekOfYear, lastWeekOfYear };
} }
private List<string> GetFiles(HeaderCommon headerCommon, string searchPattern) private NginxFileSystemSortable[] GetNginxFileSystemSortableCollection(HeaderCommon headerCommon, HttpClient httpClient, string endsWith)
{ {
List<string> results = new(); List<NginxFileSystemSortable> results = new();
string directory; Uri uri;
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)
directory = Path.Combine(_AppSettings.ApiExportPath, weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}"); uri = _FileShareRepository.Append(new Uri(_AppSettings.EcMesaFileShareMetrologySi), "Archive", "API", weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}");
else else
directory = Path.Combine(_AppSettings.ApiExportPath, weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}", $"-{headerCommon.ID}"); uri = _FileShareRepository.Append(new Uri(_AppSettings.EcMesaFileShareMetrologySi), "Archive", "API", weekYear, $"-{headerCommon.PSN}", $"-{headerCommon.Reactor}", $"-{headerCommon.RDS}", $"-{headerCommon.ID}");
if (!Directory.Exists(directory)) nginxFileSystemSortableCollection = _FileShareRepository.GetNginxFileSystemSortableCollection(httpClient, uri, endsWith);
continue; results.AddRange(nginxFileSystemSortableCollection);
results.AddRange(Directory.GetFiles(directory, searchPattern, SearchOption.AllDirectories));
} }
return results; return results.OrderByDescending(l => l.DateTime).ToArray();
}
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;
List<string> files = GetFiles(headerCommon, "*.txt"); HttpClient httpClient = _HttpClientFactory.CreateClient();
if (files.Count != 1) NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".txt");
result = string.Empty; result = GetLines(httpClient, nginxFileSystemSortableCollection);
else
result = File.ReadAllText(files.First());
return result; return result;
} }
@ -72,16 +94,17 @@ public class ExportRepository : IExportRepository
JsonElement? jsonElement; JsonElement? jsonElement;
const string ticks = "Ticks"; const string ticks = "Ticks";
JsonProperty[] jsonProperties; JsonProperty[] jsonProperties;
List<string> files = GetFiles(headerCommon, "*.json"); HttpClient httpClient = _HttpClientFactory.CreateClient();
foreach (string file in files) NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".json");
foreach (NginxFileSystemSortable nginxFileSystemSortable in nginxFileSystemSortableCollection)
{ {
json = File.ReadAllText(file); json = GetLines(httpClient, nginxFileSystemSortableCollection);
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(file); directory = Path.GetDirectoryName(nginxFileSystemSortable.Uri.OriginalString);
if (directory is null) if (directory is null)
continue; continue;
directoryName = Path.GetFileName(directory); directoryName = Path.GetFileName(directory);
@ -93,7 +116,7 @@ public class ExportRepository : IExportRepository
if (jsonElement is not null && jsonElement.Value.ValueKind == JsonValueKind.Object) if (jsonElement is not null && jsonElement.Value.ValueKind == JsonValueKind.Object)
{ {
jsonProperties = (from l in jsonElement.Value.EnumerateObject() where l.Name == ticks select l).ToArray(); jsonProperties = (from l in jsonElement.Value.EnumerateObject() where l.Name == ticks select l).ToArray();
if (jsonProperties.Any() && long.TryParse(jsonProperties[0].Value.ToString(), out long ticksValue)) if (jsonProperties.Length != 0 && long.TryParse(jsonProperties[0].Value.ToString(), out long ticksValue))
hc.Date = new(ticksValue); hc.Date = new(ticksValue);
} }
results.Add(hc); results.Add(hc);
@ -112,10 +135,11 @@ public class ExportRepository : IExportRepository
List<HeaderCommon> results = new(); List<HeaderCommon> results = new();
string json; string json;
HeaderCommon? hc; HeaderCommon? hc;
List<string> files = GetFiles(headerCommon, "*.json"); HttpClient httpClient = _HttpClientFactory.CreateClient();
foreach (string file in files) NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".json");
foreach (NginxFileSystemSortable nginxFileSystemSortable in nginxFileSystemSortableCollection)
{ {
json = File.ReadAllText(file); json = GetLines(httpClient, nginxFileSystemSortableCollection);
hc = JsonSerializer.Deserialize<HeaderCommon>(json); hc = JsonSerializer.Deserialize<HeaderCommon>(json);
if (hc is null) if (hc is null)
continue; continue;
@ -132,12 +156,92 @@ public class ExportRepository : IExportRepository
string IExportRepository.GetProcessDataStandardFormat(HeaderCommon headerCommon) string IExportRepository.GetProcessDataStandardFormat(HeaderCommon headerCommon)
{ {
string result; string result;
List<string> files = GetFiles(headerCommon, "*.pdsf"); HttpClient httpClient = _HttpClientFactory.CreateClient();
if (files.Count != 1) NginxFileSystemSortable[] nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(headerCommon, httpClient, ".pdsf");
result = string.Empty; result = GetLines(httpClient, nginxFileSystemSortableCollection);
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

@ -0,0 +1,106 @@
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

@ -4,16 +4,13 @@ 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.Repository; namespace OI.Metrology.Server.Repository;
public class InboundRepository : IInboundRepository public class InboundRepository : IInboundRepository
{ {
private readonly Serilog.ILogger _Log;
public InboundRepository() => _Log = Serilog.Log.ForContext<InboundRepository>();
bool IInboundRepository.IsIPAddressAllowed(string inboundApiAllowedIPList, IPAddress? remoteIP) bool IInboundRepository.IsIPAddressAllowed(string inboundApiAllowedIPList, IPAddress? remoteIP)
{ {
if (string.IsNullOrWhiteSpace(inboundApiAllowedIPList)) if (string.IsNullOrWhiteSpace(inboundApiAllowedIPList))
@ -34,55 +31,42 @@ public class InboundRepository : IInboundRepository
return false; return false;
} }
// this is the main endpoint, it accepts a JSON message that contains both the header and data records together DataResponse IInboundRepository.Data(IMetrologyRepository metrologyRepository, IInboundDataService inboundDataService, string toolTypeName, JsonElement? jsonElement)
// 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, JToken jsonbody)
{ {
DataResponse result = new(); DataResponse result = new();
ToolType? toolType = metrologyRepository.GetToolTypeByName(tooltype); if (jsonElement is null || jsonElement.Value.ValueKind != JsonValueKind.Object)
if (toolType is null) throw new Exception("Invalid body!");
result.Errors.Add("Invalid tool type: " + tooltype); string? json = jsonElement.ToString();
else JToken jToken = (string.IsNullOrEmpty(json) ? JToken.Parse("{}") : JToken.Parse(json)) ??
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)
{ {
List<ToolTypeMetadata> metaData = metrologyRepository.GetToolTypeMetadataByToolTypeID(toolType.ID).ToList(); try
if (metaData is null)
result.Errors.Add("Invalid metadata for tool type: " + tooltype);
else if (jsonbody is null)
result.Errors.Add("Invalid json");
else
inboundDataService.ValidateJSONFields(jsonbody, 0, metaData, result.Errors, result.Warnings);
if (metaData is not null && jsonbody is not null && !result.Errors.Any())
{ {
try result.HeaderID = inboundDataService.DoSQLInsert(jToken, toolType, metaData);
{ result.Success = result.HeaderID > 0;
result.HeaderID = inboundDataService.DoSQLInsert(jsonbody, toolType, metaData);
result.Success = result.HeaderID > 0;
}
catch (Exception ex) { result.Errors.Add(ex.Message); }
} }
catch (Exception ex) { result.Errors.Add(ex.Message); }
} }
return result; return result;
} }
// 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. void IInboundRepository.AttachFile(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, string toolTypeName, Attachment? attachment)
// 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)
{ {
string? result = null; if (attachment is null)
ToolType toolType = metrologyRepository.GetToolTypeByName(tooltype); throw new Exception("Invalid body!");
if (toolType is null) ToolType toolType = metrologyRepository.GetToolTypeByName(toolTypeName) ??
result = $"Invalid tool type: {tooltype}"; throw new Exception($"Invalid tool type: {toolTypeName}");
string filename = Path.GetFileName(fileName); if (string.IsNullOrWhiteSpace(attachment.DestinationFileName))
if (string.IsNullOrWhiteSpace(filename)) throw new Exception("Empty filename");
result = "Empty filename"; if (attachment.DestinationFileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
if (filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) throw new Exception("Invalid filename");
result = "Invalid filename"; attachmentsService.SaveAttachment(toolType, attachment);
if (result is null && toolType is not null)
attachmentsService.SaveAttachment(toolType, headerid, datauniqueid, filename, uploadedFile);
return result;
} }
} }

View File

@ -1,3 +1,4 @@
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Repositories; using OI.Metrology.Shared.Repositories;
@ -15,9 +16,9 @@ public class InfinityQSRepository : IInfinityQSRepository
private readonly string _RepositoryName; private readonly string _RepositoryName;
private readonly IDbConnectionFactory _DBConnectionFactory; private readonly IDbConnectionFactory _DBConnectionFactory;
public InfinityQSRepository(string mockRoot, IDbConnectionFactory dbConnectionFactory) public InfinityQSRepository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory)
{ {
_MockRoot = mockRoot; _MockRoot = appSettings.MockRoot;
_DBConnectionFactory = dbConnectionFactory; _DBConnectionFactory = dbConnectionFactory;
_RepositoryName = nameof(InfinityQSRepository)[..^10]; _RepositoryName = nameof(InfinityQSRepository)[..^10];
} }
@ -52,6 +53,8 @@ public class InfinityQSRepository : IInfinityQSRepository
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(nameof(dateTime)); throw new ArgumentException(nameof(dateTime));
_ = result _ = result
.AppendLine(" select iq.ev_count, iq.cl_count, iq.sl_count, iq.se_sgrp, iq.se_sgtm, iq.se_tsno, iq.td_test, iq.pr_name, iq.jd_name, iq.pl_name, iq.pd_name, iq.td_name, iq.se_val ")
.AppendLine(" from ( ")
.AppendLine(" select ") .AppendLine(" select ")
.AppendLine(" se.f_sgrp se_sgrp, ") .AppendLine(" se.f_sgrp se_sgrp, ")
.AppendLine(" se.f_sgtm se_sgtm, ") .AppendLine(" se.f_sgtm se_sgtm, ")
@ -63,11 +66,22 @@ public class InfinityQSRepository : IInfinityQSRepository
.AppendLine(" pd.f_name pd_name, ") .AppendLine(" pd.f_name pd_name, ")
.AppendLine(" td.f_test td_test, ") .AppendLine(" td.f_test td_test, ")
.AppendLine(" td.f_name td_name, ") .AppendLine(" td.f_name td_name, ")
.AppendLine(" (select count(cl.f_part) ")
.AppendLine(" from [spcepiworld].[dbo].[ctrl_lim] cl ")
.AppendLine(" where cl.f_part = pd.f_part ")
.AppendLine(" and cl.f_test = td.f_test ")
.AppendLine(" ) cl_count, ")
.AppendLine(" (select count(sl.f_part) ")
.AppendLine(" from [spcepiworld].[dbo].[spec_lim] sl ")
.AppendLine(" where sl.f_part = pd.f_part ")
.AppendLine(" and sl.f_test = td.f_test ")
.AppendLine(" ) sl_count, ")
.AppendLine(" (select count(ev.f_evnt) ") .AppendLine(" (select count(ev.f_evnt) ")
.AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ") .AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
.AppendLine(" where ev.f_prcs = pr.f_prcs ") .AppendLine(" where ev.f_prcs = pr.f_prcs ")
.AppendLine(" and ev.f_part = pd.f_part ") .AppendLine(" and ev.f_part = pd.f_part ")
.AppendLine(" and ev.f_sgtm = se.f_sgtm) ev_count ") .AppendLine(" and ev.f_sgtm = se.f_sgtm ")
.AppendLine(" ) ev_count ")
.AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ") .AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ") .AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on se.f_prcs = pr.f_prcs ") .AppendLine(" on se.f_prcs = pr.f_prcs ")
@ -92,6 +106,8 @@ public class InfinityQSRepository : IInfinityQSRepository
_ = result.Append(" and pl.f_name = '").Append(lot).AppendLine("' "); _ = 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(':')))
_ = result.Append(" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '").Append(dateTime).AppendLine("' "); _ = result.Append(" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '").Append(dateTime).AppendLine("' ");
_ = result.AppendLine(" ) as iq ");
_ = result.AppendLine(" order by iq.ev_count desc, iq.cl_count desc, iq.sl_count desc, iq.se_sgrp, iq.se_tsno, iq.td_test ");
_ = result.AppendLine(" for json path "); _ = result.AppendLine(" for json path ");
return result.ToString(); return result.ToString();
} }
@ -116,9 +132,9 @@ public class InfinityQSRepository : IInfinityQSRepository
InfinityQSBase[]? results = JsonSerializer.Deserialize<InfinityQSBase[]>(stringBuilder.ToString(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); InfinityQSBase[]? results = JsonSerializer.Deserialize<InfinityQSBase[]>(stringBuilder.ToString(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (results is null) if (results is null)
throw new NullReferenceException(nameof(results)); throw new NullReferenceException(nameof(results));
if (results.Select(l => l.SE_SGRP).Distinct().Count() != 1) // if (results.Select(l => l.SE_SGRP).Distinct().Count() != 1)
throw new NotSupportedException("Multiple ids are present!"); // throw new NotSupportedException("Multiple ids are present!");
result = (from l in results orderby l.SE_TSNO, l.TD_TEST select l).First(); result = (from l in results orderby l.SE_SGRP, l.SE_TSNO, l.TD_TEST select l).First();
return result; return result;
} }
@ -177,6 +193,37 @@ public class InfinityQSRepository : IInfinityQSRepository
return result; return result;
} }
string IInfinityQSRepository.GetCommandText(InfinityQSBase infinityQSBase)
{
StringBuilder result = new();
if (string.IsNullOrEmpty(infinityQSBase.PR_NAME))
throw new ArgumentException(nameof(infinityQSBase.PR_NAME));
if (string.IsNullOrEmpty(infinityQSBase.PD_NAME))
throw new ArgumentException(nameof(infinityQSBase.PD_NAME));
_ = result
.AppendLine(" select ")
.AppendLine(" ev.f_evnt [ev_evnt], ")
.AppendLine(" ev.f_sgtm [ev_sgtm], ")
.AppendLine(" dateadd(HH, -7, (dateadd(SS, convert(bigint, ev.f_sgtm), '19700101'))) [ev_utc7], ")
.AppendLine(" pr.f_name [pr_name], ")
.AppendLine(" pd.f_name [pd_name], ")
.AppendLine(" td.f_test [td_test], ")
.AppendLine(" td.f_name [td_name], ")
.AppendLine(" ev.f_name [ev_name] ")
.AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on ev.f_prcs = pr.f_prcs ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
.AppendLine(" on ev.f_part = pd.f_part ")
.AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
.AppendLine(" on ev.f_test = td.f_test ")
.Append(" where pr.f_name = '").Append(infinityQSBase.PR_NAME).AppendLine("' ")
.Append(" and pd.f_name = '").Append(infinityQSBase.PD_NAME).AppendLine("' ")
.Append(" and ev.f_sgtm = ").Append(infinityQSBase.SE_SGTM).AppendLine(" ")
.AppendLine(" for json path ");
return result.ToString();
}
Result<InfinityQSEvent[]> IInfinityQSRepository.GetEvents(string subGroupId) Result<InfinityQSEvent[]> IInfinityQSRepository.GetEvents(string subGroupId)
{ {
Result<InfinityQSEvent[]>? result; Result<InfinityQSEvent[]>? result;
@ -192,11 +239,11 @@ public class InfinityQSRepository : IInfinityQSRepository
InfinityQSEvent[]? results; InfinityQSEvent[]? results;
IInfinityQSRepository infinityQSRepository = this; IInfinityQSRepository infinityQSRepository = this;
InfinityQSBase infinityQSBase = GetInfinityQSBase(_DBConnectionFactory, infinityQSRepository, subGroupId); InfinityQSBase infinityQSBase = GetInfinityQSBase(_DBConnectionFactory, infinityQSRepository, subGroupId);
if (!infinityQSBase.EV_COUNT.HasValue || infinityQSBase.EV_COUNT.Value <= 0) if (infinityQSBase.EV_COUNT <= 0)
results = Array.Empty<InfinityQSEvent>(); results = Array.Empty<InfinityQSEvent>();
else else
{ {
string commandText = $"select * from [spcepiworld].[dbo].[evnt_inf] ev where ev.f_prcs = '{infinityQSBase.PR_NAME}' and ev.f_part = '{infinityQSBase.PD_NAME}' and ev.f_sgtm = {infinityQSBase.SE_SGTM} "; string commandText = infinityQSRepository.GetCommandText(infinityQSBase);
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText); StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText);
results = JsonSerializer.Deserialize<InfinityQSEvent[]>(stringBuilder.ToString(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); results = JsonSerializer.Deserialize<InfinityQSEvent[]>(stringBuilder.ToString(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (results is null) if (results is null)

View File

@ -1,3 +1,4 @@
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Repositories; using OI.Metrology.Shared.Repositories;
@ -15,9 +16,9 @@ public class InfinityQSV2Repository : IInfinityQSV2Repository
private readonly string _RepositoryName; private readonly string _RepositoryName;
private readonly IDbConnectionFactory _DBConnectionFactory; private readonly IDbConnectionFactory _DBConnectionFactory;
public InfinityQSV2Repository(string mockRoot, IDbConnectionFactory dbConnectionFactory) public InfinityQSV2Repository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory)
{ {
_MockRoot = mockRoot; _MockRoot = appSettings.MockRoot;
_DBConnectionFactory = dbConnectionFactory; _DBConnectionFactory = dbConnectionFactory;
_RepositoryName = nameof(InfinityQSV2Repository)[..^10]; _RepositoryName = nameof(InfinityQSV2Repository)[..^10];
} }
@ -26,7 +27,7 @@ public class InfinityQSV2Repository : IInfinityQSV2Repository
{ {
StringBuilder result = new(); StringBuilder result = new();
if (string.IsNullOrEmpty(subGroupId)) if (string.IsNullOrEmpty(subGroupId))
throw new ArgumentException(nameof(subGroupId)); throw new ArgumentException(null, nameof(subGroupId));
_ = result _ = result
.AppendLine(" select ") .AppendLine(" select ")
.AppendLine(" sd.f_sgrp sd_sgrp, ") .AppendLine(" sd.f_sgrp sd_sgrp, ")
@ -50,8 +51,10 @@ public class InfinityQSV2Repository : IInfinityQSV2Repository
StringBuilder result = new(); 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(nameof(dateTime)); throw new ArgumentException(null, nameof(dateTime));
_ = result _ = result
.AppendLine(" select iq.ev_count, iq.cl_count, iq.sl_count, iq.se_sgrp, iq.se_sgtm, iq.se_tsno, iq.td_test, iq.pr_name, iq.jd_name, iq.pl_name, iq.pd_name, iq.td_name, iq.se_val ")
.AppendLine(" from ( ")
.AppendLine(" select ") .AppendLine(" select ")
.AppendLine(" se.f_sgrp se_sgrp, ") .AppendLine(" se.f_sgrp se_sgrp, ")
.AppendLine(" se.f_sgtm se_sgtm, ") .AppendLine(" se.f_sgtm se_sgtm, ")
@ -63,11 +66,22 @@ public class InfinityQSV2Repository : IInfinityQSV2Repository
.AppendLine(" pd.f_name pd_name, ") .AppendLine(" pd.f_name pd_name, ")
.AppendLine(" td.f_test td_test, ") .AppendLine(" td.f_test td_test, ")
.AppendLine(" td.f_name td_name, ") .AppendLine(" td.f_name td_name, ")
.AppendLine(" (select count(cl.f_part) ")
.AppendLine(" from [spcepiworld].[dbo].[ctrl_lim] cl ")
.AppendLine(" where cl.f_part = pd.f_part ")
.AppendLine(" and cl.f_test = td.f_test ")
.AppendLine(" ) cl_count, ")
.AppendLine(" (select count(sl.f_part) ")
.AppendLine(" from [spcepiworld].[dbo].[spec_lim] sl ")
.AppendLine(" where sl.f_part = pd.f_part ")
.AppendLine(" and sl.f_test = td.f_test ")
.AppendLine(" ) sl_count, ")
.AppendLine(" (select count(ev.f_evnt) ") .AppendLine(" (select count(ev.f_evnt) ")
.AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ") .AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
.AppendLine(" where ev.f_prcs = pr.f_prcs ") .AppendLine(" where ev.f_prcs = pr.f_prcs ")
.AppendLine(" and ev.f_part = pd.f_part ") .AppendLine(" and ev.f_part = pd.f_part ")
.AppendLine(" and ev.f_sgtm = se.f_sgtm) ev_count ") .AppendLine(" and ev.f_sgtm = se.f_sgtm ")
.AppendLine(" ) ev_count ")
.AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ") .AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ") .AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on se.f_prcs = pr.f_prcs ") .AppendLine(" on se.f_prcs = pr.f_prcs ")
@ -92,6 +106,8 @@ public class InfinityQSV2Repository : IInfinityQSV2Repository
_ = result.Append(" and pl.f_name = '").Append(lot).AppendLine("' "); _ = 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(':')))
_ = result.Append(" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '").Append(dateTime).AppendLine("' "); _ = result.Append(" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '").Append(dateTime).AppendLine("' ");
_ = result.AppendLine(" ) as iq ");
_ = result.AppendLine(" order by iq.ev_count desc, iq.cl_count desc, iq.sl_count desc, iq.se_sgrp, iq.se_tsno, iq.td_test ");
_ = result.AppendLine(" for json path "); _ = result.AppendLine(" for json path ");
return result.ToString(); return result.ToString();
} }
@ -117,9 +133,9 @@ public class InfinityQSV2Repository : IInfinityQSV2Repository
if (collection is null) if (collection is null)
throw new NullReferenceException(nameof(collection)); throw new NullReferenceException(nameof(collection));
InfinityQSBaseV2[] results = InfinityQSBase.Convert(collection); InfinityQSBaseV2[] results = InfinityQSBase.Convert(collection);
if (results.Select(l => l.SubGroupId).Distinct().Count() != 1) // if (results.Select(l => l.SubGroupId).Distinct().Count() != 1)
throw new NotSupportedException("Multiple ids are present!"); // throw new NotSupportedException("Multiple ids are present!");
result = (from l in results orderby l.SiteNumber, l.VariableNumber select l).First(); result = results.First();
return result; return result;
} }
@ -180,6 +196,37 @@ public class InfinityQSV2Repository : IInfinityQSV2Repository
return result; return result;
} }
string IInfinityQSV2Repository.GetCommandText(InfinityQSBaseV2 infinityQSBase)
{
StringBuilder result = new();
if (string.IsNullOrEmpty(infinityQSBase.Process))
throw new ArgumentException(nameof(infinityQSBase.Process));
if (string.IsNullOrEmpty(infinityQSBase.Part))
throw new ArgumentException(nameof(infinityQSBase.Part));
_ = result
.AppendLine(" select ")
.AppendLine(" ev.f_evnt [ev_evnt], ")
.AppendLine(" ev.f_sgtm [ev_sgtm], ")
.AppendLine(" dateadd(HH, -7, (dateadd(SS, convert(bigint, ev.f_sgtm), '19700101'))) [ev_utc7], ")
.AppendLine(" pr.f_name [pr_name], ")
.AppendLine(" pd.f_name [pd_name], ")
.AppendLine(" td.f_test [td_test], ")
.AppendLine(" td.f_name [td_name], ")
.AppendLine(" ev.f_name [ev_name] ")
.AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on ev.f_prcs = pr.f_prcs ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
.AppendLine(" on ev.f_part = pd.f_part ")
.AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
.AppendLine(" on ev.f_test = td.f_test ")
.Append(" where pr.f_name = '").Append(infinityQSBase.Process).AppendLine("' ")
.Append(" and pd.f_name = '").Append(infinityQSBase.Part).AppendLine("' ")
.Append(" and ev.f_sgtm = ").Append(infinityQSBase.SubGroupDateTime).AppendLine(" ")
.AppendLine(" for json path ");
return result.ToString();
}
Result<InfinityQSEventV2[]> IInfinityQSV2Repository.GetEvents(string subGroupId) Result<InfinityQSEventV2[]> IInfinityQSV2Repository.GetEvents(string subGroupId)
{ {
Result<InfinityQSEventV2[]>? result; Result<InfinityQSEventV2[]>? result;
@ -195,11 +242,11 @@ public class InfinityQSV2Repository : IInfinityQSV2Repository
InfinityQSEvent[]? collection; InfinityQSEvent[]? collection;
IInfinityQSV2Repository infinityQSV2Repository = this; IInfinityQSV2Repository infinityQSV2Repository = this;
InfinityQSBaseV2 infinityQSBase = GetInfinityQSBase(_DBConnectionFactory, infinityQSV2Repository, subGroupId); InfinityQSBaseV2 infinityQSBase = GetInfinityQSBase(_DBConnectionFactory, infinityQSV2Repository, subGroupId);
if (!infinityQSBase.EventCount.HasValue || infinityQSBase.EventCount.Value <= 0) if (infinityQSBase.EventCount <= 0)
collection = Array.Empty<InfinityQSEvent>(); collection = Array.Empty<InfinityQSEvent>();
else else
{ {
string commandText = $"select * from [spcepiworld].[dbo].[evnt_inf] ev where ev.f_prcs = '{infinityQSBase.Process}' and ev.f_part = '{infinityQSBase.Part}' and ev.f_sgtm = {infinityQSBase.SubGroupDateTime} "; string commandText = infinityQSV2Repository.GetCommandText(infinityQSBase);
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText); StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText);
collection = JsonSerializer.Deserialize<InfinityQSEvent[]>(stringBuilder.ToString(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); collection = JsonSerializer.Deserialize<InfinityQSEvent[]>(stringBuilder.ToString(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (collection is null) if (collection is null)

View File

@ -0,0 +1,565 @@
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Repositories;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Common;
using System.Text;
using System.Text.Json;
namespace OI.Metrology.Server.Repository;
public class InfinityQSV3Repository : IInfinityQSV3Repository
{
private readonly string _MockRoot;
private readonly string _RepositoryName;
private readonly IHttpClientFactory _HttpClientFactory;
private readonly IDbConnectionFactory _DBConnectionFactory;
private readonly string _OpenInsightApplicationProgrammingInterface;
public InfinityQSV3Repository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory, IHttpClientFactory httpClientFactory)
{
_MockRoot = appSettings.MockRoot;
_HttpClientFactory = httpClientFactory;
_DBConnectionFactory = dbConnectionFactory;
_RepositoryName = nameof(InfinityQSV3Repository)[..^10];
_OpenInsightApplicationProgrammingInterface = appSettings.OpenInsightApplicationProgrammingInterface;
}
string IInfinityQSV3Repository.GetCommandText(string subGroupId)
{ // cSpell:disable
StringBuilder result = new();
if (string.IsNullOrEmpty(subGroupId))
throw new ArgumentException(null, nameof(subGroupId));
_ = result
.AppendLine(" select ")
.AppendLine(" sd.f_sgrp sd_sgrp, ")
.AppendLine(" sd.f_tsno sd_tsno, ")
.AppendLine(" dd.f_dsgp dd_dsgp, ")
.AppendLine(" dg.f_name gd_name, ")
.AppendLine(" dd.f_name dd_name ")
.AppendLine(" from [SPCEPIWORLD].[dbo].[SGRP_DSC] sd ")
.AppendLine(" join [SPCEPIWORLD].[dbo].[DESC_DAT] dd ")
.AppendLine(" on sd.f_dsgp = dd.f_dsgp ")
.AppendLine(" and sd.f_desc = dd.f_desc ")
.AppendLine(" join [SPCEPIWORLD].[dbo].[DESC_GRP] dg ")
.AppendLine(" on dd.f_dsgp = dg.f_dsgp ");
_ = result.Append(" where sd.f_sgrp = ").Append(subGroupId).AppendLine(" ");
_ = result.AppendLine(" for json path ");
return result.ToString();
} // cSpell:enable
string IInfinityQSV3Repository.GetCommandText(string? subGroupId, string? process, string? job, string? part, string? lot, string? dateTime)
{ // cSpell:disable
StringBuilder result = new();
const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')) && dateTime.Length != dateTimeFormat.Length)
throw new ArgumentException(null, nameof(dateTime));
_ = result
.AppendLine(" select case when iq.sl_loos is null then 0 else iq.sl_loos end + ")
.AppendLine(" case when iq.sl_uoos is null then 0 else iq.sl_uoos end + ")
.AppendLine(" iq.ev_count as iq_sum, ")
.AppendLine(" iq.sl_aflag, ")
.AppendLine(" iq.sl_loos, ")
.AppendLine(" iq.sl_uoos, ")
.AppendLine(" iq.se_sgrp, ")
.AppendLine(" iq.se_sgtm, ")
.AppendLine(" iq.se_tsno, ")
.AppendLine(" iq.td_test, ")
.AppendLine(" iq.pr_name, ")
.AppendLine(" iq.jd_name, ")
.AppendLine(" iq.pl_name, ")
.AppendLine(" iq.pd_name, ")
.AppendLine(" iq.td_name, ")
.AppendLine(" iq.se_val, ")
.AppendLine(" iq.sl_eflag, ")
.AppendLine(" iq.sl_scal, ")
.AppendLine(" iq.sl_sls, ")
.AppendLine(" iq.sl_usl ")
.AppendLine(" from ( ")
.AppendLine(" select ")
.AppendLine(" se.f_sgrp se_sgrp, ")
.AppendLine(" se.f_sgtm se_sgtm, ")
.AppendLine(" se.f_tsno se_tsno, ")
.AppendLine(" se.f_val se_val, ")
.AppendLine(" pr.f_name pr_name, ")
.AppendLine(" jd.f_name jd_name, ")
.AppendLine(" pl.f_name pl_name, ")
.AppendLine(" pd.f_name pd_name, ")
.AppendLine(" td.f_test td_test, ")
.AppendLine(" td.f_name td_name, ")
.AppendLine(" sl.f_eflag sl_eflag, ")
.AppendLine(" sl.f_aflag sl_aflag, ")
.AppendLine(" sl.f_scal sl_scal, ")
.AppendLine(" sl.f_lsl sl_sls, ")
.AppendLine(" sl.f_usl sl_usl, ")
.AppendLine(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ")
.AppendLine(" case when round(se.f_val, sl.F_scal, 1) < sl.f_lsl then 1 else 0 end ")
.AppendLine(" end as sl_loos, ")
.AppendLine(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ")
.AppendLine(" case when round(se.f_val, sl.F_scal, 1) > sl.f_usl then 1 else 0 end ")
.AppendLine(" end as sl_uoos, ")
.AppendLine(" (select count(ev.f_evnt) ")
.AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
.AppendLine(" where ev.f_prcs = pr.f_prcs ")
.AppendLine(" and ev.f_part = pd.f_part ")
.AppendLine(" and ev.f_sgtm = se.f_sgtm ")
.AppendLine(" ) ev_count ")
.AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on se.f_prcs = pr.f_prcs ")
.AppendLine(" join [spcepiworld].[dbo].[job_dat] jd ")
.AppendLine(" on se.f_job = jd.f_job ")
.AppendLine(" join [spcepiworld].[dbo].[part_lot] pl ")
.AppendLine(" on se.f_lot = pl.f_lot ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
.AppendLine(" on se.f_part = pd.f_part ")
.AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
.AppendLine(" on se.f_test = td.f_test ")
.AppendLine(" left join [spcepiworld].[dbo].[spec_lim] sl ")
.AppendLine(" on se.f_part = sl.f_part ")
.AppendLine(" and se.f_test = sl.f_test ")
.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))
_ = result.Append(" and se.f_sgrp = ").Append(subGroupId.Split(" ")[0]).AppendLine(" ");
if (!string.IsNullOrEmpty(process))
_ = result.Append(" and pr.f_name = '").Append(process).AppendLine("' ");
if (!string.IsNullOrEmpty(part))
_ = result.Append(" and pd.f_name = '").Append(part).AppendLine("' ");
if (!string.IsNullOrEmpty(job))
_ = result.Append(" and jd.f_name = '").Append(job).AppendLine("' ");
if (!string.IsNullOrEmpty(lot))
_ = result.Append(" and pl.f_name = '").Append(lot).AppendLine("' ");
if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')))
_ = result.Append(" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '").Append(dateTime).AppendLine("' ");
_ = result.AppendLine(" ) as iq ")
.AppendLine(" order by iq.sl_loos + iq.sl_uoos + iq.ev_count desc, ")
.AppendLine(" iq.sl_aflag desc, ")
.AppendLine(" iq.se_sgrp, ")
.AppendLine(" iq.se_tsno, ")
.AppendLine(" iq.td_test ")
.AppendLine(" for json path ");
return result.ToString();
} // cSpell:enable
private static StringBuilder GetForJsonPath(IDbConnectionFactory dbConnectionFactory, string commandText)
{
StringBuilder stringBuilder = new();
using DbConnection dbConnection = dbConnectionFactory.GetDbConnection();
DbCommand dbCommand = dbConnection.CreateCommand();
dbCommand.CommandText = commandText;
DbDataReader dbDataReader = dbCommand.ExecuteReader(CommandBehavior.SequentialAccess);
while (dbDataReader.Read())
_ = stringBuilder.Append(dbDataReader.GetString(0));
return stringBuilder;
}
private static InfinityQSV3 GetInfinityQSV3(IDbConnectionFactory dbConnectionFactory, IInfinityQSV3Repository infinityQSV3Repository, string subGroupId)
{
InfinityQSV3 result;
string commandText = infinityQSV3Repository.GetCommandText(subGroupId, process: string.Empty, job: string.Empty, part: string.Empty, lot: string.Empty, dateTime: string.Empty);
StringBuilder stringBuilder = GetForJsonPath(dbConnectionFactory, commandText);
InfinityQSV3[]? results = stringBuilder.Length == 0 ? Array.Empty<InfinityQSV3>() : JsonSerializer.Deserialize(stringBuilder.ToString(), ResultInfinityQSV3SourceGenerationContext.Default.InfinityQSV3Array); // , new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
if (results is null)
throw new NullReferenceException(nameof(results));
result = results.First();
return result;
}
Result<InfinityQSV3[]> IInfinityQSV3Repository.GetData(string subGroupId)
{
Result<InfinityQSV3[]>? result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV3Repository.GetData)}.json"));
result = JsonSerializer.Deserialize(json, ResultInfinityQSV3SourceGenerationContext.Default.ResultInfinityQSV3Array);
if (result is null)
throw new NullReferenceException(nameof(result));
}
else
{
IInfinityQSV3Repository infinityQSV3Repository = this;
InfinityQSV3 infinityQSV3 = GetInfinityQSV3(_DBConnectionFactory, infinityQSV3Repository, subGroupId);
string commandText = infinityQSV3Repository.GetCommandText(subGroupId, process: infinityQSV3.Process, job: infinityQSV3.Job, part: infinityQSV3.Part, lot: infinityQSV3.Lot, dateTime: string.Concat(infinityQSV3.SubGroupDateTime));
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText);
InfinityQSV3[]? results = stringBuilder.Length == 0 ? Array.Empty<InfinityQSV3>() : JsonSerializer.Deserialize(stringBuilder.ToString(), ResultInfinityQSV3SourceGenerationContext.Default.InfinityQSV3Array); // , new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
if (results is null)
throw new NullReferenceException(nameof(results));
result = new()
{
Results = results,
TotalRows = results.Length,
};
}
return result;
}
Result<InfinityQSDescriptorV3[]> IInfinityQSV3Repository.GetDescriptors(string subGroupId)
{
Result<InfinityQSDescriptorV3[]>? result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV3Repository.GetDescriptors)}.json"));
result = JsonSerializer.Deserialize(json, ResultInfinityQSDescriptorV3SourceGenerationContext.Default.ResultInfinityQSDescriptorV3Array);
if (result is null)
throw new NullReferenceException(nameof(result));
}
else
{
IInfinityQSV3Repository infinityQSV3Repository = this;
string commandText = infinityQSV3Repository.GetCommandText(subGroupId);
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText);
InfinityQSDescriptorV3[]? results = stringBuilder.Length == 0 ? Array.Empty<InfinityQSDescriptorV3>() : JsonSerializer.Deserialize(stringBuilder.ToString(), ResultInfinityQSDescriptorV3SourceGenerationContext.Default.InfinityQSDescriptorV3Array); // , new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
if (results is null)
throw new NullReferenceException(nameof(results));
result = new()
{
Results = results,
TotalRows = results.Length,
};
}
return result;
}
string IInfinityQSV3Repository.GetCommandText(InfinityQSV3 infinityQSV3)
{ // cSpell:disable
StringBuilder result = new();
if (string.IsNullOrEmpty(infinityQSV3.Process))
throw new ArgumentException(nameof(infinityQSV3.Process));
if (string.IsNullOrEmpty(infinityQSV3.Part))
throw new ArgumentException(nameof(infinityQSV3.Part));
_ = result
.AppendLine(" select ")
.AppendLine(" ev.f_evnt [ev_evnt], ")
.AppendLine(" ev.f_sgtm [ev_sgtm], ")
.AppendLine(" dateadd(HH, -7, (dateadd(SS, convert(bigint, ev.f_sgtm), '19700101'))) [ev_utc7], ")
.AppendLine(" pr.f_name [pr_name], ")
.AppendLine(" pd.f_name [pd_name], ")
.AppendLine(" td.f_test [td_test], ")
.AppendLine(" td.f_name [td_name], ")
.AppendLine(" ev.f_name [ev_name] ")
.AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on ev.f_prcs = pr.f_prcs ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
.AppendLine(" on ev.f_part = pd.f_part ")
.AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
.AppendLine(" on ev.f_test = td.f_test ")
.Append(" where pr.f_name = '").Append(infinityQSV3.Process).AppendLine("' ")
.Append(" and pd.f_name = '").Append(infinityQSV3.Part).AppendLine("' ")
.Append(" and ev.f_sgtm = ").Append(infinityQSV3.SubGroupDateTime).AppendLine(" ")
.AppendLine(" for json path ");
return result.ToString();
} // cSpell:enable
Result<InfinityQSV3[]> IInfinityQSV3Repository.GetHeader(string subGroupId)
{
Result<InfinityQSV3[]>? result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV3Repository.GetHeader)}.json"));
result = JsonSerializer.Deserialize(json, ResultInfinityQSV3SourceGenerationContext.Default.ResultInfinityQSV3Array);
if (result is null)
throw new NullReferenceException(nameof(result));
}
else
{
IInfinityQSV3Repository infinityQSV3Repository = this;
InfinityQSV3 infinityQSV3 = GetInfinityQSV3(_DBConnectionFactory, infinityQSV3Repository, subGroupId);
InfinityQSV3[] results = new InfinityQSV3[] { infinityQSV3 };
result = new()
{
Results = results,
TotalRows = results.Length,
};
}
return result;
}
string IInfinityQSV3Repository.GetCommandText(string process, string? part)
{ // cSpell:disable
StringBuilder result = new();
if (string.IsNullOrEmpty(process))
throw new ArgumentException(null, nameof(process));
if (string.IsNullOrEmpty(part))
throw new ArgumentException(null, nameof(part));
_ = result
.AppendLine(" select [f_mean] as ProcessMean, ")
.AppendLine(" [f_sp] as ProcessSigma ")
.AppendLine(" from [spcepiworld].[dbo].[test_dat] test ")
.AppendLine(" join [spcepiworld].[dbo].[ctrl_lim] ctrl ")
.AppendLine(" on test.f_test = ctrl.f_test ")
.AppendLine(" and test.f_tsgp = 1104848523 /* Product Data */ ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] part ")
.AppendLine(" on part.f_part = ctrl.f_part ")
.AppendLine(" and ctrl.f_test = 1125073605 /* Average Sum of Defects */ ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] process ")
.AppendLine(" on process.f_prcs = ctrl.f_prcs ")
.AppendLine(" where test.f_name = 'Average Sum of Defects' ")
.Append(" and process.f_name = '").Append(process).AppendLine("' ")
.Append(" and part.f_name = '").Append(part).AppendLine("' ")
.AppendLine(" for json path; ");
return result.ToString();
} // cSpell:enable
string IInfinityQSV3Repository.GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(string process, string? recipe)
{
StringBuilder result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV3Repository.GetProductDataAverageSumOfDefectsProcessMeanProcessSigma)}.json"));
result = new(json);
}
else
{
IInfinityQSV3Repository infinityQSV3Repository = this;
string commandText = infinityQSV3Repository.GetCommandText(process, recipe);
result = GetForJsonPath(_DBConnectionFactory, commandText);
if (result.Length == 0)
result = new("{}");
}
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 || reactor.ReactType != reactTypeFilter)
continue;
results.Add(reactor.ReactorNo, reactor);
}
return new(results);
}
string IInfinityQSV3Repository.GetCommandText(List<string> eppReactorNumbers)
{ // cSpell:disable
StringBuilder result = new();
_ = result
.AppendLine(" select se.f_sgrp, ")
.AppendLine(" dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgrp), '19700101'))) date_time, ")
.AppendLine(" iq.pr_name, ")
.AppendLine(" iq.pd_name, ")
.AppendLine(" max(case ")
.AppendLine(" when td.f_test = 1104769646 ")
.AppendLine(" then se.f_val ")
.AppendLine(" else null ")
.AppendLine(" end) as iq_value, ")
.AppendLine(" max(case ")
.AppendLine(" when td.f_test = 1312288843 ")
.AppendLine(" then se.f_val else null ")
.AppendLine(" end) as iq_temp_offset_percent ")
.AppendLine(" from ( ")
.AppendLine(" select ")
.AppendLine(" max(se.f_sgrp) se_max_sgrp, ")
.AppendLine(" se.f_test se_test, ")
.AppendLine(" pr.f_name pr_name, ")
.AppendLine(" pd.f_name pd_name ")
.AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on se.f_prcs = pr.f_prcs ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
.AppendLine(" on se.f_part = pd.f_part ")
.AppendLine(" where se.f_flag = 0 ")
.Append(" and pr.f_name in (").Append(string.Join(',', eppReactorNumbers)).AppendLine(") ")
.AppendLine(" and pd.f_name = '1090 - Full Load' ")
.AppendLine(" and se.f_test in (1104769646, 1312288843) ")
.AppendLine(" group by se.f_test, ")
.AppendLine(" pr.f_name, ")
.AppendLine(" pd.f_name ")
.AppendLine(" ) as iq ")
.AppendLine(" join [spcepiworld].[dbo].[sgrp_ext] se ")
.AppendLine(" on iq.se_max_sgrp = se.f_sgrp ")
.AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
.AppendLine(" on iq.se_test = td.f_test ")
.AppendLine(" and se.f_test = td.f_test ")
.AppendLine(" where se.f_flag = 0 ")
.AppendLine(" and td.f_test in (1104769646, 1312288843) ")
.AppendLine(" group by se.f_sgrp, ")
.AppendLine(" iq.pr_name, ")
.AppendLine(" iq.pd_name ")
.AppendLine(" order by iq.pr_name ")
.AppendLine(" for json path; ");
return result.ToString();
} // 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[]> IInfinityQSV3Repository.GetEpiProTempVerificationRows(int[] night)
{
List<string[]>? results;
List<string> eppReactorNumbers = new();
List<string> nightSiftReactors = Convert(night);
ReadOnlyDictionary<int, Reactor> eppReactors = GetReactorsMatchingType("EPP");
foreach (KeyValuePair<int, Reactor> keyValuePair in eppReactors)
eppReactorNumbers.Add($"'{keyValuePair.Key}'");
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV3Repository.GetEpiProTempVerificationRows)}.json"));
results = JsonSerializer.Deserialize<List<string[]>>(json);
if (results is null)
throw new NullReferenceException(nameof(results));
}
else
{
bool found;
results = new();
int loadedCount;
Reactor? reactor;
string loadedRDS;
int reactorNumber;
TimeSpan timeSpan;
List<string> columns;
List<int> used = new();
List<int> dayShiftOrder = new();
long ticks = DateTime.Now.Ticks;
List<int> nightShiftOrder = new();
InfinityQS1090FullLoad infinityQS1090FullLoad;
IInfinityQSV3Repository infinityQSV3Repository = this;
string commandText = infinityQSV3Repository.GetCommandText(eppReactorNumbers);
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText);
InfinityQS1090FullLoad[]? infinityQS1090FullLoads = stringBuilder.Length == 0 ? Array.Empty<InfinityQS1090FullLoad>() : JsonSerializer.Deserialize(stringBuilder.ToString(), InfinityQS1090FullLoadArraySourceGenerationContext.Default.InfinityQS1090FullLoadArray);
if (infinityQS1090FullLoads is null)
throw new NullReferenceException(nameof(infinityQS1090FullLoads));
for (int i = 0; i < infinityQS1090FullLoads.Length; i++)
{
infinityQS1090FullLoad = infinityQS1090FullLoads[i];
if (infinityQS1090FullLoad.Reactor is null)
continue;
if (!int.TryParse(infinityQS1090FullLoad.Reactor, out reactorNumber))
continue;
if (!eppReactors.TryGetValue(reactorNumber, out reactor))
continue;
if (!nightSiftReactors.Contains(infinityQS1090FullLoad.Reactor))
dayShiftOrder.Add(i);
else
nightShiftOrder.Add(i);
}
for (int i = 0; i < infinityQS1090FullLoads.Length; i++)
{
if (used.Contains(i) || !dayShiftOrder.Contains(i))
continue;
infinityQS1090FullLoad = infinityQS1090FullLoads[i];
if (infinityQS1090FullLoad.Reactor is null)
continue;
if (!int.TryParse(infinityQS1090FullLoad.Reactor, out reactorNumber))
continue;
if (!eppReactors.TryGetValue(reactorNumber, out reactor))
continue;
used.Add(i);
found = false;
timeSpan = new(ticks - infinityQS1090FullLoad.SubGroupIdFormatted.Ticks);
loadedCount = reactor.LoadedRDS is null ? 0 : reactor.LoadedRDS.Count;
loadedRDS = reactor.LoadedRDS is null ? "&nbsp;" : reactor.LoadedRDS[0].ToString();
results.Add(new string[]{
reactor.ReactorNo.ToString(),
reactor.E10State,
loadedRDS,
infinityQS1090FullLoad.Value.ToString(),
infinityQS1090FullLoad.TemperatureOffsetPercentage.ToString(),
infinityQS1090FullLoad.SubGroupIdFormatted.ToString(),
Math.Floor(timeSpan.TotalHours).ToString()
});
for (int j = i + 1; j < infinityQS1090FullLoads.Length; j++)
{
if (used.Contains(j) || !nightShiftOrder.Contains(j))
continue;
infinityQS1090FullLoad = infinityQS1090FullLoads[j];
if (infinityQS1090FullLoad.Reactor is null)
continue;
if (!int.TryParse(infinityQS1090FullLoad.Reactor, out reactorNumber))
continue;
if (!eppReactors.TryGetValue(reactorNumber, out reactor))
continue;
used.Add(j);
found = true;
timeSpan = new(ticks - infinityQS1090FullLoad.SubGroupIdFormatted.Ticks);
loadedCount = reactor.LoadedRDS is null ? 0 : reactor.LoadedRDS.Count;
loadedRDS = reactor.LoadedRDS is null ? "&nbsp;" : reactor.LoadedRDS[0].ToString();
columns = new();
columns.AddRange(results[^1]);
columns.AddRange(new string[]
{
"&nbsp;",
reactor.ReactorNo.ToString(),
reactor.E10State,
loadedRDS,
infinityQS1090FullLoad.Value.ToString(),
infinityQS1090FullLoad.TemperatureOffsetPercentage.ToString(),
infinityQS1090FullLoad.SubGroupIdFormatted.ToString(),
Math.Floor(timeSpan.TotalHours).ToString()
});
results[^1] = columns.ToArray();
break;
}
if (!found)
{
columns = new();
columns.AddRange(results[^1]);
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
results[^1] = columns.ToArray();
}
}
}
return results;
}
string IInfinityQSV3Repository.GetEpiProTempVerification(int[] night)
{
StringBuilder result = new();
IInfinityQSV3Repository infinityQSV3Repository = this;
List<string[]> collection = infinityQSV3Repository.GetEpiProTempVerificationRows(night);
foreach (string[] row in collection)
{
_ = result.Append("<tr>");
foreach (string column in row)
_ = result.Append("<td>").Append(column).Append("</td>");
_ = result.Append("</tr>");
}
return result.ToString();
}
}

View File

@ -0,0 +1,702 @@
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Repositories;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Common;
using System.Text;
using System.Text.Json;
namespace OI.Metrology.Server.Repository;
public class InfinityQSV4Repository : IInfinityQSV4Repository
{
private record Record(string? Color, string Text);
private readonly string _MockRoot;
private readonly string _RepositoryName;
private readonly AppSettings _AppSettings;
private readonly IHttpClientFactory _HttpClientFactory;
private readonly IDbConnectionFactory _DBConnectionFactory;
private readonly IFileShareRepository _FileShareRepository;
private readonly string _OpenInsightApplicationProgrammingInterface;
public InfinityQSV4Repository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository)
{
_AppSettings = appSettings;
_MockRoot = appSettings.MockRoot;
_HttpClientFactory = httpClientFactory;
_DBConnectionFactory = dbConnectionFactory;
_FileShareRepository = fileShareRepository;
_RepositoryName = nameof(InfinityQSV4Repository)[..^10];
_OpenInsightApplicationProgrammingInterface = appSettings.OpenInsightApplicationProgrammingInterface;
}
string IInfinityQSV4Repository.GetCommandText(string subGroupId)
{ // cSpell:disable
List<string> results = [];
if (string.IsNullOrEmpty(subGroupId))
throw new ArgumentException(null, nameof(subGroupId));
results.Add(" select ");
results.Add(" sd.f_sgrp sd_sgrp, ");
results.Add(" sd.f_tsno sd_tsno, ");
results.Add(" dd.f_dsgp dd_dsgp, ");
results.Add(" dg.f_name gd_name, ");
results.Add(" dd.f_name dd_name ");
results.Add(" from [SPCEPIWORLD].[dbo].[SGRP_DSC] sd ");
results.Add(" join [SPCEPIWORLD].[dbo].[DESC_DAT] dd ");
results.Add(" on sd.f_dsgp = dd.f_dsgp ");
results.Add(" and sd.f_desc = dd.f_desc ");
results.Add(" join [SPCEPIWORLD].[dbo].[DESC_GRP] dg ");
results.Add(" on dd.f_dsgp = dg.f_dsgp ");
results.Add($" where sd.f_sgrp = {subGroupId} ");
results.Add(" for json path ");
return string.Join(' ', results);
} // cSpell:enable
string IInfinityQSV4Repository.GetCommandText(string? subGroupId, string? process, string? job, string? part, string? lot, string? dateTime)
{ // cSpell:disable
List<string> results = [];
const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')) && dateTime.Length != dateTimeFormat.Length)
throw new ArgumentException(null, nameof(dateTime));
results.Add(" select case when iq.sl_loos is null then 0 else iq.sl_loos end + ");
results.Add(" case when iq.sl_uoos is null then 0 else iq.sl_uoos end + ");
results.Add(" iq.ev_count as iq_sum, ");
results.Add(" iq.sl_aflag, ");
results.Add(" iq.sl_loos, ");
results.Add(" iq.sl_uoos, ");
results.Add(" iq.se_sgrp, ");
results.Add(" iq.se_sgtm, ");
results.Add(" iq.se_tsno, ");
results.Add(" iq.td_test, ");
results.Add(" iq.pr_name, ");
results.Add(" iq.jd_name, ");
results.Add(" iq.pl_name, ");
results.Add(" iq.pd_name, ");
results.Add(" iq.td_name, ");
results.Add(" iq.se_val, ");
results.Add(" iq.sl_eflag, ");
results.Add(" iq.sl_scal, ");
results.Add(" iq.sl_sls, ");
results.Add(" iq.sl_usl ");
results.Add(" from ( ");
results.Add(" select ");
results.Add(" se.f_sgrp se_sgrp, ");
results.Add(" se.f_sgtm se_sgtm, ");
results.Add(" se.f_tsno se_tsno, ");
results.Add(" se.f_val se_val, ");
results.Add(" pr.f_name pr_name, ");
results.Add(" jd.f_name jd_name, ");
results.Add(" pl.f_name pl_name, ");
results.Add(" pd.f_name pd_name, ");
results.Add(" td.f_test td_test, ");
results.Add(" td.f_name td_name, ");
results.Add(" sl.f_eflag sl_eflag, ");
results.Add(" sl.f_aflag sl_aflag, ");
results.Add(" sl.f_scal sl_scal, ");
results.Add(" sl.f_lsl sl_sls, ");
results.Add(" sl.f_usl sl_usl, ");
results.Add(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ");
results.Add(" case when round(se.f_val, sl.F_scal, 1) < sl.f_lsl then 1 else 0 end ");
results.Add(" end as sl_loos, ");
results.Add(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ");
results.Add(" case when round(se.f_val, sl.F_scal, 1) > sl.f_usl then 1 else 0 end ");
results.Add(" end as sl_uoos, ");
results.Add(" (select count(ev.f_evnt) ");
results.Add(" from [spcepiworld].[dbo].[evnt_inf] ev ");
results.Add(" where ev.f_prcs = pr.f_prcs ");
results.Add(" and ev.f_part = pd.f_part ");
results.Add(" and ev.f_sgtm = se.f_sgtm ");
results.Add(" ) ev_count ");
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].[job_dat] jd ");
results.Add(" on se.f_job = jd.f_job ");
results.Add(" join [spcepiworld].[dbo].[part_lot] pl ");
results.Add(" on se.f_lot = pl.f_lot ");
results.Add(" join [spcepiworld].[dbo].[part_dat] pd ");
results.Add(" on se.f_part = pd.f_part ");
results.Add(" join [spcepiworld].[dbo].[test_dat] td ");
results.Add(" on se.f_test = td.f_test ");
results.Add(" left join [spcepiworld].[dbo].[spec_lim] sl ");
results.Add(" on se.f_part = sl.f_part ");
results.Add(" and se.f_test = sl.f_test ");
results.Add(" where se.f_flag = 0 ");
results.Add(" and (sl.f_prcs is null or se.f_prcs = sl.f_prcs or sl.f_prcs = 0) ");
if (!string.IsNullOrEmpty(subGroupId))
results.Add($" and se.f_sgrp = {subGroupId.Split(" ")[0]} ");
if (!string.IsNullOrEmpty(process))
results.Add($" and pr.f_name = '{process}' ");
if (!string.IsNullOrEmpty(part))
results.Add($" and pd.f_name = '{part}' ");
if (!string.IsNullOrEmpty(job))
results.Add($" and jd.f_name = '{job}' ");
if (!string.IsNullOrEmpty(lot))
results.Add($" and pl.f_name = '{lot}' ");
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}' ");
results.Add(" ) as iq ");
results.Add(" order by iq.sl_loos + iq.sl_uoos + iq.ev_count desc, ");
results.Add(" iq.sl_aflag desc, ");
results.Add(" iq.se_sgrp, ");
results.Add(" iq.se_tsno, ");
results.Add(" iq.td_test ");
results.Add(" for json path ");
return string.Join(' ', results);
} // 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)
{
StringBuilder stringBuilder = new();
File.WriteAllText("../../.sql", commandText);
using DbConnection dbConnection = dbConnectionFactory.GetDbConnection(useIqsConnection);
DbCommand dbCommand = dbConnection.CreateCommand();
dbCommand.CommandText = commandText;
DbDataReader dbDataReader = dbCommand.ExecuteReader(CommandBehavior.SequentialAccess);
while (dbDataReader.Read())
_ = stringBuilder.Append(dbDataReader.GetString(0));
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)
{
InfinityQSV4 result;
string commandText = infinityQSV4Repository.GetCommandText(subGroupId, process: string.Empty, job: string.Empty, part: string.Empty, lot: string.Empty, dateTime: string.Empty);
StringBuilder stringBuilder = GetForJsonPath(dbConnectionFactory, commandText, useIqsConnection: false);
InfinityQSV4[]? results = stringBuilder.Length == 0 ? Array.Empty<InfinityQSV4>() : JsonSerializer.Deserialize(stringBuilder.ToString(), ResultInfinityQSV4SourceGenerationContext.Default.InfinityQSV4Array); // , new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
if (results is null)
throw new NullReferenceException(nameof(results));
result = results.First();
return result;
}
Result<InfinityQSV4[]> IInfinityQSV4Repository.GetData(string subGroupId)
{
Result<InfinityQSV4[]>? result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV4Repository.GetData)}.json"));
result = JsonSerializer.Deserialize(json, ResultInfinityQSV4SourceGenerationContext.Default.ResultInfinityQSV4Array);
if (result is null)
throw new NullReferenceException(nameof(result));
}
else
{
IInfinityQSV4Repository infinityQSV4Repository = this;
InfinityQSV4 infinityQSV4 = GetInfinityQSV4(_DBConnectionFactory, infinityQSV4Repository, subGroupId);
GetOI(infinityQSV4);
string commandText = infinityQSV4Repository.GetCommandText(subGroupId, process: infinityQSV4.Process, job: infinityQSV4.Job, part: infinityQSV4.Part, lot: infinityQSV4.Lot, dateTime: string.Concat(infinityQSV4.SubGroupDateTime));
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText, useIqsConnection: false);
InfinityQSV4[]? results = stringBuilder.Length == 0 ? Array.Empty<InfinityQSV4>() : JsonSerializer.Deserialize(stringBuilder.ToString(), ResultInfinityQSV4SourceGenerationContext.Default.InfinityQSV4Array); // , new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
if (results is null)
throw new NullReferenceException(nameof(results));
result = new()
{
Results = results,
TotalRows = results.Length,
};
}
return result;
}
Result<InfinityQSDescriptorV4[]> IInfinityQSV4Repository.GetDescriptors(string subGroupId)
{
Result<InfinityQSDescriptorV4[]>? result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV4Repository.GetDescriptors)}.json"));
result = JsonSerializer.Deserialize(json, ResultInfinityQSDescriptorV4SourceGenerationContext.Default.ResultInfinityQSDescriptorV4Array);
if (result is null)
throw new NullReferenceException(nameof(result));
}
else
{
IInfinityQSV4Repository infinityQSV4Repository = this;
string commandText = infinityQSV4Repository.GetCommandText(subGroupId);
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText, useIqsConnection: false);
InfinityQSDescriptorV4[]? results = stringBuilder.Length == 0 ? Array.Empty<InfinityQSDescriptorV4>() : JsonSerializer.Deserialize(stringBuilder.ToString(), ResultInfinityQSDescriptorV4SourceGenerationContext.Default.InfinityQSDescriptorV4Array); // , new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
if (results is null)
throw new NullReferenceException(nameof(results));
result = new()
{
Results = results,
TotalRows = results.Length,
};
}
return result;
}
string IInfinityQSV4Repository.GetCommandText(InfinityQSV4 infinityQSV4)
{ // cSpell:disable
List<string> results = [];
if (string.IsNullOrEmpty(infinityQSV4.Process))
throw new ArgumentException(nameof(infinityQSV4.Process));
if (string.IsNullOrEmpty(infinityQSV4.Part))
throw new ArgumentException(nameof(infinityQSV4.Part));
results.Add(" select ");
results.Add(" ev.f_evnt [ev_evnt], ");
results.Add(" ev.f_sgtm [ev_sgtm], ");
results.Add(" dateadd(HH, -7, (dateadd(SS, convert(bigint, ev.f_sgtm), '19700101'))) [ev_utc7], ");
results.Add(" pr.f_name [pr_name], ");
results.Add(" pd.f_name [pd_name], ");
results.Add(" td.f_test [td_test], ");
results.Add(" td.f_name [td_name], ");
results.Add(" ev.f_name [ev_name] ");
results.Add(" from [spcepiworld].[dbo].[evnt_inf] ev ");
results.Add(" join [spcepiworld].[dbo].[prcs_dat] pr ");
results.Add(" on ev.f_prcs = pr.f_prcs ");
results.Add(" join [spcepiworld].[dbo].[part_dat] pd ");
results.Add(" on ev.f_part = pd.f_part ");
results.Add(" join [spcepiworld].[dbo].[test_dat] td ");
results.Add(" on ev.f_test = td.f_test ");
results.Add($" where pr.f_name = '{infinityQSV4.Process}' ");
results.Add($" and pd.f_name = '{infinityQSV4.Part}' ");
results.Add($" and ev.f_sgtm = {infinityQSV4.SubGroupDateTime} ");
results.Add(" for json path ");
return string.Join(' ', results);
} // cSpell:enable
Result<InfinityQSV4[]> IInfinityQSV4Repository.GetHeader(string subGroupId)
{
Result<InfinityQSV4[]>? result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV4Repository.GetHeader)}.json"));
result = JsonSerializer.Deserialize(json, ResultInfinityQSV4SourceGenerationContext.Default.ResultInfinityQSV4Array);
if (result is null)
throw new NullReferenceException(nameof(result));
}
else
{
IInfinityQSV4Repository infinityQSV4Repository = this;
InfinityQSV4 infinityQSV4 = GetInfinityQSV4(_DBConnectionFactory, infinityQSV4Repository, subGroupId);
InfinityQSV4[] results = new InfinityQSV4[] { infinityQSV4 };
result = new()
{
Results = results,
TotalRows = results.Length,
};
}
return result;
}
string IInfinityQSV4Repository.GetCommandText(string process, string? part)
{ // 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));
results.Add(" select [f_mean] as ProcessMean, ");
results.Add(" [f_sp] as ProcessSigma ");
results.Add(" from [spcepiworld].[dbo].[test_dat] test ");
results.Add(" join [spcepiworld].[dbo].[ctrl_lim] ctrl ");
results.Add(" on test.f_test = ctrl.f_test ");
results.Add(" and test.f_tsgp = 1104848523 /* Product Data */ ");
results.Add(" join [spcepiworld].[dbo].[part_dat] part ");
results.Add(" on part.f_part = ctrl.f_part ");
results.Add(" and ctrl.f_test = 1125073605 /* Average Sum of Defects */ ");
results.Add(" join [spcepiworld].[dbo].[prcs_dat] process ");
results.Add(" on process.f_prcs = ctrl.f_prcs ");
results.Add(" where test.f_name = 'Average Sum of Defects' ");
results.Add($" and process.f_name = '{process}' ");
results.Add($" and part.f_name = '{part}' ");
results.Add(" for json path; ");
return string.Join(' ', results);
} // cSpell:enable
string IInfinityQSV4Repository.GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(string process, string? recipe)
{
StringBuilder result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV4Repository.GetProductDataAverageSumOfDefectsProcessMeanProcessSigma)}.json"));
result = new(json);
}
else
{
IInfinityQSV4Repository infinityQSV4Repository = this;
string commandText = infinityQSV4Repository.GetCommandText(process, recipe);
result = GetForJsonPath(_DBConnectionFactory, commandText, useIqsConnection: false);
if (result.Length == 0)
result = new("{}");
}
return result.ToString();
}
string IInfinityQSV4Repository.GetCommandText(List<string> eppReactorNumbers)
{ // cSpell:disable
List<string> results = [];
results.Add(" select se.f_sgrp, ");
results.Add(" dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgrp), '19700101'))) date_time, ");
results.Add(" iq.pr_name, ");
results.Add(" iq.pd_name, ");
results.Add(" max(case ");
results.Add(" when td.f_test = 1104769646 ");
results.Add(" then se.f_val ");
results.Add(" else null ");
results.Add(" end) as iq_value, ");
results.Add(" max(case ");
results.Add(" when td.f_test = 1312288843 ");
results.Add(" then se.f_val else null ");
results.Add(" end) as iq_temp_offset_percent ");
results.Add(" from ( ");
results.Add(" select ");
results.Add(" max(se.f_sgrp) se_max_sgrp, ");
results.Add(" se.f_test se_test, ");
results.Add(" pr.f_name pr_name, ");
results.Add(" pd.f_name pd_name ");
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 pr.f_name in ({string.Join(',', eppReactorNumbers)}) ");
results.Add(" and pd.f_name = '1090 - Full Load' ");
results.Add(" and se.f_test in (1104769646, 1312288843) ");
results.Add(" group by se.f_test, ");
results.Add(" pr.f_name, ");
results.Add(" pd.f_name ");
results.Add(" ) as iq ");
results.Add(" join [spcepiworld].[dbo].[sgrp_ext] se ");
results.Add(" on iq.se_max_sgrp = se.f_sgrp ");
results.Add(" join [spcepiworld].[dbo].[test_dat] td ");
results.Add(" on iq.se_test = td.f_test ");
results.Add(" and se.f_test = td.f_test ");
results.Add(" where se.f_flag = 0 ");
results.Add(" and td.f_test in (1104769646, 1312288843) ");
results.Add(" group by se.f_sgrp, ");
results.Add(" iq.pr_name, ");
results.Add(" iq.pd_name ");
results.Add(" order by iq.pr_name ");
results.Add(" for json path; ");
return string.Join(' ', results);
} // cSpell:enable
List<string[]> IInfinityQSV4Repository.GetEpiProTempVerificationRows(int[] night)
{
List<string[]>? results;
List<string> eppReactorNumbers = new();
List<string> nightSiftReactors = Convert(night);
ReadOnlyDictionary<int, Reactor> eppReactors = GetReactorsMatchingType("EPP");
foreach (KeyValuePair<int, Reactor> keyValuePair in eppReactors)
eppReactorNumbers.Add($"'{keyValuePair.Key}'");
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV4Repository.GetEpiProTempVerificationRows)}.json"));
results = JsonSerializer.Deserialize<List<string[]>>(json);
if (results is null)
throw new NullReferenceException(nameof(results));
}
else
{
bool found;
results = new();
int loadedCount;
Reactor? reactor;
string loadedRDS;
int reactorNumber;
TimeSpan timeSpan;
List<string> columns;
List<int> used = new();
List<int> dayShiftOrder = new();
long ticks = DateTime.Now.Ticks;
List<int> nightShiftOrder = new();
InfinityQS1090FullLoad infinityQS1090FullLoad;
IInfinityQSV4Repository infinityQSV4Repository = this;
string commandText = infinityQSV4Repository.GetCommandText(eppReactorNumbers);
StringBuilder stringBuilder = GetForJsonPath(_DBConnectionFactory, commandText, useIqsConnection: false);
InfinityQS1090FullLoad[]? infinityQS1090FullLoads = stringBuilder.Length == 0 ? Array.Empty<InfinityQS1090FullLoad>() : JsonSerializer.Deserialize(stringBuilder.ToString(), InfinityQS1090FullLoadArraySourceGenerationContext.Default.InfinityQS1090FullLoadArray);
if (infinityQS1090FullLoads is null)
throw new NullReferenceException(nameof(infinityQS1090FullLoads));
for (int i = 0; i < infinityQS1090FullLoads.Length; i++)
{
infinityQS1090FullLoad = infinityQS1090FullLoads[i];
if (infinityQS1090FullLoad.Reactor is null)
continue;
if (!int.TryParse(infinityQS1090FullLoad.Reactor, out reactorNumber))
continue;
if (!eppReactors.TryGetValue(reactorNumber, out reactor))
continue;
if (!nightSiftReactors.Contains(infinityQS1090FullLoad.Reactor))
dayShiftOrder.Add(i);
else
nightShiftOrder.Add(i);
}
for (int i = 0; i < infinityQS1090FullLoads.Length; i++)
{
if (used.Contains(i) || !dayShiftOrder.Contains(i))
continue;
infinityQS1090FullLoad = infinityQS1090FullLoads[i];
if (infinityQS1090FullLoad.Reactor is null)
continue;
if (!int.TryParse(infinityQS1090FullLoad.Reactor, out reactorNumber))
continue;
if (!eppReactors.TryGetValue(reactorNumber, out reactor))
continue;
used.Add(i);
found = false;
timeSpan = new(ticks - infinityQS1090FullLoad.SubGroupIdFormatted.Ticks);
loadedCount = reactor.LoadedRDS is null ? 0 : reactor.LoadedRDS.Count;
loadedRDS = reactor.LoadedRDS is null ? "&nbsp;" : reactor.LoadedRDS[0].ToString();
results.Add(new string[]{
reactor.ReactorNo.ToString(),
reactor.E10State,
loadedRDS,
infinityQS1090FullLoad.Value.ToString(),
infinityQS1090FullLoad.TemperatureOffsetPercentage.ToString(),
infinityQS1090FullLoad.SubGroupIdFormatted.ToString(),
Math.Floor(timeSpan.TotalHours).ToString()
});
for (int j = i + 1; j < infinityQS1090FullLoads.Length; j++)
{
if (used.Contains(j) || !nightShiftOrder.Contains(j))
continue;
infinityQS1090FullLoad = infinityQS1090FullLoads[j];
if (infinityQS1090FullLoad.Reactor is null)
continue;
if (!int.TryParse(infinityQS1090FullLoad.Reactor, out reactorNumber))
continue;
if (!eppReactors.TryGetValue(reactorNumber, out reactor))
continue;
used.Add(j);
found = true;
timeSpan = new(ticks - infinityQS1090FullLoad.SubGroupIdFormatted.Ticks);
loadedCount = reactor.LoadedRDS is null ? 0 : reactor.LoadedRDS.Count;
loadedRDS = reactor.LoadedRDS is null ? "&nbsp;" : reactor.LoadedRDS[0].ToString();
columns = new();
columns.AddRange(results[^1]);
columns.AddRange(new string[]
{
"&nbsp;",
reactor.ReactorNo.ToString(),
reactor.E10State,
loadedRDS,
infinityQS1090FullLoad.Value.ToString(),
infinityQS1090FullLoad.TemperatureOffsetPercentage.ToString(),
infinityQS1090FullLoad.SubGroupIdFormatted.ToString(),
Math.Floor(timeSpan.TotalHours).ToString()
});
results[^1] = columns.ToArray();
break;
}
if (!found)
{
columns = new();
columns.AddRange(results[^1]);
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
columns.Add("&nbsp;");
results[^1] = columns.ToArray();
}
}
}
return results;
}
string IInfinityQSV4Repository.GetEpiProTempVerification(int[] night)
{
StringBuilder result = new();
IInfinityQSV4Repository infinityQSV4Repository = this;
List<string[]> collection = infinityQSV4Repository.GetEpiProTempVerificationRows(night);
foreach (string[] row in collection)
{
_ = result.Append("<tr>");
foreach (string column in row)
_ = result.Append("<td>").Append(column).Append("</td>");
_ = result.Append("</tr>");
}
return result.ToString();
}
List<Reactor> IInfinityQSV4Repository.GetReactors()
{
List<Reactor> results = new();
ReadOnlyDictionary<int, Reactor> keyValuePairs = GetReactorsMatchingType(reactTypeFilter: null);
foreach (KeyValuePair<int, Reactor> keyValuePair in keyValuePairs)
results.Add(keyValuePair.Value);
return results;
}
string IInfinityQSV4Repository.GetRunDataSheet(string rds)
{
string result;
HttpClient httpClient = _HttpClientFactory.CreateClient();
Task<string> task = httpClient.GetStringAsync($"{_OpenInsightApplicationProgrammingInterface}/materials/rds/{rds}");
task.Wait();
result = task.Result;
if (rds == "123456")
{
RunDataSheetRoot? runDataSheetRoot = JsonSerializer.Deserialize(result, RunDataSheetRootSourceGenerationContext.Default.RunDataSheetRoot);
if (runDataSheetRoot is not null)
{
List<string> lines = new();
foreach (char ch in runDataSheetRoot.RunDataSheet.PSN)
{
if (ch is '1')
continue;
}
result = string.Join(Environment.NewLine, lines);
}
}
return result;
}
string IInfinityQSV4Repository.GetProductionSpecification(string part)
{
string result;
HttpClient httpClient = _HttpClientFactory.CreateClient();
Task<string> task = httpClient.GetStringAsync($"{_OpenInsightApplicationProgrammingInterface}/materials/prod_spec/{part}");
task.Wait();
result = task.Result;
if (part == "4992")
{
ProdSpecRoot? prodSpecRoot = JsonSerializer.Deserialize(result, ProdSpecRootSourceGenerationContext.Default.ProdSpecRoot);
if (prodSpecRoot is not null)
{
List<string> lines = new();
foreach (PrsStage prsStage in prodSpecRoot.ProdSpec.PrsStages)
{
if (prsStage.QaMetTests is null)
continue;
foreach (QaMetTest qaMetTest in prsStage.QaMetTests)
{
lines.Add(qaMetTest.Test);
// lines.Add(qaMetTest.Slots);
lines.Add(qaMetTest.Recipe);
lines.Add(qaMetTest.RecipePattern);
if (qaMetTest.Test != "THICK_ONLY")
continue;
lines.Add(qaMetTest.Min.ToString());
lines.Add(qaMetTest.Max.ToString());
}
}
result = string.Join(Environment.NewLine, lines);
}
}
return result;
}
private static string GetCommandText(string process, string? part, int? test)
{ // 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;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV4Repository.GetLastGroupIdWithValue)}.json"));
result = new(json);
}
else
{
string commandText = GetCommandText(process, part, test);
result = GetForJsonPath(_DBConnectionFactory, commandText, useIqsConnection: false);
if (result.Length == 0)
result = new("{}");
}
return result.ToString();
}
}

View File

@ -16,6 +16,7 @@ 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;
@ -32,7 +33,8 @@ 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() => new(); internal static TransactionScope StartTransaction() =>
new();
protected void CacheItem(string key, object v) protected void CacheItem(string key, object v)
{ {
@ -56,7 +58,7 @@ public class MetrologyRepository : IMetrologyRepository
return r; return r;
} }
internal ToolType GetToolTypeByName(string name) ToolType IMetrologyRepository.GetToolTypeByName(string name)
{ {
ToolType cached; ToolType cached;
string cacheKey = "GetToolTypeByName_" + name; string cacheKey = "GetToolTypeByName_" + name;
@ -107,7 +109,7 @@ public class MetrologyRepository : IMetrologyRepository
return r; return r;
} }
internal long InsertToolDataJSON(JToken jsonrow, long headerId, List<ToolTypeMetadata> metaData, string tableName) long IMetrologyRepository.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())
@ -115,7 +117,8 @@ 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 => md.Header == isHeader).ToList(); List<ToolTypeMetadata> fields = metaData.Where(md =>
md.Header == isHeader).ToList();
// maps ApiName to ColumnName // maps ApiName to ColumnName
Dictionary<string, string> fieldmap = new(); Dictionary<string, string> fieldmap = new();
@ -155,7 +158,8 @@ 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 => string.Equals(c.Name.Trim(), containerField, StringComparison.OrdinalIgnoreCase)).SingleOrDefault(); JProperty contJP = jsonrow.Children<JProperty>().Where(c =>
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))
{ {
@ -182,7 +186,7 @@ public class MetrologyRepository : IMetrologyRepository
_ = cmd.Parameters.Add(p); _ = cmd.Parameters.Add(p);
} }
protected long InsertRowFromJSON( private long InsertRowFromJSON(
IDbConnection conn, IDbConnection conn,
string tableName, string tableName,
JToken jsonrow, JToken jsonrow,
@ -262,7 +266,7 @@ public class MetrologyRepository : IMetrologyRepository
return Convert.ToInt64(o); return Convert.ToInt64(o);
} }
internal DataTable ExportData(string spName, DateTime startTime, DateTime endTime) DataTable IMetrologyRepository.ExportData(string spName, DateTime startTime, DateTime endTime)
{ {
DataTable dt = new(); DataTable dt = new();
DateTime endTimeLocal = endTime.ToLocalTime(); DateTime endTimeLocal = endTime.ToLocalTime();
@ -312,15 +316,11 @@ public class MetrologyRepository : IMetrologyRepository
return sb.ToString(); return sb.ToString();
} }
internal DataTable GetHeaders(int toolTypeId, DateTime? startTime, DateTime? endTime, int? pageNo, int? pageSize, long? headerId, out long totalRecords) DataTable IMetrologyRepository.GetHeaders(int toolTypeId, string? startTime, string? endTime, int? pageNo, int? pageSize, long? headerId, out long totalRecords)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId); IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
if (md is null)
throw new Exception("Invalid tool type metadata");
DataTable dt = new(); DataTable dt = new();
using (DbConnection conn = _DBConnectionFactory.GetDbConnection()) using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
@ -328,7 +328,8 @@ public class MetrologyRepository : IMetrologyRepository
StringBuilder sb = new(); StringBuilder sb = new();
_ = sb.Append( _ = sb.Append(
FormDynamicSelectQuery( FormDynamicSelectQuery(
md.Where(m => m.Header == true).ToList(), md.Where(m =>
m.Header == true).ToList(),
tt.HeaderTableName) tt.HeaderTableName)
); );
@ -345,16 +346,16 @@ public class MetrologyRepository : IMetrologyRepository
} }
else else
{ {
if (startTime.HasValue) if (startTime is not null)
{ {
whereClause = "[Date] >= @StartTime "; whereClause = "[Date] >= @StartTime ";
DateTime startTimeLocal = startTime.Value.ToLocalTime(); DateTime startTimeLocal = DateTime.Parse(startTime).ToLocalTime();
AddParameter(cmd, "@StartTime", startTimeLocal); AddParameter(cmd, "@StartTime", startTimeLocal.ToString("yyyy-MM-dd HH:mm:ss"));
} }
if (endTime.HasValue) if (endTime is not null)
{ {
DateTime endTimeLocal = endTime.Value.ToLocalTime(); DateTime endTimeLocal = DateTime.Parse(endTime).ToLocalTime();
TimeSpan timeSpan = new(DateTime.Now.Ticks - endTimeLocal.Ticks); TimeSpan timeSpan = new(DateTime.Now.Ticks - endTimeLocal.Ticks);
if (timeSpan.TotalMinutes > 5) if (timeSpan.TotalMinutes > 5)
{ {
@ -362,7 +363,7 @@ public class MetrologyRepository : IMetrologyRepository
whereClause += "AND "; whereClause += "AND ";
whereClause += "[Date] <= @EndTime "; whereClause += "[Date] <= @EndTime ";
AddParameter(cmd, "@EndTime", endTimeLocal); AddParameter(cmd, "@EndTime", endTimeLocal.ToString("yyyy-MM-dd HH:mm:ss"));
} }
} }
} }
@ -405,15 +406,11 @@ public class MetrologyRepository : IMetrologyRepository
return dt; return dt;
} }
internal DataTable GetData(int toolTypeId, long headerid) DataTable IMetrologyRepository.GetData(int toolTypeId, long headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId); IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
if (md is null)
throw new Exception("Invalid tool type metadata");
DataTable dt = new(); DataTable dt = new();
using (DbConnection conn = _DBConnectionFactory.GetDbConnection()) using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
@ -421,7 +418,9 @@ public class MetrologyRepository : IMetrologyRepository
StringBuilder sb = new(); StringBuilder sb = new();
_ = sb.Append( _ = sb.Append(
FormDynamicSelectQuery( FormDynamicSelectQuery(
md.Where(m => m.Header == false).OrderBy(m => m.GridDisplayOrder).ToList(), md.Where(m =>
m.Header == false).OrderBy(m =>
m.GridDisplayOrder).ToList(),
tt.DataTableName) tt.DataTableName)
); );
@ -500,30 +499,42 @@ public class MetrologyRepository : IMetrologyRepository
return dt; return dt;
} }
internal Guid GetHeaderAttachmentID(int toolTypeId, long headerId) Guid IMetrologyRepository.GetHeaderAttachmentID(int toolTypeId, long headerId)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); Guid result;
if (tt is null) ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
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 = NEWID() WHERE ID = @HeaderID AND AttachmentID IS NULL; " +
$"SELECT AttachmentID FROM [{tt.HeaderTableName}] WHERE ID = @HeaderID"; $"SELECT AttachmentID FROM [{tt.HeaderTableName}] WHERE ID = @HeaderID";
return conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId }); result = conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId });
return result;
} }
internal string GetHeaderInsertDate(int toolTypeId, long headerId)
void IMetrologyRepository.SetHeaderAttachmentID(int toolTypeId, long headerId, string attachmentId)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID"); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
$"UPDATE [{tt.HeaderTableName}] SET AttachmentID = @AttachmentID WHERE ID = @HeaderID AND AttachmentID IS NULL; " +
$"SELECT AttachmentID FROM [{tt.HeaderTableName}] WHERE ID = @HeaderID";
Guid guid = conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId, AttachmentID = attachmentId });
if (attachmentId != guid.ToString())
throw new NotSupportedException($"{attachmentId} != {guid}");
}
string IMetrologyRepository.GetHeaderInsertDate(int toolTypeId, long headerId)
{
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 =
$"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 = "";
@ -538,30 +549,29 @@ 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 });
} }
internal Guid GetDataAttachmentID(int toolTypeId, long headerId, string title) void IMetrologyRepository.SetDataAttachmentID(int toolTypeId, long headerId, string title, string attachmentId)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
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 = NEWID() WHERE HeaderID = @HeaderID AND Title = @Title AND AttachmentID IS NULL; " + $"UPDATE [{tt.DataTableName}] SET AttachmentID = @AttachmentID 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";
return conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId, Title = title }); Guid guid = conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId, AttachmentID = attachmentId, Title = title });
if (attachmentId != guid.ToString())
throw new NotSupportedException($"{attachmentId} != {guid}");
} }
// J Ouellette Added
internal string GetDataInsertDate(int toolTypeId, long headerId, string title) string IMetrologyRepository.GetDataInsertDate(int toolTypeId, long headerId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = ""; string sql = "";
@ -576,7 +586,8 @@ 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 =
@ -584,17 +595,15 @@ 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 });
} }
internal void PurgeExistingData(int toolTypeId, string title) void IMetrologyRepository.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);
} }
internal DataSet GetOIExportData(int toolTypeId, long headerid) DataSet IMetrologyRepository.GetOIExportData(int toolTypeId, long headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
if (string.IsNullOrWhiteSpace(tt.OIExportSPName)) if (string.IsNullOrWhiteSpace(tt.OIExportSPName))
throw new Exception("OpenInsight export not available for " + tt.ToolTypeName); throw new Exception("OpenInsight export not available for " + tt.ToolTypeName);
@ -624,7 +633,7 @@ public class MetrologyRepository : IMetrologyRepository
IEnumerable<HeaderCommon> results; IEnumerable<HeaderCommon> results;
ToolType[] toolTypes = GetToolTypes().ToArray(); ToolType[] toolTypes = GetToolTypes().ToArray();
if (!toolTypes.Any() || toolTypes.FirstOrDefault() is null) if (toolTypes.Length == 0 || toolTypes.FirstOrDefault() is null)
throw new Exception("Invalid tool type ID"); throw new Exception("Invalid tool type ID");
ToolType tt; ToolType tt;
@ -644,7 +653,7 @@ public class MetrologyRepository : IMetrologyRepository
return results.ToArray(); return results.ToArray();
} }
internal HeaderCommon[] GetHeaderTitles(int? toolTypeId, int? pageNo, int? pageSize, out long totalRecords) HeaderCommon[] IMetrologyRepository.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))
@ -657,9 +666,7 @@ public class MetrologyRepository : IMetrologyRepository
return headers; return headers;
} }
ToolType tt = GetToolTypeByID(toolTypeId.Value); ToolType tt = GetToolTypeByID(toolTypeId.Value) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = $"SELECT ID, InsertDate, AttachmentID, Title, [Date], {tt.ID} AS ToolTypeID, '{tt.ToolTypeName}' AS ToolTypeName, Reactor, RDS, PSN FROM {tt.HeaderTableName} ORDER BY [Date] DESC "; string sql = $"SELECT ID, InsertDate, AttachmentID, Title, [Date], {tt.ID} AS ToolTypeID, '{tt.ToolTypeName}' AS ToolTypeName, Reactor, RDS, PSN FROM {tt.HeaderTableName} ORDER BY [Date] DESC ";
@ -682,15 +689,11 @@ public class MetrologyRepository : IMetrologyRepository
return headers; return headers;
} }
internal IEnumerable<KeyValuePair<string, string>> GetHeaderFields(int toolTypeId, long headerid) IEnumerable<KeyValuePair<string, string>> IMetrologyRepository.GetHeaderFields(int toolTypeId, long headerid)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId); IEnumerable<ToolTypeMetadata> md = GetToolTypeMetadataByToolTypeID(toolTypeId) ?? throw new Exception("Invalid tool type metadata");
if (md is null)
throw new Exception("Invalid tool type metadata");
List<KeyValuePair<string, string>> r = new(); List<KeyValuePair<string, string>> r = new();
@ -713,7 +716,9 @@ 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 => m.Header == true && m.TableDisplayOrder > 0).OrderBy(m => m.TableDisplayOrder)) foreach (ToolTypeMetadata m in md.Where(m =>
m.Header == true && m.TableDisplayOrder > 0).OrderBy(m =>
m.TableDisplayOrder))
{ {
string v = ""; string v = "";
if (dr is not null) if (dr is not null)
@ -729,7 +734,7 @@ public class MetrologyRepository : IMetrologyRepository
return r; return r;
} }
internal IEnumerable<AwaitingDisposition> GetAwaitingDisposition() IEnumerable<AwaitingDisposition> IMetrologyRepository.GetAwaitingDisposition()
{ {
IEnumerable<AwaitingDisposition>? r; IEnumerable<AwaitingDisposition>? r;
if (!string.IsNullOrEmpty(_MockRoot)) if (!string.IsNullOrEmpty(_MockRoot))
@ -747,11 +752,9 @@ public class MetrologyRepository : IMetrologyRepository
return r; return r;
} }
internal int UpdateReviewDate(int toolTypeId, long headerId, bool clearDate) int IMetrologyRepository.UpdateReviewDate(int toolTypeId, long headerId, bool clearDate)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
if (clearDate) if (clearDate)
@ -769,11 +772,9 @@ public class MetrologyRepository : IMetrologyRepository
} }
} }
internal Guid GetHeaderAttachmentIDByTitle(int toolTypeId, string title) Guid IMetrologyRepository.GetHeaderAttachmentIDByTitle(int toolTypeId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = string sql =
@ -781,11 +782,9 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<Guid>(sql, param: new { Title = title }); return conn.ExecuteScalar<Guid>(sql, param: new { Title = title });
} }
internal Guid GetDataAttachmentIDByTitle(int toolTypeId, string title) Guid IMetrologyRepository.GetDataAttachmentIDByTitle(int toolTypeId, string title)
{ {
ToolType tt = GetToolTypeByID(toolTypeId); ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
if (tt is null)
throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection(); using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = string sql =
@ -793,31 +792,13 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<Guid>(sql, param: new { Title = title }); return conn.ExecuteScalar<Guid>(sql, param: new { Title = title });
} }
DataTable IMetrologyRepository.GetDataSharePoint(int toolTypeId, string headerId) => throw new NotImplementedException(); IEnumerable<ToolType> IMetrologyRepository.GetToolTypes() =>
GetToolTypes();
IEnumerable<ToolType> IMetrologyRepository.GetToolTypes() => GetToolTypes(); ToolType IMetrologyRepository.GetToolTypeByID(int id) =>
ToolType IMetrologyRepository.GetToolTypeByName(string name) => GetToolTypeByName(name); GetToolTypeByID(id);
ToolType IMetrologyRepository.GetToolTypeByID(int id) => GetToolTypeByID(id); TransactionScope IMetrologyRepository.StartTransaction() =>
IEnumerable<ToolTypeMetadata> IMetrologyRepository.GetToolTypeMetadataByToolTypeID(int id) => GetToolTypeMetadataByToolTypeID(id); StartTransaction();
TransactionScope IMetrologyRepository.StartTransaction() => StartTransaction(); IEnumerable<ToolTypeMetadata> IMetrologyRepository.GetToolTypeMetadataByToolTypeID(int id) =>
void IMetrologyRepository.PurgeExistingData(int toolTypeId, string title) => PurgeExistingData(toolTypeId, title); GetToolTypeMetadataByToolTypeID(id);
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, DateTime? startTime, DateTime? 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,85 @@
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Repositories;
using System.Data;
using System.Data.Common;
using System.Text;
#pragma warning disable CS8600, CS8602, CS8603, CS8604, CS8625
namespace OI.Metrology.Server.Repositories;
public class OpenInsightV1Repository : IOpenInsightV1Repository
{
private readonly string _MockRoot;
private readonly string _RepositoryName;
private readonly IDbConnectionFactory _DBConnectionFactory;
public OpenInsightV1Repository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory)
{
_MockRoot = appSettings.MockRoot;
_DBConnectionFactory = dbConnectionFactory;
_RepositoryName = nameof(OpenInsightV1Repository)[..^10];
}
string IOpenInsightV1Repository.GetCommandText(string rds, string? insertDate, string? recipe)
{
StringBuilder result = new();
if (string.IsNullOrEmpty(rds))
throw new ArgumentException(null, nameof(rds));
if (string.IsNullOrEmpty(insertDate))
throw new ArgumentException(null, nameof(insertDate));
if (string.IsNullOrEmpty(recipe))
throw new ArgumentException(null, nameof(recipe));
_ = result
.AppendLine(" select header.RDS, ")
.AppendLine(" child.AttachmentId, ")
.AppendLine(" child.Slot, ")
.AppendLine(" child.SumOfDefects, ")
.AppendLine(" child.Sort, ")
.AppendLine(" child.InsertDate ")
.AppendLine(" from metrology.dbo.tencorRunHeader header ")
.AppendLine(" inner join metrology.dbo.TencorRunData child ")
.AppendLine(" on header.id = child.headerId ")
.Append(" where header.rds = '").Append(rds).AppendLine("' ")
.Append(" and header.recipe like '").Append(recipe).AppendLine("%' ")
.Append(" and child.insertdate between (select(dateadd(minute, -5, '").Append(insertDate).AppendLine("'))) ")
.Append(" and (select(dateadd(minute, 5, '").Append(insertDate).AppendLine("'))) ")
.AppendLine(" order by header.insertdate desc, ")
.AppendLine(" child.slot asc ")
.AppendLine(" for json path; ");
return result.ToString();
}
private static StringBuilder GetForJsonPath(IDbConnectionFactory dbConnectionFactory, string commandText)
{
StringBuilder stringBuilder = new();
using DbConnection dbConnection = dbConnectionFactory.GetDbConnection();
DbCommand dbCommand = dbConnection.CreateCommand();
dbCommand.CommandText = commandText;
DbDataReader dbDataReader = dbCommand.ExecuteReader(CommandBehavior.SequentialAccess);
while (dbDataReader.Read())
_ = stringBuilder.Append(dbDataReader.GetString(0));
return stringBuilder;
}
string IOpenInsightV1Repository.GetTencorRun(string rds, string? insertDate, string? recipe)
{
StringBuilder result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IOpenInsightV1Repository.GetTencorRun)}.json"));
result = new(json);
}
else
{
IOpenInsightV1Repository openInsightRepository = this;
string commandText = openInsightRepository.GetCommandText(rds, insertDate, recipe);
result = GetForJsonPath(_DBConnectionFactory, commandText);
if (result.Length == 0)
result = new("{}");
}
return result.ToString();
}
}

View File

@ -1,3 +1,4 @@
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels; using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using System.Text.Json; using System.Text.Json;
@ -8,16 +9,14 @@ public class PinRepository : IPinRepository
{ {
private readonly string _MockRoot; private readonly string _MockRoot;
private readonly Serilog.ILogger _Log;
private readonly string _RepositoryName; private readonly string _RepositoryName;
private readonly Dictionary<string, Dictionary<long, HeaderCommon>> _RdsToHeaderCommonCollection; private readonly Dictionary<string, Dictionary<long, HeaderCommon>> _RdsToHeaderCommonCollection;
public PinRepository(string mockRoot) public PinRepository(AppSettings appSettings)
{ {
_MockRoot = mockRoot; _MockRoot = appSettings.MockRoot;
_RdsToHeaderCommonCollection = new(); _RdsToHeaderCommonCollection = new();
_RepositoryName = nameof(PinRepository)[..^10]; _RepositoryName = nameof(PinRepository)[..^10];
_Log = Serilog.Log.ForContext<PinRepository>();
} }
void IPinRepository.SetPinnedTable(HeaderCommon headerCommon) void IPinRepository.SetPinnedTable(HeaderCommon headerCommon)

View File

@ -1,6 +1,5 @@
using OI.Metrology.Shared.Models.Stateless; using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.ViewModels; using OI.Metrology.Shared.ViewModels;
using Serilog.Context;
using System.Text.Json; using System.Text.Json;
namespace OI.Metrology.Server.Repository; namespace OI.Metrology.Server.Repository;
@ -8,10 +7,6 @@ namespace OI.Metrology.Server.Repository;
public class ServiceShopOrderRepository : IServiceShopOrderRepository public class ServiceShopOrderRepository : IServiceShopOrderRepository
{ {
private readonly Serilog.ILogger _Log;
public ServiceShopOrderRepository() => _Log = Serilog.Log.ForContext<ServiceShopOrderRepository>();
private static ServiceShopOrder[] GetServiceShopOrders(Shared.Models.ServiceShop? serviceShop) private static ServiceShopOrder[] GetServiceShopOrders(Shared.Models.ServiceShop? serviceShop)
{ {
ServiceShopOrder[] result = IServiceShopOrder.GetServiceShopOrders(serviceShop); ServiceShopOrder[] result = IServiceShopOrder.GetServiceShopOrders(serviceShop);
@ -35,13 +30,8 @@ public class ServiceShopOrderRepository : IServiceShopOrderRepository
async Task<ServiceShopOrder[]> IServiceShopOrderRepository.GetAllServiceShopOrders() async Task<ServiceShopOrder[]> IServiceShopOrderRepository.GetAllServiceShopOrders()
{ {
ServiceShopOrder[] results; ServiceShopOrder[] results;
string? methodName = IMethodName.GetActualAsyncMethodName(); Shared.Models.ServiceShop? serviceShop = await Task.Run(GetServiceShopOrders);
using (LogContext.PushProperty("MethodName", methodName)) results = GetServiceShopOrders(serviceShop);
{
_Log.Debug("() => ...");
Shared.Models.ServiceShop? serviceShop = await Task.Run(GetServiceShopOrders);
results = GetServiceShopOrders(serviceShop);
}
return results.ToArray(); return results.ToArray();
} }

View File

@ -1,8 +1,8 @@
using OI.Metrology.Server.Models;
using OI.Metrology.Shared.DataModels; 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;
@ -11,13 +11,17 @@ public class ToolTypesRepository : IToolTypesRepository
{ {
private readonly string _MockRoot; private readonly string _MockRoot;
private readonly Serilog.ILogger _Log;
private readonly string _RepositoryName; private readonly string _RepositoryName;
private readonly AppSettings _AppSettings;
private readonly IHttpClientFactory _HttpClientFactory;
private readonly IFileShareRepository _FileShareRepository;
public ToolTypesRepository(string mockRoot) public ToolTypesRepository(AppSettings appSettings, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository)
{ {
_MockRoot = mockRoot; _AppSettings = appSettings;
_Log = Serilog.Log.ForContext<ToolTypesRepository>(); _MockRoot = appSettings.MockRoot;
_HttpClientFactory = httpClientFactory;
_FileShareRepository = fileShareRepository;
_RepositoryName = nameof(ToolTypesRepository)[..^10]; _RepositoryName = nameof(ToolTypesRepository)[..^10];
} }
@ -79,7 +83,7 @@ public class ToolTypesRepository : IToolTypesRepository
// Gets headers, request/response format is to allow paging with igniteUI // Gets headers, request/response format is to allow paging with igniteUI
// The headerid parameter is used for navigating directly to a header, when the button is clicked in Awaiting Dispo // The headerid parameter is used for navigating directly to a header, when the button is clicked in Awaiting Dispo
Result<DataTable> IToolTypesRepository.GetHeaders(IMetrologyRepository metrologyRepository, int id, DateTime? datebegin, DateTime? dateend, int? page, int? pagesize, long? headerid) Result<DataTable> IToolTypesRepository.GetHeaders(IMetrologyRepository metrologyRepository, int id, string? datebegin, string? dateend, int? page, int? pagesize, long? headerid)
{ {
Result<DataTable>? r; Result<DataTable>? r;
if (!string.IsNullOrEmpty(_MockRoot)) if (!string.IsNullOrEmpty(_MockRoot))
@ -179,7 +183,8 @@ public class ToolTypesRepository : IToolTypesRepository
Stream? stream = null; Stream? stream = null;
string? message = null; string? message = null;
Guid attachmentIdParsed; Guid attachmentIdParsed;
string? contenttype = null; string? contentType = null;
string filenameLowerThenTrim = filename.ToLower().TrimEnd();
ToolType tt = metrologyRepository.GetToolTypeByID(toolTypeId); ToolType tt = metrologyRepository.GetToolTypeByID(toolTypeId);
bool header = !string.Equals(tabletype.Trim(), "data", StringComparison.OrdinalIgnoreCase); bool header = !string.Equals(tabletype.Trim(), "data", StringComparison.OrdinalIgnoreCase);
if (!Guid.TryParse(attachmentId, out attachmentIdParsed)) if (!Guid.TryParse(attachmentId, out attachmentIdParsed))
@ -189,154 +194,46 @@ public class ToolTypesRepository : IToolTypesRepository
try try
{ {
// figure out what content type to use. this is very simple because there are only two types being used // figure out what content type to use. this is very simple because there are only two types being used
contenttype = "application/pdf"; if (filenameLowerThenTrim.EndsWith(".txt"))
if (filename.ToLower().TrimEnd().EndsWith(".txt")) contentType = "text/plain";
contenttype = "text/plain"; else if (filenameLowerThenTrim.EndsWith(".json"))
contentType = "application/json";
else
contentType = "application/pdf";
// Get attachment stream and feed it to the client // Get attachment stream and feed it to the client
stream = attachmentsService.GetAttachmentStreamByAttachmentId(tt, header, attachmentIdParsed, filename); stream = attachmentsService.GetAttachmentStreamByAttachmentId(tt, header, attachmentIdParsed, filename);
} }
catch (Exception ex) { message = ex.Message; } catch (Exception ex) { message = ex.Message; }
} }
return new(message, contenttype, stream); return new(message, contentType, stream);
} }
// This endpoint triggers writing of the OI Export file string? IToolTypesRepository.OIExport(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, int toolTypeId, long headerid)
Exception? IToolTypesRepository.OIExport(IMetrologyRepository metrologyRepository, string oiExportPath, int toolTypeId, long headerid)
{ {
Exception? result = null; string? result;
// Call the export stored procedure ToolType toolType = metrologyRepository.GetToolTypeByID(toolTypeId);
_Log.Debug($"Exporting to <{oiExportPath}>"); if (toolType?.HeaderTableName is null)
DataSet ds = metrologyRepository.GetOIExportData(toolTypeId, headerid); result = $"Invalid tool id [{toolTypeId}] [{headerid}]!";
try else
{ {
// The SP must return 3 result tables string? processDataStandardFormat = attachmentsService.GetProcessDataStandardFormat(metrologyRepository, toolTypeId, headerid);
if (ds.Tables.Count != 3) if (processDataStandardFormat is null)
throw new Exception("Error exporting, invalid results"); result = $"Export file doesn't exist for [{toolTypeId}] [{headerid}] at <{_AppSettings.EcMesaFileShareMetrologySi}>!";
// The first table has just one row, which is the export filename else if (!_AppSettings.TableToPath.TryGetValue(toolType.HeaderTableName, out string? directly))
if (ds.Tables[0].Rows.Count != 1) result = $"Export file doesn't exist for [{toolTypeId}] [{headerid}] at <{_AppSettings.EcMesaFileShareMetrologySi}>!";
throw new Exception("Error exporting, invalid filename"); else
string? filename = Convert.ToString(ds.Tables[0].Rows[0][0]);
// The second table has the header data
if (ds.Tables[1].Rows.Count != 1)
throw new Exception("Error exporting, invalid header data");
StringBuilder sb = new();
foreach (object? o in ds.Tables[1].Rows[0].ItemArray)
{ {
if ((o is not null) && (!Convert.IsDBNull(o))) try
_ = sb.Append(Convert.ToString(o));
_ = sb.Append('\t');
}
// The third table has the detail data
foreach (DataRow dr in ds.Tables[2].Rows)
{
foreach (object? o in dr.ItemArray)
{ {
if ((o is not null) && (!Convert.IsDBNull(o))) HttpClient httpClient = _HttpClientFactory.CreateClient();
_ = sb.Append(Convert.ToString(o)); httpClient.BaseAddress = new(_AppSettings.ApiFileShare);
_ = sb.Append('\t'); _FileShareRepository.CopyFile(httpClient, processDataStandardFormat, Path.Combine(directly, $"Viewer_{Path.GetFileName(processDataStandardFormat)}"));
result = null;
} }
catch (Exception ex) { result = ex.Message; }
} }
_ = sb.AppendLine();
// The output file will only have one line, the header columns are output first
// Then each detail rows has it's columns appended
// H1, H2, H3, D1.1, D1.2, D1.3, D2.1, D2.2, D2.3, etc
// Write the file
File.WriteAllText(Path.Join(oiExportPath, filename), sb.ToString());
} }
catch (Exception ex) { result = ex; }
return result; return result;
} }
Result<DataTable> IToolTypesRepository.GetExportData(IMetrologyRepository metrologyRepository, int toolTypeId, DateTime? datebegin, DateTime? 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
{
dateend ??= DateTime.Now;
datebegin ??= dateend.Value.AddMonths(-1);
ToolType tt = metrologyRepository.GetToolTypeByID(toolTypeId);
if (string.IsNullOrEmpty(tt.ExportSPName))
throw new NullReferenceException(nameof(tt.ExportSPName));
DataTable dataTable = metrologyRepository.ExportData(tt.ExportSPName, datebegin.Value, dateend.Value);
r = new()
{
Results = dataTable,
TotalRows = dataTable.Rows.Count,
};
}
return r;
}
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();
}
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 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();
}
byte[] IToolTypesRepository.GetCSVExport(IMetrologyRepository metrologyRepository, int toolTypeId, DateTime? datebegin, DateTime? 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

@ -4,17 +4,24 @@ 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, IMetrologyRepository metrologyRepository) public AttachmentsService(AppSettings appSettings, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository, IMetrologyRepository metrologyRepository)
{ {
_AppSettings = appSettings; _AppSettings = appSettings;
_HttpClientFactory = httpClientFactory;
_FileShareRepository = fileShareRepository;
_MetrologyRepository = metrologyRepository; _MetrologyRepository = metrologyRepository;
} }
@ -27,28 +34,19 @@ 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));
int year = insertDate.Year;
DateTime d = insertDate;
CultureInfo cul = CultureInfo.CurrentCulture;
int weekNum = cul.Calendar.GetWeekOfYear(d, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
string workWeek = "WW" + weekNum.ToString("00");
string dateDir = year + @"\" + workWeek;
string fullPath = Path.Combine(_AppSettings.AttachmentPath, tableName + "_", dateDir, attachmentId.ToString(), filename); string year = insertDate.Year.ToString();
HttpClient httpClient = _HttpClientFactory.CreateClient();
// Check to see if file exists in the "New" directory structure, if not change the path back to the old. and check there Uri mesaFileShareMetrologySi = new(_AppSettings.EcMesaFileShareMetrologySi);
if (!File.Exists(fullPath)) 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);
fullPath = Path.Combine(_AppSettings.AttachmentPath, tableName, attachmentId.ToString(), filename); HttpResponseMessage httpResponseMessage = _FileShareRepository.ReadFile(httpClient, uri);
} if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception("File not found!");
if (!File.Exists(fullPath)) return httpResponseMessage.Content.ReadAsStream();
throw new Exception("File not found");
return new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
} }
public Stream GetAttachmentStreamByTitle(ToolType toolType, bool header, string title, string filename) Stream IAttachmentsService.GetAttachmentStreamByTitle(ToolType toolType, bool header, string title, string filename)
{ {
if (toolType is null) if (toolType is null)
throw new Exception("Invalid tool type"); throw new Exception("Invalid tool type");
@ -67,7 +65,7 @@ public class AttachmentsService : IAttachmentsService
return GetAttachmentStream(tableName, attachmentId, filename); return GetAttachmentStream(tableName, attachmentId, filename);
} }
public Stream GetAttachmentStreamByAttachmentId(ToolType toolType, bool header, Guid attachmentId, string filename) Stream IAttachmentsService.GetAttachmentStreamByAttachmentId(ToolType toolType, bool header, Guid attachmentId, string filename)
{ {
if (toolType is null) if (toolType is null)
throw new Exception("Invalid tool type"); throw new Exception("Invalid tool type");
@ -79,60 +77,75 @@ public class AttachmentsService : IAttachmentsService
return GetAttachmentStream(tableName, attachmentId, filename); return GetAttachmentStream(tableName, attachmentId, filename);
} }
private void SaveAttachment(ToolType toolType, long headerId, string dataUniqueId, string filename, IFormFile uploadedFile) void IAttachmentsService.SaveAttachment(ToolType toolType, Attachment attachment)
{ {
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)
using System.Transactions.TransactionScope trans = _MetrologyRepository.StartTransaction(); throw new NullReferenceException($"{nameof(attachment.HeaderId)}");
Guid attachmentId = Guid.Empty; if (attachment.AttachmentId is null)
DateTime insertDate = new(); throw new NullReferenceException($"{nameof(attachment.AttachmentId)}");
string? tableName = ""; if (attachment.DestinationFileName is null)
throw new NullReferenceException($"{nameof(attachment.DestinationFileName)}");
if (string.IsNullOrWhiteSpace(dataUniqueId)) if (string.IsNullOrWhiteSpace(attachment.UniqueId))
{ throw new NullReferenceException($"{nameof(attachment.UniqueId)}");
attachmentId = _MetrologyRepository.GetHeaderAttachmentID(toolType.ID, headerId); if (attachment.DestinationFileName != "Image.pdf")
insertDate = Convert.ToDateTime(_MetrologyRepository.GetHeaderInsertDate(toolType.ID, headerId)); _MetrologyRepository.SetHeaderAttachmentID(toolType.ID, attachment.HeaderId.Value, attachment.AttachmentId);
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;
}
int year = insertDate.Year;
DateTime d = insertDate;
CultureInfo cul = CultureInfo.CurrentCulture;
int weekNum = cul.Calendar.GetWeekOfYear(d, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
string workWeek = "WW" + weekNum.ToString("00");
string dateDir = year + @"\" + workWeek;
if (Equals(attachmentId, Guid.Empty))
throw new Exception("Invalid attachment ID");
string directoryPathSecondary = Path.Combine(_AppSettings.AttachmentPath, tableName + "_", dateDir, attachmentId.ToString());
if (!Directory.Exists(directoryPathSecondary))
_ = Directory.CreateDirectory(directoryPathSecondary);
string fullPathSecondary = Path.Combine(directoryPathSecondary, filename);
using (FileStream s = new(fullPathSecondary, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
{
uploadedFile.CopyTo(s);
}
trans.Complete();
} }
public void SaveAttachment(ToolType toolType, long headerId, string dataUniqueId, string filename, object uploadedFile) string? IAttachmentsService.GetProcessDataStandardFormat(IMetrologyRepository metrologyRepository, int toolTypeId, long headerId)
{ {
IFormFile formFile = (IFormFile)uploadedFile; string? result;
SaveAttachment(toolType, headerId, dataUniqueId, filename, formFile); int weekNum;
string file;
string year;
string directory;
Task<string> json;
Uri weekDirectory;
Uri checkDirectory;
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) };
ToolType toolType = metrologyRepository.GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
foreach (DateTime dateTime in dateTimes)
{
foreach (string item in collection)
{
year = dateTime.Year.ToString();
weekNum = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
weekDirectory = _FileShareRepository.Append(mesaFileShareMetrologySi, "MetrologyAttachments", $"{toolType.HeaderTableName}_", year, $"WW{weekNum:00}");
checkDirectory = _FileShareRepository.Append(weekDirectory, $"{item}{headerId}");
directory = Path.Combine(_AppSettings.EcMetrologySi, "MetrologyAttachments", $"{toolType.HeaderTableName}_", year, $"WW{weekNum:00}", $"{item}{headerId}");
httpResponseMessage = httpClient.GetAsync(checkDirectory);
httpResponseMessage.Wait();
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)
break;
}
result = files.Count == 0 ? null : files.First();
return result;
} }
} }

View File

@ -13,7 +13,7 @@ public class SQLDbConnectionFactory : IDbConnectionFactory
public SQLDbConnectionFactory(AppSettings appSettings) => _AppSettings = appSettings; public SQLDbConnectionFactory(AppSettings appSettings) => _AppSettings = appSettings;
public DbConnection GetDbConnection() public DbConnection GetDbConnection(bool? useIqsConnection)
{ {
DbProviderFactories.RegisterFactory( DbProviderFactories.RegisterFactory(
typeof(SqlConnection).Namespace, typeof(SqlConnection).Namespace,
@ -22,9 +22,9 @@ public class SQLDbConnectionFactory : IDbConnectionFactory
if (string.IsNullOrEmpty(_AppSettings.ConnectionString)) if (string.IsNullOrEmpty(_AppSettings.ConnectionString))
throw new Exception("Connection string is missing"); throw new Exception("Connection string is missing");
DbConnection c = SqlClientFactory.Instance.CreateConnection(); DbConnection dbConnection = SqlClientFactory.Instance.CreateConnection();
c.ConnectionString = _AppSettings.ConnectionString; dbConnection.ConnectionString = useIqsConnection is null || !useIqsConnection.Value ? _AppSettings.ConnectionString : throw new Exception();
c.Open(); dbConnection.Open();
return c; return dbConnection;
} }
} }

View File

@ -0,0 +1,300 @@
using Adaptation.FileHandlers.json;
using OI.Metrology.Shared.Models.Stateless;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Text;
using System.Text.Json;
namespace OI.Metrology.Server.Services;
public class SpreadingResistanceProfileService : ISpreadingResistanceProfileService
{
#pragma warning disable CA1416
private static RectangleF GetRectangleF(double left, double top, double width, double height) =>
new((float)left, (float)top, (float)width, (float)height);
private static void DrawLine(Graphics graphics, Pen pen, double x1, double y1, double x2, double y2) =>
graphics.DrawLine(pen, (float)x1, (float)y1, (float)x2, (float)y2);
private static void DrawString(Graphics graphics, string s, Font font, Brush brush, double x, double y) =>
graphics.DrawString(s, font, brush, (float)x, (float)y);
private static void FillEllipse(Graphics graphics, Brush brush, double x, double y, double width, double height) =>
graphics.FillEllipse(brush, (float)x, (float)y, (float)width, (float)height);
private static void DrawString(Graphics graphics, string s, Font font, Brush brush, double x, double y, StringFormat stringFormat) =>
graphics.DrawString(s, font, brush, (float)x, (float)y, stringFormat);
private static void GetMinMax(List<ProfilePoint> profilePoints, out double decades, out double maxDepth, out double concentrationMin, out double resistanceEditedMin, out double resistivityMin)
{
double ceilingCD;
double ceilingEdited;
maxDepth = int.MinValue;
double ceilingResistivity;
resistivityMin = double.MaxValue;
concentrationMin = double.MaxValue;
resistanceEditedMin = double.MaxValue;
double resistivityMax = double.MinValue;
double concentrationMax = double.MinValue;
double resistanceEditedMax = double.MinValue;
foreach (ProfilePoint profilePoint in profilePoints)
{
if (profilePoint.Log10?.ResistanceEdited is null || profilePoint.Log10?.Resistivity is null || profilePoint.Log10?.Concentration is null)
continue;
if (profilePoint.Depth <= 0 || profilePoint.ResistanceRaw == 0)
continue;
maxDepth = profilePoint.Depth;
if (profilePoint.Log10.Resistivity.Value < resistivityMin)
resistivityMin = profilePoint.Log10.Resistivity.Value;
ceilingResistivity = Math.Ceiling(profilePoint.Log10.Resistivity.Value);
if (ceilingResistivity > resistivityMax)
resistivityMax = ceilingResistivity;
if (profilePoint.Log10.ResistanceEdited.Value < resistanceEditedMin)
resistanceEditedMin = profilePoint.Log10.ResistanceEdited.Value;
ceilingEdited = Math.Ceiling(profilePoint.Log10.ResistanceEdited.Value);
if (ceilingEdited > resistanceEditedMax)
resistanceEditedMax = ceilingEdited;
if (profilePoint.Log10.Concentration.Value < concentrationMin)
concentrationMin = profilePoint.Log10.Concentration.Value;
ceilingCD = Math.Ceiling(profilePoint.Log10.Concentration.Value);
if (ceilingCD > concentrationMax)
concentrationMax = ceilingCD;
}
decades = resistivityMax - resistivityMin;
if (resistanceEditedMax - resistanceEditedMin > decades)
decades = resistanceEditedMax - resistanceEditedMin;
if (concentrationMax - concentrationMin > decades)
decades = concentrationMax - concentrationMin;
}
private static RectangleF[] GetRectangles(double leftChartArea, double widthChartArea, double topChartArea, double sizeOfBlock, double widthOfBlacks)
{
List<RectangleF> rectangles = new()
{
GetRectangleF(leftChartArea, 10, widthChartArea, 65),
// GetRectangleF(leftChartArea + widthChartArea, topChartArea, widthOfBlacks, sizeOfBlock * 5);
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 0, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 1, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 2, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 3, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 4, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 5, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 6, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 7, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 8, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 9, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 10, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 11, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 12, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 13, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 14, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 15, widthOfBlacks, sizeOfBlock),
GetRectangleF(leftChartArea + widthChartArea, topChartArea + sizeOfBlock * 16, widthOfBlacks, sizeOfBlock * 2)
};
return rectangles.ToArray();
}
private static ReadOnlyCollection<string> GetRectanglesDescriptions(Info info, Setup setup, List<Layer> layers)
{
List<string> results = new() {
string.Empty, // 0
string.Empty, // 1
string.Empty, // 2
string.Empty, // 3
string.Empty, // 4
string.Empty, // 5
string.Empty, // 6
string.Empty, // 7
string.Empty, // 8
string.Concat(info.SystemId, Environment.NewLine, info.SoftwareVersion), // 9
string.Concat("SURFACE FINISH", Environment.NewLine, setup.Finish), // 10
string.Concat("ORIENTATION", Environment.NewLine, setup.Orientation), // 11
string.Concat("BEVEL ANGLE", Environment.NewLine, setup.SineBevelAngle), // 12
string.Concat("X-STEP (um)", Environment.NewLine, setup.Steps.First().X), // 13
string.Concat("PROBE LOAD (gm)", Environment.NewLine, setup.ProbeLoad), // 14
string.Concat("SPACING (um)", Environment.NewLine, setup.ProbeSpacing), // 15
string.Concat("OPERATOR", Environment.NewLine, info.Operator), // 16
string.Concat("DATE", Environment.NewLine, info.DateTime.ToString("dd MMM yy"), Environment.NewLine, "TIME", Environment.NewLine, info.DateTime.ToString("HH:mm:ss tt")), // 17
};
StringBuilder stringBuilder = new();
foreach (Layer layer in layers)
_ = stringBuilder.AppendLine(string.Concat("First Pt. ", layer.FirstPoint, " Last Pt. ", layer.LastPoint, " Type ", layer.Type, " Smoothing ", layer.Smoothing, " Correction ", layer.Correction));
_ = stringBuilder.AppendLine(string.Join(" ", info.Comments));
results[0] = stringBuilder.ToString();
return new(results);
}
internal static byte[] GetImageBytes(CSV csv)
{
if (csv.Info is null)
throw new NullReferenceException(nameof(csv.Info));
if (csv.Setup is null)
throw new NullReferenceException(nameof(csv.Setup));
if (csv.LayerHeader is null)
throw new NullReferenceException(nameof(csv.LayerHeader));
if (csv.ProfileHeader is null)
throw new NullReferenceException(nameof(csv.ProfileHeader));
double decades, maxDepth, concentrationMin, resistanceEditedMin, resistivityMin;
GetMinMax(csv.ProfileHeader.ProfilePoints, out decades, out maxDepth, out concentrationMin, out resistanceEditedMin, out resistivityMin);
byte[] bytes;
int penSize = 1;
int width = 694;
int height = 714;
int ellipseSize = 3;
Pen pen = Pens.Black;
int blocksOfDepth = 6;
RectangleF[] rectangles;
double topChartArea = 90;
double leftChartArea = 60;
double widthOfBlacks = 120;
Brush brush = Brushes.Black;
double widthChartArea = 500;
double heightChartArea = 600;
Font consolas = new("Consolas", 9);
Color backgroundColor = Color.White;
Brush resistivityBrush = Brushes.Green;
Font consolasBold = new("Consolas", 9);
Brush concentrationBrush = Brushes.Blue;
Brush resistanceRawBrush = Brushes.Black;
Brush resistanceEditedBrush = Brushes.Red;
double sizeOfBlock = heightChartArea / 18;
Brush backgroundBrush = Brushes.WhiteSmoke;
Pen resistivityPen = new(Color.Green, penSize);
Pen concentrationPen = new(Color.Blue, penSize);
Pen resistanceRawPen = new(Color.Black, penSize);
Pen resistanceEditedPen = new(Color.Red, penSize);
double widthOfDepthBlock = Math.Ceiling(maxDepth / 3) * 3 / 6;
StringFormat stringFormat = new() { Alignment = StringAlignment.Far };
Bitmap bitmap = new(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.Clear(backgroundColor);
rectangles = new RectangleF[1];
rectangles[0] = GetRectangleF(leftChartArea, topChartArea, widthChartArea, heightChartArea);
graphics.FillRectangles(backgroundBrush, rectangles);
rectangles = GetRectangles(leftChartArea, widthChartArea, topChartArea, sizeOfBlock, widthOfBlacks);
graphics.FillRectangles(Brushes.White, rectangles);
graphics.DrawRectangles(pen, rectangles);
ReadOnlyCollection<string> descriptions = GetRectanglesDescriptions(csv.Info, csv.Setup, csv.LayerHeader.Layers);
for (int i = 0; i < descriptions.Count; i++)
graphics.DrawString(descriptions[i], consolas, brush, rectangles[i]);
DrawLine(graphics, concentrationPen, 13, 6, 13, 40);
graphics.DrawString("C", consolasBold, concentrationBrush, 8, 41);
graphics.DrawString("D", consolasBold, concentrationBrush, 8, 53);
DrawLine(graphics, resistivityPen, 28, 6, 28, 40);
graphics.DrawString("ρ", consolasBold, resistivityBrush, 21, 41);
graphics.DrawString("c", consolasBold, resistivityBrush, 21, 53);
graphics.DrawString("m", consolasBold, resistivityBrush, 21, 62);
DrawLine(graphics, resistanceRawPen, 39, 7, 39, 41);
graphics.DrawString("Ω", consolasBold, resistanceRawBrush, 34, 41);
DrawLine(graphics, resistanceEditedPen, 51, 7, 51, 41);
graphics.DrawString("Ω", consolasBold, resistanceEditedBrush, 46, 41);
graphics.DrawString("E", consolasBold, resistanceEditedBrush, 46, 53);
for (double i = decades; i >= 0; i += -1)
{
for (int j = 1; j <= 10; j++)
DrawLine(graphics, Pens.LightGray, leftChartArea, topChartArea + heightChartArea - (i * heightChartArea / decades) + heightChartArea / decades * Math.Log10(j), leftChartArea + widthChartArea, topChartArea + heightChartArea - (i * heightChartArea / decades) + heightChartArea / decades * Math.Log10(j));
}
DrawString(graphics, "0", consolas, brush, leftChartArea - 6, topChartArea + heightChartArea + 5);
double x, x1, x2;
for (int i = 0; i <= blocksOfDepth - 1; i++)
{
for (int j = 1; j <= 10; j++)
{
x = leftChartArea + 13 + (i + 1) * widthChartArea / blocksOfDepth;
x1 = leftChartArea + (i * widthChartArea / blocksOfDepth) + j * widthChartArea / blocksOfDepth / 10;
x2 = leftChartArea + (i * widthChartArea / blocksOfDepth) + (j * widthChartArea / blocksOfDepth / 10);
DrawLine(graphics, Pens.LightGray, x1, topChartArea, x2, topChartArea + heightChartArea);
DrawString(graphics, ((i + 1) * widthOfDepthBlock).ToString("0.0"), consolas, brush, x, topChartArea + heightChartArea + 5, stringFormat);
}
}
DrawString(graphics, "(um)", consolas, brush, leftChartArea + widthChartArea + 12, topChartArea + heightChartArea + 5);
for (int i = 0; i <= decades; i++)
{
DrawLine(graphics, pen, leftChartArea, topChartArea + (i * heightChartArea / decades), leftChartArea + widthChartArea, topChartArea + (i * heightChartArea / decades));
DrawString(graphics, (decades - i + resistivityMin).ToString("0"), consolasBold, resistivityBrush, 33, topChartArea - 10 + (i * heightChartArea / decades), stringFormat);
DrawString(graphics, (decades - i + concentrationMin).ToString("0"), consolasBold, concentrationBrush, 20, topChartArea - 10 + (i * heightChartArea / decades), stringFormat);
DrawString(graphics, (decades - i + resistanceEditedMin).ToString("0"), consolasBold, resistanceRawBrush, 45, topChartArea - 10 + (i * heightChartArea / decades), stringFormat);
DrawString(graphics, (decades - i + resistanceEditedMin).ToString("0"), consolasBold, resistanceEditedBrush, 58, topChartArea - 10 + (i * heightChartArea / decades), stringFormat);
}
for (int i = 0; i <= blocksOfDepth; i++)
DrawLine(graphics, pen, leftChartArea + (i * widthChartArea / blocksOfDepth), topChartArea, leftChartArea + (i * widthChartArea / blocksOfDepth), topChartArea + heightChartArea);
double y, y2;
foreach (ProfilePoint profilePoint in csv.ProfileHeader.ProfilePoints)
{
if (profilePoint.Log10?.ResistanceEdited is null || profilePoint.Log10?.Resistivity is null || profilePoint.Log10?.Concentration is null)
continue;
if (profilePoint.Depth <= 0 || profilePoint.ResistanceRaw == 0)
continue;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
x = leftChartArea + profilePoint.Depth / maxDepth * widthChartArea - ellipseSize;
FillEllipse(graphics, concentrationBrush, x, topChartArea + heightChartArea - ((profilePoint.Log10.Concentration.Value - concentrationMin) / decades * heightChartArea) - ellipseSize - ellipseSize, ellipseSize, ellipseSize);
FillEllipse(graphics, resistanceRawBrush, x, topChartArea + heightChartArea - ((profilePoint.Log10.ResistanceRaw - resistanceEditedMin) / decades * heightChartArea) - ellipseSize - ellipseSize, ellipseSize, ellipseSize);
FillEllipse(graphics, resistivityBrush, x, topChartArea + heightChartArea - ((profilePoint.Log10.Resistivity.Value - resistivityMin) / decades * heightChartArea) - ellipseSize - ellipseSize, ellipseSize, ellipseSize);
FillEllipse(graphics, resistanceEditedBrush, x, topChartArea + heightChartArea - ((profilePoint.Log10.ResistanceEdited.Value - resistanceEditedMin) / decades * heightChartArea) - ellipseSize - ellipseSize, ellipseSize, ellipseSize);
if (profilePoint.LastProfilePoint?.ResistanceEdited is not null && profilePoint.LastProfilePoint?.Resistivity is not null && profilePoint.LastProfilePoint?.Concentration is not null && profilePoint.LastProfilePoint?.Log10?.ResistanceEdited is not null && profilePoint.LastProfilePoint?.Log10?.Resistivity is not null && profilePoint.LastProfilePoint?.Log10?.Concentration is not null && profilePoint.DeltaPercent is not null && profilePoint.DeltaPercent is >= .2 or <= -.2)
{
x = leftChartArea + profilePoint.Depth / maxDepth * widthChartArea - penSize;
x2 = leftChartArea + profilePoint.LastProfilePoint.Depth / maxDepth * widthChartArea - penSize;
y = topChartArea + heightChartArea - ((profilePoint.Log10.Concentration.Value - concentrationMin) / decades * heightChartArea) - penSize;
y2 = topChartArea + heightChartArea - ((profilePoint.LastProfilePoint.Log10.Concentration.Value - concentrationMin) / decades * heightChartArea) - penSize;
DrawLine(graphics, concentrationPen, x, y, x2, y2);
y = topChartArea + heightChartArea - ((profilePoint.Log10.ResistanceRaw - resistanceEditedMin) / decades * heightChartArea) - penSize;
y2 = topChartArea + heightChartArea - ((profilePoint.LastProfilePoint.Log10.ResistanceRaw - resistanceEditedMin) / decades * heightChartArea) - penSize;
DrawLine(graphics, resistanceRawPen, x, y, x2, y2);
y = topChartArea + heightChartArea - ((profilePoint.Log10.Resistivity.Value - resistivityMin) / decades * heightChartArea) - penSize;
y2 = topChartArea + heightChartArea - ((profilePoint.LastProfilePoint.Log10.Resistivity.Value - resistivityMin) / decades * heightChartArea) - penSize;
DrawLine(graphics, resistivityPen, x, y, x2, y2);
y = topChartArea + heightChartArea - ((profilePoint.Log10.ResistanceEdited.Value - resistanceEditedMin) / decades * heightChartArea) - penSize;
y2 = topChartArea + heightChartArea - ((profilePoint.LastProfilePoint.Log10.ResistanceEdited.Value - resistanceEditedMin) / decades * heightChartArea) - penSize;
DrawLine(graphics, resistanceEditedPen, x, y, x2, y2);
}
}
using MemoryStream msMemoryStream = new();
bitmap.Save(msMemoryStream, System.Drawing.Imaging.ImageFormat.Png);
bytes = new byte[Convert.ToInt32(msMemoryStream.Length) + 1];
_ = msMemoryStream.Read(bytes, 0, bytes.Length);
bytes = msMemoryStream.ToArray();
return bytes;
}
private static byte[] GetImageBytes(string json)
{
byte[] results;
Adaptation.FileHandlers.csv.CSV? csv = JsonSerializer.Deserialize<Adaptation.FileHandlers.csv.CSV>(json);
if (csv is null)
throw new NullReferenceException(nameof(csv));
CSV result = new(csv);
results = GetImageBytes(result);
return results;
}
byte[] ISpreadingResistanceProfileService.GetImageBytes(string json)
{
byte[] results = GetImageBytes(json);
return results;
}
byte[] ISpreadingResistanceProfileService.GetImageBytes(Stream stream)
{
byte[] results;
using StreamReader streamReader = new(stream, Encoding.UTF8);
string json = streamReader.ReadToEnd();
results = GetImageBytes(json);
return results;
}
}

View File

@ -0,0 +1,85 @@
namespace Adaptation.FileHandlers.csv;
public class CSV
{
#nullable disable
#nullable enable
#pragma warning disable CA1834
public string? FileVersion { get; set; }
public Info? Info { get; set; }
public Setup? Setup { get; set; }
public LayerHeader? LayerHeader { get; set; }
public ProfileHeader? ProfileHeader { get; set; }
public Calibration? Calibration { get; set; }
public RawData? RawData { get; set; }
internal static CSV GetCSV(string path)
{
CSV result;
int? endInfo = null;
int? endSetup = null;
int? endLayers = null;
int? startInfo = null;
int? startSetup = null;
int? endProfiles = null;
int? startLayers = null;
int? startRawData = null;
int? startProfiles = null;
int? endCalibration = null;
int? startCalibration = null;
#if NET
string[] lines = File.ReadAllLines(path, System.Text.Encoding.Latin1); // µ³®
# else
string[] lines = File.ReadAllLines(path, System.Text.Encoding.GetEncoding("ISO-8859-1")); // µ³®
# endif
string? fileVersion = lines.Length == 0 ? null : GetFileVersion(lines.First());
for (int i = 1; i < lines.Length; i++)
{
if (lines[i].StartsWith("--INFO--"))
startInfo = i + 1;
else if (lines[i].StartsWith("--SETUP--"))
(endInfo, startSetup) = (i, i + 1);
else if (lines[i].StartsWith("--LAYERS--"))
(endSetup, startLayers) = (i, i + 1);
else if (lines[i].StartsWith("--PROFILES--"))
(endLayers, startProfiles) = (i, i + 1);
else if (lines[i].StartsWith("--CALIBRATION--"))
(endProfiles, startCalibration) = (i, i + 1);
else if (lines[i].StartsWith("--RAWDATA--"))
(endCalibration, startRawData) = (i, i + 1);
}
RawData? rawData = startRawData is null ? null : RawData.GetRawData(lines, startRawData.Value, lines.Length);
Info? info = startInfo is null || endInfo is null ? null : Info.GetInfo(lines, startInfo.Value, endInfo.Value);
Setup? setup = startSetup is null || endSetup is null ? null : Setup.GetSetup(lines, startSetup.Value, endSetup.Value);
LayerHeader? layerHeader = startLayers is null || endLayers is null ? null : LayerHeader.GetLayerHeader(lines, startLayers.Value, endLayers.Value);
ProfileHeader? profileHeader = startProfiles is null || endProfiles is null ? null : ProfileHeader.GetProfileHeader(lines, startProfiles.Value, endProfiles.Value);
Calibration? calibration = startCalibration is null || endCalibration is null ? null : Calibration.GetCalibration(lines, startCalibration.Value, endCalibration.Value);
result = new()
{
FileVersion = fileVersion,
Info = info,
Setup = setup,
LayerHeader = layerHeader,
ProfileHeader = profileHeader,
Calibration = calibration,
RawData = rawData,
};
return result;
}
private static string GetFileVersion(string line)
{
string result;
string[] segments = line.Split(',');
if (segments.Length < 2)
result = string.Empty;
else
result = segments.Last();
return result;
}
}

View File

@ -0,0 +1,132 @@
using System.Text;
namespace Adaptation.FileHandlers.csv;
public class Calibration
{
#nullable disable
public string NumberOfCalibrationSets { get; set; }
public List<DataSet> DataSets { get; set; }
#nullable enable
#pragma warning disable CA1834
internal static Calibration? GetCalibration(string[] lines, int start, int stop)
{
Calibration? result;
string first;
DataSet dataSet;
Position position;
string[] segments;
int? thirdStart = null;
int? secondStart = null;
List<Position> positions;
List<string> values = new();
List<DataSet> dataSets = new();
StringBuilder stringBuilder = new();
for (int i = start; i < stop; i++)
{
segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
first = segments.First();
if (first == "DataSet:")
{
secondStart = i + 1;
break;
}
_ = stringBuilder.Append(first).Append(",");
if (segments.Length > 1)
values.Add(segments[1]);
else
values.Add(string.Empty);
}
string header = "Number of Calibration Sets,";
if (secondStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
result = null;
else
{
result = new()
{
NumberOfCalibrationSets = values[0],
DataSets = dataSets,
};
for (int x = 0; x < int.MaxValue; x++)
{
values.Clear();
_ = stringBuilder.Clear();
if (secondStart is null)
break;
for (int i = secondStart.Value; i < stop; i++)
{
segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
first = segments.First();
if (first == "Resistivity(ohm-cm)")
{
thirdStart = i + 1;
break;
}
if (first == " Sample Set:")
continue;
_ = stringBuilder.Append(first).Append(",");
if (segments.Length > 1)
values.Add(segments[1]);
else
values.Add(string.Empty);
}
secondStart = null;
header = "Operator,Date & Time,Finish,Orientation,North Probe ID,South Probe ID,Polarity,Contact Radius (µm),Probe Spacing (µm),Load (gm),X Step (µm),Name,Plate ID,Type,Points per Sample,Number of Pairs,";
if (thirdStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
result = null;
else
{
positions = new();
dataSet = new()
{
Operator = values[0],
DateTime = values[1],
Finish = values[2],
Orientation = values[3],
NorthProbeID = values[4],
SouthProbeID = values[5],
Polarity = values[6],
ContactRadius = values[7],
ProbeSpacing = values[8],
Load = values[9],
XStep = values[10],
Name = values[11],
PlateId = values[12],
Type = values[13],
PointsPerSample = values[14],
NumberOfPairs = values[15],
Positions = positions,
};
dataSets.Add(dataSet);
for (int i = thirdStart.Value; i < stop; i++)
{
segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
first = segments.First();
if (first == "DataSet:")
{
secondStart = i + 1;
break;
}
if (segments.Length < 5)
continue;
position = new()
{
Resistivity = segments[0],
Resistance = segments[1],
PercentStandardDeviation = segments[2],
Number = segments[3],
Name = segments[4],
};
positions.Add(position);
}
}
}
}
return result;
}
}

View File

@ -0,0 +1,27 @@
namespace Adaptation.FileHandlers.csv;
public class DataSet
{
#nullable disable
public string Operator { get; set; }
public string DateTime { get; set; }
public string Finish { get; set; }
public string Orientation { get; set; }
public string NorthProbeID { get; set; }
public string SouthProbeID { get; set; }
public string Polarity { get; set; }
public string ContactRadius { get; set; }
public string ProbeSpacing { get; set; }
public string Load { get; set; }
public string XStep { get; set; }
// public string SampleSet { get; set; }
public string Name { get; set; }
public string PlateId { get; set; }
public string Type { get; set; }
public string PointsPerSample { get; set; }
public string NumberOfPairs { get; set; }
public List<Position> Positions { get; set; }
}

View File

@ -0,0 +1,72 @@
using System.Text;
namespace Adaptation.FileHandlers.csv;
public class Info
{
#nullable disable
public string Operator { get; set; }
public string SampleName { get; set; }
public string SoftwareVersion { get; set; }
public string DateTime { get; set; }
public string SystemId { get; set; }
public string SystemSite { get; set; }
public string SamplePosition { get; set; }
public string Units { get; set; }
public string CommentLength { get; set; }
public List<string> Comments { get; set; }
#nullable enable
#pragma warning disable CA1834
internal static Info? GetInfo(string[] lines, int start, int stop)
{
Info? result;
string first;
string[] segments;
int? secondStart = null;
List<string> values = new();
List<string> comments = new();
StringBuilder stringBuilder = new();
for (int i = start; i < stop; i++)
{
segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
first = segments.First();
if (first == "Comment:")
{
secondStart = i + 1;
break;
}
_ = stringBuilder.Append(first).Append(",");
if (segments.Length > 1)
values.Add(segments[1]);
else
values.Add(string.Empty);
}
string header = "Operator,Sample Name,Software Version,Date & Time,System ID,System Site,Sample Position,Units,Comment Length,";
if (secondStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
result = null;
else
{
result = new()
{
Operator = values[0],
SampleName = values[1],
SoftwareVersion = values[2],
DateTime = values[3],
SystemId = values[4],
SystemSite = values[5],
SamplePosition = values[6],
Units = values[7],
CommentLength = values[8],
Comments = comments,
};
for (int i = secondStart.Value; i < stop; i++)
comments.Add(lines[i]);
}
return result;
}
}

View File

@ -0,0 +1,24 @@
namespace Adaptation.FileHandlers.csv;
public class Layer
{
#nullable disable
public string FirstPoint { get; set; }
public string LastPoint { get; set; }
public string Type { get; set; }
public string Smoothing { get; set; }
public string Apply { get; set; }
public string SOrder { get; set; }
public string GOrder { get; set; }
public string Correction { get; set; }
public string Conversion { get; set; }
public string JunctionOption { get; set; }
public string JunctionConstant { get; set; }
public string CurrentDensity { get; set; }
public string M1M2Tolerance { get; set; }
public string Sheet { get; set; }
public string Dose { get; set; }
}

View File

@ -0,0 +1,80 @@
using System.Text;
namespace Adaptation.FileHandlers.csv;
public class LayerHeader
{
#nullable disable
public string NumberOfLayers { get; set; }
public List<Layer> Layers { get; set; }
#nullable enable
#pragma warning disable CA1834
internal static LayerHeader? GetLayerHeader(string[] lines, int start, int stop)
{
LayerHeader? result;
Layer layer;
string first;
string[] segments;
int? secondStart = null;
List<Layer> layerCollection = new();
List<string> values = new();
StringBuilder stringBuilder = new();
for (int i = start; i < stop; i++)
{
segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
first = segments.First();
if (first == "Layer")
{
secondStart = i + 1;
break;
}
_ = stringBuilder.Append(first).Append(",");
if (segments.Length > 1)
values.Add(segments[1]);
else
values.Add(string.Empty);
}
string header = "Number of Layers,";
if (secondStart is null || stringBuilder.Length != header.Length || stringBuilder.ToString() != header)
result = null;
else
{
result = new()
{
NumberOfLayers = values[0],
Layers = layerCollection,
};
for (int i = secondStart.Value; i < stop; i++)
{
segments = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
if (segments.Length < 15)
continue;
layer = new()
{
FirstPoint = segments[0],
LastPoint = segments[1],
Type = segments[2],
Smoothing = segments[3],
Apply = segments[4],
SOrder = segments[5],
GOrder = segments[6],
Correction = segments[7],
Conversion = segments[8],
JunctionOption = segments[9],
JunctionConstant = segments[10],
CurrentDensity = segments[11],
M1M2Tolerance = segments[12],
Sheet = segments[13],
Dose = segments[14],
};
layerCollection.Add(layer);
}
}
return result;
}
}

View File

@ -0,0 +1,16 @@
namespace Adaptation.FileHandlers.csv;
public class Point
{
#nullable disable
public string Number { get; set; }
public string Depth { get; set; }
public string Resistance { get; set; }
public string StageX { get; set; }
public string StageY { get; set; }
public string StageZ { get; set; }
public string StageT { get; set; }
}

View File

@ -0,0 +1,14 @@
namespace Adaptation.FileHandlers.csv;
public class Position
{
#nullable disable
public string Resistivity { get; set; }
public string Resistance { get; set; }
public string PercentStandardDeviation { get; set; }
public string Number { get; set; }
public string Name { get; set; }
}

View File

@ -0,0 +1,15 @@
namespace Adaptation.FileHandlers.csv;
public class Profile
{
#nullable disable
public string Id { get; set; }
public string Name { get; set; }
public string Label { get; set; }
public string Allocated { get; set; }
public string Used { get; set; }
public string List { get; set; }
}

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