Browse Source

Initial Checkin

Release
Hema Janoti 1 year ago
parent
commit
042f93b910
  1. 98
      DealerSelectionAPI.sln
  2. 14
      Source/DealerSelection.Api.Models/AuthModel.cs
  3. 14
      Source/DealerSelection.Api.Models/AuthValidateModel.cs
  4. 48
      Source/DealerSelection.Api.Models/CustomerDealerInfoRequest.cs
  5. 28
      Source/DealerSelection.Api.Models/DealerSelection.Api.Models.csproj
  6. 10
      Source/DealerSelection.Api.Models/DealerSelectionJobStatus.cs
  7. 21
      Source/DealerSelection.Api.Models/MulesoftResponse.cs
  8. 8
      Source/DealerSelection.Api.Models/MulesoftToken.cs
  9. 15
      Source/DealerSelection.Api.Models/Procedure.cs
  10. 31
      Source/DealerSelection.Api.Models/Response.cs
  11. 10
      Source/DealerSelection.Api.Models/TokenValidProperty.cs
  12. 9
      Source/DealerSelection.Api.Models/UnexpectedDataException.cs
  13. 70
      Source/DealerSelection.Api.Models/WebEngageEvent.cs
  14. 190
      Source/DealerSelection.Api/AssignDealerApi.cs
  15. 151
      Source/DealerSelection.Api/CommonUtil/AESEncryption.cs
  16. 132
      Source/DealerSelection.Api/CommonUtil/CustomConfig.cs
  17. 28
      Source/DealerSelection.Api/CommonUtil/GenerateRandomString.cs
  18. 86
      Source/DealerSelection.Api/CommonUtil/MuleSoftTokenGenerate.cs
  19. 42
      Source/DealerSelection.Api/DealerSelection.Api.csproj
  20. 143
      Source/DealerSelection.Api/InfoBipSmsServiceApi.cs
  21. 112
      Source/DealerSelection.Api/JwtTokenApi.cs
  22. 722
      Source/DealerSelection.Api/MulesoftApi.cs
  23. 68
      Source/DealerSelection.Api/MulesoftTokenApi.cs
  24. 77
      Source/DealerSelection.Api/YellowAIApi.cs
  25. 9
      Source/DealerSelection.Common/CommonBaseClass/ExceptionBase.cs
  26. 92
      Source/DealerSelection.Common/CommonBaseClass/ExceptionFilterBase.cs
  27. 235
      Source/DealerSelection.Common/CommonBaseClass/StartupBase.cs
  28. 6
      Source/DealerSelection.Common/CommonBaseClass/WebApiConfigurationCfgBase.cs
  29. 102
      Source/DealerSelection.Common/Configuration/ConfigurationHelper.cs
  30. 36
      Source/DealerSelection.Common/Data/ConnectionHelper.cs
  31. 25
      Source/DealerSelection.Common/Data/Dapper/RepositoryBaseDapperAsync.cs
  32. 25
      Source/DealerSelection.Common/Data/Dapper/RepositoryBaseDapperSync.cs
  33. 30
      Source/DealerSelection.Common/Data/Dapper/TypeMapHelper.cs
  34. 35
      Source/DealerSelection.Common/Data/RepositoryBaseDIAsync.cs
  35. 35
      Source/DealerSelection.Common/Data/RepositoryBaseDISync.cs
  36. 11
      Source/DealerSelection.Common/Data/RepositoryDIBase.cs
  37. 56
      Source/DealerSelection.Common/DealerSelection.Common.csproj
  38. 24
      Source/DealerSelection.Common/Entity/FieldMapAttribute.cs
  39. 8
      Source/DealerSelection.Common/Exceptions/AuthorizationException.cs
  40. 8
      Source/DealerSelection.Common/Exceptions/DataNotFoundException.cs
  41. 15
      Source/DealerSelection.Common/Exceptions/DbConnectionException.cs
  42. 8
      Source/DealerSelection.Common/Exceptions/DuplicateException.cs
  43. 8
      Source/DealerSelection.Common/Exceptions/NullValueException.cs
  44. 8
      Source/DealerSelection.Common/Exceptions/PartialSuccessException.cs
  45. 8
      Source/DealerSelection.Common/Exceptions/ValidationException.cs
  46. 8
      Source/DealerSelection.Common/Helpers/SwaggerCfg.cs
  47. 38
      Source/DealerSelection.Common/Helpers/SwashbuckleSchemaHelper.cs
  48. 21
      Source/DealerSelection.Common/HttpClient/MyHttpClientHandler.cs
  49. 9
      Source/DealerSelection.Common/Interfaces/Data/IRepositoryDIAsync.cs
  50. 9
      Source/DealerSelection.Common/Interfaces/Data/IRepositoryDISync.cs
  51. 8
      Source/DealerSelection.Common/Interfaces/HttpClient/IHttpClientHandler.cs
  52. 24
      Source/DealerSelection.Common/Logging/ApiInfo.cs
  53. 82
      Source/DealerSelection.Common/Logging/AzureLogHelper.cs
  54. 28
      Source/DealerSelection.Common/Logging/HttpHeaderHelper.cs
  55. 127
      Source/DealerSelection.Common/Logging/LoggingMiddleware.cs
  56. 42
      Source/DealerSelection.Common/Logging/RequestInfo.cs
  57. 37
      Source/DealerSelection.Common/Logging/ResponseInfo.cs
  58. 34
      Source/DealerSelection.Common/Middleware/SwaggerRootRoutingMiddleware.cs
  59. 31
      Source/DealerSelection.Common/Profiler/PerformanceProfiler.cs
  60. 19
      Source/DealerSelection.Common/Profiler/Profiler.cs
  61. 35
      Source/DealerSelection.DependencyInjection/ApiRegistry.cs
  62. 29
      Source/DealerSelection.DependencyInjection/DealerSelection.DependencyInjection.csproj
  63. 11
      Source/DealerSelection.DependencyInjection/DependencyInjectionBootStrapper.cs
  64. 37
      Source/DealerSelection.DependencyInjection/InfrastructureRegistry.cs
  65. 7
      Source/DealerSelection.Infrastructure/AssignDealer/IAssignDealerRepository.cs
  66. 17
      Source/DealerSelection.Infrastructure/AssignDealer/Repository.cs
  67. 26
      Source/DealerSelection.Infrastructure/CustomerDetail/CustomerInfoDto.cs
  68. 13
      Source/DealerSelection.Infrastructure/CustomerDetail/IRepository.cs
  69. 116
      Source/DealerSelection.Infrastructure/CustomerDetail/Repository.cs
  70. 37
      Source/DealerSelection.Infrastructure/DealerSelection.Api.Infrastructure.csproj
  71. 6
      Source/DealerSelection.Infrastructure/InfoBip/IRepository.cs
  72. 45
      Source/DealerSelection.Infrastructure/InfoBip/Repository.cs
  73. 14
      Source/DealerSelection.Infrastructure/Jwt/AuthValidateModelDto.cs
  74. 9
      Source/DealerSelection.Infrastructure/Jwt/IJwtRepository.cs
  75. 23
      Source/DealerSelection.Infrastructure/Jwt/JwtRepository.cs
  76. 26
      Source/DealerSelection.Infrastructure/Mulesoft/DealerDetailDto.cs
  77. 10
      Source/DealerSelection.Infrastructure/Mulesoft/IRepository.cs
  78. 46
      Source/DealerSelection.Infrastructure/Mulesoft/MulesoftCustomerInfoDto.cs
  79. 134
      Source/DealerSelection.Infrastructure/Mulesoft/Repository.cs
  80. 27
      Source/DealerSelection.Interface/DealerSelection.Api.Interface.csproj
  81. 7
      Source/DealerSelection.Interface/IAssignDealerApi.cs
  82. 9
      Source/DealerSelection.Interface/IInfoBipSmsServiceApi.cs
  83. 9
      Source/DealerSelection.Interface/IJwtTokenApi.cs
  84. 20
      Source/DealerSelection.Interface/IMulesoftApi.cs
  85. 7
      Source/DealerSelection.Interface/IMulesoftTokenApi.cs
  86. 10
      Source/DealerSelection.Interface/IYellowAIApi.cs
  87. 14
      Source/DealerSelection.WebApi.Models/BikeResponse.cs
  88. 14
      Source/DealerSelection.WebApi.Models/BookingConfirmationRequest.cs
  89. 9
      Source/DealerSelection.WebApi.Models/CityResponse.cs
  90. 26
      Source/DealerSelection.WebApi.Models/CustomerInfoMappingResponse.cs
  91. 17
      Source/DealerSelection.WebApi.Models/CustomerInfoRequest.cs
  92. 20
      Source/DealerSelection.WebApi.Models/DealerSelection.WebApi.Models.csproj
  93. 34
      Source/DealerSelection.WebApi.Models/MulesoftResponse.cs
  94. 7
      Source/DealerSelection.WebApi.Models/PaymentLinkResponse.cs
  95. 16
      Source/DealerSelection.WebApi.Models/RegisterInterestSuccessfulResponse.cs
  96. 12
      Source/DealerSelection.WebApi.Models/Response.cs
  97. 24
      Source/DealerSelection.WebApi.Models/ReviewPayCustomerInfoResponse.cs
  98. 8
      Source/DealerSelection.WebApi.Models/StateResponse.cs
  99. 12
      Source/DealerSelection.WebApi/.config/dotnet-tools.json
  100. 36
      Source/DealerSelection.WebApi/App_Start/Mapper.cs

