diff --git a/Hotel/HotelBusinessLogic/BusinessLogics/ConferenceLogic.cs b/Hotel/HotelBusinessLogic/BusinessLogics/ConferenceLogic.cs index b7bba28..bf0a2a3 100644 --- a/Hotel/HotelBusinessLogic/BusinessLogics/ConferenceLogic.cs +++ b/Hotel/HotelBusinessLogic/BusinessLogics/ConferenceLogic.cs @@ -1,4 +1,5 @@ -using HotelContracts.BindingModels; +using HotelBusinessLogic.MailWorker; +using HotelContracts.BindingModels; using HotelContracts.BusinessLogicsContracts; using HotelContracts.SearchModels; using HotelContracts.StoragesContracts; @@ -13,23 +14,31 @@ namespace HotelBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IConferenceStorage _conferenceStorage; + private readonly AbstractMailWorker _mailWorker; + private readonly IOrganiserLogic _organiserLogic; - public ConferenceLogic(ILogger logger, IConferenceStorage conferenceStorage) + public ConferenceLogic(ILogger logger, IConferenceStorage conferenceStorage, IOrganiserLogic organiserLogic, AbstractMailWorker mailWorker) { _logger = logger; _conferenceStorage = conferenceStorage; + _organiserLogic = organiserLogic; + _mailWorker = mailWorker; } public bool Create(ConferenceBindingModel model) { CheckModel(model); model.ConferenceMembers = new(); - if (_conferenceStorage.Insert(model) == null) + var result = _conferenceStorage.Insert(model); + + if (result == null) { _logger.LogWarning("Insert operation failed"); return false; } + SendConferenceMessage(result.OrganiserId, $"Гостиница \"Развитие\", Конференция №{result.Id}", $"Конференция №{result.Id} под названием {result.ConferenceName} и датой начала {result.StartDate} добавлена"); + return true; } @@ -39,12 +48,16 @@ namespace HotelBusinessLogic.BusinessLogics _logger.LogInformation("Delete. Id:{Id}", model.Id); - if (_conferenceStorage.Delete(model) == null) + var result = _conferenceStorage.Delete(model); + + if (result == null) { _logger.LogWarning("Delete operation failed"); return false; } + SendConferenceMessage(result.OrganiserId, $"Гостиница \"Развитие\", Конференция №{result.Id}", $"Конференция №{result.Id} под названием {result.ConferenceName} и датой начала {result.StartDate} удалена"); + return true; } @@ -152,5 +165,24 @@ namespace HotelBusinessLogic.BusinessLogics _logger.LogInformation("Conference. ConferenceName:{ConferenceName}.StartDate:{ StartDate}. Id: { Id}", model.ConferenceName, model.StartDate, model.Id); } + + private bool SendConferenceMessage(int organiserId, string subject, string text) + { + var organiser = _organiserLogic.ReadElement(new() { Id = organiserId }); + + if (organiser == null) + { + return false; + } + + _mailWorker.MailSendAsync(new() + { + MailAddress = organiser.OrganiserEmail, + Subject = subject, + Text = text + }); + + return true; + } } } diff --git a/Hotel/HotelBusinessLogic/BusinessLogics/MealPlanLogic.cs b/Hotel/HotelBusinessLogic/BusinessLogics/MealPlanLogic.cs index dd1dc98..3990f7d 100644 --- a/Hotel/HotelBusinessLogic/BusinessLogics/MealPlanLogic.cs +++ b/Hotel/HotelBusinessLogic/BusinessLogics/MealPlanLogic.cs @@ -1,4 +1,5 @@ -using HotelContracts.BindingModels; +using HotelBusinessLogic.MailWorker; +using HotelContracts.BindingModels; using HotelContracts.BusinessLogicsContracts; using HotelContracts.SearchModels; using HotelContracts.StoragesContracts; @@ -12,11 +13,15 @@ namespace HotelBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IMealPlanStorage _mealPlanStorage; + private readonly AbstractMailWorker _mailWorker; + private readonly IOrganiserLogic _organiserLogic; - public MealPlanLogic(ILogger logger, IMealPlanStorage mealPlanStorage) + public MealPlanLogic(ILogger logger, IMealPlanStorage mealPlanStorage, IOrganiserLogic organiserLogic, AbstractMailWorker mailWorker) { _logger = logger; _mealPlanStorage = mealPlanStorage; + _organiserLogic = organiserLogic; + _mailWorker= mailWorker; } public bool AddMemberToMealPlan(MealPlanSearchModel model, IMemberModel member) @@ -56,12 +61,16 @@ namespace HotelBusinessLogic.BusinessLogics CheckModel(model); model.MealPlanMembers = new(); - if (_mealPlanStorage.Insert(model) == null) + var result = _mealPlanStorage.Insert(model); + + if (result == null) { _logger.LogWarning("Insert operation failed"); return false; } + SendMealPlanMessage(result.OrganiserId, $"Гостиница \"Развитие\", План питания №{result.Id}", $"План питания №{result.Id} под названием {result.MealPlanName} и стоимостью {result.MealPlanPrice} добавлен"); + return true; } @@ -71,12 +80,16 @@ namespace HotelBusinessLogic.BusinessLogics _logger.LogInformation("Delete. Id:{Id}", model.Id); - if (_mealPlanStorage.Delete(model) == null) + var result = _mealPlanStorage.Delete(model); + + if (result== null) { _logger.LogWarning("Delete operation failed"); return false; } + SendMealPlanMessage(result.OrganiserId, $"Гостиница \"Развитие\", План питания №{result.Id}", $"План питания №{result.Id} под названием {result.MealPlanName} и стоимостью {result.MealPlanPrice} удален"); + return true; } @@ -166,5 +179,24 @@ namespace HotelBusinessLogic.BusinessLogics throw new InvalidOperationException("План питания с таким названием уже есть"); } } + + private bool SendMealPlanMessage(int organiserId, string subject, string text) + { + var organiser = _organiserLogic.ReadElement(new() { Id = organiserId }); + + if (organiser == null) + { + return false; + } + + _mailWorker.MailSendAsync(new() + { + MailAddress = organiser.OrganiserEmail, + Subject = subject, + Text = text + }); + + return true; + } } } diff --git a/Hotel/HotelBusinessLogic/BusinessLogics/MemberLogic.cs b/Hotel/HotelBusinessLogic/BusinessLogics/MemberLogic.cs index e536367..4823ed5 100644 --- a/Hotel/HotelBusinessLogic/BusinessLogics/MemberLogic.cs +++ b/Hotel/HotelBusinessLogic/BusinessLogics/MemberLogic.cs @@ -4,6 +4,7 @@ using HotelContracts.SearchModels; using HotelContracts.StoragesContracts; using HotelContracts.ViewModels; using Microsoft.Extensions.Logging; +using HotelBusinessLogic.MailWorker; namespace HotelBusinessLogic.BusinessLogics { @@ -11,23 +12,31 @@ namespace HotelBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IMemberStorage _memberStorage; + private readonly AbstractMailWorker _mailWorker; + private readonly IOrganiserLogic _organiserLogic; - public MemberLogic(ILogger logger, IMemberStorage memberStorage) + public MemberLogic(ILogger logger, IMemberStorage memberStorage, AbstractMailWorker mailWorker, IOrganiserLogic organiserLogic) { _logger = logger; _memberStorage = memberStorage; + _mailWorker = mailWorker; + _organiserLogic = organiserLogic; } public bool Create(MemberBindingModel model) { CheckModel(model); - if (_memberStorage.Insert(model) == null) + var result = _memberStorage.Insert(model); + + if (result == null) { _logger.LogWarning("Insert operation failed"); return false; } + SendMemberMessage(result.OrganiserId, $"Гостиница \"Развитие\", Участник №{result.Id}", $"Участник №{result.Id} по имени {result.MemberFIO} и с гражданством {result.Citizenship} добавлен"); + return true; } @@ -37,12 +46,16 @@ namespace HotelBusinessLogic.BusinessLogics _logger.LogInformation("Delete. Id:{Id}", model.Id); - if (_memberStorage.Delete(model) == null) + var result = _memberStorage.Delete(model); + + if (result == null) { _logger.LogWarning("Delete operation failed"); return false; } + SendMemberMessage(result.OrganiserId, $"Гостиница \"Развитие\", Участник №{result.Id}", $"Участник №{result.Id} по имени {result.MemberFIO} и с гражданством {result.Citizenship} удален"); + return true; } @@ -121,5 +134,24 @@ namespace HotelBusinessLogic.BusinessLogics _logger.LogInformation("Member. MemberFIO:{MemberFIO}.Citizenship:{ Citizenship}. Id: { Id}", model.MemberFIO, model.Citizenship, model.Id); } + + private bool SendMemberMessage(int organiserId, string subject, string text) + { + var organiser = _organiserLogic.ReadElement(new() { Id = organiserId }); + + if (organiser == null) + { + return false; + } + + _mailWorker.MailSendAsync(new() + { + MailAddress = organiser.OrganiserEmail, + Subject = subject, + Text = text + }); + + return true; + } } } diff --git a/Hotel/HotelBusinessLogic/HotelBusinessLogic.csproj b/Hotel/HotelBusinessLogic/HotelBusinessLogic.csproj index 37edc34..7bacb0b 100644 --- a/Hotel/HotelBusinessLogic/HotelBusinessLogic.csproj +++ b/Hotel/HotelBusinessLogic/HotelBusinessLogic.csproj @@ -8,6 +8,7 @@ + diff --git a/Hotel/HotelBusinessLogic/MailWorker/AbstractMailWorker.cs b/Hotel/HotelBusinessLogic/MailWorker/AbstractMailWorker.cs new file mode 100644 index 0000000..96f9f1c --- /dev/null +++ b/Hotel/HotelBusinessLogic/MailWorker/AbstractMailWorker.cs @@ -0,0 +1,64 @@ +using HotelContracts.BindingModels; +using HotelContracts.BusinessLogicsContracts; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HotelBusinessLogic.MailWorker +{ + public abstract class AbstractMailWorker + { + protected string _mailLogin = string.Empty; + protected string _mailPassword = string.Empty; + protected string _smtpClientHost = string.Empty; + protected int _smtpClientPort; + protected string _popHost = string.Empty; + protected int _popPort; + private readonly IOrganiserLogic _organiserLogic; + private readonly ILogger _logger; + + public AbstractMailWorker(ILogger logger, IOrganiserLogic organiserLogic) + { + _logger = logger; + _organiserLogic = organiserLogic; + } + + public void MailConfig(MailConfigBindingModel config) + { + _mailLogin = config.MailLogin; + _mailPassword = config.MailPassword; + _smtpClientHost = config.SmtpClientHost; + _smtpClientPort = config.SmtpClientPort; + _popHost = config.PopHost; + _popPort = config.PopPort; + _logger.LogDebug("Config: {login}, {password}, {clientHost}, {clientPOrt}, {popHost}, {popPort}", _mailLogin, _mailPassword, _smtpClientHost, _smtpClientPort, _popHost, _popPort); + } + + public async void MailSendAsync(MailSendInfoBindingModel info) + { + if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword)) + { + return; + } + + if (string.IsNullOrEmpty(_smtpClientHost) || _smtpClientPort == 0) + { + return; + } + + if (string.IsNullOrEmpty(info.MailAddress) || string.IsNullOrEmpty(info.Subject) || string.IsNullOrEmpty(info.Text)) + { + return; + } + + _logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject); + + await SendMailAsync(info); + } + + protected abstract Task SendMailAsync(MailSendInfoBindingModel info); + } +} diff --git a/Hotel/HotelBusinessLogic/MailWorker/MailKitWorker.cs b/Hotel/HotelBusinessLogic/MailWorker/MailKitWorker.cs new file mode 100644 index 0000000..137c8aa --- /dev/null +++ b/Hotel/HotelBusinessLogic/MailWorker/MailKitWorker.cs @@ -0,0 +1,47 @@ +using HotelContracts.BindingModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Net; +using System.Security.Authentication; +using System.Text; +using System.Threading.Tasks; +using HotelContracts.BusinessLogicsContracts; + +namespace HotelBusinessLogic.MailWorker +{ + public class MailKitWorker : AbstractMailWorker + { + public MailKitWorker(ILogger logger, IOrganiserLogic organiserLogic) : base(logger, organiserLogic) { } + + protected override async Task SendMailAsync(MailSendInfoBindingModel info) + { + using var objMailMessage = new MailMessage(); + using var objSmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort); + + try + { + objMailMessage.From = new MailAddress(_mailLogin); + objMailMessage.To.Add(new MailAddress(info.MailAddress)); + objMailMessage.Subject = info.Subject; + objMailMessage.Body = info.Text; + objMailMessage.SubjectEncoding = Encoding.UTF8; + objMailMessage.BodyEncoding = Encoding.UTF8; + objSmtpClient.UseDefaultCredentials = false; + objSmtpClient.EnableSsl = true; + objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network; + objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword); + + await Task.Run(() => objSmtpClient.Send(objMailMessage)); + } + catch (Exception) + { + throw; + } + } + + + } +} diff --git a/Hotel/HotelContracts/BindingModels/MailConfigBindingModel.cs b/Hotel/HotelContracts/BindingModels/MailConfigBindingModel.cs new file mode 100644 index 0000000..680e25e --- /dev/null +++ b/Hotel/HotelContracts/BindingModels/MailConfigBindingModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HotelContracts.BindingModels +{ + public class MailConfigBindingModel + { + public string MailLogin { get; set; } = string.Empty; + public string MailPassword { get; set; } = string.Empty; + public string SmtpClientHost { get; set; } = string.Empty; + public int SmtpClientPort { get; set; } + public string PopHost { get; set; } = string.Empty; + public int PopPort { get; set; } + } +} diff --git a/Hotel/HotelContracts/BindingModels/MailSendInfoBindingModel.cs b/Hotel/HotelContracts/BindingModels/MailSendInfoBindingModel.cs new file mode 100644 index 0000000..f4ab8d9 --- /dev/null +++ b/Hotel/HotelContracts/BindingModels/MailSendInfoBindingModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HotelContracts.BindingModels +{ + public class MailSendInfoBindingModel + { + public string MailAddress { get; set; } = string.Empty; + public string Subject { get; set; } = string.Empty; + public string Text { get; set; } = string.Empty; + } +} diff --git a/Hotel/HotelDataBaseImplement/HotelDataBase.cs b/Hotel/HotelDataBaseImplement/HotelDataBase.cs index 7141379..6d7ccea 100644 --- a/Hotel/HotelDataBaseImplement/HotelDataBase.cs +++ b/Hotel/HotelDataBaseImplement/HotelDataBase.cs @@ -9,7 +9,7 @@ namespace HotelDataBaseImplement { if (optionsBuilder.IsConfigured == false) { - optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-V0ON61E\SQLEXPRESS;Initial Catalog=HotelDataBaseFull;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-VG5USAH\SQLEXPRESS;Initial Catalog=HotelDataBaseFull;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); } base.OnConfiguring(optionsBuilder); } diff --git a/Hotel/HotelDataBaseImplement/Implemets/ConferenceStorage.cs b/Hotel/HotelDataBaseImplement/Implemets/ConferenceStorage.cs index 7543766..c083bca 100644 --- a/Hotel/HotelDataBaseImplement/Implemets/ConferenceStorage.cs +++ b/Hotel/HotelDataBaseImplement/Implemets/ConferenceStorage.cs @@ -65,7 +65,7 @@ namespace HotelDataBaseImplement.Implemets .ThenInclude(x => x.MealPlan) .Include(x => x.ConferenceBookings) .Include(x => x.Organiser) - .Where(x => x.StartDate >= model.DateFrom && x.StartDate <= model.DateTo) + .Where(x => x.StartDate >= model.DateFrom && x.StartDate <= model.DateTo && x.OrganiserId == model.OrganiserId) .Select(x => x.GetViewModel) .ToList(); } diff --git a/Hotel/HotelRestApi/Program.cs b/Hotel/HotelRestApi/Program.cs index a67a1bc..2211ad1 100644 --- a/Hotel/HotelRestApi/Program.cs +++ b/Hotel/HotelRestApi/Program.cs @@ -3,7 +3,7 @@ using HotelContracts.BusinessLogicsContracts; using HotelContracts.StoragesContracts; using HotelDataBaseImplement.Implemets; using Microsoft.OpenApi.Models; -//using HotelBusinessLogic.MailWorker; +using HotelBusinessLogic.MailWorker; using HotelContracts.BindingModels; using HotelBusinessLogic.OfficePackage; using HotelBusinessLogic.OfficePackage.Implements; @@ -44,7 +44,7 @@ builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); -//builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle @@ -60,17 +60,17 @@ builder.Services.AddSwaggerGen(c => var app = builder.Build(); -//var mailSender = app.Services.GetService(); +var mailSender = app.Services.GetService(); -//mailSender?.MailConfig(new MailConfigBindingModel -//{ - // MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty, - // MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty, - // SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty, - // SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()), - // PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty, - // PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString()) -//}); +mailSender?.MailConfig(new MailConfigBindingModel +{ + MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty, + MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty, + SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty, + SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()), + PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty, + PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString()) +}); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) diff --git a/Hotel/HotelRestApi/appsettings.json b/Hotel/HotelRestApi/appsettings.json index 10f68b8..d2cd417 100644 --- a/Hotel/HotelRestApi/appsettings.json +++ b/Hotel/HotelRestApi/appsettings.json @@ -5,5 +5,12 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + + "SmtpClientHost": "smtp.gmail.com", + "SmtpClientPort": "587", + "PopHost": "pop.gmail.com", + "PopPort": "995", + "MailLogin": "labwork7zhimol@gmail.com", + "MailPassword": "nnsz pcnf xezb gxtc" } diff --git a/Hotel/HotelRestApi/Отчет PDF.pdf b/Hotel/HotelRestApi/Отчет PDF.pdf deleted file mode 100644 index f4460a0..0000000 Binary files a/Hotel/HotelRestApi/Отчет PDF.pdf and /dev/null differ