не получается

This commit is contained in:
malimova 2024-06-02 14:24:38 +04:00
parent bb87bb3fb8
commit 059eede984
15 changed files with 123 additions and 119 deletions

View File

@ -4,6 +4,7 @@ using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.StoragesContracts; using ConfectioneryContracts.StoragesContracts;
using ConfectioneryContracts.ViewModels; using ConfectioneryContracts.ViewModels;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -89,36 +90,36 @@ namespace ConfectioneryBusinessLogic
private void CheckModel(ClientBindingModel model, bool withParams = true) private void CheckModel(ClientBindingModel model, bool withParams = true)
{ {
if (model == null) if (model == null)
{ {
throw new ArgumentNullException(nameof(model)); throw new ArgumentNullException(nameof(model));
} }
if (!withParams) if (!withParams)
{ {
return; return;
} }
if (string.IsNullOrEmpty(model.ClientFIO)) if (string.IsNullOrEmpty(model.ClientFIO))
{ {
throw new ArgumentNullException("Нет ФИО пользователя", nameof(model.ClientFIO)); throw new ArgumentNullException("Нет ФИО пользователя", nameof(model.ClientFIO));
} }
if (string.IsNullOrEmpty(model.Email)) if (string.IsNullOrEmpty(model.Email) || !Regex.IsMatch(model.Email, @"^[a-z0-9._%+-]+\@([a-z0-9-]+\.)+[a-z]{2,4}$"))
{ {
throw new ArgumentNullException("Нет почты пользователя", nameof(model.Email)); throw new ArgumentNullException("Неверно введена почта", nameof(model.Email));
} }
if (string.IsNullOrEmpty(model.Password)) if (string.IsNullOrEmpty(model.Password) || !Regex.IsMatch(model.Password, @"^(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z0-9\n]).{10,50}$"))
{ {
throw new ArgumentNullException("Нет пароля пользователя", nameof(model.Password)); throw new ArgumentNullException("Не указан правильный пароль", nameof(model.Password));
} }
_logger.LogInformation("Client. ClientFIO:{ClientFIO}.Email:{Email}.Password:{Password}.Id:{Id}", _logger.LogInformation("Client. ClientFIO:{ClientFIO}.Email:{Email}.Id:{Id}",
model.ClientFIO, model.Email, model.Password, model.Id); model.ClientFIO, model.Email, model.Id);
var element = _clientStorage.GetElement(new ClientSearchModel var element = _clientStorage.GetElement(new ClientSearchModel
{ {
ClientFIO = model.ClientFIO ClientFIO = model.ClientFIO
}); });
if (element != null && element.Id != model.Id) if (element != null && element.Id != model.Id)
{ {
throw new InvalidOperationException("Клиент с таким именем уже есть"); throw new InvalidOperationException("Клиент с таким именем уже есть");
} }
} }
} }
} }

View File

@ -61,7 +61,7 @@ namespace ConfectioneryBusinessLogic
} }
if (string.IsNullOrEmpty(model.SenderName)) if (string.IsNullOrEmpty(model.SenderName))
{ {
throw new ArgumentNullException("Не указао почта", nameof(model.SenderName)); throw new ArgumentNullException("Не указана почта", nameof(model.SenderName));
} }
if (string.IsNullOrEmpty(model.Subject)) if (string.IsNullOrEmpty(model.Subject))
{ {
@ -79,7 +79,7 @@ namespace ConfectioneryBusinessLogic
}); });
if (element == null) if (element == null)
{ {
_logger.LogWarning("Не удалоссь найти клиента, отправившего письмо с адреса Email:{Email}", model.SenderName); _logger.LogWarning("Не удалось найти клиента, отправившего письмо с адреса Email:{Email}", model.SenderName);
} }
else else
{ {

View File

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq;
namespace ConfectioneryBusinessLogic namespace ConfectioneryBusinessLogic
{ {
@ -17,11 +18,14 @@ namespace ConfectioneryBusinessLogic
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage; private readonly IOrderStorage _orderStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage) private readonly AbstractMailWorker _mailWorker;
static readonly object _locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker)
{ {
_logger = logger; _logger = logger;
_orderStorage = orderStorage; _orderStorage = orderStorage;
} _mailWorker = mailWorker;
}
public OrderViewModel? ReadElement(OrderSearchModel model) public OrderViewModel? ReadElement(OrderSearchModel model)
{ {
if (model == null) if (model == null)
@ -58,23 +62,28 @@ namespace ConfectioneryBusinessLogic
if (model.Status != OrderStatus.Неизвестен) if (model.Status != OrderStatus.Неизвестен)
return false; return false;
model.Status = OrderStatus.Принят; model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null) var element = _orderStorage.Insert(model);
{ if (element == null)
_logger.LogWarning("Insert operation failed"); {
return false; _logger.LogWarning("Insert operation failed");
} return false;
return true; }
} Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel
{
public bool TakeOrderInWork(OrderBindingModel model) MailAddress = element.ClientEmail,
{ Subject = $"Изменение статуса заказа №{element.Id}",
return ChangeStatus(model, OrderStatus.Выполняется); Text = $"Заказ №{element.Id} на кондитерское изделие {element.PastryName} от {element.DateCreate} на сумму {element.Sum} принят."
} }));
return true;
public bool FinishOrder(OrderBindingModel model) }
{ public bool TakeOrderInWork(OrderBindingModel model)
return ChangeStatus(model, OrderStatus.Готов); {
} return ChangeStatus(model, OrderStatus.Выполняется);
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model) public bool DeliveryOrder(OrderBindingModel model)
{ {
@ -141,6 +150,13 @@ namespace ConfectioneryBusinessLogic
_logger.LogWarning("Update operation failed"); _logger.LogWarning("Update operation failed");
return false; return false;
} }
string DateInfo = model.DateImplement.HasValue ? $"Дата выполнения {model.DateImplement}" : "";
Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel
{
MailAddress = element.ClientEmail,
Subject = $"Изменение статуса заказа №{element.Id}",
Text = $"Заказ №{element.Id} на кондитерское изделие {element.PastryName} от {element.DateCreate} на сумму {element.Sum} {model.Status}. {DateInfo}"
}));
return true; return true;
} }
_logger.LogWarning("Changing status operation faled: Current-{Status}:required-{requiredStatus}.", model.Status, requiredStatus); _logger.LogWarning("Changing status operation faled: Current-{Status}:required-{requiredStatus}.", model.Status, requiredStatus);

