This commit is contained in:
kirinzx 2024-05-14 11:30:42 +04:00
parent aa0971caf0
commit 26e35b8faa
67 changed files with 2890 additions and 1488 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="dyakonov.rr@gmail.com" />
<add key="MailPassword" value="asnb zmlr chgf ewmg" />
</appSettings>
</configuration>

View File

@ -0,0 +1,62 @@
namespace FurnitureAssembly
{
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()
{
this.dataGridViewMail = new System.Windows.Forms.DataGridView();
((System.ComponentModel.ISupportInitialize)(this.dataGridViewMail)).BeginInit();
this.SuspendLayout();
//
// dataGridViewMail
//
this.dataGridViewMail.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridViewMail.Location = new System.Drawing.Point(0, 0);
this.dataGridViewMail.Name = "dataGridViewMail";
this.dataGridViewMail.RowTemplate.Height = 25;
this.dataGridViewMail.Size = new System.Drawing.Size(801, 449);
this.dataGridViewMail.TabIndex = 0;
//
// FormMail
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.dataGridViewMail);
this.Name = "FormMail";
this.Text = "Письма";
this.Load += new System.EventHandler(this.FormMail_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridViewMail)).EndInit();
this.ResumeLayout(false);
}
#endregion
private DataGridView dataGridViewMail;
}
}

View File

@ -0,0 +1,41 @@
using FurnitureAssemblyContracts.BusinessLogicsContarcts;
using Microsoft.Extensions.Logging;
using System.Windows.Forms;
namespace FurnitureAssembly
{
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)
{
dataGridViewMail.DataSource = list;
dataGridViewMail.Columns["ClientId"].Visible = false;
dataGridViewMail.Columns["MessageId"].Visible = false;
dataGridViewMail.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

@ -9,6 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MailKit" Version="4.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0-preview.3.23174.2"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0-preview.3.23174.2">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@ -19,11 +19,11 @@ namespace FurnitureAssemblyView
public partial class FurnitureForm : Form public partial class FurnitureForm : Form
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IfurnitureLogic _logic; private readonly IFurnitureLogic _logic;
private int? _id; private int? _id;
private Dictionary<int, (IComponentModel, int)> _furnitureComponents; private Dictionary<int, (IComponentModel, int)> _furnitureComponents;
public int Id { set { _id = value; } } public int Id { set { _id = value; } }
public FurnitureForm(ILogger<FurnitureForm> logger, IfurnitureLogic logic) public FurnitureForm(ILogger<FurnitureForm> logger, IFurnitureLogic logic)
{ {
InitializeComponent(); InitializeComponent();
_logger = logger; _logger = logger;

View File

@ -18,9 +18,9 @@ namespace FurnitureAssemblyView
public partial class FurnituresForm : Form public partial class FurnituresForm : Form
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IfurnitureLogic _logic; private readonly IFurnitureLogic _logic;
public FurnituresForm(ILogger<FurnituresForm> logger, IfurnitureLogic logic) public FurnituresForm(ILogger<FurnituresForm> logger, IFurnitureLogic logic)
{ {
InitializeComponent(); InitializeComponent();
_logger = logger; _logger = logger;

View File

@ -45,10 +45,18 @@
this.FurnituresComponentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.FurnituresComponentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.списокЗаказовToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.списокЗаказовToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.запускРаботToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.запускРаботToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mailToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
buttonReady = new System.Windows.Forms.Button(); buttonReady = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
this.menuStrip.SuspendLayout(); this.menuStrip.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// mailToolStripMenuItem
//
this.mailToolStripMenuItem.Name = "mailToolStripMenuItem";
this.mailToolStripMenuItem.Size = new System.Drawing.Size(62, 20);
this.mailToolStripMenuItem.Text = "Письма";
this.mailToolStripMenuItem.Click += new System.EventHandler(this.mailToolStripMenuItem_Click);
//
// //
// buttonReady // buttonReady
// //
@ -122,7 +130,8 @@
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.справочникиToolStripMenuItem, this.справочникиToolStripMenuItem,
this.отчетыToolStripMenuItem, this.отчетыToolStripMenuItem,
this.запускРаботToolStripMenuItem}); this.запускРаботToolStripMenuItem,
this.mailToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0); this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip"; this.menuStrip.Name = "menuStrip";
this.menuStrip.Padding = new System.Windows.Forms.Padding(4, 1, 0, 1); this.menuStrip.Padding = new System.Windows.Forms.Padding(4, 1, 0, 1);
@ -250,5 +259,6 @@
private ToolStripMenuItem клиентыToolStripMenuItem; private ToolStripMenuItem клиентыToolStripMenuItem;
private ToolStripMenuItem исполнителиToolStripMenuItem; private ToolStripMenuItem исполнителиToolStripMenuItem;
private ToolStripMenuItem запускРаботToolStripMenuItem; private ToolStripMenuItem запускРаботToolStripMenuItem;
private ToolStripMenuItem mailToolStripMenuItem;
} }
} }

View File

@ -258,5 +258,13 @@ namespace FurnitureAssemblyView
Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!,
_orderLogic); _orderLogic);
} }
private void mailToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormMail));
if (service is FormMail form)
{
form.ShowDialog();
}
}
} }
} }

View File

