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