using DealerSelection.Api.CommonUtil; using CustomerDetailRepo = DealerSelection.Api.Infrastructure.CustomerDetail; using DealerSelection.Api.Infrastructure.Mulesoft; using DealerSelection.Api.Interface; using DealerSelection.Api.Models; using DealerSelection.Api.Models.Enum; 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("muleSoftAPIDomain", true); public static string dealerDetailApiUrl = ConfigurationHelper.GetSetting("muleSoftDealerDetail", true); public static string bookingApiUrl = ConfigurationHelper.GetSetting("muleSoftBookingAPILeadSquareDomain", true); public static string masterSchemaId = ConfigurationHelper.GetSetting("masterSchemaId", true); public static string masterDealerDetailSchemaId = ConfigurationHelper.GetSetting("masterDealerDetailSchemaId", true); #endregion #region Caching public static string CacheGetDealersDetail = ConfigurationHelper.GetSetting("MuleSoftCacheGetDealersDetail", true); private int _cacheGetDealersDetail = !string.IsNullOrEmpty(CacheGetDealersDetail) ? int.Parse(CacheGetDealersDetail) : 10; public static string CacheGetPriceOnState = ConfigurationHelper.GetSetting("MuleSoftCacheGetPriceOnState", true); private int _cacheGetPriceOnState = !string.IsNullOrEmpty(CacheGetPriceOnState) ? int.Parse(CacheGetPriceOnState) : 10; public static string CacheGetModelOnBrand = ConfigurationHelper.GetSetting("MuleSoftCacheGetModelOnBrand", true); private int _cacheGetModelOnBrand = !string.IsNullOrEmpty(CacheGetModelOnBrand) ? int.Parse(CacheGetModelOnBrand) : 10; public static string CacheGetActiveState = ConfigurationHelper.GetSetting("MuleSoftCacheGetActiveState", true); private int _cacheGetActiveState = !string.IsNullOrEmpty(CacheGetActiveState) ? int.Parse(CacheGetActiveState) : 10; public static string CacheGetActiveCity = ConfigurationHelper.GetSetting("MuleSoftCacheGetActiveCity", true); private int _cacheGetActiveCity = !string.IsNullOrEmpty(CacheGetActiveCity) ? int.Parse(CacheGetActiveCity) : 10; public static string CacheModelDetails = ConfigurationHelper.GetSetting("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; private CustomerDetailRepo.IRepository CustomerDetailRepository { get; } public MulesoftApi(IRepository repository, IMulesoftTokenApi mulesoftTokenApi, CustomerDetailRepo.IRepository customerRepo, IHttpClientHandler clientHandler, IMemoryCache memoryCache, ILogger logger) { Repository = repository; MulesoftTokenApi = mulesoftTokenApi; ClientHandler = clientHandler; _memoryCache = memoryCache; _logger = logger; CustomerDetailRepository = customerRepo; } public async Task 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($"DS Api:-BUID:- " + buId + "Api:- GetDealers:- " + ex.StackTrace.ToString()); } return response; } public async Task GetAndInsertDealerDetails(int buId, string dealerCode) { MulesoftResponse response = null; try { var cacheKey = "getDealerDetails_" + buId + dealerCode; if (!_memoryCache.TryGetValue(cacheKey, out response)) { _logger.LogInformation("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($"DS Api:-GetAndInsertDealerDetails From Cache:- {cacheKey}"); } catch (Exception ex) { _logger.LogError($"DS Api:- GetAndInsertDealerDetails:- {ex.Message.ToString()}"); } return response; } public async Task InsertLSQData(MulesoftCustomerInfoDto customerInfo) { try { try { if (customerInfo.Status == "Successful") { await UpdateDetails(customerInfo, DealerSelectionJobStatus.Complete); } var responseApi = await CallLSQBookingApi(customerInfo); } catch (Exception ex) { //await UpdateDetails(customerInfo, DealerSelectionJobStatus.ReadyForJob); _logger.LogError($"DS Api:-Error in LSQ " + ex.StackTrace.ToString()); } } catch (Exception ex) { _logger.LogError($"DS Api:-Api:- GetDealers:- " + ex.StackTrace.ToString()); } } #region Private Methods private async Task CallLSQBookingApi(MulesoftCustomerInfoDto customerInfo) { CustomCfg cfg = CustomCfg.GetCustomCfg(customerInfo.BuId); _logger.LogInformation($"DS Api:-BU:- {customerInfo.BuId} at MulesofApi:- CallBookingApi for Booking Id:- {customerInfo.BookingId}"); try { if (customerInfo != null) { string mx_Composite_Key = string.Empty, enquiryClassification = string.Empty, autoModel = string.Empty, dealerCode = string.Empty, status = string.Empty, bookingId = string.Empty, cCTransactionId = string.Empty, receiptId = string.Empty, amountPaid = string.Empty, leadPlatform = "Website", isSuccessBooking = "True", isDefaultDealer = "No"; 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; } dealerCode = customerInfo.DealerCode; status = customerInfo.Status; bookingId = customerInfo.BookingId; cCTransactionId = customerInfo.CCTransactionId; receiptId = customerInfo.ReceiptId; amountPaid = customerInfo.AmountPaid; if (customerInfo.DealerCode == cfg.DeafaultDealerCode) { isDefaultDealer = "Yes"; } string pincode = customerInfo.PinCode; //default pincode value, incase pincode column is empty for the record if (string.IsNullOrEmpty(pincode)) pincode = "400070"; dynamic message = null; if (customerInfo.Status == "Successful" && !string.IsNullOrWhiteSpace(customerInfo.DealerCode) && !string.IsNullOrWhiteSpace(customerInfo.ModelCode)) { enquiryClassification = "Hot"; autoModel = "Yes"; LsqSuccessData lsqData = new LsqSuccessData(cfg.BuCode, customerInfo.ModelCode, customerInfo.ColorCode, customerInfo.CustomerName , "", dealerCode, customerInfo.MobileNumber, "true", pincode, "Digital" , mx_Source_Of_Enquiry, mx_Enquiry_Sub_source, "", mx_Composite_Key, enquiryClassification , autoModel, "", bookingId, status, cCTransactionId, receiptId, amountPaid , "", "", "", utmSource, utmMedium, sourceCampaign, utmContent, customerInfo.IsWhatsappOptIn.ToString() , leadPlatform, isDefaultDealer); message = JsonConvert.SerializeObject(lsqData); } else { enquiryClassification = "Cold"; autoModel = "No"; status = string.Empty; bookingId = string.Empty; cCTransactionId = string.Empty; receiptId = string.Empty; amountPaid = string.Empty; isSuccessBooking = "False"; LsqData lsqData = new LsqData(cfg.BuCode, customerInfo.ModelCode, customerInfo.ColorCode, customerInfo.CustomerName , "", "", customerInfo.MobileNumber, "true", pincode, "Digital" , mx_Source_Of_Enquiry, mx_Enquiry_Sub_source, "", mx_Composite_Key, enquiryClassification , autoModel, "", bookingId, status, cCTransactionId, receiptId, amountPaid , "", "", "", utmSource, utmMedium, sourceCampaign, utmContent, customerInfo.IsWhatsappOptIn.ToString() , leadPlatform); message = JsonConvert.SerializeObject(lsqData); } 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($"DS Api:-Api:- CallBookingApi:- " + ex.StackTrace.ToString()); } return new Response(customerInfo.BuId, 0, false, "false", "", ""); } 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($"DS Api:-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($"DS Api:-Api:- DecryptBookingApi:- " + ex.StackTrace.ToString()); } return _leadData; } private async Task 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($"DS Api:-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 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($"DS Api:-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($"DS Api:- GetUTMDetails:- " + ex.Message.ToString()); } return ""; } private async Task UpdateDetails(MulesoftCustomerInfoDto customerInfo, DealerSelectionJobStatus jobStatus) { _logger.LogInformation($"DS Api:-UpdateDetails Started:- {customerInfo} JobStatus {jobStatus}"); try { CustomerDetailRepo.CustomerDealerInfoRequestDto dto = new() { BuId = customerInfo.BuId, RecordId = customerInfo.RecordId, MobileNumber = customerInfo.MobileNumber, DealerName = jobStatus == DealerSelectionJobStatus.Complete ? customerInfo.DealerName : "", DealerCode = jobStatus == DealerSelectionJobStatus.Complete ? customerInfo.DealerCode : "", DealerSelectionJobStatus = jobStatus == DealerSelectionJobStatus.Complete ? DealerSelectionJobStatus.Complete : DealerSelectionJobStatus.ReadyForJob, PinCode = customerInfo.PinCode, Latitude = customerInfo.CustomerLat, Longitude = customerInfo.CustomerLong, DealerSelectedMode = customerInfo.DealerSelectedMode }; await CustomerDetailRepository.UpdateDealerDetail(dto); } catch (Exception ex) { _logger.LogError($"DS Api:- UpdateDetails:- " + ex.Message.ToString()); } _logger.LogInformation($"DS Api:-UpdateDetails End:- {customerInfo} JobStatus {jobStatus}"); } #endregion }