diff --git a/src/DataAccess/Migrations/Custom/BaselineV7_Seed.cs b/src/DataAccess/Migrations/Custom/BaselineV7_Seed.cs index e39776ec..295a9262 100644 --- a/src/DataAccess/Migrations/Custom/BaselineV7_Seed.cs +++ b/src/DataAccess/Migrations/Custom/BaselineV7_Seed.cs @@ -14,10 +14,46 @@ public static void BaselineV7_SeedData(this MigrationBuilder migrationBuilder) { var seedDate = DateTime.Now; migrationBuilder.Sql(@$" - IF NOT EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'WebNotificationUrl') - BEGIN - INSERT [dbo].[ApplicationConfiguration] ( [Name], [Value], [Description]) VALUES ( N'WebNotificationUrl', N'', N'Setting this URL will enable pushing LandingPage/Webhook events to this external URL') - END + IF NOT EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'WebNotificationUrl') + BEGIN + INSERT [dbo].[ApplicationConfiguration] ( [Name], [Value], [Description]) VALUES ( N'WebNotificationUrl', N'', N'Setting this URL will enable pushing LandingPage/Webhook events to this external URL') + END + + IF NOT EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'EnablesSuccessfulSchedulerEmail') + BEGIN + INSERT [dbo].[ApplicationConfiguration] ( [Name], [Value], [Description]) VALUES ( N'EnablesSuccessfulSchedulerEmail', N'False', N'This will enable sending email for successful metered usage.') + END + + IF NOT EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'EnablesFailureSchedulerEmail') + BEGIN + INSERT [dbo].[ApplicationConfiguration] ( [Name], [Value], [Description]) VALUES ( N'EnablesFailureSchedulerEmail', N'False', N'This will enable sending email for failure metered usage.') + END + + IF NOT EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'EnablesMissingSchedulerEmail') + BEGIN + INSERT [dbo].[ApplicationConfiguration] ( [Name], [Value], [Description]) VALUES ( N'EnablesMissingSchedulerEmail', N'False', N'This will enable sending email for missing metered usage.') + END + + IF NOT EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'SchedulerEmailTo') + BEGIN + INSERT [dbo].[ApplicationConfiguration] ( [Name], [Value], [Description]) VALUES ( N'SchedulerEmailTo', N'', N'Scheduler email receiver(s) ') + END + + IF NOT EXISTS (SELECT * FROM [dbo].[EmailTemplate] WHERE [Status] = 'Accepted') + BEGIN + INSERT [dbo].[EmailTemplate] ([Status],[Description],[InsertDate],[TemplateBody],[Subject],[isActive]) VALUES (N'Accepted',N'Accepted',GetDate(),N'

Subscription ****SubscriptionName****


The Scheduled Task ****SchedulerTaskName**** was fired Successfully

The following section is the deatil results.


****ResponseJson****
',N'Scheduled SaaS Metered Usage Submitted Successfully!',N'True') + END + + IF NOT EXISTS (SELECT * FROM [dbo].[EmailTemplate] WHERE [Status] = 'Failure') + BEGIN + INSERT [dbo].[EmailTemplate] ([Status],[Description],[InsertDate],[TemplateBody],[Subject],[isActive]) VALUES (N'Failure',N'Failure',GetDate(),N'

Subscription ****SubscriptionName****


The Scheduled Task ****SchedulerTaskName**** was fired but Failed to Submit Data


Please try again or contact technical support to troubleshoot the issue.

The following section is the deatil results.


****ResponseJson****
',N'Scheduled SaaS Metered Usage Failure!',N'True') + END + + IF NOT EXISTS (SELECT * FROM [dbo].[EmailTemplate] WHERE [Status] = 'Missing') + BEGIN + INSERT [dbo].[EmailTemplate] ([Status],[Description],[InsertDate],[TemplateBody],[Subject],[isActive]) VALUES (N'Missing',N'Missing',GetDate(),N'

Subscription ****SubscriptionName****


The Scheduled Task ****SchedulerTaskName**** was skipped by scheduler engine!


Please try again or contact technical support to troubleshoot the issue.

The following section is the deatil results.


****ResponseJson****
',N'Scheduled SaaS Metered Task was Skipped!',N'True') + END + GO"); } @@ -28,6 +64,42 @@ IF EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'WebNot BEGIN DELETE FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'WebNotificationUrl' END + + IF EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'EnablesSuccessfulSchedulerEmail') + BEGIN + DELETE FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'EnablesSuccessfulSchedulerEmail' + END + + IF EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'EnablesFailureSchedulerEmail') + BEGIN + DELETE FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'EnablesFailureSchedulerEmail' + END + + IF EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'EnablesMissingSchedulerEmail') + BEGIN + DELETE FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'EnablesMissingSchedulerEmail' + END + + IF EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'SchedulerEmailTo') + BEGIN + DELETE FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'SchedulerEmailTo' + END + + IF EXISTS (SELECT * FROM [dbo].[EmailTemplate] WHERE [Status] = 'Accepted') + BEGIN + DELETE FROM [dbo].[EmailTemplate] WHERE [Status] = 'Accepted' + END + + IF EXISTS (SELECT * FROM [dbo].[EmailTemplate] WHERE [Status] = 'Failure') + BEGIN + DELETE FROM [dbo].[EmailTemplate] WHERE [Status] = 'Failure' + END + + IF EXISTS (SELECT * FROM [dbo].[EmailTemplate] WHERE [Status] = 'Missing') + BEGIN + DELETE FROM [dbo].[EmailTemplate] WHERE [Status] = 'Missing' + END + GO"); } } diff --git a/src/MeteredTriggerJob/MeteredTriggerHelper.cs b/src/MeteredTriggerJob/MeteredTriggerHelper.cs index 694215d3..acda2c03 100644 --- a/src/MeteredTriggerJob/MeteredTriggerHelper.cs +++ b/src/MeteredTriggerJob/MeteredTriggerHelper.cs @@ -8,64 +8,123 @@ using Marketplace.SaaS.Accelerator.Services.Exceptions; using Marketplace.SaaS.Accelerator.Services.Models; using Marketplace.SaaS.Accelerator.Services.Services; +using Microsoft.AspNetCore.Mvc; namespace Marketplace.SaaS.Accelerator.MeteredTriggerJob; public class Executor { - - private MeteredPlanSchedulerManagementService schedulerService; - private ISchedulerFrequencyRepository frequencyRepository; + /// + /// Frequency Repository Interface + /// + private readonly ISchedulerFrequencyRepository frequencyRepository; + /// + /// Scheduler Repository Interface + /// private IMeteredPlanSchedulerManagementRepository schedulerRepository; - private ISchedulerManagerViewRepository schedulerViewRepository; + /// + /// Scheduler View Repository Interface + /// + private readonly ISchedulerManagerViewRepository schedulerViewRepository; + /// + /// Subscription Usage Logs Repository Interface + /// private ISubscriptionUsageLogsRepository subscriptionUsageLogsRepository; + /// + /// Metered Billing Api Service Interface + /// private readonly IMeteredBillingApiService billingApiService; + /// + /// Application Config Repository Interface + /// private readonly IApplicationConfigRepository applicationConfigRepository; + /// + /// Email Template Repository Interface + /// + private readonly IEmailTemplateRepository emailTemplateRepository; + /// + /// Email Service Interface + /// + private IEmailService emailService; + /// + /// Metered Plan Scheduler Management Service + /// + private MeteredPlanSchedulerManagementService schedulerService; + /// + /// Application Log Service + /// + private ApplicationLogService applicationLogService = null; + private ApplicationConfigService applicationConfigService = null; + /// + /// Initiate dependency components + /// + /// + /// + /// + /// + /// + /// + /// + /// public Executor(ISchedulerFrequencyRepository frequencyRepository, IMeteredPlanSchedulerManagementRepository schedulerRepository, ISchedulerManagerViewRepository schedulerViewRepository, - ISubscriptionUsageLogsRepository subscriptionUsageLogsRepository, + ISubscriptionUsageLogsRepository subscriptionUsageLogsRepository, IMeteredBillingApiService billingApiService, - IApplicationConfigRepository applicationConfigRepository) + IApplicationConfigRepository applicationConfigRepository, + IEmailService emailService, + IEmailTemplateRepository emailTemplateRepository, IApplicationLogRepository applicationLogRepository) { this.frequencyRepository = frequencyRepository; this.schedulerRepository = schedulerRepository; this.schedulerViewRepository = schedulerViewRepository; this.subscriptionUsageLogsRepository = subscriptionUsageLogsRepository; - this.schedulerService = new MeteredPlanSchedulerManagementService(this.frequencyRepository, this.schedulerRepository, this.schedulerViewRepository, this.subscriptionUsageLogsRepository, this.applicationConfigRepository); this.billingApiService = billingApiService; this.applicationConfigRepository = applicationConfigRepository; + this.emailTemplateRepository = emailTemplateRepository; + this.emailService = emailService; + schedulerService = new MeteredPlanSchedulerManagementService(this.frequencyRepository, + this.schedulerRepository, + this.schedulerViewRepository, + this.subscriptionUsageLogsRepository, + this.applicationConfigRepository, + this.emailTemplateRepository, + this.emailService); + this.billingApiService = billingApiService; + + this.applicationLogService = new ApplicationLogService(applicationLogRepository); + this.applicationConfigService = new ApplicationConfigService(applicationConfigRepository); } + /// + /// Execute the scheduler engine + /// public void Execute() - { - schedulerService = new MeteredPlanSchedulerManagementService(frequencyRepository, - schedulerRepository, - schedulerViewRepository, - subscriptionUsageLogsRepository,applicationConfigRepository); - - + { //Get all Scheduled Data List getAllSchedulerManagerViewData = schedulerService.GetAllSchedulerManagerList(); + //GetCurrentUTC time DateTime _currentUTCTime = DateTime.UtcNow; TimeSpan ts = new TimeSpan(DateTime.UtcNow.Hour, 0, 0); _currentUTCTime = _currentUTCTime.Date + ts; + // Send Email in case of missing Scheduler + bool.TryParse(this.applicationConfigService.GetValueByName("EnablesMissingSchedulerEmail"), out bool enablesMissingSchedulerEmail); //Process each scheduler frequency foreach (SchedulerFrequencyEnum frequency in Enum.GetValues(typeof(SchedulerFrequencyEnum))) { - var ableToParse = bool.TryParse(this.applicationConfigRepository.GetValueByName($"Enable{frequency}MeterSchedules"), out bool runSchedulerForThisFrequency); + + var ableToParse = bool.TryParse(this.applicationConfigService.GetValueByName($"Enable{frequency}MeterSchedules"), out bool runSchedulerForThisFrequency); if (ableToParse && runSchedulerForThisFrequency) { - Console.WriteLine(); - Console.WriteLine($"==== Checking all {frequency} scheduled items at {_currentUTCTime} UTC. ===="); + LogLine($"==== Checking all {frequency} scheduled items at {_currentUTCTime} UTC. ===="); var scheduledItems = getAllSchedulerManagerViewData .Where(a => a.Frequency == frequency.ToString()) @@ -86,44 +145,54 @@ public void Execute() //Past scheduler items if (timeDifferentInHours > 0) { - Console.WriteLine($"Item Id: {scheduledItem.Id} will not run as {_nextRunTime} has passed. Please check audit logs if its has run previously."); + var msg = $"Scheduled Item Id: {scheduledItem.Id} will not run as {_nextRunTime} has passed. Please check audit logs if its has run previously."; + LogLine(msg,true); + + + if (enablesMissingSchedulerEmail) + { + var newMeteredAuditLog = new MeteredAuditLogs() + { + StatusCode = "Missing", + ResponseJson = msg + }; + SendMissingEmail(scheduledItem,newMeteredAuditLog); + } + continue; } else if (timeDifferentInHours < 0) { - Console.WriteLine($"Item Id: {scheduledItem.Id} future run will be at {_nextRunTime} UTC."); + LogLine($"Scheduled Item Id: {scheduledItem.Id} future run will be at {_nextRunTime} UTC."); + continue; } else if (timeDifferentInHours == 0) { - TriggerSchedulerItem(scheduledItem, - frequency, - billingApiService, - schedulerService, - subscriptionUsageLogsRepository); + TriggerSchedulerItem(scheduledItem); } else { - Console.WriteLine($"Item Id: {scheduledItem.Id} will not run as it doesn't match any time difference logic. {_nextRunTime} UTC."); + LogLine($"Scheduled Item Id: {scheduledItem.Id} will not run as it doesn't match any time difference logic. {_nextRunTime} UTC."); } + } } else { - Console.WriteLine($"{frequency} scheduled items will not be run as it's disabled in the application config."); + LogLine($"{frequency} scheduled items will not be run as it's disabled in the application config."); } } } - - public static void TriggerSchedulerItem(SchedulerManagerViewModel item, - SchedulerFrequencyEnum frequency, - IMeteredBillingApiService billingApiService, - MeteredPlanSchedulerManagementService schedulerService, - ISubscriptionUsageLogsRepository subscriptionUsageLogsRepository) + /// + /// Trigger scheduler task + /// + /// scheduler task + private void TriggerSchedulerItem(SchedulerManagerViewModel item) { try { - Console.WriteLine($"---- Item Id: {item.Id} Start Triggering meter event ----"); + LogLine($"---- Scheduled Item Id: {item.Id} Start Triggering meter event ----",true); var subscriptionUsageRequest = new MeteringUsageRequest() { @@ -138,41 +207,38 @@ public static void TriggerSchedulerItem(SchedulerManagerViewModel item, var responseJson = string.Empty; try { - Console.WriteLine($"Item Id: {item.Id} Request {requestJson}"); + LogLine($"Scheduled Item Id: {item.Id} Request {requestJson}", true); meteringUsageResult = billingApiService.EmitUsageEventAsync(subscriptionUsageRequest).ConfigureAwait(false).GetAwaiter().GetResult(); responseJson = JsonSerializer.Serialize(meteringUsageResult); - Console.WriteLine($"Item Id: {item.Id} Response {responseJson}"); + LogLine($"Scheduled Item Id: {item.Id} Response {responseJson}", true); } catch (MarketplaceException marketplaceException) { responseJson = JsonSerializer.Serialize(marketplaceException.Message); meteringUsageResult.Status = marketplaceException.ErrorCode; - Console.WriteLine($" Item Id: {item.Id} Error during EmitUsageEventAsync {responseJson}"); + LogLine($"Scheduled Item Id: {item.Id} Error during EmitUsageEventAsync {responseJson}", true); } - UpdateSchedulerItem(item, - requestJson, - responseJson, - meteringUsageResult.Status, - schedulerService, - subscriptionUsageLogsRepository); + UpdateSchedulerItem(item,requestJson, responseJson,meteringUsageResult.Status); } catch (Exception ex) { - Console.WriteLine(ex.Message); + LogLine(ex.Message, true); } } - public static void UpdateSchedulerItem(SchedulerManagerViewModel item, - string requestJson, - string responseJson, - string status, - MeteredPlanSchedulerManagementService schedulerService, - ISubscriptionUsageLogsRepository subscriptionUsageLogsRepository) + /// + /// Update Scheduler Item + /// + /// scheduler task + /// usage post payload + /// API respond + /// status code + private void UpdateSchedulerItem(SchedulerManagerViewModel item,string requestJson,string responseJson,string status) { try { - Console.WriteLine($"Item Id: {item.Id} Saving Audit information"); + LogLine($"Scheduled Item Id: {item.Id} Saving Audit information", true); var scheduler = schedulerService.GetSchedulerDetailById(item.Id); var newMeteredAuditLog = new MeteredAuditLogs() { @@ -187,9 +253,9 @@ public static void UpdateSchedulerItem(SchedulerManagerViewModel item, }; subscriptionUsageLogsRepository.Save(newMeteredAuditLog); - if ((status == "Accepted")) + if ((status == "Accepted")) { - Console.WriteLine($"Item Id: {item.Id} Meter event Accepted"); + LogLine($"Scheduled Item Id: {item.Id} Meter event Accepted", true); //Ignore updating NextRuntime value for OneTime frequency as they always depend on StartTime value Enum.TryParse(item.Frequency, out SchedulerFrequencyEnum itemFrequency); @@ -197,37 +263,58 @@ public static void UpdateSchedulerItem(SchedulerManagerViewModel item, { scheduler.NextRunTime = GetNextRunTime(item.NextRunTime ?? item.StartDate, itemFrequency); - Console.WriteLine($"Item Id: {item.Id} Updating Scheduler NextRunTime from {item.NextRunTime} to {scheduler.NextRunTime}"); + LogLine($"Scheduled Item Id: {item.Id} Updating Scheduler NextRunTime from {item.NextRunTime} to {scheduler.NextRunTime}", true); schedulerService.UpdateSchedulerNextRunTime(scheduler); } } else { - Console.WriteLine($"Item Id: {item.Id} failed with status {status}. NextRunTime will not be updated."); + LogLine($"Scheduled Item Id: {item.Id} failed with status {status}. NextRunTime will not be updated.", true); + } + LogLine($"Scheduled Item Id: {item.Id} Complete Triggering Meter event.", true); + + // Check if Sending Email is Enabled + _= bool.TryParse(applicationConfigService.GetValueByName("EnablesSuccessfulSchedulerEmail"), out bool enablesSuccessfulSchedulerEmail); + _ = bool.TryParse(applicationConfigService.GetValueByName("EnablesFailureSchedulerEmail"), out bool enablesFailureSchedulerEmail); + if(enablesFailureSchedulerEmail || enablesSuccessfulSchedulerEmail) + { + LogLine("Send scheduled Email"); + schedulerService.SendSchedulerEmail(item, newMeteredAuditLog); } - Console.WriteLine($"Item Id: {item.Id} Complete Triggering Meter event."); } catch (Exception ex) { - Console.WriteLine(ex.Message); + LogLine(ex.Message); } } - public static void PrintScheduler(SchedulerManagerViewModel item, + /// + /// Print Scheduler item + /// + /// scheduler item + /// next run time + /// difference time + private void PrintScheduler(SchedulerManagerViewModel item, DateTime? nextRun, int timeDifferenceInHours) { - Console.WriteLine($"Item Id: {item.Id} " + - $"Expected NextRun : {nextRun} " + - $"SubId : {item.AMPSubscriptionId} " + - $"Plan : {item.PlanId} " + - $"Dim : {item.Dimension} " + - $"Start Date : {item.StartDate} " + - $"NextRun : {item.NextRunTime}" + - $"TimeDifferenceInHours : {timeDifferenceInHours}"); + LogLine($"Scheduled Item Id: {item.Id} " + Environment.NewLine+ + $"Expected NextRun : {nextRun} "+Environment.NewLine+ + $"SubId : {item.AMPSubscriptionId} "+Environment.NewLine+ + $"Plan : {item.PlanId} " + Environment.NewLine + + $"Dim : {item.Dimension} " + Environment.NewLine + + $"Start Date : {item.StartDate} " + Environment.NewLine + + $"NextRun : {item.NextRunTime}" + Environment.NewLine + + $"TimeDifferenceInHours : {timeDifferenceInHours}" + Environment.NewLine ); } - public static DateTime? GetNextRunTime(DateTime? startDate, SchedulerFrequencyEnum frequency) + /// + /// Get Next Run Time + /// + /// Start task Date + /// Task frequency + /// + private DateTime? GetNextRunTime(DateTime? startDate, SchedulerFrequencyEnum frequency) { switch (frequency) { @@ -241,4 +328,23 @@ public static void PrintScheduler(SchedulerManagerViewModel item, { return null; } } } + + private void LogLine(string message, bool appplicationLog=false) { + Console.WriteLine(message); + if(appplicationLog) + this.applicationLogService.AddApplicationLog(message).ConfigureAwait(false); + + } + + private void SendMissingEmail(SchedulerManagerViewModel schedulerTask, MeteredAuditLogs meteredAuditItem) + { + // check if the task was run before + if(!this.schedulerService.CheckIfSchedulerRun(schedulerTask.Id,schedulerTask.SchedulerName)) + { + // send email if it never ran + schedulerService.SendSchedulerEmail(schedulerTask, meteredAuditItem); + } + + + } } \ No newline at end of file diff --git a/src/MeteredTriggerJob/Program.cs b/src/MeteredTriggerJob/Program.cs index aa104fef..47f4aff8 100644 --- a/src/MeteredTriggerJob/Program.cs +++ b/src/MeteredTriggerJob/Program.cs @@ -16,6 +16,10 @@ namespace Marketplace.SaaS.Accelerator.MeteredTriggerJob; class Program { + /// + /// Entery point to the scheduler engine + /// + /// static void Main (string[] args) { @@ -39,11 +43,14 @@ static void Main (string[] args) var creds = new ClientSecretCredential(config.TenantId.ToString(), config.ClientId.ToString(), config.ClientSecret); var services = new ServiceCollection() - .AddDbContext(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"))) + .AddDbContext(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient) .AddScoped() .AddScoped() .AddScoped() .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() .AddScoped() .AddSingleton(new MeteredBillingApiService(new MarketplaceMeteringClient(creds), config, new SaaSClientLogger())) .AddSingleton() diff --git a/src/Services/Helpers/EmailHelper.cs b/src/Services/Helpers/EmailHelper.cs index 7c0596a6..125601d4 100644 --- a/src/Services/Helpers/EmailHelper.cs +++ b/src/Services/Helpers/EmailHelper.cs @@ -63,20 +63,11 @@ public EmailContentModel PrepareEmailContent(Guid subscriptionID, Guid planGuId, } string subject = string.Empty; - bool copyToCustomer = false; - bool isActive = false; string toReceipents = string.Empty; string ccReceipents = string.Empty; string bccReceipents = string.Empty; - string fromMail = this.applicationConfigRepository.GetValueByName("SMTPFromEmail"); - string password = this.applicationConfigRepository.GetValueByName("SMTPPassword"); - string username = this.applicationConfigRepository.GetValueByName("SMTPUserName"); - bool smtpSsl = bool.Parse(this.applicationConfigRepository.GetValueByName("SMTPSslEnabled")); - int port = int.Parse(this.applicationConfigRepository.GetValueByName("SMTPPort")); - string smtpHost = this.applicationConfigRepository.GetValueByName("SMTPHost"); - var eventData = this.planEventsMappingRepository.GetPlanEvent(planGuId, subscriptionEvent.EventsId); if (eventData != null) @@ -105,20 +96,49 @@ public EmailContentModel PrepareEmailContent(Guid subscriptionID, Guid planGuId, subject = emailTemplateData.Subject; } - emailContent.BCCEmails = bccReceipents; - emailContent.CCEmails = ccReceipents; - emailContent.ToEmails = toReceipents; - emailContent.Body = body; - emailContent.Subject = subject; + return FinalizeContentEmail(subject, body, ccReceipents, bccReceipents, toReceipents, copyToCustomer); + + } + /// + /// Prepares the content of the scheduler email. + /// + /// The subscription Name. + /// scheduler Task Name. + /// response Json. + /// The subscription status. + /// + /// Email Content Model. + /// + /// Error while sending an email, please check the configuration. + /// or + /// Error while sending an email, please check the configuration. + public EmailContentModel PrepareMeteredEmailContent(string schedulerTaskName, String subscriptionName, string subscriptionStatus, string responseJson) + { + var emailTemplateData = this.emailTemplateRepository.GetTemplateForStatus(subscriptionStatus); + string toReceipents = this.applicationConfigRepository.GetValueByName("SchedulerEmailTo"); + if (string.IsNullOrEmpty(toReceipents)) + { + throw new Exception(" Error while sending an email, please check the configuration. "); + } + var body = emailTemplateData.TemplateBody.Replace("****SubscriptionName****", subscriptionName).Replace("****SchedulerTaskName****", schedulerTaskName).Replace("****ResponseJson****", responseJson); ; + return FinalizeContentEmail(emailTemplateData.Subject,body, string.Empty, string.Empty, toReceipents, false); + } + private EmailContentModel FinalizeContentEmail(string subject, string body, string ccEmails,string bcEmails, string toEmails, bool copyToCustomer) + { + EmailContentModel emailContent = new EmailContentModel(); + emailContent.BCCEmails = bcEmails; + emailContent.CCEmails = ccEmails; + emailContent.ToEmails = toEmails; + emailContent.IsActive = false; emailContent.CopyToCustomer = copyToCustomer; - emailContent.IsActive = isActive; - emailContent.FromEmail = fromMail; - emailContent.Password = password; - emailContent.SSL = smtpSsl; - emailContent.UserName = username; - emailContent.Port = port; - emailContent.SMTPHost = smtpHost; - + emailContent.FromEmail = this.applicationConfigRepository.GetValueByName("SMTPFromEmail"); + emailContent.Password = this.applicationConfigRepository.GetValueByName("SMTPPassword"); + emailContent.SSL = bool.Parse(this.applicationConfigRepository.GetValueByName("SMTPSslEnabled")); + emailContent.UserName = this.applicationConfigRepository.GetValueByName("SMTPUserName"); + emailContent.Port = int.Parse(this.applicationConfigRepository.GetValueByName("SMTPPort")); + emailContent.SMTPHost = this.applicationConfigRepository.GetValueByName("SMTPHost"); return emailContent; } + + } \ No newline at end of file diff --git a/src/Services/Services/ApplicationConfigurationService.cs b/src/Services/Services/ApplicationConfigurationService.cs index 24f9f57e..d1e6ab30 100644 --- a/src/Services/Services/ApplicationConfigurationService.cs +++ b/src/Services/Services/ApplicationConfigurationService.cs @@ -101,4 +101,9 @@ public bool UploadFileToDatabase(IFormFile file, string fileExtension) return false; } } + + public string GetValueByName(string configName) + { + return this.appConfigRepository.GetValueByName(configName); + } } \ No newline at end of file diff --git a/src/Services/Services/MeteredPlanSchedulerManagementService.cs b/src/Services/Services/MeteredPlanSchedulerManagementService.cs index 9a487f8e..6ecc5040 100644 --- a/src/Services/Services/MeteredPlanSchedulerManagementService.cs +++ b/src/Services/Services/MeteredPlanSchedulerManagementService.cs @@ -4,8 +4,9 @@ using System.Text.Json; using Marketplace.SaaS.Accelerator.DataAccess.Contracts; using Marketplace.SaaS.Accelerator.DataAccess.Entities; +using Marketplace.SaaS.Accelerator.Services.Contracts; +using Marketplace.SaaS.Accelerator.Services.Helpers; using Marketplace.SaaS.Accelerator.Services.Models; - namespace Marketplace.SaaS.Accelerator.Services.Services; /// @@ -13,12 +14,37 @@ namespace Marketplace.SaaS.Accelerator.Services.Services; /// public class MeteredPlanSchedulerManagementService { + /// + /// Scheduler Frequency Repository Interface + /// private ISchedulerFrequencyRepository frequencyRepository; + /// + /// Metered Plan Scheduler Management Repository Interface + /// private IMeteredPlanSchedulerManagementRepository schedulerRepository; + /// + /// Scheduler Manager View Repository Interface + /// private ISchedulerManagerViewRepository schedulerViewRepository; + /// + /// Subscription UsageLogs Repository Interface + /// private ISubscriptionUsageLogsRepository subscriptionUsageLogsRepository; + /// + /// Email Service Interface + /// + private IEmailService emailService; + /// + /// Email Helper utility + /// + private EmailHelper emailHelper; + + /// + /// Application Config Repository + /// private IApplicationConfigRepository applicationConfigRepository; + /// /// Initializes a new instance of the class. /// @@ -26,12 +52,34 @@ public class MeteredPlanSchedulerManagementService /// The Frequency attributes repository. /// The Scheduler Manager View attributes repository. - public MeteredPlanSchedulerManagementService(ISchedulerFrequencyRepository schedulerFrequencyRepository, IMeteredPlanSchedulerManagementRepository meteredPlanSchedulerManagementRepository, ISchedulerManagerViewRepository schedulerManagerViewRepository, ISubscriptionUsageLogsRepository subscriptionUsageLogsRepository,IApplicationConfigRepository applicationConfigRepository) + public MeteredPlanSchedulerManagementService(ISchedulerFrequencyRepository schedulerFrequencyRepository, + IMeteredPlanSchedulerManagementRepository meteredPlanSchedulerManagementRepository, + ISchedulerManagerViewRepository schedulerManagerViewRepository, + ISubscriptionUsageLogsRepository subscriptionUsageLogsRepository, + IApplicationConfigRepository applicationConfigRepository, + IEmailTemplateRepository emailTemplateRepository, + IEmailService emailService) { this.frequencyRepository = schedulerFrequencyRepository; this.schedulerRepository = meteredPlanSchedulerManagementRepository; this.schedulerViewRepository = schedulerManagerViewRepository; this.subscriptionUsageLogsRepository = subscriptionUsageLogsRepository; + this.emailService = emailService; + this.emailHelper = new EmailHelper(applicationConfigRepository, null, emailTemplateRepository, null, null); + + } + + public MeteredPlanSchedulerManagementService(ISchedulerFrequencyRepository schedulerFrequencyRepository, + IMeteredPlanSchedulerManagementRepository meteredPlanSchedulerManagementRepository, + ISchedulerManagerViewRepository schedulerManagerViewRepository, + ISubscriptionUsageLogsRepository subscriptionUsageLogsRepository, + IApplicationConfigRepository applicationConfigRepository) + { + this.frequencyRepository = schedulerFrequencyRepository; + this.schedulerRepository = meteredPlanSchedulerManagementRepository; + this.schedulerViewRepository = schedulerManagerViewRepository; + this.subscriptionUsageLogsRepository = subscriptionUsageLogsRepository; + this.applicationConfigRepository = applicationConfigRepository; this.applicationConfigRepository = applicationConfigRepository; } @@ -207,6 +255,25 @@ public List GetSchedulerItemRunHistory(int id) } + public bool CheckIfSchedulerRun(int id, string schedulerName) + { + var scheduledItem = this.schedulerRepository.Get(id); + var meteredAudits = this.subscriptionUsageLogsRepository.GetMeteredAuditLogsBySubscriptionId(Convert.ToInt32(scheduledItem.SubscriptionId)); + var scheduledItemView = this.schedulerViewRepository.GetById(id); + foreach (var auditLog in meteredAudits) + { + var MeteringUsageRequest = JsonSerializer.Deserialize(auditLog.RequestJson); + + if ((MeteringUsageRequest.Dimension == scheduledItemView.Dimension) && (auditLog.RunBy == $"Scheduler - {schedulerName}")) + { + return true; + } + + } + return false; + + } + /// /// Saves the Metered Plan Scheduler Management Model attributes. /// @@ -257,4 +324,26 @@ public void DeleteSchedulerDetailById(int id) this.schedulerRepository.Remove(meteredPlanScheduler); } + public void SendSchedulerEmail(SchedulerManagerViewModel schedulerTask,MeteredAuditLogs meteredAuditItem) + { + var emailContent = new EmailContentModel(); + + if ((meteredAuditItem.StatusCode== "Accepted")|| (meteredAuditItem.StatusCode == "Missing")) + { + //Success + emailContent = this.emailHelper.PrepareMeteredEmailContent(schedulerTask.SchedulerName, schedulerTask.SubscriptionName, meteredAuditItem.StatusCode, meteredAuditItem.ResponseJson); + } + else + { + //Faliure + emailContent = this.emailHelper.PrepareMeteredEmailContent(schedulerTask.SchedulerName, schedulerTask.SubscriptionName, "Failure", meteredAuditItem.ResponseJson); + } + + if (!string.IsNullOrWhiteSpace(emailContent.ToEmails)) + { + this.emailService.SendEmail(emailContent); + } + + } + } \ No newline at end of file