Compare commits

...

4 Commits

Author SHA1 Message Date
yuliya.mavrina@internet.ru
8295e7fa60 Лабораторная_7 2024-05-16 15:38:12 +03:00
yuliya.mavrina@internet.ru
6bdc77b685 Лабораторная_7 2024-05-15 08:37:13 +03:00
yuliya.mavrina@internet.ru
af3261f0cb Лабораторная_7 2024-05-14 15:14:32 +03:00
yuliya.mavrina@internet.ru
c700cbe44c Лабораторная_6 2024-05-04 10:16:17 +03:00
40 changed files with 1997 additions and 513 deletions

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="lab767676@gmail.com" />
<add key="MailPassword" value="hcrp rdjx dihb ilrs" />
</appSettings>
</configuration>

View File

@ -0,0 +1,61 @@
namespace RenovationWorkView
{
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.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowTemplate.Height = 25;
dataGridView.Size = new Size(761, 244);
dataGridView.TabIndex = 0;
//
// FormMail
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(761, 243);
Controls.Add(dataGridView);
Name = "FormMail";
Text = "Письма";
Load += FormMail_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,48 @@
using Microsoft.Extensions.Logging;
using RenovationWorkContracts.BusinessLogicsContracts;
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 RenovationWorkView
{
public partial class FormMail : Form
{
private readonly ILogger _logger;
private readonly IMessageInfoLogic _logic;
public FormMail(ILogger<FormMail> logger, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
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

@ -1,234 +1,243 @@
namespace RenovationWorkView namespace RenovationWorkView
{ {
partial class FormMain partial class FormMain
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
private System.ComponentModel.IContainer components = null; private System.ComponentModel.IContainer components = null;
/// <summary> /// <summary>
/// Clean up any resources being used. /// Clean up any resources being used.
/// </summary> /// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if (disposing && (components != null)) if (disposing && (components != null))
{ {
components.Dispose(); components.Dispose();
} }
base.Dispose(disposing); base.Dispose(disposing);
} }
#region Windows Form Designer generated code #region Windows Form Designer generated code
/// <summary> /// <summary>
/// Required method for Designer support - do not modify /// Required method for Designer support - do not modify
/// the contents of this method with the code editor. /// the contents of this method with the code editor.
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
menuStrip = new MenuStrip(); menuStrip = new MenuStrip();
refbooksToolStripMenuItem = new ToolStripMenuItem(); refbooksToolStripMenuItem = new ToolStripMenuItem();
componentsToolStripMenuItem = new ToolStripMenuItem(); componentsToolStripMenuItem = new ToolStripMenuItem();
JobTypeToolStripMenuItem = new ToolStripMenuItem(); JobTypeToolStripMenuItem = new ToolStripMenuItem();
ClientsToolStripMenuItem = new ToolStripMenuItem(); ClientsToolStripMenuItem = new ToolStripMenuItem();
отчетыToolStripMenuItem = new ToolStripMenuItem(); ImplementersToolStripMenuItem = new ToolStripMenuItem();
listComponentsToolStripMenuItem = new ToolStripMenuItem(); отчетыToolStripMenuItem = new ToolStripMenuItem();
componentRepairsПоИзделиямToolStripMenuItem = new ToolStripMenuItem(); listComponentsToolStripMenuItem = new ToolStripMenuItem();
OrdersToolStripMenuItem = new ToolStripMenuItem(); componentRepairsПоИзделиямToolStripMenuItem = new ToolStripMenuItem();
dataGridView = new DataGridView(); OrdersToolStripMenuItem = new ToolStripMenuItem();
buttonCreateOrder = new Button(); StartWorkingToolStripMenuItem = new ToolStripMenuItem();
buttonTakeOrderInWork = new Button(); dataGridView = new DataGridView();
buttonOrderReady = new Button(); buttonCreateOrder = new Button();
buttonIssuedOrder = new Button(); buttonTakeOrderInWork = new Button();
buttonRef = new Button(); buttonOrderReady = new Button();
ImplementersToolStripMenuItem = new ToolStripMenuItem(); buttonIssuedOrder = new Button();
StartWorkingToolStripMenuItem = new ToolStripMenuItem(); buttonRef = new Button();
menuStrip.SuspendLayout(); mailToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); menuStrip.SuspendLayout();
SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
// SuspendLayout();
// menuStrip //
// // menuStrip
menuStrip.Items.AddRange(new ToolStripItem[] { refbooksToolStripMenuItem, отчетыToolStripMenuItem }); //
menuStrip.Location = new Point(0, 0); menuStrip.Items.AddRange(new ToolStripItem[] { refbooksToolStripMenuItem, отчетыToolStripMenuItem, StartWorkingToolStripMenuItem, mailToolStripMenuItem });
menuStrip.Name = "menuStrip"; menuStrip.Location = new Point(0, 0);
menuStrip.Size = new Size(1129, 24); menuStrip.Name = "menuStrip";
menuStrip.TabIndex = 0; menuStrip.Size = new Size(1129, 24);
menuStrip.Text = "menuStrip1"; menuStrip.TabIndex = 0;
// menuStrip.Text = "menuStrip1";
// refbooksToolStripMenuItem //
// // refbooksToolStripMenuItem
refbooksToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { componentsToolStripMenuItem, JobTypeToolStripMenuItem, ClientsToolStripMenuItem, ImplementersToolStripMenuItem, StartWorkingToolStripMenuItem }); //
refbooksToolStripMenuItem.Name = "refbooksToolStripMenuItem"; refbooksToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { componentsToolStripMenuItem, JobTypeToolStripMenuItem, ClientsToolStripMenuItem, ImplementersToolStripMenuItem });
refbooksToolStripMenuItem.Size = new Size(94, 20); refbooksToolStripMenuItem.Name = "refbooksToolStripMenuItem";
refbooksToolStripMenuItem.Text = "Справочники"; refbooksToolStripMenuItem.Size = new Size(94, 20);
// refbooksToolStripMenuItem.Text = "Справочники";
// componentsToolStripMenuItem //
// // componentsToolStripMenuItem
componentsToolStripMenuItem.Name = "componentsToolStripMenuItem"; //
componentsToolStripMenuItem.Size = new Size(180, 22); componentsToolStripMenuItem.Name = "componentsToolStripMenuItem";
componentsToolStripMenuItem.Text = "Компоненты"; componentsToolStripMenuItem.Size = new Size(149, 22);
componentsToolStripMenuItem.Click += componentsToolStripMenuItem_Click; componentsToolStripMenuItem.Text = "Компоненты";
// componentsToolStripMenuItem.Click += componentsToolStripMenuItem_Click;
// JobTypeToolStripMenuItem //
// // JobTypeToolStripMenuItem
JobTypeToolStripMenuItem.Name = "JobTypeToolStripMenuItem"; //
JobTypeToolStripMenuItem.Size = new Size(180, 22); JobTypeToolStripMenuItem.Name = "JobTypeToolStripMenuItem";
JobTypeToolStripMenuItem.Text = "Вид работы"; JobTypeToolStripMenuItem.Size = new Size(149, 22);
JobTypeToolStripMenuItem.Click += JobTypeToolStripMenuItem_Click; JobTypeToolStripMenuItem.Text = "Вид работы";
// JobTypeToolStripMenuItem.Click += JobTypeToolStripMenuItem_Click;
// ClientsToolStripMenuItem //
// // ClientsToolStripMenuItem
ClientsToolStripMenuItem.Name = "ClientsToolStripMenuItem"; //
ClientsToolStripMenuItem.Size = new Size(180, 22); ClientsToolStripMenuItem.Name = "ClientsToolStripMenuItem";
ClientsToolStripMenuItem.Text = "Клиенты"; ClientsToolStripMenuItem.Size = new Size(149, 22);
ClientsToolStripMenuItem.Click += ClientsToolStripMenuItem_Click; ClientsToolStripMenuItem.Text = "Клиенты";
// ClientsToolStripMenuItem.Click += ClientsToolStripMenuItem_Click;
// отчетыToolStripMenuItem //
// // ImplementersToolStripMenuItem
отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { listComponentsToolStripMenuItem, componentRepairsПоИзделиямToolStripMenuItem, OrdersToolStripMenuItem }); //
отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem"; ImplementersToolStripMenuItem.Name = "ImplementersToolStripMenuItem";
отчетыToolStripMenuItem.Size = new Size(60, 20); ImplementersToolStripMenuItem.Size = new Size(149, 22);
отчетыToolStripMenuItem.Text = "Отчеты"; ImplementersToolStripMenuItem.Text = "Исполнители";
// ImplementersToolStripMenuItem.Click += ImplementersToolStripMenuItem_Click;
// listComponentsToolStripMenuItem //
// // отчетыToolStripMenuItem
listComponentsToolStripMenuItem.Name = "listComponentsToolStripMenuItem"; //
listComponentsToolStripMenuItem.Size = new Size(218, 22); отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { listComponentsToolStripMenuItem, componentRepairsПоИзделиямToolStripMenuItem, OrdersToolStripMenuItem });
listComponentsToolStripMenuItem.Text = "Список изделий"; отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem";
listComponentsToolStripMenuItem.Click += listComponentsToolStripMenuItem_Click; отчетыToolStripMenuItem.Size = new Size(60, 20);
// отчетыToolStripMenuItem.Text = "Отчеты";
// componentRepairsПоИзделиямToolStripMenuItem //
// // listComponentsToolStripMenuItem
componentRepairsПоИзделиямToolStripMenuItem.Name = "componentRepairsПоИзделиямToolStripMenuItem"; //
componentRepairsПоИзделиямToolStripMenuItem.Size = new Size(218, 22); listComponentsToolStripMenuItem.Name = "listComponentsToolStripMenuItem";
componentRepairsПоИзделиямToolStripMenuItem.Text = "Компоненты по изделиям"; listComponentsToolStripMenuItem.Size = new Size(218, 22);
componentRepairsПоИзделиямToolStripMenuItem.Click += componentRepairsПоИзделиямToolStripMenuItem_Click; listComponentsToolStripMenuItem.Text = "Список изделий";
// listComponentsToolStripMenuItem.Click += listComponentsToolStripMenuItem_Click;
// OrdersToolStripMenuItem //
// // componentRepairsПоИзделиямToolStripMenuItem
OrdersToolStripMenuItem.Name = "OrdersToolStripMenuItem"; //
OrdersToolStripMenuItem.Size = new Size(218, 22); componentRepairsПоИзделиямToolStripMenuItem.Name = "componentRepairsПоИзделиямToolStripMenuItem";
OrdersToolStripMenuItem.Text = "Список заказов"; componentRepairsПоИзделиямToolStripMenuItem.Size = new Size(218, 22);
OrdersToolStripMenuItem.Click += OrdersToolStripMenuItem_Click; componentRepairsПоИзделиямToolStripMenuItem.Text = "Компоненты по изделиям";
// componentRepairsПоИзделиямToolStripMenuItem.Click += componentRepairsПоИзделиямToolStripMenuItem_Click;
// dataGridView //
// // OrdersToolStripMenuItem
dataGridView.BackgroundColor = SystemColors.ControlLightLight; //
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; OrdersToolStripMenuItem.Name = "OrdersToolStripMenuItem";
dataGridView.Location = new Point(12, 27); OrdersToolStripMenuItem.Size = new Size(218, 22);
dataGridView.Name = "dataGridView"; OrdersToolStripMenuItem.Text = "Список заказов";
dataGridView.RowTemplate.Height = 25; OrdersToolStripMenuItem.Click += OrdersToolStripMenuItem_Click;
dataGridView.Size = new Size(942, 341); //
dataGridView.TabIndex = 1; // StartWorkingToolStripMenuItem
// //
// buttonCreateOrder StartWorkingToolStripMenuItem.Name = "StartWorkingToolStripMenuItem";
// StartWorkingToolStripMenuItem.Size = new Size(92, 20);
buttonCreateOrder.Location = new Point(960, 42); StartWorkingToolStripMenuItem.Text = "Запуск работ";
buttonCreateOrder.Name = "buttonCreateOrder"; StartWorkingToolStripMenuItem.Click += StartWorkingToolStripMenuItem_Click_1;
buttonCreateOrder.Size = new Size(157, 23); //
buttonCreateOrder.TabIndex = 2; // dataGridView
buttonCreateOrder.Text = "Создать заказ"; //
buttonCreateOrder.UseVisualStyleBackColor = true; dataGridView.BackgroundColor = SystemColors.ControlLightLight;
buttonCreateOrder.Click += buttonCreateOrder_Click; dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
// dataGridView.Location = new Point(12, 27);
// buttonTakeOrderInWork dataGridView.Name = "dataGridView";
// dataGridView.RowTemplate.Height = 25;
buttonTakeOrderInWork.Location = new Point(960, 71); dataGridView.Size = new Size(942, 341);
buttonTakeOrderInWork.Name = "buttonTakeOrderInWork"; dataGridView.TabIndex = 1;
buttonTakeOrderInWork.Size = new Size(157, 23); //
buttonTakeOrderInWork.TabIndex = 3; // buttonCreateOrder
buttonTakeOrderInWork.Text = "Отладить на выполнение"; //
buttonTakeOrderInWork.UseVisualStyleBackColor = true; buttonCreateOrder.Location = new Point(960, 42);
buttonTakeOrderInWork.Click += buttonTakeOrderInWork_Click; buttonCreateOrder.Name = "buttonCreateOrder";
// buttonCreateOrder.Size = new Size(157, 23);
// buttonOrderReady buttonCreateOrder.TabIndex = 2;
// buttonCreateOrder.Text = "Создать заказ";
buttonOrderReady.Location = new Point(960, 100); buttonCreateOrder.UseVisualStyleBackColor = true;
buttonOrderReady.Name = "buttonOrderReady"; buttonCreateOrder.Click += buttonCreateOrder_Click;
buttonOrderReady.Size = new Size(157, 23); //
buttonOrderReady.TabIndex = 4; // buttonTakeOrderInWork
buttonOrderReady.Text = "Заказ готов"; //
buttonOrderReady.UseVisualStyleBackColor = true; buttonTakeOrderInWork.Location = new Point(960, 71);
buttonOrderReady.Click += buttonOrderReady_Click; buttonTakeOrderInWork.Name = "buttonTakeOrderInWork";
// buttonTakeOrderInWork.Size = new Size(157, 23);
// buttonIssuedOrder buttonTakeOrderInWork.TabIndex = 3;
// buttonTakeOrderInWork.Text = "Отладить на выполнение";
buttonIssuedOrder.Location = new Point(960, 129); buttonTakeOrderInWork.UseVisualStyleBackColor = true;
buttonIssuedOrder.Name = "buttonIssuedOrder"; buttonTakeOrderInWork.Click += buttonTakeOrderInWork_Click;
buttonIssuedOrder.Size = new Size(157, 23); //
buttonIssuedOrder.TabIndex = 5; // buttonOrderReady
buttonIssuedOrder.Text = "Заказ выдан"; //
buttonIssuedOrder.UseVisualStyleBackColor = true; buttonOrderReady.Location = new Point(960, 100);
buttonIssuedOrder.Click += buttonIssuedOrder_Click; buttonOrderReady.Name = "buttonOrderReady";
// buttonOrderReady.Size = new Size(157, 23);
// buttonRef buttonOrderReady.TabIndex = 4;
// buttonOrderReady.Text = "Заказ готов";
buttonRef.Location = new Point(960, 158); buttonOrderReady.UseVisualStyleBackColor = true;
buttonRef.Name = "buttonRef"; buttonOrderReady.Click += buttonOrderReady_Click;
buttonRef.Size = new Size(157, 23); //
buttonRef.TabIndex = 6; // buttonIssuedOrder
buttonRef.Text = "Обновить список"; //
buttonRef.UseVisualStyleBackColor = true; buttonIssuedOrder.Location = new Point(960, 129);
buttonRef.Click += buttonRef_Click; buttonIssuedOrder.Name = "buttonIssuedOrder";
// buttonIssuedOrder.Size = new Size(157, 23);
// ImplementersToolStripMenuItem buttonIssuedOrder.TabIndex = 5;
// buttonIssuedOrder.Text = "Заказ выдан";
ImplementersToolStripMenuItem.Name = "ImplementersToolStripMenuItem"; buttonIssuedOrder.UseVisualStyleBackColor = true;
ImplementersToolStripMenuItem.Size = new Size(180, 22); buttonIssuedOrder.Click += buttonIssuedOrder_Click;
ImplementersToolStripMenuItem.Text = "Исполнители"; //
ImplementersToolStripMenuItem.Click += ImplementersToolStripMenuItem_Click; // buttonRef
// //
// StartWorkingToolStripMenuItem buttonRef.Location = new Point(960, 158);
// buttonRef.Name = "buttonRef";
StartWorkingToolStripMenuItem.Name = "StartWorkingToolStripMenuItem"; buttonRef.Size = new Size(157, 23);
StartWorkingToolStripMenuItem.Size = new Size(180, 22); buttonRef.TabIndex = 6;
StartWorkingToolStripMenuItem.Text = "Старт работ"; buttonRef.Text = "Обновить список";
StartWorkingToolStripMenuItem.Click += StartWorkingToolStripMenuItem_Click; buttonRef.UseVisualStyleBackColor = true;
// buttonRef.Click += buttonRef_Click;
// FormMain //
// // mailToolStripMenuItem
AutoScaleDimensions = new SizeF(7F, 15F); //
AutoScaleMode = AutoScaleMode.Font; mailToolStripMenuItem.Name = "mailToolStripMenuItem";
ClientSize = new Size(1129, 370); mailToolStripMenuItem.Size = new Size(62, 20);
Controls.Add(buttonRef); mailToolStripMenuItem.Text = "Письма";
Controls.Add(buttonIssuedOrder); mailToolStripMenuItem.Click += mailToolStripMenuItem_Click;
Controls.Add(buttonOrderReady); //
Controls.Add(buttonTakeOrderInWork); // FormMain
Controls.Add(buttonCreateOrder); //
Controls.Add(dataGridView); AutoScaleDimensions = new SizeF(7F, 15F);
Controls.Add(menuStrip); AutoScaleMode = AutoScaleMode.Font;
MainMenuStrip = menuStrip; ClientSize = new Size(1129, 370);
Name = "FormMain"; Controls.Add(buttonRef);
Text = "Ремонтные работы"; Controls.Add(buttonIssuedOrder);
Load += FormMain_Load; Controls.Add(buttonOrderReady);
menuStrip.ResumeLayout(false); Controls.Add(buttonTakeOrderInWork);
menuStrip.PerformLayout(); Controls.Add(buttonCreateOrder);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); Controls.Add(dataGridView);
ResumeLayout(false); Controls.Add(menuStrip);
PerformLayout(); MainMenuStrip = menuStrip;
} Name = "FormMain";
Text = "Ремонтные работы";
Load += FormMain_Load;
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion #endregion
private MenuStrip menuStrip; private MenuStrip menuStrip;
private ToolStripMenuItem refbooksToolStripMenuItem; private ToolStripMenuItem refbooksToolStripMenuItem;
private ToolStripMenuItem componentsToolStripMenuItem; private ToolStripMenuItem componentsToolStripMenuItem;
private ToolStripMenuItem JobTypeToolStripMenuItem; private ToolStripMenuItem JobTypeToolStripMenuItem;
private DataGridView dataGridView; private DataGridView dataGridView;
private Button buttonCreateOrder; private Button buttonCreateOrder;
private Button buttonTakeOrderInWork; private Button buttonTakeOrderInWork;
private Button buttonOrderReady; private Button buttonOrderReady;
private Button buttonIssuedOrder; private Button buttonIssuedOrder;
private Button buttonRef; private Button buttonRef;
private ToolStripMenuItem отчетыToolStripMenuItem; private ToolStripMenuItem отчетыToolStripMenuItem;
private ToolStripMenuItem listComponentsToolStripMenuItem; private ToolStripMenuItem listComponentsToolStripMenuItem;
private ToolStripMenuItem componentRepairsПоИзделиямToolStripMenuItem; private ToolStripMenuItem componentRepairsПоИзделиямToolStripMenuItem;
private ToolStripMenuItem OrdersToolStripMenuItem; private ToolStripMenuItem OrdersToolStripMenuItem;
private ToolStripMenuItem ClientsToolStripMenuItem; private ToolStripMenuItem ClientsToolStripMenuItem;
private ToolStripMenuItem ImplementersToolStripMenuItem; private ToolStripMenuItem ImplementersToolStripMenuItem;
private ToolStripMenuItem StartWorkingToolStripMenuItem; private ToolStripMenuItem StartWorkingToolStripMenuItem;
} private ToolStripMenuItem mailToolStripMenuItem;
}
} }