98
DealerSelectionAPI.sln

@ -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

14
Source/DealerSelection.Api.Models/AuthModel.cs

@ -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; }
}
}

14
Source/DealerSelection.Api.Models/AuthValidateModel.cs

@ -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; }
}
}

48
Source/DealerSelection.Api.Models/CustomerDealerInfoRequest.cs

@ -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}";
}
}

28
Source/DealerSelection.Api.Models/DealerSelection.Api.Models.csproj

@ -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>

10
Source/DealerSelection.Api.Models/DealerSelectionJobStatus.cs

@ -0,0 +1,10 @@
namespace DealerSelection.Api.Models;
public enum DealerSelectionJobStatus
{
OldData = -1,
ReadyForJob = 0,
Picked = 1,
SentToBot = 2,
Complete = 3,
}

21
Source/DealerSelection.Api.Models/MulesoftResponse.cs

@ -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; }
}

8
Source/DealerSelection.Api.Models/MulesoftToken.cs

@ -0,0 +1,8 @@

namespace DealerSelection.Api.Models;
public class MulesoftToken
{
public string Value { get; set; }
public int ExpiresIn { get; set; }
}

15
Source/DealerSelection.Api.Models/Procedure.cs

@ -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
}

31
Source/DealerSelection.Api.Models/Response.cs

