132 changed files with 6799 additions and 0 deletions
-
98DealerSelectionAPI.sln
-
14Source/DealerSelection.Api.Models/AuthModel.cs
-
14Source/DealerSelection.Api.Models/AuthValidateModel.cs
-
48Source/DealerSelection.Api.Models/CustomerDealerInfoRequest.cs
-
28Source/DealerSelection.Api.Models/DealerSelection.Api.Models.csproj
-
10Source/DealerSelection.Api.Models/DealerSelectionJobStatus.cs
-
21Source/DealerSelection.Api.Models/MulesoftResponse.cs
-
8Source/DealerSelection.Api.Models/MulesoftToken.cs
-
15Source/DealerSelection.Api.Models/Procedure.cs
-
31Source/DealerSelection.Api.Models/Response.cs
-
10Source/DealerSelection.Api.Models/TokenValidProperty.cs
-
9Source/DealerSelection.Api.Models/UnexpectedDataException.cs
-
70Source/DealerSelection.Api.Models/WebEngageEvent.cs
-
190Source/DealerSelection.Api/AssignDealerApi.cs
-
151Source/DealerSelection.Api/CommonUtil/AESEncryption.cs
-
132Source/DealerSelection.Api/CommonUtil/CustomConfig.cs
-
28Source/DealerSelection.Api/CommonUtil/GenerateRandomString.cs
-
86Source/DealerSelection.Api/CommonUtil/MuleSoftTokenGenerate.cs
-
42Source/DealerSelection.Api/DealerSelection.Api.csproj
-
143Source/DealerSelection.Api/InfoBipSmsServiceApi.cs
-
112Source/DealerSelection.Api/JwtTokenApi.cs
-
722Source/DealerSelection.Api/MulesoftApi.cs
-
68Source/DealerSelection.Api/MulesoftTokenApi.cs
-
77Source/DealerSelection.Api/YellowAIApi.cs
-
9Source/DealerSelection.Common/CommonBaseClass/ExceptionBase.cs
-
92Source/DealerSelection.Common/CommonBaseClass/ExceptionFilterBase.cs
-
235Source/DealerSelection.Common/CommonBaseClass/StartupBase.cs
-
6Source/DealerSelection.Common/CommonBaseClass/WebApiConfigurationCfgBase.cs
-
102Source/DealerSelection.Common/Configuration/ConfigurationHelper.cs
-
36Source/DealerSelection.Common/Data/ConnectionHelper.cs
-
25Source/DealerSelection.Common/Data/Dapper/RepositoryBaseDapperAsync.cs
-
25Source/DealerSelection.Common/Data/Dapper/RepositoryBaseDapperSync.cs
-
30Source/DealerSelection.Common/Data/Dapper/TypeMapHelper.cs
-
35Source/DealerSelection.Common/Data/RepositoryBaseDIAsync.cs
-
35Source/DealerSelection.Common/Data/RepositoryBaseDISync.cs
-
11Source/DealerSelection.Common/Data/RepositoryDIBase.cs
-
56Source/DealerSelection.Common/DealerSelection.Common.csproj
-
24Source/DealerSelection.Common/Entity/FieldMapAttribute.cs
-
8Source/DealerSelection.Common/Exceptions/AuthorizationException.cs
-
8Source/DealerSelection.Common/Exceptions/DataNotFoundException.cs
-
15Source/DealerSelection.Common/Exceptions/DbConnectionException.cs
-
8Source/DealerSelection.Common/Exceptions/DuplicateException.cs
-
8Source/DealerSelection.Common/Exceptions/NullValueException.cs
-
8Source/DealerSelection.Common/Exceptions/PartialSuccessException.cs
-
8Source/DealerSelection.Common/Exceptions/ValidationException.cs
-
8Source/DealerSelection.Common/Helpers/SwaggerCfg.cs
-
38Source/DealerSelection.Common/Helpers/SwashbuckleSchemaHelper.cs
-
21Source/DealerSelection.Common/HttpClient/MyHttpClientHandler.cs
-
9Source/DealerSelection.Common/Interfaces/Data/IRepositoryDIAsync.cs
-
9Source/DealerSelection.Common/Interfaces/Data/IRepositoryDISync.cs
-
8Source/DealerSelection.Common/Interfaces/HttpClient/IHttpClientHandler.cs
-
24Source/DealerSelection.Common/Logging/ApiInfo.cs
-
82Source/DealerSelection.Common/Logging/AzureLogHelper.cs
-
28Source/DealerSelection.Common/Logging/HttpHeaderHelper.cs
-
127Source/DealerSelection.Common/Logging/LoggingMiddleware.cs
-
42Source/DealerSelection.Common/Logging/RequestInfo.cs
-
37Source/DealerSelection.Common/Logging/ResponseInfo.cs
-
34Source/DealerSelection.Common/Middleware/SwaggerRootRoutingMiddleware.cs
-
31Source/DealerSelection.Common/Profiler/PerformanceProfiler.cs
-
19Source/DealerSelection.Common/Profiler/Profiler.cs
-
35Source/DealerSelection.DependencyInjection/ApiRegistry.cs
-
29Source/DealerSelection.DependencyInjection/DealerSelection.DependencyInjection.csproj
-
11Source/DealerSelection.DependencyInjection/DependencyInjectionBootStrapper.cs
-
37Source/DealerSelection.DependencyInjection/InfrastructureRegistry.cs
-
7Source/DealerSelection.Infrastructure/AssignDealer/IAssignDealerRepository.cs
-
17Source/DealerSelection.Infrastructure/AssignDealer/Repository.cs
-
26Source/DealerSelection.Infrastructure/CustomerDetail/CustomerInfoDto.cs
-
13Source/DealerSelection.Infrastructure/CustomerDetail/IRepository.cs
-
116Source/DealerSelection.Infrastructure/CustomerDetail/Repository.cs
-
37Source/DealerSelection.Infrastructure/DealerSelection.Api.Infrastructure.csproj
-
6Source/DealerSelection.Infrastructure/InfoBip/IRepository.cs
-
45Source/DealerSelection.Infrastructure/InfoBip/Repository.cs
-
14Source/DealerSelection.Infrastructure/Jwt/AuthValidateModelDto.cs
-
9Source/DealerSelection.Infrastructure/Jwt/IJwtRepository.cs
-
23Source/DealerSelection.Infrastructure/Jwt/JwtRepository.cs
-
26Source/DealerSelection.Infrastructure/Mulesoft/DealerDetailDto.cs
-
10Source/DealerSelection.Infrastructure/Mulesoft/IRepository.cs
-
46Source/DealerSelection.Infrastructure/Mulesoft/MulesoftCustomerInfoDto.cs
-
134Source/DealerSelection.Infrastructure/Mulesoft/Repository.cs
-
27Source/DealerSelection.Interface/DealerSelection.Api.Interface.csproj
-
7Source/DealerSelection.Interface/IAssignDealerApi.cs
-
9Source/DealerSelection.Interface/IInfoBipSmsServiceApi.cs
-
9Source/DealerSelection.Interface/IJwtTokenApi.cs
-
20Source/DealerSelection.Interface/IMulesoftApi.cs
-
7Source/DealerSelection.Interface/IMulesoftTokenApi.cs
-
10Source/DealerSelection.Interface/IYellowAIApi.cs
-
14Source/DealerSelection.WebApi.Models/BikeResponse.cs
-
14Source/DealerSelection.WebApi.Models/BookingConfirmationRequest.cs
-
9Source/DealerSelection.WebApi.Models/CityResponse.cs
-
26Source/DealerSelection.WebApi.Models/CustomerInfoMappingResponse.cs
-
17Source/DealerSelection.WebApi.Models/CustomerInfoRequest.cs
-
20Source/DealerSelection.WebApi.Models/DealerSelection.WebApi.Models.csproj
-
34Source/DealerSelection.WebApi.Models/MulesoftResponse.cs
-
7Source/DealerSelection.WebApi.Models/PaymentLinkResponse.cs
-
16Source/DealerSelection.WebApi.Models/RegisterInterestSuccessfulResponse.cs
-
12Source/DealerSelection.WebApi.Models/Response.cs
-
24Source/DealerSelection.WebApi.Models/ReviewPayCustomerInfoResponse.cs
-
8Source/DealerSelection.WebApi.Models/StateResponse.cs
-
12Source/DealerSelection.WebApi/.config/dotnet-tools.json
-
36Source/DealerSelection.WebApi/App_Start/Mapper.cs
@ -0,0 +1,98 @@ |
|||||
|
|
||||
|
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
|
# Visual Studio Version 17 |
||||
|
VisualStudioVersion = 17.6.33829.357 |
||||
|
MinimumVisualStudioVersion = 10.0.40219.1 |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DealerSelection.WebApi", "Source\DealerSelection.WebApi\DealerSelection.WebApi.csproj", "{C65D4378-AC83-4B22-A896-E2B47B7CB841}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebApi", "WebApi", "{73409D39-9D85-4EE7-B870-129129E11448}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Repo", "Repo", "{2E11D0F3-B91E-49E3-8040-EB3195B75738}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DealerSelection.Api", "Source\DealerSelection.Api\DealerSelection.Api.csproj", "{1368CA19-D9A9-4EB9-8553-0D44DAB22FA2}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DealerSelection.Api.Infrastructure", "Source\DealerSelection.Infrastructure\DealerSelection.Api.Infrastructure.csproj", "{BC5A9A1D-AE12-4E81-B80E-588A14D0FD2E}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DealerSelection.Api.Interface", "Source\DealerSelection.Interface\DealerSelection.Api.Interface.csproj", "{0F9BC8AF-A572-4423-A1BD-C0DF4694E613}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DealerSelection.Api.Models", "Source\DealerSelection.Api.Models\DealerSelection.Api.Models.csproj", "{027412DC-BDA1-4CC4-B3CE-B0B555B3A0AB}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DealerSelection.WebApi.Models", "Source\DealerSelection.WebApi.Models\DealerSelection.WebApi.Models.csproj", "{29FCE055-C131-474C-B398-0855E803905E}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DealerSelection.DependencyInjection", "Source\DealerSelection.DependencyInjection\DealerSelection.DependencyInjection.csproj", "{5FC735F8-39BF-41C5-8896-9EA2ED173CDE}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{AA19DD64-E46D-476E-9999-2C6F20007DEE}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DealerSelection.Common", "Source\DealerSelection.Common\DealerSelection.Common.csproj", "{CA12113A-A11B-4EB0-AA56-E80062962D18}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{42B510F1-8DE3-4944-9395-4945B565C614}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DealerSelection.WebApi.IntegrationTests", "Source\Tests\DealerSelection.WebApi.IntegrationTests\DealerSelection.WebApi.IntegrationTests.csproj", "{EFD6DA2D-906C-44E5-A95F-60B31353DEB7}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebJobService", "Source\WebJobService\WebJobService.csproj", "{583C09D6-5582-483E-A54F-89EB414F617C}" |
||||
|
EndProject |
||||
|
Global |
||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
|
Debug|Any CPU = Debug|Any CPU |
||||
|
Release|Any CPU = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
|
{C65D4378-AC83-4B22-A896-E2B47B7CB841}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{C65D4378-AC83-4B22-A896-E2B47B7CB841}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{C65D4378-AC83-4B22-A896-E2B47B7CB841}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{C65D4378-AC83-4B22-A896-E2B47B7CB841}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{1368CA19-D9A9-4EB9-8553-0D44DAB22FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{1368CA19-D9A9-4EB9-8553-0D44DAB22FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{1368CA19-D9A9-4EB9-8553-0D44DAB22FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{1368CA19-D9A9-4EB9-8553-0D44DAB22FA2}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{BC5A9A1D-AE12-4E81-B80E-588A14D0FD2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{BC5A9A1D-AE12-4E81-B80E-588A14D0FD2E}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{BC5A9A1D-AE12-4E81-B80E-588A14D0FD2E}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{BC5A9A1D-AE12-4E81-B80E-588A14D0FD2E}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{0F9BC8AF-A572-4423-A1BD-C0DF4694E613}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{0F9BC8AF-A572-4423-A1BD-C0DF4694E613}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{0F9BC8AF-A572-4423-A1BD-C0DF4694E613}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{0F9BC8AF-A572-4423-A1BD-C0DF4694E613}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{027412DC-BDA1-4CC4-B3CE-B0B555B3A0AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{027412DC-BDA1-4CC4-B3CE-B0B555B3A0AB}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{027412DC-BDA1-4CC4-B3CE-B0B555B3A0AB}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{027412DC-BDA1-4CC4-B3CE-B0B555B3A0AB}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{29FCE055-C131-474C-B398-0855E803905E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{29FCE055-C131-474C-B398-0855E803905E}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{29FCE055-C131-474C-B398-0855E803905E}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{29FCE055-C131-474C-B398-0855E803905E}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{5FC735F8-39BF-41C5-8896-9EA2ED173CDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{5FC735F8-39BF-41C5-8896-9EA2ED173CDE}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{5FC735F8-39BF-41C5-8896-9EA2ED173CDE}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{5FC735F8-39BF-41C5-8896-9EA2ED173CDE}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{CA12113A-A11B-4EB0-AA56-E80062962D18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{CA12113A-A11B-4EB0-AA56-E80062962D18}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{CA12113A-A11B-4EB0-AA56-E80062962D18}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{CA12113A-A11B-4EB0-AA56-E80062962D18}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{EFD6DA2D-906C-44E5-A95F-60B31353DEB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{EFD6DA2D-906C-44E5-A95F-60B31353DEB7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{EFD6DA2D-906C-44E5-A95F-60B31353DEB7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{EFD6DA2D-906C-44E5-A95F-60B31353DEB7}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{583C09D6-5582-483E-A54F-89EB414F617C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{583C09D6-5582-483E-A54F-89EB414F617C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{583C09D6-5582-483E-A54F-89EB414F617C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{583C09D6-5582-483E-A54F-89EB414F617C}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(SolutionProperties) = preSolution |
||||
|
HideSolutionNode = FALSE |
||||
|
EndGlobalSection |
||||
|
GlobalSection(NestedProjects) = preSolution |
||||
|
{C65D4378-AC83-4B22-A896-E2B47B7CB841} = {73409D39-9D85-4EE7-B870-129129E11448} |
||||
|
{1368CA19-D9A9-4EB9-8553-0D44DAB22FA2} = {2E11D0F3-B91E-49E3-8040-EB3195B75738} |
||||
|
{BC5A9A1D-AE12-4E81-B80E-588A14D0FD2E} = {2E11D0F3-B91E-49E3-8040-EB3195B75738} |
||||
|
{0F9BC8AF-A572-4423-A1BD-C0DF4694E613} = {2E11D0F3-B91E-49E3-8040-EB3195B75738} |
||||
|
{027412DC-BDA1-4CC4-B3CE-B0B555B3A0AB} = {2E11D0F3-B91E-49E3-8040-EB3195B75738} |
||||
|
{29FCE055-C131-474C-B398-0855E803905E} = {73409D39-9D85-4EE7-B870-129129E11448} |
||||
|
{5FC735F8-39BF-41C5-8896-9EA2ED173CDE} = {73409D39-9D85-4EE7-B870-129129E11448} |
||||
|
{CA12113A-A11B-4EB0-AA56-E80062962D18} = {AA19DD64-E46D-476E-9999-2C6F20007DEE} |
||||
|
{EFD6DA2D-906C-44E5-A95F-60B31353DEB7} = {42B510F1-8DE3-4944-9395-4945B565C614} |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ExtensibilityGlobals) = postSolution |
||||
|
SolutionGuid = {114CDF7F-ED0A-416A-8B06-0056936D24EE} |
||||
|
EndGlobalSection |
||||
|
EndGlobal |
@ -0,0 +1,14 @@ |
|||||
|
namespace DealerSelection.Api.Models |
||||
|
{ |
||||
|
public class AuthModel |
||||
|
{ |
||||
|
public string Role { get; set; } |
||||
|
|
||||
|
public string ClientId { get; set; } |
||||
|
|
||||
|
public string SecretId { get; set; } |
||||
|
|
||||
|
public string KeyName { get; set; } |
||||
|
public int BuId { get; set; } |
||||
|
} |
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
namespace DealerSelection.Api.Models |
||||
|
{ |
||||
|
public class AuthValidateModel |
||||
|
{ |
||||
|
public string ClientId { get; set; } |
||||
|
public string SecretId { get; set; } |
||||
|
public int BuId { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class TokenModel |
||||
|
{ |
||||
|
public string Token { get; set; } |
||||
|
} |
||||
|
} |
@ -0,0 +1,48 @@ |
|||||
|
namespace DealerSelection.Api.Models; |
||||
|
|
||||
|
public class CustomerDealerInfoRequest |
||||
|
{ |
||||
|
public CustomerDealerInfoRequest(int buId, int recordId, int mobileNumber, string modelCode, string modelName, |
||||
|
string modelVariant, string dealerName, string dealerCode, string pinCode, string latitude, string longitude, |
||||
|
DealerSelectionJobStatus dealerSelectionJobStatus) |
||||
|
{ |
||||
|
BuId = buId; |
||||
|
RecordId = recordId; |
||||
|
MobileNumber = mobileNumber; |
||||
|
ModelCode = modelCode; |
||||
|
ModelName = modelName; |
||||
|
ModelVariant = modelVariant; |
||||
|
DealerName = dealerName; |
||||
|
DealerCode = dealerCode; |
||||
|
PinCode = pinCode; |
||||
|
Latitude = latitude; |
||||
|
Longitude = longitude; |
||||
|
DealerSelectionJobStatus = dealerSelectionJobStatus; |
||||
|
} |
||||
|
|
||||
|
public int BuId { get; } |
||||
|
public int RecordId { get; } |
||||
|
public int MobileNumber { get; } |
||||
|
public string ModelCode { get; } |
||||
|
public string ModelName { get; } |
||||
|
public string ModelVariant { get; } |
||||
|
public string DealerName { get; } |
||||
|
public string DealerCode { get; } |
||||
|
public string PinCode { get; } |
||||
|
public string Latitude { get; } |
||||
|
public string Longitude { get; } |
||||
|
public DealerSelectionJobStatus DealerSelectionJobStatus { get; } |
||||
|
|
||||
|
public override string? ToString() |
||||
|
{ |
||||
|
return base.ToString(); |
||||
|
} |
||||
|
|
||||
|
public string RequestDetail() |
||||
|
{ |
||||
|
return $"BuId: {BuId}, RecordId: {RecordId}, MobileNumber: {MobileNumber}, ModelCode: {ModelCode}, " + |
||||
|
$"ModelName:{ModelName}, ModelVariant:{ModelVariant}, DealerName: {DealerName}, DealerCode: {DealerCode}, " + |
||||
|
$"PinCode: {PinCode}, Latitude: {Latitude}, Longitude: {Longitude}, DealerSelectionJobStatus: {DealerSelectionJobStatus}"; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
||||
|
<NoWarn>1701;1702;8618</NoWarn> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> |
||||
|
<NoWarn>1701;1702;8618</NoWarn> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="BouncyCastle.NetCore" Version="1.9.0" /> |
||||
|
<PackageReference Include="iTextSharp" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="itextsharp.xmlworker" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> |
||||
|
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7"> |
||||
|
<PrivateAssets>all</PrivateAssets> |
||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
||||
|
</PackageReference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
@ -0,0 +1,10 @@ |
|||||
|
namespace DealerSelection.Api.Models; |
||||
|
|
||||
|
public enum DealerSelectionJobStatus |
||||
|
{ |
||||
|
OldData = -1, |
||||
|
ReadyForJob = 0, |
||||
|
Picked = 1, |
||||
|
SentToBot = 2, |
||||
|
Complete = 3, |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Api.Models; |
||||
|
public class MulesoftResponse |
||||
|
{ |
||||
|
public MulesoftResponse(int buId, int bookingId, bool isRequestSuccessfull, string result, string message, string errorCode) |
||||
|
{ |
||||
|
BuId = buId; |
||||
|
BookingId = bookingId; |
||||
|
IsRequestSuccessfull = isRequestSuccessfull; |
||||
|
Result = result; |
||||
|
Message = message; |
||||
|
ErrorField = errorCode; |
||||
|
} |
||||
|
public int BuId { get; set; } |
||||
|
public int BookingId { get; set; } |
||||
|
public bool IsRequestSuccessfull { get; } |
||||
|
public string Result { get; } |
||||
|
public string Message { get; } |
||||
|
public string ErrorField { get; } |
||||
|
|
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Api.Models; |
||||
|
|
||||
|
public class MulesoftToken |
||||
|
{ |
||||
|
public string Value { get; set; } |
||||
|
public int ExpiresIn { get; set; } |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure; |
||||
|
|
||||
|
public class Procedure |
||||
|
{ |
||||
|
public const string UpdateDealerDetails = "usp_update_dealer_details"; |
||||
|
public const string GetCustomerBookingInfo = "usp_get_customer_booking_info"; |
||||
|
public const string InsertUpdateDealerDetail = "usp_Insert_Update_Dealer_Details"; |
||||
|
public const string InsertLSQDetail = "usp_insert_lsq_data"; |
||||
|
public const string GetDataForLsqPush = "usp_get_data_for_lsq_push"; |
||||
|
public const string GetCustomerInfoOnBookingId = "usp_get_customer_Info_on_BookingId"; |
||||
|
public const string GetCustomerDataForJob = "usp_get_CustomerDataForJob"; //TO BE ADDED IN DB
|
||||
|
public const string IsDuplicateMobileNumber = "usp_isDuplicateMobileNumber"; //TO BE ADDED IN DB
|
||||
|
public const string UpdateDealerSelectionJobStatus = "usp_update_DealerSelectionJobStatus"; //TO BE ADDED IN DB
|
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Api.Models; |
||||
|
public class Response |
||||
|
{ |
||||
|
public Response(int buId,int recordId, bool isRequestSuccessfull, string result, string message, string errorCode) |
||||
|
{ |
||||
|
BuId = buId; |
||||
|
RecordId = recordId; |
||||
|
IsRequestSuccessfull = isRequestSuccessfull; |
||||
|
Result = result; |
||||
|
Message = message; |
||||
|
ErrorCode = errorCode; |
||||
|
} |
||||
|
public bool IsRequestSuccessfull { get; } |
||||
|
public string Result { get; } |
||||
|
public string Message { get; } |
||||
|
public string ErrorCode { get; } |
||||
|
public int RecordId { get; } |
||||
|
public int BuId { get; } |
||||
|
|
||||
|
} |
||||
|
public enum ErrorCode |
||||
|
{ |
||||
|
successErrorCode = 01, |
||||
|
successWithLookupErrorCode = 02, |
||||
|
awaitedErrorCode = 03, |
||||
|
noRecordFound = 04 |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
@ -0,0 +1,10 @@ |
|||||
|
namespace DealerSelection.Api.Models |
||||
|
{ |
||||
|
public class TokenValidProperty |
||||
|
{ |
||||
|
public bool isValid { get; set; } |
||||
|
|
||||
|
public double Ttl { get; set; } |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
namespace DealerSelection.Api.Models |
||||
|
{ |
||||
|
public class UnexpectedDataException : Exception |
||||
|
{ |
||||
|
public UnexpectedDataException(string message, Exception innerException) : base(message, innerException) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,70 @@ |
|||||
|
using Newtonsoft.Json; |
||||
|
|
||||
|
namespace DealerSelection.Api.Models; |
||||
|
|
||||
|
public class WebEngageEventData |
||||
|
{ |
||||
|
public WebEngageEventData( string phoneNumber) |
||||
|
{ |
||||
|
|
||||
|
PhoneNumber = phoneNumber; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
[JsonProperty("Booking ID")] |
||||
|
public string BookingID { get; } |
||||
|
|
||||
|
[JsonProperty("Booking Status")] |
||||
|
public string BookingStatus { get; } |
||||
|
|
||||
|
[JsonProperty("Booking Amount")] |
||||
|
public string BookingAmount { get; } |
||||
|
|
||||
|
[JsonProperty("Full Name")] |
||||
|
public string FullName { get; } |
||||
|
|
||||
|
[JsonProperty("Phone Number")] |
||||
|
public string PhoneNumber { get; } |
||||
|
|
||||
|
[JsonProperty("Motorcycle Name")] |
||||
|
public string MotorcycleName { get; } |
||||
|
|
||||
|
[JsonProperty("Motorcycle Code")] |
||||
|
public string MotorcycleCode { get; } |
||||
|
|
||||
|
[JsonProperty("Location")] |
||||
|
public string Location { get; } |
||||
|
|
||||
|
[JsonProperty("Dealer Name")] |
||||
|
public string DealerName { get; } |
||||
|
|
||||
|
[JsonProperty("Dealer Phone Number")] |
||||
|
public string DealerPhoneNumber { get; } |
||||
|
|
||||
|
[JsonProperty("Booking Receipt Link")] |
||||
|
public string BookingReceiptLink { get; } |
||||
|
|
||||
|
[JsonProperty("Landing page URL")] |
||||
|
public string LandingPageURL { get; } |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
public class WebEngageEvent |
||||
|
{ |
||||
|
public WebEngageEvent(string userId, string eventName, WebEngageEventData data) |
||||
|
{ |
||||
|
UserId = userId; |
||||
|
EventName = eventName; |
||||
|
EventData = data; |
||||
|
} |
||||
|
[JsonProperty("userId")] |
||||
|
public string UserId { get; } |
||||
|
|
||||
|
[JsonProperty("eventName")] |
||||
|
public string EventName { get; } |
||||
|
|
||||
|
[JsonProperty("eventData")] |
||||
|
public WebEngageEventData EventData { get; } |
||||
|
} |
@ -0,0 +1,190 @@ |
|||||
|
using DealerSelection.Api.CommonUtil; |
||||
|
using DealerSelection.Api.Infrastructure.AssignDealer; |
||||
|
using DealerSelection.Api.Infrastructure.CustomerDetail; |
||||
|
using DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
using DealerSelection.Api.Interface; |
||||
|
using DealerSelection.Api.Models; |
||||
|
using DealerSelection.Common.Configuration; |
||||
|
using DealerSelection.Common.Interfaces.HttpClient; |
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Newtonsoft.Json; |
||||
|
using Newtonsoft.Json.Linq; |
||||
|
using Org.BouncyCastle.Asn1.Tsp; |
||||
|
using RestSharp; |
||||
|
|
||||
|
public class AssignDealerApi : IAssignDealerApi |
||||
|
{ |
||||
|
|
||||
|
#region MuleSoft
|
||||
|
|
||||
|
public static string baseApiUrl = ConfigurationHelper.GetSetting<string>("muleSoftAPIDomain", true); |
||||
|
public static string dealerDetailApiUrl = ConfigurationHelper.GetSetting<string>("muleSoftDealerDetail", true); |
||||
|
public static string bookingApiUrl = ConfigurationHelper.GetSetting<string>("muleSoftBookingAPILeadSquareDomain", true); |
||||
|
public static string masterSchemaId = ConfigurationHelper.GetSetting<string>("masterSchemaId", true); |
||||
|
public static string masterDealerDetailSchemaId = ConfigurationHelper.GetSetting<string>("masterDealerDetailSchemaId", true); |
||||
|
public static string muleSoftStateWisePrice = ConfigurationHelper.GetSetting<string>("muleSoftStateWisePrice", true); |
||||
|
public static string muleSoftBrandWiseModel = ConfigurationHelper.GetSetting<string>("muleSoftBrandWiseModel", true); |
||||
|
public static string muleSoftPricemasterSchemaId = ConfigurationHelper.GetSetting<string>("muleSoftStateWisePricemasterSchemaId", true); |
||||
|
public static string muleSoftModelmasterSchemaId = ConfigurationHelper.GetSetting<string>("muleSoftBrandWiseModelmasterSchemaId", true); |
||||
|
|
||||
|
public static string muleSoftStateMasterSchemaId = ConfigurationHelper.GetSetting<string>("muleSoftStateMasterSchemaId", true); |
||||
|
public static string muleSoftStateMasterSchemaApi = ConfigurationHelper.GetSetting<string>("muleSoftStateMasterSchemaApi", true); |
||||
|
public static string muleSoftCityMasterSchemaId = ConfigurationHelper.GetSetting<string>("muleSoftCityMasterSchemaId", true); |
||||
|
public static string muleSoftCityMasterSchemaApi = ConfigurationHelper.GetSetting<string>("muleSoftCityMasterSchemaApi", true); |
||||
|
public static string muleSoftModelMasterSchemaItemId = ConfigurationHelper.GetSetting<string>("muleSoftModelMasterSchemaItemId", true); |
||||
|
public static string muleSoftModelMasterSchemaItemApi = ConfigurationHelper.GetSetting<string>("muleSoftModelMasterSchemaItemApi", true); |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
|
||||
|
#region Caching
|
||||
|
|
||||
|
public static string CacheGetDealersDetail = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetDealersDetail", true); |
||||
|
private int _cacheGetDealersDetail = !string.IsNullOrEmpty(CacheGetDealersDetail) ? int.Parse(CacheGetDealersDetail) : 10; |
||||
|
|
||||
|
public static string CacheGetPriceOnState = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetPriceOnState", true); |
||||
|
private int _cacheGetPriceOnState = !string.IsNullOrEmpty(CacheGetPriceOnState) ? int.Parse(CacheGetPriceOnState) : 10; |
||||
|
|
||||
|
public static string CacheGetModelOnBrand = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetModelOnBrand", true); |
||||
|
private int _cacheGetModelOnBrand = !string.IsNullOrEmpty(CacheGetModelOnBrand) ? int.Parse(CacheGetModelOnBrand) : 10; |
||||
|
|
||||
|
public static string CacheGetActiveState = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetActiveState", true); |
||||
|
private int _cacheGetActiveState = !string.IsNullOrEmpty(CacheGetActiveState) ? int.Parse(CacheGetActiveState) : 10; |
||||
|
|
||||
|
public static string CacheGetActiveCity = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetActiveCity", true); |
||||
|
private int _cacheGetActiveCity = !string.IsNullOrEmpty(CacheGetActiveCity) ? int.Parse(CacheGetActiveCity) : 10; |
||||
|
|
||||
|
public static string CacheModelDetails = ConfigurationHelper.GetSetting<string>("MuleSoftCacheModelDetails", true); |
||||
|
private int _cacheModelDetails = !string.IsNullOrEmpty(CacheModelDetails) ? int.Parse(CacheModelDetails) : 10; |
||||
|
|
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
private readonly ILogger _logger; |
||||
|
private IAssignDealerRepository Repository { get; } |
||||
|
private DealerSelection.Api.Infrastructure.CustomerDetail.IRepository CustomerDetailRepository { get; } |
||||
|
private IMulesoftApi MulesoftApi { get; } |
||||
|
private IHttpClientHandler ClientHandler { get; } |
||||
|
private readonly IMemoryCache _memoryCache; |
||||
|
|
||||
|
public AssignDealerApi(IAssignDealerRepository repository, IMulesoftApi mulesoftApi, DealerSelection.Api.Infrastructure.CustomerDetail.IRepository customerRepo, |
||||
|
IHttpClientHandler clientHandler, IMemoryCache memoryCache, ILogger<MulesoftApi> logger) |
||||
|
{ |
||||
|
Repository = repository; |
||||
|
MulesoftApi = mulesoftApi; |
||||
|
CustomerDetailRepository = customerRepo; |
||||
|
ClientHandler = clientHandler; |
||||
|
_memoryCache = memoryCache; |
||||
|
_logger = logger; |
||||
|
} |
||||
|
public async Task GetCustomerDataForJob(int buId, int recordId) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
|
||||
|
MulesoftCustomerInfoDto customerInfo= await CustomerDetailRepository.GetCustomerData( buId, recordId); |
||||
|
await AssignDealers(customerInfo); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetDealers:- " + ex.StackTrace.ToString()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async Task AssignDealers(MulesoftCustomerInfoDto customerInfo) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
MulesoftResponse dealerResponse = await MulesoftApi.GetDealers(customerInfo.BuId, customerInfo.BuName, customerInfo.CustomerLat, customerInfo.CustomerLong); |
||||
|
if (dealerResponse!=null && dealerResponse.IsRequestSuccessfull) |
||||
|
{ |
||||
|
|
||||
|
JObject obj = JObject.Parse(dealerResponse.Result); |
||||
|
if (obj != null && obj["Data"] != null && obj["Data"].Count() > 0) |
||||
|
{ |
||||
|
if (obj["Data"].Count() == 1) |
||||
|
{ |
||||
|
//Save dealer Detail and Send to LSQ
|
||||
|
JToken jArrResultData = (JToken)obj["Data"][0]; |
||||
|
if (jArrResultData != null) |
||||
|
{ |
||||
|
customerInfo.DealerCode = (JValue)jArrResultData["Code"] != null ? Convert.ToString(((JValue)jArrResultData["Code"]).Value) : "0"; |
||||
|
customerInfo.DealerName = (JValue)jArrResultData["DisplayName"] != null ? Convert.ToString(((JValue)jArrResultData["DisplayName"]).Value) : "0"; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
var responseApi = await MulesoftApi.CallLSQBookingApi(customerInfo); |
||||
|
|
||||
|
if (responseApi != null && responseApi.IsRequestSuccessfull) |
||||
|
await UpdateDealerDetail(customerInfo, DealerSelectionJobStatus.Complete); |
||||
|
else |
||||
|
await UpdateDealerDetail(customerInfo, DealerSelectionJobStatus.ReadyForJob); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
await UpdateDealerDetail(customerInfo, DealerSelectionJobStatus.ReadyForJob); |
||||
|
_logger.LogError("Error in LSQ " + ex.StackTrace.ToString()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
//Send to Webengage
|
||||
|
CustomCfg cfg = CustomCfg.GetCustomCfg(customerInfo.BuId); |
||||
|
WebEngageEventData eventData = new WebEngageEventData(customerInfo.MobileNumber); |
||||
|
WebEngageEvent events = new WebEngageEvent(customerInfo.MobileNumber, cfg.WebengageEventName, eventData); |
||||
|
await WebEngageEventsAPICall(events, cfg); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("BU:- " + customerInfo.BuId + "Api:- GetDealers:- " + ex.StackTrace.ToString()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async Task WebEngageEventsAPICall(WebEngageEvent message, CustomCfg cfg) |
||||
|
{ |
||||
|
_logger.LogInformation("WebEngageEventsAPICall Started: " + JsonConvert.SerializeObject(message)); |
||||
|
try |
||||
|
{ |
||||
|
var json = JsonConvert.SerializeObject(message); |
||||
|
var baseApiUrl = Convert.ToString(cfg.WebengageApiHost + cfg.WebEngageLicenseCode + "/events"); |
||||
|
var options = new RestClientOptions(baseApiUrl) |
||||
|
{ |
||||
|
MaxTimeout = -1, |
||||
|
}; |
||||
|
var client = new RestClient(); |
||||
|
var request = new RestRequest(baseApiUrl, Method.Post); |
||||
|
request.AddHeader("Content-Type", "application/json"); |
||||
|
request.AddHeader("Authorization", "Bearer " + cfg.WebEngageAuthToken); |
||||
|
request.AddStringBody(json, DataFormat.Json); |
||||
|
RestResponse response = await client.ExecuteAsync(request); |
||||
|
var content = response.Content; |
||||
|
|
||||
|
_logger.LogInformation("WebEngageEventsAPICall End: " + content); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("PendingStatusUpdateApi:- WebEngageEventsAPICall:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private async Task UpdateDealerDetail(MulesoftCustomerInfoDto customerInfo, DealerSelectionJobStatus jobStatus) |
||||
|
{ |
||||
|
CustomerDealerInfoRequestDto dto = new CustomerDealerInfoRequestDto |
||||
|
{ |
||||
|
BuId = customerInfo.BuId, |
||||
|
DealerName = jobStatus == DealerSelectionJobStatus.Complete ? customerInfo.DealerName : "", |
||||
|
DealerCode = jobStatus == DealerSelectionJobStatus.Complete ? customerInfo.DealerCode : "", |
||||
|
DealerSelectionJobStatus = jobStatus == DealerSelectionJobStatus.Complete ? DealerSelectionJobStatus.Complete : DealerSelectionJobStatus.ReadyForJob, |
||||
|
RecordId = customerInfo.RecordId |
||||
|
|
||||
|
}; |
||||
|
await CustomerDetailRepository.UpdateDealerDetail(dto); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,151 @@ |
|||||
|
using System.Security.Cryptography; |
||||
|
using System.Text; |
||||
|
|
||||
|
namespace DealerSelection.Api.CommonUtil |
||||
|
{ |
||||
|
|
||||
|
public static class AESEncryption |
||||
|
{ |
||||
|
|
||||
|
public static byte[] EncryptString(string plainText, byte[] key, byte[] iv) |
||||
|
{ |
||||
|
// Instantiate a new Aes object to perform string symmetric encryption
|
||||
|
Aes encryptor = Aes.Create(); |
||||
|
|
||||
|
encryptor.Mode = CipherMode.CBC; |
||||
|
|
||||
|
// Set key and IV
|
||||
|
byte[] aesKey = new byte[32]; |
||||
|
Array.Copy(key, 0, aesKey, 0, 32); |
||||
|
encryptor.Key = aesKey; |
||||
|
encryptor.IV = iv; |
||||
|
|
||||
|
// Instantiate a new MemoryStream object to contain the encrypted bytes
|
||||
|
MemoryStream memoryStream = new MemoryStream(); |
||||
|
|
||||
|
// Instantiate a new encryptor from our Aes object
|
||||
|
ICryptoTransform aesEncryptor = encryptor.CreateEncryptor(); |
||||
|
|
||||
|
// Instantiate a new CryptoStream object to process the data and write it to the
|
||||
|
// memory stream
|
||||
|
CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write); |
||||
|
|
||||
|
// Convert the plainText string into a byte array
|
||||
|
byte[] plainBytes = Encoding.ASCII.GetBytes(plainText); |
||||
|
|
||||
|
// Encrypt the input plaintext string
|
||||
|
cryptoStream.Write(plainBytes, 0, plainBytes.Length); |
||||
|
|
||||
|
// Complete the encryption process
|
||||
|
cryptoStream.FlushFinalBlock(); |
||||
|
|
||||
|
// Convert the encrypted data from a MemoryStream to a byte array
|
||||
|
byte[] cipherBytes = memoryStream.ToArray(); |
||||
|
|
||||
|
// Close both the MemoryStream and the CryptoStream
|
||||
|
memoryStream.Close(); |
||||
|
cryptoStream.Close(); |
||||
|
|
||||
|
// Convert the encrypted byte array to a base64 encoded string
|
||||
|
string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length); |
||||
|
|
||||
|
// Return the encrypted data as a string
|
||||
|
return cipherBytes; |
||||
|
} |
||||
|
|
||||
|
public static string DecryptString(string cipherText, string key) |
||||
|
{ |
||||
|
// Instantiate a new Aes object to perform string symmetric encryption
|
||||
|
Aes encryptor = Aes.Create(); |
||||
|
|
||||
|
encryptor.Mode = CipherMode.CBC; |
||||
|
|
||||
|
byte[] salt = Convert.FromBase64String(cipherText).Take(16).ToArray(); |
||||
|
byte[] IVV = Convert.FromBase64String(cipherText).Skip(16).Take(16).ToArray(); |
||||
|
|
||||
|
|
||||
|
byte[] aesKey; |
||||
|
using (var pbkdf2 = new Rfc2898DeriveBytes(key, salt, 65536, HashAlgorithmName.SHA256)) |
||||
|
{ |
||||
|
aesKey = pbkdf2.GetBytes(32); |
||||
|
} |
||||
|
|
||||
|
// Set key and IV
|
||||
|
//byte[] aesKey = new byte[32];
|
||||
|
//Array.Copy(key, 0, aesKey, 0, 32);
|
||||
|
encryptor.Key = aesKey; |
||||
|
encryptor.IV = IVV; |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
// Instantiate a new MemoryStream object to contain the encrypted bytes
|
||||
|
MemoryStream memoryStream = new MemoryStream(); |
||||
|
|
||||
|
// Instantiate a new encryptor from our Aes object
|
||||
|
ICryptoTransform aesDecryptor = encryptor.CreateDecryptor(); |
||||
|
|
||||
|
// Instantiate a new CryptoStream object to process the data and write it to the
|
||||
|
// memory stream
|
||||
|
CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write); |
||||
|
|
||||
|
// Will contain decrypted plaintext
|
||||
|
string plainText = string.Empty; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
// Convert the ciphertext string into a byte array
|
||||
|
byte[] cipherBytes = Convert.FromBase64String(cipherText).Skip(32).ToArray(); |
||||
|
|
||||
|
// Decrypt the input ciphertext string
|
||||
|
cryptoStream.Write(cipherBytes, 0, cipherBytes.Length); |
||||
|
|
||||
|
// Complete the decryption process
|
||||
|
cryptoStream.FlushFinalBlock(); |
||||
|
|
||||
|
// Convert the decrypted data from a MemoryStream to a byte array
|
||||
|
byte[] plainBytes = memoryStream.ToArray(); |
||||
|
|
||||
|
// Convert the decrypted byte array to string
|
||||
|
plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
// Close both the MemoryStream and the CryptoStream
|
||||
|
memoryStream.Close(); |
||||
|
cryptoStream.Close(); |
||||
|
} |
||||
|
|
||||
|
// Return the decrypted data as a string
|
||||
|
return plainText; |
||||
|
} |
||||
|
|
||||
|
public static dynamic ReturnEncKey(string password,string message) |
||||
|
{ |
||||
|
|
||||
|
byte[] salt = new byte[16]; |
||||
|
byte[] encKey; |
||||
|
using (var rng = RandomNumberGenerator.Create()) |
||||
|
{ |
||||
|
rng.GetBytes(salt); |
||||
|
} |
||||
|
|
||||
|
using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 65536, HashAlgorithmName.SHA256)) |
||||
|
{ |
||||
|
encKey = pbkdf2.GetBytes(32); |
||||
|
} |
||||
|
|
||||
|
Random random = new Random(); |
||||
|
|
||||
|
byte[] iv = new byte[16]; |
||||
|
random.NextBytes(iv); |
||||
|
byte[] encrypted = EncryptString(message, encKey, iv); |
||||
|
byte[] finalstring = salt.Concat(iv).Concat(encrypted).ToArray(); |
||||
|
string encstring = Convert.ToBase64String(finalstring); |
||||
|
|
||||
|
return encstring; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,132 @@ |
|||||
|
using DealerSelection.Common.Configuration; |
||||
|
|
||||
|
namespace DealerSelection.Api.CommonUtil |
||||
|
{ |
||||
|
public class CustomCfg |
||||
|
{ |
||||
|
public int BuId { get; set; } |
||||
|
public string BuCode { get; set; } |
||||
|
public string InfoBipAppilcationId { get; set; } |
||||
|
public string InfoBipMessageId { get; set; } |
||||
|
public string InfoBipFroms { get; set; } |
||||
|
public string CCAvenueAccessCode { get; set; } |
||||
|
public string CCAvenueMerchantCode { get; set; } |
||||
|
public string CCAvenueBaseUrl { get; set; } |
||||
|
public string BookingPrice { get; set; } |
||||
|
public string CCAvenueWorkingKey { get; set; } |
||||
|
public string WebengageLandingPageUrl { get; set; } |
||||
|
public string WebengageEventName { get; set; } |
||||
|
public string WebEngageLicenseCode { get; set; } |
||||
|
public string WebEngageAuthToken { get; set; } |
||||
|
public string WebengageApiHost { get; set; } |
||||
|
public string ValidateDuplicate { get; set; } |
||||
|
public int ValidateDuplicateHour { get; set; } |
||||
|
|
||||
|
public string ClientId { get; set; } |
||||
|
public string ClientSecret { get; set; } |
||||
|
public string Key { get; set; } |
||||
|
public string Audience { get; set; } |
||||
|
public string Issuer { get; set; } |
||||
|
public string Role { get; set; } |
||||
|
|
||||
|
public string ExpireMinutes { get; set; } |
||||
|
public static CustomCfg GetCustomCfg(int buId) |
||||
|
{ |
||||
|
CustomCfg cfg = new CustomCfg(); |
||||
|
switch (buId) |
||||
|
{ |
||||
|
case 1: |
||||
|
cfg.InfoBipAppilcationId = ConfigurationHelper.GetSetting<string>("KtmCfg:InfoBipAppilcationId", true); |
||||
|
cfg.InfoBipMessageId = ConfigurationHelper.GetSetting<string>("KtmCfg:InfoBipMessageId", true); |
||||
|
cfg.InfoBipFroms = ConfigurationHelper.GetSetting<string>("KtmCfg:InfoBipFrom", true); |
||||
|
|
||||
|
cfg.CCAvenueAccessCode = ConfigurationHelper.GetSetting<string>("KtmCfg:CCAvenueAccessCode", true); |
||||
|
cfg.CCAvenueMerchantCode = ConfigurationHelper.GetSetting<string>("KtmCfg:CCAvenueMerchantCode", true); |
||||
|
cfg.CCAvenueBaseUrl = ConfigurationHelper.GetSetting<string>("KtmCfg:CCAvenueBaseUrl", true); |
||||
|
cfg.BookingPrice = ConfigurationHelper.GetSetting<string>("KtmCfg:BookingPrice", true); |
||||
|
cfg.CCAvenueWorkingKey = ConfigurationHelper.GetSetting<string>("KtmCfg:CCAvenueWorkingKey", true); |
||||
|
cfg.BuCode= ConfigurationHelper.GetSetting<string>("KtmCfg:BuCode", true); |
||||
|
cfg.WebengageLandingPageUrl= ConfigurationHelper.GetSetting<string>("KtmCfg:LandingPageUrl", true); |
||||
|
cfg.WebengageEventName = ConfigurationHelper.GetSetting<string>("KtmCfg:WebengageEventName", true); |
||||
|
cfg.WebEngageLicenseCode = ConfigurationHelper.GetSetting<string>("KtmCfg:WebEngageLicenseCode", true); |
||||
|
cfg.WebEngageAuthToken = ConfigurationHelper.GetSetting<string>("KtmCfg:WebEngageAuthToken", true); |
||||
|
cfg.WebengageApiHost = ConfigurationHelper.GetSetting<string>("KtmCfg:WebengageApiHost", true); |
||||
|
cfg.ValidateDuplicate = ConfigurationHelper.GetSetting<string>("KtmCfg:ValidateDuplicate", true); |
||||
|
cfg.ValidateDuplicateHour = ConfigurationHelper.GetSetting<int>("KtmCfg:ValidateDuplicateHr", true); |
||||
|
cfg.BuId = buId; |
||||
|
|
||||
|
cfg.ClientId = ConfigurationHelper.GetSetting<string>("KtmCfg:ClientId", true); |
||||
|
cfg.ClientSecret = ConfigurationHelper.GetSetting<string>("KtmCfg:ClientSecret", true); |
||||
|
cfg.Key = ConfigurationHelper.GetSetting<string>("KtmCfg:Key", true); |
||||
|
cfg.Audience = ConfigurationHelper.GetSetting<string>("KtmCfg:Audience", true); |
||||
|
cfg.Issuer = ConfigurationHelper.GetSetting<string>("KtmCfg:Issuer", true); |
||||
|
cfg.Role = ConfigurationHelper.GetSetting<string>("KtmCfg:Role", true); |
||||
|
cfg.ExpireMinutes = ConfigurationHelper.GetSetting<string>("KtmCfg:ExpireMinutes", true); |
||||
|
break; |
||||
|
case 2: |
||||
|
cfg.InfoBipAppilcationId = ConfigurationHelper.GetSetting<string>("BajajCfg:InfoBipAppilcationId", true); |
||||
|
cfg.InfoBipMessageId = ConfigurationHelper.GetSetting<string>("BajajCfg:InfoBipMessageId", true); |
||||
|
cfg.InfoBipFroms = ConfigurationHelper.GetSetting<string>("BajajCfg:InfoBipFrom", true); |
||||
|
cfg.CCAvenueAccessCode = ConfigurationHelper.GetSetting<string>("BajajCfg:CCAvenueAccessCode", true); |
||||
|
cfg.CCAvenueMerchantCode = ConfigurationHelper.GetSetting<string>("BajajCfg:CCAvenueMerchantCode", true); |
||||
|
cfg.CCAvenueBaseUrl = ConfigurationHelper.GetSetting<string>("BajajCfg:CCAvenueBaseUrl", true); |
||||
|
cfg.BookingPrice = ConfigurationHelper.GetSetting<string>("BajajCfg:BookingPrice", true); |
||||
|
cfg.CCAvenueWorkingKey = ConfigurationHelper.GetSetting<string>("BajajCfg:CCAvenueWorkingKey", true); |
||||
|
cfg.BuCode = ConfigurationHelper.GetSetting<string>("BajajCfg:BuCode", true); |
||||
|
cfg.WebengageLandingPageUrl = ConfigurationHelper.GetSetting<string>("BajajCfg:LandingPageUrl", true); |
||||
|
cfg.WebengageEventName = ConfigurationHelper.GetSetting<string>("BajajCfg:WebengageEventName", true); |
||||
|
cfg.WebEngageLicenseCode = ConfigurationHelper.GetSetting<string>("BajajCfg:WebEngageLicenseCode", true); |
||||
|
cfg.WebEngageAuthToken = ConfigurationHelper.GetSetting<string>("BajajCfg:WebEngageAuthToken", true); |
||||
|
cfg.WebengageApiHost = ConfigurationHelper.GetSetting<string>("BajajCfg:WebengageApiHost", true); |
||||
|
cfg.ValidateDuplicate = ConfigurationHelper.GetSetting<string>("BajajCfg:ValidateDuplicate", true); |
||||
|
cfg.ValidateDuplicateHour = ConfigurationHelper.GetSetting<int>("BajajCfg:ValidateDuplicateHr", true); |
||||
|
cfg.BuId = buId; |
||||
|
|
||||
|
cfg.ClientId = ConfigurationHelper.GetSetting<string>("BajajCfg:ClientId", true); |
||||
|
cfg.ClientSecret = ConfigurationHelper.GetSetting<string>("BajajCfg:ClientSecret", true); |
||||
|
cfg.Key = ConfigurationHelper.GetSetting<string>("BajajCfg:Key", true); |
||||
|
cfg.Audience = ConfigurationHelper.GetSetting<string>("BajajCfg:Audience", true); |
||||
|
cfg.Issuer = ConfigurationHelper.GetSetting<string>("BajajCfg:Issuer", true); |
||||
|
cfg.Role = ConfigurationHelper.GetSetting<string>("BajajCfg:Role", true); |
||||
|
cfg.ExpireMinutes = ConfigurationHelper.GetSetting<string>("BajajCfg:ExpireMinutes", true); |
||||
|
break; |
||||
|
case 3: |
||||
|
cfg.InfoBipAppilcationId = ConfigurationHelper.GetSetting<string>("TriumphCfg:InfoBipAppilcationId", true); |
||||
|
cfg.InfoBipMessageId = ConfigurationHelper.GetSetting<string>("TriumphCfg:InfoBipMessageId", true); |
||||
|
cfg.InfoBipFroms = ConfigurationHelper.GetSetting<string>("TriumphCfg:InfoBipFrom", true); |
||||
|
cfg.CCAvenueAccessCode = ConfigurationHelper.GetSetting<string>("TriumphCfg:CCAvenueAccessCode", true); |
||||
|
cfg.CCAvenueMerchantCode = ConfigurationHelper.GetSetting<string>("TriumphCfg:CCAvenueMerchantCode", true); |
||||
|
cfg.CCAvenueBaseUrl = ConfigurationHelper.GetSetting<string>("TriumphCfg:CCAvenueBaseUrl", true); |
||||
|
cfg.BookingPrice = ConfigurationHelper.GetSetting<string>("TriumphCfg:BookingPrice", true); |
||||
|
cfg.CCAvenueWorkingKey = ConfigurationHelper.GetSetting<string>("TriumphCfg:CCAvenueWorkingKey", true); |
||||
|
cfg.BuCode = ConfigurationHelper.GetSetting<string>("TriumphCfg:BuCode", true); |
||||
|
cfg.WebengageLandingPageUrl = ConfigurationHelper.GetSetting<string>("TriumphCfg:LandingPageUrl", true); |
||||
|
cfg.WebengageEventName = ConfigurationHelper.GetSetting<string>("TriumphCfg:WebengageEventName", true); |
||||
|
cfg.WebEngageLicenseCode = ConfigurationHelper.GetSetting<string>("TriumphCfg:WebEngageLicenseCode", true); |
||||
|
cfg.WebEngageAuthToken = ConfigurationHelper.GetSetting<string>("TriumphCfg:WebEngageAuthToken", true); |
||||
|
cfg.WebengageApiHost = ConfigurationHelper.GetSetting<string>("TriumphCfg:WebengageApiHost", true); |
||||
|
cfg.ValidateDuplicate = ConfigurationHelper.GetSetting<string>("TriumphCfg:ValidateDuplicate", true); |
||||
|
cfg.ValidateDuplicateHour = ConfigurationHelper.GetSetting<int>("TriumphCfg:ValidateDuplicateHr", true); |
||||
|
cfg.BuId = buId; |
||||
|
|
||||
|
cfg.ClientId = ConfigurationHelper.GetSetting<string>("TriumphCfg:ClientId", true); |
||||
|
cfg.ClientSecret = ConfigurationHelper.GetSetting<string>("TriumphCfg:ClientSecret", true); |
||||
|
cfg.Key = ConfigurationHelper.GetSetting<string>("TriumphCfg:Key", true); |
||||
|
cfg.Audience = ConfigurationHelper.GetSetting<string>("TriumphCfg:Audience", true); |
||||
|
cfg.Issuer = ConfigurationHelper.GetSetting<string>("TriumphCfg:Issuer", true); |
||||
|
cfg.Role = ConfigurationHelper.GetSetting<string>("TriumphCfg:Role", true); |
||||
|
cfg.ExpireMinutes = ConfigurationHelper.GetSetting<string>("TriumphCfg:ExpireMinutes", true); |
||||
|
break; |
||||
|
default: |
||||
|
cfg.InfoBipAppilcationId = ""; |
||||
|
cfg.InfoBipMessageId = ""; |
||||
|
cfg.InfoBipFroms = ""; |
||||
|
cfg.BuId = buId; |
||||
|
break; |
||||
|
} |
||||
|
return cfg; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
namespace DealerSelection.Api.CommonUtil |
||||
|
{ |
||||
|
public static class GenerateRandomString |
||||
|
{ |
||||
|
public static string GenerateString(int lgth) |
||||
|
{ |
||||
|
string random = ""; |
||||
|
try |
||||
|
{ |
||||
|
Random ran = new Random(); |
||||
|
string b = "abcdefghijklmnopqrstuvwxyz"; |
||||
|
int length = lgth; |
||||
|
|
||||
|
for (int i = 0; i < length; i++) |
||||
|
{ |
||||
|
int a = ran.Next(26); |
||||
|
random = random + b.ElementAt(a); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw ex; |
||||
|
} |
||||
|
return random; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,86 @@ |
|||||
|
using DealerSelection.Api.Models; |
||||
|
using DealerSelection.Common.Configuration; |
||||
|
using Newtonsoft.Json.Linq; |
||||
|
using System.Net; |
||||
|
using System.Net.Http.Headers; |
||||
|
using System.Text; |
||||
|
using DealerSelection.Common.Interfaces.HttpClient; |
||||
|
using DealerSelection.Common.Logging; |
||||
|
|
||||
|
namespace DealerSelection.Api.CommonUtil |
||||
|
{ |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Summary description for TestRideExcellon
|
||||
|
/// </summary>
|
||||
|
public static class MuleSoftIntegration |
||||
|
{ |
||||
|
public static string ClientId = ConfigurationHelper.GetSetting<string>("muleSoftAPIClientID", true); |
||||
|
public static string ClientSecret = ConfigurationHelper.GetSetting<string>("muleSoftAIPClientSecret", true); |
||||
|
public static string TokenGenerateUrl = ConfigurationHelper.GetSetting<string>("muleSoftGenerateTokenURL", true); |
||||
|
|
||||
|
public static async Task<MulesoftToken> generateToken(IHttpClientHandler clientHandler) |
||||
|
{ |
||||
|
AzureLogHelper.LogMessage("Api:- generateToken Started :- " + DateTime.Now); |
||||
|
MulesoftToken token = new MulesoftToken(); |
||||
|
try |
||||
|
{ |
||||
|
var url = TokenGenerateUrl + "/token"; |
||||
|
|
||||
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; |
||||
|
HttpClient client = clientHandler.GetHttpClient(); |
||||
|
Uri requestUri = new Uri(url); |
||||
|
|
||||
|
client.DefaultRequestHeaders.Add("client_id", ClientId); |
||||
|
client.DefaultRequestHeaders.Add("client_secret", ClientSecret); |
||||
|
client.DefaultRequestHeaders.Add("grant_type", "CLIENT_CREDENTIALS"); |
||||
|
client.DefaultRequestHeaders.Add("cache-control", "no-cache"); |
||||
|
|
||||
|
var response = await client.PostAsync(requestUri, null); |
||||
|
|
||||
|
if (response != null) |
||||
|
{ |
||||
|
JObject obj = JObject.Parse(await response.Content.ReadAsStringAsync()); |
||||
|
if (response.StatusCode.ToString() == "OK") |
||||
|
{ |
||||
|
if (!string.IsNullOrEmpty(Convert.ToString(obj["access_token"]))) |
||||
|
token.Value = Convert.ToString(obj["access_token"]); |
||||
|
if (!string.IsNullOrEmpty(Convert.ToString(obj["expires_in"]))) |
||||
|
token.ExpiresIn = Convert.ToInt32(obj["expires_in"]); |
||||
|
} |
||||
|
} |
||||
|
return token; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw ex; |
||||
|
} |
||||
|
return token; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public static async Task<HttpResponseMessage> ReturnMuleSoftResponse(IHttpClientHandler clientHandler, string encstring, string url, string authToken, string encKeyToHeader) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
var data = "{\"encData\": \"" + encstring + "\"}"; |
||||
|
|
||||
|
HttpClient request = clientHandler.GetHttpClient(); |
||||
|
Uri requestUri = new Uri(url); |
||||
|
|
||||
|
var httpContent = new MultipartFormDataContent(); |
||||
|
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); |
||||
|
request.DefaultRequestHeaders.Add("client_id", ClientId); |
||||
|
request.DefaultRequestHeaders.Add("client_secret", ClientSecret); |
||||
|
request.DefaultRequestHeaders.Add("Authorization", "Bearer " + authToken); |
||||
|
request.DefaultRequestHeaders.Add("encKey", encKeyToHeader); |
||||
|
return await request.PostAsync(requestUri, new StringContent(data, UnicodeEncoding.UTF8, "application/json")); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw ex; |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
||||
|
<NoWarn>1701;1702;8618;8601;8600;8602;8603;CA2254</NoWarn> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> |
||||
|
<NoWarn>1701;1702;8618;8601;8600;8602;8603;CA2254</NoWarn> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="BouncyCastle.NetCore" Version="1.9.0" /> |
||||
|
<PackageReference Include="iTextSharp" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="itextsharp.xmlworker" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.21.0" /> |
||||
|
<PackageReference Include="RestSharp.Serializers.NewtonsoftJson" Version="110.2.0" /> |
||||
|
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7"> |
||||
|
<PrivateAssets>all</PrivateAssets> |
||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
||||
|
</PackageReference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\DealerSelection.Infrastructure\DealerSelection.Api.Infrastructure.csproj" /> |
||||
|
<ProjectReference Include="..\DealerSelection.Interface\DealerSelection.Api.Interface.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Reference Include="MCPG.CCA.Util"> |
||||
|
<HintPath>CCAvenue\MCPG.CCA.Util.dll</HintPath> |
||||
|
<Private>True</Private> |
||||
|
</Reference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
@ -0,0 +1,143 @@ |
|||||
|
using DealerSelection.Api.CommonUtil; |
||||
|
using DealerSelection.Api.Infrastructure.InfoBip; |
||||
|
using DealerSelection.Api.Interface; |
||||
|
using DealerSelection.Common.Interfaces.HttpClient; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Newtonsoft.Json; |
||||
|
using Newtonsoft.Json.Linq; |
||||
|
using System.Net; |
||||
|
using System.Text; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Summary description for KarixSmsService
|
||||
|
/// </summary>
|
||||
|
public class InfoBipSmsServiceApi : IInfoBipSmsServiceApi |
||||
|
{ |
||||
|
|
||||
|
static string userAuth = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("Bajaj_OTP1" + ":" + "BAL@October2022")); |
||||
|
private IRepository Repository { get; } |
||||
|
private readonly ILogger _logger; |
||||
|
private IHttpClientHandler ClientHandler { get; } |
||||
|
public InfoBipSmsServiceApi(IRepository repository, IHttpClientHandler clientHandler, ILogger<InfoBipSmsServiceApi> logger) |
||||
|
{ |
||||
|
Repository = repository; |
||||
|
ClientHandler = clientHandler; |
||||
|
_logger = logger; |
||||
|
} |
||||
|
public InfoBipSmsServiceApi() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public async Task<JObject> sendOTP(int buId, string strMobile) |
||||
|
{ |
||||
|
CustomCfg cfg = CustomCfg.GetCustomCfg(buId); |
||||
|
JObject obj = new JObject(); |
||||
|
try |
||||
|
{ |
||||
|
var reqObject = new SendOTP |
||||
|
{ |
||||
|
applicationId = cfg.InfoBipAppilcationId, |
||||
|
messageId = cfg.InfoBipMessageId, |
||||
|
from = cfg.InfoBipFroms, |
||||
|
to = "91" + strMobile |
||||
|
}; |
||||
|
var json = JsonConvert.SerializeObject(reqObject); |
||||
|
|
||||
|
string apiUrl = "https://266k6.api.infobip.com/2fa/2/pin"; |
||||
|
|
||||
|
obj = await GetDataFromInfoBip(buId, strMobile, apiUrl, "verify", json); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- sendOTP:- " + ex.StackTrace.ToString()); |
||||
|
} |
||||
|
|
||||
|
return obj; |
||||
|
} |
||||
|
|
||||
|
public async Task<JObject> resendOTP(int buId, string strMobile, string strOtpPinId) |
||||
|
{ |
||||
|
var errorMessage = ""; |
||||
|
JObject obj = new JObject(); |
||||
|
try |
||||
|
{ |
||||
|
string apiUrl = "https://266k6.api.infobip.com/2fa/2/pin/" + strOtpPinId + "/resend"; |
||||
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(apiUrl); |
||||
|
request.Method = "POST"; |
||||
|
request.Headers.Add("Authorization", "Basic " + userAuth); |
||||
|
request.Headers.Add("cache-control", "no-cache"); |
||||
|
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); |
||||
|
Stream responseStream = response.GetResponseStream(); |
||||
|
StreamReader reader = new StreamReader(responseStream); |
||||
|
string content = reader.ReadToEnd(); |
||||
|
string apiRequest = strOtpPinId; |
||||
|
string apiResponse = content; |
||||
|
obj = JObject.Parse(content); |
||||
|
await Repository.SaveResponse(buId, strMobile, "resend otp", apiRequest, apiResponse, errorMessage); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
errorMessage = ex.Message; |
||||
|
_logger.LogError("BUID:- " + buId + "Api:- resendOTP:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
return obj; |
||||
|
} |
||||
|
|
||||
|
public async Task<JObject> verifyOTP(int buId, string strMobile, string strOtpPinId, string otpPin) |
||||
|
{ |
||||
|
JObject obj = new(); |
||||
|
try |
||||
|
{ |
||||
|
var reqObject = new OTP |
||||
|
{ |
||||
|
pin = otpPin |
||||
|
}; |
||||
|
var json = JsonConvert.SerializeObject(reqObject); |
||||
|
|
||||
|
string apiUrl = "https://266k6.api.infobip.com/2fa/2/pin/" + strOtpPinId + "/verify"; |
||||
|
|
||||
|
obj = await GetDataFromInfoBip(buId, strMobile, apiUrl, "verify", json); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("BUID:- " + buId + " Api:- verifyOTP:- " + ex.StackTrace.ToString()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
return obj; |
||||
|
} |
||||
|
|
||||
|
private async Task<JObject> GetDataFromInfoBip(int buId, string strMobile, string baseUrl, string otpRequestType, string data) |
||||
|
{ |
||||
|
HttpClient client = ClientHandler.GetHttpClient(); |
||||
|
Uri requestUri = new Uri(baseUrl); |
||||
|
|
||||
|
|
||||
|
client.DefaultRequestHeaders.Add("Authorization", "Basic " + userAuth); |
||||
|
client.DefaultRequestHeaders.Add("cache-control", "no-cache"); |
||||
|
|
||||
|
var response = await client.PostAsync(requestUri, new StringContent(data, UnicodeEncoding.UTF8, "application/json")); |
||||
|
|
||||
|
JObject obj = JObject.Parse(await response.Content.ReadAsStringAsync()); |
||||
|
|
||||
|
_logger.LogError($"BuId: {buId}, MobileNumber: {strMobile}, OTP Type: {otpRequestType}, ApiRequest: {data} , ApiResponse: {response}"); |
||||
|
|
||||
|
return obj; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class OTP |
||||
|
{ |
||||
|
public string pin { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class SendOTP |
||||
|
{ |
||||
|
public string applicationId { get; set; } |
||||
|
public string messageId { get; set; } |
||||
|
public string from { get; set; } |
||||
|
public string to { get; set; } |
||||
|
} |
@ -0,0 +1,112 @@ |
|||||
|
using DealerSelection.Api.CommonUtil; |
||||
|
using DealerSelection.Api.Infrastructure.Jwt; |
||||
|
using DealerSelection.Api.Interface; |
||||
|
using DealerSelection.Api.Models; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.IdentityModel.Tokens; |
||||
|
using System.IdentityModel.Tokens.Jwt; |
||||
|
using System.Security.Claims; |
||||
|
using System.Text; |
||||
|
|
||||
|
public class JwtTokenApi : IJwtTokenApi |
||||
|
{ |
||||
|
private IJwtRepository Repository { get; } |
||||
|
private readonly ILogger _logger; |
||||
|
|
||||
|
public JwtTokenApi(IJwtRepository repository, ILogger<JwtTokenApi> logger) |
||||
|
{ |
||||
|
Repository = repository; |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
public async Task<string> GenerateToken(AuthValidateModel user) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
bool isValidUser = await Authenticate(user); |
||||
|
if (isValidUser) |
||||
|
{ |
||||
|
AuthModel auth = new AuthModel |
||||
|
{ |
||||
|
BuId = user.BuId, |
||||
|
ClientId = user.ClientId, |
||||
|
SecretId = user.SecretId, |
||||
|
Role = "Admin" |
||||
|
}; |
||||
|
CustomCfg cfg = CustomCfg.GetCustomCfg(auth.BuId); |
||||
|
|
||||
|
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(cfg.Key)); |
||||
|
string expireMinutes = cfg.ExpireMinutes; |
||||
|
int tokenExpireMinutes = string.IsNullOrEmpty(expireMinutes) ? 1439 : int.Parse(expireMinutes); |
||||
|
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); |
||||
|
var claims = new[] |
||||
|
{ |
||||
|
new Claim(ClaimTypes.NameIdentifier,auth.ClientId), |
||||
|
new Claim(ClaimTypes.Role,auth.Role), |
||||
|
}; |
||||
|
var token = new JwtSecurityToken( |
||||
|
cfg.Issuer, |
||||
|
cfg.Audience, |
||||
|
claims, |
||||
|
expires: DateTime.UtcNow.AddMinutes(tokenExpireMinutes), |
||||
|
signingCredentials: credentials); |
||||
|
return new JwtSecurityTokenHandler().WriteToken(token); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("JwtTokenApi Api GenerateToken:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public async Task<bool> Authenticate(AuthValidateModel userLogin) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
CustomCfg cfg = CustomCfg.GetCustomCfg(userLogin.BuId); |
||||
|
|
||||
|
return cfg.ClientId.ToLower() == userLogin.ClientId.ToLower() && |
||||
|
cfg.ClientSecret.ToLower() == userLogin.SecretId.ToLower(); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("JwtTokenApi Api Authenticate:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public async Task<TokenValidProperty> IsTokenExpired(string tokenValue) |
||||
|
{ |
||||
|
TokenValidProperty tokenValid = new TokenValidProperty(); |
||||
|
try |
||||
|
{ |
||||
|
var tokenTicks = GetTokenExpirationTime(tokenValue); |
||||
|
var tokenDate = DateTimeOffset.FromUnixTimeSeconds(tokenTicks).UtcDateTime; |
||||
|
|
||||
|
var now = DateTime.UtcNow; |
||||
|
var valid = tokenDate >= now; |
||||
|
|
||||
|
tokenValid.isValid = valid; |
||||
|
tokenValid.Ttl = tokenDate.TimeOfDay.TotalSeconds - now.TimeOfDay.TotalSeconds; |
||||
|
|
||||
|
return tokenValid; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("JwtTokenApi Api IsTokenExpired:- " + ex.Message.ToString()); |
||||
|
return tokenValid; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static long GetTokenExpirationTime(string token) |
||||
|
{ |
||||
|
var handler = new JwtSecurityTokenHandler(); |
||||
|
var jwtSecurityToken = handler.ReadJwtToken(token); |
||||
|
var tokenExp = jwtSecurityToken.Claims.First(claim => claim.Type.Equals("exp")).Value; |
||||
|
var ticks = long.Parse(tokenExp); |
||||
|
return ticks; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,722 @@ |
|||||
|
using DealerSelection.Api.CommonUtil; |
||||
|
using DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
using DealerSelection.Api.Interface; |
||||
|
using DealerSelection.Api.Models; |
||||
|
using DealerSelection.Common.Configuration; |
||||
|
using DealerSelection.Common.Interfaces.HttpClient; |
||||
|
using DealerSelection.Common.Logging; |
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Newtonsoft.Json; |
||||
|
using Newtonsoft.Json.Linq; |
||||
|
using System.Text; |
||||
|
|
||||
|
public class MulesoftApi : IMulesoftApi |
||||
|
{ |
||||
|
|
||||
|
#region MuleSoft
|
||||
|
|
||||
|
public static string baseApiUrl = ConfigurationHelper.GetSetting<string>("muleSoftAPIDomain", true); |
||||
|
public static string dealerDetailApiUrl = ConfigurationHelper.GetSetting<string>("muleSoftDealerDetail", true); |
||||
|
public static string bookingApiUrl = ConfigurationHelper.GetSetting<string>("muleSoftBookingAPILeadSquareDomain", true); |
||||
|
public static string masterSchemaId = ConfigurationHelper.GetSetting<string>("masterSchemaId", true); |
||||
|
public static string masterDealerDetailSchemaId = ConfigurationHelper.GetSetting<string>("masterDealerDetailSchemaId", true); |
||||
|
public static string muleSoftStateWisePrice = ConfigurationHelper.GetSetting<string>("muleSoftStateWisePrice", true); |
||||
|
public static string muleSoftBrandWiseModel = ConfigurationHelper.GetSetting<string>("muleSoftBrandWiseModel", true); |
||||
|
public static string muleSoftPricemasterSchemaId = ConfigurationHelper.GetSetting<string>("muleSoftStateWisePricemasterSchemaId", true); |
||||
|
public static string muleSoftModelmasterSchemaId = ConfigurationHelper.GetSetting<string>("muleSoftBrandWiseModelmasterSchemaId", true); |
||||
|
|
||||
|
public static string muleSoftStateMasterSchemaId = ConfigurationHelper.GetSetting<string>("muleSoftStateMasterSchemaId", true); |
||||
|
public static string muleSoftStateMasterSchemaApi = ConfigurationHelper.GetSetting<string>("muleSoftStateMasterSchemaApi", true); |
||||
|
public static string muleSoftCityMasterSchemaId = ConfigurationHelper.GetSetting<string>("muleSoftCityMasterSchemaId", true); |
||||
|
public static string muleSoftCityMasterSchemaApi = ConfigurationHelper.GetSetting<string>("muleSoftCityMasterSchemaApi", true); |
||||
|
public static string muleSoftModelMasterSchemaItemId = ConfigurationHelper.GetSetting<string>("muleSoftModelMasterSchemaItemId", true); |
||||
|
public static string muleSoftModelMasterSchemaItemApi = ConfigurationHelper.GetSetting<string>("muleSoftModelMasterSchemaItemApi", true); |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
|
||||
|
#region Caching
|
||||
|
|
||||
|
public static string CacheGetDealersDetail = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetDealersDetail", true); |
||||
|
private int _cacheGetDealersDetail = !string.IsNullOrEmpty(CacheGetDealersDetail) ? int.Parse(CacheGetDealersDetail) : 10; |
||||
|
|
||||
|
public static string CacheGetPriceOnState = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetPriceOnState", true); |
||||
|
private int _cacheGetPriceOnState = !string.IsNullOrEmpty(CacheGetPriceOnState) ? int.Parse(CacheGetPriceOnState) : 10; |
||||
|
|
||||
|
public static string CacheGetModelOnBrand = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetModelOnBrand", true); |
||||
|
private int _cacheGetModelOnBrand = !string.IsNullOrEmpty(CacheGetModelOnBrand) ? int.Parse(CacheGetModelOnBrand) : 10; |
||||
|
|
||||
|
public static string CacheGetActiveState = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetActiveState", true); |
||||
|
private int _cacheGetActiveState = !string.IsNullOrEmpty(CacheGetActiveState) ? int.Parse(CacheGetActiveState) : 10; |
||||
|
|
||||
|
public static string CacheGetActiveCity = ConfigurationHelper.GetSetting<string>("MuleSoftCacheGetActiveCity", true); |
||||
|
private int _cacheGetActiveCity = !string.IsNullOrEmpty(CacheGetActiveCity) ? int.Parse(CacheGetActiveCity) : 10; |
||||
|
|
||||
|
public static string CacheModelDetails = ConfigurationHelper.GetSetting<string>("MuleSoftCacheModelDetails", true); |
||||
|
private int _cacheModelDetails = !string.IsNullOrEmpty(CacheModelDetails) ? int.Parse(CacheModelDetails) : 10; |
||||
|
|
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
private readonly ILogger _logger; |
||||
|
private IRepository Repository { get; } |
||||
|
private IMulesoftTokenApi MulesoftTokenApi { get; } |
||||
|
private IHttpClientHandler ClientHandler { get; } |
||||
|
private readonly IMemoryCache _memoryCache; |
||||
|
|
||||
|
public MulesoftApi(IRepository repository, IMulesoftTokenApi mulesoftTokenApi, |
||||
|
IHttpClientHandler clientHandler, IMemoryCache memoryCache, ILogger<MulesoftApi> logger) |
||||
|
{ |
||||
|
Repository = repository; |
||||
|
MulesoftTokenApi = mulesoftTokenApi; |
||||
|
ClientHandler = clientHandler; |
||||
|
_memoryCache = memoryCache; |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public async Task<MulesoftResponse> GetDealers(int buId, string buUnit, string strlat, string strLong) |
||||
|
{ |
||||
|
MulesoftResponse response = null; |
||||
|
try |
||||
|
{ |
||||
|
string authToken = await MulesoftTokenApi.FetchToken(); |
||||
|
string message = "{\"bu\": \"" + buUnit + "\", \"latitude\": " + strlat + ", \"longitude\": " |
||||
|
+ strLong + ", \"masterSchemaId\": \"" + masterSchemaId + "\"}"; |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(authToken)) |
||||
|
{ |
||||
|
string password = GenerateRandomString.GenerateString(32); |
||||
|
string encstring = AESEncryption.ReturnEncKey(password, message); |
||||
|
|
||||
|
var plainTextBytes = Encoding.UTF8.GetBytes(password); |
||||
|
string encKeyToHeader = Convert.ToBase64String(plainTextBytes); |
||||
|
|
||||
|
var response2 = await MuleSoftIntegration.ReturnMuleSoftResponse(ClientHandler, |
||||
|
encstring, baseApiUrl, authToken, encKeyToHeader); |
||||
|
|
||||
|
if (response2 != null) |
||||
|
{ |
||||
|
response = await ValidateMuleSoftResponse(buId, response2); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("BU:- " + buId + "Api:- GetDealers:- " + ex.StackTrace.ToString()); |
||||
|
} |
||||
|
return response; |
||||
|
} |
||||
|
|
||||
|
public async Task<MulesoftResponse> GetAndInsertDealerDetails(int buId, string dealerCode) |
||||
|
{ |
||||
|
MulesoftResponse response = null; |
||||
|
try |
||||
|
{ |
||||
|
var cacheKey = "getDealerDetails_" + buId + dealerCode; |
||||
|
if (!_memoryCache.TryGetValue(cacheKey, out response)) |
||||
|
{ |
||||
|
AzureLogHelper.LogMessage("Api:- GetAndInsertDealerDetails:- API:- " + cacheKey); |
||||
|
|
||||
|
string authToken = await MulesoftTokenApi.FetchToken(); |
||||
|
string message = "{\"branchCode\": \"" + dealerCode + |
||||
|
"\",\"masterSchemaId\": \"" + masterDealerDetailSchemaId + "\"}"; |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(authToken)) |
||||
|
{ |
||||
|
string password = GenerateRandomString.GenerateString(32); |
||||
|
string encstring = AESEncryption.ReturnEncKey(password, message); |
||||
|
|
||||
|
var plainTextBytes = Encoding.UTF8.GetBytes(password); |
||||
|
string encKeyToHeader = Convert.ToBase64String(plainTextBytes); |
||||
|
|
||||
|
var response2 = await MuleSoftIntegration.ReturnMuleSoftResponse(ClientHandler, |
||||
|
encstring, dealerDetailApiUrl, authToken, encKeyToHeader); |
||||
|
response = await DecryptDealerDetail(buId, response2); |
||||
|
var cacheExpiryOptions = new MemoryCacheEntryOptions |
||||
|
{ |
||||
|
AbsoluteExpiration = DateTime.Now.AddMinutes(_cacheGetDealersDetail), |
||||
|
Priority = CacheItemPriority.High |
||||
|
}; |
||||
|
_memoryCache.Set(cacheKey, response, cacheExpiryOptions); |
||||
|
} |
||||
|
} |
||||
|
_logger.LogError("Api:- GetAndInsertDealerDetails From Cache:- " + cacheKey); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetAndInsertDealerDetails:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return response; |
||||
|
} |
||||
|
|
||||
|
public async Task<MulesoftResponse> GetStateWisePrice(int buId, string stateCode, string itemId) |
||||
|
{ |
||||
|
MulesoftResponse response = null; |
||||
|
try |
||||
|
{ |
||||
|
var cacheKey = "getStateWisePrice_" + buId + stateCode + itemId; |
||||
|
if (!_memoryCache.TryGetValue(cacheKey, out response)) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetStateWisePrice API:- " + cacheKey); |
||||
|
|
||||
|
string authToken = await MulesoftTokenApi.FetchToken(); |
||||
|
string message = "{\"statecode\": \"" + stateCode.ToUpper() + "\",\"itemId\": \"" |
||||
|
+ itemId + "\",\"masterSchemaId\": \"" + muleSoftPricemasterSchemaId + "\"}"; |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(authToken)) |
||||
|
{ |
||||
|
string password = GenerateRandomString.GenerateString(32); |
||||
|
string encstring = AESEncryption.ReturnEncKey(password, message); |
||||
|
|
||||
|
var plainTextBytes = Encoding.UTF8.GetBytes(password); |
||||
|
string encKeyToHeader = Convert.ToBase64String(plainTextBytes); |
||||
|
|
||||
|
var response2 = await MuleSoftIntegration.ReturnMuleSoftResponse(ClientHandler, |
||||
|
encstring, muleSoftStateWisePrice, authToken, encKeyToHeader); |
||||
|
response = await ValidateMuleSoftResponse(buId, response2); |
||||
|
var jsonresult = JObject.Parse(response.Result); |
||||
|
|
||||
|
if (Convert.ToBoolean(jsonresult["IsRequestSuccessfull"]) && jsonresult["Data"] != null) |
||||
|
{ |
||||
|
string exShowroomPrice = jsonresult["Data"][0]["ExPrice"].ToString(); |
||||
|
MulesoftResponse mulesoftResponse = new MulesoftResponse(buId, 0, Convert.ToBoolean(jsonresult["IsRequestSuccessfull"]), |
||||
|
exShowroomPrice, "", ""); |
||||
|
|
||||
|
var cacheExpiryOptions = new MemoryCacheEntryOptions |
||||
|
{ |
||||
|
AbsoluteExpiration = DateTime.Now.AddMinutes(_cacheGetPriceOnState), |
||||
|
Priority = CacheItemPriority.High |
||||
|
}; |
||||
|
_memoryCache.Set(cacheKey, mulesoftResponse, cacheExpiryOptions); |
||||
|
|
||||
|
return mulesoftResponse; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return new MulesoftResponse(buId, 0, false, response.Result, "", ""); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
_logger.LogError("Api:- GetStateWisePrice From Cache :- " + cacheKey); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetStateWisePrice:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return response; |
||||
|
} |
||||
|
|
||||
|
public async Task<MulesoftResponse> GetModelOnBrand(int buId, string brand) |
||||
|
{ |
||||
|
MulesoftResponse response = null; |
||||
|
try |
||||
|
{ |
||||
|
var cacheKey = "getModelOnBrand_" + buId + brand; |
||||
|
if (!_memoryCache.TryGetValue(cacheKey, out response)) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetModelOnBrand API:- " + cacheKey); |
||||
|
|
||||
|
string authToken = await MulesoftTokenApi.FetchToken(); |
||||
|
string message = "{\"brand\": \"" + brand.ToUpper() + |
||||
|
"\",\"masterSchemaId\": \"" + muleSoftModelmasterSchemaId + "\"}"; |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(authToken)) |
||||
|
{ |
||||
|
string password = GenerateRandomString.GenerateString(32); |
||||
|
string encstring = AESEncryption.ReturnEncKey(password, message); |
||||
|
|
||||
|
var plainTextBytes = Encoding.UTF8.GetBytes(password); |
||||
|
string encKeyToHeader = Convert.ToBase64String(plainTextBytes); |
||||
|
|
||||
|
var response2 = await MuleSoftIntegration.ReturnMuleSoftResponse(ClientHandler, |
||||
|
encstring, muleSoftBrandWiseModel, authToken, encKeyToHeader); |
||||
|
response = await ValidateMuleSoftResponse(buId, response2); |
||||
|
|
||||
|
var cacheExpiryOptions = new MemoryCacheEntryOptions |
||||
|
{ |
||||
|
AbsoluteExpiration = DateTime.Now.AddMinutes(_cacheGetModelOnBrand), |
||||
|
Priority = CacheItemPriority.High |
||||
|
}; |
||||
|
_memoryCache.Set(cacheKey, response, cacheExpiryOptions); |
||||
|
} |
||||
|
} |
||||
|
_logger.LogError("Api:- GetModelOnBrand From Cache:- " + cacheKey); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetModelOnBrand:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return response; |
||||
|
} |
||||
|
|
||||
|
public async Task<MulesoftResponse> GetActiveState(int buId) |
||||
|
{ |
||||
|
CustomCfg cfg = CustomCfg.GetCustomCfg(buId); |
||||
|
MulesoftResponse response = null; |
||||
|
try |
||||
|
{ |
||||
|
var cacheKey = "getActiveState_" + buId; |
||||
|
if (!_memoryCache.TryGetValue(cacheKey, out response)) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetActiveState API:- " + cacheKey); |
||||
|
|
||||
|
string authToken = await MulesoftTokenApi.FetchToken(); |
||||
|
string message = "{\"bu\": \"" + cfg.BuCode.ToUpper() + |
||||
|
"\",\"masterSchemaId\": \"" + muleSoftStateMasterSchemaId + "\"}"; |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(authToken)) |
||||
|
{ |
||||
|
string password = GenerateRandomString.GenerateString(32); |
||||
|
string encstring = AESEncryption.ReturnEncKey(password, message); |
||||
|
|
||||
|
var plainTextBytes = Encoding.UTF8.GetBytes(password); |
||||
|
string encKeyToHeader = Convert.ToBase64String(plainTextBytes); |
||||
|
|
||||
|
var response2 = await MuleSoftIntegration.ReturnMuleSoftResponse(ClientHandler, encstring, |
||||
|
muleSoftStateMasterSchemaApi, authToken, encKeyToHeader); |
||||
|
|
||||
|
response = await ValidateMuleSoftResponse(0, response2); |
||||
|
|
||||
|
var cacheExpiryOptions = new MemoryCacheEntryOptions |
||||
|
{ |
||||
|
AbsoluteExpiration = DateTime.Now.AddMinutes(_cacheGetActiveState), |
||||
|
Priority = CacheItemPriority.High |
||||
|
}; |
||||
|
_memoryCache.Set(cacheKey, response, cacheExpiryOptions); |
||||
|
} |
||||
|
} |
||||
|
_logger.LogError("Api:- GetActiveState from Cache:- " + cacheKey); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetActiveState:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return response; |
||||
|
} |
||||
|
|
||||
|
public async Task<MulesoftResponse> GetActiveCity(int buId, string stateCode) |
||||
|
{ |
||||
|
CustomCfg cfg = CustomCfg.GetCustomCfg(buId); |
||||
|
MulesoftResponse response = null; |
||||
|
try |
||||
|
{ |
||||
|
var cacheKey = "getActiveCity_" + buId + stateCode; |
||||
|
if (!_memoryCache.TryGetValue(cacheKey, out response)) |
||||
|
{ |
||||
|
_logger.LogError("Api GetActiveCity:- API:- " + cacheKey); |
||||
|
|
||||
|
string authToken = await MulesoftTokenApi.FetchToken(); |
||||
|
string message = "{\"bu\": \"" + cfg.BuCode.ToUpper() + "\",\"stateId\": \"" + stateCode.ToUpper() + |
||||
|
"\",\"masterSchemaId\": \"" + muleSoftCityMasterSchemaId + "\"}"; |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(authToken)) |
||||
|
{ |
||||
|
string password = GenerateRandomString.GenerateString(32); |
||||
|
string encstring = AESEncryption.ReturnEncKey(password, message); |
||||
|
|
||||
|
var plainTextBytes = Encoding.UTF8.GetBytes(password); |
||||
|
string encKeyToHeader = Convert.ToBase64String(plainTextBytes); |
||||
|
|
||||
|
var response2 = await MuleSoftIntegration.ReturnMuleSoftResponse(ClientHandler, |
||||
|
encstring, muleSoftCityMasterSchemaApi, |
||||
|
authToken, encKeyToHeader); |
||||
|
response = await ValidateMuleSoftResponse(0, response2); |
||||
|
|
||||
|
var cacheExpiryOptions = new MemoryCacheEntryOptions |
||||
|
{ |
||||
|
AbsoluteExpiration = DateTime.Now.AddMinutes(_cacheGetActiveCity), |
||||
|
Priority = CacheItemPriority.High |
||||
|
}; |
||||
|
_memoryCache.Set(cacheKey, response, cacheExpiryOptions); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
_logger.LogError("Api:- GetStateWisePrice:- API:- From Cache" + cacheKey); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetActiveCity:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return response; |
||||
|
} |
||||
|
|
||||
|
public async Task<MulesoftResponse> ModelDetailsByItemCode(int buId, string itemId) |
||||
|
{ |
||||
|
MulesoftResponse response = null; |
||||
|
try |
||||
|
{ |
||||
|
var cacheKey = "modelDetailsItemCode_" + buId + itemId; |
||||
|
if (!_memoryCache.TryGetValue(cacheKey, out response)) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetStateWisePrice:- API:- From Cache" + cacheKey); |
||||
|
|
||||
|
string authToken = await MulesoftTokenApi.FetchToken(); |
||||
|
string message = "{\"itemid\": \"" + itemId + "\",\"masterSchemaId\": \"" |
||||
|
+ muleSoftModelMasterSchemaItemId + "\"}"; |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(authToken)) |
||||
|
{ |
||||
|
string password = GenerateRandomString.GenerateString(32); |
||||
|
string encstring = AESEncryption.ReturnEncKey(password, message); |
||||
|
|
||||
|
var plainTextBytes = Encoding.UTF8.GetBytes(password); |
||||
|
string encKeyToHeader = Convert.ToBase64String(plainTextBytes); |
||||
|
|
||||
|
var response2 = await MuleSoftIntegration.ReturnMuleSoftResponse(ClientHandler, |
||||
|
encstring, muleSoftModelMasterSchemaItemApi, authToken, encKeyToHeader); |
||||
|
response = await ValidateMuleSoftResponse(0, response2); |
||||
|
|
||||
|
var cacheExpiryOptions = new MemoryCacheEntryOptions |
||||
|
{ |
||||
|
AbsoluteExpiration = DateTime.Now.AddMinutes(_cacheModelDetails), |
||||
|
Priority = CacheItemPriority.High |
||||
|
}; |
||||
|
_memoryCache.Set(cacheKey, response, cacheExpiryOptions); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
_logger.LogError("Api:- GetStateWisePrice:- API:- From Cache" + cacheKey); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetStateWisePrice:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return response; |
||||
|
} |
||||
|
|
||||
|
public async Task<MulesoftCustomerInfoDto> GetCustomerInfo(int buId, string bookingId) |
||||
|
{ |
||||
|
return await Repository.GetCustomerInfo(buId, bookingId); |
||||
|
} |
||||
|
|
||||
|
public async Task<Response> CallLSQBookingApi( MulesoftCustomerInfoDto customerInfo) |
||||
|
{ |
||||
|
_logger.LogInformation($"BU:- {customerInfo.BuId} at MulesofApi:- CallBookingApi for Booking Id:- {customerInfo.BookingId}"); |
||||
|
try |
||||
|
{ |
||||
|
if (customerInfo != null) |
||||
|
{ |
||||
|
string mx_Composite_Key = string.Empty, enquiryClassification = string.Empty, |
||||
|
leadPlatform = "Website", autoModel = string.Empty, |
||||
|
bookingStatus = string.Empty, isSuccessBooking = "True"; |
||||
|
string utmSource = GetUTMDetails(customerInfo.ReferralUrl, "utm_source"); |
||||
|
string utmMedium = GetUTMDetails(customerInfo.ReferralUrl, "utm_medium"); |
||||
|
string sourceCampaign = GetUTMDetails(customerInfo.ReferralUrl, "utm_campaign"); |
||||
|
string utmContent = GetUTMDetails(customerInfo.ReferralUrl, "utm_content"); |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(customerInfo.DealerCode)) |
||||
|
mx_Composite_Key = customerInfo.MobileNumber + customerInfo.DealerCode + "Open"; |
||||
|
else |
||||
|
mx_Composite_Key = customerInfo.MobileNumber + "nullOpen"; |
||||
|
|
||||
|
string mx_Source_Of_Enquiry = "Organic"; string mx_Enquiry_Sub_source = "Website"; |
||||
|
if (!string.IsNullOrEmpty(customerInfo.UtmCustomDetails1)) |
||||
|
{ |
||||
|
mx_Source_Of_Enquiry = customerInfo.UtmCustomDetails1; |
||||
|
|
||||
|
} |
||||
|
if (!string.IsNullOrEmpty(customerInfo.UtmCustomDetails2)) |
||||
|
{ |
||||
|
mx_Enquiry_Sub_source = customerInfo.UtmCustomDetails2; |
||||
|
|
||||
|
} |
||||
|
if (customerInfo.IsRegisterInterestRequest || string.IsNullOrWhiteSpace(customerInfo.DealerCode) || string.IsNullOrWhiteSpace(customerInfo.ModelCode)) |
||||
|
{ |
||||
|
enquiryClassification = "Cold"; |
||||
|
autoModel = "No"; |
||||
|
customerInfo.DealerCode = string.Empty; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
enquiryClassification = "Hot"; |
||||
|
autoModel = "Yes"; |
||||
|
} |
||||
|
if (customerInfo.Status != "Successful") |
||||
|
{ |
||||
|
customerInfo.Status = string.Empty; |
||||
|
customerInfo.BookingId = string.Empty; |
||||
|
customerInfo.CCTransactionId = string.Empty; |
||||
|
customerInfo.ReceiptId = string.Empty; |
||||
|
customerInfo.AmountPaid = string.Empty; |
||||
|
isSuccessBooking = "False"; |
||||
|
} |
||||
|
string pincode = customerInfo.PinCode; |
||||
|
//default pincode value, incase pincode column is empty for the record
|
||||
|
if (string.IsNullOrEmpty(pincode)) |
||||
|
pincode = "400070"; |
||||
|
|
||||
|
string message = "{\"bu\": \"PB\", \"model_Code\": \"" + customerInfo.ModelCode + "\"," + |
||||
|
"\"color\": \"" + customerInfo.ColorCode + "\"," + |
||||
|
"\"customer_Name\": \"" + customerInfo.CustomerName + "\"" + |
||||
|
", \"location_of_the_customer\": \"\", \"dealer_Code\": \"" + customerInfo.DealerCode + "\", " + |
||||
|
"\"mobile\": \"" + customerInfo.MobileNumber + "\"" + |
||||
|
", \"otp_verified\": \"true\", \"pincode\": \"" + pincode + "\"," + |
||||
|
" \"enquiry_mode\": \"Digital\"" + |
||||
|
", \"source\": \"" + mx_Source_Of_Enquiry + "\", \"sub_source\": \"" + mx_Enquiry_Sub_source + "\"," + |
||||
|
" \"referral_URL\": \"\"" + |
||||
|
", \"composite_Key\": \"" + mx_Composite_Key + "\", \"enquiry_Classification\": \"" + enquiryClassification + "\"," + |
||||
|
" \"auto_model\": \"" + autoModel + "\"" + |
||||
|
", \"bu_Sub_type\": \"\", \"sitcore_Booking_ID\": \"" + customerInfo.BookingId + "\", " + |
||||
|
"\"booking_Status\": \"" + customerInfo.Status + "\"" + |
||||
|
", \"cc_Avenue_Transaction_ID\": \"" + customerInfo.CCTransactionId + "\"," + |
||||
|
" \"booking_receipt_Number\": \"" + customerInfo.ReceiptId + "\"," + |
||||
|
" \"booking_amount_TRM\": \"" + customerInfo.AmountPaid + "\"," + |
||||
|
" \"test_ride_date\": \"\", \"test_ride_slot\": \"\"" + |
||||
|
", \"test_ride_location\": \"\"," + |
||||
|
"\"utmSource\": \"" + utmSource + "\", \"utmMedium\":\"" + utmMedium + "\"," + |
||||
|
" \"sourceCampaign\": \"" + sourceCampaign + "\", \"utmContent\":\"" + utmContent + "\"," + |
||||
|
" \"consentToWhatsapp\": \"" + customerInfo.IsWhatsappOptIn + "\",\"leadPlatform\": \"" + leadPlatform + "\" }"; |
||||
|
|
||||
|
|
||||
|
|
||||
|
string authToken = await MulesoftTokenApi.FetchToken(); |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(authToken)) |
||||
|
{ |
||||
|
string password = GenerateRandomString.GenerateString(32); |
||||
|
string encstring = AESEncryption.ReturnEncKey(password, message); |
||||
|
|
||||
|
var plainTextBytes = Encoding.UTF8.GetBytes(password); |
||||
|
string encKeyToHeader = Convert.ToBase64String(plainTextBytes); |
||||
|
|
||||
|
// var url = "";
|
||||
|
var response2 = await MuleSoftIntegration.ReturnMuleSoftResponse(ClientHandler, encstring, bookingApiUrl, authToken, encKeyToHeader); |
||||
|
|
||||
|
LeadData _leadData = DecryptBookingApi(response2); |
||||
|
await Repository.UpdateMulesoftResponse(customerInfo.BuId, customerInfo.RecordId, customerInfo.BookingId, message, isSuccessBooking, _leadData); |
||||
|
return new Response(customerInfo.BuId, 0, true, "true", "", ""); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- CallBookingApi:- " + ex.StackTrace.ToString()); |
||||
|
} |
||||
|
return new Response(customerInfo.BuId, 0, false, "false", "", ""); |
||||
|
} |
||||
|
|
||||
|
public async Task<List<MulesoftCustomerInfoDto>> GetDataForLsqPush(int buId) |
||||
|
{ |
||||
|
return await Repository.GetDataForLsqPush(buId); |
||||
|
} |
||||
|
|
||||
|
private LeadData DecryptBookingApi(HttpResponseMessage response) |
||||
|
{ |
||||
|
LeadData _leadData = new LeadData(); |
||||
|
JObject obj = JObject.Parse(response.Content.ReadAsStringAsync().Result); |
||||
|
try |
||||
|
{ |
||||
|
if (response.StatusCode.ToString() == "OK") |
||||
|
{ |
||||
|
if (obj["encData"] != null && !string.IsNullOrEmpty(Convert.ToString(obj["encData"]))) |
||||
|
{ |
||||
|
string pass = string.Empty; |
||||
|
string encResult2 = Convert.ToString(obj["encData"]); |
||||
|
// get enckey from response header
|
||||
|
if (response.Headers.Contains("Enckey")) |
||||
|
{ |
||||
|
var decodekey = response.Headers.GetValues("Enckey").First(); |
||||
|
if (!string.IsNullOrEmpty(decodekey)) |
||||
|
{ |
||||
|
var base64EncodedBytes = Convert.FromBase64String(decodekey); |
||||
|
pass = Encoding.UTF8.GetString(base64EncodedBytes); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Decrypt result by encKey
|
||||
|
if (!string.IsNullOrEmpty(encResult2)) |
||||
|
{ |
||||
|
_leadData.ApiResponse = AESEncryption.DecryptString(encResult2, pass); |
||||
|
|
||||
|
_logger.LogInformation("DecryptBookingApi decrpted message: " + _leadData.ApiResponse); |
||||
|
|
||||
|
JObject obj1 = JObject.Parse(_leadData.ApiResponse); |
||||
|
string lead_status_code = (string)obj1["statusCode"]; |
||||
|
|
||||
|
if (lead_status_code == "200" && obj1["message"]?["IsSuccess"] != null) |
||||
|
{ |
||||
|
_leadData.Lead_status = (string)obj1["message"]["IsSuccess"]; |
||||
|
_leadData.LeadResponseStatus = lead_status_code; |
||||
|
if (_leadData.Lead_status.ToLower().Equals("true")) |
||||
|
{ |
||||
|
_leadData.Lead_transferred = "y"; |
||||
|
string[] ids = ((string)obj1["message"]["Value"]).Split(' '); |
||||
|
if (ids.Length == 1) |
||||
|
ids = ((string)obj1["message"]["Value"]).Split(','); |
||||
|
if (ids.Length > 0) |
||||
|
_leadData.Prospect_id = ids[0]; |
||||
|
if (ids.Length > 1) |
||||
|
_leadData.Opportunity_id = ids[1]; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
_leadData.Lead_transferred = "n"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
_leadData.Lead_transferred = "n"; |
||||
|
_leadData.Lead_status = "Failure"; |
||||
|
_leadData.ApiResponse = ((int)response.StatusCode) + JsonConvert.SerializeObject(obj, Formatting.None); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- DecryptBookingApi:- " + ex.StackTrace.ToString()); |
||||
|
} |
||||
|
return _leadData; |
||||
|
} |
||||
|
|
||||
|
private async Task<MulesoftResponse> ValidateMuleSoftResponse(int buId, HttpResponseMessage response2) |
||||
|
{ |
||||
|
JObject obj = JObject.Parse(await response2.Content.ReadAsStringAsync()); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
if (response2.StatusCode.ToString() == "OK") |
||||
|
{ |
||||
|
if (obj["encData"] != null && !string.IsNullOrWhiteSpace(Convert.ToString(obj["encData"]))) |
||||
|
{ |
||||
|
string pass = string.Empty; |
||||
|
string encResult2 = Convert.ToString(obj["encData"]); |
||||
|
// get enckey from response header
|
||||
|
if (response2.Headers.Contains("encKey")) |
||||
|
{ |
||||
|
var decodekey = response2.Headers.GetValues("encKey").First(); |
||||
|
if (!string.IsNullOrEmpty(decodekey)) |
||||
|
{ |
||||
|
var base64EncodedBytes = Convert.FromBase64String(decodekey); |
||||
|
pass = Encoding.UTF8.GetString(base64EncodedBytes); |
||||
|
} |
||||
|
} |
||||
|
// Decrypt result by encKey
|
||||
|
if (!string.IsNullOrWhiteSpace(encResult2)) |
||||
|
{ |
||||
|
string decrypted = AESEncryption.DecryptString(encResult2, pass); |
||||
|
JObject obj1 = JObject.Parse(decrypted); |
||||
|
return new MulesoftResponse(buId, 0, true, JsonConvert.SerializeObject(obj1, Formatting.None), "Dealer Found", ""); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else if (((int)response2.StatusCode) == 404) |
||||
|
{ |
||||
|
return new MulesoftResponse(buId, 0, true, JsonConvert.SerializeObject(obj, Formatting.None), "No Dealer Found", ""); |
||||
|
} |
||||
|
else if (((int)response2.StatusCode) == 401) |
||||
|
{ |
||||
|
return new MulesoftResponse(buId, 0, true, JsonConvert.SerializeObject(obj, Formatting.None), Convert.ToString(obj["error"]), ""); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return new MulesoftResponse(buId, 0, false, JsonConvert.SerializeObject(obj, Formatting.None), "System Down" + JsonConvert.SerializeObject(obj, Formatting.None), ""); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- ValidateMuleSoftResponse:- " + ex.StackTrace.ToString()); |
||||
|
} |
||||
|
return new MulesoftResponse(buId, 0, false, JsonConvert.SerializeObject(obj, Formatting.None), "System Down" + JsonConvert.SerializeObject(obj, Formatting.None), ""); |
||||
|
} |
||||
|
|
||||
|
private async Task<MulesoftResponse> DecryptDealerDetail(int buId, HttpResponseMessage response2) |
||||
|
{ |
||||
|
JObject obj = JObject.Parse(await response2.Content.ReadAsStringAsync()); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
if (response2.StatusCode.ToString() == "OK") |
||||
|
{ |
||||
|
if (obj["encData"] != null && !string.IsNullOrWhiteSpace(Convert.ToString(obj["encData"]))) |
||||
|
{ |
||||
|
string pass = string.Empty; |
||||
|
string encResult2 = Convert.ToString(obj["encData"]); |
||||
|
// get enckey from response header
|
||||
|
if (response2.Headers.Contains("encKey")) |
||||
|
{ |
||||
|
var decodekey = response2.Headers.GetValues("encKey").First(); |
||||
|
if (!string.IsNullOrEmpty(decodekey)) |
||||
|
{ |
||||
|
var base64EncodedBytes = Convert.FromBase64String(decodekey); |
||||
|
pass = Encoding.UTF8.GetString(base64EncodedBytes); |
||||
|
} |
||||
|
} |
||||
|
// Decrypt result by encKey
|
||||
|
if (!string.IsNullOrWhiteSpace(encResult2)) |
||||
|
{ |
||||
|
string decrypted = AESEncryption.DecryptString(encResult2, pass); |
||||
|
JObject obj1 = JObject.Parse(decrypted); |
||||
|
if (obj1 != null) |
||||
|
{ |
||||
|
JToken jArrResultData = (JToken)obj1["Data"]; |
||||
|
if (jArrResultData != null) |
||||
|
{ |
||||
|
DealerDetailDto dto = new DealerDetailDto(); |
||||
|
dto.BuId = buId; |
||||
|
dto.DealerCode = (JValue)jArrResultData["Code"] != null ? Convert.ToString(((JValue)jArrResultData["Code"]).Value) : "0"; |
||||
|
dto.Address1 = (JValue)jArrResultData["AddressLine1"] != null ? Convert.ToString(((JValue)jArrResultData["AddressLine1"]).Value) : "0"; |
||||
|
dto.Address2 = (JValue)jArrResultData["AddressLine2"] != null ? Convert.ToString(((JValue)jArrResultData["AddressLine2"]).Value) : "0"; |
||||
|
dto.City = (JValue)jArrResultData["CityName"] != null ? Convert.ToString(((JValue)jArrResultData["CityName"]).Value) : "0"; |
||||
|
dto.State = (JValue)jArrResultData["StateName"] != null ? Convert.ToString(((JValue)jArrResultData["StateName"]).Value) : "0"; |
||||
|
dto.Zip = (JValue)jArrResultData["Zip"] != null ? Convert.ToString(((JValue)jArrResultData["Zip"]).Value) : "0"; |
||||
|
dto.DisplayName = (JValue)jArrResultData["DisplayName"] != null ? Convert.ToString(((JValue)jArrResultData["DisplayName"]).Value) : "0"; |
||||
|
dto.ContactCard = (JValue)jArrResultData["ContactCard"] != null ? Convert.ToString(((JValue)jArrResultData["ContactCard"]).Value) : "0"; |
||||
|
dto.SalesPersonMail = (JValue)jArrResultData["SalesPersonEmail"] != null ? Convert.ToString(((JValue)jArrResultData["SalesPersonEmail"]).Value) : "0"; |
||||
|
dto.SaleMobileNumber = (JValue)jArrResultData["SalesPersonContact"] != null ? Convert.ToString(((JValue)jArrResultData["SalesPersonContact"]).Value) : "0"; |
||||
|
dto.EcomSalesAddress = (JValue)jArrResultData["EcomSalesAddress"] != null ? Convert.ToString(((JValue)jArrResultData["EcomSalesAddress"]).Value) : "0"; |
||||
|
await Repository.InsertAndUpdateDealerRecord(dto); |
||||
|
return new MulesoftResponse(buId, 0, true, dto.Zip, "Dealer Detail Updated", ""); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else if (((int)response2.StatusCode) == 404) |
||||
|
{ |
||||
|
return new MulesoftResponse(buId, 0, true, JsonConvert.SerializeObject(obj, Formatting.None), "No Dealer Found", ""); |
||||
|
|
||||
|
} |
||||
|
else if (((int)response2.StatusCode) == 401) |
||||
|
{ |
||||
|
return new MulesoftResponse(buId, 0, true, JsonConvert.SerializeObject(obj, Formatting.None), Convert.ToString(obj["error"]), ""); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return new MulesoftResponse(buId, 0, true, JsonConvert.SerializeObject(obj, Formatting.None), "System Down" + JsonConvert.SerializeObject(obj, Formatting.None), ""); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- DecryptDealerDetail:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return new MulesoftResponse(buId, 0, true, JsonConvert.SerializeObject(obj, Formatting.None), "System Down" + JsonConvert.SerializeObject(obj, Formatting.None), ""); |
||||
|
} |
||||
|
|
||||
|
private string GetUTMDetails(string referrerUrl, string utmName) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
Uri referrerUri = new(referrerUrl); |
||||
|
var query = referrerUri.Query.Replace("?", ""); |
||||
|
if (!string.IsNullOrWhiteSpace(query)) |
||||
|
{ |
||||
|
var dict = query.Split('&').Select(q => q.Split('=')).ToDictionary(k => k[0], v => v[1]); |
||||
|
|
||||
|
if (dict.ContainsKey(utmName)) |
||||
|
return dict[utmName]; |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Api:- GetUTMDetails:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return ""; |
||||
|
} |
||||
|
} |
@ -0,0 +1,68 @@ |
|||||
|
using DealerSelection.Api.CommonUtil; |
||||
|
using DealerSelection.Api.Interface; |
||||
|
using DealerSelection.Api.Models; |
||||
|
using DealerSelection.Common.Interfaces.HttpClient; |
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
|
||||
|
namespace DealerSelection.Api; |
||||
|
|
||||
|
public class MulesoftTokenApi : IMulesoftTokenApi |
||||
|
{ |
||||
|
private readonly ILogger _logger; |
||||
|
private readonly IMemoryCache cache; |
||||
|
IHttpClientHandler ClientHandler { get; } |
||||
|
|
||||
|
public MulesoftTokenApi(IMemoryCache cache, IHttpClientHandler clientHandler |
||||
|
, ILogger<MulesoftTokenApi> logger) |
||||
|
{ |
||||
|
this.cache = cache; |
||||
|
ClientHandler = clientHandler; |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
public async Task<string> FetchToken() |
||||
|
{ |
||||
|
string token = string.Empty; |
||||
|
try |
||||
|
{ |
||||
|
// if cache doesn't contain
|
||||
|
// an entry called TOKEN
|
||||
|
// error handling mechanism is mandatory
|
||||
|
if (!cache.TryGetValue("TOKEN", out token)) |
||||
|
{ |
||||
|
var tokenmodel = await GetTokenFromApi(); |
||||
|
// keep the value within cache for
|
||||
|
// given amount of time
|
||||
|
// if value is not accessed within the expiry time
|
||||
|
// delete the entry from the cache
|
||||
|
if (tokenmodel.ExpiresIn > 0) |
||||
|
{ |
||||
|
var options = new MemoryCacheEntryOptions() |
||||
|
.SetAbsoluteExpiration( |
||||
|
TimeSpan.FromSeconds(tokenmodel.ExpiresIn - 300)); |
||||
|
|
||||
|
cache.Set("TOKEN", tokenmodel.Value, options); |
||||
|
|
||||
|
token = tokenmodel.Value; |
||||
|
|
||||
|
_logger.LogInformation("MulesoftTokenApi at FetchToken - token Generated Successfully :- " + DateTime.Now); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("MulesoftTokenApi Api:- FetchToken:- " + ex.Message.ToString()); |
||||
|
} |
||||
|
return token; |
||||
|
} |
||||
|
|
||||
|
private async Task<MulesoftToken> GetTokenFromApi() |
||||
|
{ |
||||
|
// get api implementation happens here
|
||||
|
// returns a token model
|
||||
|
_logger.LogInformation("MulesoftTokenApi at GetTokenFromApi Started :- " + DateTime.Now); |
||||
|
MulesoftToken token = await MuleSoftIntegration.generateToken(ClientHandler); |
||||
|
return token; |
||||
|
} |
||||
|
} |
@ -0,0 +1,77 @@ |
|||||
|
using DealerSelection.Api.Infrastructure.CustomerDetail; |
||||
|
using DealerSelection.Api.Interface; |
||||
|
using DealerSelection.Api.Models; |
||||
|
using DealerSelection.Common.Exceptions; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System.Text.RegularExpressions; |
||||
|
|
||||
|
namespace DealerSelection.Api; |
||||
|
public class YellowAIApi : IYellowAIApi |
||||
|
{ |
||||
|
|
||||
|
private readonly ILogger _logger; |
||||
|
private IRepository CustomerDetailRepository { get; } |
||||
|
|
||||
|
public YellowAIApi(IRepository customerRepo, ILogger<YellowAIApi> logger) |
||||
|
{ |
||||
|
CustomerDetailRepository = customerRepo; |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public async Task UpdateSelectedDealer(CustomerDealerInfoRequest request) |
||||
|
{ |
||||
|
if (IsValidData(request.MobileNumber, request.DealerCode, request.DealerName)) |
||||
|
{ |
||||
|
var isDuplicate = await IsDuplicateMobileNumber(request.MobileNumber); |
||||
|
if (!isDuplicate) |
||||
|
{ |
||||
|
|
||||
|
//Push to LSQ then make it complete
|
||||
|
|
||||
|
|
||||
|
|
||||
|
//
|
||||
|
CustomerDealerInfoRequestDto dto = new CustomerDealerInfoRequestDto |
||||
|
{ |
||||
|
BuId = request.BuId, |
||||
|
RecordId = request.RecordId, |
||||
|
MobileNumber = request.MobileNumber, |
||||
|
ModelCode = request.ModelCode, |
||||
|
ModelName = request.ModelName, |
||||
|
ModelVariant = request.ModelVariant, |
||||
|
DealerName = request.DealerName, |
||||
|
DealerCode = request.DealerCode, |
||||
|
PinCode = request.PinCode, |
||||
|
Latitude = request.Latitude, |
||||
|
Longitude = request.Longitude, |
||||
|
DealerSelectionJobStatus = DealerSelectionJobStatus.Complete //Marking JobStatus Complete once we receive response from Yellow API
|
||||
|
}; |
||||
|
await CustomerDetailRepository.UpdateDealerDetail(dto); |
||||
|
} |
||||
|
else |
||||
|
_logger.LogWarning($"Duplicate MobileNumber exist. Data Details: {request.RequestDetail()}."); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
_logger.LogWarning($"Invalid data. Data Details: {request.RequestDetail()}."); |
||||
|
throw new ValidationException("Invalid data."); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static bool IsValidData(int mobileNumber, string dealerCode, string dealerName) |
||||
|
{ |
||||
|
bool valid = Regex.IsMatch(mobileNumber.ToString(), @"^[0-9]{10}$"); |
||||
|
|
||||
|
if (valid && string.IsNullOrWhiteSpace(dealerCode) && string.IsNullOrWhiteSpace(dealerName)) |
||||
|
valid = false; |
||||
|
|
||||
|
return valid; |
||||
|
} |
||||
|
|
||||
|
private async Task<bool> IsDuplicateMobileNumber(int mobileNumber) |
||||
|
{ |
||||
|
return await CustomerDetailRepository.IsDuplicateMobileNumber(mobileNumber); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
namespace DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
public class ExceptionBase : Exception |
||||
|
{ |
||||
|
protected ExceptionBase(string message) : base(message) |
||||
|
{ } |
||||
|
protected ExceptionBase(string message, Exception innerException) : base(message, innerException) |
||||
|
{ } |
||||
|
} |
@ -0,0 +1,92 @@ |
|||||
|
using DealerSelection.Common.Exceptions; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Mvc.Filters; |
||||
|
using System.Net; |
||||
|
|
||||
|
namespace DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
public class ExceptionFilterBase : ExceptionFilterAttribute, IExceptionFilter |
||||
|
{ |
||||
|
protected IDictionary<Type, HttpStatusCode> Mappings { get; } |
||||
|
public ExceptionFilterBase() |
||||
|
{ |
||||
|
Mappings = new Dictionary<Type, HttpStatusCode> |
||||
|
{ |
||||
|
{typeof(System.Security.Authentication.AuthenticationException), HttpStatusCode.Unauthorized }, |
||||
|
{typeof(System.Security.Authentication.InvalidCredentialException), HttpStatusCode.Unauthorized }, |
||||
|
{typeof(AuthorizationException), HttpStatusCode.Forbidden }, |
||||
|
{typeof(DataNotFoundException), HttpStatusCode.Forbidden }, |
||||
|
{typeof(DuplicateException), HttpStatusCode.Conflict }, |
||||
|
|
||||
|
{typeof(InvalidDataException), HttpStatusCode.BadRequest }, |
||||
|
{typeof(ValidationException), HttpStatusCode.BadRequest }, |
||||
|
{typeof(NullValueException), HttpStatusCode.BadRequest }, |
||||
|
{typeof(PartialSuccessException), HttpStatusCode.MultiStatus } |
||||
|
|
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public override void OnException(ExceptionContext context) |
||||
|
{ |
||||
|
Exception exception = context.Exception; |
||||
|
if (exception.StackTrace != null) |
||||
|
{ |
||||
|
string exceptionStack = exception.StackTrace.StandardizeText(true); |
||||
|
context.HttpContext.Request.Headers.Add("BajaBooking-Custom-ExceptionStack", exceptionStack); |
||||
|
} |
||||
|
|
||||
|
HttpStatusCode httpStatusCode = Mappings.ContainsKey(exception.GetType()) |
||||
|
? Mappings[exception.GetType()] : HttpStatusCode.InternalServerError; |
||||
|
|
||||
|
foreach (KeyValuePair<Type, HttpStatusCode> item in Mappings) |
||||
|
{ |
||||
|
if (exception.GetType().IsSubclassOf(item.Key) || exception.GetType() == item.Key) |
||||
|
{ |
||||
|
httpStatusCode = item.Value; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
if (context.Exception.InnerException != null) |
||||
|
context.HttpContext.Request.Headers.Add("BajaBooking-Custom-InnerException", context.Exception.InnerException.ToString().StandardizeText(true)); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
context.HttpContext.Request.Headers.Add("BajaBooking-Custom-InnerException", "Cannot add detailed error to header because: " + ex.Message); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
context.HttpContext.Request.Headers.Add("BajaBooking-Custom-InnerException", "Cannot add detailed error to header for unknown reason: " + ex.Message); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//if (ConfigurationHelper.GetSetting("IncludeErrorInResponse", false) || httpStatusCode != HttpStatusCode.InternalServerError)
|
||||
|
//{
|
||||
|
// AssignError(context, httpStatusCode, false, exception.Message);
|
||||
|
//}
|
||||
|
//else
|
||||
|
//{
|
||||
|
// context.HttpContext.Request.Headers.Add("BajaBooking-Custom-RealException", exception.Message.StandardizeText(false));
|
||||
|
//}
|
||||
|
} |
||||
|
private static void AssignError(ExceptionContext context, HttpStatusCode httpStatusCode, bool withNewLine, string? message = null, string? reason = null) |
||||
|
{ |
||||
|
reason ??= message; |
||||
|
string reasonPhrase = reason!.StandardizeText(withNewLine); |
||||
|
context.Result = new ContentResult { Content = reasonPhrase, StatusCode = (int)httpStatusCode, ContentType = "text/plain" }; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
public static class StringOps |
||||
|
{ |
||||
|
public static string StandardizeText(this string inp, bool withNewLine) |
||||
|
{ |
||||
|
if(withNewLine) |
||||
|
return inp.Replace("\r", "\r ").Replace("\n", "\n "); |
||||
|
return inp.Replace("\r", " ").Replace("\n", " "); |
||||
|
} |
||||
|
} |
@ -0,0 +1,235 @@ |
|||||
|
using DealerSelection.Common.Helpers; |
||||
|
using DealerSelection.Common.Middleware; |
||||
|
using Lamar; |
||||
|
using Lamar.Microsoft.DependencyInjection; |
||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer; |
||||
|
using Microsoft.AspNetCore.Builder; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Http.Json; |
||||
|
using Microsoft.AspNetCore.HttpOverrides; |
||||
|
using Microsoft.AspNetCore.Mvc.Formatters; |
||||
|
using Microsoft.AspNetCore.ResponseCompression; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.ApplicationInsights; |
||||
|
using Microsoft.IdentityModel.Tokens; |
||||
|
using Microsoft.OpenApi.Models; |
||||
|
using System.IO.Compression; |
||||
|
using System.Reflection; |
||||
|
using System.Text; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
public abstract class StartupBase |
||||
|
{ |
||||
|
public WebApplication CreateHostBuilder(string[] args) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
WebApplicationBuilder builder = WebApplication.CreateBuilder(args); |
||||
|
|
||||
|
builder.Host.UseLamar((context, registry) => |
||||
|
{ |
||||
|
registry.IncludeRegistry(CreateDIRegistry()); |
||||
|
registry.AddControllers(); |
||||
|
}); |
||||
|
|
||||
|
SetupService(builder.Services); |
||||
|
SetupSwaggerOptions(builder); |
||||
|
|
||||
|
#region AzureLogging
|
||||
|
|
||||
|
AzureLogging(builder); |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region JWT Authentication
|
||||
|
JWTAuthentication(builder); |
||||
|
#endregion
|
||||
|
|
||||
|
WebApplication app = builder.Build(); |
||||
|
app.UseResponseCompression(); |
||||
|
|
||||
|
app.UseRouting(); |
||||
|
|
||||
|
if (Configuration.ConfigurationHelper.GetSetting<string>("BrowseSwagger", true) == "True") |
||||
|
SetupSwagger(app); |
||||
|
|
||||
|
app.UseCors(x => x |
||||
|
//.WithOrigins("https://www.ktmindia.com", "https://www.triumphmotorcyclesindia.com") //Used for PROD
|
||||
|
.AllowAnyOrigin() //Only used for Development
|
||||
|
.AllowAnyMethod() |
||||
|
.AllowAnyHeader()); |
||||
|
|
||||
|
//app.UseMiddleware<UserAgentBlackListMiddleware>();
|
||||
|
app.UseMiddleware<SwaggerRootRoutingMiddleware>(); |
||||
|
//app.UseMiddleware<AuthenticationMiddleware>();
|
||||
|
// app.UseMiddleware<LoggingMiddleware>();
|
||||
|
|
||||
|
app.UseForwardedHeaders(new ForwardedHeadersOptions |
||||
|
{ |
||||
|
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto |
||||
|
}); |
||||
|
|
||||
|
app.UseAuthentication(); |
||||
|
app.UseAuthorization(); |
||||
|
app.UseStaticFiles(); |
||||
|
// app.MapControllers();
|
||||
|
|
||||
|
app.UseEndpoints(endpoints => |
||||
|
{ |
||||
|
endpoints.MapControllers(); |
||||
|
endpoints.MapHealthChecks("/health"); |
||||
|
}); |
||||
|
return app; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Console.WriteLine(ex); |
||||
|
throw; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void SetupService(IServiceCollection services) |
||||
|
{ |
||||
|
//Caching
|
||||
|
services.AddMemoryCache(); |
||||
|
|
||||
|
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); |
||||
|
services.AddMvc(options => options.Filters.Add(new ExceptionFilterBase())); |
||||
|
services.AddMvc(options => options.OutputFormatters.Add(new XmlSerializerOutputFormatter())); |
||||
|
|
||||
|
services.AddResponseCompression(options => |
||||
|
{ |
||||
|
options.Providers.Add<BrotliCompressionProvider>(); |
||||
|
options.EnableForHttps = true; |
||||
|
}); |
||||
|
|
||||
|
services.Configure<GzipCompressionProviderOptions>(options => |
||||
|
{ |
||||
|
options.Level = CompressionLevel.Optimal; |
||||
|
}); |
||||
|
|
||||
|
services.AddResponseCompression(options => |
||||
|
{ |
||||
|
options.Providers.Add<GzipCompressionProvider>(); |
||||
|
options.EnableForHttps = true; |
||||
|
}); |
||||
|
|
||||
|
services.AddEndpointsApiExplorer(); |
||||
|
services.AddControllers().AddXmlDataContractSerializerFormatters(); |
||||
|
services.AddHealthChecks(); |
||||
|
services.Configure<JsonOptions>(options => |
||||
|
{ |
||||
|
options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); |
||||
|
}); |
||||
|
services.Configure<Microsoft.AspNetCore.Mvc.JsonOptions>(options => |
||||
|
{ |
||||
|
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void AzureLogging(WebApplicationBuilder builder) |
||||
|
{ |
||||
|
builder.Logging.AddApplicationInsights( |
||||
|
configureTelemetryConfiguration: (config) => config.ConnectionString = |
||||
|
builder.Configuration.GetConnectionString("AZURE_LOGGING"), |
||||
|
configureApplicationInsightsLoggerOptions: (options) => { } |
||||
|
); |
||||
|
builder.Logging.AddFilter<ApplicationInsightsLoggerProvider>("traces", LogLevel.Trace); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private void JWTAuthentication(WebApplicationBuilder builder) |
||||
|
{ |
||||
|
List<string> audiences = new List<string>(); |
||||
|
string[] getAudiences = builder.Configuration["Jwt:Audience"].Split(','); |
||||
|
foreach (var audience in getAudiences) |
||||
|
{ |
||||
|
audiences.Add(audience); |
||||
|
} |
||||
|
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => |
||||
|
{ |
||||
|
options.TokenValidationParameters = new TokenValidationParameters |
||||
|
{ |
||||
|
ValidateIssuer = true, |
||||
|
ValidateAudience = true, |
||||
|
ValidateLifetime = true, |
||||
|
ValidateIssuerSigningKey = true, |
||||
|
ValidIssuer = builder.Configuration["Jwt:Issuer"], |
||||
|
ValidAudiences = new List<string>(audiences), |
||||
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) |
||||
|
}; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void SetupSwaggerOptions(WebApplicationBuilder builder) |
||||
|
{ |
||||
|
builder.Services.AddSwaggerGen(options => |
||||
|
{ |
||||
|
|
||||
|
SwashbuckleSchemaHelper schemaHelper = new SwashbuckleSchemaHelper(); |
||||
|
//handle checking for duplicate return types and makes the name unique
|
||||
|
options.CustomSchemaIds(type => schemaHelper.GetSchemaId(type)); |
||||
|
// options.DocumentFilter<HideMethodsExternallyFilter>();
|
||||
|
// options.OperationFilter<SecurityRequirementsOperationFilter>();
|
||||
|
|
||||
|
#region Swagger Customization For Authentication
|
||||
|
|
||||
|
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme |
||||
|
{ |
||||
|
Name = "Authorization", |
||||
|
Type = SecuritySchemeType.Http, |
||||
|
Scheme = "Bearer", |
||||
|
//Reference = new OpenApiReference { Id = "Bearer", Type = ReferenceType.SecurityScheme },
|
||||
|
BearerFormat = "JWT", |
||||
|
In = ParameterLocation.Header, |
||||
|
Description = "Please Enter a Valid JWT Token", |
||||
|
}); |
||||
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement |
||||
|
{ |
||||
|
{ |
||||
|
new OpenApiSecurityScheme |
||||
|
{ |
||||
|
Reference = new OpenApiReference |
||||
|
{ |
||||
|
Type=ReferenceType.SecurityScheme, |
||||
|
Id="Bearer" |
||||
|
} |
||||
|
}, |
||||
|
new string[]{} |
||||
|
} |
||||
|
}); |
||||
|
#endregion
|
||||
|
|
||||
|
options.SwaggerDoc("v1", new OpenApiInfo |
||||
|
{ |
||||
|
Version = "v1", |
||||
|
Title = "Dealer Selection API", |
||||
|
Description = "Web API for Dealer Selection Management" |
||||
|
}); |
||||
|
options.EnableAnnotations(); |
||||
|
|
||||
|
string xmlFileName = $"{Assembly.GetEntryAssembly()!.GetName().Name}.xml"; |
||||
|
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFileName)); |
||||
|
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private static void SetupSwagger(WebApplication app) |
||||
|
{ |
||||
|
app.UseSwagger(c => |
||||
|
{ |
||||
|
c.RouteTemplate = "help/ui/{documentName}/swagger.json"; |
||||
|
}); |
||||
|
app.UseSwaggerUI(c => |
||||
|
{ |
||||
|
c.SwaggerEndpoint("/help/ui/v1/swagger.json", "Sample API"); |
||||
|
c.RoutePrefix = "help/ui"; |
||||
|
c.InjectStylesheet("/CustomContent/SwaggerHeader.css"); |
||||
|
}); |
||||
|
} |
||||
|
protected abstract ServiceRegistry CreateDIRegistry(); |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
namespace DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
public abstract class WebApiConfigurationCfgBase |
||||
|
{ |
||||
|
|
||||
|
} |
@ -0,0 +1,102 @@ |
|||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using System.Configuration; |
||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace DealerSelection.Common.Configuration; |
||||
|
|
||||
|
public static class ConfigurationHelper |
||||
|
{ |
||||
|
public static int SetEnvironmentVariables(string settingsFile) |
||||
|
{ |
||||
|
IConfigurationRoot? config = LoadSettingsFile(settingsFile); |
||||
|
int count = 0; |
||||
|
|
||||
|
if (config != null) |
||||
|
{ |
||||
|
foreach (KeyValuePair<string, string?> pair in config.AsEnumerable()) |
||||
|
{ |
||||
|
if (pair.Value == null) |
||||
|
continue; |
||||
|
|
||||
|
Environment.SetEnvironmentVariable(pair.Key, pair.Value); |
||||
|
count++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return count; |
||||
|
} |
||||
|
|
||||
|
public static IConfigurationRoot? LoadSettingsFile(string settingsFile) |
||||
|
{ |
||||
|
string basePath = FindBaseLocation(settingsFile); |
||||
|
IConfigurationBuilder builder = new ConfigurationBuilder() |
||||
|
.SetBasePath(basePath) |
||||
|
.AddJsonFile(settingsFile); |
||||
|
|
||||
|
return builder.Build(); |
||||
|
} |
||||
|
|
||||
|
public static string GetConnectionString(string cxnName, string cfgFile = "connectionString.json") |
||||
|
{ |
||||
|
IConfigurationRoot? root = LoadSettingsFile(cfgFile); |
||||
|
string settings = root.GetConnectionString(cxnName); |
||||
|
if (!string.IsNullOrEmpty(settings)) |
||||
|
{ |
||||
|
return settings; |
||||
|
} |
||||
|
throw new ConfigurationErrorsException($"Connection stirng {cxnName} not found in connection strings cfg file {cfgFile}."); |
||||
|
} |
||||
|
private static string FindBaseLocation(string settingsFile) |
||||
|
{ |
||||
|
string?[] baseLocations = |
||||
|
{ |
||||
|
Directory.GetCurrentDirectory(), |
||||
|
AppDomain.CurrentDomain.BaseDirectory, |
||||
|
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) |
||||
|
}; |
||||
|
|
||||
|
foreach (string? baseLocation in baseLocations) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(baseLocation)) |
||||
|
continue; |
||||
|
string path = Path.Combine(baseLocation, settingsFile); |
||||
|
if (File.Exists(path)) |
||||
|
return baseLocation; |
||||
|
} |
||||
|
|
||||
|
return baseLocations[1]!; |
||||
|
} |
||||
|
|
||||
|
public static T? GetSetting<T>(string key, bool mustExist) |
||||
|
{ |
||||
|
return GetSetting(key, default(T), mustExist); |
||||
|
} |
||||
|
|
||||
|
public static T? GetSetting<T>(string key, T? defaultValue = default) |
||||
|
{ |
||||
|
return GetSetting(key, defaultValue, false); |
||||
|
} |
||||
|
|
||||
|
public static T GetSetting<T>(string key, T defaultValue, bool mustExist) |
||||
|
{ |
||||
|
string? valString = Environment.GetEnvironmentVariable(key); |
||||
|
|
||||
|
if (valString == null) |
||||
|
{ |
||||
|
if (mustExist) |
||||
|
{ |
||||
|
throw new ConfigurationErrorsException($"Setting {key} not found"); |
||||
|
} |
||||
|
return defaultValue; |
||||
|
} |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return (T)Convert.ChangeType(valString, typeof(T)); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw new ConfigurationErrorsException($"Settings {key} ('{valString}') cannot be converted to type {typeof(T).Name}", ex); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
|
||||
|
using System.Data.SqlClient; |
||||
|
using DealerSelection.Common.Configuration; |
||||
|
|
||||
|
namespace DealerSelection.Common.Data; |
||||
|
|
||||
|
public static class ConnectionHelper |
||||
|
{ |
||||
|
public static SqlConnection GetConnectionSync(string cxnName) |
||||
|
{ |
||||
|
SqlConnection cxn = GetConnection(cxnName); |
||||
|
cxn.Open(); |
||||
|
return cxn; |
||||
|
} |
||||
|
|
||||
|
public static SqlConnection GetConnectionAsync(string cxnName) |
||||
|
{ |
||||
|
SqlConnection cxn = GetConnection(cxnName); |
||||
|
cxn.OpenAsync(); |
||||
|
return cxn; |
||||
|
} |
||||
|
|
||||
|
private static SqlConnection GetConnection(string cxnName) |
||||
|
{ |
||||
|
string cxnString = GetConnectionString(cxnName); |
||||
|
|
||||
|
SqlConnection cxn = new SqlConnection(cxnString); |
||||
|
return cxn; |
||||
|
} |
||||
|
|
||||
|
public static string GetConnectionString(string cxnName) |
||||
|
{ |
||||
|
string cxnString = ConfigurationHelper.GetConnectionString(cxnName); |
||||
|
return cxnString; |
||||
|
} |
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
using System.Data.SqlClient; |
||||
|
|
||||
|
namespace DealerSelection.Common.Data.Dapper; |
||||
|
|
||||
|
public class RepositoryBaseDapperAsync : RepositoryBaseDIAsync |
||||
|
{ |
||||
|
public RepositoryBaseDapperAsync(string cxnName) : base(cxnName) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
protected async Task<SqlConnection> OpenCxnWithMappingAsync<T>() |
||||
|
{ |
||||
|
Task<SqlConnection> cxnTask = OpenCxnAsync(); |
||||
|
SetTypeMap<T>(); |
||||
|
|
||||
|
return await cxnTask; |
||||
|
} |
||||
|
|
||||
|
protected void SetTypeMap<T>() |
||||
|
{ |
||||
|
TypeMapHelper.SetTypeMap<T>(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
using System.Data.SqlClient; |
||||
|
|
||||
|
namespace DealerSelection.Common.Data.Dapper; |
||||
|
|
||||
|
public class RepositoryBaseDapperSync : RepositoryBaseDISync |
||||
|
{ |
||||
|
public RepositoryBaseDapperSync(string cxnName) : base(cxnName) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
protected SqlConnection OpenCxnWithMappingSync<T>() |
||||
|
{ |
||||
|
SqlConnection cxn = OpenCxnSync(); |
||||
|
SetTypeMap<T>(); |
||||
|
|
||||
|
return cxn; |
||||
|
} |
||||
|
|
||||
|
protected void SetTypeMap<T>() |
||||
|
{ |
||||
|
TypeMapHelper.SetTypeMap<T>(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
using DealerSelection.Common.Entity; |
||||
|
using Dapper; |
||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace DealerSelection.Common.Data.Dapper; |
||||
|
|
||||
|
public static class TypeMapHelper |
||||
|
{ |
||||
|
public static void SetTypeMap<T>() |
||||
|
{ |
||||
|
CustomPropertyTypeMap map = new CustomPropertyTypeMap( |
||||
|
typeof(T), |
||||
|
PropertySelector); |
||||
|
SqlMapper.SetTypeMap(typeof(T), map); |
||||
|
} |
||||
|
private static PropertyInfo PropertySelector(Type type, string columnName) |
||||
|
{ |
||||
|
PropertyInfo[] properties = type.GetProperties(); |
||||
|
return properties.FirstOrDefault( |
||||
|
prop => prop.Name.Equals(columnName, StringComparison.OrdinalIgnoreCase) |
||||
|
|| columnName.Equals(GetColumnFromAttribute(prop), StringComparison.OrdinalIgnoreCase)); |
||||
|
} |
||||
|
public static string GetColumnFromAttribute(MemberInfo member) |
||||
|
{ |
||||
|
if (member == null) return null; |
||||
|
FieldMapAttribute attrib = (FieldMapAttribute)Attribute.GetCustomAttribute( |
||||
|
member, typeof(FieldMapAttribute), true); |
||||
|
return attrib?.DbFieldName; |
||||
|
} |
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
using DealerSelection.Common.Exceptions; |
||||
|
using DealerSelection.Common.Interfaces.Data; |
||||
|
using System.Data.SqlClient; |
||||
|
|
||||
|
namespace DealerSelection.Common.Data; |
||||
|
|
||||
|
public abstract class RepositoryBaseDIAsync : RepositoryDIBase, IRepositoryDIAsync |
||||
|
{ |
||||
|
public RepositoryBaseDIAsync(string cxnName) : base(cxnName) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public async Task<SqlConnection> OpenCxnAsync() |
||||
|
{ |
||||
|
SqlConnection cxn = new SqlConnection(CxnString); |
||||
|
try |
||||
|
{ |
||||
|
await cxn.OpenAsync(); |
||||
|
} |
||||
|
catch (SqlException ex) |
||||
|
{ |
||||
|
foreach(SqlError error in ex.Errors) |
||||
|
{ |
||||
|
if(error.Number == 53) |
||||
|
{ |
||||
|
throw new DbConnectionException($"DB Connection error for CxnString: {CxnString}. Exception: {ex}"); |
||||
|
} |
||||
|
} |
||||
|
throw; |
||||
|
} |
||||
|
|
||||
|
return cxn; |
||||
|
} |
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
using DealerSelection.Common.Exceptions; |
||||
|
using DealerSelection.Common.Interfaces.Data; |
||||
|
using System.Data.SqlClient; |
||||
|
|
||||
|
namespace DealerSelection.Common.Data; |
||||
|
|
||||
|
public abstract class RepositoryBaseDISync : RepositoryDIBase, IRepositoryDISync |
||||
|
{ |
||||
|
public RepositoryBaseDISync(string cxnName) : base(cxnName) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public SqlConnection OpenCxnSync() |
||||
|
{ |
||||
|
SqlConnection cxn = new SqlConnection(CxnString); |
||||
|
try |
||||
|
{ |
||||
|
cxn.Open(); |
||||
|
} |
||||
|
catch (SqlException ex) |
||||
|
{ |
||||
|
foreach(SqlError error in ex.Errors) |
||||
|
{ |
||||
|
if(error.Number == 53) |
||||
|
{ |
||||
|
throw new DbConnectionException($"DB Connection error for CxnString: {CxnString}. Exception: {ex}"); |
||||
|
} |
||||
|
} |
||||
|
throw; |
||||
|
} |
||||
|
|
||||
|
return cxn; |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Common.Data; |
||||
|
|
||||
|
public abstract class RepositoryDIBase |
||||
|
{ |
||||
|
public string CxnString { get; } |
||||
|
protected RepositoryDIBase(string cxnName) |
||||
|
{ |
||||
|
CxnString = ConnectionHelper.GetConnectionString(cxnName); |
||||
|
} |
||||
|
} |
@ -0,0 +1,56 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
||||
|
<NoWarn>1701;1702;8603;1822;8602;8604</NoWarn> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> |
||||
|
<NoWarn>1701;1702;8603;1822;8602;8604</NoWarn> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="BouncyCastle.NetCore" Version="1.9.0" /> |
||||
|
<PackageReference Include="Dapper" Version="2.1.15" /> |
||||
|
<PackageReference Include="iTextSharp" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="itextsharp.xmlworker" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="Lamar" Version="12.0.2" /> |
||||
|
<PackageReference Include="Lamar.Microsoft.DependencyInjection" Version="12.0.0" /> |
||||
|
<PackageReference Include="Microsoft.AspNet.WebApi.Owin" Version="5.2.9" /> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.0" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.21.0" /> |
||||
|
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" /> |
||||
|
<PackageReference Include="Microsoft.Owin.Cors" Version="4.2.2" /> |
||||
|
<PackageReference Include="Microsoft.Owin.Host.SystemWeb" Version="4.2.2" /> |
||||
|
<PackageReference Include="Microsoft.Owin.Security.Jwt" Version="4.2.2" /> |
||||
|
<PackageReference Include="Microsoft.Owin.Security.OAuth" Version="4.2.2" /> |
||||
|
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7"> |
||||
|
<PrivateAssets>all</PrivateAssets> |
||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> |
||||
|
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" /> |
||||
|
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" /> |
||||
|
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Compile Update="Logging\AzureLogHelper.cs"> |
||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory> |
||||
|
</Compile> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
@ -0,0 +1,24 @@ |
|||||
|
namespace DealerSelection.Common.Entity; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// An Attribute that provides a mapping between a property on an object and a fields in a database table.
|
||||
|
/// </summary>
|
||||
|
[AttributeUsage(AttributeTargets.Property)] |
||||
|
public sealed class FieldMapAttribute : Attribute |
||||
|
{ |
||||
|
readonly string _dbFieldName; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initialize a new FieldMapAttribute
|
||||
|
/// </summary>
|
||||
|
/// <param name="dbFieldName">Name of database field that this property represents</param>
|
||||
|
public FieldMapAttribute(string dbFieldName) |
||||
|
{ |
||||
|
_dbFieldName = dbFieldName; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Name of field that the perperty this attribute is attached to is mapped to.
|
||||
|
/// </summary>
|
||||
|
public string DbFieldName => _dbFieldName; |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
using DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
namespace DealerSelection.Common.Exceptions; |
||||
|
|
||||
|
public class AuthorizationException : ExceptionBase |
||||
|
{ |
||||
|
public AuthorizationException(string message) : base(message) { } |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
using DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
namespace DealerSelection.Common.Exceptions; |
||||
|
|
||||
|
public class DataNotFoundException : ExceptionBase |
||||
|
{ |
||||
|
public DataNotFoundException(string message) : base(message) { } |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
|
||||
|
using DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
namespace DealerSelection.Common.Exceptions; |
||||
|
|
||||
|
public class DbConnectionException : ExceptionBase |
||||
|
{ |
||||
|
public DbConnectionException(string message) : base(message) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public DbConnectionException(string message, Exception innerException) : base(message, innerException) |
||||
|
{ |
||||
|
} |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
using DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
namespace DealerSelection.Common.Exceptions; |
||||
|
|
||||
|
public class DuplicateException : ExceptionBase |
||||
|
{ |
||||
|
public DuplicateException(string message) : base(message) { } |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
using DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
namespace DealerSelection.Common.Exceptions; |
||||
|
|
||||
|
public class NullValueException : ExceptionBase |
||||
|
{ |
||||
|
public NullValueException(string message) : base(message) { } |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
using DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
namespace DealerSelection.Common.Exceptions; |
||||
|
|
||||
|
public class PartialSuccessException : ExceptionBase |
||||
|
{ |
||||
|
public PartialSuccessException(string message) : base(message) { } |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
using DealerSelection.Common.CommonBaseClass; |
||||
|
|
||||
|
namespace DealerSelection.Common.Exceptions; |
||||
|
|
||||
|
public class ValidationException : ExceptionBase |
||||
|
{ |
||||
|
public ValidationException(string message) : base(message) { } |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
namespace DealerSelection.Common.Helpers; |
||||
|
|
||||
|
public class SwaggerCfg |
||||
|
{ |
||||
|
public string? Name { get; set; } |
||||
|
public string? Title { get; set; } |
||||
|
public string? Description { get; set; } |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
namespace DealerSelection.Common.Helpers; |
||||
|
|
||||
|
public class SwashbuckleSchemaHelper |
||||
|
{ |
||||
|
private readonly Dictionary<string, int> _schemaNameRepetition = new (); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Eliminate the case where more than one method returns the same type in different controllers
|
||||
|
/// swagger documentation to fail
|
||||
|
/// </summary>
|
||||
|
/// <param name="modelType"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public string GetSchemaId(Type modelType) |
||||
|
{ |
||||
|
string id = DefaultSchemaIdSelector (modelType); |
||||
|
|
||||
|
if(!_schemaNameRepetition.ContainsKey(id)) |
||||
|
_schemaNameRepetition.Add(id, 0); |
||||
|
|
||||
|
int count = _schemaNameRepetition[id] + 1; |
||||
|
_schemaNameRepetition[id] = count; |
||||
|
|
||||
|
return $"{id}{(count > 1 ? count.ToString() : "")}"; |
||||
|
} |
||||
|
|
||||
|
private string DefaultSchemaIdSelector(Type modelType) |
||||
|
{ |
||||
|
if (!modelType.IsConstructedGenericType) |
||||
|
return modelType.Name.Replace("[]", "Array"); |
||||
|
|
||||
|
string prefix = modelType.GetGenericArguments() |
||||
|
.Select(genericArg => DefaultSchemaIdSelector(genericArg)) |
||||
|
.Aggregate((previous, current) => previous + current); |
||||
|
|
||||
|
return prefix + modelType.Name.Split('`').First(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
using DealerSelection.Common.Interfaces.HttpClient; |
||||
|
|
||||
|
namespace DealerSelection.Common.HttpClient; |
||||
|
|
||||
|
public class MyHttpClientHandler : IHttpClientHandler |
||||
|
{ |
||||
|
public System.Net.Http.HttpClient GetHttpClient() |
||||
|
{ |
||||
|
var handler = new SocketsHttpHandler |
||||
|
{ |
||||
|
PooledConnectionLifetime = TimeSpan.FromMinutes(15) // Recreate every 15 minutes
|
||||
|
}; |
||||
|
|
||||
|
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient(handler); |
||||
|
|
||||
|
client.DefaultRequestHeaders.Accept.Clear(); |
||||
|
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); |
||||
|
|
||||
|
return client; |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
using System.Data.SqlClient; |
||||
|
|
||||
|
namespace DealerSelection.Common.Interfaces.Data; |
||||
|
|
||||
|
public interface IRepositoryDIAsync |
||||
|
{ |
||||
|
string CxnString { get; } |
||||
|
Task<SqlConnection> OpenCxnAsync(); |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
using System.Data.SqlClient; |
||||
|
|
||||
|
namespace DealerSelection.Common.Interfaces.Data; |
||||
|
|
||||
|
public interface IRepositoryDISync |
||||
|
{ |
||||
|
string CxnString { get; } |
||||
|
SqlConnection OpenCxnSync(); |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
|
||||
|
|
||||
|
namespace DealerSelection.Common.Interfaces.HttpClient; |
||||
|
|
||||
|
public interface IHttpClientHandler |
||||
|
{ |
||||
|
System.Net.Http.HttpClient GetHttpClient(); |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
namespace DealerSelection.Common.Logging; |
||||
|
|
||||
|
public class ApiInfo |
||||
|
{ |
||||
|
public RequestInfo RequestInfo { get; set; } |
||||
|
//public CustomInfo CustomInfo { get; set; }
|
||||
|
public ResponseInfo ResponseInfo { get; set; } |
||||
|
public ApiInfo(string httpMethod, string uriAccessed, string hostName, DateTime startDate) |
||||
|
{ |
||||
|
RequestInfo = new RequestInfo(hostName, httpMethod, uriAccessed, startDate); |
||||
|
} |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return $"WebAPI {nameof(RequestInfo)}: {RequestInfo}, " + |
||||
|
//$"{nameof(CustomInfo)}: {CustomInfo}, " +
|
||||
|
$"{nameof(ResponseInfo)}: {ResponseInfo}"; |
||||
|
} |
||||
|
|
||||
|
public bool IsValid() |
||||
|
{ |
||||
|
return RequestInfo.BuId.GetValueOrDefault() > 0; |
||||
|
} |
||||
|
} |
@ -0,0 +1,82 @@ |
|||||
|
using DealerSelection.Common.Configuration; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.Net; |
||||
|
using System.Security.Cryptography; |
||||
|
using System.Text; |
||||
|
|
||||
|
namespace DealerSelection.Common.Logging; |
||||
|
|
||||
|
public static class AzureLogHelper |
||||
|
{ |
||||
|
private static string aZureWorkspaceId = ConfigurationHelper.GetSetting<string>("aZureWorkspaceId", true); |
||||
|
private static string aZureSharedKey = ConfigurationHelper.GetSetting<string>("aZureSharedKey", true); |
||||
|
private static string aZureLogType = ConfigurationHelper.GetSetting<string>("aZureLogType", true); |
||||
|
private static string aZureApiVersion = ConfigurationHelper.GetSetting<string>("aZureApiVersion", true); |
||||
|
|
||||
|
public static void LogMessage(string message) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
string azureLog = GetAzureLogFormatLog(message); |
||||
|
string requestUriString = $"https://{aZureWorkspaceId}.ods.opinsights.azure.com/api/logs?api-version={aZureApiVersion}"; |
||||
|
DateTime dateTime = DateTime.UtcNow; |
||||
|
string dateString = dateTime.ToString("r"); |
||||
|
string signature = GetSignature("POST", azureLog.Length, "application/json", dateString, "/api/logs"); |
||||
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUriString); |
||||
|
request.ContentType = "application/json"; |
||||
|
request.Method = "POST"; |
||||
|
request.Headers["Log-Type"] = aZureLogType; |
||||
|
request.Headers["x-ms-date"] = dateString; |
||||
|
request.Headers["Authorization"] = signature; |
||||
|
byte[] content = Encoding.UTF8.GetBytes(azureLog); |
||||
|
using (Stream requestStreamAsync = request.GetRequestStream()) |
||||
|
{ |
||||
|
requestStreamAsync.Write(content, 0, content.Length); |
||||
|
} |
||||
|
using (HttpWebResponse responseAsync = (HttpWebResponse)request.GetResponse()) |
||||
|
{ |
||||
|
if (responseAsync.StatusCode != HttpStatusCode.OK && responseAsync.StatusCode != HttpStatusCode.Accepted) |
||||
|
{ |
||||
|
Stream responseStream = responseAsync.GetResponseStream(); |
||||
|
if (responseStream != null) |
||||
|
{ |
||||
|
using (StreamReader streamReader = new StreamReader(responseStream)) |
||||
|
{ |
||||
|
// throw new Exception(streamReader.ReadToEnd());
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
// throw new UnexpectedDataException($" Bajaj Booking LogMessage: ", ex);
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static string GetAzureLogFormatLog(string inputMessage) |
||||
|
{ |
||||
|
string message = string.Empty; |
||||
|
if (!string.IsNullOrWhiteSpace(inputMessage)) |
||||
|
{ |
||||
|
message = JsonConvert.SerializeObject( |
||||
|
new |
||||
|
{ |
||||
|
id = Guid.NewGuid().ToString(), |
||||
|
datetime = DateTime.Now, |
||||
|
message = inputMessage |
||||
|
}).ToString(); |
||||
|
} |
||||
|
return message; |
||||
|
} |
||||
|
|
||||
|
private static string GetSignature(string method, int contentLength, string contentType, string date, string resource) |
||||
|
{ |
||||
|
string message = $"{method}\n{contentLength}\n{contentType}\nx-ms-date:{date}\n{resource}"; |
||||
|
byte[] bytes = Encoding.UTF8.GetBytes(message); |
||||
|
using (HMACSHA256 encryptor = new HMACSHA256(Convert.FromBase64String(aZureSharedKey))) |
||||
|
{ |
||||
|
return $"SharedKey {aZureWorkspaceId}:{Convert.ToBase64String(encryptor.ComputeHash(bytes))}"; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
|
||||
|
using Microsoft.Extensions.Primitives; |
||||
|
|
||||
|
namespace DealerSelection.Common.Logging; |
||||
|
|
||||
|
public class HttpHeaderHelper |
||||
|
{ |
||||
|
public static int? ExtractInt(string key, List<KeyValuePair<string, StringValues>> headers) |
||||
|
{ |
||||
|
int? res = null; |
||||
|
string? resString = Extract(key, headers); |
||||
|
if (resString == null) |
||||
|
{ |
||||
|
if(int.TryParse(resString, out int resTemp)) |
||||
|
res = resTemp; |
||||
|
} |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
public static string? Extract(string key, List<KeyValuePair<string, StringValues>> headers) |
||||
|
{ |
||||
|
string? res = null; |
||||
|
KeyValuePair<string, StringValues> header = headers.FirstOrDefault(h=> h.Key == key); |
||||
|
if (header.Value.Any()) |
||||
|
res = header.Value.FirstOrDefault(); |
||||
|
return res; |
||||
|
} |
||||
|
} |
@ -0,0 +1,127 @@ |
|||||
|
|
||||
|
using iTextSharp.text.log; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Http.Extensions; |
||||
|
using Microsoft.IO; |
||||
|
|
||||
|
namespace DealerSelection.Common.Logging; |
||||
|
|
||||
|
public class LoggingMiddleware |
||||
|
{ |
||||
|
public const string Key = "LoggingMiddlewareCfg"; |
||||
|
private const int ReadChunkBufferLength = 4096; |
||||
|
private const int MaxContentLength = 10 * 1024 * 1024; //10MB
|
||||
|
private RecyclableMemoryStreamManager MemoryStreamManager { get; set; } = null; |
||||
|
private readonly RequestDelegate RequestDelegate; |
||||
|
enum ErrorTypes |
||||
|
{ |
||||
|
Validation, |
||||
|
Error |
||||
|
}; |
||||
|
|
||||
|
public LoggingMiddleware(RequestDelegate requestDelegate) |
||||
|
{ |
||||
|
RequestDelegate = requestDelegate; |
||||
|
|
||||
|
MemoryStreamManager = new RecyclableMemoryStreamManager(); |
||||
|
} |
||||
|
|
||||
|
public async Task Invoke(HttpContext context, ILogger logger) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
ApiInfo loggingInfo = await ExtractInfoFromRequest(context.Request); |
||||
|
|
||||
|
Stream originalBodyStream = context.Request.Body; |
||||
|
using MemoryStream responseBody = MemoryStreamManager.GetStream(); |
||||
|
context.Response.Body = responseBody; |
||||
|
|
||||
|
await RequestDelegate(context); |
||||
|
|
||||
|
ExtractMessageHeaderIntoInfo(loggingInfo, context.Request); |
||||
|
|
||||
|
if(await ExtractResponseInfo(loggingInfo, context.Response, originalBodyStream, logger)) |
||||
|
{ |
||||
|
//logger.Info(loggingInfo.ToString());
|
||||
|
AzureLogHelper.LogMessage($"Api Incoming: {loggingInfo.ToString()}"); |
||||
|
} |
||||
|
} |
||||
|
catch { } |
||||
|
} |
||||
|
|
||||
|
private async Task<ApiInfo> ExtractInfoFromRequest(HttpRequest request) |
||||
|
{ |
||||
|
ApiInfo info = new ApiInfo(request.Method, request.GetDisplayUrl(),Environment.MachineName,DateTime.Now); |
||||
|
|
||||
|
if(request.ContentLength.GetValueOrDefault() > 0) |
||||
|
{ |
||||
|
request.EnableBuffering(); |
||||
|
|
||||
|
using MemoryStream requestStream = MemoryStreamManager.GetStream(); |
||||
|
await request.Body.CopyToAsync(requestStream); |
||||
|
info.RequestInfo.ContentBody = await ReadStreamInChunks(requestStream); |
||||
|
|
||||
|
request.Body.Position = 0; |
||||
|
} |
||||
|
return info; |
||||
|
} |
||||
|
|
||||
|
private async Task<string> ReadStreamInChunks(Stream stream) |
||||
|
{ |
||||
|
stream.Seek(0, SeekOrigin.Begin); |
||||
|
await using StringWriter textWriter = new StringWriter(); |
||||
|
using StreamReader reader = new StreamReader(stream); |
||||
|
char[] readChunk = new char[ReadChunkBufferLength]; |
||||
|
int readChunkLength; |
||||
|
do |
||||
|
{ |
||||
|
readChunkLength = await reader.ReadBlockAsync(readChunk, 0, ReadChunkBufferLength); |
||||
|
await textWriter.WriteAsync(readChunk, 0, readChunkLength); |
||||
|
} while (readChunkLength > 0); |
||||
|
return textWriter.ToString(); |
||||
|
} |
||||
|
|
||||
|
private async Task<bool> ExtractResponseInfo(ApiInfo loggingInfo, HttpResponse response, Stream originalBodyStream, ILogger logger) |
||||
|
{ |
||||
|
//loggingInfo.CustomInfo = new CustomInfo(response);
|
||||
|
if(loggingInfo.IsValid()) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
loggingInfo.ResponseInfo = new ResponseInfo(response); |
||||
|
response.Body.Seek(0, SeekOrigin.Begin); |
||||
|
|
||||
|
if(response.Body.Length < MaxContentLength) |
||||
|
loggingInfo.ResponseInfo.ContentBody = await new StreamReader(response.Body).ReadToEndAsync(); |
||||
|
else |
||||
|
loggingInfo.ResponseInfo.ContentBody = $"Size {response.Body.Length} too large to retrieve"; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
logger.Error($"Exception logging request {@loggingInfo}, error {@ex}"); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
loggingInfo.ResponseInfo.ContentType = response.Headers.ContentType.Any() ? string.Join(",", response.Headers.ContentType) : null; |
||||
|
} |
||||
|
response.Body.Seek(0, SeekOrigin.Begin); |
||||
|
|
||||
|
await response.Body.CopyToAsync(originalBodyStream); |
||||
|
return loggingInfo.IsValid(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private void ExtractMessageHeaderIntoInfo(ApiInfo apiInfo, HttpRequest request) |
||||
|
{ |
||||
|
//List<KeyValuePair<string, StringValues>> headers = request.Headers.ToList();
|
||||
|
//apiInfo.RequestInfo.BuId = HttpHeaderHelper.ExtractInt(CustomInfo.BuId, headers);
|
||||
|
//apiInfo.RequestInfo.RecordId = HttpHeaderHelper.ExtractInt(CustomInfo.RecordId, headers);
|
||||
|
//apiInfo.RequestInfo.SecurityContext = HttpHeaderHelper.ExtractInt(CustomInfo.SecurityContext, headers);
|
||||
|
//apiInfo.RequestInfo.InnerException = HttpHeaderHelper.ExtractInt(CustomInfo.InnerException, headers);
|
||||
|
//apiInfo.RequestInfo.ExceptionStack = HttpHeaderHelper.ExtractInt(CustomInfo.ExceptionStack, headers);
|
||||
|
//apiInfo.RequestInfo.RealException = HttpHeaderHelper.ExtractInt(CustomInfo.RealException, headers);
|
||||
|
//apiInfo.RequestInfo.BuId = HttpHeaderHelper.ExtractInt(CustomInfo.BuId, headers);
|
||||
|
//apiInfo.RequestInfo.BuId = HttpHeaderHelper.ExtractInt(CustomInfo.BuId, headers);
|
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Common.Logging; |
||||
|
|
||||
|
public class RequestInfo |
||||
|
{ |
||||
|
public RequestInfo(string hostName, string httpMethod, string uri, DateTime startDate) |
||||
|
{ |
||||
|
HostName = hostName; |
||||
|
HttpMethod = httpMethod; |
||||
|
Uri = uri; |
||||
|
StartDate = startDate; |
||||
|
} |
||||
|
|
||||
|
public string HostName { get; set; } |
||||
|
public string HttpMethod { get; set; } |
||||
|
public string Uri { get; set; } |
||||
|
public DateTime? StartDate { get; set; } |
||||
|
public int? RecordId { get; set; } |
||||
|
public int? BuId { get; set; } |
||||
|
public string? SecurityContext { get; set; } |
||||
|
public string? ContentBody { get; set; } |
||||
|
public string? ExceptionStack { get; set;} |
||||
|
public string? RealException { get; set; } |
||||
|
public string? InnerException { get; set; } |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return $"{nameof(BuId)}:{ BuId},{nameof(RecordId)}:{RecordId},{nameof(HostName)}:{HostName}," + |
||||
|
$"{nameof(HttpMethod)}:{HttpMethod},{nameof(Uri)}:{Uri},{nameof(StartDate)}:{StartDate}," + |
||||
|
$"{nameof(SecurityContext)}:{SecurityContext},{nameof(ContentBody)}:{ContentBody}," + |
||||
|
$"{nameof(ExceptionStack)}:{ExceptionStack},{nameof(RealException)}:{RealException},{nameof(InnerException)}:{InnerException}"; |
||||
|
} |
||||
|
|
||||
|
public string BuildRequestData() |
||||
|
{ |
||||
|
if(string.IsNullOrWhiteSpace(ContentBody)) |
||||
|
{ |
||||
|
return Uri; |
||||
|
} |
||||
|
return $"{Uri} with {ContentBody}"; |
||||
|
} |
||||
|
} |
@ -0,0 +1,37 @@ |
|||||
|
|
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using System.Net; |
||||
|
|
||||
|
namespace DealerSelection.Common.Logging; |
||||
|
|
||||
|
public class ResponseInfo |
||||
|
{ |
||||
|
public ResponseInfo(HttpResponse response) |
||||
|
{ |
||||
|
StatusCode = (HttpStatusCode)response.StatusCode; |
||||
|
|
||||
|
if (IsSuccessStatusCode) |
||||
|
IsSuccess = true; |
||||
|
else if (StatusCode >= HttpStatusCode.InternalServerError) |
||||
|
IsSuccess = false; |
||||
|
else |
||||
|
IsSuccess = null; |
||||
|
|
||||
|
TimeStamp = DateTime.Now; |
||||
|
} |
||||
|
|
||||
|
public bool IsSuccessStatusCode => (int)StatusCode >= 200 && (int)StatusCode <= 299; |
||||
|
public bool? IsSuccess { get; } |
||||
|
public HttpStatusCode StatusCode { get; } |
||||
|
public DateTime TimeStamp { get; } |
||||
|
public string? ContentBody { get; set; } |
||||
|
public string? ContentType { get; set; } |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return $"{nameof(StatusCode)}: {StatusCode}, " + |
||||
|
$"{nameof(TimeStamp)}: {TimeStamp}, " + |
||||
|
$"{nameof(ContentType)}: {ContentType} " |
||||
|
+ (string.IsNullOrWhiteSpace(ContentBody)? null : $", {nameof(ContentBody)}: {ContentBody} "); |
||||
|
} |
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
using Microsoft.AspNetCore.Http; |
||||
|
|
||||
|
namespace DealerSelection.Common.Middleware; |
||||
|
|
||||
|
public class SwaggerRootRoutingMiddleware |
||||
|
{ |
||||
|
public const string SwaggerUrl = "help/ui"; |
||||
|
private readonly RequestDelegate _requestDelegate; |
||||
|
private string PathBase { get; } |
||||
|
|
||||
|
public SwaggerRootRoutingMiddleware(RequestDelegate requestDelegate) |
||||
|
{ |
||||
|
_requestDelegate = requestDelegate; |
||||
|
PathBase = "/Booking/1.0"; |
||||
|
} |
||||
|
|
||||
|
public async Task Invoke(HttpContext context) |
||||
|
|
||||
|
{ |
||||
|
if(context.Request.Method == "GET" && context.Request.Path.Value!.Contains("/index.html", StringComparison.OrdinalIgnoreCase) |
||||
|
&& !context.Request.Path.Value.Contains($"{SwaggerUrl}/index.html", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
|
||||
|
#if DEBUG
|
||||
|
context.Response.Redirect($"{SwaggerUrl}/index.html"); |
||||
|
#else
|
||||
|
context.Response.Redirect($"{PathBase}/{SwaggerUrl}/index.html"); |
||||
|
#endif
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
await _requestDelegate(context); |
||||
|
} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
namespace DealerSelection.Common.Profiler |
||||
|
{ |
||||
|
public class PerformanceProfiler : IDisposable |
||||
|
{ |
||||
|
private bool disposed; |
||||
|
|
||||
|
public PerformanceProfiler(string operationName) |
||||
|
{ |
||||
|
Profiler.StartOperation($"Custom - {operationName}"); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
Dispose(true); |
||||
|
GC.SuppressFinalize(this); |
||||
|
} |
||||
|
|
||||
|
protected virtual void Dispose(bool disposing) |
||||
|
{ |
||||
|
if (!disposed) |
||||
|
{ |
||||
|
if (disposing) |
||||
|
{ |
||||
|
Profiler.EndOperation(); |
||||
|
} |
||||
|
|
||||
|
disposed = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
using System.Diagnostics; |
||||
|
|
||||
|
namespace DealerSelection.Common.Profiler |
||||
|
{ |
||||
|
public static class Profiler |
||||
|
{ |
||||
|
private static Stopwatch watch; |
||||
|
public static void StartOperation(string operationName) |
||||
|
{ |
||||
|
watch = System.Diagnostics.Stopwatch.StartNew(); |
||||
|
} |
||||
|
public static void EndOperation() |
||||
|
{ |
||||
|
watch.Stop(); |
||||
|
var timeToExecute = watch.ElapsedMilliseconds; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
using DealerSelection.Api; |
||||
|
using DealerSelection.Api.CommonUtil; |
||||
|
using DealerSelection.Api.Interface; |
||||
|
using DealerSelection.Common.HttpClient; |
||||
|
using DealerSelection.Common.Interfaces.HttpClient; |
||||
|
using Lamar; |
||||
|
|
||||
|
namespace DealerSelection.DependencyInjection; |
||||
|
|
||||
|
public class ApiRegistry : ServiceRegistry |
||||
|
{ |
||||
|
public ApiRegistry() |
||||
|
{ |
||||
|
|
||||
|
For<IJwtTokenApi>() |
||||
|
.Use<JwtTokenApi>() |
||||
|
.Singleton(); |
||||
|
|
||||
|
For<IAssignDealerApi>() |
||||
|
.Use<AssignDealerApi>() |
||||
|
.Singleton(); |
||||
|
|
||||
|
For<IMulesoftApi>() |
||||
|
.Use<MulesoftApi>() |
||||
|
.Singleton(); |
||||
|
|
||||
|
For<IHttpClientHandler>() |
||||
|
.Use<MyHttpClientHandler>() |
||||
|
.Singleton(); |
||||
|
For<IMulesoftTokenApi>() |
||||
|
.Use<MulesoftTokenApi>() |
||||
|
.Singleton(); |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<None Include="..\..\.editorconfig" Link=".editorconfig" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="BouncyCastle.NetCore" Version="1.9.0" /> |
||||
|
<PackageReference Include="iTextSharp" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="itextsharp.xmlworker" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="Lamar" Version="12.0.2" /> |
||||
|
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7"> |
||||
|
<PrivateAssets>all</PrivateAssets> |
||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
||||
|
</PackageReference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\DealerSelection.Api\DealerSelection.Api.csproj" /> |
||||
|
<ProjectReference Include="..\DealerSelection.Interface\DealerSelection.Api.Interface.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
@ -0,0 +1,11 @@ |
|||||
|
using Lamar; |
||||
|
namespace DealerSelection.DependencyInjection; |
||||
|
|
||||
|
public class DependencyInjectionBootStrapper : ServiceRegistry |
||||
|
{ |
||||
|
public DependencyInjectionBootStrapper() |
||||
|
{ |
||||
|
IncludeRegistry<InfrastructureRegistry>(); |
||||
|
IncludeRegistry<ApiRegistry>(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,37 @@ |
|||||
|
using Lamar; |
||||
|
|
||||
|
using InfoBipRepo = DealerSelection.Api.Infrastructure.InfoBip; |
||||
|
using MulesoftRepo = DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
using AssignDealerRepo = DealerSelection.Api.Infrastructure.AssignDealer; |
||||
|
using Customerdetail = DealerSelection.Api.Infrastructure.CustomerDetail; |
||||
|
using JwtRepo = DealerSelection.Api.Infrastructure.Jwt; |
||||
|
namespace DealerSelection.DependencyInjection; |
||||
|
|
||||
|
public class InfrastructureRegistry : ServiceRegistry |
||||
|
{ |
||||
|
public InfrastructureRegistry() |
||||
|
{ |
||||
|
|
||||
|
For<MulesoftRepo.IRepository>() |
||||
|
.Use<MulesoftRepo.Repository>() |
||||
|
.Ctor<string>().Is("BOOKING") |
||||
|
.Transient(); |
||||
|
|
||||
|
For<JwtRepo.IJwtRepository>() |
||||
|
.Use<JwtRepo.JwtRepository>() |
||||
|
.Ctor<string>().Is("BOOKING") |
||||
|
.Transient(); |
||||
|
|
||||
|
For<AssignDealerRepo.IAssignDealerRepository>() |
||||
|
.Use<AssignDealerRepo.Repository>() |
||||
|
.Ctor<string>().Is("BOOKING") |
||||
|
.Transient(); |
||||
|
|
||||
|
For<Customerdetail.IRepository>() |
||||
|
.Use<Customerdetail.Repository>() |
||||
|
.Ctor<string>().Is("BOOKING") |
||||
|
.Transient(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.AssignDealer; |
||||
|
|
||||
|
public interface IAssignDealerRepository |
||||
|
{ |
||||
|
|
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
using DealerSelection.Api.Models; |
||||
|
using DealerSelection.Common.Data.Dapper; |
||||
|
using Dapper; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System.Data; |
||||
|
using System.Data.SqlClient; |
||||
|
namespace DealerSelection.Api.Infrastructure.AssignDealer; |
||||
|
|
||||
|
public class Repository : RepositoryBaseDapperAsync, IAssignDealerRepository |
||||
|
{ |
||||
|
private readonly ILogger _logger; |
||||
|
public Repository(string cxnName, ILogger<Repository> logger) : base(cxnName) |
||||
|
{ |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
using DealerSelection.Api.Models; |
||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.CustomerDetail; |
||||
|
|
||||
|
public class CustomerDealerInfoRequestDto |
||||
|
{ |
||||
|
public int BuId { get; set; } |
||||
|
public int RecordId { get; set; } |
||||
|
public int MobileNumber { get; set; } |
||||
|
public string ModelCode { get; set; } |
||||
|
public string ModelName { get; set; } |
||||
|
public string ModelVariant { get; set; } |
||||
|
public string DealerName { get; set; } |
||||
|
public string DealerCode { get; set; } |
||||
|
public string PinCode { get; set; } |
||||
|
public string Latitude { get; set; } |
||||
|
public string Longitude { get; set; } |
||||
|
public DealerSelectionJobStatus DealerSelectionJobStatus { get; set; } |
||||
|
|
||||
|
public string RequestDetail() |
||||
|
{ |
||||
|
return $"BuId: {BuId}, RecordId: {RecordId}, MobileNumber: {MobileNumber}, ModelCode: {ModelCode}, " + |
||||
|
$"ModelName:{ModelName}, ModelVariant:{ModelVariant}, DealerName: {DealerName}, DealerCode: {DealerCode}, "+ |
||||
|
$"PinCode: {PinCode}, Latitude: {Latitude}, Longitude: {Longitude}, DealerSelectionJobStatus: {DealerSelectionJobStatus}"; |
||||
|
} |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
using DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
using DealerSelection.Api.Models; |
||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.CustomerDetail; |
||||
|
|
||||
|
public interface IRepository |
||||
|
{ |
||||
|
Task<int> UpdateDealerDetail(CustomerDealerInfoRequestDto customerInfo); |
||||
|
// Task<MulesoftCustomerInfoDto> GetCustomerData();
|
||||
|
Task<MulesoftCustomerInfoDto> GetCustomerData(int buid, int recordId); |
||||
|
Task<bool> IsDuplicateMobileNumber(int mobileNumber); |
||||
|
Task UpdateDealerSelectionJobStatus(int buId, int recordId, int mobileNumber, DealerSelectionJobStatus dealerSelectionJobStatus); |
||||
|
} |
@ -0,0 +1,116 @@ |
|||||
|
using Dapper; |
||||
|
using DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
using DealerSelection.Api.Models; |
||||
|
using DealerSelection.Common.Data.Dapper; |
||||
|
using DealerSelection.Common.Exceptions; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System.Data; |
||||
|
using System.Data.SqlClient; |
||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.CustomerDetail; |
||||
|
|
||||
|
public class Repository : RepositoryBaseDapperAsync, IRepository |
||||
|
{ |
||||
|
private readonly ILogger _logger; |
||||
|
public Repository(string cxnName, ILogger<Repository> logger) : base(cxnName) |
||||
|
{ |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public async Task<int> UpdateDealerDetail(CustomerDealerInfoRequestDto dto) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (SqlConnection cxn = await OpenCxnAsync()) |
||||
|
{ |
||||
|
int receivedBookingId = await cxn.ExecuteScalarAsync<int>(Procedure.UpdateDealerDetails, |
||||
|
new |
||||
|
{ |
||||
|
dto.BuId, |
||||
|
dto.RecordId, |
||||
|
dto.MobileNumber, |
||||
|
dto.ModelCode, |
||||
|
dto.ModelName, |
||||
|
dto.ModelVariant, |
||||
|
dto.DealerName, |
||||
|
dto.DealerCode, |
||||
|
dto.PinCode, |
||||
|
dto.Latitude, |
||||
|
dto.Longitude, |
||||
|
dto.DealerSelectionJobStatus |
||||
|
}, |
||||
|
commandType: CommandType.StoredProcedure); |
||||
|
return receivedBookingId; |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError($"BU:- {dto.BuId}. Error at Repository:CustomerDetail in UpdateDealerDetail for Request: {dto.RequestDetail()}.", ex.StackTrace); |
||||
|
throw new UnexpectedDataException($"Error at Repository:CustomerDetail in UpdateDealerDetail for Request: {dto.RequestDetail()}.", ex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task<MulesoftCustomerInfoDto> GetCustomerData(int buId, int recordId) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (SqlConnection cxn = await OpenCxnAsync()) |
||||
|
{ |
||||
|
IEnumerable<MulesoftCustomerInfoDto> cusotmerInfo = await cxn.QueryAsync<MulesoftCustomerInfoDto>(Procedure.GetCustomerDataForJob, |
||||
|
commandType: CommandType.StoredProcedure); |
||||
|
return cusotmerInfo.ToList().FirstOrDefault(); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("Error at Repository:CustomerDetail in UpdateDealerDetail for Request: {customerInfo.RequestDetail()}.", ex.StackTrace); |
||||
|
throw new UnexpectedDataException($"Error at Repository:CustomerDetail in UpdateDealerDetail for Request: ", ex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task<bool> IsDuplicateMobileNumber(int mobileNumber) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (SqlConnection cxn = await OpenCxnAsync()) |
||||
|
{ |
||||
|
bool isDuplicate = await cxn.QueryFirstAsync<bool>(Procedure.IsDuplicateMobileNumber, |
||||
|
new |
||||
|
{ |
||||
|
mobileNumber |
||||
|
}, |
||||
|
commandType: CommandType.StoredProcedure); |
||||
|
return isDuplicate; |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError($"Error at Repository:CustomerDetail in IsDuplicateMobileNumber for MobileNumber: {mobileNumber}. ErrorMessage", ex.StackTrace); |
||||
|
throw new DuplicateException($"Error at Repository:CustomerDetail in IsDuplicateMobileNumber for MobileNumber: {mobileNumber}."); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public async Task UpdateDealerSelectionJobStatus(int buId, int recordId, int mobileNumber, DealerSelectionJobStatus dealerSelectionJobStatus) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (SqlConnection cxn = await OpenCxnAsync()) |
||||
|
{ |
||||
|
await cxn.QueryFirstAsync(Procedure.UpdateDealerSelectionJobStatus, |
||||
|
new |
||||
|
{ |
||||
|
buId, recordId, mobileNumber, dealerSelectionJobStatus |
||||
|
}, |
||||
|
commandType: CommandType.StoredProcedure); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError($"Error at Repository:CustomerDetail in UpdateDealerSelectionJobStatus for BuId: {buId}, RecordId: {recordId}, MobileNumber: {mobileNumber}, DealerSelectionJobStatus: {dealerSelectionJobStatus}. ErrorMessage", ex.StackTrace); |
||||
|
throw new DuplicateException($"Error at Repository:CustomerDetail in UpdateDealerSelectionJobStatus for BuId: {buId}, RecordId: {recordId}, MobileNumber: {mobileNumber}, DealerSelectionJobStatus: {dealerSelectionJobStatus}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,37 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
||||
|
<NoWarn>1701;1702;8618;8603</NoWarn> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> |
||||
|
<NoWarn>1701;1702;8618;8603</NoWarn> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="BouncyCastle.NetCore" Version="1.9.0" /> |
||||
|
<PackageReference Include="iTextSharp" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="itextsharp.xmlworker" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="Microsoft.ApplicationBlocks.Data" Version="2.0.0" /> |
||||
|
<PackageReference Include="Microsoft.SqlServer.Server" Version="1.0.0" /> |
||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> |
||||
|
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7"> |
||||
|
<PrivateAssets>all</PrivateAssets> |
||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" /> |
||||
|
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\DealerSelection.Api.Models\DealerSelection.Api.Models.csproj" /> |
||||
|
<ProjectReference Include="..\DealerSelection.Common\DealerSelection.Common.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
@ -0,0 +1,6 @@ |
|||||
|
namespace DealerSelection.Api.Infrastructure.InfoBip; |
||||
|
|
||||
|
public interface IRepository |
||||
|
{ |
||||
|
Task SaveResponse(int buId, string strMobile, string request_name, string api_request, string api_response, string error_message); |
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
using DealerSelection.Api.Models; |
||||
|
using DealerSelection.Common.Data.Dapper; |
||||
|
using Dapper; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System.Data; |
||||
|
using System.Data.SqlClient; |
||||
|
|
||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.InfoBip; |
||||
|
|
||||
|
public class Repository : RepositoryBaseDapperAsync, IRepository |
||||
|
{ |
||||
|
private readonly ILogger _logger; |
||||
|
public Repository(string cxnName, ILogger<Repository> logger) : base(cxnName) |
||||
|
{ |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
public async Task SaveResponse(int buId, string strMobile, string request_name, string api_request, string api_response, string error_message) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (SqlConnection cxn = await OpenCxnAsync()) |
||||
|
{ |
||||
|
await cxn.ExecuteScalarAsync(@"insert into tbl_infobip_api_response(request_name,api_request,api_response,error_message)
|
||||
|
values(@request_name,@api_request,@api_response,@error_message)",
|
||||
|
new |
||||
|
{ |
||||
|
request_name, |
||||
|
api_request, |
||||
|
api_response, |
||||
|
error_message |
||||
|
}, |
||||
|
commandType: CommandType.Text); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("BU:- " + buId.ToString() + $"Error at Repository:InfoBip in SaveResponse for BuId: {buId}, Mobile: {strMobile}," + |
||||
|
$"request_name: {request_name}, api_request: {api_request}, api_response: {api_response}, error_message: {error_message}." + ex.Message.ToString()); |
||||
|
throw new UnexpectedDataException($"Error at Repository:InfoBip in SaveResponse for BuId: {buId}, Mobile: {strMobile}," + |
||||
|
$"request_name: {request_name}, api_request: {api_request}, api_response: {api_response}, error_message: {error_message}.", ex); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.Jwt; |
||||
|
|
||||
|
public class AuthValidateModelDto |
||||
|
{ |
||||
|
public string ClientId { get; set; } |
||||
|
public string SecretId { get; set; } |
||||
|
public string BuId { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class TokenModel |
||||
|
{ |
||||
|
public string Token { get; set; } |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
using DealerSelection.Api.Models; |
||||
|
namespace DealerSelection.Api.Infrastructure.Jwt; |
||||
|
|
||||
|
public interface IJwtRepository |
||||
|
{ |
||||
|
Task<string> GenerateToken(AuthModel user); |
||||
|
Task<bool> Authenticate(AuthValidateModelDto userLogin); |
||||
|
Task<TokenValidProperty> IsTokenExpired(string tokenValue); |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
using DealerSelection.Api.Models; |
||||
|
|
||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.Jwt; |
||||
|
|
||||
|
public class JwtRepository : IJwtRepository |
||||
|
{ |
||||
|
|
||||
|
public Task<bool> Authenticate(AuthValidateModelDto userLogin) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public Task<string> GenerateToken(AuthModel user) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public Task<TokenValidProperty> IsTokenExpired(string tokenValue) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
|
||||
|
public class DealerDetailDto |
||||
|
{ |
||||
|
public int BuId { get; set; } |
||||
|
public string DealerCode { get; set; } |
||||
|
public string Address1 { get; set; } |
||||
|
public string Address2 { get; set; } |
||||
|
public string City { get; set; } |
||||
|
public string State { get; set; } |
||||
|
public string Zip { get; set; } |
||||
|
public string DisplayName { get; set; } |
||||
|
public string ContactCard { get; set; } |
||||
|
public string SalesPersonMail { get; set; } |
||||
|
public string SaleMobileNumber { get; set; } |
||||
|
public string EcomSalesAddress { get; set; } |
||||
|
|
||||
|
public string RequestDetail() |
||||
|
{ |
||||
|
return $"BuId: {BuId}, DealerCode: {DealerCode}, Address1: {Address1}, Address2: {Address2}, City: {City}, State: {State}, " + |
||||
|
$"Zip: {Zip}, DisplayName: {DisplayName}, ContactCard: {ContactCard}, SalesPersonMail: {SalesPersonMail}, " + |
||||
|
$"SaleMobileNumber: {SaleMobileNumber}, EcomSalesAddress: {EcomSalesAddress}."; |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,10 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
|
||||
|
public interface IRepository |
||||
|
{ |
||||
|
Task<MulesoftCustomerInfoDto> GetCustomerInfo(int buId, string bookingId); |
||||
|
Task UpdateMulesoftResponse(int buId,int recordId,string bookingId,string message,string isSuccessBooking, LeadData leadData); |
||||
|
Task InsertAndUpdateDealerRecord(DealerDetailDto dto); |
||||
|
Task<List<MulesoftCustomerInfoDto>> GetDataForLsqPush(int buId); |
||||
|
} |
@ -0,0 +1,46 @@ |
|||||
|
|
||||
|
using System; |
||||
|
|
||||
|
namespace DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
|
||||
|
public class MulesoftCustomerInfoDto |
||||
|
{ |
||||
|
public int BuId { get; set; } |
||||
|
public string BuName { get; set; } |
||||
|
public int RecordId { get; set; } |
||||
|
public string BookingId { get; set; } |
||||
|
public string CustomerName { get; set; } |
||||
|
public string MobileNumber { get; set; } |
||||
|
public string ModelCode { get; set; } |
||||
|
public string ModelName { get; set; } |
||||
|
public string ColorCode { get; set; } |
||||
|
public string DealerCode { get; set; } |
||||
|
public string DealerName { get; set; } |
||||
|
public bool IsRegisterInterestRequest { get; set; } |
||||
|
public string PinCode { get; set; } |
||||
|
public string UtmCustomDetails1 { get; set; } |
||||
|
public string UtmCustomDetails2 { get; set; } |
||||
|
public string Status { get; set; } |
||||
|
public string CCTransactionId { get; set; } |
||||
|
public string ReceiptId { get; set; } |
||||
|
public string AmountPaid { get; set; } |
||||
|
public string ReferralUrl { get; set; } |
||||
|
|
||||
|
public bool IsWhatsappOptIn { get; set; } |
||||
|
public int LeadTransferred { get; set; } |
||||
|
public string CustomerLat { get; set; } |
||||
|
public string CustomerLong { get; set; } |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
public class LeadData |
||||
|
{ |
||||
|
public string Lead_transferred { get; set; } |
||||
|
public string Lead_status { get; set; } |
||||
|
public string Opportunity_id { get; set; } |
||||
|
public string Prospect_id { get; set; } |
||||
|
public string ApiResponse { get; set; } |
||||
|
public string LeadResponseStatus { get; set; } |
||||
|
} |
||||
|
|
@ -0,0 +1,134 @@ |
|||||
|
using DealerSelection.Api.Models; |
||||
|
using DealerSelection.Common.Data.Dapper; |
||||
|
using Dapper; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System.Data; |
||||
|
using System.Data.SqlClient; |
||||
|
namespace DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
|
||||
|
public class Repository : RepositoryBaseDapperAsync, IRepository |
||||
|
{ |
||||
|
private readonly ILogger _logger; |
||||
|
public Repository(string cxnName, ILogger<Repository> logger) : base(cxnName) |
||||
|
{ |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
public async Task<MulesoftCustomerInfoDto> GetCustomerInfo(int buId, string bookingId) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (SqlConnection cxn = await OpenCxnWithMappingAsync<MulesoftCustomerInfoDto>()) |
||||
|
{ |
||||
|
IEnumerable<MulesoftCustomerInfoDto> cusotmerInfo = await cxn.QueryAsync<MulesoftCustomerInfoDto>(Procedure.GetCustomerInfoOnBookingId, |
||||
|
new |
||||
|
{ |
||||
|
buId, |
||||
|
bookingId |
||||
|
}, |
||||
|
commandType: CommandType.StoredProcedure); |
||||
|
return cusotmerInfo.ToList().FirstOrDefault(); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("BU:- " + buId.ToString() + " Error at Repository:Mulesoft in GetCustomerInfo." + ex.Message.ToString()); |
||||
|
throw new UnexpectedDataException($"Error at Repository:Mulesoft in GetCustomerInfo for BuId: {buId} and BookingId: {bookingId}.", ex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task UpdateMulesoftResponse(int buId, int recordId, string bookingId, string message, string isSuccessBooking, LeadData leadData) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (SqlConnection cxn = await OpenCxnWithMappingAsync<int>()) |
||||
|
{ |
||||
|
await cxn.QueryAsync<int>(Procedure.InsertLSQDetail, |
||||
|
new |
||||
|
{ |
||||
|
buId, |
||||
|
recordId, |
||||
|
bookingId, |
||||
|
lead_Transferred = leadData.Lead_transferred, |
||||
|
lead_Status = leadData.Lead_status, |
||||
|
api_Request = message, |
||||
|
api_Response = leadData.ApiResponse, |
||||
|
lSQProspectId = leadData.Prospect_id, |
||||
|
lSQOpportunityId = leadData.Opportunity_id, |
||||
|
isSuccessBooking |
||||
|
}, |
||||
|
commandType: CommandType.StoredProcedure); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
|
||||
|
_logger.LogError("BU:- " + buId.ToString() + $"Error at Repository:Mulesoft in UpdateMulesoftResponse for buId: {buId}, recordId: {recordId}, " + |
||||
|
$"leadData.Lead_transferred: {leadData.Lead_transferred}, message: {message},leadData.ApiResponse: {leadData.ApiResponse}, " + |
||||
|
$"leadData.Prospect_id:{leadData.Prospect_id}, leadData.Opportunity_id: {leadData.Opportunity_id}, " + |
||||
|
$"isSuccessBooking: {isSuccessBooking} " + ex.Message.ToString()); |
||||
|
|
||||
|
throw new UnexpectedDataException($"Error at Repository:Mulesoft in UpdateMulesoftResponse for buId: {buId}, recordId: {recordId}, " + |
||||
|
$"leadData.Lead_transferred: {leadData.Lead_transferred}, message: {message},leadData.ApiResponse: {leadData.ApiResponse}, " + |
||||
|
$"leadData.Prospect_id:{leadData.Prospect_id}, leadData.Opportunity_id: {leadData.Opportunity_id}, " + |
||||
|
$"isSuccessBooking: {isSuccessBooking} ", ex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task InsertAndUpdateDealerRecord(DealerDetailDto dto) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (SqlConnection cxn = await OpenCxnWithMappingAsync<int>()) |
||||
|
{ |
||||
|
await cxn.QueryAsync<int>(Procedure.InsertUpdateDealerDetail, |
||||
|
new |
||||
|
{ |
||||
|
dto.BuId, |
||||
|
dto.DealerCode, |
||||
|
dto.Address1, |
||||
|
dto.Address2, |
||||
|
dto.City, |
||||
|
dto.State, |
||||
|
dto.Zip, |
||||
|
dto.DisplayName, |
||||
|
dto.ContactCard, |
||||
|
dto.SalesPersonMail, |
||||
|
dto.SaleMobileNumber, |
||||
|
dto.EcomSalesAddress |
||||
|
|
||||
|
}, |
||||
|
commandType: CommandType.StoredProcedure); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("BU:- " + dto.BuId.ToString() + " Error at Repository:Mulesoft in InsertAndUpdateDealerRecord for InfoBip Request: {dto.RequestDetail()}" + ex.Message.ToString()); |
||||
|
throw new UnexpectedDataException($"Error at Repository:Mulesoft in InsertAndUpdateDealerRecord for InfoBip Request: {dto.RequestDetail()}", ex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task<List<MulesoftCustomerInfoDto>> GetDataForLsqPush(int buId) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (SqlConnection cxn = await OpenCxnAsync()) |
||||
|
{ |
||||
|
IEnumerable<MulesoftCustomerInfoDto> lsqDto = await cxn.QueryAsync<MulesoftCustomerInfoDto>(Procedure.GetDataForLsqPush, |
||||
|
new |
||||
|
{ |
||||
|
buId |
||||
|
}, |
||||
|
commandType: CommandType.StoredProcedure); |
||||
|
return lsqDto.ToList(); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError("BU:- " + buId.ToString() + "Error at Repository:Mulesoft in GetDataForLsqPush " + ex.Message.ToString()); |
||||
|
throw new UnexpectedDataException($"Error at Repository:Mulesoft in GetDataForLsqPush for BuId: {buId}.", ex); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="BouncyCastle.NetCore" Version="1.9.0" /> |
||||
|
<PackageReference Include="iTextSharp" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="itextsharp.xmlworker" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.21.0" /> |
||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> |
||||
|
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7"> |
||||
|
<PrivateAssets>all</PrivateAssets> |
||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
||||
|
</PackageReference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\DealerSelection.Api.Models\DealerSelection.Api.Models.csproj" /> |
||||
|
<ProjectReference Include="..\DealerSelection.Infrastructure\DealerSelection.Api.Infrastructure.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
@ -0,0 +1,7 @@ |
|||||
|
namespace DealerSelection.Api.Interface; |
||||
|
|
||||
|
public interface IAssignDealerApi |
||||
|
{ |
||||
|
Task GetCustomerDataForJob(int buId, int recordId); |
||||
|
|
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
using Newtonsoft.Json.Linq; |
||||
|
namespace DealerSelection.Api.Interface; |
||||
|
|
||||
|
public interface IInfoBipSmsServiceApi |
||||
|
{ |
||||
|
Task<JObject> sendOTP(int buId, string strMobile); |
||||
|
Task<JObject> resendOTP(int buId, string strMobile, string strOtpPinId); |
||||
|
Task<JObject> verifyOTP(int buId, string strMobile, string strOtpPinId, string otpPin); |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
using DealerSelection.Api.Models; |
||||
|
namespace DealerSelection.Api.Interface; |
||||
|
|
||||
|
public interface IJwtTokenApi |
||||
|
{ |
||||
|
Task<string> GenerateToken(AuthValidateModel user); |
||||
|
Task<bool> Authenticate(AuthValidateModel userLogin); |
||||
|
Task<TokenValidProperty> IsTokenExpired(string tokenValue); |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
using DealerSelection.Api.Infrastructure.Mulesoft; |
||||
|
using DealerSelection.Api.Models; |
||||
|
|
||||
|
namespace DealerSelection.Api.Interface; |
||||
|
|
||||
|
public interface IMulesoftApi |
||||
|
{ |
||||
|
Task<MulesoftResponse> GetDealers(int buId, string buUnit, string strlat, string strLong); |
||||
|
Task<MulesoftResponse> GetAndInsertDealerDetails(int buId, string dealerCode); |
||||
|
Task<MulesoftResponse> GetStateWisePrice(int buId, string stateCode, string itemId); |
||||
|
Task<MulesoftResponse> GetModelOnBrand(int buId, string brand); |
||||
|
Task<Response> CallLSQBookingApi( MulesoftCustomerInfoDto customerInfo); |
||||
|
Task<MulesoftCustomerInfoDto> GetCustomerInfo(int buId, string bookingId); |
||||
|
Task<List<MulesoftCustomerInfoDto>> GetDataForLsqPush (int buId); |
||||
|
Task<MulesoftResponse> GetActiveState(int buId); |
||||
|
|
||||
|
Task<MulesoftResponse> GetActiveCity(int buId, string stateCode); |
||||
|
|
||||
|
Task<MulesoftResponse> ModelDetailsByItemCode(int buId, string itemId); |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
|
||||
|
namespace DealerSelection.Api.Interface; |
||||
|
|
||||
|
public interface IMulesoftTokenApi |
||||
|
{ |
||||
|
Task<string> FetchToken(); |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
|
||||
|
using DealerSelection.Api.Models; |
||||
|
|
||||
|
namespace DealerSelection.Api.Interface; |
||||
|
|
||||
|
public interface IYellowAIApi |
||||
|
{ |
||||
|
Task UpdateSelectedDealer(CustomerDealerInfoRequest request); |
||||
|
|
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class BikeResponse |
||||
|
{ |
||||
|
public string ItemId { get; set; } |
||||
|
public string ModelCode { get; set; } |
||||
|
public string ModelName { get; set; } |
||||
|
public string ModelDisplayName { get; set; } |
||||
|
public string ColorCode { get; set; } |
||||
|
public string ColorName { get; set; } |
||||
|
public string SKUCode { get; set; } |
||||
|
public string MasterCode { get; set; } |
||||
|
public string ImagePath { get; set; } |
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
|
||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class BookingConfirmationRequest |
||||
|
{ |
||||
|
public int BuId { get; set; } |
||||
|
public int RecordId { get; set; } |
||||
|
public string BookingId { get; set; } |
||||
|
public string PaymentTransactionStatus { get; set; } |
||||
|
public string AmountPaid { get; set; } |
||||
|
public string PaymentTransactionId { get; set; } |
||||
|
public string PaymentType { get; set; } |
||||
|
public string CardName { get; set; } |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class CityResponse |
||||
|
{ |
||||
|
public string CityName { get; set; } |
||||
|
public string IsUnionTerritory { get; set; } |
||||
|
public string StateName { get; set; } |
||||
|
|
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class CustomerInfoMappingResponse |
||||
|
{ |
||||
|
|
||||
|
public int Id { get; set; } |
||||
|
public int BuId { get; set; } |
||||
|
public string CustomerName { get; set; } |
||||
|
public string MobileNumber { get; set; } |
||||
|
public string ModelCode { get; set; } |
||||
|
public string ModelName { get; set; } |
||||
|
public string DealerLat { get; set; } |
||||
|
public string DealerLong { get; set; } |
||||
|
public string DealerCode { get; set; } |
||||
|
public string DealerAddress { get; set; } |
||||
|
public string DealerDisplayName { get; set; } |
||||
|
public string DealerMobileNumber { get; set; } |
||||
|
public string ColorCode { get; set; } |
||||
|
public string Location { get; set; } |
||||
|
public string PinCode { get; set; } |
||||
|
public string BikeImgPath { get; set; } |
||||
|
public bool IsWhatsappOptIn { get; set; } |
||||
|
public DateTime BookingDate { get; set; } |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
|
||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class CustomerDealerInfoRequest |
||||
|
{ |
||||
|
public int BuId { get; set; } |
||||
|
public int RecordId { get; set; } |
||||
|
public int MobileNumber { get; set; } |
||||
|
public string ModelCode { get; set; } |
||||
|
public string ModelName { get; set; } |
||||
|
public string ModelVariant { get; set; } |
||||
|
public string DealerName { get; set; } |
||||
|
public string DealerCode { get; set; } |
||||
|
public string PinCode { get; set; } |
||||
|
public string Latitude { get; set; } |
||||
|
public string Longitude { get; set; } |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="BouncyCastle.NetCore" Version="1.9.0" /> |
||||
|
<PackageReference Include="iTextSharp" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="itextsharp.xmlworker" Version="5.5.13.3" /> |
||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> |
||||
|
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7"> |
||||
|
<PrivateAssets>all</PrivateAssets> |
||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
||||
|
</PackageReference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
@ -0,0 +1,34 @@ |
|||||
|
|
||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class MulesoftResponse |
||||
|
{ |
||||
|
public int StatusCode { get; set; } |
||||
|
public bool IsRequestSuccessfull { get; set; } |
||||
|
public List<Data> Data { get; set; } |
||||
|
|
||||
|
} |
||||
|
public class MulesoftPriceResponse |
||||
|
{ |
||||
|
public int StatusCode { get; set; } |
||||
|
public bool IsRequestSuccessfull { get; set; } |
||||
|
public string ExPrice { get; set; } |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public class Data |
||||
|
{ |
||||
|
public string DocumentId { get; set; } |
||||
|
public string Code { get; set; } |
||||
|
public bool IsBookingActive { get; set; } |
||||
|
public bool IsTestRideActive { get; set; } |
||||
|
public string Latitude { get; set; } |
||||
|
public string Longitude { get; set; } |
||||
|
public string DisplayName { get; set; } |
||||
|
public string CompanyName { get; set; } |
||||
|
public string CompanyCode { get; set; } |
||||
|
public bool IsActive { get; set; } |
||||
|
public string BranchName { get; set; } |
||||
|
public double Distance { get; set; } |
||||
|
} |
||||
|
|
@ -0,0 +1,7 @@ |
|||||
|
|
||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class PaymentLinkResponse : Response |
||||
|
{ |
||||
|
public string SourceUrl { get; set; } |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
|
||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class RegisterInterestSuccessfullResponse |
||||
|
{ |
||||
|
public int BuId { get; set; } |
||||
|
public int RecordId { get; set; } |
||||
|
public string CustomerName { get; set; } |
||||
|
public string MobileNumber { get; set; } |
||||
|
public string ModelCode { get; set; } |
||||
|
public string ModelName { get; set; } |
||||
|
public string ColorCode { get; set; } |
||||
|
public string BikeImgPath { get; set; } |
||||
|
public string Location { get; set; } |
||||
|
|
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
|
||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class Response |
||||
|
{ |
||||
|
public int BuId { get; set; } |
||||
|
public int RecordId { get; set; } |
||||
|
public bool IsRequestSuccessfull { get; set; } |
||||
|
public string Result { get; set; } |
||||
|
public string Message { get; set; } |
||||
|
public string ErrorCode { get; set; } |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
|
||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class ReviewPayCustomerInfoResponse |
||||
|
{ |
||||
|
|
||||
|
public int BuId { get; set; } |
||||
|
public int RecordId { get; set; } |
||||
|
public string CustomerName { get; set; } |
||||
|
public string MobileNumber { get; set; } |
||||
|
public string ModelCode { get; set; } |
||||
|
public string ModelName { get; } |
||||
|
public string ColorCode { get; set; } |
||||
|
public string Location { get; } |
||||
|
public string DealerName { get; set; } |
||||
|
public string Amount { get; set; } |
||||
|
public string DealerCode { get; set; } |
||||
|
public string BikeImgPath { get; set; } |
||||
|
public string IsBookingDone { get; set; } |
||||
|
public string IsExpired { get; set; } |
||||
|
public string DealerAddress { get; set; } |
||||
|
public string DealerMobileNumber { get; set; } |
||||
|
public string DealerSalesEmail { get; set; } |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
namespace DealerSelection.WebApi.Models; |
||||
|
|
||||
|
public class StateResponse |
||||
|
{ |
||||
|
public string State { get; set; } |
||||
|
public string StateCode { get; set; } |
||||
|
|
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
{ |
||||
|
"version": 1, |
||||
|
"isRoot": true, |
||||
|
"tools": { |
||||
|
"dotnet-ef": { |
||||
|
"version": "7.0.9", |
||||
|
"commands": [ |
||||
|
"dotnet-ef" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
using AutoMapper; |
||||
|
using DealerSelection.WebApi.Models; |
||||
|
|
||||
|
namespace DealerSelection.WebApi; |
||||
|
|
||||
|
public static class MapperConfig |
||||
|
{ |
||||
|
private static MapperConfiguration Config { get; set; } |
||||
|
|
||||
|
public static void Register() |
||||
|
{ |
||||
|
Config = new MapperConfiguration( |
||||
|
cfg => |
||||
|
{ |
||||
|
cfg.CreateMap<Api.Models.Response, Response>(); |
||||
|
cfg.CreateMap<Api.Models.MulesoftResponse, MulesoftResponse>(); |
||||
|
cfg.CreateMap<CustomerDealerInfoRequest, Api.Models.CustomerDealerInfoRequest>(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public static Response MapResponse(Api.Models.Response from) |
||||
|
{ |
||||
|
return Config.CreateMapper().Map<Response>(from); |
||||
|
} |
||||
|
|
||||
|
public static MulesoftResponse MapMulesoftResponse(Api.Models.MulesoftResponse from) |
||||
|
{ |
||||
|
return Config.CreateMapper().Map<Api.Models.MulesoftResponse, MulesoftResponse>(from); |
||||
|
} |
||||
|
|
||||
|
public static Api.Models.CustomerDealerInfoRequest MapCustomerDealerInfoRequest(CustomerDealerInfoRequest from) |
||||
|
{ |
||||
|
return Config.CreateMapper().Map<CustomerDealerInfoRequest, Api.Models.CustomerDealerInfoRequest>(from); |
||||
|
} |
||||
|
|
||||
|
} |
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue