Compare commits

...

10 Commits

Author SHA1 Message Date
7be540964a Pull Request 33523 suggestions
Pull Request 33520 suggestions

Injected AppSettings instead of using GetEnvironmentVariable at Services level

When debugging only
app.Services.GetRequiredService<IPCRBService>();

Get ready to use VSCode IDE

Align .editorconfig files
2024-12-03 10:48:07 -07:00
08fcd985ea corrected expiring OOO bug 2024-11-12 13:08:32 -07:00
6e8210a920 update notify date for approval notif dups 2024-10-24 08:10:23 -07:00
2d94b26d3c Only one approval reminder email per user per issue 2024-10-18 09:11:40 -07:00
62a805374f Filtering out deleted and cancelled ECNs and CAs 2024-10-08 08:08:13 -07:00
03197508a2 Limiting active approval list 2024-10-07 13:14:43 -07:00
b9b0299d3f Created approval reminder worker 2024-09-09 10:00:49 -07:00
0fdf8179e1 Remove cancelled TECNs from expirations 2024-07-10 09:19:04 -07:00
6e957afafe Remove closed date clause from expiring tecn worker 2024-06-10 09:53:13 -07:00
1c9b7a8328 Fixed sql in CA follow up approval 2024-06-10 08:36:46 -07:00
60 changed files with 3318 additions and 201 deletions

View File

@ -19,7 +19,7 @@ insert_final_newline = false
# Organize usings
dotnet_separate_import_directive_groups = true
dotnet_sort_system_directives_first = false
dotnet_sort_system_directives_first = true
file_header_template = unset
# this. and Me. preferences
@ -249,4 +249,39 @@ dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = crlf
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
# Question
csharp_style_inlined_variable_declaration = false
csharp_style_prefer_primary_constructors = false
dotnet_diagnostic.CA1510.severity = none # "Use 'ArgumentNullException.ThrowIfNull' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1806.severity = none # SendEmailWithValidArgsShouldSendMailThroughClient calls TryParse but does not explicitly
dotnet_diagnostic.CA1827.severity = none # Count() is used where Any() could be used instead to improve performance
dotnet_diagnostic.CA1829.severity = none # Use the property instead of Enumerable.Count()
dotnet_diagnostic.CA1860.severity = none # Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
dotnet_diagnostic.CA2208.severity = none # Method .ctor passes
dotnet_diagnostic.CA2208.severity = none # Method .ctor passes
dotnet_diagnostic.CA2211.severity = none # Non-constant fields should not be visible
dotnet_diagnostic.CA2253.severity = none # Named placeholders in the logging message template should not be comprised
dotnet_diagnostic.CA2254.severity = none # The logging message template should not vary between calls to
dotnet_diagnostic.CS1998.severity = none # This async method lacks 'await' operators and will run synchronously
dotnet_diagnostic.CS8618.severity = none # Non-nullable field '_mockDalService' must contain a non-null value when exiting constructor
dotnet_diagnostic.CS8625.severity = none # Cannot convert null literal to non-nullable reference type
dotnet_diagnostic.IDE0005.severity = none # Using directive is unnecessary.
dotnet_diagnostic.IDE0017.severity = none # Object initialization can be simplified
dotnet_diagnostic.IDE0018.severity = none # Variable declaration can be inlined
dotnet_diagnostic.IDE0028.severity = none # Collection initialization can be simplified
dotnet_diagnostic.IDE0044.severity = none # Make field readonly
dotnet_diagnostic.IDE0046.severity = none # 'if' statement can be simplified
dotnet_diagnostic.IDE0052.severity = none # "Private member can be removed
dotnet_diagnostic.IDE0270.severity = none # Null check can be simplified
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor
dotnet_diagnostic.IDE1006.severity = none # Naming rule violation: These words must begin with upper case characters
dotnet_diagnostic.IDE2000.severity = error # IDE2000: Allow multiple blank lines
dotnet_diagnostic.NUnit2001.severity = none # Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model
dotnet_diagnostic.NUnit2004.severity = none # Consider using the constraint model
dotnet_diagnostic.NUnit2010.severity = none # Use Is.EqualTo constraint instead of direct comparison for better assertion messages in ca
dotnet_style_coalesce_expression = false
dotnet_style_object_initializer = false
dotnet_style_prefer_conditional_expression_over_return = false

5
.gitignore vendored
View File

@ -2,4 +2,7 @@
bin
obj
TestResults
Properties
Properties
/FabApprovalWorkerService/.vscode/.UserSecrets
/FabApprovalWorkerServiceTests/.vscode/.UserSecrets

1
.vscode/format-report.json vendored Normal file
View File

@ -0,0 +1 @@
[]

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

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

424
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,424 @@
{
"[markdown]": {
"editor.wordWrap": "off"
},
"files.exclude": {
"**/.git": false,
"**/node_modules": true
},
"files.watcherExclude": {
"**/node_modules": true
},
"cSpell.words": [
"abutton",
"accessibilities",
"accodingly",
"acknowledgmentby",
"Acks",
"actionsheet",
"Additonal",
"Addtional",
"againm",
"agendaview",
"Antlr",
"Appover",
"Appprrovers",
"Approvalog",
"Aprovers",
"Aproverslist",
"asax",
"aspnetmvc",
"Assignedto",
"Atachments",
"Attachemnt",
"Attachemnts",
"Attchment",
"auditee",
"Auditee",
"Auditees",
"automaically",
"Autthorized",
"beacuase",
"beforeunload",
"Belguim",
"bfound",
"bgcolor",
"Bies",
"binded",
"blackbackground",
"blackhover",
"blackpressed",
"blueenergy",
"blueopal",
"buttongroup",
"BYMRB",
"bytesgot",
"CAID",
"casection",
"CAXXXX",
"CCPCR",
"CCPCRB",
"cellspacing",
"Cheeso's",
"chkbx",
"Clib",
"colorpicker",
"columnmenu",
"columnsreorder",
"columnsresize",
"comming",
"Containmen",
"Copmments",
"correctiv",
"Correctivet",
"Creat",
"currentd",
"Cyle",
"dadada",
"darkbluehover",
"darkbluepressed",
"darkred",
"datafields",
"datasource",
"dataviz",
"datepicker",
"datetimepicker",
"dayview",
"Deletet",
"Delgation",
"DENITED",
"Deparmtent",
"departmentids",
"Descirption",
"devprog",
"dfeffc",
"Disp",
"Dispo",
"Dispoitio",
"Dispos",
"Dispositon",
"Dispostion",
"Dispostions",
"dispotypevalidation",
"Docbase",
"Documentum",
"Documetum",
"dont",
"downlaoded",
"draganddrop",
"dragcancel",
"dropdownlist",
"Eamils",
"ECNPCRB",
"Ecns",
"edmx",
"EECN",
"emai",
"emailparams",
"Emergrncy",
"energyblue",
"Eran",
"Esql",
"ETECN",
"EXCELOPENXML",
"existinglocation",
"Expando",
"extrafield",
"fadc",
"fbec",
"fcfdfd",
"fdff",
"fece",
"feeebd",
"ffdc",
"ffdd",
"fieldset",
"FILIPE",
"filtermenu",
"Fldr",
"flintstone",
"FLOWLOCS",
"FMEA",
"ftplib",
"FTPSPN",
"GETDATE",
"gitea",
"globaldocudms",
"glyphicons",
"groupable",
"Guids",
"halflings",
"Hexsize",
"highcontrast",
"Hmac",
"holdsteps",
"hostspecific",
"icenium",
"IECN",
"imagebrowser",
"IMRB",
"Infineon",
"Insertd",
"inverseicons",
"IPCRB",
"ISADMIN",
"islast",
"ISNULL",
"ITAR",
"jquery",
"jqueryval",
"jqwidgets",
"jqxbuttongroup",
"jqxbuttons",
"jqxcalendar",
"jqxchart",
"jqxcheckbox",
"jqxcolorpicker",
"jqxcombobox",
"jqxcore",
"jqxdata",
"jqxdatatable",
"jqxdatetimeinput",
"jqxdocking",
"jqxdockpanel",
"jqxdragdrop",
"jqxdropdownbutton",
"jqxdropdownlist",
"jqxexpander",
"jqxgauge",
"jqxgrid",
"jqxinput",
"jqxknockout",
"jqxlistbox",
"jqxlistmenu",
"jqxmaskedinput",
"jqxmenu",
"jqxnavigationbar",
"jqxnumberinput",
"jqxpanel",
"jqxpasswordinput",
"jqxprogressbar",
"jqxradiobutton",
"jqxrangeselector",
"jqxrating",
"jqxresponse",
"jqxscrollbar",
"jqxscrollview",
"jqxslider",
"jqxsplitter",
"jqxswitchbutton",
"jqxtabs",
"jqxtooltip",
"jqxtouch",
"jqxtree",
"jqxtreegrid",
"jqxtreemap",
"jqxvalidator",
"jqxwindow",
"kendogridcustom",
"kendoui",
"labelelement",
"labelledby",
"Leanred",
"lightgray",
"linkbutton",
"Linq",
"Listdiv",
"listview",
"Lnks",
"localfilename",
"loclist",
"logis",
"logtext",
"loopmis",
"lotdispo",
"LOTDISPSITION",
"Lotfile",
"lotlist",
"lotstatusoption",
"LTRIM",
"MADUREIRA",
"mailrelay",
"MDTM",
"meego",
"meetingid",
"menubutton",
"mesafi",
"metroblack",
"metrodark",
"miliseconds",
"modalview",
"modernizr",
"Modernizr",
"monthview",
"MRBIs",
"Mrbs",
"msecs",
"multipleextended",
"Navigatable",
"nbsp",
"newbase",
"newchange",
"newdi",
"newfilename",
"newsource",
"Newtonsoft",
"notications",
"Notifcation",
"Notifyf",
"NTLM",
"Nullcc",
"numerictextbox",
"objdata",
"OCAP",
"occured",
"odata",
"oldfilename",
"OLHOLD",
"onclick",
"onmousemove",
"OPDESC",
"OPENQUERY",
"Oper",
"operationslist",
"Orginator",
"Originatorname",
"Ouellette",
"Owin",
"pageable",
"Pageable",
"panelbar",
"parentid",
"parminput",
"parms",
"Parms",
"particula",
"pasv",
"PASV",
"PATINDEX",
"PCRB",
"PCRBID",
"pcrvalues",
"pdbonly",
"Preventitive",
"preventivet",
"Prevetative",
"proces",
"Processedl",
"procs",
"productfamilies",
"progess",
"progressbar",
"qrcode",
"Quanityt",
"rangebar",
"Recep",
"Recepient",
"recieved",
"recordlock",
"remotefilename",
"reorderable",
"reportform",
"reportslist",
"reportslistdiv",
"Reqquired",
"Reqs",
"Requiest",
"Responsibles",
"RETR",
"Revisioing",
"Revisioned",
"Revison",
"rgba",
"rkotian",
"RNFR",
"RNTO",
"Roless",
"roundbg",
"RTRIM",
"SAMDB",
"scroller",
"scrollview",
"seleced",
"selectionlog",
"Selectpart",
"sess",
"Sfisharepoint",
"shinyblack",
"showpassword",
"SIGNON",
"simpleparser",
"slddrw",
"sldprt",
"sortasc",
"sortascbutton",
"sortdesc",
"sortdescbutton",
"sortremove",
"sparkline",
"splitview",
"SPNMRB",
"SPNPDB",
"SSRS",
"Sssign",
"Staus",
"stylesheet",
"Submited",
"subrole",
"subroles",
"Succefully",
"Succesfully",
"sucessfully",
"SURP",
"Swashbuckle",
"SWRN",
"tabindex",
"tabstrip",
"Tahoma",
"taskcompleted",
"Tasklist",
"Taveler",
"TECN",
"TECNs",
"TEMIRWAP",
"tempecd",
"tempimplement",
"templabel",
"tempvalue",
"TEMSA",
"timepicker",
"Tobe",
"Toplevel",
"Totrav",
"trainingby",
"Traininglist",
"traininglistdiv",
"transanction",
"Trav",
"Traveller",
"Traverler",
"TRAVLELER",
"Travler",
"TREEVIEW",
"trigerred",
"ttinclude",
"Uhandled",
"Updat",
"Uplaod",
"Upto",
"userevents",
"userids",
"userlist",
"Validatable",
"valueelement",
"Variabls",
"Verdana",
"vgrid",
"viewmodel",
"vsdoc",
"whethere",
"windowsphone",
"Winsock",
"worlflow"
]
}

1
.vscode/spell.md vendored Normal file
View File

@ -0,0 +1 @@
# Spell

