Browse Source

email notifications nearly done

master
Milad Karbasizadeh 11 years ago
parent
commit
15cf17513f
11 changed files with 160 additions and 3 deletions
  1. +25
    -0
      Sevomin.Models/Helpers/ScheduledTasks/ExpiringJob.cs
  2. +26
    -0
      Sevomin.Models/Helpers/ScheduledTasks/NewApplication.cs
  3. +29
    -0
      Sevomin.Models/Helpers/ScheduledTasks/NewJob.cs
  4. +30
    -3
      Sevomin.Models/Helpers/SevominEmailer.cs
  5. +20
    -0
      Sevomin.Models/Helpers/SevominRegistry.cs
  6. +1
    -0
      Sevomin.Models/Repositories/IRepository.cs
  7. +5
    -0
      Sevomin.Models/Repositories/UserRepository.cs
  8. +7
    -0
      Sevomin.Models/Sevomin.Models.csproj
  9. +1
    -0
      Sevomin.Models/packages.config
  10. +13
    -0
      Sevomin.WebFrontend/Global.asax.cs
  11. +3
    -0
      Sevomin.WebFrontend/Sevomin.WebFrontend.csproj

+ 25
- 0
Sevomin.Models/Helpers/ScheduledTasks/ExpiringJob.cs View File

@ -0,0 +1,25 @@
using FluentScheduler;
using Sevomin.Models.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sevomin.Models.Helpers.ScheduledTasks
{
public class ExpiringJob : ITask
{
public async void Execute()
{
var expiringJobs = JobRepository.Current.ListAll().Where(j => j.ExpireDate.Date == DateTime.Now.AddDays(-2).Date);
foreach (var job in expiringJobs)
{
SevominEmailer emailer = new SevominEmailer();
emailer.EmailType = EmailType.ExpiringJob;
emailer.Parameters.Add("", "");
await emailer.SendAsync(string.IsNullOrWhiteSpace(job.ContactPersonEMail) ? job.Avalin.Email : job.ContactPersonEMail, "", true);
}
}
}
}

+ 26
- 0
Sevomin.Models/Helpers/ScheduledTasks/NewApplication.cs View File

@ -0,0 +1,26 @@
using FluentScheduler;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sevomin.Models.Helpers.ScheduledTasks
{
public class NewApplication : ITask
{
public async void Execute()
{
var avalins = SevominDbContext.Current.DovominJobs.Where(dj => dj.ApplyDate.Date == DateTime.Now.AddDays(-2).Date).Select(a => a.Job.Avalin);
foreach (var avalin in avalins.Distinct())
{
SevominEmailer emailer = new SevominEmailer();
emailer.EmailType = EmailType.NewApplication;
emailer.Parameters.Add("", "");
await emailer.SendAsync(avalin.Email, "", true);
}
}
}
}

+ 29
- 0
Sevomin.Models/Helpers/ScheduledTasks/NewJob.cs View File

@ -0,0 +1,29 @@
using FluentScheduler;
using Sevomin.Models.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sevomin.Models.Helpers.ScheduledTasks
{
public class NewJob : ITask
{
public async void Execute()
{
var newJobs = JobRepository.Current.ListAll().Where(j => j.CreateDate.Date == DateTime.Now.AddDays(-1).Date).ToList();
if (newJobs.Count > 0)
{
foreach (var dovomin in UserRepository.Current.ListAll().Where(u => u is Dovomin && u.EmailConfirmed))
{
SevominEmailer emailer = new SevominEmailer();
emailer.EmailType = EmailType.NewJob;
emailer.Parameters.Add("", "");
await emailer.SendAsync(dovomin.Email, "", true);
}
}
}
}
}

+ 30
- 3
Sevomin.Models/Helpers/SevominEmailer.cs View File