@ -28,137 +28,106 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
comboBoxFurniture = new ComboBox(); this.comboBoxFurniture = new System.Windows.Forms.ComboBox();
labelFurniture = new Label(); this.labelFurniture = new System.Windows.Forms.Label();
labelCount = new Label(); this.labelCount = new System.Windows.Forms.Label();
labelSum = new Label(); this.labelSum = new System.Windows.Forms.Label();
textBoxCount = new TextBox(); this.textBoxCount = new System.Windows.Forms.TextBox();
textBoxSum = new TextBox(); this.textBoxSum = new System.Windows.Forms.TextBox();
buttonSave = new Button(); this.buttonSave = new System.Windows.Forms.Button();
buttonCancel = new Button(); this.buttonCancel = new System.Windows.Forms.Button();
clientLabel = new Label(); this.SuspendLayout();
clientBox = new ComboBox();
SuspendLayout();
// //
// comboBoxFurniture // comboBoxFurniture
// //
comboBoxFurniture.FormattingEnabled = true; this.comboBoxFurniture.FormattingEnabled = true;
comboBoxFurniture.Location = new Point(92, 11); this.comboBoxFurniture.Location = new System.Drawing.Point(115, 14);
comboBoxFurniture.Margin = new Padding(2); this.comboBoxFurniture.Name = "comboBoxFurniture";
comboBoxFurniture.Name = "comboBoxFurniture"; this.comboBoxFurniture.Size = new System.Drawing.Size(250, 33);
comboBoxFurniture.Size = new Size(201, 28); this.comboBoxFurniture.TabIndex = 0;
comboBoxFurniture.TabIndex = 0;
// //
// labelFurniture // labelFurniture
// //
labelFurniture.AutoSize = true; this.labelFurniture.AutoSize = true;
labelFurniture.Location = new Point(10, 18); this.labelFurniture.Location = new System.Drawing.Point(12, 22);
labelFurniture.Margin = new Padding(2, 0, 2, 0); this.labelFurniture.Name = "labelFurniture";
labelFurniture.Name = "labelFurniture"; this.labelFurniture.Size = new System.Drawing.Size(80, 25);
labelFurniture.Size = new Size(68, 20); this.labelFurniture.TabIndex = 1;
labelFurniture.TabIndex = 1; this.labelFurniture.Text = "Изделие";
labelFurniture.Text = "Изделие";
// //
// labelCount // labelCount
// //
labelCount.AutoSize = true; this.labelCount.AutoSize = true;
labelCount.Location = new Point(10, 54); this.labelCount.Location = new System.Drawing.Point(12, 67);
labelCount.Margin = new Padding(2, 0, 2, 0); this.labelCount.Name = "labelCount";
labelCount.Name = "labelCount"; this.labelCount.Size = new System.Drawing.Size(107, 25);
labelCount.Size = new Size(90, 20); this.labelCount.TabIndex = 2;
labelCount.TabIndex = 2; this.labelCount.Text = "Количество";
labelCount.Text = "Количество";
// //
// labelSum // labelSum
// //
labelSum.AutoSize = true; this.labelSum.AutoSize = true;
labelSum.Location = new Point(10, 94); this.labelSum.Location = new System.Drawing.Point(12, 118);
labelSum.Margin = new Padding(2, 0, 2, 0); this.labelSum.Name = "labelSum";
labelSum.Name = "labelSum"; this.labelSum.Size = new System.Drawing.Size(67, 25);
labelSum.Size = new Size(55, 20); this.labelSum.TabIndex = 3;
labelSum.TabIndex = 3; this.labelSum.Text = "Сумма";
labelSum.Text = "Сумма";
// //
// textBoxCount // textBoxCount
// //
textBoxCount.Location = new Point(92, 51); this.textBoxCount.Location = new System.Drawing.Point(115, 64);
textBoxCount.Margin = new Padding(2); this.textBoxCount.Name = "textBoxCount";
textBoxCount.Name = "textBoxCount"; this.textBoxCount.Size = new System.Drawing.Size(250, 31);
textBoxCount.Size = new Size(201, 27); this.textBoxCount.TabIndex = 4;
textBoxCount.TabIndex = 4; this.textBoxCount.TextChanged += new System.EventHandler(this.textBoxCount_TextChanged);
textBoxCount.TextChanged += textBoxCount_TextChanged;
// //
// textBoxSum // textBoxSum
// //
textBoxSum.Location = new Point(92, 92); this.textBoxSum.Location = new System.Drawing.Point(115, 115);
textBoxSum.Margin = new Padding(2); this.textBoxSum.Name = "textBoxSum";
textBoxSum.Name = "textBoxSum"; this.textBoxSum.ReadOnly = true;
textBoxSum.ReadOnly = true; this.textBoxSum.Size = new System.Drawing.Size(250, 31);
textBoxSum.Size = new Size(201, 27); this.textBoxSum.TabIndex = 5;
textBoxSum.TabIndex = 5;
// //
// buttonSave // buttonSave
// //
buttonSave.Location = new Point(26, 163); this.buttonSave.Location = new System.Drawing.Point(31, 161);
buttonSave.Margin = new Padding(2); this.buttonSave.Name = "buttonSave";
buttonSave.Name = "buttonSave"; this.buttonSave.Size = new System.Drawing.Size(112, 34);
buttonSave.Size = new Size(90, 27); this.buttonSave.TabIndex = 6;
buttonSave.TabIndex = 6; this.buttonSave.Text = "Сохранить";
buttonSave.Text = "Сохранить"; this.buttonSave.UseVisualStyleBackColor = true;
buttonSave.UseVisualStyleBackColor = true; this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click);
buttonSave.Click += buttonSave_Click;
// //
// buttonCancel // buttonCancel
// //
buttonCancel.Location = new Point(203, 163); this.buttonCancel.Location = new System.Drawing.Point(253, 161);
buttonCancel.Margin = new Padding(2); this.buttonCancel.Name = "buttonCancel";
buttonCancel.Name = "buttonCancel"; this.buttonCancel.Size = new System.Drawing.Size(112, 34);
buttonCancel.Size = new Size(90, 27); this.buttonCancel.TabIndex = 7;
buttonCancel.TabIndex = 7; this.buttonCancel.Text = "Отмена";
buttonCancel.Text = "Отмена"; this.buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.UseVisualStyleBackColor = true; this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
buttonCancel.Click += buttonCancel_Click;
//
// clientLabel
//
clientLabel.AutoSize = true;
clientLabel.Location = new Point(17, 131);
clientLabel.Name = "clientLabel";
clientLabel.RightToLeft = RightToLeft.No;
clientLabel.Size = new Size(58, 20);
clientLabel.TabIndex = 9;
clientLabel.Text = "Клиент";
//
// clientBox
//
clientBox.FormattingEnabled = true;
clientBox.Location = new Point(92, 128);
clientBox.Margin = new Padding(2);
clientBox.Name = "clientBox";
clientBox.Size = new Size(201, 28);
clientBox.TabIndex = 10;
// //
// OrderForm // OrderForm
// //
AutoScaleDimensions = new SizeF(8F, 20F); this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
AutoScaleMode = AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
ClientSize = new Size(304, 201); this.ClientSize = new System.Drawing.Size(401, 207);
Controls.Add(clientBox); this.Controls.Add(this.buttonCancel);
Controls.Add(clientLabel); this.Controls.Add(this.buttonSave);
Controls.Add(buttonCancel); this.Controls.Add(this.textBoxSum);
Controls.Add(buttonSave); this.Controls.Add(this.textBoxCount);
Controls.Add(textBoxSum); this.Controls.Add(this.labelSum);
Controls.Add(textBoxCount); this.Controls.Add(this.labelCount);
Controls.Add(labelSum); this.Controls.Add(this.labelFurniture);
Controls.Add(labelCount); this.Controls.Add(this.comboBoxFurniture);
Controls.Add(labelFurniture); this.Name = "OrderForm";
Controls.Add(comboBoxFurniture); this.Text = "Заказ";
Margin = new Padding(2); this.Load += new System.EventHandler(this.OrderForm_Load);
Name = "OrderForm"; this.ResumeLayout(false);
Text = "Заказ"; this.PerformLayout();
Load += OrderForm_Load;
ResumeLayout(false);
PerformLayout();
} }
#endregion #endregion
@ -171,7 +140,5 @@
private TextBox textBoxSum; private TextBox textBoxSum;
private Button buttonSave; private Button buttonSave;
private Button buttonCancel; private Button buttonCancel;
private Label clientLabel;
private ComboBox clientBox;
} }
} }