239
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,239 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "FabApprovalWorkerService-User Secrets Init",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/FabApprovalWorkerService/FabApprovalWorkerService.csproj",
"init"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerService-User Secrets Set",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/FabApprovalWorkerService/FabApprovalWorkerService.csproj",
"set",
"_UserSecretsId",
"0c43f9aa-96e9-4298-967c-ed069d79e262"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerService-Format",
"command": "dotnet",
"type": "process",
"args": [
"format",
"--report",
".vscode",
"--verbosity",
"detailed",
"--severity",
"warn"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerService-Format-Whitespaces",
"command": "dotnet",
"type": "process",
"args": [
"format",
"whitespace"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerService-build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/FabApprovalWorkerService/FabApprovalWorkerService.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerService-publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/FabApprovalWorkerService/FabApprovalWorkerService.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerService-watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/FabApprovalWorkerService/FabApprovalWorkerService.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerService-Publish AOT",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"-r",
"win-x64",
"-c",
"Release",
"-p:PublishAot=true",
"${workspaceFolder}/FabApprovalWorkerService/FabApprovalWorkerService.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-User Secrets Init",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/FabApprovalWorkerServiceTests/FabApprovalWorkerServiceTests.csproj",
"init"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-User Secrets Set",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/FabApprovalWorkerServiceTests/FabApprovalWorkerServiceTests.csproj",
"set",
"_UserSecretsId",
"f445e6e0-784b-4dde-9ef0-2143e6e90b1b"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-Format",
"command": "dotnet",
"type": "process",
"args": [
"format",
"--report",
".vscode",
"--verbosity",
"detailed",
"--severity",
"warn"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-Format-Whitespaces",
"command": "dotnet",
"type": "process",
"args": [
"format",
"whitespace"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/FabApprovalWorkerServiceTests/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-testDebug",
"command": "dotnet",
"type": "process",
"args": [
"test",
"${workspaceFolder}/FabApprovalWorkerServiceTests/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-testRelease",
"command": "dotnet",
"type": "process",
"args": [
"test",
"${workspaceFolder}/FabApprovalWorkerServiceTests/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"-c",
"Release"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/FabApprovalWorkerServiceTests/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/FabApprovalWorkerServiceTests/FabApprovalWorkerServiceTests.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "FabApprovalWorkerServiceTests-Publish AOT",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"-r",
"win-x64",
"-c",
"Release",
"-p:PublishAot=true",
"${workspaceFolder}/FabApprovalWorkerServiceTests/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -0,0 +1,287 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline = false
#### .NET Coding Conventions ####
# Organize usings
dotnet_separate_import_directive_groups = true
dotnet_sort_system_directives_first = true
file_header_template = unset
# this. and Me. preferences
dotnet_style_qualification_for_event = false
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_property = false
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true
dotnet_style_predefined_type_for_member_access = true
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:error
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:error
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:error
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members
# Expression-level preferences
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true
dotnet_style_explicit_tuple_names = true
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true
dotnet_style_object_initializer = true
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_collection_expression = when_types_loosely_match
dotnet_style_prefer_compound_assignment = true
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
dotnet_style_prefer_inferred_anonymous_type_member_names = true
dotnet_style_prefer_inferred_tuple_names = true
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_simplified_boolean_expressions = true
dotnet_style_prefer_simplified_interpolation = true
# Field preferences
dotnet_style_readonly_field = true
# Parameter preferences
dotnet_code_quality_unused_parameters = all:error
# Suppression preferences
dotnet_remove_unnecessary_suppression_exclusions = none
# New line preferences
dotnet_style_allow_multiple_blank_lines_experimental = false:error
dotnet_style_allow_statement_immediately_after_block_experimental = false:warning
#### C# Coding Conventions ####
# var preferences
csharp_style_var_elsewhere = false:error
csharp_style_var_for_built_in_types = false:error
csharp_style_var_when_type_is_apparent = false:error
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true
csharp_style_pattern_matching_over_is_with_cast_check = true
csharp_style_prefer_extended_property_pattern = true
csharp_style_prefer_not_pattern = true
csharp_style_prefer_pattern_matching = true
csharp_style_prefer_switch_expression = true
# Null-checking preferences
csharp_style_conditional_delegate_call = true
# Modifier preferences
csharp_prefer_static_local_function = false
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
csharp_style_prefer_readonly_struct = true:warning
csharp_style_prefer_readonly_struct_member = true
# Code-block preferences
csharp_prefer_braces = true:silent
csharp_prefer_simple_using_statement = false:suggestion
csharp_style_namespace_declarations = file_scoped:error
csharp_style_prefer_method_group_conversion = true:suggestion
csharp_style_prefer_primary_constructors = true:suggestion
csharp_style_prefer_top_level_statements = true:error
# Expression-level preferences
csharp_prefer_simple_default_expression = true
csharp_style_deconstructed_variable_declaration = false:suggestion
csharp_style_implicit_object_creation_when_type_is_apparent = false
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_prefer_index_operator = false:error
csharp_style_prefer_local_over_anonymous_function = true:error
csharp_style_prefer_null_check_over_type_check = true
csharp_style_prefer_range_operator = false:error
csharp_style_prefer_tuple_swap = true
csharp_style_prefer_utf8_string_literals = true
csharp_style_throw_expression = true
csharp_style_unused_value_assignment_preference = unused_local_variable
csharp_style_unused_value_expression_statement_preference = unused_local_variable
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:error
# New line preferences
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:error
csharp_style_allow_embedded_statements_on_same_line_experimental = true
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
[*.{cs,vb}]
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = crlf
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
# Question
csharp_style_inlined_variable_declaration = false
csharp_style_prefer_primary_constructors = false
dotnet_diagnostic.CA1510.severity = none # "Use 'ArgumentNullException.ThrowIfNull' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1806.severity = none # SendEmailWithValidArgsShouldSendMailThroughClient calls TryParse but does not explicitly
dotnet_diagnostic.CA1827.severity = none # Count() is used where Any() could be used instead to improve performance
dotnet_diagnostic.CA1829.severity = none # Use the property instead of Enumerable.Count()
dotnet_diagnostic.CA1860.severity = none # Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
dotnet_diagnostic.CA2208.severity = none # Method .ctor passes
dotnet_diagnostic.CA2208.severity = none # Method .ctor passes
dotnet_diagnostic.CA2211.severity = none # Non-constant fields should not be visible
dotnet_diagnostic.CA2253.severity = none # Named placeholders in the logging message template should not be comprised
dotnet_diagnostic.CA2254.severity = none # The logging message template should not vary between calls to
dotnet_diagnostic.CS1998.severity = none # This async method lacks 'await' operators and will run synchronously
dotnet_diagnostic.CS8618.severity = none # Non-nullable field '_mockDalService' must contain a non-null value when exiting constructor
dotnet_diagnostic.CS8625.severity = none # Cannot convert null literal to non-nullable reference type
dotnet_diagnostic.IDE0005.severity = none # Using directive is unnecessary.
dotnet_diagnostic.IDE0017.severity = none # Object initialization can be simplified
dotnet_diagnostic.IDE0018.severity = none # Variable declaration can be inlined
dotnet_diagnostic.IDE0028.severity = none # Collection initialization can be simplified
dotnet_diagnostic.IDE0044.severity = none # Make field readonly
dotnet_diagnostic.IDE0046.severity = none # 'if' statement can be simplified
dotnet_diagnostic.IDE0052.severity = none # "Private member can be removed
dotnet_diagnostic.IDE0270.severity = none # Null check can be simplified
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor
dotnet_diagnostic.IDE1006.severity = none # Naming rule violation: These words must begin with upper case characters
dotnet_diagnostic.IDE2000.severity = error # IDE2000: Allow multiple blank lines
dotnet_diagnostic.NUnit2001.severity = none # Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model
dotnet_diagnostic.NUnit2004.severity = none # Consider using the constraint model
dotnet_diagnostic.NUnit2010.severity = none # Use Is.EqualTo constraint instead of direct comparison for better assertion messages in ca
dotnet_style_coalesce_expression = false
dotnet_style_object_initializer = false
dotnet_style_prefer_conditional_expression_over_return = false

View File

@ -0,0 +1 @@
[]

View File

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

View File

@ -0,0 +1,424 @@
{
"[markdown]": {
"editor.wordWrap": "off"
},
"files.exclude": {
"**/.git": false,
"**/node_modules": true
},
"files.watcherExclude": {
"**/node_modules": true
},
"cSpell.words": [
"abutton",
"accessibilities",
"accodingly",
"acknowledgmentby",
"Acks",
"actionsheet",
"Additonal",
"Addtional",
"againm",
"agendaview",
"Antlr",
"Appover",
"Appprrovers",
"Approvalog",
"Aprovers",
"Aproverslist",
"asax",
"aspnetmvc",
"Assignedto",
"Atachments",
"Attachemnt",
"Attachemnts",
"Attchment",
"auditee",
"Auditee",
"Auditees",
"automaically",
"Autthorized",
"beacuase",
"beforeunload",
"Belguim",
"bfound",
"bgcolor",
"Bies",
"binded",
"blackbackground",
"blackhover",
"blackpressed",
"blueenergy",
"blueopal",
"buttongroup",
"BYMRB",
"bytesgot",
"CAID",
"casection",
"CAXXXX",
"CCPCR",
"CCPCRB",
"cellspacing",
"Cheeso's",
"chkbx",
"Clib",
"colorpicker",
"columnmenu",
"columnsreorder",
"columnsresize",
"comming",
"Containmen",
"Copmments",
"correctiv",
"Correctivet",
"Creat",
"currentd",
"Cyle",
"dadada",
"darkbluehover",
"darkbluepressed",
"darkred",
"datafields",
"datasource",
"dataviz",
"datepicker",
"datetimepicker",
"dayview",
"Deletet",
"Delgation",
"DENITED",
"Deparmtent",
"departmentids",
"Descirption",
"devprog",
"dfeffc",
"Disp",
"Dispo",
"Dispoitio",
"Dispos",
"Dispositon",
"Dispostion",
"Dispostions",
"dispotypevalidation",
"Docbase",
"Documentum",
"Documetum",
"dont",
"downlaoded",
"draganddrop",
"dragcancel",
"dropdownlist",
"Eamils",
"ECNPCRB",
"Ecns",
"edmx",
"EECN",
"emai",
"emailparams",
"Emergrncy",
"energyblue",
"Eran",
"Esql",
"ETECN",
"EXCELOPENXML",
"existinglocation",
"Expando",
"extrafield",
"fadc",
"fbec",
"fcfdfd",
"fdff",
"fece",
"feeebd",
"ffdc",
"ffdd",
"fieldset",
"FILIPE",
"filtermenu",
"Fldr",
"flintstone",
"FLOWLOCS",
"FMEA",
"ftplib",
"FTPSPN",
"GETDATE",
"gitea",
"globaldocudms",
"glyphicons",
"groupable",
"Guids",
"halflings",
"Hexsize",
"highcontrast",
"Hmac",
"holdsteps",
"hostspecific",
"icenium",
"IECN",
"imagebrowser",
"IMRB",
"Infineon",
"Insertd",
"inverseicons",
"IPCRB",
"ISADMIN",
"islast",
"ISNULL",
"ITAR",
"jquery",
"jqueryval",
"jqwidgets",
"jqxbuttongroup",
"jqxbuttons",
"jqxcalendar",
"jqxchart",
"jqxcheckbox",
"jqxcolorpicker",
"jqxcombobox",
"jqxcore",
"jqxdata",
"jqxdatatable",
"jqxdatetimeinput",
"jqxdocking",
"jqxdockpanel",
"jqxdragdrop",
"jqxdropdownbutton",
"jqxdropdownlist",
"jqxexpander",
"jqxgauge",
"jqxgrid",
"jqxinput",
"jqxknockout",
"jqxlistbox",
"jqxlistmenu",
"jqxmaskedinput",
"jqxmenu",
"jqxnavigationbar",
"jqxnumberinput",
"jqxpanel",
"jqxpasswordinput",
"jqxprogressbar",
"jqxradiobutton",
"jqxrangeselector",
"jqxrating",
"jqxresponse",
"jqxscrollbar",
"jqxscrollview",
"jqxslider",
"jqxsplitter",
"jqxswitchbutton",
"jqxtabs",
"jqxtooltip",
"jqxtouch",
"jqxtree",
"jqxtreegrid",
"jqxtreemap",
"jqxvalidator",
"jqxwindow",
"kendogridcustom",
"kendoui",
"labelelement",
"labelledby",
"Leanred",
"lightgray",
"linkbutton",
"Linq",
"Listdiv",
"listview",
"Lnks",
"localfilename",
"loclist",
"logis",
"logtext",
"loopmis",
"lotdispo",
"LOTDISPSITION",
"Lotfile",
"lotlist",
"lotstatusoption",
"LTRIM",
"MADUREIRA",
"mailrelay",
"MDTM",
"meego",
"meetingid",
"menubutton",
"mesafi",
"metroblack",
"metrodark",
"miliseconds",
"modalview",
"modernizr",
"Modernizr",
"monthview",
"MRBIs",
"Mrbs",
"msecs",
"multipleextended",
"Navigatable",
"nbsp",
"newbase",
"newchange",
"newdi",
"newfilename",
"newsource",
"Newtonsoft",
"notications",
"Notifcation",
"Notifyf",
"NTLM",
"Nullcc",
"numerictextbox",
"objdata",
"OCAP",
"occured",
"odata",
"oldfilename",
"OLHOLD",
"onclick",
"onmousemove",
"OPDESC",
"OPENQUERY",
"Oper",
"operationslist",
"Orginator",
"Originatorname",
"Ouellette",
"Owin",
"pageable",
"Pageable",
"panelbar",
"parentid",
"parminput",
"parms",
"Parms",
"particula",
"pasv",
"PASV",
"PATINDEX",
"PCRB",
"PCRBID",
"pcrvalues",
"pdbonly",
"Preventitive",
"preventivet",
"Prevetative",
"proces",
"Processedl",
"procs",
"productfamilies",
"progess",
"progressbar",
"qrcode",
"Quanityt",
"rangebar",
"Recep",
"Recepient",
"recieved",
"recordlock",
"remotefilename",
"reorderable",
"reportform",
"reportslist",
"reportslistdiv",
"Reqquired",
"Reqs",
"Requiest",
"Responsibles",
"RETR",
"Revisioing",
"Revisioned",
"Revison",
"rgba",
"rkotian",
"RNFR",
"RNTO",
"Roless",
"roundbg",
"RTRIM",
"SAMDB",
"scroller",
"scrollview",
"seleced",
"selectionlog",
"Selectpart",
"sess",
"Sfisharepoint",
"shinyblack",
"showpassword",
"SIGNON",
"simpleparser",
"slddrw",
"sldprt",
"sortasc",
"sortascbutton",
"sortdesc",
"sortdescbutton",
"sortremove",
"sparkline",
"splitview",
"SPNMRB",
"SPNPDB",
"SSRS",
"Sssign",
"Staus",
"stylesheet",
"Submited",
"subrole",
"subroles",
"Succefully",
"Succesfully",
"sucessfully",
"SURP",
"Swashbuckle",
"SWRN",
"tabindex",
"tabstrip",
"Tahoma",
"taskcompleted",
"Tasklist",
"Taveler",
"TECN",
"TECNs",
"TEMIRWAP",
"tempecd",
"tempimplement",
"templabel",
"tempvalue",
"TEMSA",
"timepicker",
"Tobe",
"Toplevel",
"Totrav",
"trainingby",
"Traininglist",
"traininglistdiv",
"transanction",
"Trav",
"Traveller",
"Traverler",
"TRAVLELER",
"Travler",
"TREEVIEW",
"trigerred",
"ttinclude",
"Uhandled",
"Updat",
"Uplaod",
"Upto",
"userevents",
"userids",
"userlist",
"Validatable",
"valueelement",
"Variabls",
"Verdana",
"vgrid",
"viewmodel",
"vsdoc",
"whethere",
"windowsphone",
"Winsock",
"worlflow"
]
}

View File

@ -0,0 +1,109 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "User Secrets Init",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/FabApprovalWorkerService.csproj",
"init"
],
"problemMatcher": "$msCompile"
},
{
"label": "User Secrets Set",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/FabApprovalWorkerService.csproj",
"set",
"_UserSecretsId",
"e76dda63-1df3-422a-b758-1c057e5b1e25"
],
"problemMatcher": "$msCompile"
},
{
"label": "Format",
"command": "dotnet",
"type": "process",
"args": [
"format",
"--report",
".vscode",
"--verbosity",
"detailed",
"--severity",
"warn"
],
"problemMatcher": "$msCompile"
},
{
"label": "Format-Whitespaces",
"command": "dotnet",
"type": "process",
"args": [
"format",
"whitespace"
],
"problemMatcher": "$msCompile"
},
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/FabApprovalWorkerService.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/FabApprovalWorkerService.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/FabApprovalWorkerService.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "Publish AOT",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"-r",
"win-x64",
"-c",
"Release",
"-p:PublishAot=true",
"${workspaceFolder}/FabApprovalWorkerService.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -17,4 +17,4 @@ public class SmtpClientWrapper : ISmtpClientWrapper {
public void Send(MailMessage message) {
_client.Send(message);
}
}
}

View File

@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-FabApprovalWorkerService-e76dda63-1df3-422a-b758-1c057e5b1e25</UserSecretsId>
<UserSecretsId>e76dda63-1df3-422a-b758-1c057e5b1e25</UserSecretsId>
<ServerGarbageCollection>true</ServerGarbageCollection>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<Configurations>Debug;Release;Staging</Configurations>
@ -34,6 +34,7 @@
<PackageReference Include="Infineon.Monitoring.MonA" Version="3.0.1" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />

View File

@ -0,0 +1,133 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace FabApprovalWorkerService.Models;
public record AppSettings(string AsmHtrTrainingGroupName,
string CleansTrainingGroupName,
string EpiProTrainingGroupName,
string BaseUrl,
string Company,
string DbConnectionString,
string EnvironmentName,
bool ShouldSendEmail,
string WorkerServiceMonInResource,
string FqaTrainingGroupName,
string MonInSite,
string NewBaseUrl,
string OldBaseUrl,
string PackagingAndLabelingTrainingGroupName,
string SiProductionTrainingGroupName,
string UserCertificationRecordsFilePath,
string WorkingDirectoryName) {
public override string ToString() {
string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings);
return result;
}
public static AppSettings Get(IConfigurationRoot configurationRoot) {
AppSettings? result;
try {
#pragma warning disable IL3050, IL2026
result = configurationRoot.Get<AppSettings>() ?? throw new Exception();
#pragma warning restore IL3050, IL2026
} catch (Exception) {
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())}");
}
return result;
}
internal static void SetEnvironmentVariables(HostApplicationBuilder builder) {
builder.Configuration.AddUserSecrets<Program>();
AppSettings appSettings = Get(builder.Configuration);
Environment.SetEnvironmentVariable("AsmHtrTrainingGroupName", appSettings.AsmHtrTrainingGroupName);
Environment.SetEnvironmentVariable("CleansTrainingGroupName", appSettings.CleansTrainingGroupName);
Environment.SetEnvironmentVariable("EpiProTrainingGroupName", appSettings.EpiProTrainingGroupName);
Environment.SetEnvironmentVariable("FabApprovalBaseUrl", appSettings.BaseUrl);
Environment.SetEnvironmentVariable("FabApprovalDbConnectionString", appSettings.DbConnectionString);
Environment.SetEnvironmentVariable("FabApprovalEnvironmentName", appSettings.EnvironmentName);
Environment.SetEnvironmentVariable("FabApprovalShouldSendEmail", appSettings.ShouldSendEmail.ToString());
Environment.SetEnvironmentVariable("FabApprovalWorkerServiceMonInResource", appSettings.WorkerServiceMonInResource);
Environment.SetEnvironmentVariable("FqaTrainingGroupName", appSettings.FqaTrainingGroupName);
Environment.SetEnvironmentVariable("MonInSite", appSettings.MonInSite);
Environment.SetEnvironmentVariable("NewFabApprovalBaseUrl", appSettings.NewBaseUrl);
Environment.SetEnvironmentVariable("OldFabApprovalUrl", appSettings.OldBaseUrl);
Environment.SetEnvironmentVariable("PackagingAndLabelingTrainingGroupName", appSettings.PackagingAndLabelingTrainingGroupName);
Environment.SetEnvironmentVariable("SiProductionTrainingGroupName", appSettings.SiProductionTrainingGroupName);
Environment.SetEnvironmentVariable("UserCertificationRecordsFilePath", appSettings.UserCertificationRecordsFilePath);
}
internal static AppSettings LoadEnvironmentVariables() {
AppSettings result;
try {
string asmHtrTrainingGroupName = Environment.GetEnvironmentVariable("AsmHtrTrainingGroupName") ??
throw new ArgumentNullException("AsmHtrTrainingGroupName environment variable not found");
string cleansTrainingGroupName = Environment.GetEnvironmentVariable("CleansTrainingGroupName") ??
throw new ArgumentNullException("CleansTrainingGroupName environment variable not found");
string epiProTrainingGroupName = Environment.GetEnvironmentVariable("EpiProTrainingGroupName") ??
throw new ArgumentNullException("EpiProTrainingGroupName environment variable not found");
string baseUrl = Environment.GetEnvironmentVariable("FabApprovalBaseUrl") ??
throw new ArgumentNullException("FabApprovalBaseUrl environment variable not found");
string dbConnectionString = Environment.GetEnvironmentVariable("FabApprovalDbConnectionString") ??
throw new ArgumentNullException("FabApprovalDbConnectionString environment variable not found");
string environmentName = Environment.GetEnvironmentVariable("FabApprovalEnvironmentName") ??
throw new ArgumentNullException("FabApprovalEnvironmentName environment variable not found");
if (!bool.TryParse(Environment.GetEnvironmentVariable("FabApprovalShouldSendEmail"), out bool shouldSendEmail))
throw new ArgumentNullException("FabApprovalShouldSendEmail environment variable not found");
string workerServiceMonInResource = Environment.GetEnvironmentVariable("FabApprovalWorkerServiceMonInResource") ??
throw new ArgumentNullException("FabApprovalWorkerServiceMonInResource environment variable not found");
string fqaTrainingGroupName = Environment.GetEnvironmentVariable("FqaTrainingGroupName") ??
throw new ArgumentNullException("FqaTrainingGroupName environment variable not found");
string monInSite = Environment.GetEnvironmentVariable("MonInSite") ??
throw new ArgumentNullException("MonInSite environment variable not found");
string newBaseUrl = Environment.GetEnvironmentVariable("NewFabApprovalBaseUrl") ??
throw new ArgumentNullException("NewFabApprovalBaseUrl environment variable not found");
string oldBaseUrl = Environment.GetEnvironmentVariable("OldFabApprovalUrl") ??
throw new ArgumentNullException("OldFabApprovalUrl environment variable not found");
string packagingAndLabelingTrainingGroupName = Environment.GetEnvironmentVariable("PackagingAndLabelingTrainingGroupName") ??
throw new ArgumentNullException("PackagingAndLabelingTrainingGroupName environment variable not found");
string siProductionTrainingGroupName = Environment.GetEnvironmentVariable("SiProductionTrainingGroupName") ??
throw new ArgumentNullException("SiProductionTrainingGroupName environment variable not found");
string userCertificationRecordsFilePath = Environment.GetEnvironmentVariable("UserCertificationRecordsFilePath") ??
throw new ArgumentNullException("UserCertificationRecordsFilePath environment variable not found");
result = new(AsmHtrTrainingGroupName: asmHtrTrainingGroupName,
CleansTrainingGroupName: cleansTrainingGroupName,
EpiProTrainingGroupName: epiProTrainingGroupName,
BaseUrl: baseUrl,
Company: "Infineon Technologies Americas Corp.",
DbConnectionString: dbConnectionString,
EnvironmentName: environmentName,
ShouldSendEmail: shouldSendEmail,
WorkerServiceMonInResource: workerServiceMonInResource,
FqaTrainingGroupName: fqaTrainingGroupName,
MonInSite: monInSite,
NewBaseUrl: newBaseUrl,
OldBaseUrl: oldBaseUrl,
PackagingAndLabelingTrainingGroupName: packagingAndLabelingTrainingGroupName,
SiProductionTrainingGroupName: siProductionTrainingGroupName,
UserCertificationRecordsFilePath: userCertificationRecordsFilePath,
WorkingDirectoryName: "IFXApps");
} catch (Exception ex) {
NLog.LogManager.GetCurrentClassLogger().Error($"Unable to load environment variables, because {ex.Message}");
throw;
}
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(AppSettings))]
internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext {
}