@ -12,7 +12,10 @@ namespace Sevomin.Models.Helpers
{ {
EmailConfirmation, EmailConfirmation,
PasswordReset, PasswordReset,
NewPassword
NewPassword,
NewApplication,
NewJob,
ExpiringJob
} }
public class SevominEmailer public class SevominEmailer
@ -23,6 +26,9 @@ namespace Sevomin.Models.Helpers
private string EmailConfirmationFilePath; private string EmailConfirmationFilePath;
private string NewPasswordFilePath; private string NewPasswordFilePath;
private string PasswordResetFilePath; private string PasswordResetFilePath;
private string ExpiringJobFilePath;
private string NewJobFilePath;
private string NewApplicationFilePath;
public SevominEmailer() public SevominEmailer()
{ {
EmailFolderPath = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/app_data"), "emails"); EmailFolderPath = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/app_data"), "emails");
@ -31,12 +37,21 @@ namespace Sevomin.Models.Helpers
EmailConfirmationFilePath = Path.Combine(EmailFolderPath, "email-confirmation.html"); EmailConfirmationFilePath = Path.Combine(EmailFolderPath, "email-confirmation.html");
NewPasswordFilePath = Path.Combine(EmailFolderPath, "new-password.html"); NewPasswordFilePath = Path.Combine(EmailFolderPath, "new-password.html");
PasswordResetFilePath = Path.Combine(EmailFolderPath, "password-reset.html"); PasswordResetFilePath = Path.Combine(EmailFolderPath, "password-reset.html");
ExpiringJobFilePath = Path.Combine(EmailFolderPath, "expiring-job.html");
NewJobFilePath = Path.Combine(EmailFolderPath, "new-job.html");
NewApplicationFilePath = Path.Combine(EmailFolderPath, "new-application.html");
if(!File.Exists(EmailConfirmationFilePath)) if(!File.Exists(EmailConfirmationFilePath))
throw new ApplicationException("Email confirmation template does not exist in the right address."); throw new ApplicationException("Email confirmation template does not exist in the right address.");
if (!File.Exists(NewPasswordFilePath)) if (!File.Exists(NewPasswordFilePath))
throw new ApplicationException("New password template does not exist in the right address."); throw new ApplicationException("New password template does not exist in the right address.");
if (!File.Exists(PasswordResetFilePath)) if (!File.Exists(PasswordResetFilePath))
throw new ApplicationException("Password reset template does not exist in the right address."); throw new ApplicationException("Password reset template does not exist in the right address.");
if (!File.Exists(ExpiringJobFilePath))
throw new ApplicationException("Expiring job template does not exist in the right address.");
if (!File.Exists(NewJobFilePath))
throw new ApplicationException("New job template does not exist in the right address.");
if (!File.Exists(NewApplicationFilePath))
throw new ApplicationException("New application template does not exist in the right address.");
Parameters = new Dictionary<string, string>(); Parameters = new Dictionary<string, string>();
} }
public SevominEmailer(Dictionary<string, string> parameters, EmailType emailType) : this() public SevominEmailer(Dictionary<string, string> parameters, EmailType emailType) : this()
@ -64,6 +79,18 @@ namespace Sevomin.Models.Helpers
template = template =
File.ReadAllText(NewPasswordFilePath, Encoding.UTF8); File.ReadAllText(NewPasswordFilePath, Encoding.UTF8);
break; break;
case EmailType.ExpiringJob:
template =
File.ReadAllText(ExpiringJobFilePath, Encoding.UTF8);
break;
case EmailType.NewApplication:
template =
File.ReadAllText(NewApplicationFilePath, Encoding.UTF8);
break;
case EmailType.NewJob:
template =
File.ReadAllText(NewJobFilePath, Encoding.UTF8);
break;
default: default:
template = string.Empty; template = string.Empty;
break; break;
@ -75,7 +102,7 @@ namespace Sevomin.Models.Helpers
msg.SubjectEncoding = Encoding.UTF8; msg.SubjectEncoding = Encoding.UTF8;
msg.BodyEncoding = Encoding.UTF8; msg.BodyEncoding = Encoding.UTF8;
msg.Subject = subject; msg.Subject = subject;
msg.IsBodyHtml = isHtml;
msg.IsBodyHtml = isHtml;
Func<string> getBody = () => Func<string> getBody = () =>
{ {
foreach (var param in Parameters) foreach (var param in Parameters)
@ -90,4 +117,4 @@ namespace Sevomin.Models.Helpers
}); });
} }
} }
}
}

+ 20
- 0
Sevomin.Models/Helpers/SevominRegistry.cs View File

@ -0,0 +1,20 @@
using FluentScheduler;
using Sevomin.Models.Helpers.ScheduledTasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sevomin.Models.Helpers
{
public class SevominRegistry : Registry
{
public SevominRegistry()
{
Schedule<NewApplication>().ToRunEvery(2).Days().At(8, 0);
Schedule<ExpiringJob>().ToRunEvery(1).Days().At(8, 10);
Schedule<NewJob>().ToRunEvery(2).Days().At(8, 20);
}
}
}

+ 1
- 0
Sevomin.Models/Repositories/IRepository.cs View File

@ -13,6 +13,7 @@ namespace Sevomin.Models.Repositories
public interface IUserRepository : IRepository<string, User> public interface IUserRepository : IRepository<string, User>
{ {
User FindWithConfirmationCode(string code); User FindWithConfirmationCode(string code);
IQueryable<User> ListAll();
} }
public interface IJobRepository : IRepository<long ,Job> public interface IJobRepository : IRepository<long ,Job>


+ 5
- 0
Sevomin.Models/Repositories/UserRepository.cs View File

