ISEbd-21.Fedotov.I.A.LabWork07 #7

Closed
Ilfedotov.01 wants to merge 2 commits from ISEbd-21.Fedotov.I.A.LabWork07 into ISEbd-21.Fedotov.I.A.LabWork06
56 changed files with 1282 additions and 964 deletions

View File

@ -118,5 +118,13 @@ namespace DinerClientApp.Controllers {
var _snack = APIClient.GetRequest<SnackViewModel>($"api/main/getproduct?snackid={snack}"); var _snack = APIClient.GetRequest<SnackViewModel>($"api/main/getproduct?snackid={snack}");
return count * (_snack?.Price ?? 1); return count * (_snack?.Price ?? 1);
} }
[HttpGet]
public IActionResult Mails() {
if (APIClient.Client == null) {
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientid={APIClient.Client.ID}"));
}
} }
} }

View File

@ -0,0 +1,52 @@
@using DinerContracts.ViewModels
@model List<MessageInfoViewModel>
@{
ViewData["Title"] = "Mails";
}
<div class="text-center">
<h1 class="display-4">Заказы</h1>
</div>
<div class="text-center">
@{
if (Model == null) {
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<table class="table">
<thead>
<tr>
<th>
Дата письма
</th>
<th>
Заголовок
</th>
<th>
Текст
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.DateDelivery)
</td>
<td>
@Html.DisplayFor(modelItem => item.Subject)
</td>
<td>
@Html.DisplayFor(modelItem => item.Body)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -27,6 +27,9 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a> <a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li> </li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Mails">Письма</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a> <a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li> </li>

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.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; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.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;
}
}

View File

