PIbd-23. Konovalov A.V. Lab work 07 #8

Closed
K.Senya wants to merge 1 commits from Lab_7 into Lab_6
49 changed files with 1961 additions and 652 deletions
Showing only changes of commit f2dcfe8eca - Show all commits

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="lawfirmlab7@gmail.com" />
<add key="MailPassword" value="logf arhv rtkk rqfe" />
</appSettings>
</configuration>

View File

@ -1,212 +1,222 @@
namespace TypographyView
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
partial class FormMain
{
/// <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);
}
/// <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
#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()
{
dataGridViewOrders = new DataGridView();
menuStrip = new MenuStrip();
directoriesToolStripMenuItem = new ToolStripMenuItem();
componentsToolStripMenuItem = new ToolStripMenuItem();
printedsToolStripMenuItem = new ToolStripMenuItem();
clientsToolStripMenuItem = new ToolStripMenuItem();
implementersToolStripMenuItem = new ToolStripMenuItem();
ReportsToolStripMenuItem = new ToolStripMenuItem();
PrintedListToolStripMenuItem = new ToolStripMenuItem();
PrintedComponentsToolStripMenuItem = new ToolStripMenuItem();
ListOfOrdersToolStripMenuItem = new ToolStripMenuItem();
workLaunchToolStripMenuItem = new ToolStripMenuItem();
buttonCreateOrder = new Button();
buttonIssuedOrder = new Button();
buttonRef = new Button();
((System.ComponentModel.ISupportInitialize)dataGridViewOrders).BeginInit();
menuStrip.SuspendLayout();
SuspendLayout();
//
// dataGridViewOrders
//
dataGridViewOrders.BackgroundColor = Color.White;
dataGridViewOrders.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewOrders.Location = new Point(0, 31);
dataGridViewOrders.Name = "dataGridViewOrders";
dataGridViewOrders.RowHeadersVisible = false;
dataGridViewOrders.RowHeadersWidth = 51;
dataGridViewOrders.RowTemplate.Height = 29;
dataGridViewOrders.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewOrders.Size = new Size(1080, 424);
dataGridViewOrders.TabIndex = 3;
//
// menuStrip
//
menuStrip.ImageScalingSize = new Size(20, 20);
menuStrip.Items.AddRange(new ToolStripItem[] { directoriesToolStripMenuItem, ReportsToolStripMenuItem, workLaunchToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1331, 28);
menuStrip.TabIndex = 6;
menuStrip.Text = "menuStrip";
//
// directoriesToolStripMenuItem
//
directoriesToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { componentsToolStripMenuItem, printedsToolStripMenuItem, clientsToolStripMenuItem, implementersToolStripMenuItem });
directoriesToolStripMenuItem.Name = "directoriesToolStripMenuItem";
directoriesToolStripMenuItem.Size = new Size(117, 24);
directoriesToolStripMenuItem.Text = "Справочники";
//
// componentsToolStripMenuItem
//
componentsToolStripMenuItem.Name = "componentsToolStripMenuItem";
componentsToolStripMenuItem.Size = new Size(237, 26);
componentsToolStripMenuItem.Text = "Компоненты";
componentsToolStripMenuItem.Click += componentsToolStripMenuItem_Click;
//
// printedsToolStripMenuItem
//
printedsToolStripMenuItem.Name = "printedsToolStripMenuItem";
printedsToolStripMenuItem.Size = new Size(237, 26);
printedsToolStripMenuItem.Text = "Печатная продукция";
printedsToolStripMenuItem.Click += printedsToolStripMenuItem_Click;
//
// clientsToolStripMenuItem
//
clientsToolStripMenuItem.Name = "clientsToolStripMenuItem";
clientsToolStripMenuItem.Size = new Size(237, 26);
clientsToolStripMenuItem.Text = "Клиенты";
clientsToolStripMenuItem.Click += clientsToolStripMenuItem_Click;
//
// implementersToolStripMenuItem
//
implementersToolStripMenuItem.Name = "implementersToolStripMenuItem";
implementersToolStripMenuItem.Size = new Size(237, 26);
implementersToolStripMenuItem.Text = "Исполнители";
implementersToolStripMenuItem.Click += implementersToolStripMenuItem_Click;
//
// ReportsToolStripMenuItem
//
ReportsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { PrintedListToolStripMenuItem, PrintedComponentsToolStripMenuItem, ListOfOrdersToolStripMenuItem });
ReportsToolStripMenuItem.Name = "ReportsToolStripMenuItem";
ReportsToolStripMenuItem.Size = new Size(73, 24);
ReportsToolStripMenuItem.Text = "Отчеты";
//
// PrintedListToolStripMenuItem
//
PrintedListToolStripMenuItem.Name = "PrintedListToolStripMenuItem";
PrintedListToolStripMenuItem.Size = new Size(332, 26);
PrintedListToolStripMenuItem.Text = "Список печатной продукции";
PrintedListToolStripMenuItem.Click += PrintedListToolStripMenuItem_Click;
//
// PrintedComponentsToolStripMenuItem
//
PrintedComponentsToolStripMenuItem.Name = "PrintedComponentsToolStripMenuItem";
PrintedComponentsToolStripMenuItem.Size = new Size(332, 26);
PrintedComponentsToolStripMenuItem.Text = "Компоненты печатной продукции";
PrintedComponentsToolStripMenuItem.Click += PrintedComponentsToolStripMenuItem_Click;
//
// ListOfOrdersToolStripMenuItem
//
ListOfOrdersToolStripMenuItem.Name = "ListOfOrdersToolStripMenuItem";
ListOfOrdersToolStripMenuItem.Size = new Size(332, 26);
ListOfOrdersToolStripMenuItem.Text = "Список заказов";
ListOfOrdersToolStripMenuItem.Click += ListOfOrdersToolStripMenuItem_Click;
//
// workLaunchToolStripMenuItem
//
workLaunchToolStripMenuItem.Name = "workLaunchToolStripMenuItem";
workLaunchToolStripMenuItem.Size = new Size(114, 24);
workLaunchToolStripMenuItem.Text = "Запуск работ";
workLaunchToolStripMenuItem.Click += workLaunchToolStripMenuItem_Click;
//
// buttonCreateOrder
//
buttonCreateOrder.Location = new Point(1109, 42);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(195, 29);
buttonCreateOrder.TabIndex = 5;
buttonCreateOrder.Text = "Создать заказ";
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += buttonCreateOrder_Click;
//
// buttonIssuedOrder
//
buttonIssuedOrder.Location = new Point(1109, 108);
buttonIssuedOrder.Name = "buttonIssuedOrder";
buttonIssuedOrder.Size = new Size(195, 29);
buttonIssuedOrder.TabIndex = 8;
buttonIssuedOrder.Text = "Заказ выдан";
buttonIssuedOrder.UseVisualStyleBackColor = true;
buttonIssuedOrder.Click += buttonIssuedOrder_Click;
//
// buttonRef
//
buttonRef.Location = new Point(1109, 174);
buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(195, 29);
buttonRef.TabIndex = 9;
buttonRef.Text = "Обновить список";
buttonRef.UseVisualStyleBackColor = true;
buttonRef.Click += buttonRef_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1331, 453);
Controls.Add(buttonRef);
Controls.Add(buttonIssuedOrder);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridViewOrders);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormMain";
Text = "Типография";
Load += FormMain_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewOrders).EndInit();
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
buttonCreateOrder = new Button();
buttonIssuedOrder = new Button();
dataGridViewOrders = new DataGridView();
buttonRef = new Button();
menuStrip = new MenuStrip();
directoriesToolStripMenuItem = new ToolStripMenuItem();
componentsToolStripMenuItem = new ToolStripMenuItem();
printedsToolStripMenuItem = new ToolStripMenuItem();
clientsToolStripMenuItem = new ToolStripMenuItem();
implementersToolStripMenuItem = new ToolStripMenuItem();
reportsToolStripMenuItem = new ToolStripMenuItem();
printedsListToolStripMenuItem = new ToolStripMenuItem();
componentPrintedsToolStripMenuItem = new ToolStripMenuItem();
ordersListToolStripMenuItem = new ToolStripMenuItem();
workLaunchToolStripMenuItem = new ToolStripMenuItem();
messagesToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)dataGridViewOrders).BeginInit();
menuStrip.SuspendLayout();
SuspendLayout();
//
// buttonCreateOrder
//
buttonCreateOrder.Location = new Point(1267, 31);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(203, 29);
buttonCreateOrder.TabIndex = 0;
buttonCreateOrder.Text = "Создать заказ";
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += ButtonCreateOrder_Click;
//
// buttonIssuedOrder
//
buttonIssuedOrder.Location = new Point(1267, 66);
buttonIssuedOrder.Name = "buttonIssuedOrder";
buttonIssuedOrder.Size = new Size(203, 29);
buttonIssuedOrder.TabIndex = 2;
buttonIssuedOrder.Text = "Заказ выдан";
buttonIssuedOrder.UseVisualStyleBackColor = true;
buttonIssuedOrder.Click += ButtonIssuedOrder_Click;
//
// dataGridViewOrders
//
dataGridViewOrders.BackgroundColor = SystemColors.ControlLightLight;
dataGridViewOrders.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewOrders.Location = new Point(0, 31);
dataGridViewOrders.Name = "dataGridViewOrders";
dataGridViewOrders.RowHeadersVisible = false;
dataGridViewOrders.RowHeadersWidth = 51;
dataGridViewOrders.RowTemplate.Height = 29;
dataGridViewOrders.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewOrders.Size = new Size(1252, 402);
dataGridViewOrders.TabIndex = 3;
//
// buttonRef
//
buttonRef.Location = new Point(1267, 101);
buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(203, 29);
buttonRef.TabIndex = 4;
buttonRef.Text = "Обновить список";
buttonRef.UseVisualStyleBackColor = true;
buttonRef.Click += ButtonRef_Click;
//
// menuStrip
//
menuStrip.ImageScalingSize = new Size(20, 20);
menuStrip.Items.AddRange(new ToolStripItem[] { directoriesToolStripMenuItem, reportsToolStripMenuItem, workLaunchToolStripMenuItem, messagesToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1482, 28);
menuStrip.TabIndex = 6;
menuStrip.Text = "menuStrip1";
//
// directoriesToolStripMenuItem
//
directoriesToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { componentsToolStripMenuItem, printedsToolStripMenuItem, clientsToolStripMenuItem, implementersToolStripMenuItem });
directoriesToolStripMenuItem.Name = "directoriesToolStripMenuItem";
directoriesToolStripMenuItem.Size = new Size(117, 24);
directoriesToolStripMenuItem.Text = "Справочники";
//
// componentsToolStripMenuItem
//
componentsToolStripMenuItem.Name = "componentsToolStripMenuItem";
componentsToolStripMenuItem.Size = new Size(237, 26);
componentsToolStripMenuItem.Text = "Компоненты";
componentsToolStripMenuItem.Click += ComponentsToolStripMenuItem_Click;
//
// printedsToolStripMenuItem
//
printedsToolStripMenuItem.Name = "printedsToolStripMenuItem";
printedsToolStripMenuItem.Size = new Size(237, 26);
printedsToolStripMenuItem.Text = "Печатная продукция";
printedsToolStripMenuItem.Click += PrintedsToolStripMenuItem_Click;
//
// clientsToolStripMenuItem
//
clientsToolStripMenuItem.Name = "clientsToolStripMenuItem";
clientsToolStripMenuItem.Size = new Size(237, 26);
clientsToolStripMenuItem.Text = "Клиенты";
clientsToolStripMenuItem.Click += ClientsToolStripMenuItem_Click;
//
// implementersToolStripMenuItem
//
implementersToolStripMenuItem.Name = "implementersToolStripMenuItem";
implementersToolStripMenuItem.Size = new Size(237, 26);
implementersToolStripMenuItem.Text = "Исполнители";
implementersToolStripMenuItem.Click += ImplementersToolStripMenuItem_Click;
//
// reportsToolStripMenuItem
//
reportsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { printedsListToolStripMenuItem, componentPrintedsToolStripMenuItem, ordersListToolStripMenuItem });
reportsToolStripMenuItem.Name = "reportsToolStripMenuItem";
reportsToolStripMenuItem.Size = new Size(73, 24);
reportsToolStripMenuItem.Text = "Отчеты";
//
// printedsListToolStripMenuItem
//
printedsListToolStripMenuItem.Name = "printedsListToolStripMenuItem";
printedsListToolStripMenuItem.Size = new Size(332, 26);
printedsListToolStripMenuItem.Text = "Список печатной продукции";
printedsListToolStripMenuItem.Click += PrintedsListToolStripMenuItem_Click;
//
// componentPrintedsToolStripMenuItem
//
componentPrintedsToolStripMenuItem.Name = "componentPrintedsToolStripMenuItem";
componentPrintedsToolStripMenuItem.Size = new Size(332, 26);
componentPrintedsToolStripMenuItem.Text = "Компоненты печатной продукции";
componentPrintedsToolStripMenuItem.Click += ComponentPrintedsToolStripMenuItem_Click;
//
// ordersListToolStripMenuItem
//
ordersListToolStripMenuItem.Name = "ordersListToolStripMenuItem";
ordersListToolStripMenuItem.Size = new Size(332, 26);
ordersListToolStripMenuItem.Text = "Список заказов";
ordersListToolStripMenuItem.Click += OrdersListToolStripMenuItem_Click;
//
// workLaunchToolStripMenuItem
//
workLaunchToolStripMenuItem.Name = "workLaunchToolStripMenuItem";
workLaunchToolStripMenuItem.Size = new Size(114, 24);
workLaunchToolStripMenuItem.Text = "Запуск работ";
workLaunchToolStripMenuItem.Click += WorkLaunchToolStripMenuItem_Click;
//
// messagesToolStripMenuItem
//
messagesToolStripMenuItem.Name = "messagesToolStripMenuItem";
messagesToolStripMenuItem.Size = new Size(77, 24);
messagesToolStripMenuItem.Text = "Письма";
messagesToolStripMenuItem.Click += MessagesToolStripMenuItem_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1482, 433);
Controls.Add(buttonRef);
Controls.Add(dataGridViewOrders);
Controls.Add(buttonIssuedOrder);
Controls.Add(buttonCreateOrder);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormMain";
StartPosition = FormStartPosition.CenterScreen;
Text = "Типография";
Load += FormMain_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewOrders).EndInit();
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
#endregion
private DataGridView dataGridViewOrders;
private MenuStrip menuStrip;
private ToolStripMenuItem directoriesToolStripMenuItem;
private ToolStripMenuItem componentsToolStripMenuItem;
private ToolStripMenuItem printedsToolStripMenuItem;
private Button buttonCreateOrder;
private Button buttonIssuedOrder;
private Button buttonRef;
private ToolStripMenuItem ReportsToolStripMenuItem;
private ToolStripMenuItem PrintedListToolStripMenuItem;
private ToolStripMenuItem PrintedComponentsToolStripMenuItem;
private ToolStripMenuItem ListOfOrdersToolStripMenuItem;
private ToolStripMenuItem clientsToolStripMenuItem;
private ToolStripMenuItem implementersToolStripMenuItem;
private ToolStripMenuItem workLaunchToolStripMenuItem;
}
private Button buttonCreateOrder;
private Button buttonIssuedOrder;
private DataGridView dataGridViewOrders;
private Button buttonRef;
private MenuStrip menuStrip;
private ToolStripMenuItem directoriesToolStripMenuItem;
private ToolStripMenuItem componentsToolStripMenuItem;
private ToolStripMenuItem printedsToolStripMenuItem;
private ToolStripMenuItem reportsToolStripMenuItem;
private ToolStripMenuItem printedsListToolStripMenuItem;
private ToolStripMenuItem componentPrintedsToolStripMenuItem;
private ToolStripMenuItem ordersListToolStripMenuItem;
private ToolStripMenuItem clientsToolStripMenuItem;
private ToolStripMenuItem implementersToolStripMenuItem;
private ToolStripMenuItem workLaunchToolStripMenuItem;
private ToolStripMenuItem messagesToolStripMenuItem;
}
}