View File

@ -0,0 +1,22 @@
using FabApprovalWorkerService.Utilities;
namespace FabApprovalWorkerService.Models;
public class Approval {
public int ApprovalID { get; set; }
public required int IssueID { get; set; }
public required string RoleName { get; set; }
public required string SubRole { get; set; }
public required int UserID { get; set; }
public User? User { get; set; }
public required int SubRoleID { get; set; }
public int ItemStatus { get; set; } = 0;
public string StatusMessage = "Assigned";
public DateTime NotifyDate { get; set; } = DateTimeUtilities.MIN_DT;
public required DateTime AssignedDate { get; set; }
public DateTime CompletedDate { get; set; } = DateTimeUtilities.MAX_DT;
public string Comments { get; set; } = "";
public int Step { get; set; } = 1;
public string SubRoleCategoryItem { get; set; } = "";
public int TaskID { get; set; }
}

View File

@ -1,10 +1,10 @@
namespace FabApprovalWorkerService.Models;
public class CorrectiveAction {
public required int CANo { get; set; }
public required int CANo { get; set; }
public bool ApprovalStatus { get; set; }
public DateTime FollowUpDate { get; set; }
public DateTime ClosedDate { get; set; }
public int QAID { get; set; }
public required string CATitle { get; set; }
}
}

View File

@ -12,4 +12,4 @@ public class ECN {
public required int OriginatorID { get; set; }
public required string Title { get; set; }
public DateTime CloseDate { get; set; } = DateTime.MaxValue;
}
}

View File

@ -0,0 +1,29 @@
using FabApprovalWorkerService.Utilities;
namespace FabApprovalWorkerService.Models;
public class MRB {
public int MRBNumber { get; set; }
public int OriginatorID { get; set; }
public string Title { get; set; } = "";
public DateTime SubmittedDate { get; set; } = DateTimeUtilities.MIN_DT;
public DateTime CloseDate { get; set; } = DateTimeUtilities.MAX_DT;
public DateTime CancelDate { get; set; } = DateTimeUtilities.MAX_DT;
public DateTime ApprovalDate { get; set; } = DateTimeUtilities.MAX_DT;
public string IssueDescription { get; set; } = "";
public int NumberOfLotsAffected { get; set; }
public int Val { get; set; }
public bool CustomerImpacted { get; set; } = false;
public string CustomerImpactedName { get; set; } = "";
public string Department { get; set; } = "";
public string Process { get; set; } = "";
public int RMANo { get; set; }
public string PCRBNo { get; set; } = "";
public bool SpecsImpacted { get; set; } = false;
public int ProcessECNNumber { get; set; }
public bool TrainingRequired { get; set; } = false;
public required int StageNo { get; set; }
public required string Status { get; set; }
public string Tool { get; set; } = "";
public string Category { get; set; } = string.Empty;
}

View File

@ -7,4 +7,4 @@ public class OOOTemp {
public required DateTime OOOStartDate { get; set; }
public required DateTime OOOExpirationDate { get; set; }
public bool Processed { get; set; } = false;
}
}

View File

@ -0,0 +1,18 @@
using FabApprovalWorkerService.Utilities;
namespace FabApprovalWorkerService.Models;
public class PCRB {
public int PlanNumber { get; set; }
public int OwnerID { get; set; }
public string OwnerName { get; set; } = "";
public string Title { get; set; } = "";
public string ChangeLevel { get; set; } = "Mesa";
public bool IsITAR { get; set; } = false;
public int CurrentStep { get; set; } = 0;
public string ReasonForChange { get; set; } = "";
public string ChangeDescription { get; set; } = "";
public DateTime InsertTimeStamp { get; set; } = DateTimeUtilities.MIN_DT;
public DateTime LastUpdateDate { get; set; } = DateTimeUtilities.MIN_DT;
public DateTime ClosedDate { get; set; } = DateTimeUtilities.MAX_DT;
}

View File

@ -12,5 +12,5 @@ public class TrainingAssignment {
public bool status { get; set; } = false;
public bool Deleted { get; set; } = false;
public DateTime DeletedDate { get; set; }
public DateTime LastNotification { get; set; }
}
public DateTime LastNotification { get; set; }
}

View File

@ -1,7 +1,7 @@
using Dapper.Contrib.Extensions;
namespace FabApprovalWorkerService.Models;
[Table ("Users")]
[Table("Users")]
public class User {
[Key]
public required int UserID { get; set; }
@ -16,7 +16,7 @@ public class User {
public DateTime OOOStartDate { get; set; }
public DateTime OOOExpirationDate { get; set; }
public int DelegatedTo { get; set; }
public required bool CanViewITAR { get; set; }
public required bool CanViewITAR { get; set; }
public required bool IsManager { get; set; }
public bool IsCleansCertified { get; set; } = false;
public bool IsAnyLevelCertified { get; set; } = false;
@ -25,4 +25,4 @@ public class User {
public bool IsFqaCertified { get; set; } = false;
public bool IsFqaAssessmentCertified { get; set; } = false;
public bool IsActive { get; set; } = false;
}
}

View File

@ -5,4 +5,4 @@ public class UserSubRole {
public required int UserID { get; set; }
public required int SubRoleID { get; set; }
public bool Delegated { get; set; } = false;
}
}

View File