@ -0,0 +1,22 @@
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BindingModels {
public class MessageInfoBindingModel : IMessageInfoModel {
public string MessageID { get; set; } = string.Empty;
public int? ClientID { get; set; }
public string SenderName { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
}
}

View File

@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace DinerContracts.BusinessLogicsContracts { namespace DinerContracts.BusinessLogicsContracts {
public interface IClientLogic { public interface IClientLogic {
List<ClientViewModel>? ReadList(ClientSearchModel? model); List<ClientViewModel>? ReadList(ClientSearchModel? model);
ClientViewModel? ReadELement(ClientSearchModel model); ClientViewModel? ReadElement(ClientSearchModel model);
bool Create(ClientBindingModel model); bool Create(ClientBindingModel model);
bool Update(ClientBindingModel model); bool Update(ClientBindingModel model);

View File

@ -0,0 +1,17 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BusinessLogicsContracts {
public interface IMessageInfoLogic {
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model);
bool Create(MessageInfoBindingModel model);
}
}

View File

@ -0,0 +1,17 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.SearchModels {
public interface IMessageInfoStorage {
List<MessageInfoViewModel> GetFullList();
List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model);
MessageInfoViewModel? GetElement(MessageInfoSearchModel model);
MessageInfoViewModel? Insert(MessageInfoBindingModel model);
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.SearchModels
{
public class MessageInfoSearchModel
{
public int? ClientID { get; set; }
public string? MessageID { get; set; }
}
}

View File

@ -0,0 +1,27 @@
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.ViewModels {
public class MessageInfoViewModel : IMessageInfoModel {
public string MessageID { get; set; } = string.Empty;
public int? ClientID { get; set; }
[DisplayName("Отправитель")]
public string SenderName { get; set; } = string.Empty;
[DisplayName("Дата письма")]
public DateTime DateDelivery { get; set; }
[DisplayName("Заголовоск")]
public string Subject { get; set; } = string.Empty;
[DisplayName("Текст")]
public string Body { get; set; } = string.Empty;
}
}

View File

@ -3,11 +3,11 @@ using Microsoft.EntityFrameworkCore;
namespace DinerDataBaseImplement namespace DinerDataBaseImplement
{ {
public class DinerDatabaseBy6Work : DbContext public class DinerDatabaseBy7Work : DbContext
{ {
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
if (optionsBuilder.IsConfigured == false) { if (optionsBuilder.IsConfigured == false) {
optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-O0N00SH\SQLEXPRESS;Initial Catalog=DinerDatabaseBy6Work;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-O0N00SH\SQLEXPRESS;Initial Catalog=DinerDatabaseBy7Work;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
} }
base.OnConfiguring(optionsBuilder); base.OnConfiguring(optionsBuilder);
} }
@ -17,5 +17,6 @@ namespace DinerDataBaseImplement
public virtual DbSet<Order> Orders { get; set; } public virtual DbSet<Order> Orders { get; set; }
public virtual DbSet<Client> Clients { get; set; } public virtual DbSet<Client> Clients { get; set; }
public virtual DbSet<Implementer> Implementers { get; set; } public virtual DbSet<Implementer> Implementers { get; set; }
public virtual DbSet<MessageInfo> MessageInfos { get; set; }
} }
} }

View File

@ -18,7 +18,7 @@ namespace DinerDataBaseImplement.Implements {
if (newClient == null) { if (newClient == null) {
return null; return null;
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
context.Clients.Add(newClient); context.Clients.Add(newClient);
context.SaveChanges(); context.SaveChanges();
@ -29,7 +29,7 @@ namespace DinerDataBaseImplement.Implements {
} }
public ClientViewModel? Update(ClientBindingModel model) { public ClientViewModel? Update(ClientBindingModel model) {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var client = context.Clients.FirstOrDefault(x => x.ID == model.ID); var client = context.Clients.FirstOrDefault(x => x.ID == model.ID);
if (client == null) { if (client == null) {
return null; return null;
@ -40,7 +40,7 @@ namespace DinerDataBaseImplement.Implements {
} }
public ClientViewModel? Delete(ClientBindingModel model) { public ClientViewModel? Delete(ClientBindingModel model) {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var element = context.Clients.FirstOrDefault(x => x.ID == model.ID); var element = context.Clients.FirstOrDefault(x => x.ID == model.ID);
if (element != null) { if (element != null) {
context.Clients.Remove(element); context.Clients.Remove(element);
@ -51,7 +51,7 @@ namespace DinerDataBaseImplement.Implements {
} }
public ClientViewModel? GetElement(ClientSearchModel model) { public ClientViewModel? GetElement(ClientSearchModel model) {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
if (model.ID.HasValue) { if (model.ID.HasValue) {
return context.Clients return context.Clients
.Include(x => x.Orders) .Include(x => x.Orders)
@ -71,7 +71,7 @@ namespace DinerDataBaseImplement.Implements {
if (string.IsNullOrEmpty(model.ClientFIO)) { if (string.IsNullOrEmpty(model.ClientFIO)) {
return new(); return new();
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Clients return context.Clients
.Include(x => x.Orders) .Include(x => x.Orders)
@ -81,7 +81,7 @@ namespace DinerDataBaseImplement.Implements {
} }
public List<ClientViewModel> GetFullList() { public List<ClientViewModel> GetFullList() {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Clients return context.Clients
.Include(x => x.Orders) .Include(x => x.Orders)

View File

@ -16,7 +16,7 @@ namespace DinerDataBaseImplement.Implements
{ {
public FoodViewModel? Delete(FoodBindingModel model) public FoodViewModel? Delete(FoodBindingModel model)
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var element = context.Components.FirstOrDefault(x => x.ID == model.ID); var element = context.Components.FirstOrDefault(x => x.ID == model.ID);
if (element != null) if (element != null)
{ {
@ -32,7 +32,7 @@ namespace DinerDataBaseImplement.Implements
if (string.IsNullOrEmpty(model.ComponentName) && !model.ID.HasValue) { if (string.IsNullOrEmpty(model.ComponentName) && !model.ID.HasValue) {
return null; return null;
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Components return context.Components
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ComponentName) && .FirstOrDefault(x => (!string.IsNullOrEmpty(model.ComponentName) &&
x.ComponentName == model.ComponentName) || model.ID.HasValue && x.ComponentName == model.ComponentName) || model.ID.HasValue &&
@ -45,7 +45,7 @@ namespace DinerDataBaseImplement.Implements
return new(); return new();
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Components.Where(x => x.ComponentName.Contains(model.ComponentName)) return context.Components.Where(x => x.ComponentName.Contains(model.ComponentName))
.Select(x => x.GetViewModel).ToList(); .Select(x => x.GetViewModel).ToList();
@ -53,7 +53,7 @@ namespace DinerDataBaseImplement.Implements
public List<FoodViewModel> GetFullList() public List<FoodViewModel> GetFullList()
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Components.Select(x => x.GetViewModel).ToList(); return context.Components.Select(x => x.GetViewModel).ToList();
} }
@ -63,7 +63,7 @@ namespace DinerDataBaseImplement.Implements
if (newComponent == null) { if (newComponent == null) {
return null; return null;
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
context.Components.Add(newComponent); context.Components.Add(newComponent);
context.SaveChanges(); context.SaveChanges();
return newComponent.GetViewModel; return newComponent.GetViewModel;
@ -71,7 +71,7 @@ namespace DinerDataBaseImplement.Implements
public FoodViewModel? Update(FoodBindingModel model) public FoodViewModel? Update(FoodBindingModel model)
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var component = context.Components.FirstOrDefault(x => x.ID == model.ID); var component = context.Components.FirstOrDefault(x => x.ID == model.ID);
if (component == null) { if (component == null) {
return null; return null;

View File

@ -19,7 +19,7 @@ namespace DinerDataBaseImplement.Implements {
if (newImplementer == null) { if (newImplementer == null) {
return null; return null;
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
context.Implementers.Add(newImplementer); context.Implementers.Add(newImplementer);
context.SaveChanges(); context.SaveChanges();
@ -30,7 +30,7 @@ namespace DinerDataBaseImplement.Implements {
} }
public ImplementerViewModel? Update(ImplementerBindingModel model) { public ImplementerViewModel? Update(ImplementerBindingModel model) {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var implementer = context.Implementers.FirstOrDefault(x => x.ID == model.ID); var implementer = context.Implementers.FirstOrDefault(x => x.ID == model.ID);
if (implementer == null) { if (implementer == null) {
return null; return null;
@ -41,7 +41,7 @@ namespace DinerDataBaseImplement.Implements {
} }
public ImplementerViewModel? Delete(ImplementerBindingModel model) { public ImplementerViewModel? Delete(ImplementerBindingModel model) {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var element = context.Implementers.FirstOrDefault(x => x.ID == model.ID); var element = context.Implementers.FirstOrDefault(x => x.ID == model.ID);
if (element != null) { if (element != null) {
context.Implementers.Remove(element); context.Implementers.Remove(element);
@ -52,7 +52,7 @@ namespace DinerDataBaseImplement.Implements {
} }
public ImplementerViewModel? GetElement(ImplementerSearchModel model) { public ImplementerViewModel? GetElement(ImplementerSearchModel model) {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
if (model.ID.HasValue) { if (model.ID.HasValue) {
return context.Implementers return context.Implementers
.Include(x => x.Orders) .Include(x => x.Orders)
@ -66,7 +66,7 @@ namespace DinerDataBaseImplement.Implements {
if (string.IsNullOrEmpty(model.ImplementerFIO)) { if (string.IsNullOrEmpty(model.ImplementerFIO)) {
return new(); return new();
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Implementers return context.Implementers
.Include(x => x.Orders) .Include(x => x.Orders)
@ -76,7 +76,7 @@ namespace DinerDataBaseImplement.Implements {
} }
public List<ImplementerViewModel> GetFullList() { public List<ImplementerViewModel> GetFullList() {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Implementers return context.Implementers
.Include(x => x.Orders) .Include(x => x.Orders)

View File

@ -0,0 +1,47 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using DinerDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataBaseImplement.Implements {
public class MessageInfoStorage : IMessageInfoStorage {
public MessageInfoViewModel? Insert(MessageInfoBindingModel model) {
using var context = new DinerDatabaseBy7Work();
var newMessageInfo = MessageInfo.Create(context, model);
if (newMessageInfo == null) {
return null;
}
context.MessageInfos.Add(newMessageInfo);
context.SaveChanges();
return newMessageInfo.GetViewModel;
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model) {
using var context = new DinerDatabaseBy7Work();
if (!string.IsNullOrEmpty(model.MessageID)) {
return context.MessageInfos.FirstOrDefault(x => string.IsNullOrEmpty(model.MessageID) &&
model.MessageID == x.MessageID)?.GetViewModel;
}
return new();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model) {
using var context = new DinerDatabaseBy7Work();
return context.MessageInfos.
Where(x => x.ClientID == model.ClientID).Select(x => x.GetViewModel).ToList();
}
public List<MessageInfoViewModel> GetFullList() {
using var context = new DinerDatabaseBy7Work();
return context.MessageInfos.Select(x => x.GetViewModel).ToList();
}
}
}

View File

@ -16,7 +16,7 @@ namespace DinerDataBaseImplement.Implements
{ {
public OrderViewModel? Delete(OrderBindingModel model) public OrderViewModel? Delete(OrderBindingModel model)
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var element = context.Orders.FirstOrDefault(x => x.ID == model.ID); var element = context.Orders.FirstOrDefault(x => x.ID == model.ID);
if (element != null) if (element != null)
{ {
@ -32,7 +32,7 @@ namespace DinerDataBaseImplement.Implements
if (!model.ID.HasValue) { if (!model.ID.HasValue) {
return null; return null;
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Orders.Include(x => x.Snack) return context.Orders.Include(x => x.Snack)
.Include(x => x.Client) .Include(x => x.Client)
.FirstOrDefault(x => model.ID.HasValue && x.ID == model.ID)?.GetViewModel; .FirstOrDefault(x => model.ID.HasValue && x.ID == model.ID)?.GetViewModel;
@ -41,7 +41,7 @@ namespace DinerDataBaseImplement.Implements
public List<OrderViewModel> GetFilteredList(OrderSearchModel model) public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
if (!model.ID.HasValue && model.DateFrom.HasValue && model.DateTo.HasValue) { if (!model.ID.HasValue && model.DateFrom.HasValue && model.DateTo.HasValue) {
return context.Orders return context.Orders
.Include(x => x.Snack) .Include(x => x.Snack)
@ -80,13 +80,13 @@ namespace DinerDataBaseImplement.Implements
public List<OrderViewModel> GetFullList() public List<OrderViewModel> GetFullList()
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Orders.Include(x => x.Snack).Include(x => x.Client).Include(x => x.Implementer) return context.Orders.Include(x => x.Snack).Include(x => x.Client).Include(x => x.Implementer)
.Select(x => x.GetViewModel).ToList(); .Select(x => x.GetViewModel).ToList();
} }
public OrderViewModel? Insert(OrderBindingModel model) public OrderViewModel? Insert(OrderBindingModel model)
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var newOrder = Order.Create(model); var newOrder = Order.Create(model);
if (newOrder == null) { if (newOrder == null) {
return null; return null;
@ -98,7 +98,7 @@ namespace DinerDataBaseImplement.Implements
.FirstOrDefault(x => x.ID == newOrder.ID)?.GetViewModel; .FirstOrDefault(x => x.ID == newOrder.ID)?.GetViewModel;
} }
public OrderViewModel? Update(OrderBindingModel model) { public OrderViewModel? Update(OrderBindingModel model) {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var order = context.Orders.FirstOrDefault(x => x.ID == model.ID); var order = context.Orders.FirstOrDefault(x => x.ID == model.ID);
if (order == null) { return null; } if (order == null) { return null; }
order.Update(model); order.Update(model);

View File

@ -17,7 +17,7 @@ namespace DinerDataBaseImplement.Implements
{ {
public SnackViewModel? Delete(SnackBindingModel model) public SnackViewModel? Delete(SnackBindingModel model)
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var element = context.Snacks var element = context.Snacks
.Include(x => x.Components) .Include(x => x.Components)
.Include(x => x.Orders) .Include(x => x.Orders)
@ -36,7 +36,7 @@ namespace DinerDataBaseImplement.Implements
if (string.IsNullOrEmpty(model.ProductName) && !model.ID.HasValue) { if (string.IsNullOrEmpty(model.ProductName) && !model.ID.HasValue) {
return null; return null;
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Snacks return context.Snacks
.Include(x => x.Components) .Include(x => x.Components)
.ThenInclude(x => x.Component) .ThenInclude(x => x.Component)
@ -50,7 +50,7 @@ namespace DinerDataBaseImplement.Implements
if (string.IsNullOrEmpty(model.ProductName)) { if (string.IsNullOrEmpty(model.ProductName)) {
return new(); return new();
} }
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Snacks return context.Snacks
.Include(x => x.Components) .Include(x => x.Components)
.ThenInclude(x => x.Component) .ThenInclude(x => x.Component)
@ -61,7 +61,7 @@ namespace DinerDataBaseImplement.Implements
public List<SnackViewModel> GetFullList() public List<SnackViewModel> GetFullList()
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
return context.Snacks return context.Snacks
.Include(x => x.Components) .Include(x => x.Components)
.ThenInclude(x => x.Component).ToList() .ThenInclude(x => x.Component).ToList()
@ -70,7 +70,7 @@ namespace DinerDataBaseImplement.Implements
public SnackViewModel? Insert(SnackBindingModel model) public SnackViewModel? Insert(SnackBindingModel model)
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
var newProduct = Snack.Create(context, model); var newProduct = Snack.Create(context, model);
if (newProduct == null) { if (newProduct == null) {
return null; return null;
@ -82,7 +82,7 @@ namespace DinerDataBaseImplement.Implements
public SnackViewModel? Update(SnackBindingModel model) public SnackViewModel? Update(SnackBindingModel model)
{ {
using var context = new DinerDatabaseBy6Work(); using var context = new DinerDatabaseBy7Work();
using var transcation = context.Database.BeginTransaction(); using var transcation = context.Database.BeginTransaction();
try try
{ {

View File

@ -1,260 +0,0 @@
// <auto-generated />
using System;
using DinerDataBaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
[DbContext(typeof(DinerDatabaseBy6Work))]
[Migration("20240513154945_InitMigration")]
partial class InitMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DinerDataBaseImplement.Models.Client", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Clients");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("ID");
b.ToTable("Components");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("ID");
b.ToTable("Implementers");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ClientID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerID")
.IsRequired()
.HasColumnType("int");
b.Property<int>("SnackID")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("ID");
b.HasIndex("ClientID");
b.HasIndex("ImplementerID");
b.HasIndex("SnackID");
b.ToTable("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ProductName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Snacks");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ComponentID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("SnackID")
.HasColumnType("int");
b.HasKey("ID");
b.HasIndex("ComponentID");
b.HasIndex("SnackID");
b.ToTable("ProductComponents");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Snack", "Snack")
.WithMany("Orders")
.HasForeignKey("SnackID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Snack");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Food", "Component")
.WithMany("SnackFood")
.HasForeignKey("ComponentID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Snack", "Product")
.WithMany("Components")
.HasForeignKey("SnackID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Product");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Navigation("SnackFood");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,257 +0,0 @@
// <auto-generated />
using System;
using DinerDataBaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
[DbContext(typeof(DinerDatabaseBy6Work))]
[Migration("20240513162929_Migration01")]
partial class Migration01
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DinerDataBaseImplement.Models.Client", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Clients");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("ID");
b.ToTable("Components");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("ID");
b.ToTable("Implementers");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ClientID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerID")
.HasColumnType("int");
b.Property<int>("SnackID")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("ID");
b.HasIndex("ClientID");
b.HasIndex("ImplementerID");
b.HasIndex("SnackID");
b.ToTable("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ProductName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Snacks");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ComponentID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("SnackID")
.HasColumnType("int");
b.HasKey("ID");
b.HasIndex("ComponentID");
b.HasIndex("SnackID");
b.ToTable("ProductComponents");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerID");
b.HasOne("DinerDataBaseImplement.Models.Snack", "Snack")
.WithMany("Orders")
.HasForeignKey("SnackID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Snack");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Food", "Component")
.WithMany("SnackFood")
.HasForeignKey("ComponentID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Snack", "Product")
.WithMany("Components")
.HasForeignKey("SnackID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Product");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Navigation("SnackFood");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,59 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class Migration01 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Orders_Implementers_ImplementerID",
table: "Orders");
migrationBuilder.AlterColumn<int>(
name: "ImplementerID",
table: "Orders",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AddForeignKey(
name: "FK_Orders_Implementers_ImplementerID",
table: "Orders",
column: "ImplementerID",
principalTable: "Implementers",
principalColumn: "ID");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Orders_Implementers_ImplementerID",
table: "Orders");
migrationBuilder.AlterColumn<int>(
name: "ImplementerID",
table: "Orders",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_Orders_Implementers_ImplementerID",
table: "Orders",
column: "ImplementerID",
principalTable: "Implementers",
principalColumn: "ID",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -1,29 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class Migration02 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ProductName",
table: "Orders",
type: "nvarchar(max)",
nullable: false,
defaultValue: "");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ProductName",
table: "Orders");
}
}
}

View File

@ -1,257 +0,0 @@
// <auto-generated />
using System;
using DinerDataBaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
[DbContext(typeof(DinerDatabaseBy6Work))]
[Migration("20240515121617_Migration03")]
partial class Migration03
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DinerDataBaseImplement.Models.Client", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Clients");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("ID");
b.ToTable("Components");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("ID");
b.ToTable("Implementers");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ClientID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerID")
.HasColumnType("int");
b.Property<int>("SnackID")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("ID");
b.HasIndex("ClientID");
b.HasIndex("ImplementerID");
b.HasIndex("SnackID");
b.ToTable("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ProductName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Snacks");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ComponentID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("SnackID")
.HasColumnType("int");
b.HasKey("ID");
b.HasIndex("ComponentID");
b.HasIndex("SnackID");
b.ToTable("ProductComponents");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerID");
b.HasOne("DinerDataBaseImplement.Models.Snack", "Snack")
.WithMany("Orders")
.HasForeignKey("SnackID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Snack");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Food", "Component")
.WithMany("SnackFood")
.HasForeignKey("ComponentID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Snack", "Product")
.WithMany("Components")
.HasForeignKey("SnackID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Product");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Navigation("SnackFood");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,29 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class Migration03 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ProductName",
table: "Orders");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ProductName",
table: "Orders",
type: "nvarchar(max)",
nullable: false,
defaultValue: "");
}
}
}

View File

@ -11,9 +11,9 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace DinerDataBaseImplement.Migrations namespace DinerDataBaseImplement.Migrations
{ {
[DbContext(typeof(DinerDatabaseBy6Work))] [DbContext(typeof(DinerDatabaseBy7Work))]
[Migration("20240515115440_Migration02")] [Migration("20240516122239_InitMigration")]
partial class Migration02 partial class InitMigration
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -97,6 +97,36 @@ namespace DinerDataBaseImplement.Migrations
b.ToTable("Implementers"); b.ToTable("Implementers");
}); });
modelBuilder.Entity("DinerDataBaseImplement.Models.MessageInfo", b =>
{
b.Property<string>("MessageID")
.HasColumnType("nvarchar(450)");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ClientID")
.HasColumnType("int");
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("MessageID");
b.HasIndex("ClientID");
b.ToTable("MessageInfos");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b => modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{ {
b.Property<int>("ID") b.Property<int>("ID")
@ -120,10 +150,6 @@ namespace DinerDataBaseImplement.Migrations
b.Property<int?>("ImplementerID") b.Property<int?>("ImplementerID")
.HasColumnType("int"); .HasColumnType("int");
b.Property<string>("ProductName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("SnackID") b.Property<int>("SnackID")
.HasColumnType("int"); .HasColumnType("int");
@ -190,6 +216,15 @@ namespace DinerDataBaseImplement.Migrations
b.ToTable("ProductComponents"); b.ToTable("ProductComponents");
}); });
modelBuilder.Entity("DinerDataBaseImplement.Models.MessageInfo", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Client", "Client")
.WithMany()
.HasForeignKey("ClientID");
b.Navigation("Client");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b => modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{ {
b.HasOne("DinerDataBaseImplement.Models.Client", "Client") b.HasOne("DinerDataBaseImplement.Models.Client", "Client")

View File

@ -70,6 +70,27 @@ namespace DinerDataBaseImplement.Migrations
table.PrimaryKey("PK_Snacks", x => x.ID); table.PrimaryKey("PK_Snacks", x => x.ID);
}); });
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.CreateTable( migrationBuilder.CreateTable(
name: "Orders", name: "Orders",
columns: table => new columns: table => new
@ -78,7 +99,7 @@ namespace DinerDataBaseImplement.Migrations
.Annotation("SqlServer:Identity", "1, 1"), .Annotation("SqlServer:Identity", "1, 1"),
SnackID = table.Column<int>(type: "int", nullable: false), SnackID = table.Column<int>(type: "int", nullable: false),
ClientID = table.Column<int>(type: "int", nullable: false), ClientID = table.Column<int>(type: "int", nullable: false),
ImplementerID = table.Column<int>(type: "int", nullable: false), ImplementerID = table.Column<int>(type: "int", nullable: true),
Count = table.Column<int>(type: "int", nullable: false), Count = table.Column<int>(type: "int", nullable: false),
Sum = table.Column<double>(type: "float", nullable: false), Sum = table.Column<double>(type: "float", nullable: false),
Status = table.Column<int>(type: "int", nullable: false), Status = table.Column<int>(type: "int", nullable: false),
@ -98,8 +119,7 @@ namespace DinerDataBaseImplement.Migrations
name: "FK_Orders_Implementers_ImplementerID", name: "FK_Orders_Implementers_ImplementerID",
column: x => x.ImplementerID, column: x => x.ImplementerID,
principalTable: "Implementers", principalTable: "Implementers",
principalColumn: "ID", principalColumn: "ID");
onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "FK_Orders_Snacks_SnackID", name: "FK_Orders_Snacks_SnackID",
column: x => x.SnackID, column: x => x.SnackID,
@ -135,6 +155,11 @@ namespace DinerDataBaseImplement.Migrations
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.CreateIndex(
name: "IX_MessageInfos_ClientID",
table: "MessageInfos",
column: "ClientID");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_Orders_ClientID", name: "IX_Orders_ClientID",
table: "Orders", table: "Orders",
@ -164,6 +189,9 @@ namespace DinerDataBaseImplement.Migrations
/// <inheritdoc /> /// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.DropTable(
name: "MessageInfos");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Orders"); name: "Orders");

View File

@ -10,8 +10,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace DinerDataBaseImplement.Migrations namespace DinerDataBaseImplement.Migrations
{ {
[DbContext(typeof(DinerDatabaseBy6Work))] [DbContext(typeof(DinerDatabaseBy7Work))]
partial class DinerDatabaseBy6WorkModelSnapshot : ModelSnapshot partial class DinerDatabaseBy7WorkModelSnapshot : ModelSnapshot
{ {
protected override void BuildModel(ModelBuilder modelBuilder) protected override void BuildModel(ModelBuilder modelBuilder)
{ {
@ -44,7 +44,7 @@ namespace DinerDataBaseImplement.Migrations
b.HasKey("ID"); b.HasKey("ID");
b.ToTable("Clients"); b.ToTable("Clients", (string)null);
}); });
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b => modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
@ -64,7 +64,7 @@ namespace DinerDataBaseImplement.Migrations
b.HasKey("ID"); b.HasKey("ID");
b.ToTable("Components"); b.ToTable("Components", (string)null);
}); });
modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b => modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b =>
@ -91,7 +91,37 @@ namespace DinerDataBaseImplement.Migrations
b.HasKey("ID"); b.HasKey("ID");
b.ToTable("Implementers"); b.ToTable("Implementers", (string)null);
});
modelBuilder.Entity("DinerDataBaseImplement.Models.MessageInfo", b =>
{
b.Property<string>("MessageID")
.HasColumnType("nvarchar(450)");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ClientID")
.HasColumnType("int");
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("MessageID");
b.HasIndex("ClientID");
b.ToTable("MessageInfos", (string)null);
}); });
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b => modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
@ -134,7 +164,7 @@ namespace DinerDataBaseImplement.Migrations
b.HasIndex("SnackID"); b.HasIndex("SnackID");
b.ToTable("Orders"); b.ToTable("Orders", (string)null);
}); });
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b => modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
@ -154,7 +184,7 @@ namespace DinerDataBaseImplement.Migrations
b.HasKey("ID"); b.HasKey("ID");
b.ToTable("Snacks"); b.ToTable("Snacks", (string)null);
}); });
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b => modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
@ -180,7 +210,16 @@ namespace DinerDataBaseImplement.Migrations
b.HasIndex("SnackID"); b.HasIndex("SnackID");
b.ToTable("ProductComponents"); b.ToTable("ProductComponents", (string)null);
});
modelBuilder.Entity("DinerDataBaseImplement.Models.MessageInfo", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Client", "Client")
.WithMany()
Review

Связь настроена не до конца

Связь настроена не до конца
.HasForeignKey("ClientID");
b.Navigation("Client");
}); });
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b => modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>

View File

@ -0,0 +1,52 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataBaseImplement.Models {
public class MessageInfo : IMessageInfoModel {
[Key]
public string MessageID { get; set; } = string.Empty;
public int? ClientID { get; set; }
public string SenderName { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public virtual Client? Client { get; set; }
public static MessageInfo? Create(DinerDatabaseBy7Work context, MessageInfoBindingModel model) {
if (model == null) {
return null;
}
return new MessageInfo() {
MessageID = model.MessageID,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
Subject = model.Subject,
Body = model.Body
};
}
public MessageInfoViewModel GetViewModel => new() {
MessageID = MessageID,
ClientID = ClientID,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body,
};
}
}

View File

@ -1,7 +1,6 @@
using DinerContracts.BindingModels; using DinerContracts.BindingModels;
using DinerContracts.ViewModels; using DinerContracts.ViewModels;
using DinerDataBaseImplement.Implements; using DinerDataBaseImplement.Implements;
using DinerDataBaseImplement.Migrations;
using DinerDataModels.Enums; using DinerDataModels.Enums;
using DinerDataModels.Models; using DinerDataModels.Models;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;

View File

@ -44,7 +44,7 @@ namespace DinerDataBaseImplement.Models
[ForeignKey("SnackID")] [ForeignKey("SnackID")]
public virtual List<Order> Orders { get; set; } = new(); public virtual List<Order> Orders { get; set; } = new();
public static Snack? Create(DinerDatabaseBy6Work context,SnackBindingModel model) public static Snack? Create(DinerDatabaseBy7Work context,SnackBindingModel model)
{ {
return new Snack() return new Snack()
{ {
@ -72,7 +72,7 @@ namespace DinerDataBaseImplement.Models
ProductComponents = ProductComponents ProductComponents = ProductComponents
}; };
public void UpdateComponents(DinerDatabaseBy6Work context, SnackBindingModel model) { public void UpdateComponents(DinerDatabaseBy7Work context, SnackBindingModel model) {
var productComponents = context.ProductComponents.Where(rec => rec.SnackID == model.ID).ToList(); var productComponents = context.ProductComponents.Where(rec => rec.SnackID == model.ID).ToList();
if (ProductComponents != null && ProductComponents.Count > 0) { if (ProductComponents != null && ProductComponents.Count > 0) {
context.ProductComponents.RemoveRange(productComponents.Where(rec => !model.ProductComponents.ContainsKey(rec.ComponentID))); context.ProductComponents.RemoveRange(productComponents.Where(rec => !model.ProductComponents.ContainsKey(rec.ComponentID)));

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataModels.Models {
public interface IMessageInfoModel {
string MessageID { get; }
int? ClientID { get; }
string SenderName { get; }
DateTime DateDelivery { get; }
string Subject { get; }
string Body { get; }
}
}

View File

@ -16,6 +16,7 @@ namespace DinerListImplement
public List<Order> Orders { get; set; } public List<Order> Orders { get; set; }
public List<Client> Clients { get; set; } public List<Client> Clients { get; set; }
public List<Implementer> Implementers { get; set; } public List<Implementer> Implementers { get; set; }
public List<MessageInfo> MessageInfos { get; set; }
private DataListSingleton() { private DataListSingleton() {
Foods = new List<Food>(); Foods = new List<Food>();
@ -23,6 +24,7 @@ namespace DinerListImplement
Orders = new List<Order>(); Orders = new List<Order>();
Clients = new List<Client>(); Clients = new List<Client>();
Implementers = new List<Implementer>(); Implementers = new List<Implementer>();
MessageInfos = new List<MessageInfo>();
} }
public static DataListSingleton GetInstance() { public static DataListSingleton GetInstance() {
if (_instance == null) _instance = new DataListSingleton(); if (_instance == null) _instance = new DataListSingleton();

View File

@ -0,0 +1,65 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using DinerListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Implements {
public class MessageInfoStorage : IMessageInfoStorage {
private readonly DataListSingleton _source;
public MessageInfoStorage() {
_source = DataListSingleton.GetInstance();
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model) {
var newMessageInfo = MessageInfo.Create(model);
if (newMessageInfo == null) {
return null;
}
_source.MessageInfos.Add(newMessageInfo);
return newMessageInfo.GetViewModel;
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model) {
if (string.IsNullOrEmpty(model.MessageID)) {
return null;
}
foreach(var messageInfos in _source.MessageInfos) {
if ((!string.IsNullOrEmpty(model.MessageID) &&
messageInfos.MessageID == model.MessageID)) {
return messageInfos.GetViewModel;
}
}
return null;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model) {
var result = new List<MessageInfoViewModel>();
if (string.IsNullOrEmpty(model.MessageID)) {
return result;
}
foreach (var messageInfos in _source.MessageInfos) {
if (messageInfos.MessageID.Contains(model.MessageID)) {
result.Add(messageInfos.GetViewModel);
}
}
return result;
}
public List<MessageInfoViewModel> GetFullList() {
var result = new List<MessageInfoViewModel>();
foreach (var messageInfos in _source.MessageInfos) {
result.Add(messageInfos.GetViewModel);
}
return result;
}
}
}

View File

@ -28,6 +28,7 @@ namespace DinerListImplement.Models {
Password = model.Password, Password = model.Password,
WorkExperience = model.WorkExperience, WorkExperience = model.WorkExperience,
Qualification = model.Qualification, Qualification = model.Qualification,
ID = model.ID,
}; };
} }
public void Update(ImplementerBindingModel? model) { public void Update(ImplementerBindingModel? model) {

View File

@ -0,0 +1,47 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Models {
public class MessageInfo : IMessageInfoModel {
public string MessageID { get; private set; } = string.Empty;
public int? ClientID { get; set; }
public string SenderName { get; private set; } = string.Empty;
public DateTime DateDelivery { get; set; }
public string Subject { get; private set; } = string.Empty;
public string Body { get; private set; } = string.Empty;
public static MessageInfo? Create(MessageInfoBindingModel? model) {
if (model == null) {
return null;
}
return new MessageInfo() {
MessageID = model.MessageID,
ClientID = model.ClientID,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
Subject = model.Subject,
Body = model.Body
};
}
public MessageInfoViewModel GetViewModel => new() {
MessageID = MessageID,
ClientID = ClientID,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body
};
}
}

View File

@ -13,16 +13,18 @@ namespace DinerRestApi.Controllers {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IClientLogic _logic; private readonly IClientLogic _logic;
private readonly IMessageInfoLogic _messageLogic;
public ClientController(ILogger<ClientController> logger, IClientLogic logic) { public ClientController(ILogger<ClientController> logger, IClientLogic logic, IMessageInfoLogic messageLogic) {
_logger = logger; _logger = logger;
_logic = logic; _logic = logic;
_messageLogic = messageLogic;
} }
[HttpGet] [HttpGet]
public ClientViewModel? Login(string login, string password) { public ClientViewModel? Login(string login, string password) {
try { try {
return _logic.ReadELement(new ClientSearchModel { return _logic.ReadElement(new ClientSearchModel {
Email = login, Email = login,
Password = password Password = password
}); });
@ -54,5 +56,18 @@ namespace DinerRestApi.Controllers {
throw; throw;
} }
} }
[HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientID) {
try {
return _messageLogic.ReadList(new MessageInfoSearchModel {
ClientID = clientID
});
}
catch (Exception ex) {
_logger.LogError(ex, "Ошибка получения писем клиента");
throw;
}
}
} }
} }

View File

@ -1,9 +1,12 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts; using DinerContracts.BusinessLogicsContacts;
using DinerContracts.BusinessLogicsContracts; using DinerContracts.BusinessLogicsContracts;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts; using DinerContracts.StoragesContracts;
using DinerDataBaseImplement.Implements; using DinerDataBaseImplement.Implements;
using DineryBusinessLogic.BusinessLogic; using DineryBusinessLogic.BusinessLogic;
using DineryBusinessLogic.MailWorker;
using DocumentFormat.OpenXml.VariantTypes; using DocumentFormat.OpenXml.VariantTypes;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
@ -19,11 +22,15 @@ namespace DinerRestAPI {
builder.Services.AddTransient<ISnackStorage, SnackStorage>(); builder.Services.AddTransient<ISnackStorage, SnackStorage>();
builder.Services.AddTransient<IClientStorage, ClientStorage>(); builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>(); builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>(); builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<ISnackLogic, SnackLogic>(); builder.Services.AddTransient<ISnackLogic, SnackLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>(); builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
// Add services to the container. // Add services to the container.
@ -34,8 +41,18 @@ namespace DinerRestAPI {
var app = builder.Build(); var app = builder.Build();
var mailSender = app.Services.GetService<AbstractMailWorker>();
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. // Configure the HTTP request pipeline.
if(app.Environment.IsDevelopment()) { if (app.Environment.IsDevelopment()) {
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "DinerRestApi v1")); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "DinerRestApi v1"));
} }

View File

@ -5,5 +5,12 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"SmtpClientHost": "smtp.gmail.com",
"SmtpClientPort": "587",
"PopHost": "pop.gmail.com",
"PopPort": "995",
"MailLogin": "fedotovilyabylabwork@gmail.com",
"MailPassword": "gyve lvpe gcna pscp"
} }

View File

@ -22,11 +22,14 @@ namespace DinerFileImplement
private readonly string ImplementerFileName = "Implementer.xml"; private readonly string ImplementerFileName = "Implementer.xml";
private readonly string MessageInfoFileName = "MessageInfo.xml";
public List<Food> Foods { get; set; } public List<Food> Foods { get; set; }
public List<Order> Orders { get; private set; } public List<Order> Orders { get; private set; }
public List<Snack> Snacks { get; private set; } public List<Snack> Snacks { get; private set; }
public List<Client> Clients { get; private set; } public List<Client> Clients { get; private set; }
public List<Implementer> Implementers { get; private set; } public List<Implementer> Implementers { get; private set; }
public List<MessageInfo> MessageInfos { get; private set; }
private DataFileSingleton() { private DataFileSingleton() {
Foods = LoadData(FoodFileName, "Food", x => Food.Create(x)!)!; Foods = LoadData(FoodFileName, "Food", x => Food.Create(x)!)!;
@ -34,6 +37,7 @@ namespace DinerFileImplement
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!; Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!; Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
MessageInfos = LoadData(MessageInfoFileName, "MessageInfo", x => MessageInfo.Create(x)!)!;
} }
public static DataFileSingleton GetInstance() { public static DataFileSingleton GetInstance() {
if (instance == null) instance = new DataFileSingleton(); if (instance == null) instance = new DataFileSingleton();
@ -49,6 +53,8 @@ namespace DinerFileImplement
x => x.GetXElement); x => x.GetXElement);
public void SaveImplementer() => SaveData(Implementers, ImplementerFileName, "Implementers", public void SaveImplementer() => SaveData(Implementers, ImplementerFileName, "Implementers",
x => x.GetXElement); x => x.GetXElement);
public void SaveMessageInfo() => SaveData(MessageInfos, MessageInfoFileName, "MessageInfo",
x => x.GetXElement);
private static void SaveData<T>(List<T> data, string filename, string xmlNodeName, private static void SaveData<T>(List<T> data, string filename, string xmlNodeName,
Func<T, XElement> selectFunction) Func<T, XElement> selectFunction)

View File

@ -0,0 +1,50 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using DinerFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerFileImplement.Implements {
public class MessageInfoStorage : IMessageInfoStorage {
private readonly DataFileSingleton _source;
private MessageInfoStorage() {
_source = DataFileSingleton.GetInstance();
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model) {
var newMessageInfo = MessageInfo.Create(model);
if (newMessageInfo == null) {
return null;
}
_source.MessageInfos.Add(newMessageInfo);
_source.SaveMessageInfo();
return newMessageInfo.GetViewModel;
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model) {
if (string.IsNullOrEmpty(model.MessageID)) {
return null;
}
return _source.MessageInfos.FirstOrDefault(x => (!string.IsNullOrEmpty(model.MessageID) &&
x.MessageID == model.MessageID))?.GetViewModel;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model) {
if (string.IsNullOrEmpty(model.MessageID)) {
return new();
}
return _source.MessageInfos.Where(x => x.MessageID.Contains(model.MessageID)).Select(x => x.GetViewModel).ToList();
}
public List<MessageInfoViewModel> GetFullList() {
return _source.MessageInfos.Select(x => x.GetViewModel).ToList();
}
}
}

View File

@ -0,0 +1,69 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DinerFileImplement.Models {
public class MessageInfo : IMessageInfoModel {
public string MessageID { get; set; } = string.Empty;
public int? ClientID { get; set; }
public string SenderName { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public static MessageInfo? Create(MessageInfoBindingModel? model) {
if (model == null) {
return null;
}
return new MessageInfo() {
MessageID = model.MessageID,
ClientID = model.ClientID,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
Subject = model.Subject,
Body = model.Body,
};
}
public static MessageInfo? Create(XElement element) {
if (element == null) {
return null;
}
return new MessageInfo() {
MessageID = element.Element("MessageID")!.Value,
ClientID = Convert.ToInt32(element.Element("ClientID")!.Value),
SenderName = element.Element("SenderName")!.Value,
DateDelivery = Convert.ToDateTime(element.Element("DateImplement")!.Value),
Subject = element.Element("Subject")!.Value,
Body = element.Element("Body")!.Value
};
}
public MessageInfoViewModel GetViewModel => new() {
MessageID = MessageID,
ClientID = ClientID,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body,
};
public XElement GetXElement => new("MessageInfo", new XAttribute("MessageID", MessageID),
new XElement("ClientID", ClientID.ToString()),
new XElement("SenderName", SenderName),
new XElement("DateDelivery", DateDelivery.ToString()),
new XElement("Subject", Subject),
new XElement("Body", Body));
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SmtpClientHost" value="smtp.gmail.com" />
<add key="SmtpClientPort" value="587" />
<add key="PopHost" value="pop.gmail.com" />
<add key="PopPort" value="995" />
<add key="MailLogin" value="fedotovilyabylabwork@gmail.com" />
<add key="MailPassword" value="gyve lvpe gcna pscp" />
</appSettings>
</configuration>

View File

@ -54,4 +54,10 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Update="App.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project> </Project>

57
Diner/DinerView/FormMail.Designer.cs generated Normal file
View File

@ -0,0 +1,57 @@
namespace DinerView {
partial class FormMail {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.BorderStyle = BorderStyle.None;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.Size = new Size(800, 450);
dataGridView.TabIndex = 0;
//
// FormMail
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridView);
Name = "FormMail";
Text = "FormMail";
Review

Заголовок формы оформлен неверно

Заголовок формы оформлен неверно
Load += FormMail_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,42 @@
using DinerContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DinerView {
public partial class FormMail : Form {
private readonly ILogger _logger;
private readonly IMessageInfoLogic _logic;
public FormMail(ILogger<FormMail> logger, IMessageInfoLogic logic) {
InitializeComponent();
_logic = logic;
_logger = logger;
}
private void FormMail_Load(object sender, EventArgs e) {
try {
var list = _logic.ReadList(null);
if (list != null) {
dataGridView.DataSource = list;
dataGridView.Columns["ClientID"].Visible = false;
dataGridView.Columns["MessageID"].Visible = false;
dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка списка писем");
}
catch (Exception ex) {
_logger.LogError(ex, "Ошибка загрузки писем");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -42,6 +42,7 @@
buttonCreateOrder = new Button(); buttonCreateOrder = new Button();
buttonIsDelivery = new Button(); buttonIsDelivery = new Button();
buttonUpdateList = new Button(); buttonUpdateList = new Button();
toolStripMenuItemMail = new ToolStripMenuItem();
menuStrip.SuspendLayout(); menuStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout(); SuspendLayout();
@ -49,7 +50,7 @@
// menuStrip // menuStrip
// //
menuStrip.BackColor = SystemColors.Control; menuStrip.BackColor = SystemColors.Control;
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItemMenu, toolStripMenuItemReport, toolStripMenuItemStartOfWork }); menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItemMenu, toolStripMenuItemReport, toolStripMenuItemStartOfWork, toolStripMenuItemMail });
menuStrip.Location = new Point(0, 0); menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip"; menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1114, 24); menuStrip.Size = new Size(1114, 24);
@ -173,6 +174,13 @@
buttonUpdateList.UseVisualStyleBackColor = true; buttonUpdateList.UseVisualStyleBackColor = true;
buttonUpdateList.Click += buttonUpdateList_Click; buttonUpdateList.Click += buttonUpdateList_Click;
// //
// toolStripMenuItemMail
//
toolStripMenuItemMail.Name = "toolStripMenuItemMail";
toolStripMenuItemMail.Size = new Size(53, 20);
toolStripMenuItemMail.Text = "Почта";
toolStripMenuItemMail.Click += toolStripMenuItemMail_Click;
//
// FormMain // FormMain
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
@ -212,5 +220,6 @@
private ToolStripMenuItem toolStripMenuItemClient; private ToolStripMenuItem toolStripMenuItemClient;
private ToolStripMenuItem toolStripMenuItemStartOfWork; private ToolStripMenuItem toolStripMenuItemStartOfWork;
private ToolStripMenuItem toolStripMenuItemImplementer; private ToolStripMenuItem toolStripMenuItemImplementer;
private ToolStripMenuItem toolStripMenuItemMail;
} }
} }

View File

@ -178,5 +178,12 @@ namespace DinerView
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBox.Show("Процесс обработки запущен", "Сообщение",
MessageBoxButtons.OK, MessageBoxIcon.Information); MessageBoxButtons.OK, MessageBoxIcon.Information);
} }
private void toolStripMenuItemMail_Click(object sender, EventArgs e) {
var service = Program.ServiceProvider?.GetService(typeof(FormMail));
if (service is FormMail form) {
form.ShowDialog();
}
}
} }
} }

View File

@ -1,8 +1,11 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts; using DinerContracts.BusinessLogicsContacts;
using DinerContracts.BusinessLogicsContracts; using DinerContracts.BusinessLogicsContracts;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts; using DinerContracts.StoragesContracts;
using DinerDataBaseImplement.Implements; using DinerDataBaseImplement.Implements;
using DineryBusinessLogic.BusinessLogic; using DineryBusinessLogic.BusinessLogic;
using DineryBusinessLogic.MailWorker;
using DineryBusinessLogic.OfficePackage; using DineryBusinessLogic.OfficePackage;
using DineryBusinessLogic.OfficePackage.Implements; using DineryBusinessLogic.OfficePackage.Implements;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -27,6 +30,26 @@ namespace DinerView
var services = new ServiceCollection(); var services = new ServiceCollection();
ConfigureServices(services); ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider(); _serviceProvider = services.BuildServiceProvider();
try {
var mailSender = _serviceProvider.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel {
MailLogin = System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty,
MailPassword = System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty,
SmtpClientHost = System.Configuration.ConfigurationManager.AppSettings["SmtpClientHost"] ?? string.Empty,
SmtpClientPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SmtpClientPort"]),
PopHost = System.Configuration.ConfigurationManager.AppSettings["PopHost"] ?? string.Empty,
PopPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PopPort"])
});
// ñîçäàåì òàéìåð
var timer = new System.Threading.Timer(new TimerCallback(MailCheck!), null, 0, 100000);
}
catch (Exception ex) {
var logger = _serviceProvider.GetService<ILogger>();
logger?.LogError(ex, "Îøèþêà ðàáîòû ñ ïî÷òîé");
}
Application.Run(_serviceProvider.GetRequiredService<FormMain>()); Application.Run(_serviceProvider.GetRequiredService<FormMain>());
} }
@ -42,6 +65,7 @@ namespace DinerView
services.AddTransient<IImplementerStorage, ImplementerStorage>(); services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<ISnackStorage, SnackStorage>(); services.AddTransient<ISnackStorage, SnackStorage>();
services.AddTransient<IClientStorage, ClientStorage>(); services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
services.AddTransient<IClientLogic, ClientLogic>(); services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IFoodLogic, FoodLogic>(); services.AddTransient<IFoodLogic, FoodLogic>();
@ -50,6 +74,9 @@ namespace DinerView
services.AddTransient<ISnackLogic, SnackLogic>(); services.AddTransient<ISnackLogic, SnackLogic>();
services.AddTransient<IReportLogic, ReportLogic>(); services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IWorkProcess, WorkModelling>(); services.AddTransient<IWorkProcess, WorkModelling>();
services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
services.AddSingleton<AbstractMailWorker, MailKitWorker>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>(); services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>(); services.AddTransient<AbstractSaveToWord, SaveToWord>();
@ -67,6 +94,10 @@ namespace DinerView
services.AddTransient<FormClient>(); services.AddTransient<FormClient>();
services.AddTransient<FormImplementers>(); services.AddTransient<FormImplementers>();
services.AddTransient<FormImplementer>(); services.AddTransient<FormImplementer>();
services.AddTransient<FormMail>();
} }
private static void MailCheck(object obj) => ServiceProvider?.GetService<AbstractMailWorker>()?.MailCheck();
} }
} }

View File

@ -51,7 +51,7 @@ namespace DineryBusinessLogic.BusinessLogic {
return true; return true;
} }
public ClientViewModel? ReadELement(ClientSearchModel model) { public ClientViewModel? ReadElement(ClientSearchModel model) {
if (model == null) { if (model == null) {
throw new ArgumentNullException(nameof(model)); throw new ArgumentNullException(nameof(model));
} }

View File

@ -3,6 +3,7 @@ using DinerContracts.BusinessLogicsContracts;
using DinerContracts.SearchModels; using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts; using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels; using DinerContracts.ViewModels;
using DocumentFormat.OpenXml.Office2016.Drawing.Command;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -87,16 +88,16 @@ namespace DineryBusinessLogic.BusinessLogic {
throw new ArgumentNullException("Нет ФИО исполнителя", nameof(model.ImplementerFIO)); throw new ArgumentNullException("Нет ФИО исполнителя", nameof(model.ImplementerFIO));
} }
if (string.IsNullOrEmpty(model.Password)) { if (string.IsNullOrEmpty(model.Password)) {
throw new ArgumentNullException("Нет пароля"); throw new ArgumentNullException("Нет пароля", nameof(model.Password));
} }
if (string.IsNullOrEmpty((model.WorkExperience).ToString())) { if (string.IsNullOrEmpty((model.WorkExperience).ToString())) {
throw new ArgumentNullException("Не указан стаж"); throw new ArgumentNullException("Не указан стаж", nameof(model.WorkExperience));
} }
if (string.IsNullOrEmpty((model.Qualification).ToString())) { if (string.IsNullOrEmpty((model.Qualification).ToString())) {
throw new ArgumentNullException("Нет квалификации"); throw new ArgumentNullException("Нет квалификации", nameof(model.Qualification));
} }
if (string.IsNullOrEmpty((model.ID).ToString())) { if (string.IsNullOrEmpty((model.ID).ToString())) {
throw new ArgumentNullException("Нет ID пользователя", nameof(model.ID)); throw new ArgumentNullException("Нет ID исполнителя", nameof(model.ID));
} }
_logger.LogInformation($"Implementer. ID:{model.ID}.ImplementerFIO:{model.ImplementerFIO}.WorkExperience:{model.WorkExperience}." + _logger.LogInformation($"Implementer. ID:{model.ID}.ImplementerFIO:{model.ImplementerFIO}.WorkExperience:{model.WorkExperience}." +
$"Qualification:{model.Qualification}"); $"Qualification:{model.Qualification}");

View File

@ -0,0 +1,66 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using DocumentFormat.OpenXml.Packaging;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Threading.Tasks;
namespace DineryBusinessLogic.BusinessLogic {
public class MessageInfoLogic : IMessageInfoLogic {
private readonly ILogger _logger;
private readonly IMessageInfoStorage _storage;
public MessageInfoLogic(ILogger<MessageInfoLogic> logger, IMessageInfoStorage storage) {
_logger = logger;
_storage = storage;
}
public bool Create(MessageInfoBindingModel model) {
CheckModel(model);
if (_storage.Insert(model) == null) {
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model) {
_logger.LogInformation($"ReadList. MessageID:{model?.MessageID}");
var list = model == null ? _storage.GetFullList() : _storage.GetFilteredList(model);
if (list == null) {
_logger.LogWarning("ReadList. return null list");
return null;
}
_logger.LogInformation($"ReadList. Count:{list.Count}");
return list;
}
private void CheckModel(MessageInfoBindingModel model, bool withParams = true) {
if (model == null) {
throw new ArgumentNullException(nameof(model));
}
if (!withParams) {
return;
}
if (string.IsNullOrEmpty(model.MessageID)) {
throw new ArgumentNullException("Нет ID письма", nameof(model.MessageID));
}
if (string.IsNullOrEmpty((model.ClientID).ToString())) {
throw new ArgumentNullException("Нет ID клиента", nameof(model.ClientID));
}
if (string.IsNullOrEmpty((model.DateDelivery).ToString())) {
throw new ArgumentNullException("Нет даты письма", nameof(model.DateDelivery));
}
_logger.LogInformation($"MessageInfo. MessageID:{model.MessageID}.ClientID:{model.ClientID}.DataDelivery:{model.DateDelivery}." +
$"Subject:{model.Subject}.Body:{model.Body}");
}
}
}

View File

@ -1,9 +1,11 @@
using DinerContracts.BindingModels; using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts; using DinerContracts.BusinessLogicsContacts;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.SearchModels; using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts; using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels; using DinerContracts.ViewModels;
using DinerDataModels.Enums; using DinerDataModels.Enums;
using DineryBusinessLogic.MailWorker;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -17,21 +19,28 @@ namespace DineryBusinessLogic.BusinessLogic
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage; private readonly IOrderStorage _orderStorage;
private readonly AbstractMailWorker _mailWorker;
private readonly IClientLogic _clientLogic;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage) { public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker, IClientLogic clientLogic) {
_logger = logger; _logger = logger;
_orderStorage = orderStorage; _orderStorage = orderStorage;
_mailWorker = mailWorker;
_clientLogic = clientLogic;
} }
public bool CreateOrder(OrderBindingModel model) public bool CreateOrder(OrderBindingModel model)
{ {
CheckModel(model); CheckModel(model);
model.Status = OrderStatus.Принят; model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null) { var result = _orderStorage.Insert(model);
if (result == null) {
model.Status = OrderStatus.Неизвестен; model.Status = OrderStatus.Неизвестен;
_logger.LogWarning("Insert operation failed"); _logger.LogWarning("Insert operation failed");
return false; return false;
} }
SendOrderStatusMail(result.ClientID, $"Новый заказ создан. Номер заказа #{result.ID}", $"Заказ #{result.ID} от " +
$"{result.DateCreate} на сумму {result.Sum:0.00} принят");
return true; return true;
} }
@ -118,11 +127,24 @@ namespace DineryBusinessLogic.BusinessLogic
} }
CheckModel(model, false); CheckModel(model, false);
var result = _orderStorage.Update(model);
if (_orderStorage.Update(model) == null) { if (result == null) {
_logger.LogWarning("Update operarion failed"); _logger.LogWarning("Update operarion failed");
return false; return false;
} }
SendOrderStatusMail(result.ClientID, $"Изменен статус заказа #{result.ID}", $"Заказ #{model.ID} изменен статус на {result.Status}");
return true;
}
private bool SendOrderStatusMail(int clientId, string subject, string text) {
var client = _clientLogic.ReadElement(new() { ID = clientId });
if (client == null) {
return false;
}
_mailWorker.MailSendAsync(new() {
MailAddress = client.Email,
Subject = subject,
Text = text
});
return true; return true;
} }
} }

View File

@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" /> <PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" />
<PackageReference Include="MailKit" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" /> <PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup> </ItemGroup>

View File

@ -0,0 +1,77 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DineryBusinessLogic.BusinessLogic;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading.Tasks;
namespace DineryBusinessLogic.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 IMessageInfoLogic _messageInfoLogic;
private readonly IClientLogic _clientLogic;
private readonly ILogger _logger;
public AbstractMailWorker(ILogger<AbstractMailWorker> logger, IMessageInfoLogic messageInfoLogic, IClientLogic clientLogic) {
_logger = logger;
_messageInfoLogic = messageInfoLogic;
_clientLogic = clientLogic;
}
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: {_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: {info.MailAddress}, {info.Subject}");
await SendMailAsync(info);
}
public async void MailCheck() {
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword)) {
return;
}
if (string.IsNullOrEmpty(_popHost) || _popPort == 0) {
return;
}
if (_messageInfoLogic == null) {
return;
}
var list = await ReceiveMailAsync();
_logger.LogDebug($"Check Mail: {list.Count} new mails");
foreach (var mail in list) {
mail.ClientID= _clientLogic.ReadElement(new() { Email = mail.SenderName })?.ID;
_messageInfoLogic.Create(mail);
}
}
protected abstract Task SendMailAsync(MailSendInfoBindingModel info);
protected abstract Task<List<MessageInfoBindingModel>> ReceiveMailAsync();
}
}

View File

@ -0,0 +1,73 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DocumentFormat.OpenXml.Wordprocessing;
using MailKit.Net.Pop3;
using MailKit.Security;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Runtime.Intrinsics.X86;
using System.Text;
using System.Threading.Tasks;
namespace DineryBusinessLogic.MailWorker {
public class MailKitWorker : AbstractMailWorker {
public MailKitWorker(ILogger<MailKitWorker> logger, IMessageInfoLogic messageInfoLogic, IClientLogic clientLogic) : base(logger, messageInfoLogic, clientLogic) { }
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;
}
}
protected override async Task<List<MessageInfoBindingModel>> ReceiveMailAsync() {
var list = new List<MessageInfoBindingModel>();
using var client = new Pop3Client();
await Task.Run(() => {
try {
client.Connect(_popHost, _popPort, SecureSocketOptions.SslOnConnect);
client.Authenticate(_mailLogin, _mailPassword);
for (int i = 0; i < client.Count; i++) {
var message = client.GetMessage(i);
foreach (var mail in message.From.Mailboxes) {
list.Add(new MessageInfoBindingModel {
DateDelivery = message.Date.DateTime,
MessageID = message.MessageId,
SenderName = mail.Address,
Subject = message.Subject,
Body = message.TextBody
});
}
}
}
catch (AuthenticationException) { }
finally {
client.Disconnect(true);
}
});
return list;
}
}
}