View File

@ -1,149 +1,170 @@
using TypographyDataModels.Enums;
using TypographyContracts.BindingModels;
using TypographyContracts.BindingModels;
using TypographyContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using Typography;
using TypographyContracts.BindingModels;
using TypographyBusinessLogic.BusinessLogics;
namespace TypographyView
{
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
private readonly IWorkProcess _workProcess;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
_workProcess = workProcess;
}
private void LoadData()
{
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridViewOrders.DataSource = list;
dataGridViewOrders.Columns["ClientId"].Visible = false;
dataGridViewOrders.Columns["ImplementerId"].Visible = false;
dataGridViewOrders.Columns["PrintedId"].Visible = false;
dataGridViewOrders.Columns["PrintedName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void componentsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form)
{
form.ShowDialog();
}
}
private void printedsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormPrinteds));
if (service is FormPrinteds form)
{
form.ShowDialog();
}
}
private void buttonCreateOrder_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
private void buttonIssuedOrder_Click(object sender, EventArgs e)
{
if (dataGridViewOrders.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridViewOrders.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ №{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonRef_Click(object sender, EventArgs e)
{
LoadData();
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void PrintedListToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SavePrintedsToWordFile(new ReportBindingModel { FileName = dialog.FileName });
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void PrintedComponentsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportPrintedComponents));
if (service is FormReportPrintedComponents form)
{
form.ShowDialog();
}
}
private void ListOfOrdersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
}
private void clientsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
private void implementersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if (service is FormImplementers form)
{
form.ShowDialog();
}
}
private void workLaunchToolStripMenuItem_Click(object sender, EventArgs e)
{
_workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
private readonly IWorkProcess _workProcess;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
_workProcess = workProcess;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridViewOrders.DataSource = list;
dataGridViewOrders.Columns["ClientId"].Visible = false;
dataGridViewOrders.Columns["ClientEmail"].Visible = false;
dataGridViewOrders.Columns["ImplementerId"].Visible = false;
dataGridViewOrders.Columns["PrintedId"].Visible = false;
dataGridViewOrders.Columns["PrintedName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ComponentsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form)
{
form.ShowDialog();
}
}
private void PrintedsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormPrinteds));
if (service is FormPrinteds form)
{
form.ShowDialog();
}
}
private void ClientsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
private void ImplementersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if (service is FormImplementers form)
{
form.ShowDialog();
}
}
private void PrintedsListToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SavePrintedsToWordFile(new ReportBindingModel { FileName = dialog.FileName });
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void ComponentPrintedsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportPrintedComponents));
if (service is FormReportPrintedComponents form)
{
form.ShowDialog();
}
}
private void OrdersListToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
}
private void WorkLaunchToolStripMenuItem_Click(object sender, EventArgs e)
{
_workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void MessagesToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormMessages));
if (service is FormMessages form)
{
form.ShowDialog();
}
}
private void ButtonCreateOrder_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
private void ButtonIssuedOrder_Click(object sender, EventArgs e)
{
if (dataGridViewOrders.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridViewOrders.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ №{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

@ -1,64 +1,4 @@
<?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.
-->
<root>
<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">

View File

@ -0,0 +1,65 @@
namespace TypographyView
{
partial class FormMessages
{
/// <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()
{
dataGridViewMessages = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridViewMessages).BeginInit();
SuspendLayout();
//
// dataGridViewMessages
//
dataGridViewMessages.BackgroundColor = SystemColors.ControlLightLight;
dataGridViewMessages.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewMessages.Location = new Point(1, 1);
dataGridViewMessages.Name = "dataGridViewMessages";
dataGridViewMessages.RowHeadersVisible = false;
dataGridViewMessages.RowHeadersWidth = 51;
dataGridViewMessages.RowTemplate.Height = 29;
dataGridViewMessages.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewMessages.Size = new Size(979, 750);
dataGridViewMessages.TabIndex = 0;
//
// FormMessages
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(982, 753);
Controls.Add(dataGridViewMessages);
Name = "FormMessages";
Text = "Входящие письма";
Load += FormMessages_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewMessages).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridViewMessages;
}
}

View File

@ -0,0 +1,45 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
using TypographyContracts.BusinessLogicsContracts;
namespace TypographyView
{
public partial class FormMessages : Form
{
private readonly ILogger _logger;
private readonly IMessageInfoLogic _logic;
public FormMessages(ILogger<FormMessages> logger, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormMessages_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridViewMessages.DataSource = list;
dataGridViewMessages.Columns["MessageId"].Visible = false;
dataGridViewMessages.Columns["ClientId"].Visible = false;
dataGridViewMessages.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,60 @@
<root>
<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

@ -1,4 +1,4 @@
using TypographyBusinessLogic.BusinessLogics;
using TypographyBusinessLogic.BusinessLogics;
using TypographyContracts.BusinessLogicsContracts;
using TypographyContracts.StoragesContracts;
using TypographyDatabaseImplement.Implements;
@ -8,6 +8,8 @@ using NLog.Extensions.Logging;
using TypographyBusinessLogic.OfficePackage.Implements;
using TypographyBusinessLogic.OfficePackage;
using System;
using TypographyBusinessLogic.MailWorker;
using TypographyContracts.BindingModels;
using Typography;
namespace TypographyView
@ -29,7 +31,27 @@ namespace TypographyView
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
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>());
}
private static void ConfigureServices(ServiceCollection services)
{
@ -43,16 +65,19 @@ namespace TypographyView
services.AddTransient<IPrintedStorage, PrintedStorage>();
services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IPrintedLogic, PrintedLogic>();
services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IWorkProcess, WorkModeling>();
services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
services.AddSingleton<AbstractMailWorker, MailKitWorker>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
@ -68,6 +93,8 @@ namespace TypographyView
services.AddTransient<FormClients>();
services.AddTransient<FormImplementer>();
services.AddTransient<FormImplementers>();
}
}
services.AddTransient<FormMessages>();
}
private static void MailCheck(object obj) => ServiceProvider?.GetService<AbstractMailWorker>()?.MailCheck();
}
}