View File

@ -17,16 +17,14 @@ namespace FurnitureAssemblyView
public partial class OrderForm : Form public partial class OrderForm : Form
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IfurnitureLogic _logicP; private readonly IFurnitureLogic _logicP;
private readonly IOrderLogic _logicO; private readonly IOrderLogic _logicO;
private readonly IClientLogic _logicC; public OrderForm(ILogger<OrderForm> logger, IFurnitureLogic logicP, IOrderLogic logicO)
public OrderForm(ILogger<OrderForm> logger, IfurnitureLogic logicP, IOrderLogic logicO, IClientLogic logicC)
{ {
InitializeComponent(); InitializeComponent();
_logger = logger; _logger = logger;
_logicP = logicP; _logicP = logicP;
_logicO = logicO; _logicO = logicO;
_logicC = logicC;
} }
private void OrderForm_Load(object sender, EventArgs e) private void OrderForm_Load(object sender, EventArgs e)
@ -49,23 +47,6 @@ namespace FurnitureAssemblyView
_logger.LogError(ex, "Ошибка загрузки списка изделий"); _logger.LogError(ex, "Ошибка загрузки списка изделий");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
_logger.LogInformation("Загрузка клиентов для заказа");
try
{
var clientList = _logicC.ReadList(null);
if (clientList != null)
{
clientBox.DisplayMember = "Client";
clientBox.ValueMember = "Id";
clientBox.DataSource = clientList.Select(c => c.ClientFIO).ToList();
clientBox.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка клиентов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
} }
private void CalcSum() private void CalcSum()
{ {
@ -121,8 +102,7 @@ namespace FurnitureAssemblyView
{ {
FurnitureId = Convert.ToInt32(comboBoxFurniture.SelectedIndex)+1, FurnitureId = Convert.ToInt32(comboBoxFurniture.SelectedIndex)+1,
Count = Convert.ToInt32(textBoxCount.Text), Count = Convert.ToInt32(textBoxCount.Text),
Sum = Convert.ToDouble(textBoxSum.Text), Sum = Convert.ToDouble(textBoxSum.Text)
ClientId = Convert.ToInt32(clientBox.SelectedIndex) + 1
}); });
if (!operationResult) if (!operationResult)
{ {

View File

@ -1,64 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <root>
<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: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:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">

View File

@ -1,14 +1,17 @@
using FurnitureAssemblyBusinessLogic;
using FurnitureAssemblyBusinessLogic.OfficePackage.Implements;
using FurnitureAssemblyBusinessLogic.OfficePackage;
using FurnitureAssemblyContracts.BusinessLogicsContarcts;
using FurnitureAssemblyContracts.StoragesContracts; using FurnitureAssemblyContracts.StoragesContracts;
using Microsoft.Extensions.DependencyInjection;
using FurnitureAssemblyDatabaseImplement.Implements; using FurnitureAssemblyDatabaseImplement.Implements;
using FurnitureAssemblyBusinessLogic.BusinessLogics; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using FurnitureAssemblyBusinessLogic.MailWorker;
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts; using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyBusinessLogic.BusinessLogics; using FurnitureAssemblyBusinessLogic.BusinessLogics;
using NLog.Extensions.Logging;
using FurnitureAssemblyView; using FurnitureAssemblyView;
using Microsoft.Extensions.Logging;
using FurnitureAssemblyBusinessLogic.OfficePackage;
using FurnitureAssemblyBusinessLogic.OfficePackage.Implements;
namespace FurnitureAssembly namespace FurnitureAssembly
{ {
@ -22,12 +25,45 @@ namespace FurnitureAssembly
[STAThread] [STAThread]
static void Main() static void Main()
{ {
// To customize application configuration such as set high DPI settings or default font,
// 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<MainForm>()); 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<MainForm>());
}
private static void ConfigureServices(ServiceCollection services) private static void ConfigureServices(ServiceCollection services)
{ {
services.AddLogging(option => services.AddLogging(option =>
@ -39,34 +75,39 @@ namespace FurnitureAssembly
services.AddTransient<IOrderStorage, OrderStorage>(); services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IFurnitureStorage, FurnitureStorage>(); services.AddTransient<IFurnitureStorage, FurnitureStorage>();
services.AddTransient<IClientStorage, ClientStorage>(); 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<IOrderLogic, OrderLogic>();
services.AddTransient<IfurnitureLogic, FurnitureLogic>(); services.AddTransient<IFurnitureLogic, FurnitureLogic>();
services.AddTransient<IReportLogic, ReportLogic>(); services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IClientLogic, ClientLogic>(); services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<IImplementerLogic, ImplementerLogic>(); services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IWorkProcess, WorkModeling>(); services.AddTransient<IWorkProcess, WorkModeling>();
services.AddTransient<MainForm>(); services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
services.AddTransient<ComponentForm>();
services.AddTransient<ComponentsForm>();
services.AddTransient<OrderForm>();
services.AddTransient<FurnitureForm>();
services.AddTransient<FurnituresForm>();
services.AddTransient<FurnitureComponentForm>();
services.AddTransient<ClientsForm>();
services.AddTransient<ReportFurnitureComponentsForm>(); services.AddSingleton<AbstractMailWorker, MailKitWorker>();
services.AddTransient<ReportOrdersForm>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>(); services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>(); services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToPdf, SaveToPdf>(); services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
services.AddTransient<MainForm>();
services.AddTransient<ComponentForm>();
services.AddTransient<ComponentsForm>();
services.AddTransient<OrderForm>();
services.AddTransient<FurnitureForm>();
services.AddTransient<FurnitureComponentForm>();
services.AddTransient<FurnituresForm>();
services.AddTransient<ReportFurnitureComponentsForm>();
services.AddTransient<ReportOrdersForm>();
services.AddTransient<ClientsForm>();
services.AddTransient<ImplementersForm>(); services.AddTransient<ImplementersForm>();
services.AddTransient<ImplementerForm>(); services.AddTransient<ImplementerForm>();
services.AddTransient<FormMail>();
} }
private static void MailCheck(object obj) => ServiceProvider?.GetService<AbstractMailWorker>()?.MailCheck();
} }
} }

View File

@ -8,6 +8,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.BusinessLogics namespace FurnitureAssemblyBusinessLogic.BusinessLogics
@ -112,6 +113,14 @@ namespace FurnitureAssemblyBusinessLogic.BusinessLogics
throw new ArgumentNullException("Нет пароля пользователя", throw new ArgumentNullException("Нет пароля пользователя",
nameof(model.Password)); nameof(model.Password));
} }
if (!Regex.IsMatch(model.Email, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,})+)$"))
{
throw new ArgumentException("Некорректно введена почта клиента", nameof(model.Email));
}
if (!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 ArgumentException("Некорректно введен пароль клиента", nameof(model.Password));
}
_logger.LogInformation("Component. ClientFIO:{ClientFIO}. Email:{ Email}. Id: { Id}", model.ClientFIO, model.Email, model.Id); _logger.LogInformation("Component. ClientFIO:{ClientFIO}. Email:{ Email}. Id: { Id}", model.ClientFIO, model.Email, model.Id);
var element = _clientStorage.GetElement(new ClientSearchModel { Email = model.Email }); var element = _clientStorage.GetElement(new ClientSearchModel { Email = model.Email });
if (element != null && element.Id != model.Id) if (element != null && element.Id != model.Id)