@ -1,4 +1,8 @@
using System.Diagnostics;
using System.Net.Mail;
using FabApprovalWorkerService.Clients;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;
using FabApprovalWorkerService.Workers;
@ -6,8 +10,6 @@ using NLog.Extensions.Logging;
using Quartz;
using System.Net.Mail;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.ClearProviders();
@ -16,10 +18,20 @@ builder.Logging.AddNLog();
builder.Services.AddHttpClient();
if (Debugger.IsAttached) {
string? asmHtrTrainingGroupName = Environment.GetEnvironmentVariable("AsmHtrTrainingGroupName");
if (string.IsNullOrEmpty(asmHtrTrainingGroupName)) {
AppSettings.SetEnvironmentVariables(builder);
}
}
AppSettings appSettings = AppSettings.LoadEnvironmentVariables();
builder.Services.AddSingleton(_ => appSettings);
builder.Services.AddScoped<IDbConnectionService, DbConnectionService>();
builder.Services.AddScoped<IMonInClient, MonInClient>();
builder.Services.AddScoped<IDalService, DalService>();
builder.Services.AddScoped<SmtpClient>((serviceProvider) => {
builder.Services.AddScoped((serviceProvider) => {
return new SmtpClient("mailrelay-external.infineon.com");
});
builder.Services.AddScoped<ISmtpClientWrapper, SmtpClientWrapper>();
@ -29,6 +41,9 @@ builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IECNService, ECNService>();
builder.Services.AddScoped<ITrainingService, TrainingService>();
builder.Services.AddScoped<ICorrectiveActionService, CorrectiveActionService>();
builder.Services.AddScoped<IPCRBService, PCRBService>();
builder.Services.AddScoped<IMRBService, MRBService>();
builder.Services.AddScoped<IApprovalService, ApprovalService>();
builder.Services.AddQuartz(q => {
JobKey pendingOOOStatusJob = new JobKey("Pending OOO status job");
@ -100,6 +115,16 @@ builder.Services.AddQuartz(q => {
.WithIdentity("Certification training group trigger")
.WithCronSchedule(CronScheduleBuilder.DailyAtHourAndMinute(1, 0))
);
JobKey approvalNotificationJob = new JobKey("Approval notification job");
q.AddJob<ApprovalNotificationWorker>(opts => opts
.WithIdentity(approvalNotificationJob)
);
q.AddTrigger(opts => opts
.ForJob(approvalNotificationJob)
.WithIdentity("Approval notification trigger")
.WithCronSchedule(CronScheduleBuilder.DailyAtHourAndMinute(6, 0))
);
});
builder.Services.AddQuartzHostedService(opt => {
@ -113,4 +138,7 @@ builder.Services.AddHostedService<WindowsService>();
IHost app = builder.Build();
app.Run();
if (Debugger.IsAttached)
app.Services.GetRequiredService<IApprovalService>();
app.Run();

View File

@ -0,0 +1,66 @@
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Utilities;
namespace FabApprovalWorkerService.Services;
public interface IApprovalService {
Task<IEnumerable<Approval>> GetActiveApprovalsWithNotificationOlderThanFiveDays();
Task UpdateApproval(Approval approval);
}
public class ApprovalService : IApprovalService {
private readonly ILogger<ApprovalService> _logger;
private readonly IDalService _dalService;
public ApprovalService(ILogger<ApprovalService> logger, IDalService dalService) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_dalService = dalService ?? throw new ArgumentNullException("IDalService not injected");
}
public async Task<IEnumerable<Approval>> GetActiveApprovalsWithNotificationOlderThanFiveDays() {
try {
_logger.LogInformation($"Attempting to get active approvals with notifications older than five days");
StringBuilder queryBuilder = new();
queryBuilder.Append("select * from Approval where ");
queryBuilder.Append($"ItemStatus=0 and AssignedDate > '{DateTimeOffset.Now.AddDays(-365).DateTime.ToString("yyyy-MM-dd HH:mm:ss")}' and ");
queryBuilder.Append($"(CompletedDate is null or CompletedDate >= '{DateTimeUtilities.MAX_DT.ToString("yyyy-MM-dd HH:mm")}') and ");
queryBuilder.Append($"(NotifyDate is null or NotifyDate < '{DateTimeOffset.Now.AddDays(-5).DateTime.ToString("yyyy-MM-dd HH:mm")}')");
IEnumerable<Approval> approvals = await _dalService.QueryAsync<Approval>(queryBuilder.ToString());
return approvals;
} catch (Exception ex) {
_logger.LogError($"Unable to get active approvals with notifications older than five days, because {ex.Message}");
throw;
}
}
public async Task UpdateApproval(Approval approval) {
try {
_logger.LogInformation("Attempting to update an approval");
if (approval is null) throw new ArgumentNullException("Approval cannot be null");
StringBuilder queryBuilder = new();
queryBuilder.Append($"update Approval set IssueID={approval.IssueID}, RoleName='{approval.RoleName}', ");
queryBuilder.Append($"SubRole='{approval.SubRole}', UserID={approval.UserID}, SubRoleID={approval.SubRoleID}, ");
queryBuilder.Append($"ItemStatus={Convert.ToInt32(approval.ItemStatus)}, Step={approval.Step}, ");
queryBuilder.Append($"NotifyDate='{approval.NotifyDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"AssignedDate='{approval.AssignedDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"CompletedDate='{approval.CompletedDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"Comments='{approval.Comments.Replace("'", "''")}', ");
queryBuilder.Append($"TaskID={approval.TaskID} ");
queryBuilder.Append($"where ApprovalID={approval.ApprovalID};");
int rowsUpdated = await _dalService.ExecuteAsync(queryBuilder.ToString());
if (rowsUpdated <= 0) throw new Exception("Unable to update approval in database");
} catch (Exception ex) {
_logger.LogError($"Approval update failed, because {ex.Message}");
throw;
}
}
}

View File

@ -1,12 +1,15 @@
using FabApprovalWorkerService.Models;
using System.Text;
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Utilities;
namespace FabApprovalWorkerService.Services;
public interface ICorrectiveActionService {
Task<IEnumerable<CorrectiveAction>> GetCorrectiveActionsWithFollowUpInFiveDays();
Task CreateCorrectiveActionFollowUpApproval(int caNo, int qaId);
Task<bool> CANumberIsActive(int number);
Task<CorrectiveAction> GetCorrectiveActionById(int id);
}
public class CorrectiveActionService : ICorrectiveActionService {
@ -31,7 +34,7 @@ public class CorrectiveActionService : ICorrectiveActionService {
queryBuilder.Append("insert into Approval (IssueID, RoleName, SubRole, UserID, SubRoleID, ItemStatus, Step, ");
queryBuilder.Append("AssignedDate, NotifyDate,RoleAssignedDate, ApprovalType, DocumentTypeID) ");
queryBuilder.Append($"values ({caNo}, '8DQAFollowUp', '8DQAFollowUp', {qaId}, 335, 0, 2, ");
queryBuilder.Append($"{today}, {today}, {today}, 1, 9);");
queryBuilder.Append($"'{today}', '{today}', '{today}', 1, 9);");
await _dalService.ExecuteAsync(queryBuilder.ToString());
} catch (Exception ex) {
@ -64,4 +67,43 @@ public class CorrectiveActionService : ICorrectiveActionService {
throw;
}
}
}
public async Task<bool> CANumberIsActive(int number) {
try {
_logger.LogInformation($"Attempting to determine if {number} is an active CA#");
if (number <= 0) return false;
StringBuilder queryBuilder = new();
queryBuilder.Append($"select count(CANo) as count from _8DCorrectiveAction ");
queryBuilder.Append($"where CANo={number} and Deleted=0 and ");
queryBuilder.Append($"(ClosedDate is null or ClosedDate >= '{DateTimeUtilities.MAX_DT.ToString("yyyy-MM-dd HH:mm")}')");
int rowsReturned = (await _dalService.QueryAsync<int>(queryBuilder.ToString())).FirstOrDefault();
return rowsReturned > 0;
} catch (Exception ex) {
_logger.LogError($"Unable to determine if {number} is an active CA#, because {ex.Message}");
throw;
}
}
public async Task<CorrectiveAction> GetCorrectiveActionById(int id) {
try {
_logger.LogInformation($"Attempting to get CA# {id}");
if (id <= 0) throw new ArgumentException($"{id} is not a valid CA#");
string sql = $"select * from _8DCorrectiveAction where CANo={id}";
CorrectiveAction? ca = (await _dalService.QueryAsync<CorrectiveAction>(sql)).FirstOrDefault();
if (ca is null) throw new Exception($"no CA found with CA# {id}");
return ca;
} catch (Exception ex) {
_logger.LogError($"Unable to get CA# {id}, because {ex.Message}");
throw;
}
}
}

View File

@ -1,6 +1,6 @@
using Dapper;
using System.Data;
using System.Data;
using Dapper;
namespace FabApprovalWorkerService.Services;
@ -28,7 +28,7 @@ public class DalService : IDalService {
int remainingRetries = RETRIES;
bool queryWasSuccessful = false;
Exception exception = null;
Exception? exception = null;
IEnumerable<T> result = new List<T>();
while (!queryWasSuccessful && remainingRetries > 0) {
int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL;
@ -60,7 +60,7 @@ public class DalService : IDalService {
int remainingRetries = RETRIES;
bool queryWasSuccessful = false;
Exception exception = null;
Exception? exception = null;
int rowsAffected = 0;
while (!queryWasSuccessful && remainingRetries > 0) {
int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL;
@ -86,4 +86,4 @@ public class DalService : IDalService {
return rowsAffected;
}
}
}

View File

@ -1,7 +1,8 @@
using Microsoft.Data.SqlClient;
using Microsoft.Data.Sqlite;
using System.Data;
using System.Data;
using FabApprovalWorkerService.Models;
using Microsoft.Data.SqlClient;
namespace FabApprovalWorkerService.Services;
@ -10,21 +11,13 @@ public interface IDbConnectionService {
}
public class DbConnectionService : IDbConnectionService {
private readonly string _envName;
private readonly string _dbConnectionString;
public DbConnectionService() {
_envName = Environment.GetEnvironmentVariable("FabApprovalEnvironmentName") ??
throw new ArgumentNullException("FabApprovalEnvironmentName environment variable not found");
_dbConnectionString = Environment.GetEnvironmentVariable("FabApprovalDbConnectionString") ??
throw new ArgumentNullException("FabApprovalDbConnectionString environment variable not found");
public DbConnectionService(AppSettings appSettings) {
_dbConnectionString = appSettings.DbConnectionString;
}
public IDbConnection GetConnection() {
if (_envName.ToLower().Equals("development")) {
return new SqliteConnection(_dbConnectionString);
} else {
return new SqlConnection(_dbConnectionString);
}
return new SqlConnection(_dbConnectionString);
}
}
}

View File

@ -1,6 +1,7 @@
using FabApprovalWorkerService.Models;
using System.Text;
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Utilities;
namespace FabApprovalWorkerService.Services;
@ -10,6 +11,7 @@ public interface IECNService {
Task<IEnumerable<string>> GetTECNNotificationUserEmails();
Task<ECN> GetEcnByNumber(int ecnNumber);
bool EcnIsExpired(ECN ecn);
Task<bool> ECNNumberIsActive(int number);
}
public class ECNService : IECNService {
@ -78,8 +80,8 @@ public class ECNService : IECNService {
StringBuilder queryBuilder = new StringBuilder();
queryBuilder.Append("select ECNNumber, IsTECN, ExpirationDate, ExtensionDate, OriginatorID, Title ");
queryBuilder.Append($"from ECN where IsTECN = 1 and ");
queryBuilder.Append("Cancelled = 0 and Deleted = 0 ");
queryBuilder.Append("and (CloseDate IS NULL or CloseDate = '');");
queryBuilder.Append("Cancelled = 0 and Deleted = 0 and ");
queryBuilder.Append($"CancellationDate is null;");
IEnumerable<ECN> activeTecns = await _dalService.QueryAsync<ECN>(queryBuilder.ToString());
@ -116,8 +118,8 @@ public class ECNService : IECNService {
StringBuilder queryBuilder = new StringBuilder();
queryBuilder.Append("select * from ECN ");
queryBuilder.Append($"where IsTECN = 1 and ");
queryBuilder.Append("Cancelled = 0 and Deleted = 0 ");
queryBuilder.Append("and (CloseDate IS NULL or CloseDate = '');");
queryBuilder.Append("Cancelled = 0 and Deleted = 0 and ");
queryBuilder.Append($"CancellationDate is null;");
IEnumerable<ECN> activeTecns = (await _dalService.QueryAsync<ECN>(queryBuilder.ToString()));
@ -163,4 +165,24 @@ public class ECNService : IECNService {
throw;
}
}
}
public async Task<bool> ECNNumberIsActive(int number) {
try {
_logger.LogInformation($"Attempting to determine if {number} is a valid ECN#");
if (number <= 0) return false;
StringBuilder queryBuilder = new();
queryBuilder.Append($"select count(ECNNumber) as count from ECN where ECNNumber={number} and ");
queryBuilder.Append("Deleted=0 and Cancelled=0 and ");
queryBuilder.Append($"(CloseDate is null or CloseDate >= '{DateTimeUtilities.MAX_DT.ToString("yyyy-MM-dd HH:mm")}')");
int rowsReturned = (await _dalService.QueryAsync<int>(queryBuilder.ToString())).FirstOrDefault();
return rowsReturned > 0;
} catch (Exception ex) {
_logger.LogError($"Unable to determine if {number} is a valid ECN#, because {ex.Message}");
throw;
}
}
}

View File

@ -0,0 +1,59 @@
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Utilities;
namespace FabApprovalWorkerService.Services;
public interface IMRBService {
Task<bool> MRBNumberIsActive(int number);
Task<MRB> GetMRBById(int id);
}
public class MRBService : IMRBService {
private readonly ILogger<MRBService> _logger;
private readonly IDalService _dalService;
public MRBService(ILogger<MRBService> logger, IDalService dalService) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_dalService = dalService ?? throw new ArgumentNullException("IDalService not injected");
}
public async Task<bool> MRBNumberIsActive(int number) {
try {
_logger.LogInformation($"Attempting to determine if {number} is an active MRB#");
if (number <= 0) return false;
StringBuilder queryBuilder = new();
queryBuilder.Append($"select count(MRBNumber) as count from MRB where MRBNumber={number} and ");
queryBuilder.Append($"(CloseDate is null or CloseDate >= '{DateTimeUtilities.MAX_DT.ToString("yyyy-MM-dd HH:mm")}')");
int rowsReturned = (await _dalService.QueryAsync<int>(queryBuilder.ToString())).FirstOrDefault();
return rowsReturned > 0;
} catch (Exception ex) {
_logger.LogError($"Unable to determine if {number} is an active MRB#, because {ex.Message}");
throw;
}
}
public async Task<MRB> GetMRBById(int id) {
try {
_logger.LogInformation("Attempting to get an MRB by ID");
if (id < 0) throw new ArgumentException("Invalid MRB number");
string sql = $"select * from MRB where MRBNumber={id}";
MRB? mrb = (await _dalService.QueryAsync<MRB>(sql)).FirstOrDefault();
if (mrb is null) throw new Exception($"Unable to get MRB {id}");
return mrb;
} catch (Exception ex) {
_logger.LogError($"Unable to get MRB# {id}, because {ex.Message}");
throw;
}
}
}

View File

@ -1,4 +1,6 @@
using Infineon.Monitoring.MonA;
using FabApprovalWorkerService.Models;
using Infineon.Monitoring.MonA;
namespace FabApprovalWorkerService.Services;
@ -13,13 +15,11 @@ public class MonInClient : IMonInClient {
private readonly string _site;
private readonly string _resource;
public MonInClient(ILogger<MonInClient> logger) {
public MonInClient(ILogger<MonInClient> logger, AppSettings appSettings) {
_logger = logger ??
throw new ArgumentNullException("ILogger not injected");
_site = Environment.GetEnvironmentVariable("MonInSite") ??
throw new ArgumentNullException("MonInSite environment variable not found");
_resource = Environment.GetEnvironmentVariable("FabApprovalWorkerServiceMonInResource") ??
throw new ArgumentNullException("FabApprovalWorkerServiceMonInResource environment variable not found");
_site = appSettings.MonInSite;
_resource = appSettings.WorkerServiceMonInResource;
}
public void PostMetric(string metricName, double metricValue) {
@ -55,4 +55,4 @@ public class MonInClient : IMonInClient {
ex.Message);
}
}
}
}

View File

@ -0,0 +1,60 @@
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Utilities;
namespace FabApprovalWorkerService.Services;
public interface IPCRBService {
Task<bool> PCRBNumberIsActive(int number);
public Task<PCRB> GetPCRBByPlanNumber(int planNumber);
}
public class PCRBService : IPCRBService {
private readonly ILogger<PCRBService> _logger;
private readonly IDalService _dalService;
public PCRBService(ILogger<PCRBService> logger, IDalService dalService) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_dalService = dalService ?? throw new ArgumentNullException("IDalService not injected");
}
public async Task<bool> PCRBNumberIsActive(int number) {
try {
_logger.LogInformation($"Attempting to determine if {number} is an active PCRB#");
if (number <= 0) return false;
StringBuilder queryBuilder = new();
queryBuilder.Append("select count(PlanNumber) as count from CCChangeControl ");
queryBuilder.Append($"where PlanNumber={number} and ");
queryBuilder.Append($"(ClosedDate is null or ClosedDate >= '{DateTimeUtilities.MAX_DT.ToString("yyyy-MM-dd HH:mm")}')");
int rowsReturned = (await _dalService.QueryAsync<int>(queryBuilder.ToString())).FirstOrDefault();
return rowsReturned > 0;
} catch (Exception ex) {
_logger.LogError($"Unable to determine if {number} is an active PCRB#, because {ex.Message}");
throw;
}
}
public async Task<PCRB> GetPCRBByPlanNumber(int planNumber) {
try {
_logger.LogInformation("Attempting to get a PCRB by plan#");
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB#");
string sql = $"select * from CCChangeControl where PlanNumber={planNumber}";
PCRB? pcrb = (await _dalService.QueryAsync<PCRB>(sql)).FirstOrDefault();
if (pcrb is null) throw new Exception($"unable to find PCRB {planNumber}");
return pcrb;
} catch (Exception ex) {
_logger.LogError($"Unable to get PCRB# {planNumber}, because {ex.Message}");
throw;
}
}
}

View File

@ -1,9 +1,10 @@
using FabApprovalWorkerService.Clients;
using System.Net.Mail;
using FabApprovalWorkerService.Clients;
using FabApprovalWorkerService.Models;
using Microsoft.IdentityModel.Tokens;
using System.Net.Mail;
namespace FabApprovalWorkerService.Services;
public interface ISmtpService {
@ -15,13 +16,19 @@ public class SmtpService : ISmtpService {
private ISmtpClientWrapper _smtpClient;
private bool _shouldSendEmail;
public SmtpService(ILogger<SmtpService> logger, ISmtpClientWrapper smtpClient) {
public SmtpService(ILogger<SmtpService> logger,
ISmtpClientWrapper smtpClient,
AppSettings? appSettings = null) {
_logger = logger ??
throw new ArgumentNullException("ILogger not injected");
_smtpClient = smtpClient ??
throw new ArgumentNullException("SmtpClient not injected");
if (!Boolean.TryParse(Environment.GetEnvironmentVariable("FabApprovalShouldSendEmail"), out _shouldSendEmail))
throw new ArgumentNullException("FabApprovalShouldSendEmail environment variable not found");
if (appSettings is not null)
_shouldSendEmail = appSettings.ShouldSendEmail;
else {
if (!bool.TryParse(Environment.GetEnvironmentVariable("FabApprovalShouldSendEmail"), out _shouldSendEmail))
throw new ArgumentNullException("FabApprovalShouldSendEmail environment variable not found");
}
}
public async Task<bool> SendEmail(IEnumerable<MailAddress> recipients,
@ -32,7 +39,7 @@ public class SmtpService : ISmtpService {
if (ccRecipients is null) throw new ArgumentNullException("ccRecipients cannot be null!");
if (subject.IsNullOrEmpty()) throw new ArgumentNullException("subject cannot be null or empty!");
if (body.IsNullOrEmpty()) throw new ArgumentNullException("body cannot be null or empty!");
return await Task.Run(() => {
int maxRetries = 3;
int backoffSeconds = 30;
@ -66,6 +73,7 @@ public class SmtpService : ISmtpService {
}
}
} else {
_logger.LogInformation("Not sending email per configuration");
messageWasSent = true;
}
} catch (Exception ex) {
@ -75,4 +83,4 @@ public class SmtpService : ISmtpService {
return messageWasSent;
});
}
}
}

View File

@ -1,8 +1,8 @@
using FabApprovalWorkerService.Models;
using System.Text;
using System.Text;
using System.Text.Json;
using FabApprovalWorkerService.Models;
namespace FabApprovalWorkerService.Services;
public interface ITrainingService {
@ -30,20 +30,25 @@ public class TrainingService : ITrainingService {
private readonly string _userCertRecordsFilePath;
public TrainingService(ILogger<TrainingService> logger, IDalService dalService, IUserService userService) {
public TrainingService(ILogger<TrainingService> logger,
IDalService dalService,
IUserService userService,
AppSettings? appSettings = null) {
_logger = logger ??
throw new ArgumentNullException("ILogger not injected");
_dalService = dalService ??
throw new ArgumentNullException("IDalService not injected");
_userService = userService ??
throw new ArgumentNullException("IUserService not injected");
_userCertRecordsFilePath = Environment.GetEnvironmentVariable("UserCertificationRecordsFilePath") ??
throw new ArgumentNullException("UserCertificationRecordsFilePath environment variable not found");
_userCertRecordsFilePath = appSettings is not null
? appSettings.UserCertificationRecordsFilePath
: Environment.GetEnvironmentVariable("UserCertificationRecordsFilePath") ??
throw new ArgumentNullException("UserCertificationRecordsFilePath environment variable not found");
}
public async Task DeleteDocAssignment(int trainingAssignmentId) {
if (trainingAssignmentId <= 0) throw new ArgumentException($"Invalid training assignment id: {trainingAssignmentId}");
try {
_logger.LogInformation($"Attempting to delete training doc assignments for training assignment {trainingAssignmentId}");
@ -84,7 +89,7 @@ public class TrainingService : ITrainingService {
}
public async Task DeleteTrainingAssignmentById(int trainingAssignmentId) {
if (trainingAssignmentId <= 0)
if (trainingAssignmentId <= 0)
throw new ArgumentException($"Invalid training assignment id: {trainingAssignmentId}");
try {
@ -341,4 +346,4 @@ public class TrainingService : ITrainingService {
throw;
}
}
}
}

View File

@ -1,9 +1,9 @@
using FabApprovalWorkerService.Models;
using System.Text;
using FabApprovalWorkerService.Models;
using Microsoft.IdentityModel.Tokens;
using System.Text;
namespace FabApprovalWorkerService.Services;
public interface IUserService {
@ -204,9 +204,8 @@ public class UserService : IUserService {
_logger.LogInformation($"User {userId} delegated sub roles to {delegatedUserId}");
StringBuilder queryBuilder = new StringBuilder();
queryBuilder.Append("select SubRoleID from OOODelegatedRoles O inner join UserSubRole U ");
queryBuilder.Append("on O.DelegatedSubRoleID = U.UserSubRoleID ");
queryBuilder.Append($"where O.UserID = {userId} and Active = 1");
queryBuilder.Append("select DelegatedSubRoleID from OOODelegatedRoles ");
queryBuilder.Append($"where UserID = {userId} and Active = 1");
List<int> userSubRoleIds = (await _dalService.QueryAsync<int>(queryBuilder.ToString())).ToList();
@ -268,9 +267,8 @@ public class UserService : IUserService {
StringBuilder queryBuilder = new StringBuilder();
queryBuilder.Append("select SubRoleID from OOODelegatedRoles O inner join UserSubRole U ");
queryBuilder.Append("on O.DelegatedSubRoleID = U.UserSubRoleID ");
queryBuilder.Append($"where O.UserID = {userId} and Active = 1");
queryBuilder.Append("select DelegatedSubRoleID from OOODelegatedRoles ");
queryBuilder.Append($"where UserID = {userId} and Active = 1");
List<int> userSubRoleIds = (await _dalService.QueryAsync<int>(queryBuilder.ToString())).ToList();
@ -419,4 +417,4 @@ public class UserService : IUserService {
throw;
}
}
}
}

View File

@ -39,4 +39,4 @@ public class WindowsService : BackgroundService {
Environment.Exit(1);
}
}
}
}

View File

@ -0,0 +1,14 @@
namespace FabApprovalWorkerService.Utilities;
public class DateTimeUtilities {
public static DateTime MIN_DT = new DateTime(1753, 1, 1, 0, 0, 0);
public static DateTime MAX_DT = new DateTime(9999, 12, 31, 11, 59, 59);
public static string GetDateAsStringMinDefault(DateTime dt) {
return dt > MIN_DT ? dt.ToString("yyyy-MM-dd HH:mm") : "";
}
public static string GetDateAsStringMaxDefault(DateTime dt) {
return dt < MAX_DT ? dt.ToString("yyyy-MM-dd HH:mm") : "";
}
}

View File

@ -0,0 +1,169 @@
using System.Net.Mail;
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;
using Infineon.Monitoring.MonA;
using Quartz;
namespace FabApprovalWorkerService.Workers;
public class ApprovalNotificationWorker : IJob {
private readonly ILogger<ApprovalNotificationWorker> _logger;
private readonly IApprovalService _approvalService;
private readonly IECNService _ecnService;
private readonly ICorrectiveActionService _caService;
private readonly IMRBService _mrbService;
private readonly IPCRBService _pcrbService;
private readonly ISmtpService _smtpService;
private readonly IMonInClient _monInClient;
private readonly IUserService _userService;
private readonly string _oldFabApprovalBaseUrl;
private readonly string _newFabApprovalBaseUrl;
public ApprovalNotificationWorker(ILogger<ApprovalNotificationWorker> logger,
IApprovalService approvalService,
IECNService ecnService,
ICorrectiveActionService caService,
IMRBService mrbService,
IPCRBService pcrbService,
ISmtpService smtpService,
IMonInClient monInClient,
IUserService userService,
AppSettings appSettings) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_approvalService = approvalService ?? throw new ArgumentNullException("IApprovalService not injected");
_ecnService = ecnService ?? throw new ArgumentNullException("IECNService not injected");
_caService = caService ?? throw new ArgumentNullException("ICorrectiveActionService not injected");
_mrbService = mrbService ?? throw new ArgumentNullException("IMRBService not injected");
_pcrbService = pcrbService ?? throw new ArgumentNullException("IPCRBService not injected");
_smtpService = smtpService ?? throw new ArgumentNullException("ISmtpService not injected");
_monInClient = monInClient ?? throw new ArgumentNullException("IMonInClient not injected");
_userService = userService ?? throw new ArgumentNullException("IUserService not injected");
_oldFabApprovalBaseUrl = appSettings.OldBaseUrl;
_newFabApprovalBaseUrl = appSettings.NewBaseUrl;
}
public async Task Execute(IJobExecutionContext context) {
DateTime start = DateTime.Now;
bool isInternalError = false;
StringBuilder errorMessage = new();
string metricName = "ApprovalNotificationWorker";
try {
_logger.LogInformation("Attempting to notify approvers of outstanding approvals");
IEnumerable<Approval> approvals = await _approvalService.GetActiveApprovalsWithNotificationOlderThanFiveDays();
HashSet<string> issueAndUserIds = new();
foreach (Approval approval in approvals) {
bool isEcn = false;
bool isCa = false;
bool isMrb = false;
bool isPcrb = false;
string approvalType = string.Empty;
string title = string.Empty;
string url = string.Empty;
if (await _ecnService.ECNNumberIsActive(approval.IssueID)) {
isEcn = true;
approvalType = "ECN";
ECN ecn = await _ecnService.GetEcnByNumber(approval.IssueID);
title = ecn.Title;
url = $"{_oldFabApprovalBaseUrl}/ECN/Edit?IssueID={approval.IssueID}";
} else if (await _caService.CANumberIsActive(approval.IssueID)) {
isCa = true;
approvalType = "Corrective Action";
CorrectiveAction ca = await _caService.GetCorrectiveActionById(approval.IssueID);
title = ca.CATitle;
url = $"{_oldFabApprovalBaseUrl}/CorrectiveAction/Edit?IssueID={approval.IssueID}";
} else if (await _mrbService.MRBNumberIsActive(approval.IssueID)) {
isMrb = true;
approvalType = "MRB";
MRB mrb = await _mrbService.GetMRBById(approval.IssueID);
title = mrb.Title;
url = $"{_newFabApprovalBaseUrl}/redirect?redirectPath=mrb/{approval.IssueID}";
} else if (await _pcrbService.PCRBNumberIsActive(approval.IssueID)) {
isPcrb = true;
approvalType = "PCRB";
PCRB pcrb = await _pcrbService.GetPCRBByPlanNumber(approval.IssueID);
title = pcrb.Title;
url = $"{_newFabApprovalBaseUrl}/redirect?redirectPath=pcrb/{approval.IssueID}";
}
/*if (approval.AssignedDate < DateTimeOffset.Now.AddDays(-150)) {
approval.CompletedDate = DateTime.Now;
approval.ItemStatus = 1;
await _approvalService.UpdateApproval(approval);
}*/
if (issueAndUserIds.Contains($"{approval.IssueID}{approval.UserID}")) {
approval.NotifyDate = DateTime.Now;
await _approvalService.UpdateApproval(approval);
} else if ((isEcn || isCa || isMrb || isPcrb) &&
!string.IsNullOrWhiteSpace(title) &&
!string.IsNullOrWhiteSpace(url) &&
!issueAndUserIds.Contains($"{approval.IssueID}{approval.UserID}")) {
User user = await _userService.GetUserById(approval.UserID);
IEnumerable<MailAddress> recipients = new List<MailAddress>() {
new MailAddress(user.Email)
};
IEnumerable<MailAddress> ccRecipients = new List<MailAddress>();
StringBuilder bodyBuilder = new();
bodyBuilder.Append($"*** Please DO NOT reply to this email ***");
bodyBuilder.Append("<br/><br/>This is a reminder that you have an approval waiting for you to review.");
bodyBuilder.Append("<br/><br/>Please log on to the Mesa Approval website to view the assignment and act accordingly. ");
bodyBuilder.Append($"<br/><br/>Document Type: {approvalType}");
bodyBuilder.Append($"<br/>Title: {title}");
bodyBuilder.Append($"<br/></br><a href='{url}'>{url}</a>");
bodyBuilder.Append($"<br/><br/>If you have any questions or trouble logging on please contact a site administrator.");
bodyBuilder.Append($"<br/><br/>Thank you!");
string subject = $"{approvalType} Approval Reminder: {title}";
await _smtpService.SendEmail(recipients, ccRecipients, subject, bodyBuilder.ToString());
approval.NotifyDate = DateTime.Now;
await _approvalService.UpdateApproval(approval);
issueAndUserIds.Add($"{approval.IssueID}{approval.UserID}");
}
}
} catch (Exception ex) {
StringBuilder errMsgBuilder = new();
errMsgBuilder.Append("An exception occurred when attempting to create follow up approvals for ");
errMsgBuilder.Append($"CAs needing it in five days. Exception: {ex.Message}");
_logger.LogError(errMsgBuilder.ToString());
isInternalError = true;
} finally {
DateTime end = DateTime.Now;
double latencyInMS = (end - start).TotalMilliseconds;
_monInClient.PostMetric(metricName + "Latency", latencyInMS);
if (isInternalError) {
_monInClient.PostStatus(metricName, State.Critical);
} else {
_monInClient.PostStatus(metricName, State.Ok);
}
}
}
}

View File

@ -1,13 +1,13 @@
using FabApprovalWorkerService.Models;
using System.Net.Mail;
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;
using Infineon.Monitoring.MonA;
using Quartz;
using System.Net.Mail;
using System.Text;
namespace FabApprovalWorkerService.Workers;
public class CAFollowUpWorker : IJob {
@ -22,14 +22,14 @@ public class CAFollowUpWorker : IJob {
ICorrectiveActionService caService,
IUserService userService,
ISmtpService smtpService,
IMonInClient monInClient) {
IMonInClient monInClient,
AppSettings appSettings) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_caService = caService ?? throw new ArgumentNullException("ICorrectiveActionService not injected");
_userService = userService ?? throw new ArgumentNullException("IUserService not injected");
_smtpService = smtpService ?? throw new ArgumentNullException("ISmtpService not injected");
_monInClient = monInClient ?? throw new ArgumentNullException("IMonInClient not injected");
_baseUrl = Environment.GetEnvironmentVariable("FabApprovalBaseUrl") ??
throw new ArgumentNullException("FabApprovalBaseUrl environment variable not found");
_baseUrl = appSettings.BaseUrl;
}
public async Task Execute(IJobExecutionContext context) {
@ -45,7 +45,7 @@ public class CAFollowUpWorker : IJob {
.ToList();
foreach (CorrectiveAction ca in followUpCAs) {
await _caService.CreateCorrectiveActionFollowUpApproval(ca.CANo, ca.QAID);
string qaEmail = await _userService.GetUserEmail(ca.QAID);
IEnumerable<MailAddress> recipients = new List<MailAddress>() {
new MailAddress(qaEmail)
@ -84,4 +84,4 @@ public class CAFollowUpWorker : IJob {
}
}
}
}
}

View File

@ -1,3 +1,5 @@
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;
@ -5,14 +7,12 @@ using Infineon.Monitoring.MonA;
using Quartz;
using System.Text;
namespace FabApprovalWorkerService.Workers;
public class CertificationTrainingGroupWorker : IJob {
private static readonly int MAX_RETRIES = 3;
private static readonly int BACKOFF_SECONDS = 30;
private readonly ILogger<CertificationTrainingGroupWorker> _logger;
private readonly ITrainingService _trainingService;
private readonly IUserService _userService;
@ -26,25 +26,20 @@ public class CertificationTrainingGroupWorker : IJob {
private readonly string _packagingAndLabelingTrainingGroupName;
public CertificationTrainingGroupWorker(ILogger<CertificationTrainingGroupWorker> logger,
ITrainingService trainingService,
IUserService userService,
IMonInClient monInClient) {
ITrainingService trainingService,
IUserService userService,
IMonInClient monInClient,
AppSettings appSettings) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_trainingService = trainingService ?? throw new ArgumentNullException("ITrainingService not injected");
_userService = userService ?? throw new ArgumentNullException("IUserService not injected");
_monInClient = monInClient ?? throw new ArgumentNullException("IMonInClient not injected");
_siProductionGroupName = Environment.GetEnvironmentVariable("SiProductionTrainingGroupName") ??
throw new ArgumentNullException("SiProductionTrainingGroupName environment variable not found");
_asmHtrTrainingGroupName = Environment.GetEnvironmentVariable("AsmHtrTrainingGroupName") ??
throw new ArgumentNullException("AsmHtrTrainingGroupName environment variable not found");
_cleansTrainingGroupName = Environment.GetEnvironmentVariable("CleansTrainingGroupName") ??
throw new ArgumentNullException("CleansTrainingGroupName environment variable not found");
_epiProTrainingGroupName = Environment.GetEnvironmentVariable("EpiProTrainingGroupName") ??
throw new ArgumentNullException("EpiProTrainingGroupName environment variable not found");
_fqaTrainingGroupName = Environment.GetEnvironmentVariable("FqaTrainingGroupName") ??
throw new ArgumentNullException("FqaTrainingGroupName environment variable not found");
_packagingAndLabelingTrainingGroupName = Environment.GetEnvironmentVariable("PackagingAndLabelingTrainingGroupName") ??
throw new ArgumentNullException("PackagingAndLabelingTrainingGroupName environment variable not found");
_fqaTrainingGroupName = appSettings.FqaTrainingGroupName;
_asmHtrTrainingGroupName = appSettings.AsmHtrTrainingGroupName;
_cleansTrainingGroupName = appSettings.CleansTrainingGroupName;
_epiProTrainingGroupName = appSettings.EpiProTrainingGroupName;
_siProductionGroupName = appSettings.SiProductionTrainingGroupName;
_packagingAndLabelingTrainingGroupName = appSettings.PackagingAndLabelingTrainingGroupName;
}
public async Task Execute(IJobExecutionContext context) {
@ -93,10 +88,11 @@ public class CertificationTrainingGroupWorker : IJob {
_logger.LogInformation($"Processing cert record {{{record}}}");
if (record is not null) {
User user = null;
User? user;
try {
user = await _userService.GetUserByEmail(record.Email);
} catch (Exception ex) {
user = null;
StringBuilder errMsgBuilder = new();
errMsgBuilder.Append($"An exception occurred when attempting to get user for email {record.Email}. ");
errMsgBuilder.Append($"Exception: {ex.Message}");

View File

@ -1,12 +1,12 @@
using FabApprovalWorkerService.Models;
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;
using Infineon.Monitoring.MonA;
using Quartz;
using System.Text;
namespace FabApprovalWorkerService.Workers;
public sealed class ExpiredOOOStatusWorker : IJob {
@ -43,7 +43,7 @@ public sealed class ExpiredOOOStatusWorker : IJob {
List<User> expiredOOOUsers = await _userService.GetAllExpiredOOOUsersAsync();
_logger.LogInformation($"There are {expiredOOOUsers.Count()} OOO users expiring");
foreach (User user in expiredOOOUsers) {
bool approvalsRemoved = await _userService.RemoveDelegatedApprovalsForUser(user.UserID, user.DelegatedTo);
bool subRolesRemoved = await _userService.RemoveDelegatedUserSubRoles(user.UserID, user.DelegatedTo);
@ -61,7 +61,7 @@ public sealed class ExpiredOOOStatusWorker : IJob {
errMsgBuilder.Append($"OOO flag removed: {oooFlagRemoved}");
throw new Exception(errMsgBuilder.ToString());
}
}
}
} catch (Exception ex) {
StringBuilder errMsgBuilder = new();
errMsgBuilder.Append("An exception occurred when attempting to remove OOO status for users with OOO expired ");
@ -80,4 +80,4 @@ public sealed class ExpiredOOOStatusWorker : IJob {
}
}
}
}
}

View File

@ -1,14 +1,13 @@
using FabApprovalWorkerService.Models;
using System.Net.Mail;
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;
using Infineon.Monitoring.MonA;
using Quartz;
using System.Net.Mail;
using System.Text;
namespace FabApprovalWorkerService.Workers;
public class ExpiredTECNWorker : IJob {
private readonly ILogger<ExpiredTECNWorker> _logger;
@ -24,7 +23,8 @@ public class ExpiredTECNWorker : IJob {
ITrainingService trainingService,
IUserService userService,
ISmtpService smtpService,
IMonInClient monInClient) {
IMonInClient monInClient,
AppSettings appSettings) {
_logger = logger ??
throw new ArgumentNullException("ILogger not injected");
_ecnService = ecnService ??
@ -37,8 +37,7 @@ public class ExpiredTECNWorker : IJob {
throw new ArgumentNullException("ISmtpService not injected");
_monInClient = monInClient ??
throw new ArgumentNullException("IMonInClient not injected");
_baseUrl = Environment.GetEnvironmentVariable("FabApprovalBaseUrl") ??
throw new ArgumentNullException("FabApprovalBaseUrl environment variable not found");
_baseUrl = appSettings.BaseUrl;
}
public async Task Execute(IJobExecutionContext context) {
@ -61,14 +60,14 @@ public class ExpiredTECNWorker : IJob {
foreach (ECN ecn in expiredEcns) {
List<int> trainingIds = (await _trainingService.GetTrainingIdsForECN(ecn.ECNNumber)).ToList();
foreach (int trainingId in trainingIds) {
await _trainingService.DeleteTrainingAssignmentsByTrainingId(trainingId);
List<int> trainingAssignmentIds =
List<int> trainingAssignmentIds =
(await _trainingService.GetTrainingAssignmentIdsForTraining(trainingId)).ToList();
foreach (int assignmentId in trainingAssignmentIds) {
foreach (int assignmentId in trainingAssignmentIds) {
await _trainingService.DeleteDocAssignment(assignmentId);
}
@ -76,8 +75,8 @@ public class ExpiredTECNWorker : IJob {
}
string recipientEmail = await _userService.GetUserEmail(ecn.OriginatorID);
List<MailAddress> recipientEamils = new List<MailAddress>() {
new MailAddress(recipientEmail)
List<MailAddress> recipientEamils = new List<MailAddress>() {
new MailAddress(recipientEmail)
};
string subject = "Notice of Expired TECN";
@ -108,4 +107,4 @@ public class ExpiredTECNWorker : IJob {
}
}
}
}
}

View File

@ -1,13 +1,13 @@
using FabApprovalWorkerService.Models;
using System.Net.Mail;
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;
using Infineon.Monitoring.MonA;
using Quartz;
using System.Net.Mail;
using System.Text;
namespace FabApprovalWorkerService.Workers;
public class ExpiringTECNWorker : IJob {
@ -22,7 +22,8 @@ public class ExpiringTECNWorker : IJob {
IMonInClient monInClient,
IUserService userService,
IECNService ecnService,
ISmtpService smtpService) {
ISmtpService smtpService,
AppSettings appSettings) {
_logger = logger ??
throw new ArgumentNullException("ILogger not injected");
_monInClient = monInClient ??
@ -33,8 +34,7 @@ public class ExpiringTECNWorker : IJob {
throw new ArgumentNullException("IECNService not injected");
_smtpService = smtpService ??
throw new ArgumentNullException("ISmtpService not injected");
_baseUrl = Environment.GetEnvironmentVariable("FabApprovalBaseUrl") ??
throw new ArgumentNullException("FabApprovalBaseUrl environment variable not found");
_baseUrl = appSettings.BaseUrl;
}
public async Task Execute(IJobExecutionContext context) {
@ -57,8 +57,8 @@ public class ExpiringTECNWorker : IJob {
foreach (ECN eCN in expiringTECNs) {
string recipientEmail = await _userService.GetUserEmail(eCN.OriginatorID);
MailAddress recipientAddress = new MailAddress(recipientEmail);
List<MailAddress> recipientList = new () { recipientAddress };
List<MailAddress> recipientList = new() { recipientAddress };
List<MailAddress> ccRecipientList = new();
foreach (string email in tecnNotificationUserEmails) {
ccRecipientList.Add(new MailAddress(email));
@ -94,4 +94,4 @@ public class ExpiringTECNWorker : IJob {
}
}
}
}
}

View File

@ -1,12 +1,12 @@
using FabApprovalWorkerService.Models;
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;
using Infineon.Monitoring.MonA;
using Quartz;
using System.Text;
namespace FabApprovalWorkerService.Workers;
public sealed class PendingOOOStatusWorker : IJob {
@ -43,7 +43,7 @@ public sealed class PendingOOOStatusWorker : IJob {
List<OOOTemp> pendingOOOUsers = await _userService.GetAllPendingOOOUsersAsync();
_logger.LogInformation($"There are {pendingOOOUsers.Count()} pending OOO users");
foreach (OOOTemp oooTemp in pendingOOOUsers) {
bool userAlreadyOOO = await _userService.IsUserAlreadyOOO(oooTemp.OOOUserID);
bool delegateAlreadyADelegate = await _userService.IsDelegatorAlreadyDelegatedTo(oooTemp.DelegatedTo);
@ -84,4 +84,4 @@ public sealed class PendingOOOStatusWorker : IJob {
}
}
}
}
}

View File

@ -1,13 +1,13 @@
using FabApprovalWorkerService.Models;
using System.Net.Mail;
using System.Text;
using FabApprovalWorkerService.Models;
using FabApprovalWorkerService.Services;
using Infineon.Monitoring.MonA;
using Quartz;
using System.Net.Mail;
using System.Text;
namespace FabApprovalWorkerService.Workers;
public class TrainingNotificationWorker : IJob {
@ -24,15 +24,15 @@ public class TrainingNotificationWorker : IJob {
IUserService userService,
IECNService ecnService,
ISmtpService smtpService,
IMonInClient monInClient) {
IMonInClient monInClient,
AppSettings appSettings) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_trainingService = trainingService ?? throw new ArgumentNullException("ITrainingService not injected");
_userService = userService ?? throw new ArgumentNullException("IUserService not injected");
_ecnService = ecnService ?? throw new ArgumentNullException("IECNService not injected");
_smtpService = smtpService ?? throw new ArgumentNullException("ISmtpService not injected");
_monInClient = monInClient ?? throw new ArgumentNullException("IMonInClient not injected");
_baseUrl = Environment.GetEnvironmentVariable("FabApprovalBaseUrl") ??
throw new ArgumentNullException("FabApprovalBaseUrl environment variable not found");
_baseUrl = appSettings.BaseUrl;
}
public async Task Execute(IJobExecutionContext context) {
@ -67,7 +67,7 @@ public class TrainingNotificationWorker : IJob {
_logger.LogInformation($"User {user.UserID} is inactive. Cancelling all training.");
IEnumerable<int> userTrainingAssignmentIds = await _trainingService.GetTrainingAssignmentIdsByUserId(user.UserID);
foreach (int trainingAssignmentId in userTrainingAssignmentIds) {
await _trainingService.DeleteTrainingAssignmentById(trainingAssignmentId);
await _trainingService.DeleteDocAssignment(trainingAssignmentId);
@ -124,7 +124,7 @@ public class TrainingNotificationWorker : IJob {
};
IEnumerable<MailAddress> ccRecipients = new List<MailAddress>();
StringBuilder bodyBuilder = new();
bodyBuilder.Append("Hello, you have open training assignments in Fab Approval. This is a reminder to ");
bodyBuilder.Append("finish your training assignments. <br /> View your open training assignments ");
@ -134,4 +134,4 @@ public class TrainingNotificationWorker : IJob {
await _smtpService.SendEmail(recipients, ccRecipients, subject, bodyBuilder.ToString());
}
}
}

View File

@ -1,3 +0,0 @@
{
}

View File

@ -0,0 +1,287 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline = false
#### .NET Coding Conventions ####
# Organize usings
dotnet_separate_import_directive_groups = true
dotnet_sort_system_directives_first = true
file_header_template = unset
# this. and Me. preferences
dotnet_style_qualification_for_event = false
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_property = false
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true
dotnet_style_predefined_type_for_member_access = true
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:error
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:error
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:error
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members
# Expression-level preferences
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true
dotnet_style_explicit_tuple_names = true
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true
dotnet_style_object_initializer = true
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_collection_expression = when_types_loosely_match
dotnet_style_prefer_compound_assignment = true
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
dotnet_style_prefer_inferred_anonymous_type_member_names = true
dotnet_style_prefer_inferred_tuple_names = true
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_simplified_boolean_expressions = true
dotnet_style_prefer_simplified_interpolation = true
# Field preferences
dotnet_style_readonly_field = true
# Parameter preferences
dotnet_code_quality_unused_parameters = all:error
# Suppression preferences
dotnet_remove_unnecessary_suppression_exclusions = none
# New line preferences
dotnet_style_allow_multiple_blank_lines_experimental = false:error
dotnet_style_allow_statement_immediately_after_block_experimental = false:warning
#### C# Coding Conventions ####
# var preferences
csharp_style_var_elsewhere = false:error
csharp_style_var_for_built_in_types = false:error
csharp_style_var_when_type_is_apparent = false:error
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true
csharp_style_pattern_matching_over_is_with_cast_check = true
csharp_style_prefer_extended_property_pattern = true
csharp_style_prefer_not_pattern = true
csharp_style_prefer_pattern_matching = true
csharp_style_prefer_switch_expression = true
# Null-checking preferences
csharp_style_conditional_delegate_call = true
# Modifier preferences
csharp_prefer_static_local_function = false
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
csharp_style_prefer_readonly_struct = true:warning
csharp_style_prefer_readonly_struct_member = true
# Code-block preferences
csharp_prefer_braces = true:silent
csharp_prefer_simple_using_statement = false:suggestion
csharp_style_namespace_declarations = file_scoped:error
csharp_style_prefer_method_group_conversion = true:suggestion
csharp_style_prefer_primary_constructors = true:suggestion
csharp_style_prefer_top_level_statements = true:error
# Expression-level preferences
csharp_prefer_simple_default_expression = true
csharp_style_deconstructed_variable_declaration = false:suggestion
csharp_style_implicit_object_creation_when_type_is_apparent = false
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_prefer_index_operator = false:error
csharp_style_prefer_local_over_anonymous_function = true:error
csharp_style_prefer_null_check_over_type_check = true
csharp_style_prefer_range_operator = false:error
csharp_style_prefer_tuple_swap = true
csharp_style_prefer_utf8_string_literals = true
csharp_style_throw_expression = true
csharp_style_unused_value_assignment_preference = unused_local_variable
csharp_style_unused_value_expression_statement_preference = unused_local_variable
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:error
# New line preferences
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:error
csharp_style_allow_embedded_statements_on_same_line_experimental = true
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
[*.{cs,vb}]
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = crlf
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
# Question
csharp_style_inlined_variable_declaration = false
csharp_style_prefer_primary_constructors = false
dotnet_diagnostic.CA1510.severity = none # "Use 'ArgumentNullException.ThrowIfNull' instead of explicitly throwing a new exception instance
dotnet_diagnostic.CA1806.severity = none # SendEmailWithValidArgsShouldSendMailThroughClient calls TryParse but does not explicitly
dotnet_diagnostic.CA1827.severity = none # Count() is used where Any() could be used instead to improve performance
dotnet_diagnostic.CA1829.severity = none # Use the property instead of Enumerable.Count()
dotnet_diagnostic.CA1860.severity = none # Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
dotnet_diagnostic.CA2208.severity = none # Method .ctor passes
dotnet_diagnostic.CA2208.severity = none # Method .ctor passes
dotnet_diagnostic.CA2211.severity = none # Non-constant fields should not be visible
dotnet_diagnostic.CA2253.severity = none # Named placeholders in the logging message template should not be comprised
dotnet_diagnostic.CA2254.severity = none # The logging message template should not vary between calls to
dotnet_diagnostic.CS1998.severity = none # This async method lacks 'await' operators and will run synchronously
dotnet_diagnostic.CS8618.severity = none # Non-nullable field '_mockDalService' must contain a non-null value when exiting constructor
dotnet_diagnostic.CS8625.severity = none # Cannot convert null literal to non-nullable reference type
dotnet_diagnostic.IDE0005.severity = none # Using directive is unnecessary.
dotnet_diagnostic.IDE0017.severity = none # Object initialization can be simplified
dotnet_diagnostic.IDE0018.severity = none # Variable declaration can be inlined
dotnet_diagnostic.IDE0028.severity = none # Collection initialization can be simplified
dotnet_diagnostic.IDE0044.severity = none # Make field readonly
dotnet_diagnostic.IDE0046.severity = none # 'if' statement can be simplified
dotnet_diagnostic.IDE0052.severity = none # "Private member can be removed
dotnet_diagnostic.IDE0270.severity = none # Null check can be simplified
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor
dotnet_diagnostic.IDE1006.severity = none # Naming rule violation: These words must begin with upper case characters
dotnet_diagnostic.IDE2000.severity = error # IDE2000: Allow multiple blank lines
dotnet_diagnostic.NUnit2001.severity = none # Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model
dotnet_diagnostic.NUnit2004.severity = none # Consider using the constraint model
dotnet_diagnostic.NUnit2010.severity = none # Use Is.EqualTo constraint instead of direct comparison for better assertion messages in ca
dotnet_style_coalesce_expression = false
dotnet_style_object_initializer = false
dotnet_style_prefer_conditional_expression_over_return = false

View File

@ -0,0 +1 @@
[]

View File

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

View File

@ -0,0 +1,5 @@
# mklink
```bash 1731705389065 = 638673021890650000 = Fri Nov 15 2024 14:16:28 GMT-0700 (Mountain Standard Time)
mklink /J "L:\DevOps\Mesa_FI\FabApprovalWorkerService\FabApprovalWorkerServiceTests\.vscode\.UserSecrets" "C:\Users\phares\AppData\Roaming\Microsoft\UserSecrets\f445e6e0-784b-4dde-9ef0-2143e6e90b1b"
```

View File

@ -0,0 +1,424 @@
{
"[markdown]": {
"editor.wordWrap": "off"
},
"files.exclude": {
"**/.git": false,
"**/node_modules": true
},
"files.watcherExclude": {
"**/node_modules": true
},
"cSpell.words": [
"abutton",
"accessibilities",
"accodingly",
"acknowledgmentby",
"Acks",
"actionsheet",
"Additonal",
"Addtional",
"againm",
"agendaview",
"Antlr",
"Appover",
"Appprrovers",
"Approvalog",
"Aprovers",
"Aproverslist",
"asax",
"aspnetmvc",
"Assignedto",
"Atachments",
"Attachemnt",
"Attachemnts",
"Attchment",
"auditee",
"Auditee",
"Auditees",
"automaically",
"Autthorized",
"beacuase",
"beforeunload",
"Belguim",
"bfound",
"bgcolor",
"Bies",
"binded",
"blackbackground",
"blackhover",
"blackpressed",
"blueenergy",
"blueopal",
"buttongroup",
"BYMRB",
"bytesgot",
"CAID",
"casection",
"CAXXXX",
"CCPCR",
"CCPCRB",
"cellspacing",
"Cheeso's",
"chkbx",
"Clib",
"colorpicker",
"columnmenu",
"columnsreorder",
"columnsresize",
"comming",
"Containmen",
"Copmments",
"correctiv",
"Correctivet",
"Creat",
"currentd",
"Cyle",
"dadada",
"darkbluehover",
"darkbluepressed",
"darkred",
"datafields",
"datasource",
"dataviz",
"datepicker",
"datetimepicker",
"dayview",
"Deletet",
"Delgation",
"DENITED",
"Deparmtent",
"departmentids",
"Descirption",
"devprog",
"dfeffc",
"Disp",
"Dispo",
"Dispoitio",
"Dispos",
"Dispositon",
"Dispostion",
"Dispostions",
"dispotypevalidation",
"Docbase",
"Documentum",
"Documetum",
"dont",
"downlaoded",
"draganddrop",
"dragcancel",
"dropdownlist",
"Eamils",
"ECNPCRB",
"Ecns",
"edmx",
"EECN",
"emai",
"emailparams",
"Emergrncy",
"energyblue",
"Eran",
"Esql",
"ETECN",
"EXCELOPENXML",
"existinglocation",
"Expando",
"extrafield",
"fadc",
"fbec",
"fcfdfd",
"fdff",
"fece",
"feeebd",
"ffdc",
"ffdd",
"fieldset",
"FILIPE",
"filtermenu",
"Fldr",
"flintstone",
"FLOWLOCS",
"FMEA",
"ftplib",
"FTPSPN",
"GETDATE",
"gitea",
"globaldocudms",
"glyphicons",
"groupable",
"Guids",
"halflings",
"Hexsize",
"highcontrast",
"Hmac",
"holdsteps",
"hostspecific",
"icenium",
"IECN",
"imagebrowser",
"IMRB",
"Infineon",
"Insertd",
"inverseicons",
"IPCRB",
"ISADMIN",
"islast",
"ISNULL",
"ITAR",
"jquery",
"jqueryval",
"jqwidgets",
"jqxbuttongroup",
"jqxbuttons",
"jqxcalendar",
"jqxchart",
"jqxcheckbox",
"jqxcolorpicker",
"jqxcombobox",
"jqxcore",
"jqxdata",
"jqxdatatable",
"jqxdatetimeinput",
"jqxdocking",
"jqxdockpanel",
"jqxdragdrop",
"jqxdropdownbutton",
"jqxdropdownlist",
"jqxexpander",
"jqxgauge",
"jqxgrid",
"jqxinput",
"jqxknockout",
"jqxlistbox",
"jqxlistmenu",
"jqxmaskedinput",
"jqxmenu",
"jqxnavigationbar",
"jqxnumberinput",
"jqxpanel",
"jqxpasswordinput",
"jqxprogressbar",
"jqxradiobutton",
"jqxrangeselector",
"jqxrating",
"jqxresponse",
"jqxscrollbar",
"jqxscrollview",
"jqxslider",
"jqxsplitter",
"jqxswitchbutton",
"jqxtabs",
"jqxtooltip",
"jqxtouch",
"jqxtree",
"jqxtreegrid",
"jqxtreemap",
"jqxvalidator",
"jqxwindow",
"kendogridcustom",
"kendoui",
"labelelement",
"labelledby",
"Leanred",
"lightgray",
"linkbutton",
"Linq",
"Listdiv",
"listview",
"Lnks",
"localfilename",
"loclist",
"logis",
"logtext",
"loopmis",
"lotdispo",
"LOTDISPSITION",
"Lotfile",
"lotlist",
"lotstatusoption",
"LTRIM",
"MADUREIRA",
"mailrelay",
"MDTM",
"meego",
"meetingid",
"menubutton",
"mesafi",
"metroblack",
"metrodark",
"miliseconds",
"modalview",
"modernizr",
"Modernizr",
"monthview",
"MRBIs",
"Mrbs",
"msecs",
"multipleextended",
"Navigatable",
"nbsp",
"newbase",
"newchange",
"newdi",
"newfilename",
"newsource",
"Newtonsoft",
"notications",
"Notifcation",
"Notifyf",
"NTLM",
"Nullcc",
"numerictextbox",
"objdata",
"OCAP",
"occured",
"odata",
"oldfilename",
"OLHOLD",
"onclick",
"onmousemove",
"OPDESC",
"OPENQUERY",
"Oper",
"operationslist",
"Orginator",
"Originatorname",
"Ouellette",
"Owin",
"pageable",
"Pageable",
"panelbar",
"parentid",
"parminput",
"parms",
"Parms",
"particula",
"pasv",
"PASV",
"PATINDEX",
"PCRB",
"PCRBID",
"pcrvalues",
"pdbonly",
"Preventitive",
"preventivet",
"Prevetative",
"proces",
"Processedl",
"procs",
"productfamilies",
"progess",
"progressbar",
"qrcode",
"Quanityt",
"rangebar",
"Recep",
"Recepient",
"recieved",
"recordlock",
"remotefilename",
"reorderable",
"reportform",
"reportslist",
"reportslistdiv",
"Reqquired",
"Reqs",
"Requiest",
"Responsibles",
"RETR",
"Revisioing",
"Revisioned",
"Revison",
"rgba",
"rkotian",
"RNFR",
"RNTO",
"Roless",
"roundbg",
"RTRIM",
"SAMDB",
"scroller",
"scrollview",
"seleced",
"selectionlog",
"Selectpart",
"sess",
"Sfisharepoint",
"shinyblack",
"showpassword",
"SIGNON",
"simpleparser",
"slddrw",
"sldprt",
"sortasc",
"sortascbutton",
"sortdesc",
"sortdescbutton",
"sortremove",
"sparkline",
"splitview",
"SPNMRB",
"SPNPDB",
"SSRS",
"Sssign",
"Staus",
"stylesheet",
"Submited",
"subrole",
"subroles",
"Succefully",
"Succesfully",
"sucessfully",
"SURP",
"Swashbuckle",
"SWRN",
"tabindex",
"tabstrip",
"Tahoma",
"taskcompleted",
"Tasklist",
"Taveler",
"TECN",
"TECNs",
"TEMIRWAP",
"tempecd",
"tempimplement",
"templabel",
"tempvalue",
"TEMSA",
"timepicker",
"Tobe",
"Toplevel",
"Totrav",
"trainingby",
"Traininglist",
"traininglistdiv",
"transanction",
"Trav",
"Traveller",
"Traverler",
"TRAVLELER",
"Travler",
"TREEVIEW",
"trigerred",
"ttinclude",
"Uhandled",
"Updat",
"Uplaod",
"Upto",
"userevents",
"userids",
"userlist",
"Validatable",
"valueelement",
"Variabls",
"Verdana",
"vgrid",
"viewmodel",
"vsdoc",
"whethere",
"windowsphone",
"Winsock",
"worlflow"
]
}

View File

@ -0,0 +1,135 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "User Secrets Init",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/FabApprovalWorkerServiceTests.csproj",
"init"
],
"problemMatcher": "$msCompile"
},
{
"label": "User Secrets Set",
"command": "dotnet",
"type": "process",
"args": [
"user-secrets",
"-p",
"${workspaceFolder}/FabApprovalWorkerServiceTests.csproj",
"set",
"_UserSecretsId",
"f445e6e0-784b-4dde-9ef0-2143e6e90b1b"
],
"problemMatcher": "$msCompile"
},
{
"label": "Format",
"command": "dotnet",
"type": "process",
"args": [
"format",
"--report",
".vscode",
"--verbosity",
"detailed",
"--severity",
"warn"
],
"problemMatcher": "$msCompile"
},
{
"label": "Format-Whitespaces",
"command": "dotnet",
"type": "process",
"args": [
"format",
"whitespace"
],
"problemMatcher": "$msCompile"
},
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "testDebug",
"command": "dotnet",
"type": "process",
"args": [
"test",
"${workspaceFolder}/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "testRelease",
"command": "dotnet",
"type": "process",
"args": [
"test",
"${workspaceFolder}/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"-c",
"Release"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/FabApprovalWorkerServiceTests.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "Publish AOT",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"-r",
"win-x64",
"-c",
"Release",
"-p:PublishAot=true",
"${workspaceFolder}/FabApprovalWorkerServiceTests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -40,7 +40,7 @@ public class CorrectiveActionServiceTests {
[Test]
public async Task GetCorrectiveActionsWithFollowUpInFiveDaysShouldReturnExpectedCAs() {
IEnumerable<CorrectiveAction> expectedCAs = new List<CorrectiveAction>() {
IEnumerable<CorrectiveAction> expectedCAs = new List<CorrectiveAction>() {
new CorrectiveAction() {
CANo = 1,
CATitle = "title"
@ -98,4 +98,4 @@ public class CorrectiveActionServiceTests {
_mockDalService.Verify(d => d.ExecuteAsync(It.IsAny<string>()), Times.Once());
}
}
}

View File

@ -74,7 +74,7 @@ internal class ECNServiceTests {
[Test]
public async Task GetExpiringTECNsWithNoExtensionFromDbShouldReturnSameResults() {
IEnumerable<ECN> ecns = new List<ECN>() {
IEnumerable<ECN> ecns = new List<ECN>() {
new ECN() {
ECNNumber = 1,
OriginatorID = 1,
@ -225,7 +225,7 @@ internal class ECNServiceTests {
[Test]
public async Task GetTECNNotificationUserEmailsShouldReturnExpectedUserEmails() {
IEnumerable<string> userEmails = new List<string>() {
IEnumerable<string> userEmails = new List<string>() {
"fake1@email.com",
"fake2@email.com"
};
@ -270,7 +270,7 @@ internal class ECNServiceTests {
[Test]
public async Task GetEcnByNumberShouldReturnExpectedEcn() {
IEnumerable<ECN> expectedEcns = new List<ECN>() {
IEnumerable<ECN> expectedEcns = new List<ECN>() {
new ECN() {
ECNNumber = 1,
OriginatorID = 1,
@ -433,4 +433,4 @@ internal class ECNServiceTests {
Assert.True(isExpired);
}
}
}

View File

@ -1,15 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<Configurations>Debug;Release;Staging</Configurations>
<UserSecretsId>f445e6e0-784b-4dde-9ef0-2143e6e90b1b</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
@ -19,13 +17,10 @@
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FabApprovalWorkerService\FabApprovalWorkerService.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>
</Project>
</Project>

View File

@ -1,12 +1,12 @@
using FabApprovalWorkerService.Clients;
using System.Net.Mail;
using FabApprovalWorkerService.Clients;
using FabApprovalWorkerService.Services;
using Microsoft.Extensions.Logging;
using Moq;
using System.Net.Mail;
namespace FabApprovalWorkerServiceTests;
internal class SmtpServiceTests {
private static readonly List<MailAddress> ADDRESS_LIST = new List<MailAddress>() {
@ -48,7 +48,7 @@ internal class SmtpServiceTests {
_smtpService = new SmtpService(_mockLogger.Object, _mockSmtpClient.Object);
Assert.ThrowsAsync<ArgumentNullException>(async Task () => {
await _smtpService.SendEmail(new List<MailAddress> (), ADDRESS_LIST, "subject", "body");
await _smtpService.SendEmail(new List<MailAddress>(), ADDRESS_LIST, "subject", "body");
});
}
@ -100,13 +100,13 @@ internal class SmtpServiceTests {
[Test]
public async Task SendEmailWithValidArgsShouldSendMailThroughClient() {
_smtpService = new SmtpService(_mockLogger.Object, _mockSmtpClient.Object);
Assert.True(await _smtpService.SendEmail(ADDRESS_LIST, ADDRESS_LIST, "subject", "body"));
bool shouldSendEmail = false;
Boolean.TryParse(Environment.GetEnvironmentVariable("FabApprovalShouldSendEmail"), out shouldSendEmail);
bool.TryParse(Environment.GetEnvironmentVariable("FabApprovalShouldSendEmail"), out shouldSendEmail);
if (shouldSendEmail)
_mockSmtpClient.Verify(s => s.Send(It.IsAny<MailMessage>()));
}
}
}

View File

@ -156,7 +156,7 @@ public class TrainingServiceTests {
public void MarkTrainingAsCompleteWithInvalidIdShouldThrowException() {
_trainingService = new TrainingService(_mockLogger.Object, _mockDalService.Object, _mockUserService.Object);
Assert.ThrowsAsync<ArgumentException>(async Task() => await _trainingService.MarkTrainingAsComplete(-1));
Assert.ThrowsAsync<ArgumentException>(async Task () => await _trainingService.MarkTrainingAsComplete(-1));
}
[Test]
@ -181,7 +181,7 @@ public class TrainingServiceTests {
[Test]
public async Task GetActiveTrainingAssignmentsShouldReturnExpectedAssignments() {
IEnumerable<TrainingAssignment> expectedAssignments = new List<TrainingAssignment>() {
IEnumerable<TrainingAssignment> expectedAssignments = new List<TrainingAssignment>() {
new TrainingAssignment() {
ID = 1,
TrainingID = 1,
@ -217,7 +217,7 @@ public class TrainingServiceTests {
_trainingService = new TrainingService(_mockLogger.Object, _mockDalService.Object, _mockUserService.Object);
Assert.ThrowsAsync<Exception>(async Task() => await _trainingService.GetActiveTrainingAssignments());
Assert.ThrowsAsync<Exception>(async Task () => await _trainingService.GetActiveTrainingAssignments());
}
[Test]
@ -341,4 +341,4 @@ public class TrainingServiceTests {
Assert.That(expectedIds, Is.EquivalentTo(actualIds));
}
}
}

View File

@ -77,9 +77,9 @@ internal class UserServiceTests {
_userService = new UserService(MOCK_LOGGER, _mockDalService.Object);
Assert.ThrowsAsync<Exception>(async Task() => await _userService.GetAllExpiredOOOUsersAsync());
Assert.ThrowsAsync<Exception>(async Task () => await _userService.GetAllExpiredOOOUsersAsync());
}
[Test]
public async Task GetAllExpiredOOOUsersShouldReturnMockUsers() {
_mockDalService.Setup(d => d.QueryAsync<User>(It.IsAny<string>())).Returns(Task.FromResult(MOCK_USERS));
@ -99,7 +99,7 @@ internal class UserServiceTests {
Assert.ThrowsAsync<Exception>(async Task () => await _userService.GetAllPendingOOOUsersAsync());
}
[Test]
public async Task GetAllPendingOOOUsersShouldReturnMockOOOTemps() {
_mockDalService.Setup(d => d.QueryAsync<OOOTemp>(It.IsAny<string>())).Returns(Task.FromResult(MOCK_OOO_TEMPS));
@ -157,7 +157,7 @@ internal class UserServiceTests {
_userService = new UserService(MOCK_LOGGER, _mockDalService.Object);
Assert.ThrowsAsync<Exception>(async Task() => await _userService.IsDelegatorAlreadyDelegatedTo(2));
Assert.ThrowsAsync<Exception>(async Task () => await _userService.IsDelegatorAlreadyDelegatedTo(2));
}
[Test]
@ -195,7 +195,7 @@ internal class UserServiceTests {
[Test]
public async Task InsertDelegatedRolesWithValidUserIdShouldReturnTrue() {
IEnumerable<UserSubRole> userSubRoles = new List<UserSubRole>() {
IEnumerable<UserSubRole> userSubRoles = new List<UserSubRole>() {
new UserSubRole() {
UserSubRoleID = 1,
UserID = 1,
@ -274,7 +274,7 @@ internal class UserServiceTests {
[Test]
public async Task RemoveDelegatedUserSubRolesWithValidParamsShouldReturnTrue() {
IEnumerable<int> roleIds = new List<int>() {1, 2};
IEnumerable<int> roleIds = new List<int>() { 1, 2 };
_mockDalService.Setup(d => d.QueryAsync<int>(It.IsAny<string>())).Returns(Task.FromResult(roleIds));
_mockDalService.Setup(d => d.ExecuteAsync(It.IsAny<string>())).Returns(Task.FromResult(1));
@ -337,7 +337,7 @@ internal class UserServiceTests {
[Test]
public async Task FlagUserAsOOOWithValidOOOTempShouldReturnTrue() {
OOOTemp oooTemp = new OOOTemp() {
OOOTemp oooTemp = new OOOTemp() {
ID = 1,
OOOUserID = 1,
OOOStartDate = DateTime.Now,
@ -434,7 +434,7 @@ internal class UserServiceTests {
public void GetUserEmailWithInvalidUserIdShouldThrowException() {
_userService = new UserService(MOCK_LOGGER, _mockDalService.Object);
Assert.ThrowsAsync<ArgumentException>(async Task() => await _userService.GetUserEmail(-1));
Assert.ThrowsAsync<ArgumentException>(async Task () => await _userService.GetUserEmail(-1));
}
[Test]
@ -443,7 +443,7 @@ internal class UserServiceTests {
_userService = new UserService(MOCK_LOGGER, _mockDalService.Object);
Assert.ThrowsAsync<Exception>(async Task() => await _userService.GetUserEmail(3));
Assert.ThrowsAsync<Exception>(async Task () => await _userService.GetUserEmail(3));
}
[Test]
@ -483,12 +483,12 @@ internal class UserServiceTests {
_mockDalService.Setup(d => d.QueryAsync<User>(It.IsAny<string>())).Returns(Task.FromResult(emptyUsers));
Assert.ThrowsAsync<Exception>(async Task() => await _userService.GetUserById(5));
Assert.ThrowsAsync<Exception>(async Task () => await _userService.GetUserById(5));
}
[Test]
public async Task GetUserByIdShouldReturnExpectedUser() {
IEnumerable<User> expectedUsers = new List<User>() {
IEnumerable<User> expectedUsers = new List<User>() {
new User() {
UserID = 1,
LoginID = "id",