View File

@ -4,6 +4,7 @@ using TypographyContracts.SearchModels;
using TypographyContracts.StoragesContracts;
using TypographyContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace TypographyBusinessLogic.BusinessLogics
{
@ -91,16 +92,27 @@ namespace TypographyBusinessLogic.BusinessLogics
{
throw new ArgumentNullException("Нет ФИО клиента", nameof(model.ClientFIO));
}
if (string.IsNullOrEmpty(model.Email))
{
throw new ArgumentNullException("Нет логина клиента", nameof(model.Email));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля клиента", nameof(model.Password));
}
_logger.LogInformation("Client. Id: {Id}. ClientFIO: {ClientFIO}. Email: {Email}.",
model?.Id, model?.ClientFIO, model?.Email);
if (string.IsNullOrEmpty(model.Email))
{
throw new ArgumentNullException("Нет электронной почты клиента", nameof(model.Email));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля клиента", nameof(model.Password));
}
if (!Regex.IsMatch(model.Email, @"^[-\w.]+@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,4}$"))
{
throw new ArgumentNullException("Введенное не является адресом электронной почты", nameof(model.Email));
}
if (model.Password.Length < 10 || model.Password.Length > 50 ||
!Regex.IsMatch(model.Password, @"^((\w+\d+\W+)|(\w+\W+\d+)|(\d+\w+\W+)|(\d+\W+\w+)|(\W+\w+\d+)|(\W+\d+\w+))[\w\d\W]*$"))
{
throw new ArgumentNullException("Пароль не соответсвует требованиям безопасности", nameof(model.Password));
}
_logger.LogInformation("Client. Id: {Id}. ClientFIO: {ClientFIO}. Email: {Email}.",
model?.Id, model?.ClientFIO, model?.Email);
var element = _clientStorage.GetElement(new ClientSearchModel { Email = model.Email });
if (element != null && element.Id != model.Id)
{

View File

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using TypographyContracts.BindingModels;
using TypographyContracts.BusinessLogicsContracts;
using TypographyContracts.SearchModels;
using TypographyContracts.StoragesContracts;
using TypographyContracts.ViewModels;
namespace TypographyBusinessLogic.BusinessLogics
{
public class MessageInfoLogic : IMessageInfoLogic
{
private readonly ILogger _logger;
private readonly IMessageInfoStorage _messageInfoStorage;
private readonly IClientStorage _clientStorage;
public MessageInfoLogic(ILogger<MessageInfoLogic> logger, IMessageInfoStorage messageInfoStorage, IClientStorage clientStorage)
{
_logger = logger;
_messageInfoStorage = messageInfoStorage;
_clientStorage = clientStorage;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{
_logger.LogInformation("ReadList. Id: {MessageId}. ClientId: {ClientId}.",
model?.MessageId, model?.ClientId);
var list = model == null ? _messageInfoStorage.GetFullList() : _messageInfoStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public bool Create(MessageInfoBindingModel model)
{
CheckModel(model);
if (_messageInfoStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private void CheckModel(MessageInfoBindingModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (string.IsNullOrEmpty(model.MessageId))
{
throw new ArgumentNullException("Нет id письма", nameof(model.MessageId));
}
if (string.IsNullOrEmpty(model.SenderName))
{
throw new ArgumentNullException("Нет адреса электронной почты отправителя", nameof(model.SenderName));
}
if (string.IsNullOrEmpty(model.Subject))
{
throw new ArgumentNullException("Нет заголовка письма", nameof(model.Subject));
}
if (string.IsNullOrEmpty(model.Body))
{
throw new ArgumentNullException("Нет текста письма", nameof(model.Body));
}
_logger.LogInformation("MessageInfo. SenderName: {SenderName}. Subject: {Subject}. Body: {Body}. Id: {MessageId}",
model.SenderName, model.Subject, model.Body, model.MessageId);
var client = _clientStorage.GetElement(new ClientSearchModel { Email = model.SenderName });
if (client != null)
{
model.ClientId = client.Id;
}
}
}
}

View File

@ -5,125 +5,168 @@ using TypographyContracts.StoragesContracts;
using TypographyContracts.ViewModels;
using Microsoft.Extensions.Logging;
using TypographyDataModels.Enums;
using System.Xml.Linq;
using TypographyBusinessLogic.MailWorker;
namespace TypographyBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
static readonly object _locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
{
_logger = logger;
_orderStorage = orderStorage;
}
public OrderViewModel? ReadElement(OrderSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ClientId: {ClientId}. ImplementerId: {ImplementerId}. Status: {Status}. DateFrom: {DateFrom}. DateTo: {DateTo}. Id: {Id}",
model.ClientId, model.ImplementerId, model.Status, model.DateFrom, model.DateTo, model.Id);
var element = _orderStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
return element;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Order status change failed");
return false;
}
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
{
_logger.LogWarning("Order creation failed");
return false;
}
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
lock (_locker)
{
return ChangeOrderStatus(model, OrderStatus.Выполняется);
}
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeOrderStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return ChangeOrderStatus(model, OrderStatus.Выдан);
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Кол-во печатных изделий в заказе должно быть больше 0", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentNullException("Сумма заказа должна быть больше 0", nameof(model.Sum));
}
_logger.LogInformation("Order. Count: {Count}. Sum: {Sum} Id: {Id}", model.Count, model.Sum, model.Id);
}
private bool ChangeOrderStatus(OrderBindingModel model, OrderStatus newStatus)
{
CheckModel(model, false);
var orderView = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (orderView == null || newStatus - orderView.Status != 1)
{
_logger.LogWarning("Order status change failed");
return false;
}
model.Status = newStatus;
if (!model.ImplementerId.HasValue)
model.ImplementerId = orderView.ImplementerId;
model.DateImplement = orderView.DateImplement;
if (newStatus == OrderStatus.Готов)
{
model.DateImplement = DateTime.Now;
}
if (_orderStorage.Update(model) == null)
{
_logger.LogWarning("Order status change failed");
return false;
}
return true;
}
}
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly AbstractMailWorker _mailWorker;
private readonly IClientLogic _clientLogic;
static readonly object _locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker, IClientLogic clientLogic)
{
_logger = logger;
_orderStorage = orderStorage;
_mailWorker = mailWorker;
_clientLogic = clientLogic;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Insert operation failed. Order status incorrect.");
return false;
}
model.Status = OrderStatus.Принят;
var result = _orderStorage.Insert(model);
if (result == null)
{
model.Status = OrderStatus.Неизвестен;
_logger.LogWarning("Insert operation failed");
return false;
}
SendOrderStatusMail(result.ClientId, $"Новый заказ создан. Номер заказа #{result.Id}", $"Заказ #{result.Id} от {result.DateCreate} на сумму {result.Sum:0.00} принят");
return true;
}
public bool StatusUpdate(OrderBindingModel rawModel, OrderStatus newStatus)
{
var viewModel = _orderStorage.GetElement(new OrderSearchModel
{
Id = rawModel.Id
});
if (viewModel == null)
{
_logger.LogWarning("Order model not found");
return false;
}
OrderBindingModel model = new OrderBindingModel
{
Id = viewModel.Id,
PrintedId = viewModel.PrintedId,
Status = viewModel.Status,
DateCreate = viewModel.DateCreate,
DateImplement = viewModel.DateImplement,
Count = viewModel.Count,
Sum = viewModel.Sum,
ImplementerId = viewModel.ImplementerId
};
if (rawModel.ImplementerId.HasValue)
{
model.ImplementerId = rawModel.ImplementerId;
}
CheckModel(model, false);
if (model.Status + 1 != newStatus)
{
_logger.LogWarning("Status update to " + newStatus.ToString() + " operation failed. Order status incorrect.");
return false;
}
model.Status = newStatus;
if (model.Status == OrderStatus.Выдан) model.DateImplement = DateTime.Now;
var result = _orderStorage.Update(model);
if (result == null)
{
model.Status--;
_logger.LogWarning("Update operation failed");
return false;
}
SendOrderStatusMail(result.ClientId, $"Изменен статус заказа #{result.Id}", $"Заказ #{result.Id} изменен статус на {result.Status}");
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
lock (_locker)
{
return StatusUpdate(model, OrderStatus.Выполняется);
}
}
public bool FinishOrder(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выдан);
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("Order. OrderID:{Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public OrderViewModel? ReadElement(OrderSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id:{ Id}", model.Id);
var element = _orderStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
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;
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.PrintedId < 0)
{
throw new ArgumentNullException("Некорректный идентификатор документа", nameof(model.PrintedId));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Количество документов в заказе должно быть больше 0", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentNullException("Сумма заказа должна быть больше 0", nameof(model.Sum));
}
_logger.LogInformation("Order. OrderID:{Id}.Sum:{ Sum}. PrintedId: { PrintedtId}", model.Id, model.Sum, model.PrintedId);
}
}
}