View File

@ -12,7 +12,7 @@ using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.BusinessLogics namespace FurnitureAssemblyBusinessLogic.BusinessLogics
{ {
public class FurnitureLogic: IfurnitureLogic public class FurnitureLogic: IFurnitureLogic
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IFurnitureStorage _FurnitureStorage; private readonly IFurnitureStorage _FurnitureStorage;

View File

@ -0,0 +1,88 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContarcts;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace FurnitureAssemblyBusinessLogic
{
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 bool Create(MessageInfoBindingModel model)
{
CheckModel(model);
if (_messageInfoStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{
_logger.LogInformation("ReadList. ClientId:{ClientId}. MessageId:{ MessageId}", model?.ClientId, model?.MessageId);
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;
}
private void CheckModel(MessageInfoBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.MessageId))
{
throw new ArgumentNullException("Не указан id сообщения", nameof(model.MessageId));
}
if (string.IsNullOrEmpty(model.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.Subject));
}
_logger.LogInformation("MessageInfo. MessageId:{MessageId}.SenderName:{SenderName}.Subject:{Subject}.Body:{Body}", model.MessageId, model.SenderName, model.Subject, model.Body);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.SenderName
});
if (element == null)
{
_logger.LogWarning("Не удалоссь найти клиента, отправившего письмо с адреса Email:{Email}", model.SenderName);
}
else
{
model.ClientId = element.Id;
}
}
}
}

