Adding
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
[*.cs]
|
||||
|
||||
# CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
|
||||
dotnet_diagnostic.CS8632.severity = silent
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_using_directive_placement = outside_namespace:silent
|
||||
csharp_prefer_simple_using_statement = true:suggestion
|
||||
csharp_prefer_braces = true:silent
|
||||
csharp_style_namespace_declarations = block_scoped:silent
|
||||
csharp_style_prefer_method_group_conversion = true:silent
|
||||
csharp_style_prefer_top_level_statements = true:silent
|
||||
csharp_style_expression_bodied_methods = false:silent
|
||||
csharp_style_expression_bodied_constructors = false:silent
|
||||
csharp_style_expression_bodied_operators = false:silent
|
||||
csharp_style_expression_bodied_properties = true:silent
|
||||
csharp_style_expression_bodied_indexers = true:silent
|
||||
csharp_style_expression_bodied_accessors = true:silent
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_style_expression_bodied_lambdas = true:silent
|
||||
csharp_style_expression_bodied_local_functions = false:silent
|
||||
|
||||
[*.{cs,vb}]
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
end_of_line = crlf
|
||||
[*.{cs,vb}]
|
||||
#### 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.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
|
||||
|
||||
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.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_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
|
||||
@@ -0,0 +1,363 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
.idea/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
@@ -0,0 +1,41 @@
|
||||
# .NET Core SDK
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS aspnetcore-build
|
||||
|
||||
# Copy Projects
|
||||
COPY LCU.API.Internal.LoanRate/LCU.API.Internal.LoanRate.csproj ./source/LCU.API.Internal.LoanRate/
|
||||
COPY LCU.API.Internal.LoanRateLib/LCU.API.Internal.LoanRateLib.csproj ./source/LCU.API.Internal.LoanRateLib/
|
||||
COPY LCU.Library.Internal.LoanRateModels/LCU.Library.Internal.LoanRateModels.csproj ./source/LCU.Library.Internal.LoanRateModels/
|
||||
|
||||
# Install Credential Provider and set env variables to enable Nuget restore with auth
|
||||
ARG PAT=bh2lq3jibktw67b2wdbqyfln7cd3je6lk52kijntpj43v6kimpgq
|
||||
RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh | sh
|
||||
#RUN wget -qO- https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh | bash
|
||||
ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true
|
||||
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS "{\"endpointCredentials\": [{\"endpoint\":\"https://landmarkcu.pkgs.visualstudio.com/_packaging/LCU-Internal/nuget/v3/index.json\", \"password\":\"${PAT}\"}]}"
|
||||
|
||||
# .NET Core Restore, use auth'd feed
|
||||
RUN dotnet restore -s "https://landmarkcu.pkgs.visualstudio.com/_packaging/LCU-Internal/nuget/v3/index.json" -s "https://api.nuget.org/v3/index.json" ./source/LCU.API.Internal.LoanRate/LCU.API.Internal.LoanRate.csproj
|
||||
|
||||
# Copy All Files
|
||||
COPY . ./source/
|
||||
|
||||
FROM aspnetcore-build AS test
|
||||
LABEL test=true
|
||||
COPY LCU.API.Internal.LoanRateTests/LCU.API.Internal.LoanRateTests.csproj ./source/LCU.API.Internal.LoanRateTests/
|
||||
RUN dotnet restore ./source/LCU.API.Internal.LoanRateTests/LCU.API.Internal.LoanRateTests.csproj
|
||||
RUN dotnet test -c Release --results-directory /testresults --logger "trx;LogFileName=test_results.trx" ./source/LCU.API.Internal.LoanRateTests/LCU.API.Internal.LoanRateTests.csproj
|
||||
|
||||
# .NET Core Publish
|
||||
FROM aspnetcore-build as publish
|
||||
RUN dotnet publish ./source/LCU.API.Internal.LoanRate/LCU.API.Internal.LoanRate.csproj -c Release -o /dist
|
||||
|
||||
# ASP.NET Core
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine3.20
|
||||
RUN apk add --no-cache icu-libs && apk add --no-cache tzdata;
|
||||
ENV TZ America/Chicago
|
||||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
|
||||
ENV ASPNETCORE_ENVIRONMENT=Development
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=publish /dist .
|
||||
ENTRYPOINT ["dotnet", "LCU.API.Internal.LoanRate.dll"]
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33205.214
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.LoanRate", "LCU.API.Internal.LoanRate\LCU.API.Internal.LoanRate.csproj", "{CFB340C3-F73D-4552-801D-6B8CFA1FD70A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.LoanRateTests", "LCU.API.Internal.LoanRateTests\LCU.API.Internal.LoanRateTests.csproj", "{08ED9646-3A26-4ECF-AC34-39AABF46F78A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.Library.Internal.LoanRateModels", "LCU.Library.Internal.LoanRateModels\LCU.Library.Internal.LoanRateModels.csproj", "{1BAA207B-92F5-4DAB-B3B8-A7887451720D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.LoanRateLib", "LCU.API.Internal.LoanRateLib\LCU.API.Internal.LoanRateLib.csproj", "{6FE9201A-EAE6-49FA-8F4A-D0B10022F985}"
|
||||
EndProject
|
||||
Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "LCU.API.Internal.LoanRateSql", "LCU.API.Internal.LoanRateSql\LCU.API.Internal.LoanRateSql.sqlproj", "{33CBC5AD-1B92-4D5F-A79F-4464C79C5F0C}"
|
||||
EndProject
|
||||
Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "LCU.API.Internal.LoanRateLoadTestingSql", "LCU.API.Internal.LoanRateLoadTestingSql\LCU.API.Internal.LoanRateLoadTestingSql.sqlproj", "{0687C40B-33B7-48FD-9611-C3AF96987CBE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LCU.API.Internal.LoanRateLoadTestingLib", "LCU.API.Internal.LoanRateLoadTestingLib\LCU.API.Internal.LoanRateLoadTestingLib.csproj", "{F9374890-27F2-4155-9781-674929ECE779}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CFB340C3-F73D-4552-801D-6B8CFA1FD70A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CFB340C3-F73D-4552-801D-6B8CFA1FD70A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CFB340C3-F73D-4552-801D-6B8CFA1FD70A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CFB340C3-F73D-4552-801D-6B8CFA1FD70A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{08ED9646-3A26-4ECF-AC34-39AABF46F78A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{08ED9646-3A26-4ECF-AC34-39AABF46F78A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{08ED9646-3A26-4ECF-AC34-39AABF46F78A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{08ED9646-3A26-4ECF-AC34-39AABF46F78A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1BAA207B-92F5-4DAB-B3B8-A7887451720D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1BAA207B-92F5-4DAB-B3B8-A7887451720D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1BAA207B-92F5-4DAB-B3B8-A7887451720D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1BAA207B-92F5-4DAB-B3B8-A7887451720D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6FE9201A-EAE6-49FA-8F4A-D0B10022F985}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6FE9201A-EAE6-49FA-8F4A-D0B10022F985}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6FE9201A-EAE6-49FA-8F4A-D0B10022F985}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6FE9201A-EAE6-49FA-8F4A-D0B10022F985}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{33CBC5AD-1B92-4D5F-A79F-4464C79C5F0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{33CBC5AD-1B92-4D5F-A79F-4464C79C5F0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{33CBC5AD-1B92-4D5F-A79F-4464C79C5F0C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{33CBC5AD-1B92-4D5F-A79F-4464C79C5F0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{33CBC5AD-1B92-4D5F-A79F-4464C79C5F0C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{33CBC5AD-1B92-4D5F-A79F-4464C79C5F0C}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{0687C40B-33B7-48FD-9611-C3AF96987CBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0687C40B-33B7-48FD-9611-C3AF96987CBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0687C40B-33B7-48FD-9611-C3AF96987CBE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{0687C40B-33B7-48FD-9611-C3AF96987CBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0687C40B-33B7-48FD-9611-C3AF96987CBE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0687C40B-33B7-48FD-9611-C3AF96987CBE}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{F9374890-27F2-4155-9781-674929ECE779}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F9374890-27F2-4155-9781-674929ECE779}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F9374890-27F2-4155-9781-674929ECE779}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F9374890-27F2-4155-9781-674929ECE779}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {5F5E7D18-CECB-4D1B-87A7-071F1037BDD6}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
namespace LCU.API.Internal.LoanRate.Configurations;
|
||||
|
||||
public class ApiConfiguration
|
||||
{
|
||||
public string AppName { get; set; }
|
||||
public string SeqUrl { get; set; }
|
||||
public string SeqApiKey { get; set; }
|
||||
public string[] CorsAllowedOrigins { get; set; }
|
||||
public FeatureFlags FeatureFlags { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace LCU.API.Internal.LoanRate.Configurations;
|
||||
|
||||
public class FeatureFlags
|
||||
{
|
||||
public bool RunLoadTestInitiateConsumer { get; set; }
|
||||
public bool RunLoadTestProcessRateConsumer { get; set; }
|
||||
public bool RunLoadTestRateCompletionConsumer { get; set; }
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
namespace LCU.API.Internal.LoanRate.Configurations;
|
||||
|
||||
public class FileOperationsApiConfiguration
|
||||
{
|
||||
public string Url { get; set; }
|
||||
public string ExtractExcelWorkBookDataEndpoint { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public Uri ExtractExcelWorkBookDataEndpointUri => new Uri(Url + ExtractExcelWorkBookDataEndpoint);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
namespace LCU.API.Internal.LoanRate.Configurations;
|
||||
|
||||
public class LoanRateLoadTestingSqlConnectionConfiguration
|
||||
{
|
||||
public string ConnectionString { get; set; }
|
||||
public int MaxRetryCount { get; set; }
|
||||
public TimeSpan MaxRetryDelay { get; set; }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
namespace LCU.API.Internal.LoanRate.Configurations;
|
||||
|
||||
public class LoanRateSqlConnectionConfiguration
|
||||
{
|
||||
public string ConnectionString { get; set; }
|
||||
public int MaxRetryCount { get; set; }
|
||||
public TimeSpan MaxRetryDelay { get; set; }
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
namespace LCU.API.Internal.LoanRate.Configurations;
|
||||
|
||||
public class ReceiveEndpointConfigurations
|
||||
{
|
||||
public ReceiveEndpointConfiguration LoadTestInitiateReceiveEndpoint { get; set; }
|
||||
public ReceiveEndpointConfiguration LoadTestProcessRateReceiveEndpoint { get; set; }
|
||||
public ReceiveEndpointConfiguration LoadTestRateCompletionReceiveEndpoint { get; set; }
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using MassTransit;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
using LCU.Api.Internal.MaidBotLib.Models;
|
||||
using LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
namespace LCU.API.Internal.LoanRate.Consumers;
|
||||
|
||||
public class LoadTestInitiateConsumer : IConsumer<LoadTestInitiateRequest>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public LoadTestInitiateConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task Consume(ConsumeContext<LoadTestInitiateRequest> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Debug("Starting HandleLoadTestInitiation.");
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<ILoadTestInitiationService>().HandleLoadTestInitiation(context.Message));
|
||||
Log.Debug("Starting HandleLoadTestInitiation.");
|
||||
}
|
||||
catch (ServiceException serviceException)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(serviceException, $"Load Test Initiation Failure. " +
|
||||
$"The LoadTestInitiateRequest is placed on LCU.LoanRate.LoadTest.Initiate_error.");
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, $"Unexpected Load Test Initiation Failure. " +
|
||||
$"The LoadTestInitiateRequest is placed on LCU.LoanRate.LoadTest.Initiate_error.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using MassTransit;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
using LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
using LCU.Api.Internal.MaidBotLib.Models;
|
||||
namespace LCU.API.Internal.LoanRate.Consumers;
|
||||
|
||||
public class LoadTestProcessRateConsumer : IConsumer<LoadTestProcessRateRequest>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public LoadTestProcessRateConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task Consume(ConsumeContext<LoadTestProcessRateRequest> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Debug("Starting HandleLoadTestProcessRate.");
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<ILoadTestProcessRateService>().HandleLoadTestProcessRate(context.Message));
|
||||
Log.Debug("Starting HandleLoadTestProcessRate.");
|
||||
}
|
||||
catch (ServiceException serviceException)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(serviceException, $"Load Test Process Rate Failure. " +
|
||||
$"The LoadTestProcessRateRequest is placed on LCU.LoanRate.LoadTest.ProcessRate_error.");
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, $"Unexpected Load Test Process Rate Failure. " +
|
||||
$"The LoadTestProcessRateRequest is placed on LCU.LoanRate.LoadTest.ProcessRate_error.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
using MassTransit;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
using LCU.Api.Internal.MaidBotLib.Models;
|
||||
using LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
namespace LCU.API.Internal.LoanRate.Consumers;
|
||||
|
||||
public class LoadTestRateCompletionConsumer : IConsumer<Batch<LoadTestRateCompletionRequest>>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public LoadTestRateCompletionConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task Consume(ConsumeContext<Batch<LoadTestRateCompletionRequest>> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Debug("Starting HandleLoadTestRateCompletion.");
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
|
||||
var loadTestRateCompletionRequests = new List<LoadTestRateCompletionRequest>();
|
||||
for (int index = 0; index < context.Message.Length; index++)
|
||||
{
|
||||
ConsumeContext<LoadTestRateCompletionRequest> messageContext = context.Message[index];
|
||||
loadTestRateCompletionRequests.Add(messageContext.Message);
|
||||
}
|
||||
|
||||
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<ILoadTestRateCompletionService>().HandleLoadTestRateCompletion(loadTestRateCompletionRequests));
|
||||
Log.Debug("Starting HandleLoadTestRateCompletion.");
|
||||
}
|
||||
catch (ServiceException serviceException)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(serviceException, $"Load Test Rate Completion Failure. " +
|
||||
$"The LoadTestRateCompletionRequest is placed on LCU.LoanRate.LoadTest.RateCompletion_error.");
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, $"Unexpected Load Test Rate Completion Failure. " +
|
||||
$"The LoadTestRateCompletionRequest is placed on LCU.LoanRate.LoadTest.RateCompletion_error.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Entities;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Requests;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ComplexEvaluationDetailController : ControllerBase
|
||||
{
|
||||
private readonly IComplexEvaluationDetailService _complexEvaluationDetailService;
|
||||
|
||||
public ComplexEvaluationDetailController(IComplexEvaluationDetailService complexEvaluationDetailService)
|
||||
{
|
||||
_complexEvaluationDetailService = complexEvaluationDetailService;
|
||||
}
|
||||
|
||||
[HttpPost("")]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(EvaluationDetail), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> LoanRatePostComplex([FromBody] EvaluationDetailRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request is null)
|
||||
{
|
||||
return BadRequest("Request cannot be null.");
|
||||
}
|
||||
|
||||
var result = await _complexEvaluationDetailService.SaveComplexAsync(request);
|
||||
return CreatedAtAction("GetById", new { controller = "EvaluationDetail", id = result.EvaluationDetailId }, result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the EvaluationDetail, as well as the Create/Edit/Delete of the EvaluationParameter child collection.
|
||||
/// </summary>
|
||||
/// <param name="evaluationDetail"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> LoanRatePutComplex([FromBody] EvaluationDetail evaluationDetail)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (evaluationDetail is null)
|
||||
{
|
||||
return BadRequest("EvaluationDetail cannot be null.");
|
||||
}
|
||||
|
||||
if (evaluationDetail.EvaluationDetailId == 0)
|
||||
{
|
||||
return BadRequest("EvaluationDetailId cannot be empty.");
|
||||
}
|
||||
|
||||
|
||||
if (!evaluationDetail.EvaluationParameters.Any())
|
||||
{
|
||||
return BadRequest("EvaluationParameters cannot be empty.");
|
||||
}
|
||||
|
||||
var result = await _complexEvaluationDetailService.UpdateComplexAsync(evaluationDetail);
|
||||
if (result is null)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status406NotAcceptable);
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the EvaluationDetail, as well as removes the end date of the previous version.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> LoanRateDeleteComplex(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return BadRequest($"EvaluationDetailId {id} is invalid.");
|
||||
}
|
||||
|
||||
await _complexEvaluationDetailService.DeleteComplexAsync(id);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
using LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class LoadTestInitiateController : ControllerBase
|
||||
{
|
||||
private readonly IQueueLoadTestInitiateService _queueLoadTestInitiateService;
|
||||
|
||||
public LoadTestInitiateController(IQueueLoadTestInitiateService queueLoadTestInitiateService)
|
||||
{
|
||||
_queueLoadTestInitiateService = queueLoadTestInitiateService;
|
||||
}
|
||||
|
||||
[HttpPost("QueueLoadTestInitiateRequest")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> QueueLoadTestInitiateRequest([FromBody] LoadTestInitiateRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _queueLoadTestInitiateService.QueueLoadTestInitiateRequest(request);
|
||||
return Accepted();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+312
@@ -0,0 +1,312 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
using LCU.Library.Internal.LCUFilterModels.Pagination;
|
||||
using LCU.Library.Internal.LoanRateModels.Entities.LoadTestingEntities;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class LoadTestRunInfoController : ControllerBase
|
||||
{
|
||||
private readonly ILoadTestRunInfoService _loadTestRunInfoService;
|
||||
|
||||
public LoadTestRunInfoController(ILoadTestRunInfoService loadTestRunInfoService)
|
||||
{
|
||||
_loadTestRunInfoService = loadTestRunInfoService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _loadTestRunInfoService.GetAsync();
|
||||
if (result is null || !result.Any())
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(LoadTestRunInfo), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetById(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return BadRequest($"Id {id} is invalid.");
|
||||
}
|
||||
|
||||
var result = await _loadTestRunInfoService.GetByIdAsync(id);
|
||||
if (result is null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("GetListById")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(IEnumerable<LoadTestRunInfo>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetListById([FromBody] List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ids is null || !ids.Any())
|
||||
{
|
||||
return BadRequest("List of ids are invalid.");
|
||||
}
|
||||
|
||||
var result = await _loadTestRunInfoService.GetRangeByIdAsync(ids);
|
||||
if (result == null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("GetFilteredLoadTestRunInfo")]
|
||||
[ProducesResponseType(typeof(PagedResponse<LoadTestRunInfo>), 200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetFilteredLoadTestRunInfo([FromBody] LoadTestRunInfoFilter loadTestRunInfoFilter)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filterResult = await _loadTestRunInfoService.GetFilteredLoadTestRunInfo(loadTestRunInfoFilter);
|
||||
var result = new PagedResponse<LoadTestRunInfo>(filterResult, loadTestRunInfoFilter);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(LoadTestRunInfo), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Post([FromBody] LoadTestRunInfo loadTestRunInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (loadTestRunInfo is null)
|
||||
{
|
||||
return BadRequest("LoadTestRunInfo cannot be null.");
|
||||
}
|
||||
|
||||
var result = await _loadTestRunInfoService.SaveAsync(loadTestRunInfo);
|
||||
return CreatedAtAction(nameof(GetById), new { id = result.LoadTestRunInfoId }, result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("SaveRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(typeof(IEnumerable<LoadTestRunInfo>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> SaveRange([FromBody] List<LoadTestRunInfo> loadTestRunInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (loadTestRunInfos is null || !loadTestRunInfos.Any())
|
||||
{
|
||||
return BadRequest("LoadTestRunInfos cannot be null or empty.");
|
||||
}
|
||||
|
||||
await _loadTestRunInfoService.SaveRangeAsync(loadTestRunInfos);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Put([FromBody] LoadTestRunInfo loadTestRunInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (loadTestRunInfo is null)
|
||||
{
|
||||
return BadRequest("LoadTestRunInfo cannot be null.");
|
||||
}
|
||||
|
||||
if (loadTestRunInfo.LoadTestRunInfoId == 0)
|
||||
{
|
||||
return BadRequest("LoadTestRunInfoId cannot be empty.");
|
||||
}
|
||||
|
||||
var result = await _loadTestRunInfoService.UpdateAsync(loadTestRunInfo);
|
||||
if (result is null)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status406NotAcceptable);
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("UpdateRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> UpdateRange([FromBody] List<LoadTestRunInfo> loadTestRunInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (loadTestRunInfos is null || !loadTestRunInfos.Any())
|
||||
{
|
||||
return BadRequest("LoadTestRunInfos cannot be null or empty.");
|
||||
}
|
||||
|
||||
if (loadTestRunInfos.Any(loadTestRunInfo => loadTestRunInfo.LoadTestRunInfoId == 0))
|
||||
{
|
||||
return BadRequest("LoadTestRunInfoIds cannot be empty.");
|
||||
}
|
||||
|
||||
var result = await _loadTestRunInfoService.UpdateRangeAsync(loadTestRunInfos);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Delete(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return BadRequest($"LoadTestRunInfoId {id} is invalid.");
|
||||
}
|
||||
|
||||
await _loadTestRunInfoService.DeleteAsync(id);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("DeleteRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> DeleteRange([FromBody] List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ids is null || !ids.Any())
|
||||
{
|
||||
return BadRequest("List of ids are invalid.");
|
||||
}
|
||||
|
||||
await _loadTestRunInfoService.DeleteRangeAsync(ids);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateController : ControllerBase
|
||||
{
|
||||
private readonly IRateService _rateService;
|
||||
|
||||
public RateController(IRateService rateService)
|
||||
{
|
||||
_rateService = rateService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _rateService.GetAsync();
|
||||
if (result is null || !result.Any())
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(Rate), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetById(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return BadRequest($"Id {id} is invalid.");
|
||||
}
|
||||
|
||||
var result = await _rateService.GetByIdAsync(id);
|
||||
if (result is null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("GetListById")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(IEnumerable<Rate>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetListById([FromBody] List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ids is null || !ids.Any())
|
||||
{
|
||||
return BadRequest("List of ids are invalid.");
|
||||
}
|
||||
|
||||
var result = await _rateService.GetRangeByIdAsync(ids);
|
||||
if (result == null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("GetByLoadTestRunInfo/{loadTestRunInfoId:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(IEnumerable<Rate>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetByLoadTestRunInfo([FromRoute] int loadTestRunInfoId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (loadTestRunInfoId == 0)
|
||||
{
|
||||
return BadRequest("Id is required");
|
||||
}
|
||||
|
||||
var result = await _rateService.GetByLoadTestRunInfoId(loadTestRunInfoId);
|
||||
if (result == null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(Rate), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Post([FromBody] Rate rate)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rate is null)
|
||||
{
|
||||
return BadRequest("Rate cannot be null.");
|
||||
}
|
||||
|
||||
var result = await _rateService.SaveAsync(rate);
|
||||
return CreatedAtAction(nameof(GetById), new { id = result.RateId }, result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("SaveRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(typeof(IEnumerable<Rate>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> SaveRange([FromBody] List<Rate> rates)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rates is null || !rates.Any())
|
||||
{
|
||||
return BadRequest("Rates cannot be null or empty.");
|
||||
}
|
||||
|
||||
await _rateService.SaveRangeAsync(rates);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Put([FromBody] Rate rate)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rate is null)
|
||||
{
|
||||
return BadRequest("Rate cannot be null.");
|
||||
}
|
||||
|
||||
if (rate.RateId == 0)
|
||||
{
|
||||
return BadRequest("RateId cannot be empty.");
|
||||
}
|
||||
|
||||
var result = await _rateService.UpdateAsync(rate);
|
||||
if (result is null)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status406NotAcceptable);
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("UpdateRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> UpdateRange([FromBody] List<Rate> rates)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rates is null || !rates.Any())
|
||||
{
|
||||
return BadRequest("Rates cannot be null or empty.");
|
||||
}
|
||||
|
||||
if (rates.Any(rate => rate.RateId == 0))
|
||||
{
|
||||
return BadRequest("RateIds cannot be empty.");
|
||||
}
|
||||
|
||||
var result = await _rateService.UpdateRangeAsync(rates);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Delete(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return BadRequest($"RateId {id} is invalid.");
|
||||
}
|
||||
|
||||
await _rateService.DeleteAsync(id);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("DeleteRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> DeleteRange([FromBody] List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ids is null || !ids.Any())
|
||||
{
|
||||
return BadRequest("List of ids are invalid.");
|
||||
}
|
||||
|
||||
await _rateService.DeleteRangeAsync(ids);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("ClearCache")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult ClearCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
_rateService.ClearCache();
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateEvaluationController : ControllerBase
|
||||
{
|
||||
private readonly IRateEvaluationService _rateEvaluationService;
|
||||
|
||||
public RateEvaluationController(IRateEvaluationService rateEvaluationService)
|
||||
{
|
||||
_rateEvaluationService = rateEvaluationService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _rateEvaluationService.GetAsync();
|
||||
if (result is null || !result.Any())
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(RateEvaluation), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetById(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return BadRequest($"Id {id} is invalid.");
|
||||
}
|
||||
|
||||
var result = await _rateEvaluationService.GetByIdAsync(id);
|
||||
if (result is null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("GetListById")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(IEnumerable<RateEvaluation>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetListById([FromBody] List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ids is null || !ids.Any())
|
||||
{
|
||||
return BadRequest("List of ids are invalid.");
|
||||
}
|
||||
|
||||
var result = await _rateEvaluationService.GetRangeByIdAsync(ids);
|
||||
if (result == null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(RateEvaluation), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Post([FromBody] RateEvaluation rateEvaluation)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rateEvaluation is null)
|
||||
{
|
||||
return BadRequest("RateEvaluation cannot be null.");
|
||||
}
|
||||
|
||||
var result = await _rateEvaluationService.SaveAsync(rateEvaluation);
|
||||
return CreatedAtAction(nameof(GetById), new { id = result.RateEvaluationId }, result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("SaveRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(typeof(IEnumerable<RateEvaluation>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> SaveRange([FromBody] List<RateEvaluation> rateEvaluations)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rateEvaluations is null || !rateEvaluations.Any())
|
||||
{
|
||||
return BadRequest("RateEvaluations cannot be null or empty.");
|
||||
}
|
||||
|
||||
await _rateEvaluationService.SaveRangeAsync(rateEvaluations);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Put([FromBody] RateEvaluation rateEvaluation)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rateEvaluation is null)
|
||||
{
|
||||
return BadRequest("RateEvaluation cannot be null.");
|
||||
}
|
||||
|
||||
if (rateEvaluation.RateEvaluationId == 0)
|
||||
{
|
||||
return BadRequest("RateEvaluationId cannot be empty.");
|
||||
}
|
||||
|
||||
var result = await _rateEvaluationService.UpdateAsync(rateEvaluation);
|
||||
if (result is null)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status406NotAcceptable);
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("UpdateRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> UpdateRange([FromBody] List<RateEvaluation> rateEvaluations)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rateEvaluations is null || !rateEvaluations.Any())
|
||||
{
|
||||
return BadRequest("RateEvaluations cannot be null or empty.");
|
||||
}
|
||||
|
||||
if (rateEvaluations.Any(rateEvaluation => rateEvaluation.RateEvaluationId == 0))
|
||||
{
|
||||
return BadRequest("RateEvaluationIds cannot be empty.");
|
||||
}
|
||||
|
||||
var result = await _rateEvaluationService.UpdateRangeAsync(rateEvaluations);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Delete(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return BadRequest($"RateEvaluationId {id} is invalid.");
|
||||
}
|
||||
|
||||
await _rateEvaluationService.DeleteAsync(id);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("DeleteRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> DeleteRange([FromBody] List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ids is null || !ids.Any())
|
||||
{
|
||||
return BadRequest("List of ids are invalid.");
|
||||
}
|
||||
|
||||
await _rateEvaluationService.DeleteRangeAsync(ids);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("CountByEvaluationDetailId/{evaluationDetailId:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> CountByEvaluationDetailId(int evaluationDetailId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (evaluationDetailId <= 0)
|
||||
{
|
||||
return BadRequest($"EvaluationDetailId {evaluationDetailId} is invalid.");
|
||||
}
|
||||
|
||||
return Ok(await _rateEvaluationService.CountByEvaluationDetailIdAsync(evaluationDetailId));
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateFinderController : ControllerBase
|
||||
{
|
||||
private readonly IRateFinderService _rateFinderService;
|
||||
|
||||
public RateFinderController(IRateFinderService rateFinderService)
|
||||
{
|
||||
_rateFinderService = rateFinderService;
|
||||
}
|
||||
|
||||
[HttpPost("FindRate")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> FindRate([FromBody] RateRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(await _rateFinderService.FindRate(request));
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("FindRateObject")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> FindRateObject([FromBody] RateRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(await _rateFinderService.FindRateObject(request));
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
using LCU.Library.Internal.LoanRateModels.Entities.LoadTestingEntities;
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateProcessingInfoController : ControllerBase
|
||||
{
|
||||
private readonly IRateProcessingInfoService _rateProcessingInfoService;
|
||||
|
||||
public RateProcessingInfoController(IRateProcessingInfoService rateProcessingInfoService)
|
||||
{
|
||||
_rateProcessingInfoService = rateProcessingInfoService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _rateProcessingInfoService.GetAsync();
|
||||
if (result is null || !result.Any())
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(RateProcessingInfo), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetById(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return BadRequest($"Id {id} is invalid.");
|
||||
}
|
||||
|
||||
var result = await _rateProcessingInfoService.GetByIdAsync(id);
|
||||
if (result is null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("GetListById")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(IEnumerable<RateProcessingInfo>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetListById([FromBody] List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ids is null || !ids.Any())
|
||||
{
|
||||
return BadRequest("List of ids are invalid.");
|
||||
}
|
||||
|
||||
var result = await _rateProcessingInfoService.GetRangeByIdAsync(ids);
|
||||
if (result == null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(RateProcessingInfo), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Post([FromBody] RateProcessingInfo rateProcessingInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rateProcessingInfo is null)
|
||||
{
|
||||
return BadRequest("RateProcessingInfo cannot be null.");
|
||||
}
|
||||
|
||||
var result = await _rateProcessingInfoService.SaveAsync(rateProcessingInfo);
|
||||
return CreatedAtAction(nameof(GetById), new { id = result.RateProcessingInfoId }, result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("SaveRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(typeof(IEnumerable<RateProcessingInfo>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> SaveRange([FromBody] List<RateProcessingInfo> rateProcessingInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rateProcessingInfos is null || !rateProcessingInfos.Any())
|
||||
{
|
||||
return BadRequest("RateProcessingInfos cannot be null or empty.");
|
||||
}
|
||||
|
||||
await _rateProcessingInfoService.SaveRangeAsync(rateProcessingInfos);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Put([FromBody] RateProcessingInfo rateProcessingInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rateProcessingInfo is null)
|
||||
{
|
||||
return BadRequest("RateProcessingInfo cannot be null.");
|
||||
}
|
||||
|
||||
if (rateProcessingInfo.RateProcessingInfoId == 0)
|
||||
{
|
||||
return BadRequest("RateProcessingInfoId cannot be empty.");
|
||||
}
|
||||
|
||||
var result = await _rateProcessingInfoService.UpdateAsync(rateProcessingInfo);
|
||||
if (result is null)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status406NotAcceptable);
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("UpdateRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> UpdateRange([FromBody] List<RateProcessingInfo> rateProcessingInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rateProcessingInfos is null || !rateProcessingInfos.Any())
|
||||
{
|
||||
return BadRequest("RateProcessingInfos cannot be null or empty.");
|
||||
}
|
||||
|
||||
if (rateProcessingInfos.Any(rateProcessingInfo => rateProcessingInfo.RateProcessingInfoId == 0))
|
||||
{
|
||||
return BadRequest("RateProcessingInfoIds cannot be empty.");
|
||||
}
|
||||
|
||||
var result = await _rateProcessingInfoService.UpdateRangeAsync(rateProcessingInfos);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Delete(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id <= 0)
|
||||
{
|
||||
return BadRequest($"RateProcessingInfoId {id} is invalid.");
|
||||
}
|
||||
|
||||
await _rateProcessingInfoService.DeleteAsync(id);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("DeleteRange")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> DeleteRange([FromBody] List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ids is null || !ids.Any())
|
||||
{
|
||||
return BadRequest("List of ids are invalid.");
|
||||
}
|
||||
|
||||
await _rateProcessingInfoService.DeleteRangeAsync(ids);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateSheetCellController : CrudController<RateSheetCell>
|
||||
{
|
||||
private readonly IRateSheetCellService _rateSheetCellService;
|
||||
|
||||
public RateSheetCellController(IRateSheetCellService rateSheetCellService) : base(rateSheetCellService)
|
||||
{
|
||||
_rateSheetCellService = rateSheetCellService;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateSheetCellUploaderController : ControllerBase
|
||||
{
|
||||
private readonly IRateSheetCellUploaderService _rateSheetCellUploaderService;
|
||||
|
||||
public RateSheetCellUploaderController(IRateSheetCellUploaderService rateSheetCellUploaderService)
|
||||
{
|
||||
_rateSheetCellUploaderService = rateSheetCellUploaderService;
|
||||
}
|
||||
|
||||
[HttpPost("UploadRateSheetCells")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> UploadRateSheetCells(RateSheetCellUploadRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request is null)
|
||||
{
|
||||
return BadRequest("RateSheetCellUploadRequest is required.");
|
||||
}
|
||||
|
||||
var result = await _rateSheetCellUploaderService.UploadRateSheetCellsAsync(request);
|
||||
if (result is null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Controllers;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateSheetController : CrudController<RateSheet>
|
||||
{
|
||||
private readonly IRateSheetService _rateSheetService;
|
||||
|
||||
public RateSheetController(IRateSheetService rateSheetService) : base(rateSheetService)
|
||||
{
|
||||
_rateSheetService = rateSheetService;
|
||||
}
|
||||
|
||||
[HttpPost("GetByDateAndRateType")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(Rate), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetByDateAndRateType([FromBody] RateSheetRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request is null)
|
||||
{
|
||||
return BadRequest("Request cannot be null.");
|
||||
}
|
||||
|
||||
var result = await _rateSheetService.GetByDateAndRateTypeAsync( request.EffectiveDate, request.RateType);
|
||||
if (result is null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("ClearCache")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult ClearCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
_rateSheetService.ClearCache();
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Controllers;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateUploadInfoController : CrudController<RateUploadInfo>
|
||||
{
|
||||
private readonly IRateUploadInfoService _rateUploadInfoService;
|
||||
|
||||
public RateUploadInfoController(IRateUploadInfoService rateUploadInfoService) : base(rateUploadInfoService)
|
||||
{
|
||||
_rateUploadInfoService = rateUploadInfoService;
|
||||
}
|
||||
|
||||
[HttpGet("GetLatest")]
|
||||
[ProducesResponseType(typeof(RateUploadInfo), 200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetLatest()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _rateUploadInfoService.GetLatestAsync();
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("GetFilteredRateUploadInfo")]
|
||||
[ProducesResponseType(typeof(RateUploadInfoFilterResponse), 200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetFilteredRateUploadInfo([FromBody] RateUploadInfoFilter rateUploadInfoFilter)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filterResult = await _rateUploadInfoService.GetFilteredRateUploadInfo(rateUploadInfoFilter);
|
||||
var result = new RateUploadInfoFilterResponse(filterResult, rateUploadInfoFilter);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("ComplexDelete/{id:int}")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> ComplexDelete(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return BadRequest("RateProcessingInfoId is required.");
|
||||
}
|
||||
|
||||
await _rateUploadInfoService.ComplexDelete(id);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("ComplexSave")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> ComplexSave(RateUploadInfoRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request is null)
|
||||
{
|
||||
return BadRequest("RateProcessingInfoRequest is required.");
|
||||
}
|
||||
|
||||
var result = await _rateUploadInfoService.ComplexSave(request);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Requests;
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateUploaderController : ControllerBase
|
||||
{
|
||||
private readonly IRateUploaderService _rateUploaderService;
|
||||
|
||||
public RateUploaderController(IRateUploaderService rateUploaderService)
|
||||
{
|
||||
_rateUploaderService = rateUploaderService;
|
||||
}
|
||||
|
||||
[HttpPost("UploadRates")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> UploadRates(RateUploadRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request is null)
|
||||
{
|
||||
return BadRequest("RateUploadRequest is required.");
|
||||
}
|
||||
|
||||
await _rateUploaderService.UploadRates(request);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("UploadRatesByExcelDataRequest")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> UploadRates([FromBody] RateUploadExcelDataRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _rateUploaderService.UploadRates(request);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("InitiateRatesRulesRequest")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> InitiateRatesRulesRequest([FromBody] IEnumerable<InitiateRatesEvaluationsRequest> requests)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (requests is null || !requests.Any())
|
||||
{
|
||||
return BadRequest("Request can't be null.");
|
||||
}
|
||||
|
||||
var result = await _rateUploaderService.InitiateRatesEvaluations(requests);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
using LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Controllers;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses.Validation;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses.Validation.RateSheetValidations;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class RateValidationController : ControllerBase
|
||||
{
|
||||
private readonly IRateValidationService _rateValidationService;
|
||||
|
||||
public RateValidationController(IRateValidationService rateValidationService)
|
||||
{
|
||||
_rateValidationService = rateValidationService;
|
||||
}
|
||||
|
||||
[HttpPost("Validate")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(RateSheetValidationResult), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Validate([FromBody] List<Rate> rates)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rates is null || rates.Count == 0)
|
||||
{
|
||||
return BadRequest("Rates cannot be null.");
|
||||
}
|
||||
|
||||
var result = await _rateValidationService.ValidateAsync(rates);
|
||||
if (result is null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class StatusController : ControllerBase
|
||||
{
|
||||
private readonly IStatusService _statusService;
|
||||
public StatusController(IStatusService statusService)
|
||||
{
|
||||
_statusService = statusService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(_statusService.GetEnviromentView());
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.LcuEvaluation.Services.EvaluationServices;
|
||||
using LCU.API.Internal.LoanRate.Services.ValidateLoanRateServices;
|
||||
using LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ValidateRateEvaluationsController : ControllerBase
|
||||
{
|
||||
private readonly IValidateRateEvaluationsService _validateRateEvaluationsService;
|
||||
private readonly IRateFinderService _rateFinderService;
|
||||
private readonly IExecuteEvaluationService _executeEvaluationService;
|
||||
|
||||
public ValidateRateEvaluationsController(IValidateRateEvaluationsService validateRateEvaluationsService,
|
||||
IRateFinderService rateFinderService,
|
||||
IExecuteEvaluationService executeEvaluationService)
|
||||
{
|
||||
_validateRateEvaluationsService = validateRateEvaluationsService;
|
||||
_rateFinderService = rateFinderService;
|
||||
_executeEvaluationService = executeEvaluationService;
|
||||
}
|
||||
|
||||
[HttpPost("ValidateRatePassesEvaluation")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> ValidateRatePassesEvaluation([FromBody] RateRequest request, int rateId, int evaluationDetailId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(await _validateRateEvaluationsService.ValidateRatePassesEvaluation(request, rateId, evaluationDetailId));
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("ValidateRatePassesEvaluations")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> ValidateRatePassesEvaluations([FromBody] RateRequest request, int rateId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(await _validateRateEvaluationsService.ValidateRatePassesEvaluations(request, rateId));
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("DetermineRatePassedRules")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> DetermineVehicleRatePassedRules([FromBody] RateRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(await _rateFinderService.DeterminePassedRules(request));
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("RawEvaluationTest")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult RawEvaluationTest(string evaluationCondition, EvaluationReturnTypes evaluationReturnType)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(_executeEvaluationService.ExecuteCondition(evaluationCondition, evaluationReturnType));
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using LCU.Library.Internal.LcuHttpClient.HttpRequest;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Requests;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Responses;
|
||||
using LCU.API.Internal.LoanRate.Configurations;
|
||||
namespace LCU.API.Internal.LoanRate.DataAccess;
|
||||
|
||||
public class FileOperationsApiDao : IFileOperationsApiDao
|
||||
{
|
||||
private readonly FileOperationsApiConfiguration _fileOperationsApiConfiguration;
|
||||
private readonly IPostRequest _postRequest;
|
||||
|
||||
public FileOperationsApiDao(FileOperationsApiConfiguration fileOperationsApiConfiguration, IPostRequest postRequest)
|
||||
{
|
||||
_fileOperationsApiConfiguration = fileOperationsApiConfiguration;
|
||||
_postRequest = postRequest;
|
||||
}
|
||||
|
||||
public async Task<ExcelDataResponse> DirectExtractExcelWorkBookData(ExcelDataRequest request)
|
||||
{
|
||||
return await _postRequest.Async<ExcelDataRequest, ExcelDataResponse>(_fileOperationsApiConfiguration.ExtractExcelWorkBookDataEndpointUri,
|
||||
request);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Requests;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Responses;
|
||||
namespace LCU.API.Internal.LoanRate.DataAccess;
|
||||
|
||||
public interface IFileOperationsApiDao
|
||||
{
|
||||
Task<ExcelDataResponse> DirectExtractExcelWorkBookData(ExcelDataRequest request);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<NoWarn>1701;1702;8618;1591</NoWarn>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<NoWarn>1701;1702;8618;1591</NoWarn>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="HostedServices\**" />
|
||||
<Content Remove="HostedServices\**" />
|
||||
<EmbeddedResource Remove="HostedServices\**" />
|
||||
<None Remove="HostedServices\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LCU.Api.Internal.FileOperationsLib" Version="3.30.6" />
|
||||
<PackageReference Include="LCU.Api.Internal.MaidBotLib" Version="1.0.2" />
|
||||
<PackageReference Include="LCU.Library.Internal.Configuration" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.Exceptions" Version="1.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuClassPatterns.Crud" Version="1.0.2" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuEvaluation" Version="2.0.3" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuHttpClient" Version="1.12.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuMassTransit" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuMassTransitModels" Version="1.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.Logging" Version="1.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.Status" Version="1.2.0" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.8" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LCU.API.Internal.LoanRateLib\LCU.API.Internal.LoanRateLib.csproj" />
|
||||
<ProjectReference Include="..\LCU.API.Internal.LoanRateLoadTestingLib\LCU.API.Internal.LoanRateLoadTestingLib.csproj" />
|
||||
<ProjectReference Include="..\LCU.Library.Internal.LoanRateModels\LCU.Library.Internal.LoanRateModels.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,328 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MassTransit;
|
||||
using Newtonsoft.Json;
|
||||
using LCU.Library.Internal.Configuration;
|
||||
using LCU.Library.Internal.Logging;
|
||||
using LCU.Library.Internal.Logging.Middleware;
|
||||
using LCU.Library.Internal.Logging.Models;
|
||||
using LCU.Library.Internal.Status;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.Library.Internal.LcuMassTransit;
|
||||
using LCU.Library.Internal.LcuHttpClient;
|
||||
using LCU.API.Internal.LoanRate.Configurations;
|
||||
using LoadTestingLibAppDbContext = LCU.API.Internal.LoanRateLoadTestingLib.Persistence.AppDbContext;
|
||||
using LoadTestingLibRepository = LCU.API.Internal.LoanRateLoadTestingLib.Repositories;
|
||||
using LCU.API.Internal.LoanRateLoadTestingLib.Repositories;
|
||||
using LCU.API.Internal.LoanRate.Services;
|
||||
using LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
using LoanRateLibRepository = LCU.API.Internal.LoanRateLib.Repositories;
|
||||
using LoanRateLibPersistence = LCU.API.Internal.LoanRateLib.Persistence;
|
||||
using LCU.API.Internal.LoanRateLib.Repositories;
|
||||
using LCU.API.Internal.LoanRate.Services.ValidateLoanRateServices;
|
||||
using LCU.API.Internal.LoanRate.Consumers;
|
||||
using LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
using LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
using LCU.API.Internal.LoanRate.DataAccess;
|
||||
using LCU.API.Internal.LoanRate.Services.MicroApiServices;
|
||||
using LCU.API.Internal.LoanRateLib.Configurations;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud;
|
||||
using LCU.Library.Internal.LcuEvaluation;
|
||||
|
||||
string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
|
||||
|
||||
var builder = BuildBuilder(args);
|
||||
BuildServicesAndConfigurations(builder);
|
||||
BuildAppAndRun(builder);
|
||||
|
||||
WebApplicationBuilder BuildBuilder(string[] args)
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Configuration.AddJsonFile("/app/config/environment-appsettings/appsettings.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/app/config/mapped-appsettings/appsettings.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/loan-rate-queue-password.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/loan-rate-queue-username.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/loan-rate-evaluation-connection-string.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/loan-rate-load-test-connection-string.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/loan-rate-loan-rate-connection-string.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/loan-rate-seq-api-key.json", optional: true, reloadOnChange: true);
|
||||
builder.Host.UseSerilog();
|
||||
return builder;
|
||||
}
|
||||
|
||||
void BuildServicesAndConfigurations(WebApplicationBuilder builder)
|
||||
{
|
||||
var services = builder.Services;
|
||||
var configuration = builder.Configuration;
|
||||
|
||||
var apiConfiguration = configuration.Bind<ApiConfiguration>(services, "Primary");
|
||||
configuration.Bind<FileOperationsApiConfiguration>(services);
|
||||
configuration.Bind<RateCacheConfiguration>(services);
|
||||
configuration.Bind<RateSheetCacheConfiguration>(services);
|
||||
|
||||
var connectionConfiguration = MassTransitConfigurationSetUp.AddConnectionConfiguration(ref services, configuration);
|
||||
//debugging
|
||||
Console.WriteLine(JsonConvert.SerializeObject(connectionConfiguration));
|
||||
|
||||
var receiveEndpointConfigurations = new ReceiveEndpointConfigurations()
|
||||
{
|
||||
LoadTestInitiateReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
|
||||
"LoadTestInitiateReceiveEndpoint"),
|
||||
LoadTestProcessRateReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
|
||||
"LoadTestProcessRateReceiveEndpoint"),
|
||||
LoadTestRateCompletionReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
|
||||
"LoadTestRateCompletionReceiveEndpoint")
|
||||
};
|
||||
services.AddSingleton(receiveEndpointConfigurations);
|
||||
//debugging
|
||||
Console.WriteLine(JsonConvert.SerializeObject(receiveEndpointConfigurations));
|
||||
|
||||
var loggerConfiguration = new LoggingConfiguration(apiConfiguration.AppName,
|
||||
apiConfiguration.SeqApiKey,
|
||||
apiConfiguration.SeqUrl);
|
||||
var lcuLogging = new LcuLogging(loggerConfiguration);
|
||||
lcuLogging.UseLcuLogging();
|
||||
|
||||
var loanRateSqlConnectionConfiguration = configuration.Bind<LoanRateSqlConnectionConfiguration>(services);
|
||||
services.AddDbContext<LoanRateLibPersistence.AppDbContext>(options =>
|
||||
{
|
||||
options.UseSqlServer
|
||||
(
|
||||
loanRateSqlConnectionConfiguration.ConnectionString,
|
||||
sql => sql.EnableRetryOnFailure(loanRateSqlConnectionConfiguration.MaxRetryCount,
|
||||
loanRateSqlConnectionConfiguration.MaxRetryDelay,
|
||||
null)
|
||||
);
|
||||
});
|
||||
|
||||
var loanRateLoadTestingSqlConnectionConfiguration = configuration.Bind<LoanRateLoadTestingSqlConnectionConfiguration>(services);
|
||||
services.AddDbContext<LoadTestingLibAppDbContext>(options =>
|
||||
{
|
||||
options.UseSqlServer
|
||||
(
|
||||
loanRateLoadTestingSqlConnectionConfiguration.ConnectionString,
|
||||
sql => sql.EnableRetryOnFailure(loanRateLoadTestingSqlConnectionConfiguration.MaxRetryCount,
|
||||
loanRateLoadTestingSqlConnectionConfiguration.MaxRetryDelay,
|
||||
null)
|
||||
);
|
||||
});
|
||||
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(MyAllowSpecificOrigins,
|
||||
builder =>
|
||||
{
|
||||
builder.WithOrigins(
|
||||
apiConfiguration.CorsAllowedOrigins
|
||||
).AllowAnyHeader().AllowAnyMethod();
|
||||
});
|
||||
});
|
||||
|
||||
AddMassTransitServices(ref services, connectionConfiguration, receiveEndpointConfigurations, apiConfiguration);
|
||||
services.AddLCUHttpServices();
|
||||
AddLoanRateLib(services);
|
||||
AddLoanRateLoadTestingLib(services);
|
||||
AddDataAccess(services);
|
||||
AddApiServices(services);
|
||||
|
||||
services.AddLcuEvaluationServices();
|
||||
services.AddLcuEvaluationCrudServices(configuration);
|
||||
services.AddLCUStatusServicesWithApiHealthCheck(configuration);
|
||||
services.AddLcuCrudServices();
|
||||
services.AddHttpClient();
|
||||
services.AddMemoryCache();
|
||||
|
||||
services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
|
||||
services.AddEndpointsApiExplorer();
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = $"{apiConfiguration.AppName}", Version = "v1" });
|
||||
});
|
||||
}
|
||||
|
||||
void AddMassTransitServices(ref IServiceCollection services,
|
||||
ConnectionConfiguration connectionConfiguration,
|
||||
ReceiveEndpointConfigurations receiveEndpointConfigurations,
|
||||
ApiConfiguration apiConfiguration)
|
||||
{
|
||||
services.AddMassTransit(x =>
|
||||
{
|
||||
x.AddConsumer<LoadTestInitiateConsumer>();
|
||||
x.AddConsumer<LoadTestProcessRateConsumer>();
|
||||
x.AddConsumer<LoadTestRateCompletionConsumer>();
|
||||
|
||||
x.UsingRabbitMq((context, cfg) =>
|
||||
{
|
||||
cfg.Host(connectionConfiguration.HostUrl, "/", host =>
|
||||
{
|
||||
host.Username(connectionConfiguration.UserName);
|
||||
host.Password(connectionConfiguration.Password);
|
||||
});
|
||||
cfg.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
|
||||
|
||||
if (apiConfiguration.FeatureFlags.RunLoadTestInitiateConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.LoadTestInitiateReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<LoadTestInitiateConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.LoadTestInitiateReceiveEndpoint.PrefetchLimit;
|
||||
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
|
||||
});
|
||||
}
|
||||
|
||||
if (apiConfiguration.FeatureFlags.RunLoadTestProcessRateConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.LoadTestProcessRateReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<LoadTestProcessRateConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.LoadTestProcessRateReceiveEndpoint.PrefetchLimit;
|
||||
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
|
||||
});
|
||||
}
|
||||
|
||||
if (apiConfiguration.FeatureFlags.RunLoadTestRateCompletionConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.LoadTestRateCompletionReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<LoadTestRateCompletionConsumer>(context, cons =>
|
||||
{
|
||||
//TODO: Will need to add optional configuration in our LCU Masstransit Library for these configurables.
|
||||
cons.Options<BatchOptions>(options => options
|
||||
.SetMessageLimit(100)
|
||||
.SetTimeLimit(5000)
|
||||
.SetConcurrencyLimit(1));
|
||||
});
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.LoadTestRateCompletionReceiveEndpoint.PrefetchLimit;
|
||||
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
services.AddMassTransitHostedService();
|
||||
}
|
||||
|
||||
|
||||
void AddApiServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IStatusService, StatusService>();
|
||||
|
||||
AddLoadTestingServices(services);
|
||||
AddLoanRateOperationServices(services);
|
||||
AddValidateLoanRateServices(services);
|
||||
AddMicroApiServices(services);
|
||||
AddQueueServices(services);
|
||||
services.AddScoped<IRateUploadInfoService, RateUploadInfoService>();
|
||||
services.AddScoped<IRateSheetService, RateSheetService>();
|
||||
services.AddScoped<IRateSheetCellService, RateSheetCellService>();
|
||||
services.AddScoped<IRateService, RateService>();
|
||||
services.AddScoped<IRateEvaluationService, RateEvaluationService>();
|
||||
services.AddScoped<IComplexEvaluationDetailService, ComplexEvaluationDetailService>();
|
||||
services.AddScoped<ILoadTestRunInfoService, LoadTestRunInfoService>();
|
||||
services.AddScoped<IRateProcessingInfoService, RateProcessingInfoService>();
|
||||
}
|
||||
|
||||
void AddLoadTestingServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<ILoadTestInitiationService, LoadTestInitiationService>();
|
||||
services.AddScoped<ILoadTestProcessRateService, LoadTestProcessRateService>();
|
||||
services.AddScoped<ILoadTestRateCompletionService, LoadTestRateCompletionService>();
|
||||
}
|
||||
|
||||
void AddLoanRateOperationServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IRateFinderService, RateFinderService>();
|
||||
services.AddScoped<IRateValidationService, RateValidationService>();
|
||||
services.AddScoped<IRateSheetCellUploaderService, RateSheetCellUploaderService>();
|
||||
}
|
||||
|
||||
void AddValidateLoanRateServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IValidateRateEvaluationsService, ValidateRateEvaluationsService>();
|
||||
}
|
||||
|
||||
void AddMicroApiServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IFileOperationsApiService, FileOperationsApiService>();
|
||||
}
|
||||
|
||||
void AddQueueServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IQueueLoadTestInitiateService, QueueLoadTestInitiateService>();
|
||||
services.AddScoped<IQueueLoadTestProcessRateService, QueueLoadTestProcessRateService>();
|
||||
services.AddScoped<IQueueLoadTestRateCompletionService, QueueLoadTestRateCompletionService>();
|
||||
}
|
||||
|
||||
void AddDataAccess(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IFileOperationsApiDao, FileOperationsApiDao>();
|
||||
}
|
||||
|
||||
void AddLoanRateLib(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<LoanRateLibRepository.IUnitOfWork, LoanRateLibRepository.UnitOfWork>();
|
||||
services.AddScoped<IRateSheetRepository, RateSheetRepository>();
|
||||
services.AddScoped<IRateSheetCellRepository, RateSheetCellRepository>();
|
||||
services.AddScoped<IRateUploadInfoRepository, RateUploadInfoRepository>();
|
||||
services.AddScoped<IRateRepository, RateRepository>();
|
||||
services.AddScoped<IRateEvaluationRepository, RateEvaluationRepository>();
|
||||
}
|
||||
|
||||
void AddLoanRateLoadTestingLib(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<LoadTestingLibRepository.IUnitOfWork, LoadTestingLibRepository.UnitOfWork>();
|
||||
services.AddScoped<ILoadTestRunInfoRepository, LoadTestRunInfoRepository>();
|
||||
services.AddScoped<IRateProcessingInfoRepository, RateProcessingInfoRepository>();
|
||||
}
|
||||
|
||||
void BuildAppAndRun(WebApplicationBuilder builder)
|
||||
{
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseSwagger(c =>
|
||||
{
|
||||
c.PreSerializeFilters.Add((swaggerDoc, request) =>
|
||||
{
|
||||
const string prefixHeader = "X-Forwarded-Prefix";
|
||||
if (!request.Headers.ContainsKey(prefixHeader)) return;
|
||||
|
||||
var serverUrl = request.Headers[prefixHeader];
|
||||
if (!string.IsNullOrWhiteSpace(serverUrl))
|
||||
{
|
||||
swaggerDoc.Servers = new List<OpenApiServer>
|
||||
{
|
||||
new() { Description = serverUrl, Url = serverUrl }
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
c.RoutePrefix = "swagger";
|
||||
c.SwaggerEndpoint("v1/swagger.json", "LCU.API.Internal.LoanRate v1");
|
||||
});
|
||||
app.UseMiddleware<RequestResponseLoggingMiddleware>();
|
||||
app.UseSerilogRequestLogging(options =>
|
||||
{
|
||||
options.EnrichDiagnosticContext = RequestResponseLoggingMiddleware.RequestDataParser.EnrichFromRequest;
|
||||
});
|
||||
|
||||
app.UseRouting();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseCors(MyAllowSpecificOrigins);
|
||||
app.UseHttpsRedirection();
|
||||
app.MapControllers();
|
||||
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
|
||||
|
||||
app.Run();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:28863",
|
||||
"sslPort": 44350
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"API": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "https://localhost:7068;http://localhost:5159",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
using LCU.Library.Internal.LcuEvaluation.Services;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Entities;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Requests;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public class ComplexEvaluationDetailService : IComplexEvaluationDetailService
|
||||
{
|
||||
private readonly IRateEvaluationService _rateEvaluationService;
|
||||
private readonly IEvaluationDetailService _evaluationDetailService;
|
||||
|
||||
public ComplexEvaluationDetailService(IRateEvaluationService rateEvaluationService,
|
||||
IEvaluationDetailService evaluationDetailService)
|
||||
{
|
||||
_rateEvaluationService = rateEvaluationService;
|
||||
_evaluationDetailService = evaluationDetailService;
|
||||
}
|
||||
|
||||
public async Task<EvaluationDetail> UpdateComplexAsync(EvaluationDetail evaluationDetail)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _evaluationDetailService.UpdateComplexAsync(evaluationDetail);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure completing complex update for EvaluationDetail. EvaluationDetailId: {evaluationDetail.EvaluationDetailId}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<EvaluationDetail> SaveComplexAsync(EvaluationDetailRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var newEvaluationDetail = await _evaluationDetailService.SaveComplexAsync(request);
|
||||
|
||||
var previousVersionId = request.PreviousVersionEvaluationDetailId ?? 0;
|
||||
if (previousVersionId <= 0)
|
||||
{
|
||||
return newEvaluationDetail;
|
||||
}
|
||||
|
||||
var rateEvaluations =
|
||||
(await _rateEvaluationService.GetRangeByEvaluationDetailIdAsync(previousVersionId)).ToList();
|
||||
|
||||
if (rateEvaluations is null || !rateEvaluations.Any())
|
||||
{
|
||||
return newEvaluationDetail;
|
||||
}
|
||||
|
||||
var newRateEvaluations = rateEvaluations.Select(rateEvaluation =>
|
||||
new RateEvaluation
|
||||
{
|
||||
RateId = rateEvaluation.RateId,
|
||||
EvaluationDetailId = newEvaluationDetail.EvaluationDetailId
|
||||
}).ToList();
|
||||
|
||||
await _rateEvaluationService.SaveRangeAsync(newRateEvaluations);
|
||||
|
||||
return newEvaluationDetail;
|
||||
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure on SaveComplexAsync. " +
|
||||
$"EvaluationDetailRequest: ({JsonConvert.SerializeObject(request)})";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteComplexAsync(int evaluationDetailId)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _rateEvaluationService.DeleteRangeByEvaluationDetailIdAsync(evaluationDetailId);
|
||||
await _evaluationDetailService.DeleteComplexAsync(evaluationDetailId);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure on DeleteComplexAsync. " +
|
||||
$"EvaluationDetailId: ({evaluationDetailId})";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Entities;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Requests;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public interface IComplexEvaluationDetailService
|
||||
{
|
||||
Task<EvaluationDetail> UpdateComplexAsync(EvaluationDetail evaluationDetail);
|
||||
Task<EvaluationDetail> SaveComplexAsync(EvaluationDetailRequest request);
|
||||
Task DeleteComplexAsync(int evaluationDetailId);
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
using LCU.Library.Internal.LCUFilterModels.Pagination;
|
||||
using LCU.Library.Internal.LoanRateModels.Entities.LoadTestingEntities;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public interface ILoadTestRunInfoService
|
||||
{
|
||||
Task<IEnumerable<LoadTestRunInfo>> GetAsync();
|
||||
Task<LoadTestRunInfo?> GetByIdAsync(int id);
|
||||
Task<IEnumerable<LoadTestRunInfo>> GetRangeByIdAsync(List<int> ids);
|
||||
Task<PagedResult<LoadTestRunInfo>> GetFilteredLoadTestRunInfo(LoadTestRunInfoFilter loadTestRunInfoFilter);
|
||||
Task<LoadTestRunInfo> SaveAsync(LoadTestRunInfo loadTestRunInfo);
|
||||
Task SaveRangeAsync(IEnumerable<LoadTestRunInfo> loadTestRunInfos);
|
||||
Task<LoadTestRunInfo> IncreaseRateProcessingInfosCompleteCountAsync(int loadTestRunInfoId, int countCompleted);
|
||||
Task<LoadTestRunInfo> UpdateAsync(LoadTestRunInfo loadTestRunInfo);
|
||||
Task<IEnumerable<LoadTestRunInfo>> UpdateRangeAsync(IEnumerable<LoadTestRunInfo> loadTestRunInfos);
|
||||
Task DeleteAsync(int id);
|
||||
Task DeleteRangeAsync(List<int> ids);
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public interface IRateEvaluationService
|
||||
{
|
||||
Task<IEnumerable<RateEvaluation>> GetAsync();
|
||||
Task<RateEvaluation?> GetByIdAsync(int id);
|
||||
Task<IEnumerable<RateEvaluation>> GetRangeByIdAsync(List<int> ids);
|
||||
Task<IEnumerable<RateEvaluation>> GetRangeByEvaluationDetailIdAsync(int evaluationDetailId);
|
||||
Task<IEnumerable<RateEvaluation>> GetByRateSheetIdsAsync(List<int> rateSheetIds);
|
||||
Task<RateEvaluation> SaveAsync(RateEvaluation rateEvaluation);
|
||||
Task SaveRangeAsync(IEnumerable<RateEvaluation> rateEvaluations);
|
||||
Task<RateEvaluation> UpdateAsync(RateEvaluation rateEvaluation);
|
||||
Task<IEnumerable<RateEvaluation>> UpdateRangeAsync(IEnumerable<RateEvaluation> rateEvaluations);
|
||||
Task DeleteAsync(int id);
|
||||
Task DeleteRangeAsync(List<int> ids);
|
||||
Task DeleteRangeByEvaluationDetailIdAsync(int evaluationDetailId);
|
||||
Task<int> CountByEvaluationDetailIdAsync(int evaluationDetailId);
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Entities.LoadTestingEntities;
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public interface IRateProcessingInfoService
|
||||
{
|
||||
Task<IEnumerable<RateProcessingInfo>> GetAsync();
|
||||
Task<RateProcessingInfo?> GetByIdAsync(int id);
|
||||
Task<IEnumerable<RateProcessingInfo>> GetRangeByIdAsync(List<int> ids);
|
||||
Task<IEnumerable<RateProcessingInfo>?> GetByLoadTestRunInfoId(int loadTestRunInfoId);
|
||||
Task<RateProcessingInfo> SaveAsync(RateProcessingInfo rateProcessingInfo);
|
||||
Task SaveRangeAsync(IEnumerable<RateProcessingInfo> rateProcessingInfos);
|
||||
Task<RateProcessingInfo> UpdateAsync(RateProcessingInfo rateProcessingInfo);
|
||||
Task<IEnumerable<RateProcessingInfo>> UpdateRangeAsync(IEnumerable<RateProcessingInfo> rateProcessingInfos);
|
||||
Task DeleteAsync(int id);
|
||||
Task DeleteRangeAsync(List<int> ids);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
public interface IRateService
|
||||
{
|
||||
Task<IEnumerable<Rate>> GetAsync();
|
||||
Task<Rate?> GetByIdAsync(int id);
|
||||
Task<IEnumerable<Rate>?> GetByClosingRateUploadInfoIdAsync(int id);
|
||||
Task<IEnumerable<Rate>?> GetByDateAsync(DateTime date);
|
||||
Task<IEnumerable<Rate>?> GetRateHistory(Rate rate);
|
||||
Task<IEnumerable<Rate>> GetRangeByIdAsync(List<int> ids);
|
||||
Task<IEnumerable<Rate>?> GetByDateEvaluationIdAndEvaluationTypeAsync(DateTime date,
|
||||
List<int> evaluationIds,
|
||||
EvaluationTypes evaluationType);
|
||||
Task<Dictionary<DateTime, List<Rate>>?> GetByLoadTestRunInfoId(int loadTestRunInfoId);
|
||||
Task<Rate> SaveAsync(Rate rate);
|
||||
Task SaveRangeAsync(IEnumerable<Rate> rates);
|
||||
Task<Rate> UpdateAsync(Rate rate);
|
||||
Task<IEnumerable<Rate>> UpdateRangeAsync(IEnumerable<Rate> rates);
|
||||
Task DeleteAsync(int id);
|
||||
Task DeleteRangeAsync(List<int> ids);
|
||||
void ClearCache();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Services;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
public interface IRateSheetCellService : ICrudService<RateSheetCell>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Services;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
public interface IRateSheetService : ICrudService<RateSheet>
|
||||
{
|
||||
Task<IEnumerable<RateSheet>?> GetIncludeAllAsync();
|
||||
Task<IEnumerable<RateSheet>?> GetIncludeRateSheetCellsAsync();
|
||||
Task<IEnumerable<Rate>?> GetRatesByDateAndRateTypeAsync(DateTime date, RateTypes rateType);
|
||||
Task<RateSheet?> GetByDateAndRateTypeAsync(DateTime date, RateTypes rateType);
|
||||
Task<IEnumerable<Rate>?> GetRatesByRateTypeAsync(RateTypes rateType);
|
||||
Task<IEnumerable<int>?> GetRateSheetIdsByRateTypeAsync(RateTypes rateType);
|
||||
void ClearCache();
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Services;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
public interface IRateUploadInfoService : ICrudService<RateUploadInfo>
|
||||
{
|
||||
Task<RateUploadInfo?> GetLatestAsync();
|
||||
Task<RateUploadInfo?> GetByVersionAsync(int version, DateTime effectiveDate);
|
||||
Task<RateUploadInfo?> GetLatestVersionOnDate(DateTime effectiveDate);
|
||||
Task<RateUploadInfoFilterResult> GetFilteredRateUploadInfo(RateUploadInfoFilter rateUploadInfoFilter);
|
||||
Task ComplexDelete(int id);
|
||||
Task<RateUploadInfo> ComplexSave(RateUploadInfoRequest request);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.StatusModels.Models;
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public interface IStatusService
|
||||
{
|
||||
EnvironmentView GetEnviromentView();
|
||||
}
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
using Microsoft.Data.SqlClient;
|
||||
using LCU.Library.Internal.LoanRateModels.Entities.LoadTestingEntities;
|
||||
using LCU.API.Internal.LoanRateLoadTestingLib.Repositories;
|
||||
using LCU.Library.Internal.LCUFilterModels.Pagination;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public class LoadTestRunInfoService : ILoadTestRunInfoService
|
||||
{
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly ILoadTestRunInfoRepository _loadTestRunInfoRepository;
|
||||
|
||||
public LoadTestRunInfoService(IUnitOfWork unitOfWork, ILoadTestRunInfoRepository loadTestRunInfoRepository)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_loadTestRunInfoRepository = loadTestRunInfoRepository;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<LoadTestRunInfo>> GetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _loadTestRunInfoRepository.FindAsync() ?? new List<LoadTestRunInfo>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving LoadTestRunInfos.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<LoadTestRunInfo?> GetByIdAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _loadTestRunInfoRepository.FindByIdAsync(id);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving LoadTestRunInfo with id: {id}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<LoadTestRunInfo>> GetRangeByIdAsync(List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _loadTestRunInfoRepository.FindRangeByIdAsync(ids) ?? new List<LoadTestRunInfo>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving LoadTestRunInfos. " +
|
||||
$"Ids: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())}).";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<PagedResult<LoadTestRunInfo>> GetFilteredLoadTestRunInfo(LoadTestRunInfoFilter loadTestRunInfoFilter)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _loadTestRunInfoRepository.FindFilteredLoadTestRunInfosAsync(loadTestRunInfoFilter);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving filtered LoadTestRunInfos.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<LoadTestRunInfo> SaveAsync(LoadTestRunInfo loadTestRunInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _loadTestRunInfoRepository.AddAsync(loadTestRunInfo);
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
throw new Exception("Saving a LoadTestRunInfo returned null.");
|
||||
}
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
return result;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure saving LoadTestRunInfo.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SaveRangeAsync(IEnumerable<LoadTestRunInfo> loadTestRunInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _loadTestRunInfoRepository.AddRangeAsync(loadTestRunInfos);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure saving list of LoadTestRunInfos.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<LoadTestRunInfo> IncreaseRateProcessingInfosCompleteCountAsync(int loadTestRunInfoId, int countCompleted)
|
||||
{
|
||||
try
|
||||
{
|
||||
var existing = await GetByIdAsync(loadTestRunInfoId);
|
||||
if (existing is null)
|
||||
{
|
||||
Log.Error($"LoadTestRunInfo with id:{loadTestRunInfoId} was not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
existing.RateProcessingInfosCompleteCount = existing.RateProcessingInfosCompleteCount + countCompleted;
|
||||
|
||||
if (existing.RateProcessingInfosCount == existing.RateProcessingInfosCompleteCount)
|
||||
{
|
||||
existing.EndTimeStamp = DateTime.Now;
|
||||
}
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
return existing;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = $"SQL Failure LoadTestRunInfo Increasing Rate Processing Infos Complete Count. LoadTestRunInfoId: {loadTestRunInfoId}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure LoadTestRunInfo Increasing Rate Processing Infos Complete Count. LoadTestRunInfoId: {loadTestRunInfoId}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<LoadTestRunInfo> UpdateAsync(LoadTestRunInfo loadTestRunInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
var existing = await GetByIdAsync(loadTestRunInfo.LoadTestRunInfoId);
|
||||
if (existing is null)
|
||||
{
|
||||
Log.Error($"LoadTestRunInfo with id:{loadTestRunInfo.LoadTestRunInfoId} was not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
existing.StartTimeStamp = loadTestRunInfo.StartTimeStamp;
|
||||
existing.EndTimeStamp = loadTestRunInfo.EndTimeStamp;
|
||||
existing.RateType = loadTestRunInfo.RateType;
|
||||
existing.RateProcessingInfosCount = loadTestRunInfo.RateProcessingInfosCount;
|
||||
existing.RateProcessingInfosCompleteCount = loadTestRunInfo.RateProcessingInfosCompleteCount;
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
return existing;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = $"SQL Failure updating LoadTestRunInfo. LoadTestRunInfoId: {loadTestRunInfo.LoadTestRunInfoId}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure updating LoadTestRunInfo. LoadTestRunInfoId: {loadTestRunInfo.LoadTestRunInfoId}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<LoadTestRunInfo>> UpdateRangeAsync(IEnumerable<LoadTestRunInfo> loadTestRunInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
var records = loadTestRunInfos.ToList();
|
||||
|
||||
_loadTestRunInfoRepository.UpdateRange(records);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
|
||||
return records;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL Failure updating list of LoadTestRunInfos.";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure updating list of LoadTestRunInfos.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var loadTestRunInfo = await GetByIdAsync(id);
|
||||
ArgumentNullException.ThrowIfNull(loadTestRunInfo);
|
||||
_loadTestRunInfoRepository.Remove(loadTestRunInfo);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = $"SQL failure removing LoadTestRunInfo. LoadTestRunInfoId: {id}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure removing LoadTestRunInfo. LoadTestRunInfoId: {id}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteRangeAsync(List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
var loadTestRunInfos = await GetRangeByIdAsync(ids);
|
||||
|
||||
if (loadTestRunInfos is null || !loadTestRunInfos.Any())
|
||||
{
|
||||
throw new Exception("GetRangeByIdAsync returned no LoadTestRunInfos to remove.");
|
||||
}
|
||||
|
||||
_loadTestRunInfoRepository.RemoveRange(loadTestRunInfos);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL failure removing list of LoadTestRunInfos. " +
|
||||
$"LoadTestRunInfoIds: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())})";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure removing list of LoadTestRunInfos. " +
|
||||
$"LoadTestRunInfoIds: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())})";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
|
||||
public interface ILoadTestInitiationService
|
||||
{
|
||||
Task HandleLoadTestInitiation(LoadTestInitiateRequest request);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
|
||||
public interface ILoadTestProcessRateService
|
||||
{
|
||||
Task HandleLoadTestProcessRate(LoadTestProcessRateRequest request);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
|
||||
public interface ILoadTestRateCompletionService
|
||||
{
|
||||
Task HandleLoadTestRateCompletion(List<LoadTestRateCompletionRequest> requests);
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
using Newtonsoft.Json;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
using LCU.Library.Internal.LoanRateModels.Entities.LoadTestingEntities;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums.LoadTestingEnums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
|
||||
public class LoadTestInitiationService : ILoadTestInitiationService
|
||||
{
|
||||
private readonly ILoadTestRunInfoService _loadTestRunInfoService;
|
||||
private readonly IRateProcessingInfoService _rateProcessingInfoService;
|
||||
private readonly IQueueLoadTestProcessRateService _queueLoadTestProcessRateService;
|
||||
|
||||
public LoadTestInitiationService(ILoadTestRunInfoService loadTestRunInfoService,
|
||||
IRateProcessingInfoService rateProcessingInfoService,
|
||||
IQueueLoadTestProcessRateService queueLoadTestProcessRateService)
|
||||
{
|
||||
_loadTestRunInfoService = loadTestRunInfoService;
|
||||
_rateProcessingInfoService = rateProcessingInfoService;
|
||||
_queueLoadTestProcessRateService = queueLoadTestProcessRateService;
|
||||
}
|
||||
|
||||
public async Task HandleLoadTestInitiation(LoadTestInitiateRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var combinations = GenerateModelCombinations<RateRequest>(request.PropertyList);
|
||||
|
||||
var loadTestRunInfo = new LoadTestRunInfo
|
||||
{
|
||||
StartTimeStamp = DateTime.Now,
|
||||
RateType = (RateTypes)request.RateType,
|
||||
RateProcessingInfosCount = combinations.Count
|
||||
};
|
||||
|
||||
combinations = SetRateType(request.RateType, combinations);
|
||||
|
||||
loadTestRunInfo = await _loadTestRunInfoService.SaveAsync(loadTestRunInfo);
|
||||
var rateProcessingInfos = await CreateAndSaveCombinationsRateProcessingInfos(combinations, loadTestRunInfo.LoadTestRunInfoId);
|
||||
await CreateLoadTestProcessRateRequestAndQueue(rateProcessingInfos);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure during Handle Load Test initiation. Exception Message: {exception.Message}";
|
||||
Log.Error(message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<RateProcessingInfo>> CreateAndSaveCombinationsRateProcessingInfos<TCombination>(List<TCombination> combinations, int loadTestRunInfoId)
|
||||
{
|
||||
var rateProcessingInfos = new List<RateProcessingInfo>();
|
||||
foreach (var combination in combinations)
|
||||
{
|
||||
var rateProcessingInfo = new RateProcessingInfo
|
||||
{
|
||||
LoadTestRunInfoId = loadTestRunInfoId,
|
||||
Payload = JsonConvert.SerializeObject(combination),
|
||||
RateProcessingStatusType = RateProcessingStatusTypes.Processing
|
||||
};
|
||||
|
||||
rateProcessingInfos.Add(rateProcessingInfo);
|
||||
}
|
||||
await _rateProcessingInfoService.SaveRangeAsync(rateProcessingInfos);
|
||||
var newRateProcessingInfos = await _rateProcessingInfoService.GetByLoadTestRunInfoId(loadTestRunInfoId);
|
||||
return newRateProcessingInfos.ToList();
|
||||
}
|
||||
|
||||
private async Task CreateLoadTestProcessRateRequestAndQueue(List<RateProcessingInfo> rateProcessingInfos)
|
||||
{
|
||||
var tasks = new List<Task>();
|
||||
foreach (var rateProcessingInfo in rateProcessingInfos)
|
||||
{
|
||||
var loadTestProcessRateRequest = new LoadTestProcessRateRequest
|
||||
{
|
||||
RateProcessingInfo = rateProcessingInfo
|
||||
};
|
||||
tasks.Add(_queueLoadTestProcessRateService.QueueLoadTestProcessRateRequest(loadTestProcessRateRequest));
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
private static List<RateRequest> SetRateType(RateTypes? rateType, List<RateRequest> combinations)
|
||||
{
|
||||
foreach (var combination in combinations)
|
||||
{
|
||||
combination.RateType = (RateTypes)rateType;
|
||||
}
|
||||
|
||||
return combinations;
|
||||
}
|
||||
|
||||
private List<TModel> GenerateModelCombinations<TModel>(Dictionary<string, List<string>> propertyLists)
|
||||
{
|
||||
var combinations = new List<TModel>();
|
||||
GenerateModelCombinationsHelper(propertyLists, combinations, Activator.CreateInstance<TModel>(), propertyLists.Keys.ToArray(), 0);
|
||||
return combinations;
|
||||
}
|
||||
|
||||
private void GenerateModelCombinationsHelper<TModel>(IReadOnlyDictionary<string, List<string>> propertyLists,
|
||||
ICollection<TModel> combinations,
|
||||
TModel currentModel,
|
||||
IReadOnlyList<string> propertyNames,
|
||||
int currentIndex)
|
||||
{
|
||||
if (currentIndex == propertyNames.Count)
|
||||
{
|
||||
combinations.Add(CreateNewInstanceOfModel(currentModel));
|
||||
return;
|
||||
}
|
||||
|
||||
var propertyName = propertyNames[currentIndex];
|
||||
foreach (var item in propertyLists[propertyName])
|
||||
{
|
||||
currentModel = SetModelValueByPropertyName(currentModel, item, propertyName);
|
||||
GenerateModelCombinationsHelper(propertyLists, combinations, currentModel, propertyNames, currentIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private TModel CreateNewInstanceOfModel<TModel>(TModel originalObject)
|
||||
{
|
||||
var newInstance = Activator.CreateInstance<TModel>();
|
||||
var properties = typeof(TModel).GetProperties();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.GetValue(originalObject);
|
||||
property.SetValue(newInstance, value);
|
||||
}
|
||||
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
private TModel SetModelValueByPropertyName<TModel>(TModel currentModel, string item, string propertyName)
|
||||
{
|
||||
var targetTypes = GetObjectsPropertyTypes(currentModel);
|
||||
foreach (var type in targetTypes)
|
||||
{
|
||||
if (currentModel.GetType().GetProperty(propertyName)?.PropertyType.FullName == type.FullName)
|
||||
{
|
||||
var finalItem = ConvertPropertyStringValueToType(item, type);
|
||||
currentModel.GetType().GetProperty(propertyName)?.SetValue(currentModel, finalItem);
|
||||
return currentModel;
|
||||
}
|
||||
}
|
||||
|
||||
return currentModel;
|
||||
}
|
||||
|
||||
private static object ConvertPropertyStringValueToType(string value, Type type)
|
||||
{
|
||||
if (type.IsEnum)
|
||||
{
|
||||
return Enum.Parse(type, value);
|
||||
}
|
||||
|
||||
return Convert.ChangeType(value, type);
|
||||
}
|
||||
|
||||
static List<Type> GetObjectsPropertyTypes(object obj)
|
||||
{
|
||||
var objectType = obj.GetType();
|
||||
var propertyTypes = new List<Type>();
|
||||
var properties = objectType.GetProperties();
|
||||
|
||||
foreach (var propertyInfo in properties)
|
||||
{
|
||||
if (!propertyTypes.Contains(propertyInfo.PropertyType))
|
||||
{
|
||||
propertyTypes.Add(propertyInfo.PropertyType);
|
||||
}
|
||||
}
|
||||
|
||||
return propertyTypes;
|
||||
}
|
||||
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
using Newtonsoft.Json;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.LoanRateModels.Entities.LoadTestingEntities;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
using LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
using LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums.LoadTestingEnums;
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
|
||||
public class LoadTestProcessRateService : ILoadTestProcessRateService
|
||||
{
|
||||
private readonly IRateFinderService _rateFinderService;
|
||||
private readonly IQueueLoadTestRateCompletionService _queueLoadTestRateCompletionService;
|
||||
|
||||
public LoadTestProcessRateService(IRateFinderService rateFinderService,
|
||||
IQueueLoadTestRateCompletionService queueLoadTestRateCompletionService)
|
||||
{
|
||||
_rateFinderService = rateFinderService;
|
||||
_queueLoadTestRateCompletionService = queueLoadTestRateCompletionService;
|
||||
}
|
||||
|
||||
public async Task HandleLoadTestProcessRate(LoadTestProcessRateRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rateRequest = JsonConvert.DeserializeObject<RateRequest>(request.RateProcessingInfo.Payload);
|
||||
var rateProcessingInfo = await FindRateDetails(request.RateProcessingInfo, rateRequest);
|
||||
|
||||
rateProcessingInfo.Rate = rateProcessingInfo.Rate > 0 ? rateProcessingInfo.Rate : (decimal)99.0;
|
||||
var loadTestRateCompletionRequest = new LoadTestRateCompletionRequest
|
||||
{
|
||||
RateProcessingInfo = rateProcessingInfo
|
||||
};
|
||||
|
||||
await _queueLoadTestRateCompletionService.QueueLoadTestRateCompletionRequest(loadTestRateCompletionRequest);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure during Handle Load Test Process Rate. Exception Message: {exception.Message}";
|
||||
Log.Error(message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<RateProcessingInfo> FindRateDetails<TRateRequest>(RateProcessingInfo rateProcessingInfo,
|
||||
TRateRequest rateRequest)
|
||||
where TRateRequest : RateRequest
|
||||
{
|
||||
try
|
||||
{
|
||||
var passedRules = await _rateFinderService.DeterminePassedRules(rateRequest);
|
||||
var rateResponse = await _rateFinderService.DetermineRate(rateRequest.ApplicationDate, passedRules);
|
||||
|
||||
if (rateResponse.rate is null)
|
||||
{
|
||||
throw new ServiceException(rateResponse.message);
|
||||
}
|
||||
|
||||
var rateValue = await _rateFinderService.CalculateFinalRateValue(rateRequest, rateResponse.rate);
|
||||
|
||||
rateProcessingInfo.Column = rateResponse.rate.Column;
|
||||
rateProcessingInfo.Row = rateResponse.rate.Row;
|
||||
rateProcessingInfo.Rate = rateValue;
|
||||
rateProcessingInfo.RateProcessingResultType = RateProcessingResultTypes.RateFound;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
rateProcessingInfo.ProcessingMessage = exception.Message;
|
||||
rateProcessingInfo.RateProcessingResultType = RateProcessingResultTypes.RateFailure;
|
||||
}
|
||||
finally
|
||||
{
|
||||
rateProcessingInfo.RateProcessingStatusType = RateProcessingStatusTypes.Complete;
|
||||
}
|
||||
|
||||
return rateProcessingInfo;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoadTestingServices;
|
||||
|
||||
public class LoadTestRateCompletionService : ILoadTestRateCompletionService
|
||||
{
|
||||
private readonly IRateProcessingInfoService _rateProcessingInfoService;
|
||||
private readonly ILoadTestRunInfoService _loadTestRunInfoService;
|
||||
|
||||
public LoadTestRateCompletionService(IRateProcessingInfoService rateProcessingInfoService, ILoadTestRunInfoService loadTestRunInfoService)
|
||||
{
|
||||
_rateProcessingInfoService = rateProcessingInfoService;
|
||||
_loadTestRunInfoService = loadTestRunInfoService;
|
||||
}
|
||||
|
||||
public async Task HandleLoadTestRateCompletion(List<LoadTestRateCompletionRequest> requests)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rateProcessingInfos = requests.Select(request => request.RateProcessingInfo).ToList();
|
||||
await _rateProcessingInfoService.UpdateRangeAsync(rateProcessingInfos);
|
||||
|
||||
var loadTestRunInfoGroups = rateProcessingInfos.GroupBy(
|
||||
p => p.LoadTestRunInfoId,
|
||||
p => p.RateProcessingInfoId,
|
||||
(key, g) => new { LoadTestRunInfoId = key, RateProcessingInfoIds = g.ToList() });
|
||||
foreach(var loadTestRunInfoGroup in loadTestRunInfoGroups)
|
||||
{
|
||||
await _loadTestRunInfoService.IncreaseRateProcessingInfosCompleteCountAsync(loadTestRunInfoGroup.LoadTestRunInfoId,
|
||||
loadTestRunInfoGroup.RateProcessingInfoIds.Count);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure during Handle Load Test Rate Completion. Exception Message: {exception.Message}";
|
||||
Log.Error(message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Entities;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
|
||||
public interface IRateFinderService
|
||||
{
|
||||
Task<RateResponse> FindRate<TRequest>(TRequest request) where TRequest : RateRequest;
|
||||
Task<Rate?> FindRateObject<TRequest>(TRequest request) where TRequest : RateRequest;
|
||||
Task<List<EvaluationDetail>> DeterminePassedRules<TRequest>(TRequest request) where TRequest : RateRequest;
|
||||
Task<(Rate rate, string message)> DetermineRate(DateTime applicationDate, List<EvaluationDetail> passedRules);
|
||||
Task<decimal> CalculateFinalRateValue<TRequest>(TRequest request, Rate rate) where TRequest : RateRequest;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
public interface IRateSheetCellUploaderService
|
||||
{
|
||||
public Task<List<RateSheet>> UploadRateSheetCellsAsync(RateSheetCellUploadRequest request);
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Requests;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
|
||||
public interface IRateUploaderService
|
||||
{
|
||||
Task UploadRates(RateUploadRequest request);
|
||||
Task UploadRates(RateUploadExcelDataRequest request);
|
||||
Task<IEnumerable<InitiateRatesEvaluationsResponse>> InitiateRatesEvaluations(IEnumerable<InitiateRatesEvaluationsRequest> requests);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Responses.Validation.RateSheetValidations;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
public interface IRateValidationService
|
||||
{
|
||||
Task<List<RateSheetValidationResult>> ValidateAsync(List<Rate> rates);
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Enums;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Requests;
|
||||
using LCU.Library.Internal.LcuEvaluation.Services;
|
||||
using LCU.Library.Internal.LcuEvaluation.Services.EvaluationServices;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Entities;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
|
||||
public class RateFinderService : IRateFinderService
|
||||
{
|
||||
private readonly IEvaluationDetailService _evaluationDetailService;
|
||||
private readonly IRateService _rateService;
|
||||
private readonly IRateSheetService _rateSheetService;
|
||||
private readonly IRateEvaluationService _rateEvaluationService;
|
||||
private readonly IRunRuleService _runRuleService;
|
||||
private readonly IRunCalculationService _runCalculationService;
|
||||
|
||||
public RateFinderService(IEvaluationDetailService evaluationDetailService,
|
||||
IRateService rateService,
|
||||
IRateSheetService rateSheetService,
|
||||
IRateEvaluationService rateEvaluationService,
|
||||
IRunRuleService runRuleService,
|
||||
IRunCalculationService runCalculationService)
|
||||
{
|
||||
_evaluationDetailService = evaluationDetailService;
|
||||
_rateService = rateService;
|
||||
_rateSheetService = rateSheetService;
|
||||
_rateEvaluationService = rateEvaluationService;
|
||||
_runRuleService = runRuleService;
|
||||
_runCalculationService = runCalculationService;
|
||||
}
|
||||
|
||||
public async Task<RateResponse> FindRate<TRequest>(TRequest request) where TRequest : RateRequest
|
||||
{
|
||||
try
|
||||
{
|
||||
var passedRules = await DeterminePassedRules(request);
|
||||
var rate = await DetermineRate(request.ApplicationDate, passedRules);
|
||||
return rate.rate is not null
|
||||
? new RateResponse { Rate = await CalculateFinalRateValue(request, rate.rate) }
|
||||
: new RateResponse().SetDefault().AddErrorMessage(rate.message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure during FindRate. ExceptionMessage: {exception.Message}";
|
||||
Log.Error(message, exception);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Rate?> FindRateObject<TRequest>(TRequest request) where TRequest : RateRequest
|
||||
{
|
||||
try
|
||||
{
|
||||
var passedRules = await DeterminePassedRules(request);
|
||||
return (await DetermineRate(request.ApplicationDate, passedRules)).rate;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure during FindRateObject. ExceptionMessage: {exception.Message}";
|
||||
Log.Error(message, exception);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<EvaluationDetail>> DeterminePassedRules<TRequest>(TRequest request) where TRequest : RateRequest
|
||||
{
|
||||
var rateSheetIds = (await _rateSheetService.GetRateSheetIdsByRateTypeAsync(request.RateType))?.ToList();
|
||||
|
||||
if (rateSheetIds is null || rateSheetIds.Count == 0)
|
||||
{
|
||||
throw new ServiceException("No RateSheets were found to help determine rates.");
|
||||
}
|
||||
|
||||
var rateEvaluations = await _rateEvaluationService.GetByRateSheetIdsAsync(rateSheetIds);
|
||||
var ratesEvaluationDetailIds = rateEvaluations.GroupBy(rateEvaluation => rateEvaluation.EvaluationDetailId)
|
||||
.Select(group => group.First().EvaluationDetailId)
|
||||
.ToList();
|
||||
var rules = (await _evaluationDetailService.GetActiveByEvaluationTypeAndIdsAsync(request.ApplicationDate,
|
||||
EvaluationTypes.Rule,
|
||||
ratesEvaluationDetailIds))?.ToList();
|
||||
if (rules is null || rules.Count == 0)
|
||||
{
|
||||
throw new ServiceException("There were no Evaluations to help determine rates.");
|
||||
}
|
||||
|
||||
var passedRules = _runRuleService.ValidateRequestRules(request, rules.ToList());
|
||||
return passedRules;
|
||||
}
|
||||
|
||||
public async Task<(Rate? rate, string message)> DetermineRate(DateTime applicationDate, List<EvaluationDetail> passedRules)
|
||||
{
|
||||
var evaluationIds = passedRules.Select(passedRule => passedRule.EvaluationDetailId).ToList();
|
||||
var matchingRates = (await _rateService.GetByDateEvaluationIdAndEvaluationTypeAsync(applicationDate, evaluationIds, EvaluationTypes.Rule))?.ToList();
|
||||
|
||||
if (matchingRates?.FirstOrDefault() == null)
|
||||
{
|
||||
return ( null, "There were no Rates that matched the evaluations that have passed.");
|
||||
}
|
||||
|
||||
if (matchingRates.Count > 1)
|
||||
{
|
||||
return ( null, "There were more then one Rate that matched the evaluations that passed. " +
|
||||
"This should not happen and the evaluations to rates needs to be confirmed.");
|
||||
}
|
||||
|
||||
return ( matchingRates.FirstOrDefault(), string.Empty );
|
||||
}
|
||||
|
||||
public async Task<decimal> CalculateFinalRateValue<TRequest>(TRequest request, Rate rate) where TRequest : RateRequest
|
||||
{
|
||||
var possibleCalculationIds = rate.RateEvaluations.Select(rateEvaluation => rateEvaluation.EvaluationDetailId).ToList();
|
||||
var calculations = await _evaluationDetailService.GetActiveByEvaluationTypeAndIdsAsync(request.ApplicationDate, EvaluationTypes.Calculation, possibleCalculationIds);
|
||||
|
||||
foreach (var calculation in calculations)
|
||||
{
|
||||
var calculationRequest = new RateCalculationRequest
|
||||
{
|
||||
CurrentRate = rate.Value
|
||||
};
|
||||
var requests = new List<EvaluationRequest> { request, calculationRequest };
|
||||
var calculatedRate = _runCalculationService.CalculateEvaluationWithSetOfRequests(requests, calculation);
|
||||
rate.Value = calculatedRate == null ? rate.Value : (decimal)calculatedRate;
|
||||
}
|
||||
return rate.Value;
|
||||
}
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Requests;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Responses;
|
||||
using LCU.API.Internal.LoanRate.Services.MicroApiServices;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.TypeExtensions.EnumExtensions;
|
||||
using LCU.Library.Internal.TypeExtensions.ObjectExtensions;
|
||||
using RateSheetCell = LCU.Library.Internal.LoanRateModels.Entities.RateSheetCell;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
public class RateSheetCellUploaderService : IRateSheetCellUploaderService
|
||||
{
|
||||
private readonly IRateSheetService _rateSheetService;
|
||||
private readonly IFileOperationsApiService _fileOperationsApiService;
|
||||
|
||||
public RateSheetCellUploaderService(IRateSheetService rateSheetService, IFileOperationsApiService fileOperationsApiService)
|
||||
{
|
||||
_rateSheetService = rateSheetService;
|
||||
_fileOperationsApiService = fileOperationsApiService;
|
||||
}
|
||||
|
||||
public async Task<List<RateSheet>> UploadRateSheetCellsAsync(RateSheetCellUploadRequest uploadRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var excelDataRequest = new ExcelDataRequest
|
||||
{
|
||||
FileContent = uploadRequest.FileContent,
|
||||
SheetRequests = BuildSheetRequests(uploadRequest)
|
||||
};
|
||||
|
||||
var excelDataResponse = await _fileOperationsApiService.DirectExtractExcelWorkBookData(excelDataRequest);
|
||||
var rateSheetCells = await GetRateSheetCells(excelDataResponse, uploadRequest);
|
||||
|
||||
return rateSheetCells;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var message = $"Failure during UploadRateSheetCellsAsync. Exception Message: {ex.Message}";
|
||||
Log.Error(message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private List<SheetRequest> BuildSheetRequests(RateSheetCellUploadRequest uploadRequest)
|
||||
{
|
||||
var sheetRequests = new List<SheetRequest>();
|
||||
foreach (var request in uploadRequest.Requests)
|
||||
{
|
||||
var rows = request.HeaderTopRows.DeepCopy();
|
||||
rows.AddRange(request.HeaderLeftRows);
|
||||
rows = rows.Distinct().ToList();
|
||||
|
||||
var columns = request.HeaderTopColumns.DeepCopy();
|
||||
columns.AddRange(request.HeaderLeftColumns);
|
||||
columns = columns.Distinct().ToList();
|
||||
|
||||
|
||||
sheetRequests.Add(
|
||||
new()
|
||||
{
|
||||
SheetName = request.RateType.GetNameFromValue(),
|
||||
Columns = columns,
|
||||
Rows = rows
|
||||
}
|
||||
);
|
||||
}
|
||||
return sheetRequests;
|
||||
}
|
||||
|
||||
private async Task<List<RateSheet>> GetRateSheetCells(ExcelDataResponse excelDataResponse, RateSheetCellUploadRequest uploadRequest)
|
||||
{
|
||||
var rateSheets = (await _rateSheetService.GetIncludeRateSheetCellsAsync())?.ToList();
|
||||
foreach (var sheetResponse in excelDataResponse.WorkBook.SheetResponses)
|
||||
{
|
||||
var request = uploadRequest.Requests.FirstOrDefault(x => x.RateType.GetNameFromValue() == sheetResponse.SheetName);
|
||||
|
||||
if (request == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var rateSheet = rateSheets?.FirstOrDefault(rateSheet => rateSheet.RateType == request.RateType);
|
||||
|
||||
if (rateSheet == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var cell in sheetResponse.CellResponses)
|
||||
{
|
||||
if (!(request.HeaderTopRows.Contains(cell.Row) &&
|
||||
request.HeaderTopColumns.Contains(cell.ColumnName))
|
||||
&& !(request.HeaderLeftRows.Contains(cell.Row) &&
|
||||
request.HeaderLeftColumns.Contains(cell.ColumnName)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var existingCell = rateSheet.RateSheetCells.FirstOrDefault(rateSheetCell => int.Parse(rateSheetCell.Row) == cell.Row
|
||||
&& rateSheetCell.Column == cell.ColumnName);
|
||||
RateSheetCell rateSheetCell;
|
||||
if (existingCell != null)
|
||||
{
|
||||
rateSheetCell = existingCell;
|
||||
rateSheetCell.Value = FormatValue(cell.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
rateSheetCell = new RateSheetCell
|
||||
{
|
||||
RateSheetId = rateSheet.RateSheetId,
|
||||
RateSheetCellType = RateSheetCellTypes.TopHeader,
|
||||
Column = cell.ColumnName,
|
||||
ColumnSpan = GetColumnSpan(sheetResponse.CellResponses, cell),
|
||||
Row = cell.Row.ToString(),
|
||||
RowSpan = GetRowSpan(sheetResponse.CellResponses, cell),
|
||||
Value = FormatValue(cell.Value)
|
||||
};
|
||||
rateSheet.RateSheetCells.Add(rateSheetCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (await _rateSheetService.UpdateRangeAsync(rateSheets)).ToList();
|
||||
}
|
||||
|
||||
private int GetColumnSpan(List<CellResponse> cellResponses, CellResponse cell)
|
||||
{
|
||||
var rowCells = cellResponses.Where(cellResponse => cellResponse.Row == cell.Row).ToList();
|
||||
var one = rowCells.Where(rowCell => string.Compare(rowCell.ColumnName, cell.ColumnName, StringComparison.InvariantCulture) > 0)
|
||||
.ToList()
|
||||
.Min(rc => rc.ColumnName);
|
||||
|
||||
if (one is null || !one.Any())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var two = cell.ColumnName.ToCharArray().First();
|
||||
return one.ToCharArray().FirstOrDefault() - two;
|
||||
}
|
||||
|
||||
private int GetRowSpan(List<CellResponse> cellResponses, CellResponse cell)
|
||||
{
|
||||
var columnCells = cellResponses.Where(cellResponse => cellResponse.ColumnName == cell.ColumnName).ToList();
|
||||
var one = columnCells.OrderBy(x => x.Row).FirstOrDefault(rc => rc.Row > cell.Row)?.Row ?? cell.Row + 1;
|
||||
var two = cell.Row;
|
||||
return one - two;
|
||||
}
|
||||
|
||||
private string FormatValue(string value)
|
||||
{
|
||||
value = value.Trim();
|
||||
value = value.Replace("\n", "<br>");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.LcuEvaluation.Services;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Requests;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Responses;
|
||||
using LCU.API.Internal.LoanRate.Services.MicroApiServices;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
using LCU.Library.Internal.TypeExtensions.EnumExtensions;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
|
||||
public class RateUploaderService : IRateUploaderService
|
||||
{
|
||||
private readonly IRateService _rateService;
|
||||
private readonly IRateSheetService _rateSheetService;
|
||||
private readonly IEvaluationDetailService _evaluationDetailService;
|
||||
private readonly IRateEvaluationService _rateEvaluationService;
|
||||
private readonly IRateUploadInfoService _rateUploadInfoService;
|
||||
private readonly IFileOperationsApiService _fileOperationsApiService;
|
||||
|
||||
public RateUploaderService(IRateService rateService,
|
||||
IRateSheetService rateSheetService,
|
||||
IEvaluationDetailService evaluationDetailService,
|
||||
IRateEvaluationService rateEvaluationService,
|
||||
IRateUploadInfoService rateUploadInfoService,
|
||||
IFileOperationsApiService fileOperationsApiService)
|
||||
{
|
||||
_rateService = rateService;
|
||||
_rateSheetService = rateSheetService;
|
||||
_evaluationDetailService = evaluationDetailService;
|
||||
_rateEvaluationService = rateEvaluationService;
|
||||
_rateUploadInfoService = rateUploadInfoService;
|
||||
_fileOperationsApiService = fileOperationsApiService;
|
||||
}
|
||||
|
||||
public async Task UploadRates(RateUploadRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rates = (await _rateService.GetByDateAsync(request.EffectiveDate))?.ToList();
|
||||
|
||||
if (rates is null || !rates.Any())
|
||||
{
|
||||
throw new ServiceException($"No rates were found for the EffectiveDate: ({request.EffectiveDate:MM/dd/yyyy})");
|
||||
}
|
||||
|
||||
var previousVersion = await _rateUploadInfoService.GetLatestVersionOnDate(request.EffectiveDate);
|
||||
var rateUploadInfo = BuildNewRateUploadInfo(previousVersion?.Version, request.EffectiveDate, request.FileName, request.CreatedBy);
|
||||
var rateSheets = (await _rateSheetService.GetAsync()).ToList();
|
||||
|
||||
var excelDataRequest = BuildExcelDataRequest(request.FileContent, rates, rateSheets);
|
||||
var excelDataResponse = await _fileOperationsApiService.DirectExtractExcelWorkBookData(excelDataRequest);
|
||||
|
||||
var countOfCellValues = 0;
|
||||
foreach ( var sheet in excelDataResponse.WorkBook.SheetResponses )
|
||||
{
|
||||
countOfCellValues += sheet.CellResponses.Count;
|
||||
}
|
||||
|
||||
if (rates.Count != countOfCellValues)
|
||||
{
|
||||
var message = $"Rate Count of {rates.Count} does not match the count of cell values returned {countOfCellValues}";
|
||||
Log.Error(message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
|
||||
await WorkThroughExcelDataResponseAndUpdateRates(excelDataResponse, rateUploadInfo, rates, rateSheets, request.EffectiveDate);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure during UploadRates. RateExcel FileName: '{request.FileName}' Exception Message: {exception.Message}";
|
||||
Log.Error(message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UploadRates(RateUploadExcelDataRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var excelDataResponse = await _fileOperationsApiService.DirectExtractExcelWorkBookData(request.ExcelDataRequest);
|
||||
var previousVersion = await _rateUploadInfoService.GetLatestVersionOnDate(request.EffectiveDate);
|
||||
var rateUploadInfo = BuildNewRateUploadInfo(previousVersion?.Version, request.EffectiveDate, request.FileName, request.CreatedBy);
|
||||
var rates = (await _rateService.GetByDateAsync(request.EffectiveDate))?.ToList();
|
||||
var rateSheets = (await _rateSheetService.GetAsync()).ToList();
|
||||
await WorkThroughExcelDataResponseAndUpdateRates(excelDataResponse, rateUploadInfo, rates, rateSheets, request.EffectiveDate);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure during UploadRates. Exception Message: {exception.Message}";
|
||||
Log.Error(message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public ExcelDataRequest BuildExcelDataRequest(string rateExcelContent, List<Rate> rates, List<RateSheet> rateSheets)
|
||||
{
|
||||
var sheetRequests = new List<SheetRequest>();
|
||||
foreach (var rate in rates)
|
||||
{
|
||||
var rateSheet = rateSheets.FirstOrDefault(x => x.RateSheetId == rate.RateSheetId);
|
||||
|
||||
if (rateSheet is null)
|
||||
{
|
||||
throw new ServiceException($"Rate Sheet Id {rate.RateSheetId} does not exist");
|
||||
}
|
||||
|
||||
var sheetRequest = sheetRequests.FirstOrDefault(sheet => sheet.SheetName == rateSheet.SheetName);
|
||||
if (sheetRequest == null)
|
||||
{
|
||||
sheetRequest = new SheetRequest();
|
||||
sheetRequest.Rows = new List<int>();
|
||||
sheetRequest.Columns = new List<string>();
|
||||
sheetRequest.SheetName = rateSheet.SheetName;
|
||||
sheetRequests.Add(sheetRequest);
|
||||
}
|
||||
|
||||
var intRow = Convert.ToInt32(rate.Row);
|
||||
if (!sheetRequest.Rows.Contains(intRow))
|
||||
{
|
||||
sheetRequest.Rows.Add(intRow);
|
||||
}
|
||||
|
||||
if (!sheetRequest.Columns.Contains(rate.Column))
|
||||
{
|
||||
sheetRequest.Columns.Add(rate.Column);
|
||||
}
|
||||
}
|
||||
|
||||
var excelDataRequest = new ExcelDataRequest
|
||||
{
|
||||
FileContent = rateExcelContent,
|
||||
SheetRequests = sheetRequests,
|
||||
};
|
||||
|
||||
return excelDataRequest;
|
||||
}
|
||||
|
||||
public async Task WorkThroughExcelDataResponseAndUpdateRates(ExcelDataResponse excelDataResponse,
|
||||
RateUploadInfo rateUploadInfo,
|
||||
List<Rate> rates,
|
||||
List<RateSheet> rateSheets,
|
||||
DateTime effectiveDate)
|
||||
{
|
||||
if (excelDataResponse.WorkBook?.SheetResponses is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ratesToCreate = new List<Rate>();
|
||||
var ratesToClose = new List<Rate>();
|
||||
foreach (var sheet in excelDataResponse.WorkBook.SheetResponses)
|
||||
{
|
||||
var rateSheet = rateSheets.FirstOrDefault(x => x.SheetName == sheet.SheetName);
|
||||
if (rateSheet is null)
|
||||
{
|
||||
var message = $"RateSheet with SheetName: {sheet.SheetName} does not exist.";
|
||||
Log.Error(message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
|
||||
foreach (var cell in sheet.CellResponses)
|
||||
{
|
||||
if (!decimal.TryParse(cell.Value, out decimal newDecimalValue))
|
||||
{
|
||||
var message = $"Cell value was not able to be parsed into a decimal. " +
|
||||
$"Column:{cell.ColumnName}, Row:{cell.Row}, Value:{cell.Value}";
|
||||
Log.Error(message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
|
||||
var rate = rates.FirstOrDefault(requestedRate => requestedRate.RateSheetId == rateSheet.RateSheetId &&
|
||||
requestedRate.Row == cell.Row.ToString() &&
|
||||
string.Equals(requestedRate.Column, cell.ColumnName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (rate is null)
|
||||
{
|
||||
var newRate = new Rate
|
||||
{
|
||||
Column = cell.ColumnName,
|
||||
Row = cell.Row.ToString(),
|
||||
Value = newDecimalValue,
|
||||
RateStartDate = effectiveDate,
|
||||
RateSheetId = rateSheet.RateSheetId
|
||||
};
|
||||
|
||||
ratesToCreate.Add(newRate);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var isNewValue = rate.Value != Math.Round(newDecimalValue, 2);
|
||||
if (!isNewValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var rateToCreate = rate.DeepCopyNewRate();
|
||||
rateToCreate.Value = newDecimalValue;
|
||||
rateToCreate.RateStartDate = effectiveDate;
|
||||
ratesToCreate.Add(rateToCreate);
|
||||
|
||||
if (rate.RateEndDate != null)
|
||||
{
|
||||
throw new ServiceException($"Previous rate, with RateId {rate.RateId}, already has an end date " +
|
||||
$"of {rate.RateEndDate:MM/dd/yyyy}. This should not occur.");
|
||||
}
|
||||
|
||||
rate.RateEndDate = effectiveDate;
|
||||
ratesToClose.Add(rate);
|
||||
}
|
||||
}
|
||||
|
||||
if (ratesToCreate.Count > 0)
|
||||
{
|
||||
rateUploadInfo.Rates = ratesToCreate;
|
||||
rateUploadInfo.RateCount = rateUploadInfo.Rates.Count;
|
||||
}
|
||||
|
||||
if (ratesToClose.Count > 0)
|
||||
{
|
||||
rateUploadInfo.ClosedRates = ratesToClose;
|
||||
}
|
||||
|
||||
if (rateUploadInfo.ClosedRates?.Count > 0 || rateUploadInfo.Rates?.Count > 0)
|
||||
{
|
||||
await _rateUploadInfoService.SaveAsync(rateUploadInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<InitiateRatesEvaluationsResponse>> InitiateRatesEvaluations(IEnumerable<InitiateRatesEvaluationsRequest> requests)
|
||||
{
|
||||
try
|
||||
{
|
||||
var newRateEvaluations = new List<RateEvaluation>();
|
||||
var responses = new List<InitiateRatesEvaluationsResponse>();
|
||||
|
||||
foreach (var request in requests)
|
||||
{
|
||||
var response = new InitiateRatesEvaluationsResponse { Request = request };
|
||||
var rateType = request.SheetName.GetValueFromName<RateTypes>();
|
||||
var existingRates = (await _rateSheetService.GetRatesByRateTypeAsync(rateType))?.ToList();
|
||||
|
||||
var rule = await _evaluationDetailService.GetByIdAsync(request.EvaluationDetailId);
|
||||
if (rule is null)
|
||||
{
|
||||
response.AddSuccessMessage($"Rule was not found with EvaluationDetailId: {request.EvaluationDetailId}");
|
||||
responses.Add(response);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var rowsOrColumns in request.RowsOrColumns)
|
||||
{
|
||||
var foundRates = request.IsRowsRule ? existingRates?.Where(rate => rate.Row == rowsOrColumns).ToList()
|
||||
: existingRates?.Where(rate => rate.Column == rowsOrColumns).ToList();
|
||||
|
||||
if (foundRates is null || !foundRates.Any())
|
||||
{
|
||||
response.AddFailureMessage($"Rule does not exist with EvaluationDetailId: {request.EvaluationDetailId}");
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var foundRate in foundRates)
|
||||
{
|
||||
var rateRuleAlreadyExist = foundRate.RateEvaluations.FirstOrDefault(rate => rate.EvaluationDetailId == request.EvaluationDetailId) is not null;
|
||||
if (rateRuleAlreadyExist)
|
||||
{
|
||||
response.AddSuccessMessage($"RateEvaluation already exists with EvaluationDetailId: {request.EvaluationDetailId}");
|
||||
continue;
|
||||
}
|
||||
|
||||
var newRateEvaluation = new RateEvaluation
|
||||
{
|
||||
EvaluationDetailId = request.EvaluationDetailId,
|
||||
RateId = foundRate.RateId
|
||||
};
|
||||
|
||||
response.RateEvaluationResults.Add(newRateEvaluation);
|
||||
newRateEvaluations.Add(newRateEvaluation);
|
||||
}
|
||||
}
|
||||
responses.Add(response);
|
||||
}
|
||||
|
||||
await _rateEvaluationService.SaveRangeAsync(newRateEvaluations);
|
||||
return responses;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure Initiating RatesEvaluations.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private RateUploadInfo BuildNewRateUploadInfo(int? previousVersion, DateTime effectiveDate, string fileName, string createdBy)
|
||||
=> new ()
|
||||
{
|
||||
Version = (previousVersion ?? 0) + 1,
|
||||
EffectiveDate = effectiveDate,
|
||||
Filename = fileName,
|
||||
TimeCreated = DateTime.Now,
|
||||
CreatedBy = createdBy
|
||||
};
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Responses.Validation;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses.Validation.RateSheetValidations;
|
||||
using Rate = LCU.Library.Internal.LoanRateModels.Entities.Rate;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
public class RateValidationService : IRateValidationService
|
||||
{
|
||||
private readonly IRateService _rateService;
|
||||
|
||||
public RateValidationService(IRateService rateService)
|
||||
{
|
||||
_rateService = rateService;
|
||||
}
|
||||
|
||||
public async Task<List<RateSheetValidationResult>> ValidateAsync(List<Rate> rates)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
var result = new List<RateSheetValidationResult>();
|
||||
foreach (var rate in rates)
|
||||
{
|
||||
var validation = new RateSheetValidationResult
|
||||
{
|
||||
NewItem = rate
|
||||
};
|
||||
|
||||
var rateHistory = (await _rateService.GetRateHistory(rate))?.ToList();
|
||||
if (rateHistory is null || rateHistory.Count == 0)
|
||||
{
|
||||
validation.Message = "Rate history could not be found.";
|
||||
result.Add(validation);
|
||||
validation.Pass = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
rateHistory = rateHistory.OrderBy(x => x.RateStartDate)
|
||||
.ThenBy(x => x.RateEndDate)
|
||||
.ToList();
|
||||
|
||||
var originalRate = await _rateService.GetByIdAsync(rate.RateId);
|
||||
if (originalRate is null)
|
||||
{
|
||||
validation.Message = "Original rate could not be found.";
|
||||
result.Add(validation);
|
||||
validation.Pass = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
validation.OriginalItem = originalRate;
|
||||
|
||||
validation.Validations = new List<RateSheetValidationItem>
|
||||
{
|
||||
RateSheetValidation.IsWithinTrendRange(rate.Value, originalRate.Value, rateHistory.Select(x => x.Value).ToList()),
|
||||
RateSheetValidation.IsWithinRange(rate.Value, rateHistory.Min(x => x.Value), rateHistory.Max(x => x.Value))
|
||||
};
|
||||
|
||||
validation.CheckValidation();
|
||||
result.Add(validation);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure to validate rates.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Requests;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Responses;
|
||||
using LCU.API.Internal.LoanRate.DataAccess;
|
||||
namespace LCU.API.Internal.LoanRate.Services.MicroApiServices;
|
||||
|
||||
public class FileOperationsApiService : IFileOperationsApiService
|
||||
{
|
||||
private readonly IFileOperationsApiDao _fileOperationsApiDao;
|
||||
|
||||
public FileOperationsApiService(IFileOperationsApiDao fileOperationsApiDao)
|
||||
{
|
||||
_fileOperationsApiDao = fileOperationsApiDao;
|
||||
}
|
||||
|
||||
public async Task<ExcelDataResponse> DirectExtractExcelWorkBookData(ExcelDataRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _fileOperationsApiDao.DirectExtractExcelWorkBookData(request);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var error = $"Failure during DirectExtractExcelWorkBookData. Exception Message: {exception.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Requests;
|
||||
using LCU.Api.Internal.FileOperationsLib.Models.ExcelModels.Responses;
|
||||
namespace LCU.API.Internal.LoanRate.Services.MicroApiServices;
|
||||
|
||||
public interface IFileOperationsApiService
|
||||
{
|
||||
Task<ExcelDataResponse> DirectExtractExcelWorkBookData(ExcelDataRequest request);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
namespace LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
|
||||
public interface IQueueLoadTestInitiateService
|
||||
{
|
||||
Task QueueLoadTestInitiateRequest(LoadTestInitiateRequest request);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
namespace LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
|
||||
public interface IQueueLoadTestProcessRateService
|
||||
{
|
||||
Task QueueLoadTestProcessRateRequest(LoadTestProcessRateRequest request);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
namespace LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
|
||||
public interface IQueueLoadTestRateCompletionService
|
||||
{
|
||||
Task QueueLoadTestRateCompletionRequest(LoadTestRateCompletionRequest request);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using MassTransit;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
using LCU.Api.Internal.MaidBotLib.Models;
|
||||
using LCU.API.Internal.LoanRate.Configurations;
|
||||
namespace LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
|
||||
public class QueueLoadTestInitiateService : IQueueLoadTestInitiateService
|
||||
{
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
|
||||
public QueueLoadTestInitiateService(IBusControl busControl,
|
||||
ReceiveEndpointConfigurations receiveEndpointConfigurations)
|
||||
{
|
||||
_sendEndpoint = busControl.GetSendEndpoint(receiveEndpointConfigurations.LoadTestInitiateReceiveEndpoint.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
public async Task QueueLoadTestInitiateRequest(LoadTestInitiateRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
await _sendEndpoint.Send(request, cancellationTokenSource.Token);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, "Failed to Queue Load Test Initiate Request.");
|
||||
throw new ServiceException("Failed to Queue Load Test Initiate Request.");
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using MassTransit;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
using LCU.Api.Internal.MaidBotLib.Models;
|
||||
using LCU.API.Internal.LoanRate.Configurations;
|
||||
namespace LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
|
||||
public class QueueLoadTestProcessRateService : IQueueLoadTestProcessRateService
|
||||
{
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
|
||||
public QueueLoadTestProcessRateService(IBusControl busControl,
|
||||
ReceiveEndpointConfigurations receiveEndpointConfigurations)
|
||||
{
|
||||
_sendEndpoint = busControl.GetSendEndpoint(receiveEndpointConfigurations.LoadTestProcessRateReceiveEndpoint.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
public async Task QueueLoadTestProcessRateRequest(LoadTestProcessRateRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
await _sendEndpoint.Send(request, cancellationTokenSource.Token);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, "Failed to Queue Load Test Process Rate Request.");
|
||||
throw new ServiceException("Failed to Queue Load Test Process Rate Request.");
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using MassTransit;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests.LoadTestRequest;
|
||||
using LCU.Api.Internal.MaidBotLib.Models;
|
||||
using LCU.API.Internal.LoanRate.Configurations;
|
||||
namespace LCU.API.Internal.LoanRate.Services.QueueServices;
|
||||
|
||||
public class QueueLoadTestRateCompletionService : IQueueLoadTestRateCompletionService
|
||||
{
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
|
||||
public QueueLoadTestRateCompletionService(IBusControl busControl,
|
||||
ReceiveEndpointConfigurations receiveEndpointConfigurations)
|
||||
{
|
||||
_sendEndpoint = busControl.GetSendEndpoint(receiveEndpointConfigurations.LoadTestRateCompletionReceiveEndpoint.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
public async Task QueueLoadTestRateCompletionRequest(LoadTestRateCompletionRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
await _sendEndpoint.Send(request, cancellationTokenSource.Token);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, "Failed to Queue Load Test Rate Completion Request.");
|
||||
throw new ServiceException("Failed to Queue Load Test Rate Completion Request.");
|
||||
}
|
||||
}
|
||||
}
|
||||
+311
@@ -0,0 +1,311 @@
|
||||
using Microsoft.Data.SqlClient;
|
||||
using LCU.API.Internal.LoanRateLib.Repositories;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public class RateEvaluationService : IRateEvaluationService
|
||||
{
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IRateEvaluationRepository _rateEvaluationRepository;
|
||||
private readonly IRateService _rateService;
|
||||
|
||||
public RateEvaluationService(IUnitOfWork unitOfWork,
|
||||
IRateEvaluationRepository rateEvaluationRepository,
|
||||
IRateService rateService)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_rateEvaluationRepository = rateEvaluationRepository;
|
||||
_rateService = rateService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateEvaluation>> GetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateEvaluationRepository.FindAsync() ?? new List<RateEvaluation>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving RateEvaluations.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateEvaluation?> GetByIdAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateEvaluationRepository.FindByIdAsync(id);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving RateEvaluation with id: {id}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateEvaluation>> GetRangeByIdAsync(List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateEvaluationRepository.FindRangeByIdAsync(ids) ?? new List<RateEvaluation>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving RateEvaluations. " +
|
||||
$"Ids: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())}).";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateEvaluation>> GetRangeByEvaluationDetailIdAsync(int evaluationDetailId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateEvaluationRepository.FindRangeByEvaluationDetailIdAsync(evaluationDetailId) ?? new List<RateEvaluation>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving RateEvaluations by EvaluationDetailId. " +
|
||||
$"EvaluationDetailId: {evaluationDetailId}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateEvaluation>> GetByRateSheetIdsAsync(List<int> rateSheetIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateEvaluationRepository.FindByRateSheetIdsAsync(rateSheetIds) ?? new List<RateEvaluation>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving RateEvaluations in GetByRateSheetIdsAsync. " +
|
||||
$"RateSheetIds: {string.Join(", ",rateSheetIds)}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateEvaluation> SaveAsync(RateEvaluation rateEvaluation)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _rateEvaluationRepository.AddAsync(rateEvaluation);
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
throw new Exception("Saving a RateEvaluation returned null.");
|
||||
}
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
_rateService.ClearCache();
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure saving RateEvaluation.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SaveRangeAsync(IEnumerable<RateEvaluation> rateEvaluations)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _rateEvaluationRepository.AddRangeAsync(rateEvaluations);
|
||||
|
||||
_rateService.ClearCache();
|
||||
await _unitOfWork.CompleteAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure saving list of RateEvaluations.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateEvaluation> UpdateAsync(RateEvaluation rateEvaluation)
|
||||
{
|
||||
try
|
||||
{
|
||||
var existing = await GetByIdAsync(rateEvaluation.RateEvaluationId);
|
||||
if (existing is null)
|
||||
{
|
||||
Log.Error($"RateEvaluation with id:{rateEvaluation.RateEvaluationId} was not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
existing.RateId = rateEvaluation.RateId;
|
||||
existing.EvaluationDetailId = rateEvaluation.EvaluationDetailId;
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
_rateService.ClearCache();
|
||||
|
||||
return existing;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = $"SQL Failure updating RateEvaluation. RateEvaluationId: {rateEvaluation.RateEvaluationId}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure updating RateEvaluation. RateEvaluationId: {rateEvaluation.RateEvaluationId}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateEvaluation>> UpdateRangeAsync(IEnumerable<RateEvaluation> rateEvaluations)
|
||||
{
|
||||
try
|
||||
{
|
||||
var records = rateEvaluations.ToList();
|
||||
|
||||
_rateEvaluationRepository.UpdateRange(records);
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
_rateService.ClearCache();
|
||||
|
||||
return records;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL Failure updating list of RateEvaluations.";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure updating list of RateEvaluations.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rateEvaluation = await GetByIdAsync(id);
|
||||
ArgumentNullException.ThrowIfNull(rateEvaluation);
|
||||
|
||||
_rateEvaluationRepository.Remove(rateEvaluation);
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
_rateService.ClearCache();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = $"SQL failure removing RateEvaluation. RateEvaluationId: {id}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure removing RateEvaluation. RateEvaluationId: {id}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteRangeAsync(List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rateEvaluations = await GetRangeByIdAsync(ids);
|
||||
|
||||
if (rateEvaluations is null || !rateEvaluations.Any())
|
||||
{
|
||||
throw new Exception("GetRangeByIdAsync returned no RateEvaluations to remove.");
|
||||
}
|
||||
|
||||
_rateEvaluationRepository.RemoveRange(rateEvaluations);
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
_rateService.ClearCache();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL failure removing list of RateEvaluations. " +
|
||||
$"RateEvaluationIds: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())})";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure removing list of RateEvaluations. " +
|
||||
$"RateEvaluationIds: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())})";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteRangeByEvaluationDetailIdAsync(int evaluationDetailId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (evaluationDetailId <= 0)
|
||||
{
|
||||
throw new Exception("EvaluationDetailId must be greater than 0.");
|
||||
}
|
||||
|
||||
var rateEvaluations = (await _rateEvaluationRepository.FindRangeByEvaluationDetailIdAsync(evaluationDetailId))?.ToList();
|
||||
|
||||
if (rateEvaluations is null || !rateEvaluations.Any())
|
||||
{
|
||||
Log.Warning("No RateEvaluations were found for DeleteRangeByEvaluationDetailIdAsync");
|
||||
return;
|
||||
}
|
||||
|
||||
await DeleteRangeAsync(rateEvaluations.Select( x => x.RateEvaluationId ).ToList());
|
||||
_rateService.ClearCache();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL failure removing list of RateEvaluations. " +
|
||||
$"EvaluationDetailId: {evaluationDetailId}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure removing list of RateEvaluations. " +
|
||||
$"EvaluationDetailId: {evaluationDetailId}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<int> CountByEvaluationDetailIdAsync(int evaluationDetailId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateEvaluationRepository.CountByEvaluationDetailIdAsync(evaluationDetailId);
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL failure on CountByEvaluationDetailIdAsync. " +
|
||||
$"EvaluationDetailId: ({evaluationDetailId})";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure on CountByEvaluationDetailIdAsync. " +
|
||||
$"EvaluationDetailId: ({evaluationDetailId})";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
using Microsoft.Data.SqlClient;
|
||||
using LCU.Library.Internal.LoanRateModels.Entities.LoadTestingEntities;
|
||||
using LCU.API.Internal.LoanRateLoadTestingLib.Repositories;
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public class RateProcessingInfoService : IRateProcessingInfoService
|
||||
{
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IRateProcessingInfoRepository _rateProcessingInfoRepository;
|
||||
|
||||
public RateProcessingInfoService(IUnitOfWork unitOfWork,
|
||||
IRateProcessingInfoRepository rateProcessingInfoRepository)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_rateProcessingInfoRepository = rateProcessingInfoRepository;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateProcessingInfo>> GetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateProcessingInfoRepository.FindAsync() ?? new List<RateProcessingInfo>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving RateProcessingInfos.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateProcessingInfo?> GetByIdAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateProcessingInfoRepository.FindByIdAsync(id);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving RateProcessingInfo with id: {id}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateProcessingInfo>> GetRangeByIdAsync(List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateProcessingInfoRepository.FindRangeByIdAsync(ids) ?? new List<RateProcessingInfo>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving RateProcessingInfos. " +
|
||||
$"Ids: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())}).";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateProcessingInfo>?> GetByLoadTestRunInfoId(int loadTestRunInfoId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateProcessingInfoRepository.FindByLoadTestRunInfoIdAsync(loadTestRunInfoId) ?? new List<RateProcessingInfo>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving RateProcessingInfo with loadTestRunInfoId: {loadTestRunInfoId}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateProcessingInfo> SaveAsync(RateProcessingInfo rateProcessingInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _rateProcessingInfoRepository.AddAsync(rateProcessingInfo);
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
throw new Exception("Saving a RateProcessingInfo returned null.");
|
||||
}
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
return result;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure saving RateProcessingInfo.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SaveRangeAsync(IEnumerable<RateProcessingInfo> rateProcessingInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _rateProcessingInfoRepository.AddRangeAsync(rateProcessingInfos);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure saving list of RateProcessingInfos.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateProcessingInfo> UpdateAsync(RateProcessingInfo rateProcessingInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
var existing = await GetByIdAsync(rateProcessingInfo.RateProcessingInfoId);
|
||||
if (existing is null)
|
||||
{
|
||||
Log.Error($"RateProcessingInfo with id:{rateProcessingInfo.RateProcessingInfoId} was not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
existing.LoadTestRunInfoId = rateProcessingInfo.LoadTestRunInfoId;
|
||||
existing.Payload = rateProcessingInfo.Payload;
|
||||
existing.Rate = rateProcessingInfo.Rate;
|
||||
existing.Column = rateProcessingInfo.Column;
|
||||
existing.Row = rateProcessingInfo.Row;
|
||||
existing.RateProcessingStatusType = rateProcessingInfo.RateProcessingStatusType;
|
||||
existing.RateProcessingResultType = rateProcessingInfo.RateProcessingResultType;
|
||||
existing.ProcessingMessage = rateProcessingInfo.ProcessingMessage;
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
return existing;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = $"SQL Failure updating RateProcessingInfo. RateProcessingInfoId: {rateProcessingInfo.RateProcessingInfoId}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure updating RateProcessingInfo. RateProcessingInfoId: {rateProcessingInfo.RateProcessingInfoId}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateProcessingInfo>> UpdateRangeAsync(IEnumerable<RateProcessingInfo> rateProcessingInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
var records = rateProcessingInfos.ToList();
|
||||
|
||||
_rateProcessingInfoRepository.UpdateRange(records);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
|
||||
return records;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL Failure updating list of RateProcessingInfos.";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure updating list of RateProcessingInfos.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rateProcessingInfo = await GetByIdAsync(id);
|
||||
ArgumentNullException.ThrowIfNull(rateProcessingInfo);
|
||||
_rateProcessingInfoRepository.Remove(rateProcessingInfo);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = $"SQL failure removing RateProcessingInfo. RateProcessingInfoId: {id}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure removing RateProcessingInfo. RateProcessingInfoId: {id}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteRangeAsync(List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rateProcessingInfos = await GetRangeByIdAsync(ids);
|
||||
|
||||
if (rateProcessingInfos is null || !rateProcessingInfos.Any())
|
||||
{
|
||||
throw new Exception("GetRangeByIdAsync returned no RateProcessingInfos to remove.");
|
||||
}
|
||||
|
||||
_rateProcessingInfoRepository.RemoveRange(rateProcessingInfos);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL failure removing list of RateProcessingInfos. " +
|
||||
$"RateProcessingInfoIds: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())})";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure removing list of RateProcessingInfos. " +
|
||||
$"RateProcessingInfoIds: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())})";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
using Microsoft.Data.SqlClient;
|
||||
using LCU.API.Internal.LoanRateLib.Repositories;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Enums;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.TypeExtensions.EnumExtensions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public class RateService : IRateService
|
||||
{
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IRateRepository _rateRepository;
|
||||
private readonly IRateSheetService _rateSheetService;
|
||||
private readonly ILoadTestRunInfoService _loadTestRunInfoService;
|
||||
|
||||
public RateService(IUnitOfWork unitOfWork,
|
||||
IRateRepository rateRepository,
|
||||
IRateSheetService rateSheetService,
|
||||
ILoadTestRunInfoService loadTestRunInfoService)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_rateRepository = rateRepository;
|
||||
_rateSheetService = rateSheetService;
|
||||
_loadTestRunInfoService = loadTestRunInfoService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>> GetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateRepository.FindAsync() ?? new List<Rate>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving Rates.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Rate?> GetByIdAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateRepository.FindByIdAsync(id);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving Rate with id: {id}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> GetByDateAsync(DateTime date)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateRepository.FindByDateAsync(date) ?? new List<Rate>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving Rates.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> GetRateHistory(Rate rate)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateRepository.FindRateHistoryAsync(rate) ?? new List<Rate>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving rate history. " +
|
||||
$"Rate: {JsonConvert.SerializeObject(rate)}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>> GetRangeByIdAsync(List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateRepository.FindRangeByIdAsync(ids) ?? new List<Rate>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving Rates. " +
|
||||
$"Ids: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())}).";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> GetByClosingRateUploadInfoIdAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateRepository.FindByClosingRateUploadInfoIdAsync(id) ?? new List<Rate>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving Rates by ClosingRateUploadInfoId with id {id}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> GetByDateEvaluationIdAndEvaluationTypeAsync(DateTime date,
|
||||
List<int> evaluationIds,
|
||||
EvaluationTypes evaluationType)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateRepository.FindByDateEvaluationIdsAndEvaluationTypeAsync(date, evaluationIds, evaluationType) ?? new List<Rate>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving Rates. " +
|
||||
$"Ids: ({string.Join(",", evaluationIds.Select(n => n.ToString()).ToArray())})." +
|
||||
$"EvaluationType: {evaluationType} ";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Dictionary<DateTime, List<Rate>>?> GetByLoadTestRunInfoId(int loadTestRunInfoId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var loadTestRunInfo = await _loadTestRunInfoService.GetByIdAsync(loadTestRunInfoId);
|
||||
|
||||
if (loadTestRunInfo is null)
|
||||
{
|
||||
return new Dictionary<DateTime, List<Rate>>();
|
||||
}
|
||||
|
||||
var rateRequests = loadTestRunInfo.RateProcessingInfos.Select(x => JsonConvert.DeserializeObject<RateRequest>(x.Payload)).ToList();
|
||||
var applicationDates = rateRequests.Select(x => x.ApplicationDate).Distinct();
|
||||
|
||||
var response = new Dictionary<DateTime, List<Rate>>();
|
||||
foreach (var date in applicationDates)
|
||||
{
|
||||
var rates = (await _rateSheetService.GetRatesByDateAndRateTypeAsync(date, loadTestRunInfo.RateType) ?? new List<Rate>()).ToList();
|
||||
response.Add(date, rates);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving Rates by LoadTestRunInfoId. " +
|
||||
$"LoadTestRunInfoId: ({loadTestRunInfoId}).";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Rate> SaveAsync(Rate rate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _rateRepository.AddAsync(rate);
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
throw new Exception("Saving a Rate returned null.");
|
||||
}
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
ClearCache();
|
||||
return result;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure saving Rate.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SaveRangeAsync(IEnumerable<Rate> rates)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _rateRepository.AddRangeAsync(rates);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
ClearCache();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure saving list of Rates.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Rate> UpdateAsync(Rate rate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var existing = await GetByIdAsync(rate.RateId);
|
||||
if (existing is null)
|
||||
{
|
||||
Log.Error($"Rate with id:{rate.RateId} was not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
existing.RateUploadInfoId = rate.RateUploadInfoId;
|
||||
existing.ClosingRateUploadInfoId = rate.ClosingRateUploadInfoId;
|
||||
existing.Column = rate.Column;
|
||||
existing.Row = rate.Row;
|
||||
existing.RateSheetId = rate.RateSheetId;
|
||||
existing.Value = rate.Value;
|
||||
existing.RateStartDate = rate.RateStartDate;
|
||||
existing.RateEndDate = rate.RateEndDate;
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
ClearCache();
|
||||
return existing;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = $"SQL Failure updating Rate. RateId: {rate.RateId}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure updating Rate. RateId: {rate.RateId}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>> UpdateRangeAsync(IEnumerable<Rate> rates)
|
||||
{
|
||||
try
|
||||
{
|
||||
var records = rates.ToList();
|
||||
|
||||
_rateRepository.UpdateRange(records);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
ClearCache();
|
||||
return records;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL Failure updating list of Rates.";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure updating list of Rates.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rate = await GetByIdAsync(id);
|
||||
ArgumentNullException.ThrowIfNull(rate);
|
||||
_rateRepository.Remove(rate);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
ClearCache();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = $"SQL failure removing Rate. RateId: {id}";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure removing Rate. RateId: {id}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteRangeAsync(List<int> ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rates = await GetRangeByIdAsync(ids);
|
||||
|
||||
if (rates is null || !rates.Any())
|
||||
{
|
||||
throw new Exception("GetRangeByIdAsync returned no Rates to remove.");
|
||||
}
|
||||
|
||||
_rateRepository.RemoveRange(rates);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
ClearCache();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
var message = "SQL failure removing list of Rates. " +
|
||||
$"RateIds: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())})";
|
||||
Log.Error(sqlException, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure removing list of Rates. " +
|
||||
$"RateIds: ({string.Join(",", ids.Select(n => n.ToString()).ToArray())})";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
_rateRepository.ClearCache();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure to clear cache for Rates";
|
||||
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using LCU.API.Internal.LoanRateLib.Repositories;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Services;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public class RateSheetCellService : CrudService<RateSheetCell>, IRateSheetCellService
|
||||
{
|
||||
private readonly IRateSheetCellRepository _rateSheetCellRepository;
|
||||
|
||||
public RateSheetCellService(IRateSheetCellRepository rateSheetCellRepository) : base(rateSheetCellRepository)
|
||||
{
|
||||
_rateSheetCellRepository = rateSheetCellRepository;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using LCU.API.Internal.LoanRateLib.Repositories;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Services;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public class RateSheetService : CrudService<RateSheet>, IRateSheetService
|
||||
{
|
||||
private readonly IRateSheetRepository _rateSheetRepository;
|
||||
|
||||
public RateSheetService(IRateSheetRepository rateSheetRepository) : base(rateSheetRepository)
|
||||
{
|
||||
_rateSheetRepository = rateSheetRepository;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateSheet>?> GetIncludeAllAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateSheetRepository.FindIncludeAllAsync() ?? new List<RateSheet>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure during GetIncludeAllAsync.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateSheet>?> GetIncludeRateSheetCellsAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateSheetRepository.FindIncludeRateSheetCellsAsync() ?? new List<RateSheet>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure during GetIncludeRateSheetCellsAsync.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> GetRatesByRateTypeAsync(RateTypes rateType)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateSheetRepository.FindRatesByRateType(rateType) ?? new List<Rate>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving Rates with RateType: {rateType}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<int>?> GetRateSheetIdsByRateTypeAsync(RateTypes rateType)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateSheetRepository.FindRateSheetIdsByRateType(rateType) ?? new List<int>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving RateSheetIds with RateType: {rateType}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> GetRatesByDateAndRateTypeAsync(DateTime date, RateTypes rateType)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateSheetRepository.FindRatesByDateAndRateType(date, rateType) ?? new List<Rate>();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving Rates with RateType ({rateType}) and Date: {date::MM-dd-yyyy HH:mm:ss}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateSheet?> GetByDateAndRateTypeAsync(DateTime date, RateTypes rateType)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateSheetRepository.FindByDateAndRateType(date, rateType);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving RateSheet with RateType ({rateType}) and Date: {date::MM-dd-yyyy HH:mm:ss}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
_rateSheetRepository.ClearCache();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure to clear cache for RateSheets";
|
||||
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
using LCU.API.Internal.LoanRateLib.Repositories;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Services;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
using LCU.Library.Internal.TypeExtensions.ObjectExtensions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public class RateUploadInfoService : CrudService<RateUploadInfo>, IRateUploadInfoService
|
||||
{
|
||||
private readonly IRateUploadInfoRepository _rateUploadInfoRepository;
|
||||
private readonly IRateService _rateService;
|
||||
|
||||
public RateUploadInfoService(IRateUploadInfoRepository rateUploadInfoRepository,
|
||||
IRateService rateService) : base(rateUploadInfoRepository)
|
||||
{
|
||||
_rateUploadInfoRepository = rateUploadInfoRepository;
|
||||
_rateService = rateService;
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfo?> GetLatestAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateUploadInfoRepository.FindLatestAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving latest RateUploadInfo.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfo?> GetByVersionAsync(int version, DateTime effectiveDate)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateUploadInfoRepository.FindByVersionAsync(version, effectiveDate);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving RateUploadInfo with version ({version}) and effective date ({effectiveDate:MM/dd/yyyy}).";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfo?> GetPreviousVersion(RateUploadInfo rateUploadInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateUploadInfoRepository.FindPreviousVersion(rateUploadInfo);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving previous RateUploadInfo. "
|
||||
+ $"RateUploadInfo: {JsonConvert.SerializeObject(rateUploadInfo)}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfo?> GetLatestVersionOnDate(DateTime date)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateUploadInfoRepository.FindLatestVersionOnDate(date);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure retrieving previous RateUploadInfo on date EffectiveDate: {date:MM/dd/yyyy}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfoFilterResult> GetFilteredRateUploadInfo(RateUploadInfoFilter rateUploadInfoFilter)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _rateUploadInfoRepository.FindFilteredRateUploadInfosAsync(rateUploadInfoFilter);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure retrieving filtered RateUploadInfos.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfo> ComplexSave(RateUploadInfoRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var previousVersion = (await GetLatestVersionOnDate(request.EffectiveDate))?.Version;
|
||||
|
||||
var newRates = new List<Rate>();
|
||||
foreach (var newRate in request.Rates.Select(rate => rate.DeepCopy()))
|
||||
{
|
||||
newRate.RateId = 0;
|
||||
newRate.RateStartDate = request.EffectiveDate;
|
||||
newRates.Add(newRate);
|
||||
}
|
||||
|
||||
var oldRates = (await _rateService.GetRangeByIdAsync(request.Rates.Select(rate => rate.RateId).ToList())).ToList();
|
||||
foreach (var rate in oldRates)
|
||||
{
|
||||
rate.RateEndDate = request.EffectiveDate;
|
||||
}
|
||||
|
||||
var rateUploadInfo = new RateUploadInfo
|
||||
{
|
||||
Version = (previousVersion ?? 0) + 1,
|
||||
Filename = request.FileName,
|
||||
EffectiveDate = request.EffectiveDate,
|
||||
ClosedRates = oldRates,
|
||||
Rates = newRates,
|
||||
RateCount = newRates.Count,
|
||||
TimeCreated = DateTime.Now,
|
||||
CreatedBy = request.CreatedBy
|
||||
};
|
||||
|
||||
return await SaveAsync(rateUploadInfo);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = "Failure completing a complex save for RateUploadInfo: " +
|
||||
$"EvaluationDate: {request.EffectiveDate:MM/dd/yyyy} | " +
|
||||
$"Rate Count: {request.Rates.Count}";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ComplexDelete(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id != (await GetLatestAsync())?.RateUploadInfoId)
|
||||
{
|
||||
throw new Exception("Only the most recent RateUploadInfo can be deleted.");
|
||||
}
|
||||
|
||||
var closedRates = (await _rateService.GetByClosingRateUploadInfoIdAsync(id))?.ToList();
|
||||
if (closedRates is not null && closedRates.Count > 0)
|
||||
{
|
||||
foreach (var rate in closedRates)
|
||||
{
|
||||
rate.RateEndDate = null;
|
||||
}
|
||||
|
||||
await _rateService.UpdateRangeAsync(closedRates);
|
||||
}
|
||||
|
||||
await DeleteAsync(id);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var message = $"Failure ComplexDelete for RateUploadInfo with RateUploadInfoId {id}.";
|
||||
Log.Error(exception, message);
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using LCU.Library.Internal.Status.Services;
|
||||
using LCU.Library.Internal.StatusModels.Models;
|
||||
namespace LCU.API.Internal.LoanRate.Services;
|
||||
|
||||
public class StatusService : IStatusService
|
||||
{
|
||||
private readonly IEnvironmentViewService _environmentViewService;
|
||||
|
||||
public StatusService(IEnvironmentViewService environmentViewService)
|
||||
{
|
||||
_environmentViewService = environmentViewService;
|
||||
}
|
||||
|
||||
public EnvironmentView GetEnviromentView()
|
||||
{
|
||||
try
|
||||
{
|
||||
var environmentView = _environmentViewService.BuildEnvironmentView();
|
||||
Log.Verbose("Status Environment View Heartbeat. EnvironmentView: {@EnvironmentView}", environmentView);
|
||||
return environmentView;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failure Getting Enviroment View Information.");
|
||||
throw new ServiceException($"Failure Getting Enviroment View Information.");
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
namespace LCU.API.Internal.LoanRate.Services.ValidateLoanRateServices;
|
||||
|
||||
public interface IValidateRateEvaluationsService
|
||||
{
|
||||
Task<bool> ValidateRatePassesEvaluation(RateRequest request, int rateId, int evaluationDetailId);
|
||||
Task<bool> ValidateRatePassesEvaluations(RateRequest request, int rateId);
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
using LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Enums;
|
||||
using LCU.Library.Internal.LcuEvaluation.Services;
|
||||
using LCU.Library.Internal.LcuEvaluation.Services.EvaluationServices;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Entities;
|
||||
using LCU.Library.Internal.LoanRateModels.Requests;
|
||||
namespace LCU.API.Internal.LoanRate.Services.ValidateLoanRateServices;
|
||||
|
||||
public class ValidateRateEvaluationsService : IValidateRateEvaluationsService
|
||||
{
|
||||
private readonly IEvaluationDetailService _evaluationDetailService;
|
||||
private readonly IRateService _rateService;
|
||||
private readonly IRunRuleService _runRuleService;
|
||||
private readonly IRateFinderService _rateFinderService;
|
||||
|
||||
public ValidateRateEvaluationsService(IEvaluationDetailService evaluationDetailService,
|
||||
IRateService rateService,
|
||||
IRunRuleService runRuleService,
|
||||
IRateFinderService rateFinderService)
|
||||
{
|
||||
_evaluationDetailService = evaluationDetailService;
|
||||
_rateService = rateService;
|
||||
_runRuleService = runRuleService;
|
||||
_rateFinderService = rateFinderService;
|
||||
}
|
||||
|
||||
public async Task<bool> ValidateRatePassesEvaluation(RateRequest request, int rateId, int evaluationDetailId)
|
||||
{
|
||||
var evaluation = await _evaluationDetailService.GetByIdAsync(evaluationDetailId);
|
||||
var passedEvaluations = _runRuleService.ValidateRequestRules(request, new List<EvaluationDetail> { evaluation });
|
||||
var rate = await _rateService.GetByIdAsync(rateId);
|
||||
|
||||
var passedEvaluation = passedEvaluations.FirstOrDefault();
|
||||
if (passedEvaluation == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var passRate = rate.RateEvaluations.FirstOrDefault(rateEvaluation => rateEvaluation.EvaluationDetailId == passedEvaluation.EvaluationDetailId);
|
||||
return passRate != null;
|
||||
}
|
||||
|
||||
public async Task<bool> ValidateRatePassesEvaluations(RateRequest request, int rateId)
|
||||
{
|
||||
var rate = await _rateService.GetByIdAsync(rateId);
|
||||
var evaluationIds = rate.RateEvaluations.Select(rateEvaluation => rateEvaluation.EvaluationDetailId).ToList();
|
||||
var evaluations = await _evaluationDetailService.GetActiveByEvaluationTypeAndIdsAsync(request.ApplicationDate, EvaluationTypes.Rule, evaluationIds);
|
||||
if (!evaluations.Any())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var passedEvaluations = _runRuleService.ValidateRequestRules(request, evaluations.ToList());
|
||||
var matchingRate = (await _rateFinderService.DetermineRate(request.ApplicationDate, passedEvaluations)).rate;
|
||||
|
||||
return matchingRate != null && matchingRate.RateId == rateId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"Primary": {
|
||||
"AppName": "Loan Rate API",
|
||||
"SeqUrl": "https://qa-seq.lcu-internal.com",
|
||||
"SeqApiKey": "",
|
||||
"CorsAllowedOrigins": [
|
||||
"http://localhost:3000",
|
||||
"http://lcu-internal.com",
|
||||
"https://lcu-internal.com",
|
||||
"https://qa-api.lcu-internal.com"
|
||||
],
|
||||
"FeatureFlags": {
|
||||
"RunLoadTestInitiateConsumer": true,
|
||||
"RunLoadTestProcessRateConsumer": true,
|
||||
"RunLoadTestRateCompletionConsumer": true
|
||||
}
|
||||
},
|
||||
"LoanRateSqlConnectionConfiguration": {
|
||||
"ConnectionString": "data source=localhost;initial catalog=LoanRate;Integrated Security=SSPI;MultipleActiveResultSets=True;App=EntityFramework;Encrypt=False;",
|
||||
"MaxRetryCount": 3,
|
||||
"MaxRetryDelay": "00:00:30"
|
||||
},
|
||||
"LoanRateLoadTestingSqlConnectionConfiguration": {
|
||||
"ConnectionString": "data source=localhost;initial catalog=LoanRateLoadTest;Integrated Security=SSPI;MultipleActiveResultSets=True;App=EntityFramework;Encrypt=False;",
|
||||
"MaxRetryCount": 3,
|
||||
"MaxRetryDelay": "00:00:30"
|
||||
},
|
||||
"EvaluationSqlConnectionConfiguration": {
|
||||
"ConnectionString": "data source=localhost;initial catalog=LoanRate;Integrated Security=SSPI;MultipleActiveResultSets=True;App=EntityFramework;Encrypt=False;",
|
||||
"MaxRetryCount": 3,
|
||||
"MaxRetryDelay": "00:00:30"
|
||||
},
|
||||
"ConnectionConfiguration": {
|
||||
"HostUrl": "localhost",
|
||||
"UserName": "guest",
|
||||
"Password": "guest"
|
||||
},
|
||||
"LoadTestInitiateReceiveEndpoint": {
|
||||
"ReceiveEndpoint": "LCU.LoanRate.LoadTest.Initiate",
|
||||
"ReceiveEndpointType": "exchange",
|
||||
"PrefetchLimit": 1
|
||||
},
|
||||
"LoadTestProcessRateReceiveEndpoint": {
|
||||
"ReceiveEndpoint": "LCU.LoanRate.LoadTest.ProcessRate",
|
||||
"ReceiveEndpointType": "exchange",
|
||||
"PrefetchLimit": 1
|
||||
},
|
||||
"LoadTestRateCompletionReceiveEndpoint": {
|
||||
"ReceiveEndpoint": "LCU.LoanRate.LoadTest.RateCompletion",
|
||||
"ReceiveEndpointType": "exchange",
|
||||
"PrefetchLimit": 100
|
||||
},
|
||||
"FileOperationsApiConfiguration": {
|
||||
"Url": "https://localhost:44368",
|
||||
"ExtractExcelWorkBookDataEndpoint": "/api/Excel/ExtractExcelWorkBookData"
|
||||
},
|
||||
"RateCacheConfiguration": {
|
||||
"CacheName": "RateCache",
|
||||
"ExpirationMinutes": "480"
|
||||
},
|
||||
"RateUploadInfoCacheConfiguration": {
|
||||
"CacheName": "RateUploadInfoCache",
|
||||
"ExpirationMinutes": "480"
|
||||
},
|
||||
"RateSheetCacheConfiguration": {
|
||||
"CacheName": "RateSheetCache",
|
||||
"ExpirationMinutes": "480"
|
||||
},
|
||||
"EvaluationCacheConfiguration": {
|
||||
"CacheName": "EvaluationCache",
|
||||
"ExpirationMinutes": "480"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
global using Serilog;
|
||||
global using LCU.Library.Internal.Exceptions;
|
||||
global using LCU.Library.Internal.LoanRateModels.Entities;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LcuCaching.Configurations;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Configurations;
|
||||
|
||||
public class RateCacheConfiguration : CacheConfiguration
|
||||
{
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.LcuCaching.Configurations;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Configurations;
|
||||
|
||||
public class RateSheetCacheConfiguration : CacheConfiguration
|
||||
{
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
namespace LCU.API.Internal.LoanRateLib.Configurations;
|
||||
|
||||
public class RateUploadInfoCacheConfiguration
|
||||
{
|
||||
public string CacheName { get; set; }
|
||||
public int ExpirationMinutes { get; set; }
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
namespace LCU.API.Internal.LoanRateLib.Extensions.Queryables;
|
||||
|
||||
public static class IncludeAllQueryable
|
||||
{
|
||||
public static IQueryable<Rate> IncludeAll(this IQueryable<Rate> queryable)
|
||||
{
|
||||
return queryable.Include(rate => rate.RateEvaluations);
|
||||
}
|
||||
|
||||
public static IQueryable<Rate> IncludeAllRatesEvaluations(this IQueryable<Rate> queryable)
|
||||
{
|
||||
return queryable.Include(rate => rate.RateEvaluations)
|
||||
.ThenInclude(rate => rate.EvaluationDetail);
|
||||
}
|
||||
|
||||
public static IQueryable<RateUploadInfo> IncludeAll(this IQueryable<RateUploadInfo> queryable)
|
||||
{
|
||||
return queryable.Include(rateUploadInfo => rateUploadInfo.Rates)
|
||||
.Include(rateUploadInfo => rateUploadInfo.ClosedRates)
|
||||
.ThenInclude(rate => rate.RateEvaluations);
|
||||
}
|
||||
|
||||
public static IQueryable<RateUploadInfo> IncludeAllButClosedRates(this IQueryable<RateUploadInfo> queryable)
|
||||
{
|
||||
return queryable.Include(rateUploadInfo => rateUploadInfo.Rates)
|
||||
.ThenInclude(rate => rate.RateEvaluations);
|
||||
}
|
||||
|
||||
public static IQueryable<RateSheet> IncludeAll(this IQueryable<RateSheet> queryable)
|
||||
{
|
||||
return queryable.Include(rateSheet => rateSheet.RateSheetCells)
|
||||
.Include(rateSheet => rateSheet.Rates)
|
||||
.ThenInclude(rate => rate.RateEvaluations);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
namespace LCU.API.Internal.LoanRateLib.Extensions.Queryables;
|
||||
public static class IncludeFiltersQueryable
|
||||
{
|
||||
public static IQueryable<RateUploadInfo> IncludeFilters(this IQueryable<RateUploadInfo> queryable, RateUploadInfoFilter rateUploadInfoFilter)
|
||||
=> queryable.FilterByEffectiveDate(rateUploadInfoFilter)
|
||||
.FilterByVersion(rateUploadInfoFilter)
|
||||
.FilterByCreatedBy(rateUploadInfoFilter);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
namespace LCU.API.Internal.LoanRateLib.Extensions.Queryables;
|
||||
public static class RateUploadInfoCreatedByQueryable
|
||||
{
|
||||
public static IQueryable<RateUploadInfo> FilterByCreatedBy(this IQueryable<RateUploadInfo> queryable, RateUploadInfoFilter rateUploadInfoFilter)
|
||||
{
|
||||
if (rateUploadInfoFilter.CreatedBy == null)
|
||||
{
|
||||
return queryable;
|
||||
}
|
||||
|
||||
return queryable.Where(rateUploadInfo => rateUploadInfo.CreatedBy.ToUpper().Contains(rateUploadInfoFilter.CreatedBy.ToUpper()));
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
namespace LCU.API.Internal.LoanRateLib.Extensions.Queryables;
|
||||
public static class RateUploadInfoEffectiveDateQueryable
|
||||
{
|
||||
public static IQueryable<RateUploadInfo> FilterByEffectiveDate(this IQueryable<RateUploadInfo> queryable, RateUploadInfoFilter rateUploadInfoFilter)
|
||||
{
|
||||
if (rateUploadInfoFilter.EffectiveDate == null)
|
||||
{
|
||||
return queryable;
|
||||
}
|
||||
|
||||
return queryable.Where(rateUploadInfo => rateUploadInfo.EffectiveDate.Date == ((DateTime)rateUploadInfoFilter.EffectiveDate).Date);
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
namespace LCU.API.Internal.LoanRateLib.Extensions.Queryables;
|
||||
public static class RateUploadInfoVersionQueryable
|
||||
{
|
||||
public static IQueryable<RateUploadInfo> FilterByVersion(this IQueryable<RateUploadInfo> queryable, RateUploadInfoFilter rateUploadInfoFilter)
|
||||
{
|
||||
if (rateUploadInfoFilter.Version == null)
|
||||
{
|
||||
return queryable;
|
||||
}
|
||||
|
||||
return queryable.Where(rateUploadInfo => rateUploadInfo.Version == (int)rateUploadInfoFilter.Version);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
using System.Linq.Dynamic.Core;
|
||||
using System.Text;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Extensions.Queryables;
|
||||
public static class SortableFieldsQueryable
|
||||
{
|
||||
public static IQueryable<RateUploadInfo> OrderBySortableFields(this IQueryable<RateUploadInfo> queryable, RateUploadInfoFilter rateUploadInfoFilter)
|
||||
{
|
||||
var sortableFields = rateUploadInfoFilter.SortableFields
|
||||
.Where(sortableField => sortableField.Active && sortableField.Position >= 0)
|
||||
.OrderBy(sortableField => sortableField.Position).ToList();
|
||||
|
||||
if (sortableFields == null || !sortableFields.Any())
|
||||
{
|
||||
return queryable;
|
||||
}
|
||||
|
||||
var orderBy = new StringBuilder();
|
||||
foreach (var field in sortableFields)
|
||||
{
|
||||
var addedComma = orderBy.ToString() == "" ? "" : " ,";
|
||||
var desc = field.IsDescending ? " desc" : "";
|
||||
orderBy.Append($"{addedComma}{field.Field}{desc}");
|
||||
}
|
||||
|
||||
return queryable.OrderBy(orderBy.ToString());
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LCU.Library.Internal.LcuCaching" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuClassPatterns.Crud" Version="1.0.2" />
|
||||
<PackageReference Include="LCU.Library.Internal.TypeExtensions" Version="1.2.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.8" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LCU.Library.Internal.LoanRateModels\LCU.Library.Internal.LoanRateModels.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,45 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
namespace LCU.API.Internal.LoanRateLib.Persistence;
|
||||
|
||||
public class AppDbContext : DbContext
|
||||
{
|
||||
public DbSet<Rate> Rates { get; set; }
|
||||
public DbSet<RateEvaluation> RateEvaluations { get; set; }
|
||||
public DbSet<RateUploadInfo> RateUploadInfos { get; set; }
|
||||
public DbSet<RateSheet> RateSheets { get; set; }
|
||||
public DbSet<RateSheetCell> RateSheetCells { get; set; }
|
||||
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
|
||||
builder.Entity<Rate>().ToTable("Rate");
|
||||
builder.Entity<RateEvaluation>().ToTable("RateEvaluation");
|
||||
builder.Entity<RateUploadInfo>().ToTable("RateUploadInfo")
|
||||
.HasMany(rateUploadInfo => rateUploadInfo.Rates)
|
||||
.WithOne()
|
||||
.HasForeignKey(rate => rate.RateUploadInfoId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<RateUploadInfo>().ToTable("RateUploadInfo")
|
||||
.HasMany(rateUploadInfo => rateUploadInfo.ClosedRates)
|
||||
.WithOne()
|
||||
.HasForeignKey(rate => rate.ClosingRateUploadInfoId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
builder.Entity<RateSheet>().ToTable("RateSheet")
|
||||
.HasMany(rateSheet => rateSheet.Rates)
|
||||
.WithOne()
|
||||
.HasForeignKey(rate => rate.RateSheetId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<RateSheet>().ToTable("RateSheet")
|
||||
.HasMany(rateSheet => rateSheet.RateSheetCells)
|
||||
.WithOne()
|
||||
.HasForeignKey(rateSheetCell => rateSheetCell.RateSheetId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<RateSheetCell>().ToTable("RateSheetCell");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using LCU.API.Internal.LoanRateLib.Persistence;
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
|
||||
public abstract class BaseRepository
|
||||
{
|
||||
protected readonly AppDbContext _context;
|
||||
|
||||
public BaseRepository(AppDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
|
||||
public interface IRateEvaluationRepository
|
||||
{
|
||||
Task<IEnumerable<RateEvaluation>?> FindAsync();
|
||||
Task<RateEvaluation?> FindByIdAsync(int id);
|
||||
Task<IEnumerable<RateEvaluation>?> FindRangeByIdAsync(List<int> ids);
|
||||
Task<IEnumerable<RateEvaluation>?> FindRangeByEvaluationDetailIdAsync(int evaluationDetailId);
|
||||
Task<IEnumerable<RateEvaluation>?> FindByRateSheetIdsAsync(List<int> rateSheetIds);
|
||||
Task<RateEvaluation?> AddAsync(RateEvaluation rateEvaluation);
|
||||
Task AddRangeAsync(IEnumerable<RateEvaluation> rateEvaluations);
|
||||
void UpdateRange(IEnumerable<RateEvaluation> rateEvaluations);
|
||||
void Remove(RateEvaluation rateEvaluation);
|
||||
void RemoveRange(IEnumerable<RateEvaluation> rateEvaluations);
|
||||
Task<int> CountByEvaluationDetailIdAsync(int evaluationDetailId);
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
public interface IRateRepository
|
||||
{
|
||||
Task<IEnumerable<Rate>?> FindAsync();
|
||||
Task<IEnumerable<Rate>?> FindWithRateEvaluationsAsync();
|
||||
Task<Rate?> FindByIdAsync(int id);
|
||||
Task<IEnumerable<Rate>?> FindByClosingRateUploadInfoIdAsync(int id);
|
||||
Task<IEnumerable<Rate>?> FindByDateAsync(DateTime date);
|
||||
Task<IEnumerable<Rate>?> FindRateHistoryAsync(Rate rate);
|
||||
Task<IEnumerable<Rate>?> FindRangeByIdAsync(List<int> ids);
|
||||
Task<IEnumerable<Rate>?> FindByDateEvaluationIdsAndEvaluationTypeAsync(DateTime date,
|
||||
List<int> evaluationIds,
|
||||
EvaluationTypes evaluationType);
|
||||
Task<Rate?> AddAsync(Rate rate);
|
||||
Task AddRangeAsync(IEnumerable<Rate> rates);
|
||||
void UpdateRange(IEnumerable<Rate> rates);
|
||||
void Remove(Rate rate);
|
||||
void RemoveRange(IEnumerable<Rate> rates);
|
||||
Task<IEnumerable<Rate>> FindCacheAsync();
|
||||
void ClearCache();
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Repositories;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
public interface IRateSheetCellRepository : ICrudRepository<RateSheetCell>
|
||||
{
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Repositories;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
public interface IRateSheetRepository : ICrudRepository<RateSheet>
|
||||
{
|
||||
Task<IEnumerable<RateSheet>> FindIncludeAllAsync();
|
||||
Task<IEnumerable<RateSheet>> FindIncludeRateSheetCellsAsync();
|
||||
Task<IEnumerable<Rate>?> FindRatesByDateAndRateType(DateTime date, RateTypes rateType);
|
||||
Task<RateSheet?> FindByDateAndRateType(DateTime date, RateTypes rateType);
|
||||
Task<IEnumerable<Rate>?> FindRatesByRateType(RateTypes rateType);
|
||||
Task<IEnumerable<int>?> FindRateSheetIdsByRateType(RateTypes rateType);
|
||||
Task<IEnumerable<RateSheet>> FindCacheAsync();
|
||||
void ClearCache();
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Repositories;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
public interface IRateUploadInfoRepository : ICrudRepository<RateUploadInfo>
|
||||
{
|
||||
Task<RateUploadInfo?> FindLatestAsync();
|
||||
Task<RateUploadInfo?> FindByVersionAsync(int version, DateTime effectiveDate);
|
||||
Task<RateUploadInfo?> FindPreviousVersion(RateUploadInfo rateUploadInfo);
|
||||
Task<RateUploadInfo?> FindLatestVersionOnDate(DateTime effectiveDate);
|
||||
Task<RateUploadInfoFilterResult> FindFilteredRateUploadInfosAsync(RateUploadInfoFilter rateUploadInfoFilter);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
|
||||
public interface IUnitOfWork
|
||||
{
|
||||
Task CompleteAsync();
|
||||
void Complete();
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using LCU.API.Internal.LoanRateLib.Persistence;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
|
||||
public class RateEvaluationRepository : BaseRepository, IRateEvaluationRepository
|
||||
{
|
||||
public IRateRepository _rateRepository;
|
||||
|
||||
public RateEvaluationRepository(AppDbContext context,
|
||||
IRateRepository rateRepository) : base(context)
|
||||
{
|
||||
_rateRepository = rateRepository;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateEvaluation>?> FindAsync()
|
||||
{
|
||||
return await _context.RateEvaluations.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<RateEvaluation?> FindByIdAsync(int id)
|
||||
{
|
||||
return await _context.RateEvaluations.FirstOrDefaultAsync(rateEvaluation => rateEvaluation.RateEvaluationId == id);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateEvaluation>?> FindRangeByIdAsync(List<int> ids)
|
||||
{
|
||||
return await _context.RateEvaluations
|
||||
.Where(rateEvaluation => ids.Contains(rateEvaluation.RateEvaluationId))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateEvaluation>?> FindRangeByEvaluationDetailIdAsync(int evaluationDetailId)
|
||||
{
|
||||
return await _context.RateEvaluations
|
||||
.Where(rateEvaluation => rateEvaluation.EvaluationDetailId == evaluationDetailId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateEvaluation>?> FindByRateSheetIdsAsync(List<int> rateSheetIds)
|
||||
{
|
||||
return (await _rateRepository.FindCacheAsync())
|
||||
.Where(rate => rateSheetIds.Contains(rate.RateSheetId))
|
||||
.SelectMany(rate => rate.RateEvaluations);
|
||||
}
|
||||
|
||||
public async Task<RateEvaluation?> AddAsync(RateEvaluation rateEvaluation)
|
||||
{
|
||||
return (await _context.RateEvaluations.AddAsync(rateEvaluation)).Entity;
|
||||
}
|
||||
|
||||
public async Task AddRangeAsync(IEnumerable<RateEvaluation> rateEvaluations)
|
||||
{
|
||||
await _context.RateEvaluations.AddRangeAsync(rateEvaluations);
|
||||
}
|
||||
|
||||
public void UpdateRange(IEnumerable<RateEvaluation> rateEvaluations)
|
||||
{
|
||||
_context.RateEvaluations.UpdateRange(rateEvaluations);
|
||||
}
|
||||
|
||||
public void Remove(RateEvaluation rateEvaluation)
|
||||
{
|
||||
_context.RateEvaluations.Remove(rateEvaluation);
|
||||
}
|
||||
|
||||
public void RemoveRange(IEnumerable<RateEvaluation> rateEvaluations)
|
||||
{
|
||||
_context.RateEvaluations.RemoveRange(rateEvaluations);
|
||||
}
|
||||
|
||||
public async Task<int> CountByEvaluationDetailIdAsync(int evaluationDetailId)
|
||||
{
|
||||
return await _context.RateEvaluations
|
||||
.Where(rateEvaluation => rateEvaluation.EvaluationDetailId == evaluationDetailId)
|
||||
.Select(rateEvaluation => rateEvaluation.RateId)
|
||||
.Distinct()
|
||||
.CountAsync();
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using LCU.API.Internal.LoanRateLib.Configurations;
|
||||
using LCU.API.Internal.LoanRateLib.Extensions.Queryables;
|
||||
using LCU.API.Internal.LoanRateLib.Persistence;
|
||||
using LCU.Library.Internal.LcuCaching.Services;
|
||||
using LCU.Library.Internal.LcuEvaluationModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
|
||||
public class RateRepository : BaseRepository, IRateRepository
|
||||
{
|
||||
private readonly RateCacheConfiguration _rateCacheConfiguration;
|
||||
private readonly ICacheService _cacheService;
|
||||
|
||||
public RateRepository(AppDbContext context,
|
||||
RateCacheConfiguration rateCacheConfiguration,
|
||||
ICacheService cacheService) : base(context)
|
||||
{
|
||||
_rateCacheConfiguration = rateCacheConfiguration;
|
||||
_cacheService = cacheService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> FindAsync()
|
||||
{
|
||||
return await _context.Rates.IncludeAll().ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> FindWithRateEvaluationsAsync()
|
||||
{
|
||||
return await _context.Rates.IncludeAllRatesEvaluations().ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<Rate?> FindByIdAsync(int id)
|
||||
{
|
||||
return await _context.Rates.IncludeAll().FirstOrDefaultAsync(rate => rate.RateId == id);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> FindByClosingRateUploadInfoIdAsync(int id)
|
||||
{
|
||||
return await _context.Rates.Where(rate => rate.ClosingRateUploadInfoId == id)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> FindByDateAsync(DateTime date)
|
||||
{
|
||||
return await _context.Rates.Where(rate => date >= rate.RateStartDate &&
|
||||
(rate.RateEndDate == null || date < rate.RateEndDate))
|
||||
.IncludeAll()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> FindRateHistoryAsync(Rate rate)
|
||||
{
|
||||
return await _context.Rates.Where(x => x.Row == rate.Row
|
||||
&& x.Column == rate.Column
|
||||
&& x.RateSheetId == rate.RateSheetId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> FindRangeByIdAsync(List<int> ids)
|
||||
{
|
||||
return await _context.Rates
|
||||
.Where(rate => ids.Contains(rate.RateId))
|
||||
.IncludeAll()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will get Rates that:
|
||||
/// - Are between the RateStartDate-RateEndDate(if not null).
|
||||
/// - Match the evaluation type
|
||||
/// - Match All the EvaluationIds
|
||||
/// - Contains ALL the evaluationids and the count of RateEvaluation.EvaluationDetailIds match the count of evaluationIds
|
||||
/// </summary>
|
||||
/// <param name="date"></param>
|
||||
/// <param name="evaluationIds"></param>
|
||||
/// <param name="evaluationType"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<Rate>?> FindByDateEvaluationIdsAndEvaluationTypeAsync(DateTime date,
|
||||
List<int> evaluationIds,
|
||||
EvaluationTypes evaluationType)
|
||||
{
|
||||
return await _context.Rates
|
||||
.Where(
|
||||
rate => date >= rate.RateStartDate &&
|
||||
(!rate.RateEndDate.HasValue || date < rate.RateEndDate) &&
|
||||
(rate.RateEvaluations.Any() &&
|
||||
rate.RateEvaluations
|
||||
.Where(rateEvaluation =>
|
||||
(date >= rateEvaluation.EvaluationDetail.StartDate &&
|
||||
(!rateEvaluation.EvaluationDetail.EndDate.HasValue || date < rateEvaluation.EvaluationDetail.EndDate)) &&
|
||||
rateEvaluation.EvaluationDetail.EvaluationType == evaluationType &&
|
||||
rateEvaluation.EvaluationDetail.Active == true)
|
||||
.All(rateEvaluation => evaluationIds.Contains(rateEvaluation.EvaluationDetailId)) &&
|
||||
rate.RateEvaluations
|
||||
.Where(rateEvaluation =>
|
||||
(date >= rateEvaluation.EvaluationDetail.StartDate &&
|
||||
(!rateEvaluation.EvaluationDetail.EndDate.HasValue || date < rateEvaluation.EvaluationDetail.EndDate)) &&
|
||||
rateEvaluation.EvaluationDetail.EvaluationType == evaluationType &&
|
||||
rateEvaluation.EvaluationDetail.Active == true &&
|
||||
evaluationIds.Contains(rateEvaluation.EvaluationDetailId))
|
||||
.Select(rateEvaluation => rateEvaluation.EvaluationDetailId).Count() == evaluationIds.Count))
|
||||
.IncludeAllRatesEvaluations()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<Rate?> AddAsync(Rate rate)
|
||||
{
|
||||
return (await _context.Rates.AddAsync(rate)).Entity;
|
||||
}
|
||||
|
||||
public async Task AddRangeAsync(IEnumerable<Rate> rates)
|
||||
{
|
||||
await _context.Rates.AddRangeAsync(rates);
|
||||
}
|
||||
|
||||
public void UpdateRange(IEnumerable<Rate> rates)
|
||||
{
|
||||
_context.Rates.UpdateRange(rates);
|
||||
}
|
||||
|
||||
public void Remove(Rate rate)
|
||||
{
|
||||
_context.Rates.Remove(rate);
|
||||
}
|
||||
|
||||
public void RemoveRange(IEnumerable<Rate> rates)
|
||||
{
|
||||
_context.Rates.RemoveRange(rates);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>> FindCacheAsync()
|
||||
=> await _cacheService.FindCacheAsync(FindAsync,
|
||||
_rateCacheConfiguration.CacheName,
|
||||
_rateCacheConfiguration.ExpirationMinutes);
|
||||
|
||||
public void ClearCache()
|
||||
=> _cacheService.ClearCache(_rateCacheConfiguration.CacheName);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
using LCU.API.Internal.LoanRateLib.Persistence;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Repositories;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
public class RateSheetCellRepository : CrudRepository<RateSheetCell>, IRateSheetCellRepository
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public RateSheetCellRepository(AppDbContext context) : base(context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
using LCU.API.Internal.LoanRateLib.Configurations;
|
||||
using LCU.API.Internal.LoanRateLib.Extensions.Queryables;
|
||||
using LCU.API.Internal.LoanRateLib.Persistence;
|
||||
using LCU.Library.Internal.LcuCaching.Services;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Repositories;
|
||||
using LCU.Library.Internal.LoanRateModels.Enums;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
public class RateSheetRepository : CrudRepository<RateSheet>, IRateSheetRepository
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
private readonly RateSheetCacheConfiguration _rateSheetCacheConfiguration;
|
||||
private readonly ICacheService _cacheService;
|
||||
|
||||
public RateSheetRepository(AppDbContext context,
|
||||
RateSheetCacheConfiguration rateSheetCacheConfiguration,
|
||||
ICacheService cacheService) : base(context)
|
||||
{
|
||||
_context = context;
|
||||
_rateSheetCacheConfiguration = rateSheetCacheConfiguration;
|
||||
_cacheService = cacheService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateSheet>> FindIncludeAllAsync()
|
||||
{
|
||||
return await _context.RateSheets.IncludeAll().ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateSheet>> FindIncludeRateSheetCellsAsync()
|
||||
{
|
||||
return await _context.RateSheets.Include(rateSheet => rateSheet.RateSheetCells).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> FindRatesByDateAndRateType(DateTime date, RateTypes rateType)
|
||||
{
|
||||
return (await FindCacheAsync()).FirstOrDefault(rateSheet => rateSheet.RateType == rateType)?
|
||||
.Rates.Where(rate =>
|
||||
date >= rate.RateStartDate
|
||||
&& (rate.RateEndDate == null || date < rate.RateEndDate));
|
||||
}
|
||||
|
||||
public async Task<RateSheet?> FindByDateAndRateType(DateTime date, RateTypes rateType)
|
||||
{
|
||||
return await _context.RateSheets.Include(rateSheet => rateSheet.Rates)
|
||||
.Include(rateSheet => rateSheet.RateSheetCells)
|
||||
.Where(rateSheet => rateSheet.RateType == rateType)
|
||||
.Select(rateSheet =>
|
||||
new RateSheet
|
||||
{
|
||||
RateSheetId = rateSheet.RateSheetId,
|
||||
RateType = rateSheet.RateType,
|
||||
RateSheetCells = rateSheet.RateSheetCells,
|
||||
Rates = _context.Rates.Where(rate => rate.RateSheetId == rateSheet.RateSheetId
|
||||
&& date >= rate.RateStartDate
|
||||
&& (rate.RateEndDate == null || date < rate.RateEndDate)).ToList(),
|
||||
CreatedBy = rateSheet.CreatedBy,
|
||||
TimeCreated = rateSheet.TimeCreated
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Rate>?> FindRatesByRateType(RateTypes rateType)
|
||||
{
|
||||
return (await FindCacheAsync()).FirstOrDefault(rateSheet => rateSheet.RateType == rateType)?.Rates;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<int>?> FindRateSheetIdsByRateType(RateTypes rateType)
|
||||
{
|
||||
return await _context.RateSheets.Where(rateSheet => rateSheet.RateType == rateType)
|
||||
.Select(rateSheet => rateSheet.RateSheetId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RateSheet>> FindCacheAsync()
|
||||
{
|
||||
return await _cacheService.FindCacheAsync(FindIncludeAllAsync,
|
||||
_rateSheetCacheConfiguration.CacheName,
|
||||
_rateSheetCacheConfiguration.ExpirationMinutes);
|
||||
}
|
||||
|
||||
public void ClearCache() => _cacheService.ClearCache(_rateSheetCacheConfiguration.CacheName);
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
using LCU.API.Internal.LoanRateLib.Extensions.Queryables;
|
||||
using LCU.API.Internal.LoanRateLib.Persistence;
|
||||
using LCU.Library.Internal.LcuClassPatterns.Crud.Repositories;
|
||||
using LCU.Library.Internal.LoanRateModels.Responses;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LCU.API.Internal.LoanRateLib.Repositories;
|
||||
public class RateUploadInfoRepository : CrudRepository<RateUploadInfo>, IRateUploadInfoRepository
|
||||
{
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
public RateUploadInfoRepository(AppDbContext context) : base(context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfo?> FindLatestAsync()
|
||||
{
|
||||
return await _context.RateUploadInfos.OrderByDescending(r => r.EffectiveDate)
|
||||
.ThenByDescending(r => r.Version)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfo?> FindByVersionAsync(int version, DateTime effectiveDate)
|
||||
{
|
||||
return await _context.RateUploadInfos.Where(rateUploadInfo => rateUploadInfo.EffectiveDate.Date == effectiveDate.Date
|
||||
&& rateUploadInfo.Version == version)
|
||||
.IncludeAllButClosedRates()
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfo?> FindPreviousVersion(RateUploadInfo rateUploadInfo)
|
||||
{
|
||||
return await _context.RateUploadInfos.Where(r => r.EffectiveDate.Date <= rateUploadInfo.EffectiveDate.Date
|
||||
&& (r.EffectiveDate.Date != rateUploadInfo.EffectiveDate.Date || r.Version < rateUploadInfo.Version )
|
||||
&& r.RateUploadInfoId != rateUploadInfo.RateUploadInfoId)
|
||||
.OrderByDescending(r => r.EffectiveDate)
|
||||
.ThenByDescending(r => r.Version)
|
||||
.IncludeAllButClosedRates()
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfo?> FindLatestVersionOnDate(DateTime effectiveDate)
|
||||
{
|
||||
return await _context.RateUploadInfos.Where(r => r.EffectiveDate.Date == effectiveDate.Date)
|
||||
.OrderByDescending(r => r.Version)
|
||||
.IncludeAllButClosedRates()
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public override async Task<IEnumerable<RateUploadInfo>> FindAsync()
|
||||
{
|
||||
return await _context.RateUploadInfos.IncludeAllButClosedRates().ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<RateUploadInfoFilterResult> FindFilteredRateUploadInfosAsync(RateUploadInfoFilter rateUploadInfoFilter)
|
||||
{
|
||||
var results = new RateUploadInfoFilterResult();
|
||||
var skip = (rateUploadInfoFilter.Page - 1) * rateUploadInfoFilter.Limit;
|
||||
|
||||
results.Total = await _context.RateUploadInfos
|
||||
.IncludeFilters(rateUploadInfoFilter)
|
||||
.CountAsync();
|
||||
|
||||
results.Items = await _context.RateUploadInfos
|
||||
.IncludeFilters(rateUploadInfoFilter)
|
||||
.OrderBySortableFields(rateUploadInfoFilter)
|
||||
.Skip(skip)
|
||||
.Take(rateUploadInfoFilter.Limit)
|
||||
.ToArrayAsync();
|
||||
|
||||
results.TotalCount = await _context.RateUploadInfos.CountAsync();
|
||||
results.LatestRateUploadInfo = await FindLatestAsync();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public override async Task<RateUploadInfo> FindByIdAsync(int id)
|
||||
{
|
||||
return await _context.RateUploadInfos.Where(rateUploadInfo => rateUploadInfo.RateUploadInfoId == id)
|
||||
.IncludeAllButClosedRates()
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public override async Task<IEnumerable<RateUploadInfo>> FindRangeByIdAsync(List<int> ids)
|
||||
{
|
||||
return await _context.RateUploadInfos.Where(rateUploadInfo => ids.Contains(rateUploadInfo.RateUploadInfoId))
|
||||
.IncludeAllButClosedRates()
|
||||
.ToListAsync();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user