View File

@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using TypographyBusinessLogic.BusinessLogics;
using TypographyContracts.BindingModels;
using TypographyContracts.BusinessLogicsContracts;
namespace TypographyBusinessLogic.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 ILogger _logger;
public AbstractMailWorker(ILogger<AbstractMailWorker> logger, IMessageInfoLogic messageInfoLogic)
{
_logger = logger;
_messageInfoLogic = messageInfoLogic;
}
public void MailConfig(MailConfigBindingModel config)
{
_mailLogin = config.MailLogin;
_mailPassword = config.MailPassword;
_smtpClientHost = config.SmtpClientHost;
_smtpClientPort = config.SmtpClientPort;
_popHost = config.PopHost;
_popPort = config.PopPort;
_logger.LogDebug("Config: {login}, {password}, {clientHost}, {clientPOrt}, {popHost}, {popPort}", _mailLogin, _mailPassword, _smtpClientHost, _smtpClientPort, _popHost, _popPort);
}
public async void MailSendAsync(MailSendInfoBindingModel info)
{
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword))
{
return;
}
if (string.IsNullOrEmpty(_smtpClientHost) || _smtpClientPort == 0)
{
return;
}
if (string.IsNullOrEmpty(info.MailAddress) || string.IsNullOrEmpty(info.Subject) || string.IsNullOrEmpty(info.Text))
{
return;
}
_logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject);
await SendMailAsync(info);
}
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: {Count} new mails", list.Count);
foreach (var mail in list)
{
_messageInfoLogic.Create(mail);
}
}
protected abstract Task SendMailAsync(MailSendInfoBindingModel info);
protected abstract Task<List<MessageInfoBindingModel>> ReceiveMailAsync();
}
}