@ -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
}

10
Source/DealerSelection.Api.Models/TokenValidProperty.cs

@ -0,0 +1,10 @@
namespace DealerSelection.Api.Models
{
public class TokenValidProperty
{
public bool isValid { get; set; }
public double Ttl { get; set; }
}
}

9
Source/DealerSelection.Api.Models/UnexpectedDataException.cs

@ -0,0 +1,9 @@
namespace DealerSelection.Api.Models
{
public class UnexpectedDataException : Exception
{
public UnexpectedDataException(string message, Exception innerException) : base(message, innerException)
{
}
}
}

70
Source/DealerSelection.Api.Models/WebEngageEvent.cs

@ -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; }
}

190
Source/DealerSelection.Api/AssignDealerApi.cs

@ -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);
}
}

151
Source/DealerSelection.Api/CommonUtil/AESEncryption.cs

@ -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;
}
}
}

132
Source/DealerSelection.Api/CommonUtil/CustomConfig.cs

@ -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;
}
}
}

28
Source/DealerSelection.Api/CommonUtil/GenerateRandomString.cs

@ -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;
}
}
}

86
Source/DealerSelection.Api/CommonUtil/MuleSoftTokenGenerate.cs

@ -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;
}
}
}

42
Source/DealerSelection.Api/DealerSelection.Api.csproj

@ -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>

143
Source/DealerSelection.Api/InfoBipSmsServiceApi.cs

@ -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; }
}