View File

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FurnitureAssemblyBusinessLogic.MailWorker;
namespace FurnitureAssemblyBusinessLogic.BusinessLogics namespace FurnitureAssemblyBusinessLogic.BusinessLogics
{ {
@ -17,10 +18,14 @@ namespace FurnitureAssemblyBusinessLogic.BusinessLogics
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage; private readonly IOrderStorage _orderStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage) private readonly AbstractMailWorker _mailWorker;
private readonly IClientLogic _clientLogic;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IClientLogic clientLogic, AbstractMailWorker abstractMailWorker)
{ {
_logger = logger; _logger = logger;
_orderStorage = orderStorage; _orderStorage = orderStorage;
_clientLogic = clientLogic;
_mailWorker = abstractMailWorker;
} }
public bool CreateOrder(OrderBindingModel model) public bool CreateOrder(OrderBindingModel model)
@ -28,11 +33,13 @@ namespace FurnitureAssemblyBusinessLogic.BusinessLogics
CheckModel(model); CheckModel(model);
if (model.Status != OrderStatus.Неизвестен) return false; if (model.Status != OrderStatus.Неизвестен) return false;
model.Status = OrderStatus.Принят; model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null) var order = _orderStorage.Insert(model);
if (order == null)
{ {
_logger.LogWarning("Insert operation failed"); _logger.LogWarning("Insert operation failed");
return false; return false;
} }
SendMail(model.ClientId, $"Создание заказа {order.Id}", $"Заказ под номером {order.Id} создан {model.DateCreate}");
return true; return true;
} }
@ -77,11 +84,13 @@ namespace FurnitureAssemblyBusinessLogic.BusinessLogics
model.ImplementerId = viewModel.ImplementerId.Value; model.ImplementerId = viewModel.ImplementerId.Value;
} }
CheckModel(model, false); CheckModel(model, false);
if (_orderStorage.Update(model) == null) var order = _orderStorage.Update(model);
if (order == null)
{ {
_logger.LogWarning("Change status operation failed"); _logger.LogWarning("Change status operation failed");
return false; return false;
} }
SendMail(order.ClientId, $"Заказ №{order.Id}", $"Заказ №{order.Id} изменил статус на {order.Status}.");
return true; return true;
} }
@ -143,5 +152,21 @@ namespace FurnitureAssemblyBusinessLogic.BusinessLogics
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id); _logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element; return element;
} }
private bool SendMail(int clientId, string subject, string text)
{
var client = _clientLogic.ReadElement(new() { Id = clientId });
if (client == null)
{
_logger.LogWarning("Email sending failed. Client with id {Id} not found", clientId);
return false;
}
_mailWorker.MailSendAsync(new MailSendInfoBindingModel()
{
Subject = subject,
Text = text,
MailAddress = client.Email
});
return true;
}
} }
} }

View File