View File

@ -0,0 +1,78 @@
using TypographyContracts.BindingModels;
using TypographyContracts.BusinessLogicsContracts;
using MailKit.Net.Pop3;
using MailKit.Security;
using Microsoft.Extensions.Logging;
using System.Net;
using System.Net.Mail;
using System.Text;
namespace TypographyBusinessLogic.MailWorker
{
public class MailKitWorker : AbstractMailWorker
{
public MailKitWorker(ILogger<MailKitWorker> logger, IMessageInfoLogic messageInfoLogic) : base(logger, messageInfoLogic) { }
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;
}
}
}

View File

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

View File

@ -130,5 +130,14 @@ namespace TypographyClientApp.Controllers
var prod = APIClient.GetRequest<PrintedViewModel>($"api/main/getprinted?printedId={printed}");
return count * (prod?.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,54 @@
@using TypographyContracts.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

@ -28,6 +28,9 @@
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</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">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TypographyContracts.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,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TypographyContracts.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,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TypographyDataModels.Models;
namespace TypographyContracts.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 string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TypographyContracts.BindingModels;
using TypographyContracts.SearchModels;
using TypographyContracts.ViewModels;
namespace TypographyContracts.BusinessLogicsContracts
{
public interface IMessageInfoLogic
{
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model);
bool Create(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 TypographyContracts.SearchModels
{
public class MessageInfoSearchModel
{
public int? ClientId { get; set; }
public string? MessageId { get; set; }
}
}

View File

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

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TypographyDataModels.Models;
namespace TypographyContracts.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

@ -11,7 +11,8 @@ namespace TypographyContracts.ViewModels
public int ClientId { get; set; }
[DisplayName("Клиент")]
public string ClientFIO { get; set; } = string.Empty;
public int? ImplementerId { get; set; }
public string ClientEmail { get; set; } = string.Empty;
public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")]
public string? ImplementerFIO { get; set; } = string.Empty;
public int PrintedId { get; set; }

View File

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

View File

@ -8,74 +8,75 @@ namespace TypographyDatabaseImplement.Implements
{
public class ClientStorage : IClientStorage
{
public List<ClientViewModel> GetFullList()
{
using var context = new TypographyDatabase();
return context.Clients
.Select(x => x.GetViewModel)
.ToList();
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email))
{
return new();
}
using var context = new TypographyDatabase();
return context.Clients
.Where(x => (!string.IsNullOrEmpty(model.ClientFIO) && x.ClientFIO.Contains(model.ClientFIO)) ||
(!string.IsNullOrEmpty(model.Email) && x.ClientFIO.Contains(model.Email)))
.Select(x => x.GetViewModel)
.ToList();
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
if (!model.Id.HasValue && string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email) && string.IsNullOrEmpty(model.Password))
{
return null;
}
using var context = new TypographyDatabase();
return context.Clients
.FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id) ||
(!string.IsNullOrEmpty(model.ClientFIO) && x.ClientFIO == model.ClientFIO) ||
(!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password) && x.Email == model.Email && x.Password == model.Password))
?.GetViewModel;
}
public ClientViewModel? Insert(ClientBindingModel model)
{
var newClient = Client.Create(model);
if (newClient == null)
{
return null;
}
using var context = new TypographyDatabase();
context.Clients.Add(newClient);
context.SaveChanges();
return newClient.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{
using var context = new TypographyDatabase();
var client = context.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client == null)
{
return null;
}
client.Update(model);
context.SaveChanges();
return client.GetViewModel;
}
public ClientViewModel? Delete(ClientBindingModel model)
{
using var context = new TypographyDatabase();
var element = context.Clients.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Clients.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
public List<ClientViewModel> GetFullList()
{
using var context = new TypographyDatabase();
return context.Clients
.Select(x => x.GetViewModel)
.ToList();
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email))
{
return new();
}
using var context = new TypographyDatabase();
return context.Clients
.Where(x => (!string.IsNullOrEmpty(model.ClientFIO) && x.ClientFIO.Contains(model.ClientFIO)) ||
(!string.IsNullOrEmpty(model.Email) && x.ClientFIO.Contains(model.Email)))
.Select(x => x.GetViewModel)
.ToList();
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
if (!model.Id.HasValue && string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email) && string.IsNullOrEmpty(model.Password))
{
return null;
}
using var context = new TypographyDatabase();
return context.Clients
.FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id) ||
(!string.IsNullOrEmpty(model.ClientFIO) && x.ClientFIO == model.ClientFIO) ||
(!string.IsNullOrEmpty(model.Email) && x.Email == model.Email) ||
(!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password) && x.Email == model.Email && x.Password == model.Password))
?.GetViewModel;
}
public ClientViewModel? Insert(ClientBindingModel model)
{
var newClient = Client.Create(model);
if (newClient == null)
{
return null;
}
using var context = new TypographyDatabase();
context.Clients.Add(newClient);
context.SaveChanges();
return newClient.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{
using var context = new TypographyDatabase();
var client = context.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client == null)
{
return null;
}
client.Update(model);
context.SaveChanges();
return client.GetViewModel;
}
public ClientViewModel? Delete(ClientBindingModel model)
{
using var context = new TypographyDatabase();
var element = context.Clients.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Clients.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,55 @@
using TypographyContracts.BindingModels;
using TypographyContracts.SearchModels;
using TypographyContracts.StoragesContracts;
using TypographyContracts.ViewModels;
using TypographyDatabaseImplement.Models;
namespace TypographyDatabaseImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
public List<MessageInfoViewModel> GetFullList()
{
using var context = new TypographyDatabase();
return context.Messages
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (!model.ClientId.HasValue)
{
return new();
}
using var context = new TypographyDatabase();
return context.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId) && !model.ClientId.HasValue)
{
return null;
}
using var context = new TypographyDatabase();
return context.Messages
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.MessageId) && x.MessageId == model.MessageId) ||
(model.ClientId.HasValue && x.ClientId == model.ClientId))?
.GetViewModel;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessageInfo = MessageInfo.Create(model);
if (newMessageInfo == null)
{
return null;
}
using var context = new TypographyDatabase();
context.Messages.Add(newMessageInfo);
context.SaveChanges();
return newMessageInfo.GetViewModel;
}
}
}