112
Source/DealerSelection.Api/JwtTokenApi.cs

@ -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;
}
}

722
Source/DealerSelection.Api/MulesoftApi.cs

@ -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 "";
}
}

68
Source/DealerSelection.Api/MulesoftTokenApi.cs

@ -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;
}
}

77
Source/DealerSelection.Api/YellowAIApi.cs

@ -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);
}
}

9
Source/DealerSelection.Common/CommonBaseClass/ExceptionBase.cs

@ -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)
{ }
}

92
Source/DealerSelection.Common/CommonBaseClass/ExceptionFilterBase.cs

@ -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", " ");
}
}

235
Source/DealerSelection.Common/CommonBaseClass/StartupBase.cs

@ -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();
}

6
Source/DealerSelection.Common/CommonBaseClass/WebApiConfigurationCfgBase.cs

@ -0,0 +1,6 @@
namespace DealerSelection.Common.CommonBaseClass;
public abstract class WebApiConfigurationCfgBase
{
}

102
Source/DealerSelection.Common/Configuration/ConfigurationHelper.cs

@ -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);
}
}
}

36
Source/DealerSelection.Common/Data/ConnectionHelper.cs

@ -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;
}
}

25
Source/DealerSelection.Common/Data/Dapper/RepositoryBaseDapperAsync.cs

@ -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>();
}
}

25
Source/DealerSelection.Common/Data/Dapper/RepositoryBaseDapperSync.cs

@ -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>();
}
}

30
Source/DealerSelection.Common/Data/Dapper/TypeMapHelper.cs

@ -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;
}
}

35
Source/DealerSelection.Common/Data/RepositoryBaseDIAsync.cs

@ -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;
}
}

35
Source/DealerSelection.Common/Data/RepositoryBaseDISync.cs

@ -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;
}
}

11
Source/DealerSelection.Common/Data/RepositoryDIBase.cs

@ -0,0 +1,11 @@

namespace DealerSelection.Common.Data;
public abstract class RepositoryDIBase
{
public string CxnString { get; }
protected RepositoryDIBase(string cxnName)
{
CxnString = ConnectionHelper.GetConnectionString(cxnName);
}
}

56
Source/DealerSelection.Common/DealerSelection.Common.csproj

@ -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>

24
Source/DealerSelection.Common/Entity/FieldMapAttribute.cs

@ -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;
}

8
Source/DealerSelection.Common/Exceptions/AuthorizationException.cs

@ -0,0 +1,8 @@
using DealerSelection.Common.CommonBaseClass;
namespace DealerSelection.Common.Exceptions;
public class AuthorizationException : ExceptionBase
{
public AuthorizationException(string message) : base(message) { }
}

8
Source/DealerSelection.Common/Exceptions/DataNotFoundException.cs

@ -0,0 +1,8 @@
using DealerSelection.Common.CommonBaseClass;
namespace DealerSelection.Common.Exceptions;
public class DataNotFoundException : ExceptionBase
{
public DataNotFoundException(string message) : base(message) { }
}

15
Source/DealerSelection.Common/Exceptions/DbConnectionException.cs

@ -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)
{
}
}

8
Source/DealerSelection.Common/Exceptions/DuplicateException.cs

@ -0,0 +1,8 @@
using DealerSelection.Common.CommonBaseClass;
namespace DealerSelection.Common.Exceptions;
public class DuplicateException : ExceptionBase
{
public DuplicateException(string message) : base(message) { }
}

8
Source/DealerSelection.Common/Exceptions/NullValueException.cs

@ -0,0 +1,8 @@
using DealerSelection.Common.CommonBaseClass;
namespace DealerSelection.Common.Exceptions;
public class NullValueException : ExceptionBase
{
public NullValueException(string message) : base(message) { }
}

8
Source/DealerSelection.Common/Exceptions/PartialSuccessException.cs

@ -0,0 +1,8 @@
using DealerSelection.Common.CommonBaseClass;
namespace DealerSelection.Common.Exceptions;
public class PartialSuccessException : ExceptionBase
{
public PartialSuccessException(string message) : base(message) { }
}