@ -60,7 +60,6 @@ namespace FurnitureAssemblyBusinessLogic.BusinessLogics
{ {
return; return;
} }
await RunOrderInWork(implementer);
await Task.Run(() => await Task.Run(() =>
{ {
@ -68,6 +67,7 @@ namespace FurnitureAssemblyBusinessLogic.BusinessLogics
{ {
try try
{ {
RunOrderInWork(implementer);
_logger.LogDebug("DoWork. Worker {Id} try get order { Order}", implementer.Id, order.Id); _logger.LogDebug("DoWork. Worker {Id} try get order { Order}", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя // пытаемся назначить заказ на исполнителя
_orderLogic.TakeOrderInWork(new OrderBindingModel _orderLogic.TakeOrderInWork(new OrderBindingModel

View File

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

View File

@ -0,0 +1,81 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContarcts;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
namespace FurnitureAssemblyBusinessLogic.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;
private readonly IClientLogic _clientLogic;
public AbstractMailWorker(ILogger<AbstractMailWorker> logger,
IMessageInfoLogic messageInfoLogic,
IClientLogic clientLogic)
{
_logger = logger;
_messageInfoLogic = messageInfoLogic;
_clientLogic = clientLogic;
}
public void MailConfig(MailConfigBindingModel config)
{
_mailLogin = config.MailLogin;
_mailPassword = config.MailPassword;
_smtpClientHost = config.SmtpClientHost;
_smtpClientPort = config.SmtpClientPort;
_popHost = config.PopHost;
_popPort = config.PopPort;
_logger.LogDebug("Config: {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 FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContarcts;
using Microsoft.Extensions.Logging;
using System.Net.Mail;
using System.Net;
using System.Text;
using MailKit.Net.Pop3;
using MailKit.Security;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
namespace FurnitureAssemblyBusinessLogic.MailWorker
{
public class MailKitWorker : AbstractMailWorker
{
public MailKitWorker(ILogger<MailKitWorker> logger, IMessageInfoLogic messageInfoLogic, IClientLogic clientLogic)
: base(logger, messageInfoLogic, clientLogic) { }
protected override async Task SendMailAsync(MailSendInfoBindingModel info)
{
using var objMailMessage = new MailMessage();
using var objSmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort);
try
{
objMailMessage.From = new MailAddress(_mailLogin);
objMailMessage.To.Add(new MailAddress(info.MailAddress));
objMailMessage.Subject = info.Subject;
objMailMessage.Body = info.Text;
objMailMessage.SubjectEncoding = Encoding.UTF8;
objMailMessage.BodyEncoding = Encoding.UTF8;
objSmtpClient.UseDefaultCredentials = false;
objSmtpClient.EnableSsl = true;
objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword);
await Task.Run(() => objSmtpClient.Send(objMailMessage));
}
catch (Exception)
{
throw;
}
}
protected override async Task<List<MessageInfoBindingModel>> ReceiveMailAsync()
{
var list = new List<MessageInfoBindingModel>();
using var client = new Pop3Client();
await Task.Run(() =>
{
try
{
client.Connect(_popHost, _popPort, SecureSocketOptions.SslOnConnect);
client.Authenticate(_mailLogin, _mailPassword);
for (int i = 0; i < client.Count; i++)
{
var message = client.GetMessage(i);
foreach (var mail in message.From.Mailboxes)
{
list.Add(new MessageInfoBindingModel
{
DateDelivery = message.Date.DateTime,
MessageId = message.MessageId,
SenderName = mail.Address,
Subject = message.Subject,
Body = message.TextBody
});
}
}
}
catch (AuthenticationException)
{ }
finally
{
client.Disconnect(true);
}
});
return list;
}
}
}

View File

@ -145,5 +145,15 @@ namespace FurnitureAssemblyClientApp.Controllers
); );
return count * (prod?.Price ?? 1); 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

@ -7,6 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MailKit" Version="4.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup> </ItemGroup>
@ -14,4 +15,6 @@
<ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" /> <ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" />
</ItemGroup> </ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
</Project> </Project>

View File

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

View File

@ -27,6 +27,9 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a> <a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li> </li>
<li class="nav-item">
<a class="nav-link text-dark" 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,13 @@
namespace FurnitureAssemblyContracts.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,9 @@
namespace FurnitureAssemblyContracts.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 FurnitureAssemblyDataModels.Models;
namespace FurnitureAssemblyContracts.BindingModels
{
public class MessageInfoBindingModel : IMessageInfoModel
{
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
public string SenderName { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
}
}

View File

@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.BusinessLogicsContracts namespace FurnitureAssemblyContracts.BusinessLogicsContracts
{ {
public interface IfurnitureLogic public interface IFurnitureLogic
{ {
List<FurnitureViewModel>? ReadList(FurnitureSearchModel? model); List<FurnitureViewModel>? ReadList(FurnitureSearchModel? model);
FurnitureViewModel? ReadElement(FurnitureSearchModel model); FurnitureViewModel? ReadElement(FurnitureSearchModel model);

View File

@ -0,0 +1,12 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.ViewModels;
namespace FurnitureAssemblyContracts.BusinessLogicsContarcts
{
public interface IMessageInfoLogic
{
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model);
bool Create(MessageInfoBindingModel model);
}
}

View File

@ -6,6 +6,10 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="MailKit" Version="4.0.0" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" /> <ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" />
<ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" /> <ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" />

View File

@ -0,0 +1,9 @@
namespace FurnitureAssemblyContracts.SearchModels
{
public class MessageInfoSearchModel
{
public int? ClientId { get; set; }
public string? MessageId { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.ViewModels;
namespace FurnitureAssemblyContracts.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,20 @@
using FurnitureAssemblyDataModels.Models;
using System.ComponentModel;
namespace FurnitureAssemblyContracts.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

@ -6,4 +6,8 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="MailKit" Version="4.0.0" />
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,12 @@
namespace FurnitureAssemblyDataModels.Models
{
public interface IMessageInfoModel
{
string MessageId { get; }
int? ClientId { get; }
string SenderName { get; }
DateTime DateDelivery { get; }
string Subject { get; }
string Body { get; }
}
}

View File

@ -24,5 +24,6 @@ namespace FurnitureAssemblyDatabaseImplement
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

@ -7,6 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MailKit" Version="4.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0-preview.3.23174.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0-preview.3.23174.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0-preview.3.23174.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0-preview.3.23174.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0-preview.3.23174.2"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0-preview.3.23174.2">

View File

@ -28,17 +28,27 @@ namespace FurnitureAssemblyDatabaseImplement.Implements
public ClientViewModel? GetElement(ClientSearchModel model) public ClientViewModel? GetElement(ClientSearchModel model)
{ {
if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue && string.IsNullOrEmpty(model.Password))
{ {
return null; return null;
} }
using var context = new FurnitureAssemblyDatabase(); using var context = new FurnitureAssemblyDatabase();
if (model.Id.HasValue)
{
return context.Clients.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
}
if (model.Email != null && model.Password != null)
{
return context.Clients return context.Clients
.FirstOrDefault(x => .FirstOrDefault(x => x.Email.Equals(model.Email) && x.Password.Equals(model.Password))
(!string.IsNullOrEmpty(model.Email) && x.Email == model.Email) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel; ?.GetViewModel;
} }
if (model.Email != null)
{
return context.Clients.FirstOrDefault(x => x.Email.Equals(model.Email))?.GetViewModel;
}
return null;
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model) public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{ {

View File

@ -0,0 +1,54 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System.Security.Cryptography.X509Certificates;
namespace FurnitureAssemblyDatabaseImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (model.MessageId == null)
{
return null;
}
using var context = new FurnitureAssemblyDatabase();
return context.Messages.FirstOrDefault(x => x.MessageId.Equals(model.MessageId))?.GetViewModel;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (!model.ClientId.HasValue)
{
return new();
}
using var context = new FurnitureAssemblyDatabase();
return context.Messages.Where(x => x.ClientId.HasValue && x.ClientId == model.ClientId).Select(x => x.GetViewModel).ToList();
}
public List<MessageInfoViewModel> GetFullList()
{
using var context = new FurnitureAssemblyDatabase();
return context.Messages.Select(x => x.GetViewModel).ToList();
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = MessageInfo.Create(model);
if (newMessage == null)
{
return null;
}
using var context = new FurnitureAssemblyDatabase();
context.Messages.Add(newMessage);
context.SaveChanges();
return newMessage.GetViewModel;
}
}
}

View File

@ -36,8 +36,7 @@ namespace FurnitureAssemblyDatabaseImplement.Implements
using var context = new FurnitureAssemblyDatabase(); using var context = new FurnitureAssemblyDatabase();
return context.Orders.Include(x => x.Furniture).Include(x => x.Client).FirstOrDefault(x => return context.Orders.Include(x => x.Furniture).Include(x => x.Client).FirstOrDefault(x =>
(model.Id.HasValue && x.Id == model.Id)) (model.Id.HasValue && x.Id == model.Id))
?.GetViewModel; ?.GetViewModel; if (model.Id.HasValue)
if (model.Id.HasValue)
{ {
return context.Orders.Include(x => x.Furniture).Include(x => x.Client).Include(x => x.Implementer).FirstOrDefault(x => return context.Orders.Include(x => x.Furniture).Include(x => x.Client).Include(x => x.Implementer).FirstOrDefault(x =>
(model.Id.HasValue && x.Id == model.Id)) (model.Id.HasValue && x.Id == model.Id))

View File

@ -0,0 +1,296 @@
// <auto-generated />
using System;
using FurnitureAssemblyDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace FurnitureAssemblyDatabaseImplement.Migrations
{
[DbContext(typeof(FurnitureAssemblyDatabase))]
[Migration("20240430080044_lab7")]
partial class lab7
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.0-preview.3.23174.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.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("FurnitureAssemblyDatabaseImplement.Models.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("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("FurnitureName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Furnitures");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureComponent", 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>("FurnitureId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("FurnitureId");
b.ToTable("FurnitureComponents");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.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("FurnitureAssemblyDatabaseImplement.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("FurnitureAssemblyDatabaseImplement.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>("FurnitureId")
.HasColumnType("int");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("FurnitureId");
b.HasIndex("ImplementerId");
b.ToTable("Orders");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureComponent", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Component", "Component")
.WithMany("FurnitureComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("Components")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Furniture");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.MessageInfo", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Client", "Client")
.WithMany("Messages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Client", "Client")
.WithMany()
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("Orders")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.Navigation("Client");
b.Navigation("Furniture");
b.Navigation("Implementer");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Client", b =>
{
b.Navigation("Messages");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Component", b =>
{
b.Navigation("FurnitureComponents");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,48 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace FurnitureAssemblyDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class lab7 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
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.CreateIndex(
name: "IX_Messages_ClientId",
table: "Messages",
column: "ClientId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Messages");
}
}
}

View File

@ -140,6 +140,36 @@ namespace FurnitureAssemblyDatabaseImplement.Migrations
b.ToTable("Implementers"); b.ToTable("Implementers");
}); });
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.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("FurnitureAssemblyDatabaseImplement.Models.Order", b => modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -202,6 +232,15 @@ namespace FurnitureAssemblyDatabaseImplement.Migrations
b.Navigation("Furniture"); b.Navigation("Furniture");
}); });
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.MessageInfo", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Client", "Client")
.WithMany("Messages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b => modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{ {
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Client", "Client") b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Client", "Client")
@ -227,6 +266,11 @@ namespace FurnitureAssemblyDatabaseImplement.Migrations
b.Navigation("Implementer"); b.Navigation("Implementer");
}); });
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Client", b =>
{
b.Navigation("Messages");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Component", b => modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Component", b =>
{ {
b.Navigation("FurnitureComponents"); b.Navigation("FurnitureComponents");

View File

@ -7,6 +7,7 @@ using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations.Schema;
namespace FurnitureAssemblyDatabaseImplement.Models namespace FurnitureAssemblyDatabaseImplement.Models
{ {
@ -19,6 +20,8 @@ namespace FurnitureAssemblyDatabaseImplement.Models
public string Email { get; private set; } = string.Empty; public string Email { get; private set; } = string.Empty;
[Required] [Required]
public string Password { get; private set; } = string.Empty; public string Password { get; private set; } = string.Empty;
[ForeignKey("ClientId")]
public virtual List<MessageInfo> Messages { get; set; } = new();
public static Client? Create(ClientBindingModel model) public static Client? Create(ClientBindingModel model)
{ {

View File

@ -0,0 +1,54 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Models;
using System.ComponentModel.DataAnnotations;
namespace FurnitureAssemblyDatabaseImplement.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 virtual Client? Client { get; private set; }
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

@ -1,5 +1,5 @@
using FurnitureAssemblyFileImplement_.Models; using FurnitureAssemblyFileImplement.Models;
using FurnitureAssemblyFileImplement.Models; using FurnitureAssemblyFileImplement_.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -17,11 +17,13 @@ namespace FurnitureAssemblyFileImplement
private readonly string FurnitureFileName = "Furniture.xml"; private readonly string FurnitureFileName = "Furniture.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";
private readonly string MessageFileName = "Message.xml";
public List<Component> Components { get; private set; } public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; } public List<Order> Orders { get; private set; }
public List<Furniture> Furnitures { get; private set; } public List<Furniture> Furnitures { 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()
{ {
@ -36,6 +38,7 @@ namespace FurnitureAssemblyFileImplement
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);
public void SaveMessages() => SaveData(Messages, MessageFileName, "Messages", x => x.GetXElement);
private DataFileSingleton() private DataFileSingleton()
{ {
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!; Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
@ -43,6 +46,7 @@ namespace FurnitureAssemblyFileImplement
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!; Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!; Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
Messages = LoadData(MessageFileName, "Message", x => MessageInfo.Create(x)!)!;
} }
private static List<T>? LoadData<T>(string filename, string xmlNodeName, private static List<T>? LoadData<T>(string filename, string xmlNodeName,
Func<XElement, T> selectFunction) Func<XElement, T> selectFunction)

View File

@ -8,6 +8,11 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MailKit" Version="4.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FurnitureAssemblyDatabaseImplement\FurnitureAssemblyDatabaseImplement.csproj" />
<ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" /> <ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" />
<ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" /> <ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" />
</ItemGroup> </ItemGroup>

View File

@ -0,0 +1,54 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyFileImplement.Models;
namespace FurnitureAssemblyFileImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataFileSingleton _source;
public MessageInfoStorage()
{
_source = DataFileSingleton.GetInstance();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (model.MessageId == null)
{
return null;
}
return _source.Messages.FirstOrDefault(x => x.MessageId.Equals(model.MessageId))?.GetViewModel;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (!model.ClientId.HasValue)
{
return new();
}
return _source.Messages.Where(x => x.ClientId.Equals(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 newClient = MessageInfo.Create(model);
if (newClient == null)
{
return null;
}
_source.Messages.Add(newClient);
_source.SaveMessages();
return newClient.GetViewModel;
}
}
}

View File

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

View File

@ -10,6 +10,7 @@ namespace FurnitureAssemblyListImplement
public List<Furniture> Furnitures { get; set; } public List<Furniture> Furnitures { get; set; }
public List<Client> Clients { get; set; } public List<Client> Clients { get; set; }
public List<Implementer> Implementers { get; set; } public List<Implementer> Implementers { get; set; }
public List<MessageInfo> Messages { get; set; }
private DataListSingleton() private DataListSingleton()
{ {
Components = new List<Component>(); Components = new List<Component>();
@ -17,6 +18,7 @@ namespace FurnitureAssemblyListImplement
Furnitures = new List<Furniture>(); Furnitures = new List<Furniture>();
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()
{ {

View File

@ -6,6 +6,10 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="MailKit" Version="4.0.0" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" /> <ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" />
<ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" /> <ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" />

View File

@ -0,0 +1,68 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyListImplement.Models;
namespace FurnitureAssemblyListImplement.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 && message.MessageId.Equals(model.MessageId))
{
return message.GetViewModel;
}
}
return null;
}
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.Equals(model.ClientId))
{
result.Add(message.GetViewModel);
}
}
return result;
}
public List<MessageInfoViewModel> GetFullList()
{
var result = new List<MessageInfoViewModel>();
foreach (var message in _source.Messages)
{
result.Add(message.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,48 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Models;
namespace FurnitureAssemblyListImplement.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()
{
MessageId = model.MessageId,
ClientId = model.ClientId,
Body = model.Body,
Subject = model.Subject,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
};
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
Subject = Subject,
ClientId = ClientId,
MessageId = MessageId,
SenderName = SenderName,
DateDelivery = DateDelivery,
};
}
}

View File

@ -1,4 +1,5 @@
using FurnitureAssemblyContracts.BindingModels; using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContarcts;
using FurnitureAssemblyContracts.BusinessLogicsContracts; using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyContracts.SearchModels; using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.ViewModels; using FurnitureAssemblyContracts.ViewModels;
@ -12,11 +13,13 @@ namespace FurnitureAssemblyRestApi.Controllers
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IClientLogic _logic; 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; _logger = logger;
_logic = logic; _logic = logic;
_mailLogic = mailLogic;
} }
[HttpGet] [HttpGet]
@ -62,5 +65,21 @@ namespace FurnitureAssemblyRestApi.Controllers
throw; 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

@ -13,9 +13,9 @@ namespace FurnitureAssemblyRestApi.Controllers
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderLogic _order; private readonly IOrderLogic _order;
private readonly IfurnitureLogic _furniture; private readonly IFurnitureLogic _furniture;
public MainController(ILogger<MainController> logger, IOrderLogic order, IfurnitureLogic furniture) public MainController(ILogger<MainController> logger, IOrderLogic order, IFurnitureLogic furniture)
{ {
_logger = logger; _logger = logger;
_order = order; _order = order;

View File

@ -7,6 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MailKit" Version="4.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="6.1.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="6.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> </ItemGroup>
@ -14,6 +15,9 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FurnitureAssemblyBusinessLogic\FurnitureAssemblyBusinessLogic.csproj" /> <ProjectReference Include="..\FurnitureAssemblyBusinessLogic\FurnitureAssemblyBusinessLogic.csproj" />
<ProjectReference Include="..\FurnitureAssemblyDatabaseImplement\FurnitureAssemblyDatabaseImplement.csproj" /> <ProjectReference Include="..\FurnitureAssemblyDatabaseImplement\FurnitureAssemblyDatabaseImplement.csproj" />
<ProjectReference Include="..\FurnitureAssemblyListImplement\FurnitureAssemblyListImplement.csproj" />
</ItemGroup> </ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
</Project> </Project>

View File

@ -4,7 +4,9 @@ using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyContracts.StoragesContracts; using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyDatabaseImplement.Implements; using FurnitureAssemblyDatabaseImplement.Implements;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using FurnitureAssemblyContracts.BusinessLogicsContarcts;
using FurnitureAssemblyBusinessLogic.MailWorker;
using FurnitureAssemblyContracts.BindingModels;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -17,7 +19,10 @@ builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IFurnitureStorage, FurnitureStorage>(); builder.Services.AddTransient<IFurnitureStorage, FurnitureStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>(); builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IfurnitureLogic, FurnitureLogic>(); builder.Services.AddTransient<IFurnitureLogic, FurnitureLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
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
@ -33,6 +38,17 @@ builder.Services.AddSwaggerGen(c =>
}); });
}); });
var app = builder.Build(); var app = builder.Build();
var mailSender = app.Services.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty,
MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty,
SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty,
SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()),
PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty,
PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString())
});
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
{ {

View File

@ -5,5 +5,12 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"SmtpClientHost": "smtp.gmail.com",
"SmtpClientPort": "587",
"PopHost": "pop.gmail.com",
"PopPort": "995",
"MailLogin": "dyakonov.rr@gmail.com",
"MailPassword": "asnb zmlr chgf ewmg"
} }