View File

@ -12,7 +12,7 @@ using TypographyDatabaseImplement;
namespace TypographyDatabaseImplement.Migrations
{
[DbContext(typeof(TypographyDatabase))]
[Migration("20240525000632_r")]
[Migration("20240620155631_r")]
partial class r
{
/// <inheritdoc />
@ -97,6 +97,36 @@ namespace TypographyDatabaseImplement.Migrations
b.ToTable("Implementers");
});
modelBuilder.Entity("TypographyDatabaseImplement.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("Messages");
});
modelBuilder.Entity("TypographyDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@ -186,6 +216,15 @@ namespace TypographyDatabaseImplement.Migrations
b.ToTable("PrintedComponents");
});
modelBuilder.Entity("TypographyDatabaseImplement.Models.MessageInfo", b =>
{
b.HasOne("TypographyDatabaseImplement.Models.Client", "Client")
.WithMany("ClientMessages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("TypographyDatabaseImplement.Models.Order", b =>
{
b.HasOne("TypographyDatabaseImplement.Models.Client", "Client")
@ -232,6 +271,8 @@ namespace TypographyDatabaseImplement.Migrations
modelBuilder.Entity("TypographyDatabaseImplement.Models.Client", b =>
{
b.Navigation("ClientMessages");
b.Navigation("ClientOrders");
});

View File

@ -70,6 +70,27 @@ namespace TypographyDatabaseImplement.Migrations
table.PrimaryKey("PK_Printeds", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Messages",
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_Messages", x => x.MessageId);
table.ForeignKey(
name: "FK_Messages_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
@ -134,6 +155,11 @@ namespace TypographyDatabaseImplement.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Messages_ClientId",
table: "Messages",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_Orders_ClientId",
table: "Orders",
@ -163,6 +189,9 @@ namespace TypographyDatabaseImplement.Migrations
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Messages");
migrationBuilder.DropTable(
name: "Orders");

View File

@ -94,6 +94,36 @@ namespace TypographyDatabaseImplement.Migrations
b.ToTable("Implementers");
});
modelBuilder.Entity("TypographyDatabaseImplement.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("Messages");
});
modelBuilder.Entity("TypographyDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@ -183,6 +213,15 @@ namespace TypographyDatabaseImplement.Migrations
b.ToTable("PrintedComponents");
});
modelBuilder.Entity("TypographyDatabaseImplement.Models.MessageInfo", b =>
{
b.HasOne("TypographyDatabaseImplement.Models.Client", "Client")
.WithMany("ClientMessages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("TypographyDatabaseImplement.Models.Order", b =>
{
b.HasOne("TypographyDatabaseImplement.Models.Client", "Client")
@ -229,6 +268,8 @@ namespace TypographyDatabaseImplement.Migrations
modelBuilder.Entity("TypographyDatabaseImplement.Models.Client", b =>
{
b.Navigation("ClientMessages");
b.Navigation("ClientOrders");
});

View File

@ -17,9 +17,11 @@ namespace TypographyDatabaseImplement.Models
public string Password { get; set; } = string.Empty;
[ForeignKey("ClientId")]
public virtual List<Order> ClientOrders { get; set; } = new();
public static Client? Create(ClientBindingModel model)
{
if (model == null)
[ForeignKey("ClientId")]
public virtual List<MessageInfo> ClientMessages { get; set; } = new();
public static Client? Create(ClientBindingModel model)
{
if (model == null)
{
return null;
}

View File

@ -0,0 +1,48 @@
using TypographyContracts.BindingModels;
using TypographyContracts.ViewModels;
using TypographyDataModels.Models;
using System.ComponentModel.DataAnnotations;
namespace TypographyDatabaseImplement.Models
{
public class MessageInfo : IMessageInfoModel
{
[Key]
public string MessageId { get; private set; } = string.Empty;
public int? ClientId { get; private set; }
public virtual Client? Client { get; private set; }
[Required]
public string SenderName { get; private set; } = string.Empty;
[Required]
public DateTime DateDelivery { get; private set; }
[Required]
public string Subject { get; private set; } = string.Empty;
[Required]
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

@ -67,7 +67,8 @@ namespace TypographyDatabaseImplement.Models
Id = Id,
ClientId = ClientId,
ClientFIO = Client.ClientFIO,
ImplementerId = ImplementerId,
ClientEmail = Client.Email,
ImplementerId = ImplementerId,
ImplementerFIO = Implementer != null ? Implementer.ImplementerFIO : null,
PrintedId = PrintedId,
PrintedName = Printed.PrintedName,

View File

@ -10,7 +10,7 @@ namespace TypographyDatabaseImplement
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=Typograph6;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=Typographylab7rpp;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
}
base.OnConfiguring(optionsBuilder);
}
@ -20,5 +20,6 @@ namespace TypographyDatabaseImplement
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Client> Clients { set; get; }
public virtual DbSet<Implementer> Implementers { set; get; }
}
public virtual DbSet<MessageInfo> Messages { set; get; }
}
}

View File

@ -12,12 +12,14 @@ namespace TypographyFileImplement
private readonly string PrintedFileName = "Printed.xml";
private readonly string ClientFileName = "Client.xml";
private readonly string ImplementerFileName = "Implementer.xml";
public List<Component> Components { get; private set; }
private readonly string MessageFileName = "Message.xml";
public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; }
public List<Printed> Printeds { get; private set; }
public List<Client> Clients { get; private set; }
public List<Implementer> Implementers { get; private set; }
public static DataFileSingleton GetInstance()
public List<MessageInfo> Messages { get; private set; }
public static DataFileSingleton GetInstance()
{
if (instance == null)
{
@ -30,14 +32,16 @@ namespace TypographyFileImplement
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
private DataFileSingleton()
public void SaveMessages() => SaveData(Messages, MessageFileName, "Messages", x => x.GetXElement);
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
Printeds = LoadData(PrintedFileName, "Product", x => Printed.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
}
Messages = LoadData(MessageFileName, "Message", x => MessageInfo.Create(x)!)!;
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction)
{
if (File.Exists(filename))

View File

@ -40,8 +40,9 @@ namespace TypographyFileImplement.Implements
return source.Clients
.FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id) ||
(!string.IsNullOrEmpty(model.ClientFIO) && x.ClientFIO == model.ClientFIO) ||
(!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password) && x.Email == model.Email && x.Password == model.Password))
?.GetViewModel;
(!string.IsNullOrEmpty(model.Email) && x.Email == model.Email) ||
(!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password) && x.Email == model.Email && x.Password == model.Password))
?.GetViewModel;
}
public ClientViewModel? Insert(ClientBindingModel model)
{

View File

@ -0,0 +1,56 @@
using TypographyContracts.BindingModels;
using TypographyContracts.SearchModels;
using TypographyContracts.StoragesContracts;
using TypographyContracts.ViewModels;
using TypographyFileImplement.Models;
namespace TypographyFileImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataFileSingleton source;
public MessageInfoStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<MessageInfoViewModel> GetFullList()
{
return source.Messages
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (!model.ClientId.HasValue)
{
return new();
}
return source.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId) && !model.ClientId.HasValue)
{
return null;
}
return source.Messages
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.MessageId) && x.MessageId == model.MessageId) ||
(model.ClientId.HasValue && x.ClientId == model.ClientId))?
.GetViewModel;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = MessageInfo.Create(model);
if (newMessage == null)
{
return null;
}
source.Messages.Add(newMessage);
source.SaveMessages();
return newMessage.GetViewModel;
}
}
}