View File

@ -17,6 +17,7 @@ namespace ConfectioneryContracts.ViewModels
[DisplayName("ФИО клиента")] [DisplayName("ФИО клиента")]
public string ClientFIO { get; set; } = string.Empty; public string ClientFIO { get; set; } = string.Empty;
public string ClientEmail { get; set; } = string.Empty;
public int? ImplementerId { get; set; } public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")] [DisplayName("Исполнитель")]
public string? ImplementerFIO { get; set; } = null; public string? ImplementerFIO { get; set; } = null;

View File

@ -22,10 +22,13 @@ namespace ConfectioneryDatabaseImplement.Models
[Required] [Required]
public string Password { get; set; } = string.Empty; public string Password { get; set; } = string.Empty;
[ForeignKey("ClientId")] [ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new(); public virtual List<Order> ClientOrders { get; set; } = new();
public static Client? Create(ClientBindingModel model) [ForeignKey("ClientId")]
public virtual List<MessageInfo> ClientMessages { get; set; } = new();
public static Client? Create(ClientBindingModel model)
{ {
if (model == null) if (model == null)
{ {

View File

@ -36,11 +36,10 @@ namespace ConfectioneryDatabaseImplement.Implements
return null; return null;
} }
using var context = new ConfectioneryDatabase(); using var context = new ConfectioneryDatabase();
return context.Clients.FirstOrDefault(x => return context.Clients.FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id) ||
(!string.IsNullOrEmpty(model.Email) && x.Email == model.Email && !string.IsNullOrEmpty(model.Password) && x.Password == model.Password) || (!string.IsNullOrEmpty(model.ClientFIO) && x.ClientFIO == model.ClientFIO) ||
(model.Id.HasValue && x.Id == model.Id)) (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email && (string.IsNullOrEmpty(model.Password) || x.Password == model.Password)))?.GetViewModel;
?.GetViewModel; }
}
public ClientViewModel? Insert(ClientBindingModel model) public ClientViewModel? Insert(ClientBindingModel model)
{ {

View File

@ -15,7 +15,7 @@ namespace ConfectioneryDatabaseImplement
{ {
if (optionsBuilder.IsConfigured == false) if (optionsBuilder.IsConfigured == false)
{ {
optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=ConfectioneryDatabaseNewMail;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=ConfectioneryDatabaseNewMailDB;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
} }
base.OnConfiguring(optionsBuilder); base.OnConfiguring(optionsBuilder);
} }

View File

@ -1,48 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ConfectioneryDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitialMail : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "MessageInfos",
columns: table => new
{
MessageId = table.Column<string>(type: "nvarchar(450)", nullable: false),
ClientId = table.Column<int>(type: "int", nullable: true),
SenderName = table.Column<string>(type: "nvarchar(max)", nullable: false),
DateDelivery = table.Column<DateTime>(type: "datetime2", nullable: false),
Subject = table.Column<string>(type: "nvarchar(max)", nullable: false),
Body = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_MessageInfos", x => x.MessageId);
table.ForeignKey(
name: "FK_MessageInfos_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_MessageInfos_ClientId",
table: "MessageInfos",
column: "ClientId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "MessageInfos");
}
}
}

View File

@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace ConfectioneryDatabaseImplement.Migrations namespace ConfectioneryDatabaseImplement.Migrations
{ {
[DbContext(typeof(ConfectioneryDatabase))] [DbContext(typeof(ConfectioneryDatabase))]
[Migration("20240523044722_InitialMail")] [Migration("20240602085942_InitialMail")]
partial class InitialMail partial class InitialMail
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -219,7 +219,7 @@ namespace ConfectioneryDatabaseImplement.Migrations
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.MessageInfo", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.MessageInfo", b =>
{ {
b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client") b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client")
.WithMany() .WithMany("ClientMessages")
.HasForeignKey("ClientId"); .HasForeignKey("ClientId");
b.Navigation("Client"); b.Navigation("Client");
@ -228,7 +228,7 @@ namespace ConfectioneryDatabaseImplement.Migrations
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b =>
{ {
b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client") b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client")
.WithMany("Orders") .WithMany("ClientOrders")
.HasForeignKey("ClientId") .HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
@ -271,7 +271,9 @@ namespace ConfectioneryDatabaseImplement.Migrations
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b =>
{ {
b.Navigation("Orders"); b.Navigation("ClientMessages");
b.Navigation("ClientOrders");
}); });
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b =>

View File

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ConfectioneryDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitialMail : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@ -216,7 +216,7 @@ namespace ConfectioneryDatabaseImplement.Migrations
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.MessageInfo", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.MessageInfo", b =>
{ {
b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client") b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client")
.WithMany() .WithMany("ClientMessages")
.HasForeignKey("ClientId"); .HasForeignKey("ClientId");
b.Navigation("Client"); b.Navigation("Client");
@ -225,7 +225,7 @@ namespace ConfectioneryDatabaseImplement.Migrations
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b =>
{ {
b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client") b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client")
.WithMany("Orders") .WithMany("ClientOrders")
.HasForeignKey("ClientId") .HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
@ -268,7 +268,9 @@ namespace ConfectioneryDatabaseImplement.Migrations
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b =>
{ {
b.Navigation("Orders"); b.Navigation("ClientMessages");
b.Navigation("ClientOrders");
}); });
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b =>

View File

@ -76,7 +76,8 @@ namespace ConfectioneryDatabaseImplement.Models
Id = Id, Id = Id,
ClientId = ClientId, ClientId = ClientId,
ClientFIO = Client.ClientFIO, ClientFIO = Client.ClientFIO,
PastryId = PastryId, ClientEmail = Client.Email,
PastryId = PastryId,
PastryName = Pastry.PastryName, PastryName = Pastry.PastryName,
ImplementerId = ImplementerId, ImplementerId = ImplementerId,
ImplementerFIO = Implementer != null ? Implementer.ImplementerFIO : null, ImplementerFIO = Implementer != null ? Implementer.ImplementerFIO : null,

View File

@ -22,10 +22,10 @@ builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>(); builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddTransient<AbstractMailWorker, MailKitWorker>(); builder.Services.AddTransient<AbstractMailWorker, MailKitWorker>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at
https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(c =>
{ {

View File

@ -43,6 +43,7 @@ namespace ConfectioneryView
dataGridView.DataSource = list; dataGridView.DataSource = list;
dataGridView.Columns["PastryId"].Visible = false; dataGridView.Columns["PastryId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false; dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["ClientEmail"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false; dataGridView.Columns["ImplementerId"].Visible = false;
dataGridView.Columns["PastryName"].AutoSizeMode = dataGridView.Columns["PastryName"].AutoSizeMode =
DataGridViewAutoSizeColumnMode.Fill; DataGridViewAutoSizeColumnMode.Fill;

View File

@ -63,6 +63,7 @@ namespace ConfectioneryView
services.AddTransient<IMessageInfoStorage, MessageInfoStorage>(); services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
services.AddTransient<IClientStorage, ClientStorage>(); services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IImplementerStorage, ImplementerStorage>(); services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<IImplementerLogic, ImplementerLogic>(); services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IClientLogic, ClientLogic>(); services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IComponentLogic, ComponentLogic>(); services.AddTransient<IComponentLogic, ComponentLogic>();
@ -71,10 +72,12 @@ namespace ConfectioneryView
services.AddTransient<IReportLogic, ReportLogic>(); services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IMessageInfoLogic, MessageInfoLogic>(); services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
services.AddTransient<IWorkProcess, WorkModeling>(); services.AddTransient<IWorkProcess, WorkModeling>();
services.AddTransient<AbstractSaveToWord, SaveToWord>(); services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>(); services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToPdf, SaveToPdf>(); services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
services.AddSingleton<AbstractMailWorker, MailKitWorker>(); services.AddSingleton<AbstractMailWorker, MailKitWorker>();
services.AddTransient<FormMain>(); services.AddTransient<FormMain>();
services.AddTransient<FormComponent>(); services.AddTransient<FormComponent>();
services.AddTransient<FormComponents>(); services.AddTransient<FormComponents>();
@ -88,6 +91,7 @@ namespace ConfectioneryView
services.AddTransient<FormImplementers>(); services.AddTransient<FormImplementers>();
services.AddTransient<FormImplementer>(); services.AddTransient<FormImplementer>();
services.AddTransient<FormMail>(); services.AddTransient<FormMail>();
services.AddTransient<EntityFrameworkDesignServicesBuilder>(); services.AddTransient<EntityFrameworkDesignServicesBuilder>();
} }
private static void MailCheck(object obj) => ServiceProvider?.GetService<AbstractMailWorker>()?.MailCheck(); private static void MailCheck(object obj) => ServiceProvider?.GetService<AbstractMailWorker>()?.MailCheck();