View File

@ -14,211 +14,220 @@ using RenovationWorkBusinessLogic.BusinessLogics;
namespace RenovationWorkView namespace RenovationWorkView
{ {
public partial class FormMain : Form public partial class FormMain : Form
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic; private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic; private readonly IReportLogic _reportLogic;
private readonly IWorkProcess _workProcess; private readonly IWorkProcess _workProcess;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess) public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
{ {
InitializeComponent(); InitializeComponent();
_logger = logger; _logger = logger;
_orderLogic = orderLogic; _orderLogic = orderLogic;
_reportLogic = reportLogic; _reportLogic = reportLogic;
_workProcess = workProcess; _workProcess = workProcess;
} }
private void FormMain_Load(object sender, EventArgs e) private void FormMain_Load(object sender, EventArgs e)
{ {
LoadData(); LoadData();
} }
private void LoadData() private void LoadData()
{ {
_logger.LogInformation("Загрузка заказов"); _logger.LogInformation("Загрузка заказов");
try try
{ {
var list = _orderLogic.ReadList(null); var list = _orderLogic.ReadList(null);
if (list != null) if (list != null)
{ {
dataGridView.DataSource = list; dataGridView.DataSource = list;
dataGridView.Columns["RepairId"].Visible = false; dataGridView.Columns["RepairId"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false; dataGridView.Columns["ImplementerId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false; dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["RepairName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; dataGridView.Columns["RepairName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка загрузки заказов"); _logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void componentsToolStripMenuItem_Click(object sender, EventArgs e) private void componentsToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormComponents)); var service = Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form) if (service is FormComponents form)
{ {
form.ShowDialog(); form.ShowDialog();
} }
} }
private void JobTypeToolStripMenuItem_Click(object sender, EventArgs e) private void JobTypeToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormRepairs)); var service = Program.ServiceProvider?.GetService(typeof(FormRepairs));
if (service is FormRepairs form) if (service is FormRepairs form)
{ {
form.ShowDialog(); form.ShowDialog();
} }
} }
private void buttonCreateOrder_Click(object sender, EventArgs e) private void buttonCreateOrder_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form) if (service is FormCreateOrder form)
{ {
form.ShowDialog(); form.ShowDialog();
LoadData(); LoadData();
} }
} }
private void buttonTakeOrderInWork_Click(object sender, EventArgs e) private void buttonTakeOrderInWork_Click(object sender, EventArgs e)
{ {
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)
{ {
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id); _logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id);
try try
{ {
var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { Id = id }); var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { Id = id });
if (!operationResult) if (!operationResult)
{ {
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
} }
LoadData(); LoadData();
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка передачи заказа в работу"); _logger.LogError(ex, "Ошибка передачи заказа в работу");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
} }
private void buttonOrderReady_Click(object sender, EventArgs e) private void buttonOrderReady_Click(object sender, EventArgs e)
{ {
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)
{ {
int id = int id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id); _logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id);
try try
{ {
var operationResult = _orderLogic.FinishOrder(new var operationResult = _orderLogic.FinishOrder(new
OrderBindingModel OrderBindingModel
{ Id = id }); { Id = id });
if (!operationResult) if (!operationResult)
{ {
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
} }
LoadData(); LoadData();
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка отметки о готовности заказа"); _logger.LogError(ex, "Ошибка отметки о готовности заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
} }
private void buttonIssuedOrder_Click(object sender, EventArgs e) private void buttonIssuedOrder_Click(object sender, EventArgs e)
{ {
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)
{ {
int id = int id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id); _logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id);
try try
{ {
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id }); var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id });
if (!operationResult) if (!operationResult)
{ {
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
} }
_logger.LogInformation("Заказ №{id} выдан", id); _logger.LogInformation("Заказ №{id} выдан", id);
LoadData(); LoadData();
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка отметки о выдачи заказа"); _logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
} }
private void buttonRef_Click(object sender, EventArgs e) private void buttonRef_Click(object sender, EventArgs e)
{ {
LoadData(); LoadData();
} }
private void listComponentsToolStripMenuItem_Click(object sender, EventArgs e) private void listComponentsToolStripMenuItem_Click(object sender, EventArgs e)
{ {
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" }; using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK) if (dialog.ShowDialog() == DialogResult.OK)
{ {
_reportLogic.SaveRepairsToWordFile(new ReportBindingModel _reportLogic.SaveRepairsToWordFile(new ReportBindingModel
{ {
FileName = dialog.FileName FileName = dialog.FileName
}); });
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK,
MessageBoxIcon.Information); MessageBoxIcon.Information);
} }
} }
private void componentRepairsПоИзделиямToolStripMenuItem_Click(object sender, EventArgs e) private void componentRepairsПоИзделиямToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormReportRepairComponents)); var service = Program.ServiceProvider?.GetService(typeof(FormReportRepairComponents));
if (service is FormReportRepairComponents form) if (service is FormReportRepairComponents form)
{ {
form.ShowDialog(); form.ShowDialog();
} }
} }
private void OrdersToolStripMenuItem_Click(object sender, EventArgs e) private void OrdersToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders)); var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form) if (service is FormReportOrders form)
{ {
form.ShowDialog(); form.ShowDialog();
} }
} }
private void ClientsToolStripMenuItem_Click(object sender, EventArgs e) private void ClientsToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormClients)); var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form) if (service is FormClients form)
{ {
form.ShowDialog(); form.ShowDialog();
} }
} }
private void ImplementersToolStripMenuItem_Click(object sender, EventArgs e) private void ImplementersToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers)); var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if (service is FormImplementers form) if (service is FormImplementers form)
{ {
form.ShowDialog(); form.ShowDialog();
} }
} }
private void StartWorkingToolStripMenuItem_Click(object sender, EventArgs e) private void StartWorkingToolStripMenuItem_Click_1(object sender, EventArgs e)
{ {
_workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic); _workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
} }
}
private void mailToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormMail));
if (service is FormMail form)
{
form.ShowDialog();
}
}
}
} }