View File

@ -21,23 +21,24 @@ namespace TypographyFileImplement.Implements
}
private OrderViewModel DefineOthersNames(OrderViewModel model)
{
string? clientFIO = source.Clients.FirstOrDefault(x => model.ClientId == x.Id)?.ClientFIO;
string? implementerFIO = source.Implementers.FirstOrDefault(x => model.ImplementerId == x.Id)?.ImplementerFIO;
string? printedName = source.Printeds.FirstOrDefault(x => model.PrintedId == x.Id)?.PrintedName;
if (clientFIO != null)
{
model.ClientFIO = clientFIO;
}
if (implementerFIO != null)
{
model.ImplementerFIO = implementerFIO;
}
if (printedName != null)
{
model.PrintedName = printedName;
}
return model;
}
var client = source.Clients.FirstOrDefault(x => model.ClientId == x.Id);
string? implementerFIO = source.Implementers.FirstOrDefault(x => model.ImplementerId == x.Id)?.ImplementerFIO;
string? printedName = source.Printeds.FirstOrDefault(x => model.PrintedId == x.Id)?.PrintedName;
if (client != null)
{
model.ClientFIO = client.ClientFIO;
model.ClientEmail = client.Email;
}
if (implementerFIO != null)
{
model.ImplementerFIO = implementerFIO;
}
if (printedName != null)
{
model.PrintedName = printedName;
}
return model;
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if ((!model.DateFrom.HasValue || !model.DateTo.HasValue) && !model.ClientId.HasValue && !model.Status.HasValue)

View File