@ -57,5 +57,10 @@ namespace Sevomin.Models.Repositories
{ {
SevominDbContext.Current.SaveChanges(); SevominDbContext.Current.SaveChanges();
} }
public IQueryable<User> ListAll()
{
return SevominDbContext.Current.Users;
}
} }
} }

+ 7
- 0
Sevomin.Models/Sevomin.Models.csproj View File

@ -38,6 +38,9 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.SqlServer.dll</HintPath> <HintPath>..\packages\EntityFramework.6.1.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference> </Reference>
<Reference Include="FluentScheduler">
<HintPath>..\packages\FluentScheduler.3.1.42\lib\net40\FluentScheduler.dll</HintPath>
</Reference>
<Reference Include="MailChimp"> <Reference Include="MailChimp">
<HintPath>..\packages\MailChimp.NET.1.1.0.2\lib\net40\MailChimp.dll</HintPath> <HintPath>..\packages\MailChimp.NET.1.1.0.2\lib\net40\MailChimp.dll</HintPath>
</Reference> </Reference>
@ -73,6 +76,10 @@
<Compile Include="Avalin.cs" /> <Compile Include="Avalin.cs" />
<Compile Include="AvalinViewModel.cs" /> <Compile Include="AvalinViewModel.cs" />
<Compile Include="ChangePasswordViewModel.cs" /> <Compile Include="ChangePasswordViewModel.cs" />
<Compile Include="Helpers\ScheduledTasks\ExpiringJob.cs" />
<Compile Include="Helpers\ScheduledTasks\NewJob.cs" />
<Compile Include="Helpers\ScheduledTasks\NewApplication.cs" />
<Compile Include="Helpers\SevominRegistry.cs" />
<Compile Include="ResetPasswordViewModel.cs" /> <Compile Include="ResetPasswordViewModel.cs" />
<Compile Include="ForgotPasswordViewModel.cs" /> <Compile Include="ForgotPasswordViewModel.cs" />
<Compile Include="DovominJob.cs" /> <Compile Include="DovominJob.cs" />


+ 1
- 0
Sevomin.Models/packages.config View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="EntityFramework" version="6.1.0" targetFramework="net451" /> <package id="EntityFramework" version="6.1.0" targetFramework="net451" />
<package id="FluentScheduler" version="3.1.42" targetFramework="net451" />
<package id="MailChimp.NET" version="1.1.0.2" targetFramework="net451" /> <package id="MailChimp.NET" version="1.1.0.2" targetFramework="net451" />
<package id="Microsoft.AspNet.Identity.Core" version="2.0.0" targetFramework="net451" /> <package id="Microsoft.AspNet.Identity.Core" version="2.0.0" targetFramework="net451" />
<package id="Microsoft.AspNet.Identity.EntityFramework" version="2.0.0" targetFramework="net451" /> <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.0.0" targetFramework="net451" />


+ 13
- 0
Sevomin.WebFrontend/Global.asax.cs View File

@ -1,6 +1,10 @@
using Elmah; using Elmah;
using FluentScheduler;
using Sevomin.Models; using Sevomin.Models;
using Sevomin.Models.Helpers;
using Sevomin.WebFrontend.Controllers; using Sevomin.WebFrontend.Controllers;
using System;
using System.Threading.Tasks;
using System.Web; using System.Web;
using System.Web.Mvc; using System.Web.Mvc;
using System.Web.Routing; using System.Web.Routing;
@ -13,6 +17,8 @@ namespace Sevomin.WebFrontend
{ {
AreaRegistration.RegisterAllAreas(); AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes); RouteConfig.RegisterRoutes(RouteTable.Routes);
TaskManager.Initialize(new SevominRegistry());
} }
void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e) void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e)
@ -26,6 +32,13 @@ namespace Sevomin.WebFrontend
} }
} }
static void TaskManager_UnobservedTaskException(Task sender, UnhandledExceptionEventArgs e)
{
var error = new Elmah.Error(e.ExceptionObject as Exception);
Elmah.ErrorLog.GetDefault(System.Web.HttpContext.Current).Log(error);
}
protected void Application_EndRequest() protected void Application_EndRequest()
{ {
if (Context.Response.StatusCode == 404) if (Context.Response.StatusCode == 404)


+ 3
- 0
Sevomin.WebFrontend/Sevomin.WebFrontend.csproj View File

@ -41,6 +41,9 @@
<Reference Include="Elmah"> <Reference Include="Elmah">
<HintPath>..\packages\elmah.corelibrary.1.2.2\lib\Elmah.dll</HintPath> <HintPath>..\packages\elmah.corelibrary.1.2.2\lib\Elmah.dll</HintPath>
</Reference> </Reference>
<Reference Include="FluentScheduler">
<HintPath>..\packages\FluentScheduler.3.1.42\lib\net40\FluentScheduler.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.0.0\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath> <HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.0.0\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>


Loading…
Cancel
Save