8
Source/DealerSelection.Common/Exceptions/ValidationException.cs

@ -0,0 +1,8 @@
using DealerSelection.Common.CommonBaseClass;
namespace DealerSelection.Common.Exceptions;
public class ValidationException : ExceptionBase
{
public ValidationException(string message) : base(message) { }
}

8
Source/DealerSelection.Common/Helpers/SwaggerCfg.cs

@ -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; }
}

38
Source/DealerSelection.Common/Helpers/SwashbuckleSchemaHelper.cs

@ -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();
}
}

21
Source/DealerSelection.Common/HttpClient/MyHttpClientHandler.cs

@ -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;
}
}

9
Source/DealerSelection.Common/Interfaces/Data/IRepositoryDIAsync.cs

@ -0,0 +1,9 @@
using System.Data.SqlClient;
namespace DealerSelection.Common.Interfaces.Data;
public interface IRepositoryDIAsync
{
string CxnString { get; }
Task<SqlConnection> OpenCxnAsync();
}

9
Source/DealerSelection.Common/Interfaces/Data/IRepositoryDISync.cs

@ -0,0 +1,9 @@
using System.Data.SqlClient;
namespace DealerSelection.Common.Interfaces.Data;
public interface IRepositoryDISync
{
string CxnString { get; }
SqlConnection OpenCxnSync();
}

8
Source/DealerSelection.Common/Interfaces/HttpClient/IHttpClientHandler.cs

@ -0,0 +1,8 @@

namespace DealerSelection.Common.Interfaces.HttpClient;
public interface IHttpClientHandler
{
System.Net.Http.HttpClient GetHttpClient();
}

24
Source/DealerSelection.Common/Logging/ApiInfo.cs

@ -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;
}
}

82
Source/DealerSelection.Common/Logging/AzureLogHelper.cs

@ -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))}";
}
}
}

28
Source/DealerSelection.Common/Logging/HttpHeaderHelper.cs

@ -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;
}
}

127
Source/DealerSelection.Common/Logging/LoggingMiddleware.cs

@ -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);
}
}

42
Source/DealerSelection.Common/Logging/RequestInfo.cs

@ -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}";
}
}

37
Source/DealerSelection.Common/Logging/ResponseInfo.cs

@ -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} ");
}
}

34
Source/DealerSelection.Common/Middleware/SwaggerRootRoutingMiddleware.cs

@ -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);
}
}

31
Source/DealerSelection.Common/Profiler/PerformanceProfiler.cs

@ -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;
}
}
}
}

19
Source/DealerSelection.Common/Profiler/Profiler.cs

@ -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;
}
}
}

35
Source/DealerSelection.DependencyInjection/ApiRegistry.cs

@ -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();
}
}

29
Source/DealerSelection.DependencyInjection/DealerSelection.DependencyInjection.csproj

@ -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>

11
Source/DealerSelection.DependencyInjection/DependencyInjectionBootStrapper.cs

@ -0,0 +1,11 @@
using Lamar;
namespace DealerSelection.DependencyInjection;
public class DependencyInjectionBootStrapper : ServiceRegistry
{
public DependencyInjectionBootStrapper()
{
IncludeRegistry<InfrastructureRegistry>();
IncludeRegistry<ApiRegistry>();
}
}

37
Source/DealerSelection.DependencyInjection/InfrastructureRegistry.cs

@ -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();
}
}

7
Source/DealerSelection.Infrastructure/AssignDealer/IAssignDealerRepository.cs

@ -0,0 +1,7 @@

namespace DealerSelection.Api.Infrastructure.AssignDealer;
public interface IAssignDealerRepository
{
}

17
Source/DealerSelection.Infrastructure/AssignDealer/Repository.cs

@ -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;
}
}

26
Source/DealerSelection.Infrastructure/CustomerDetail/CustomerInfoDto.cs

@ -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}";
}
}

13
Source/DealerSelection.Infrastructure/CustomerDetail/IRepository.cs

@ -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);
}

116
Source/DealerSelection.Infrastructure/CustomerDetail/Repository.cs

@ -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}");
}
}
}

37
Source/DealerSelection.Infrastructure/DealerSelection.Api.Infrastructure.csproj