@ -0,0 +1,65 @@
using TypographyContracts.BindingModels;
using TypographyContracts.ViewModels;
using TypographyDataModels.Models;
using System.Xml.Linq;
namespace TypographyFileImplement.Models
{
public class MessageInfo : IMessageInfoModel
{
public string MessageId { get; private set; } = string.Empty;
public int? ClientId { get; private set; }
public string SenderName { get; private set; } = string.Empty;
public DateTime DateDelivery { get; private 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 static MessageInfo? Create(XElement element)
{
if (element == null)
{
return null;
}
return new MessageInfo()
{
MessageId = element.Attribute("MessageId")!.Value,
ClientId = Convert.ToInt32(element.Element("ClientId")!.Value),
SenderName = element.Element("SenderName")!.Value,
DateDelivery = Convert.ToDateTime(element.Element("DateDelivery")!.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("Message",
new XAttribute("MessageId", MessageId),
new XElement("ClientId", ClientId),
new XElement("SenderName", SenderName),
new XElement("DateDelivery", DateDelivery.ToString()),
new XElement("Subject", Subject),
new XElement("Body", Body));
}
}

View File

@ -10,14 +10,16 @@ namespace TypographyListImplement
public List<Printed> Printeds { get; set; }
public List<Client> Clients { get; set; }
public List<Implementer> Implementers { get; set; }
private DataListSingleton()
public List<MessageInfo> Messages { get; set; }
private DataListSingleton()
{
Components = new List<Component>();
Orders = new List<Order>();
Printeds = new List<Printed>();
Clients = new List<Client>();
Implementers = new List<Implementer>();
}
Messages = new List<MessageInfo>();
}
public static DataListSingleton GetInstance()
{
if (_instance == null)

View File

@ -49,8 +49,9 @@ namespace TypographyListImplement.Implements
{
if ((model.Id.HasValue && client.Id == model.Id) ||
(!string.IsNullOrEmpty(model.ClientFIO) && client.ClientFIO == model.ClientFIO) ||
(!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password) && client.Email == model.Email && client.Password == model.Password))
{
(!string.IsNullOrEmpty(model.Email) && client.Email == model.Email) ||
(!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password) && client.Email == model.Email && client.Password == model.Password))
{
return client.GetViewModel;
}
}

View File

@ -0,0 +1,68 @@
using TypographyContracts.BindingModels;
using TypographyContracts.SearchModels;
using TypographyContracts.StoragesContracts;
using TypographyContracts.ViewModels;
using TypographyListImplement.Models;
namespace TypographyListImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataListSingleton _source;
public MessageInfoStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<MessageInfoViewModel> GetFullList()
{
var result = new List<MessageInfoViewModel>();
foreach (var message in _source.Messages)
{
result.Add(message.GetViewModel);
}
return result;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
var result = new List<MessageInfoViewModel>();
if (!model.ClientId.HasValue)
{
return result;
}
foreach (var message in _source.Messages)
{
if (message.ClientId == model.ClientId)
{
result.Add(message.GetViewModel);
}
}
return result;
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId) && !model.ClientId.HasValue)
{
return null;
}
foreach (var message in _source.Messages)
{
if ((!string.IsNullOrEmpty(model.MessageId) && message.MessageId == model.MessageId) ||
(model.ClientId.HasValue && message.ClientId == model.ClientId))
{
return message.GetViewModel;
}
}
return null;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = MessageInfo.Create(model);
if (newMessage == null)
{
return null;
}
_source.Messages.Add(newMessage);
return newMessage.GetViewModel;
}
}
}

View File

@ -30,7 +30,8 @@ namespace TypographyListImplement.Implements
if (result.ClientId == client.Id)
{
result.ClientFIO = client.ClientFIO;
break;
result.ClientEmail = client.Email;
break;
}
}
foreach (var implementer in _source.Implementers)

View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TypographyContracts.BindingModels;
using TypographyContracts.ViewModels;
using TypographyDataModels.Models;
namespace TypographyListImplement.Models
{
public class MessageInfo : IMessageInfoModel
{
public string MessageId { get; private set; } = string.Empty;
public int? ClientId { get; private set; }
public string SenderName { get; private set; } = string.Empty;
public DateTime DateDelivery { get; private 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

@ -0,0 +1,122 @@
using TypographyContracts.BindingModels;
using TypographyContracts.BusinessLogicsContracts;
using TypographyContracts.SearchModels;
using TypographyContracts.StoragesContracts;
using TypographyContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace TypographyBusinessLogic.BusinessLogics
{
public class ClientLogic : IClientLogic
{
private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage)
{
_logger = logger;
_clientStorage = clientStorage;
}
public List<ClientViewModel>? ReadList(ClientSearchModel? model)
{
_logger.LogInformation("ReadList. Id: {Id}. ClientFIO: {ClientFIO}. Email: {Email}.",
model?.Id, model?.ClientFIO, model?.Email);
var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public ClientViewModel? ReadElement(ClientSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id: {Id}. ClientFIO: {ClientFIO}. Email: {Email}.",
model?.Id, model?.ClientFIO, model?.Email);
var element = _clientStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
return element;
}
public bool Create(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ClientBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id: {Id}", model.Id);
if (_clientStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ClientBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ClientFIO))
{
throw new ArgumentNullException("Нет ФИО клиента", nameof(model.ClientFIO));
}
if (string.IsNullOrEmpty(model.Email))
{
throw new ArgumentNullException("Нет электронной почты клиента", nameof(model.Email));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля клиента", nameof(model.Password));
}
if (!Regex.IsMatch(model.Email, @"^[-\w.]+@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,4}$"))
{
throw new ArgumentNullException("Введенное не является адресом электронной почты", nameof(model.Email));
}
if (model.Password.Length < 10 || model.Password.Length > 50 ||
!Regex.IsMatch(model.Password, @"^((\w+\d+\W+)|(\w+\W+\d+)|(\d+\w+\W+)|(\d+\W+\w+)|(\W+\w+\d+)|(\W+\d+\w+))[\w\d\W]*$"))
{
throw new ArgumentNullException("Пароль не соответсвует требованиям безопасности", nameof(model.Password));
}
_logger.LogInformation("Client. Id: {Id}. ClientFIO: {ClientFIO}. Email: {Email}.",
model?.Id, model?.ClientFIO, model?.Email);
var element = _clientStorage.GetElement(new ClientSearchModel { Email = model.Email });
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Клиент с таким логином уже есть");
}
}
}
}

View File

@ -12,11 +12,13 @@ namespace TypographyRestApi.Controllers
{
private readonly ILogger _logger;
private readonly IClientLogic _logic;
private readonly IMessageInfoLogic _mailLogic;
public ClientController(IClientLogic logic, ILogger<ClientController> logger)
public ClientController(IClientLogic logic, ILogger<ClientController> logger, IMessageInfoLogic mailLogic)
{
_logger = logger;
_logic = logic;
_mailLogic = mailLogic;
}
[HttpGet]
@ -64,5 +66,21 @@ namespace TypographyRestApi.Controllers
throw;
}
}
[HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientId)
{
try
{
return _mailLogic.ReadList(new MessageInfoSearchModel
{
ClientId = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения писем клиента");
throw;
}
}
}
}

View File

@ -3,6 +3,8 @@ using TypographyContracts.BusinessLogicsContracts;
using TypographyContracts.StoragesContracts;
using TypographyDatabaseImplement.Implements;
using Microsoft.OpenApi.Models;
using TypographyBusinessLogic.MailWorker;
using TypographyContracts.BindingModels;
var builder = WebApplication.CreateBuilder(args);
@ -14,11 +16,15 @@ builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IPrintedStorage, PrintedStorage>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IPrintedLogic, PrintedLogic>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
@ -29,7 +35,16 @@ builder.Services.AddSwaggerGen(c =>
});
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.
if (app.Environment.IsDevelopment())
{

View File

@ -5,5 +5,12 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"SmtpClientHost": "smtp.gmail.com",
"SmtpClientPort": "587",
"PopHost": "pop.gmail.com",
"PopPort": "995",
"MailLogin": "lawfirmlab7@gmail.com",
"MailPassword": "logf arhv rtkk rqfe"
}