View File

@ -1,3 +1,5 @@
using RenovationWorkBusinessLogic.MailWorker;
using RenovationWorkContracts.BindingModels;
using RenovationWorkBusinessLogic.BusinessLogics; using RenovationWorkBusinessLogic.BusinessLogics;
using RenovationWorkBusinessLogic.OfficePackage.Implements; using RenovationWorkBusinessLogic.OfficePackage.Implements;
using RenovationWorkBusinessLogic.OfficePackage; using RenovationWorkBusinessLogic.OfficePackage;
@ -12,25 +14,48 @@ using System;
namespace RenovationWorkView namespace RenovationWorkView
{ {
internal static class Program internal static class Program
{ {
private static ServiceProvider? _serviceProvider; private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider; public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary> /// <summary>
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
static void Main() static void Main()
{ {
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize(); ApplicationConfiguration.Initialize();
var services = new ServiceCollection(); var services = new ServiceCollection();
ConfigureServices(services); ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider(); _serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>()); try
} {
private static void ConfigureServices(ServiceCollection services) 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)
{ {
services.AddLogging(option => services.AddLogging(option =>
{ {
@ -51,7 +76,10 @@ namespace RenovationWorkView
services.AddTransient<IClientStorage, ClientStorage>(); services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IImplementerLogic, ImplementerLogic>(); services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IImplementerStorage, ImplementerStorage>(); services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<IWorkProcess, WorkModeling>(); services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
services.AddSingleton<AbstractMailWorker, MailKitWorker>();
services.AddTransient<IWorkProcess, WorkModeling>();
services.AddTransient<FormMain>(); services.AddTransient<FormMain>();
services.AddTransient<FormComponent>(); services.AddTransient<FormComponent>();
services.AddTransient<FormComponents>(); services.AddTransient<FormComponents>();
@ -64,6 +92,8 @@ namespace RenovationWorkView
services.AddTransient<FormClients>(); services.AddTransient<FormClients>();
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

@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Text.RegularExpressions;
namespace RenovationWorkBusinessLogic.BusinessLogics namespace RenovationWorkBusinessLogic.BusinessLogics
{ {
@ -81,41 +82,49 @@ namespace RenovationWorkBusinessLogic.BusinessLogics
} }
return true; return true;
} }
private void CheckModel(ClientBindingModel model, bool withParams = private void CheckModel(ClientBindingModel model, bool withParams = true)
true)
{ {
if (model == null) if(model == null)
{
throw new ArgumentNullException(nameof(model)); {
} throw new ArgumentNullException(nameof(model));
if (!withParams) }
{ if (!withParams)
return; {
} return;
if (string.IsNullOrEmpty(model.ClientFIO)) }
{ if (string.IsNullOrEmpty(model.ClientFIO))
throw new ArgumentNullException(nameof(model.ClientFIO)); {
} throw new ArgumentNullException(nameof(model.ClientFIO));
if (string.IsNullOrEmpty(model.Email)) }
{ if (string.IsNullOrEmpty(model.Email))
throw new ArgumentNullException("Нет Email клиента", {
nameof(model.ClientFIO)); throw new ArgumentNullException("Нет Email клиента",
} nameof(model.ClientFIO));
if (string.IsNullOrEmpty(model.Password)) }
{ if (string.IsNullOrEmpty(model.Password))
throw new ArgumentNullException("Нет пароля клиента", {
nameof(model.ClientFIO)); throw new ArgumentNullException("Нет пароля клиента",
} nameof(model.ClientFIO));
_logger.LogInformation("Client. ClientFIO:{ClientFIO}." + }
"Email:{ Email}. Password:{ Password}. Id: { Id} ", model.ClientFIO, model.Email, model.Password, model.Id); if (!Regex.IsMatch(model.Email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))
var element = _clientStorage.GetElement(new ClientSearchModel {
{ throw new ArgumentException("Некорретно введен email клиента", nameof(model.Email));
Email = model.Email, }
}); if (!Regex.IsMatch(model.Password, @"^(?=.*\d)(?=.*\W)(?=.*[^\d\s]).+$"))
if (element != null && element.Id != model.Id) {
{ throw new ArgumentException("Некорректно введен пароль клиента", nameof(model.Password));
throw new InvalidOperationException("Клиент с таким лоигном уже есть"); }
} _logger.LogInformation("Client. ClientFIO:{ClientFIO}." +
} "Email:{ Email}. Password:{ Password}. Id: { Id} ", model.ClientFIO, model.Email, model.Password, model.Id);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.Email,
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Клиент с таким логином уже есть");
}
}
} }
} }

View File

@ -0,0 +1,46 @@
using Microsoft.Extensions.Logging;
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.BusinessLogicsContracts;
using RenovationWorkContracts.SearchModels;
using RenovationWorkContracts.StoragesContracts;
using RenovationWorkContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkBusinessLogic.BusinessLogics
{
public class MessageInfoLogic : IMessageInfoLogic
{
private readonly ILogger _logger;
private readonly IMessageInfoStorage _messageInfoStorage;
public MessageInfoLogic(ILogger<MessageInfoLogic> logger, IMessageInfoStorage MessageInfoStorage)
{
_logger = logger;
_messageInfoStorage = MessageInfoStorage;
}
public bool Create(MessageInfoBindingModel model)
{
if (_messageInfoStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{
_logger.LogInformation("ReadList. MessageId:{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;
}
}
}

View File

@ -10,6 +10,7 @@ using RenovationWorkContracts.StoragesContracts;
using RenovationWorkContracts.ViewModels; using RenovationWorkContracts.ViewModels;
using RenovationWorkDataModels.Enums; using RenovationWorkDataModels.Enums;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using RenovationWorkBusinessLogic.MailWorker;
namespace RenovationWorkBusinessLogic.BusinessLogics namespace RenovationWorkBusinessLogic.BusinessLogics
{ {
@ -17,12 +18,17 @@ namespace RenovationWorkBusinessLogic.BusinessLogics
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage; private readonly IOrderStorage _orderStorage;
static readonly object locker = new object(); private readonly AbstractMailWorker _mailWorker;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage) private readonly IClientLogic _clientLogic;
{ static readonly object locker = new object();
_logger = logger; public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage,
AbstractMailWorker mailWorker, IClientLogic clientLogic)
{
_orderStorage = orderStorage; _orderStorage = orderStorage;
} _logger = logger;
_mailWorker = mailWorker;
_clientLogic = clientLogic;
}
public bool CreateOrder(OrderBindingModel model) public bool CreateOrder(OrderBindingModel model)
{ {
CheckModel(model); CheckModel(model);
@ -31,16 +37,32 @@ namespace RenovationWorkBusinessLogic.BusinessLogics
_logger.LogWarning("Insert operation failed. Order status incorrect."); _logger.LogWarning("Insert operation failed. Order status incorrect.");
return false; return false;
} }
model.Status = OrderStatus.Принят; model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null) var res = _orderStorage.Insert(model);
{ if (res == null)
model.Status = OrderStatus.Неизвестен; {
_logger.LogWarning("Insert operation failed"); _logger.LogWarning("Insert operation failed");
return false; return false;
} }
return true; SendOrderStatusMail(res.ClientId, $"Изменен статус заказа #{res.Id}", $"Заказ #{res.Id} изменен статус на {model.Status}");
} return true;
public bool StatusUpdate(OrderBindingModel model, OrderStatus newStatus) }
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;
}
public bool StatusUpdate(OrderBindingModel model, OrderStatus newStatus)
{ {
CheckModel(model, false); CheckModel(model, false);
var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
@ -59,9 +81,15 @@ namespace RenovationWorkBusinessLogic.BusinessLogics
model.DateImplement = DateTime.Now; model.DateImplement = DateTime.Now;
if (element.ImplementerId.HasValue) if (element.ImplementerId.HasValue)
model.ImplementerId = element.ImplementerId; model.ImplementerId = element.ImplementerId;
_orderStorage.Update(model); var result = _orderStorage.Update(model);
return true; if (result == null)
} {
_logger.LogWarning("Update operation failed");
return false;
}
SendOrderStatusMail(result.ClientId, $"Изменен статус заказа #{result.Id}", $"Заказ #{result.Id} изменен статус на {result.Status}");
return true;
}
public bool DeliveryOrder(OrderBindingModel model) public bool DeliveryOrder(OrderBindingModel model)
{ {
return StatusUpdate(model, OrderStatus.Выдан); return StatusUpdate(model, OrderStatus.Выдан);

View File

@ -0,0 +1,83 @@
using Microsoft.Extensions.Logging;
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.BusinessLogicsContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkBusinessLogic.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,81 @@
using MailKit.Net.Pop3;
using MailKit.Security;
using Microsoft.Extensions.Logging;
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.BusinessLogicsContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkBusinessLogic.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> <ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" /> <PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" />
<PackageReference Include="MailKit" Version="4.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" /> <PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup> </ItemGroup>

View File

@ -13,8 +13,7 @@ namespace RenovationWorkClientApp
{ {
_client.BaseAddress = new Uri(configuration["IPAddress"]); _client.BaseAddress = new Uri(configuration["IPAddress"]);
_client.DefaultRequestHeaders.Accept.Clear(); _client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
MediaTypeWithQualityHeaderValue("application/json"));
} }
public static T? GetRequest<T>(string requestUrl) public static T? GetRequest<T>(string requestUrl)
{ {

View File

@ -125,8 +125,7 @@ namespace RenovationWorkClientApp.Controllers
{ {
throw new Exception("Количество и сумма должны быть\r\nбольше 0"); throw new Exception("Количество и сумма должны быть\r\nбольше 0");
} }
APIClient.PostRequest("api/main/createorder", new APIClient.PostRequest("api/main/createorder", new OrderBindingModel
OrderBindingModel
{ {
ClientId = APIClient.Client.Id, ClientId = APIClient.Client.Id,
RepairId = repair, RepairId = repair,
@ -141,5 +140,14 @@ namespace RenovationWorkClientApp.Controllers
var _repair = APIClient.GetRequest<RepairViewModel>($"api/main/getrepair?repairid={repair}"); var _repair = APIClient.GetRequest<RepairViewModel>($"api/main/getrepair?repairid={repair}");
return Math.Round(count * (_repair?.Price ?? 1), 2); return Math.Round(count * (_repair?.Price ?? 1), 2);
} }
} [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,49 @@
@using RenovationWorkContracts.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

@ -26,6 +26,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" asparea="" 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,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkContracts.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 RenovationWorkContracts.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,20 @@

using RenovationWorkDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkContracts.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 RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.SearchModels;
using RenovationWorkContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkContracts.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 RenovationWorkContracts.SearchModels
{
public class MessageInfoSearchModel
{
public int? ClientId { get; set; }
public string? MessageId { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.SearchModels;
using RenovationWorkContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkContracts.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 RenovationWorkDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkContracts.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

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

View File

@ -0,0 +1,53 @@
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.SearchModels;
using RenovationWorkContracts.StoragesContracts;
using RenovationWorkContracts.ViewModels;
using RenovationWorkDatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkDatabaseImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
using var context = new RenovationWorkDatabase();
if (model.MessageId != null)
{
return context.Messages.FirstOrDefault(x => x.MessageId == model.MessageId)?.GetViewModel;
}
return null;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
using var context = new RenovationWorkDatabase();
return context.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFullList()
{
using var context = new RenovationWorkDatabase();
return context.Messages
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
using var context = new RenovationWorkDatabase();
var newMessage = MessageInfo.Create(context, model);
if (newMessage == null || context.Messages.Any(x => x.MessageId.Equals(model.MessageId)))
{
return null;
}
context.Messages.Add(newMessage);
context.SaveChanges();
return newMessage.GetViewModel;
}
}
}

View File

@ -0,0 +1,296 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using RenovationWorkDatabaseImplement;
#nullable disable
namespace RenovationWorkDatabaseImplement_.Migrations
{
[DbContext(typeof(RenovationWorkDatabase))]
[Migration("20240516094211_InitialCreateMail")]
partial class InitialCreateMail
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.17")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("RenovationWorkDatabaseImplement.Component", 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>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.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("RenovationWorkDatabaseImplement.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("RenovationWorkDatabaseImplement.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("RenovationWorkDatabaseImplement.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>("RepairId")
.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("RepairId");
b.ToTable("Orders");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.Models.Repair", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("RepairName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Repairs");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.Models.RepairComponent", 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>("RepairId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("RepairId");
b.ToTable("RepairComponents");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.Models.MessageInfo", b =>
{
b.HasOne("RenovationWorkDatabaseImplement.Models.Client", "Client")
.WithMany()
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.Models.Order", b =>
{
b.HasOne("RenovationWorkDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("RenovationWorkDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("RenovationWorkDatabaseImplement.Models.Repair", "Repair")
.WithMany("Orders")
.HasForeignKey("RepairId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Repair");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.Models.RepairComponent", b =>
{
b.HasOne("RenovationWorkDatabaseImplement.Component", "Component")
.WithMany("RepairComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("RenovationWorkDatabaseImplement.Models.Repair", "Repair")
.WithMany("Components")
.HasForeignKey("RepairId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Repair");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.Component", b =>
{
b.Navigation("RepairComponents");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("RenovationWorkDatabaseImplement.Models.Repair", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,50 @@
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.ViewModels;
using RenovationWorkDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkDatabaseImplement.Models
{
public class MessageInfo : IMessageInfoModel
{
[Key]
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; } = DateTime.Now;
public string Subject { get; private set; } = string.Empty;
public string Body { get; private set; } = string.Empty;
public Client? Client { get; private set; }
public static MessageInfo? Create(RenovationWorkDatabase context, MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new()
{
Body = model.Body,
Subject = model.Subject,
ClientId = context.Clients.FirstOrDefault(x => x.Email == model.SenderName).Id,
Client = context.Clients.FirstOrDefault(x => x.Email == model.SenderName),
MessageId = model.MessageId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
};
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
Subject = Subject,
ClientId = ClientId,
MessageId = MessageId,
SenderName = SenderName,
DateDelivery = DateDelivery,
};
}
}

View File

@ -15,7 +15,7 @@ namespace RenovationWorkDatabaseImplement
{ {
if (!optionsBuilder.IsConfigured) if (!optionsBuilder.IsConfigured)
{ {
optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=RenovationWorkDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=RenovationWorkDatabase_7.1;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
} }
base.OnConfiguring(optionsBuilder); base.OnConfiguring(optionsBuilder);
} }
@ -25,5 +25,6 @@ namespace RenovationWorkDatabaseImplement
public virtual DbSet<Order> Orders { set; get; } public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Client> Clients { set; get; } public virtual DbSet<Client> Clients { set; get; }
public virtual DbSet<Implementer> Implementers { set; get; } public virtual DbSet<Implementer> Implementers { set; get; }
} public virtual DbSet<MessageInfo> Messages { set; get; }
}
} }

View File

@ -17,13 +17,15 @@ namespace RenovationWorkFileImplement
private readonly string RepairFileName = "Repair.xml"; private readonly string RepairFileName = "Repair.xml";
private readonly string ClientFileName = "Client.xml"; private readonly string ClientFileName = "Client.xml";
private readonly string ImplementerFileName = "Implementer.xml"; private readonly string ImplementerFileName = "Implementer.xml";
public List<Component> Components { get; private set; } private readonly string MessageInfoFileName = "MessageInfo.xml";
public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; } public List<Order> Orders { get; private set; }
public List<Repair> Repairs { get; private set; } public List<Repair> Repairs { 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> Messages { get; private set; }
public static DataFileSingleton GetInstance() public static DataFileSingleton GetInstance()
{ {
if (instance == null) if (instance == null)
{ {
@ -37,7 +39,8 @@ namespace RenovationWorkFileImplement
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement); public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName,"Implementers", x => x.GetXElement); public void SaveImplementers() => SaveData(Implementers, ImplementerFileName,"Implementers", x => x.GetXElement);
private DataFileSingleton() public void SaveMessages() => SaveData(Orders, ImplementerFileName,"Messages", x => x.GetXElement);
private DataFileSingleton()
{ {
Components = LoadData(ComponentFileName, "Component", x => Components = LoadData(ComponentFileName, "Component", x =>
Component.Create(x)!)!; Component.Create(x)!)!;
@ -49,7 +52,9 @@ namespace RenovationWorkFileImplement
Client.Create(x)!)!; Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementers = LoadData(ImplementerFileName, "Implementer", x =>
Implementer.Create(x)!)!; Implementer.Create(x)!)!;
} Messages = LoadData(MessageInfoFileName, "MessageInfo", x =>
MessageInfo.Create(x)!)!;
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction) private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction)
{ {
if (File.Exists(filename)) if (File.Exists(filename))

View File

@ -0,0 +1,55 @@
using RenovationWorkFileImplement;
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.SearchModels;
using RenovationWorkContracts.StoragesContracts;
using RenovationWorkContracts.ViewModels;
using RenovationWorkFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkFileImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataFileSingleton _source;
public MessageInfoStorage()
{
_source = DataFileSingleton.GetInstance();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (model.MessageId != null)
{
return _source.Messages.FirstOrDefault(x => x.MessageId == model.MessageId)?.GetViewModel;
}
return null;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
return _source.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFullList()
{
return _source.Messages
.Select(x => x.GetViewModel)
.ToList();
}
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

@ -0,0 +1,71 @@
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.ViewModels;
using RenovationWorkDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace RenovationWorkFileImplement.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; } = DateTime.Now;
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()
{
Body = model.Body,
Subject = model.Subject,
ClientId = model.ClientId,
MessageId = model.MessageId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
};
}
public static MessageInfo? Create(XElement element)
{
if (element == null)
{
return null;
}
return new()
{
Body = element.Attribute("Body")!.Value,
Subject = element.Attribute("Subject")!.Value,
ClientId = Convert.ToInt32(element.Attribute("ClientId")!.Value),
MessageId = element.Attribute("MessageId")!.Value,
SenderName = element.Attribute("SenderName")!.Value,
DateDelivery = Convert.ToDateTime(element.Attribute("DateDelivery")!.Value),
};
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
Subject = Subject,
ClientId = ClientId,
MessageId = MessageId,
SenderName = SenderName,
DateDelivery = DateDelivery,
};
public XElement GetXElement => new("MessageInfo",
new XAttribute("Body", Body),
new XAttribute("Subject", Subject),
new XAttribute("ClientId", ClientId ?? 0),
new XAttribute("MessageId", MessageId),
new XAttribute("SenderName", SenderName),
new XAttribute("DateDelivery", DateDelivery)
);
}
}

View File

@ -15,14 +15,16 @@ namespace RenovationWorkListImplement
public List<Repair> Repairs { get; set; } public List<Repair> Repairs { 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; }
private DataListSingleton() public List<MessageInfo> Messages { get; set; }
private DataListSingleton()
{ {
Components = new List<Component>(); Components = new List<Component>();
Orders = new List<Order>(); Orders = new List<Order>();
Repairs = new List<Repair>(); Repairs = new List<Repair>();
Clients = new List<Client>(); Clients = new List<Client>();
Implementers = new List<Implementer>(); Implementers = new List<Implementer>();
} Messages = new List<MessageInfo>();
}
public static DataListSingleton GetInstance() public static DataListSingleton GetInstance()
{ {
if (_instance == null) if (_instance == null)

View File

@ -0,0 +1,62 @@
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.SearchModels;
using RenovationWorkContracts.StoragesContracts;
using RenovationWorkContracts.ViewModels;
using RenovationWorkListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkListImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataListSingleton _source;
public MessageInfoStorage()
{
_source = DataListSingleton.GetInstance();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
foreach (var message in _source.Messages)
{
if (model.MessageId != null && model.MessageId.Equals(message.MessageId))
return message.GetViewModel;
}
return null;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
List<MessageInfoViewModel> result = new();
foreach (var item in _source.Messages)
{
if (item.ClientId.HasValue && item.ClientId == model.ClientId)
{
result.Add(item.GetViewModel);
}
}
return result;
}
public List<MessageInfoViewModel> GetFullList()
{
List<MessageInfoViewModel> result = new();
foreach (var item in _source.Messages)
{
result.Add(item.GetViewModel);
}
return result;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = MessageInfo.Create(model);
if (newMessage == null)
{
return null;
}
_source.Messages.Add(newMessage);
return newMessage.GetViewModel;
}
}
}

View File

@ -0,0 +1,46 @@
using RenovationWorkContracts.BindingModels;
using RenovationWorkContracts.ViewModels;
using RenovationWorkDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RenovationWorkListImplement.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; } = DateTime.Now;
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()
{
Body = model.Body,
Subject = model.Subject,
ClientId = model.ClientId,
MessageId = model.MessageId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
};
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
Subject = Subject,
ClientId = ClientId,
MessageId = MessageId,
SenderName = SenderName,
DateDelivery = DateDelivery,
};
}
}

View File

@ -11,12 +11,15 @@ namespace RenovationWorkRestApi.Controllers
public class ClientController : Controller public class ClientController : Controller
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IClientLogic _logic; private readonly IClientLogic _logic;
public ClientController(IClientLogic logic, ILogger<ClientController> logger) private readonly IMessageInfoLogic _mailLogic;
{ public ClientController(IClientLogic logic, IMessageInfoLogic mailLogic,
ILogger<ClientController> logger)
{
_logger = logger; _logger = logger;
_logic = logic; _logic = logic;
} _mailLogic = mailLogic;
}
[HttpGet] [HttpGet]
public ClientViewModel? Login(string login, string password) public ClientViewModel? Login(string login, string password)
{ {
@ -47,7 +50,20 @@ namespace RenovationWorkRestApi.Controllers
throw; throw;
} }
} }
[HttpPost] [HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientId)
{
try
{
return _mailLogic.ReadList(new MessageInfoSearchModel{ ClientId = clientId });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения писем клиента");
throw;
}
}
[HttpPost]
public void UpdateData(ClientBindingModel model) public void UpdateData(ClientBindingModel model)
{ {
try try

View File

@ -3,6 +3,9 @@ using RenovationWorkContracts.BusinessLogicsContracts;
using RenovationWorkContracts.StoragesContracts; using RenovationWorkContracts.StoragesContracts;
using RenovationWorkDatabaseImplement.Implements; using RenovationWorkDatabaseImplement.Implements;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using RenovationWorkBusinessLogic.MailWorker;
using RenovationWorkContracts.BindingModels;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Trace); builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddLog4Net("log4net.config"); builder.Logging.AddLog4Net("log4net.config");
@ -10,9 +13,14 @@ builder.Logging.AddLog4Net("log4net.config");
builder.Services.AddTransient<IClientStorage, ClientStorage>(); builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>(); builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IRepairStorage, RepairStorage>(); builder.Services.AddTransient<IRepairStorage, RepairStorage>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>(); builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IRepairLogic, RepairLogic>(); builder.Services.AddTransient<IRepairLogic, RepairLogic>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at // Learn more about configuring Swagger/OpenAPI at
//https://aka.ms/aspnetcore/swashbuckle //https://aka.ms/aspnetcore/swashbuckle
@ -27,6 +35,18 @@ builder.Services.AddSwaggerGen(c =>
}); });
}); });
var app = builder.Build(); var app = builder.Build();
var mailSender = app.Services.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
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())
{ {

View File

@ -5,5 +5,11 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
} "SmtpClientHost": "smtp.gmail.com",
"SmtpClientPort": "587",
"PopHost": "pop.gmail.com",
"PopPort": "995",
"MailLogin": "lab767676@gmail.com",
"MailPassword": "hcrp rdjx dihb ilrs"
}