@ -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>

6
Source/DealerSelection.Infrastructure/InfoBip/IRepository.cs

@ -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);
}

45
Source/DealerSelection.Infrastructure/InfoBip/Repository.cs

@ -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);
}
}
}

14
Source/DealerSelection.Infrastructure/Jwt/AuthValidateModelDto.cs

@ -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; }
}

9
Source/DealerSelection.Infrastructure/Jwt/IJwtRepository.cs

@ -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);
}

23
Source/DealerSelection.Infrastructure/Jwt/JwtRepository.cs

@ -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();
}
}

26
Source/DealerSelection.Infrastructure/Mulesoft/DealerDetailDto.cs

@ -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}.";
}
}

10
Source/DealerSelection.Infrastructure/Mulesoft/IRepository.cs

@ -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);
}

46
Source/DealerSelection.Infrastructure/Mulesoft/MulesoftCustomerInfoDto.cs

@ -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; }
}

134
Source/DealerSelection.Infrastructure/Mulesoft/Repository.cs

@ -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);
}
}
}

27
Source/DealerSelection.Interface/DealerSelection.Api.Interface.csproj

@ -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>

7
Source/DealerSelection.Interface/IAssignDealerApi.cs

@ -0,0 +1,7 @@
namespace DealerSelection.Api.Interface;
public interface IAssignDealerApi
{
Task GetCustomerDataForJob(int buId, int recordId);
}

9
Source/DealerSelection.Interface/IInfoBipSmsServiceApi.cs

@ -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);
}

9
Source/DealerSelection.Interface/IJwtTokenApi.cs

@ -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);
}

20
Source/DealerSelection.Interface/IMulesoftApi.cs

@ -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);
}

7
Source/DealerSelection.Interface/IMulesoftTokenApi.cs

@ -0,0 +1,7 @@

namespace DealerSelection.Api.Interface;
public interface IMulesoftTokenApi
{
Task<string> FetchToken();
}

10
Source/DealerSelection.Interface/IYellowAIApi.cs

@ -0,0 +1,10 @@

using DealerSelection.Api.Models;
namespace DealerSelection.Api.Interface;
public interface IYellowAIApi
{
Task UpdateSelectedDealer(CustomerDealerInfoRequest request);
}

14
Source/DealerSelection.WebApi.Models/BikeResponse.cs

@ -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; }
}

14
Source/DealerSelection.WebApi.Models/BookingConfirmationRequest.cs

@ -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; }
}

9
Source/DealerSelection.WebApi.Models/CityResponse.cs

@ -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; }
}

26
Source/DealerSelection.WebApi.Models/CustomerInfoMappingResponse.cs

@ -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; }
}

17
Source/DealerSelection.WebApi.Models/CustomerInfoRequest.cs

@ -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; }
}

20
Source/DealerSelection.WebApi.Models/DealerSelection.WebApi.Models.csproj

@ -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>

34
Source/DealerSelection.WebApi.Models/MulesoftResponse.cs

@ -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; }
}

7
Source/DealerSelection.WebApi.Models/PaymentLinkResponse.cs

@ -0,0 +1,7 @@

namespace DealerSelection.WebApi.Models;
public class PaymentLinkResponse : Response
{
public string SourceUrl { get; set; }
}

16
Source/DealerSelection.WebApi.Models/RegisterInterestSuccessfulResponse.cs

@ -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; }
}

12
Source/DealerSelection.WebApi.Models/Response.cs

@ -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; }
}

24
Source/DealerSelection.WebApi.Models/ReviewPayCustomerInfoResponse.cs

@ -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; }
}

8
Source/DealerSelection.WebApi.Models/StateResponse.cs

@ -0,0 +1,8 @@
namespace DealerSelection.WebApi.Models;
public class StateResponse
{
public string State { get; set; }
public string StateCode { get; set; }
}

12
Source/DealerSelection.WebApi/.config/dotnet-tools.json

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "7.0.9",
"commands": [
"dotnet-ef"
]
}
}
}

36
Source/DealerSelection.WebApi/App_Start/Mapper.cs

@ -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

Loading…
Cancel
Save