Compare commits

...

2 Commits

Author SHA1 Message Date
a22c8352bf lab8 2024-06-22 09:32:05 +04:00
722792852e lab7 2024-06-22 01:05:59 +04:00
72 changed files with 2558 additions and 439 deletions

11
Bar/Bar/App.config Normal file
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="danilafilippov7299@gmail.com" />
<add key="MailPassword" value="ayks nyia mgiv hzlf" />
</appSettings>
</configuration>

View File

@ -9,6 +9,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.18">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="NLog" Version="5.3.2" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.11" />

View File

@ -0,0 +1,44 @@
using BarContracts.Attrubites;
namespace BarView
{
public static class DataGridViewExtension
{
public static void FillAndConfigGrid<T>(this DataGridView Grid, List<T>? Data)
{
if (Data == null)
return;
Grid.DataSource = Data;
var Type = typeof(T);
var Properties = Type.GetProperties();
foreach (DataGridViewColumn Column in Grid.Columns)
{
var Property = Properties.FirstOrDefault(x => x.Name == Column.Name);
if (Property == null)
throw new InvalidOperationException($"В типе {Type.Name} не найдено свойство с именем {Column.Name}");
var Attribute = Property.GetCustomAttributes(typeof(ColumnAttribute), true)?.SingleOrDefault();
if (Attribute == null)
throw new InvalidOperationException($"Не найден атрибут типа ColumnAttribute для свойства {Property.Name}");
if (Attribute is ColumnAttribute СolumnAttr)
{
Column.HeaderText = СolumnAttr.Title;
Column.Visible = СolumnAttr.Visible;
if (СolumnAttr.IsUseAutoSize)
{
Column.AutoSizeMode = (DataGridViewAutoSizeColumnMode)Enum.Parse(typeof(DataGridViewAutoSizeColumnMode), СolumnAttr.GridViewAutoSize.ToString());
}
else
{
Column.Width = СolumnAttr.Width;
}
}
}
}
}
}

View File

@ -44,7 +44,8 @@
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.StartWorkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.MailToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)(this.DataGridView)).BeginInit();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
@ -115,7 +116,8 @@
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ToolStripMenu,
this.отчётыToolStripMenuItem,
this.запускРаботToolStripMenuItem});
this.StartWorkToolStripMenuItem,
this.MailToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(1279, 28);
@ -136,28 +138,28 @@
// ComponentsStripMenuItem
//
this.ComponentsStripMenuItem.Name = "ComponentsStripMenuItem";
this.ComponentsStripMenuItem.Size = new System.Drawing.Size(224, 26);
this.ComponentsStripMenuItem.Size = new System.Drawing.Size(185, 26);
this.ComponentsStripMenuItem.Text = "Компоненты";
this.ComponentsStripMenuItem.Click += new System.EventHandler(this.ComponentsStripMenuItem_Click);
//
// CocktailStripMenuItem
//
this.CocktailStripMenuItem.Name = "CocktailStripMenuItem";
this.CocktailStripMenuItem.Size = new System.Drawing.Size(224, 26);
this.CocktailStripMenuItem.Size = new System.Drawing.Size(185, 26);
this.CocktailStripMenuItem.Text = "Коктейль";
this.CocktailStripMenuItem.Click += new System.EventHandler(this.CocktailsStripMenuItem_Click);
//
// ClientsToolStripMenuItem
//
this.ClientsToolStripMenuItem.Name = "ClientsToolStripMenuItem";
this.ClientsToolStripMenuItem.Size = new System.Drawing.Size(224, 26);
this.ClientsToolStripMenuItem.Size = new System.Drawing.Size(185, 26);
this.ClientsToolStripMenuItem.Text = "Клиенты";
this.ClientsToolStripMenuItem.Click += new System.EventHandler(this.ClientsToolStripMenuItem_Click);
//
// EmployersToolStripMenuItem
//
this.EmployersToolStripMenuItem.Name = "EmployersToolStripMenuItem";
this.EmployersToolStripMenuItem.Size = new System.Drawing.Size(224, 26);
this.EmployersToolStripMenuItem.Size = new System.Drawing.Size(185, 26);
this.EmployersToolStripMenuItem.Text = "Исполнители";
this.EmployersToolStripMenuItem.Click += new System.EventHandler(this.EmployersToolStripMenuItem_Click);
//
@ -192,12 +194,19 @@
this.списокЗаказовToolStripMenuItem.Text = "Список заказов";
this.списокЗаказовToolStripMenuItem.Click += new System.EventHandler(this.OrdersToolStripMenuItem_Click);
//
// запускРаботToolStripMenuItem
// StartWorkToolStripMenuItem
//
this.запускРаботToolStripMenuItem.Name = апускРаботToolStripMenuItem";
this.запускРаботToolStripMenuItem.Size = new System.Drawing.Size(114, 24);
this.запускРаботToolStripMenuItem.Text = "Запуск работ";
this.запускРаботToolStripMenuItem.Click += new System.EventHandler(this.запускРаботToolStripMenuItem_Click);
this.StartWorkToolStripMenuItem.Name = "StartWorkToolStripMenuItem";
this.StartWorkToolStripMenuItem.Size = new System.Drawing.Size(114, 24);
this.StartWorkToolStripMenuItem.Text = "Запуск работ";
this.StartWorkToolStripMenuItem.Click += new System.EventHandler(this.запускРаботToolStripMenuItem_Click);
//
// MailToolStripMenuItem
//
this.MailToolStripMenuItem.Name = "MailToolStripMenuItem";
this.MailToolStripMenuItem.Size = new System.Drawing.Size(65, 24);
this.MailToolStripMenuItem.Text = "Почта";
this.MailToolStripMenuItem.Click += new System.EventHandler(this.MailToolStripMenuItem_Click);
//
// FormMain
//
@ -239,7 +248,8 @@
private ToolStripMenuItem компонентыПоИзделиямToolStripMenuItem;
private ToolStripMenuItem списокЗаказовToolStripMenuItem;
private ToolStripMenuItem ClientsToolStripMenuItem;
private ToolStripMenuItem запускРаботToolStripMenuItem;
private ToolStripMenuItem StartWorkToolStripMenuItem;
private ToolStripMenuItem EmployersToolStripMenuItem;
private ToolStripMenuItem MailToolStripMenuItem;
}
}

View File

@ -1,6 +1,7 @@
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using BarContracts.BusinessLogicsContracts;
using BarContracts.DI;
using BarView.Forms;
using Microsoft.Extensions.Logging;
@ -12,7 +13,10 @@ namespace BarView
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
private readonly IWorkProcess _workProcess;
public FormMain(ILogger<FormMain> Logger, IOrderLogic OrderLogic, IReportLogic ReportLogic, IWorkProcess WorkProcess)
private readonly IBackUpLogic _backUpLogic;
public FormMain(ILogger<FormMain> Logger, IOrderLogic OrderLogic, IReportLogic ReportLogic, IWorkProcess WorkProcess, IBackUpLogic backUpLogic)
{
InitializeComponent();
@ -20,6 +24,7 @@ namespace BarView
_orderLogic = OrderLogic;
_reportLogic = ReportLogic;
_workProcess = WorkProcess;
_backUpLogic = backUpLogic;
}
private void FormMain_Load(object sender, EventArgs e)
@ -33,17 +38,7 @@ namespace BarView
try
{
var List = _orderLogic.ReadList(null);
if (List != null)
{
DataGridView.DataSource = List;
DataGridView.Columns["CocktailId"].Visible = false;
DataGridView.Columns["ClientId"].Visible = false;
DataGridView.Columns["ImplementerId"].Visible = false;
DataGridView.Columns["CocktailName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
DataGridView.FillAndConfigGrid(_orderLogic.ReadList(null));
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
@ -55,7 +50,7 @@ namespace BarView
private void ComponentsStripMenuItem_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormComponents));
var Service = DependencyManager.Instance.Resolve<FormComponents>();
if (Service is FormComponents Form)
{
@ -65,7 +60,7 @@ namespace BarView
private void CocktailsStripMenuItem_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormCocktails));
var Service = DependencyManager.Instance.Resolve<FormCocktails>();
if (Service is FormCocktails Form)
{
@ -75,7 +70,7 @@ namespace BarView
private void CreateOrderButton_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
var Service = DependencyManager.Instance.Resolve<FormCreateOrder>();
if (Service is FormCreateOrder Form)
{
@ -171,6 +166,7 @@ namespace BarView
{
LoadData();
}
private void ComponentsToolStripMenuItem_Click(object sender, EventArgs e)
{
using var Dialog = new SaveFileDialog { Filter = "docx|*.docx" };
@ -184,7 +180,7 @@ namespace BarView
private void ComponentCocktailToolStripMenuItem_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormReportCocktailComponents));
var Service = DependencyManager.Instance.Resolve<FormReportCocktailComponents>();
if (Service is FormReportCocktailComponents Form)
{
@ -194,7 +190,7 @@ namespace BarView
private void OrdersToolStripMenuItem_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
var Service = DependencyManager.Instance.Resolve<FormReportOrders>();
if (Service is FormReportOrders Form)
{
@ -204,7 +200,7 @@ namespace BarView
private void ClientsToolStripMenuItem_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormClients));
var Service = DependencyManager.Instance.Resolve<FormClients>();
if (Service is FormClients Form)
{
@ -212,22 +208,60 @@ namespace BarView
}
}
private void запускРаботToolStripMenuItem_Click(object sender, EventArgs e)
{
var ImplementerLogic = Program.ServiceProvider?.GetService(typeof(IImplementerLogic));
_workProcess.DoWork((ImplementerLogic as IImplementerLogic)!, _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void EmployersToolStripMenuItem_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
var Service = DependencyManager.Instance.Resolve<FormImplementers>();
if (Service is FormImplementers Form)
{
Form.ShowDialog();
}
}
private void запускРаботToolStripMenuItem_Click(object sender, EventArgs e)
{
var ImplementerLogic = DependencyManager.Instance.Resolve<IImplementerLogic>();
_workProcess.DoWork(ImplementerLogic, _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void MailToolStripMenuItem_Click(object sender, EventArgs e)
{
var Service = DependencyManager.Instance.Resolve<FormMail>();
if (Service is FormMail Form)
{
Form.ShowDialog();
}
}
private void CreateBackupToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (_backUpLogic != null)
{
var FolderBrowser = new FolderBrowserDialog();
if (FolderBrowser.ShowDialog() == DialogResult.OK)
{
_backUpLogic.CreateBackUp(new BackUpSaveBindingModel
{
FolderName = FolderBrowser.SelectedPath
});
MessageBox.Show("Бекап создан", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка создания бэкапа", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void CreateBackupToolStripMenuItem_Click_1(object sender, EventArgs e)
{
}
}
}

View File

@ -153,7 +153,7 @@
this.DataGridView.RowTemplate.Height = 29;
this.DataGridView.Size = new System.Drawing.Size(391, 213);
this.DataGridView.TabIndex = 13;
this.DataGridView.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.DataGridView_CellContentClick);
//this.DataGridView.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.DataGridView_CellContentClick);
//
// IdColumn
//

View File

@ -1,5 +1,6 @@
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using BarContracts.DI;
using BarContracts.SearchModels;
using BarDataModels.Models;
using Microsoft.Extensions.Logging;
@ -14,7 +15,7 @@ namespace BarView.Forms
private int? _id;
private Dictionary<int, (IComponentModel, int)> _CocktailComponents;
private Dictionary<int, (IComponentModel, int)> _cocktailComponents;
public int Id { set { _id = value; } }
@ -23,14 +24,14 @@ namespace BarView.Forms
InitializeComponent();
_logger = Logger;
_logic = Logic;
_CocktailComponents = new Dictionary<int, (IComponentModel, int)>();
_cocktailComponents = new Dictionary<int, (IComponentModel, int)>();
}
private void FormCocktail_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
_logger.LogInformation("Загрузка коктеля");
_logger.LogInformation("Загрузка коктейльа");
try
{
@ -44,13 +45,13 @@ namespace BarView.Forms
NameTextBox.Text = View.CocktailName;
PriceTextBox.Text = View.Price.ToString();
_CocktailComponents = View.CocktailComponents ?? new Dictionary<int, (IComponentModel, int)>();
_cocktailComponents = View.CocktailComponents ?? new Dictionary<int, (IComponentModel, int)>();
LoadData();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки коктеля");
_logger.LogError(ex, "Ошибка загрузки коктейльа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
@ -58,14 +59,14 @@ namespace BarView.Forms
private void LoadData()
{
_logger.LogInformation("Загрузка компонентов коктеля");
_logger.LogInformation("Загрузка компонентов коктейльа");
try
{
if (_CocktailComponents != null)
if (_cocktailComponents != null)
{
DataGridView.Rows.Clear();
foreach (var Comp in _CocktailComponents)
foreach (var Comp in _cocktailComponents)
{
DataGridView.Rows.Add(new object[] { Comp.Key, Comp.Value.Item1.ComponentName, Comp.Value.Item2 });
}
@ -75,14 +76,14 @@ namespace BarView.Forms
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки компонентов коктеля");
_logger.LogError(ex, "Ошибка загрузки компонентов коктейльа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void AddButton_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormCocktailComponent));
var Service = DependencyManager.Instance.Resolve<FormCocktailComponent>();
if (Service is FormCocktailComponent Form)
{
@ -95,13 +96,13 @@ namespace BarView.Forms
_logger.LogInformation("Добавление нового компонента: {ComponentName} - {Count}", Form.ComponentModel.ComponentName, Form.Count);
if (_CocktailComponents.ContainsKey(Form.Id))
if (_cocktailComponents.ContainsKey(Form.Id))
{
_CocktailComponents[Form.Id] = (Form.ComponentModel, Form.Count);
_cocktailComponents[Form.Id] = (Form.ComponentModel, Form.Count);
}
else
{
_CocktailComponents.Add(Form.Id, (Form.ComponentModel, Form.Count));
_cocktailComponents.Add(Form.Id, (Form.ComponentModel, Form.Count));
}
LoadData();
@ -113,12 +114,12 @@ namespace BarView.Forms
{
if (DataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCocktailComponent));
var service = DependencyManager.Instance.Resolve<FormCocktailComponent>();
if (service is FormCocktailComponent Form)
{
int id = Convert.ToInt32(DataGridView.SelectedRows[0].Cells[0].Value);
Form.Id = id;
Form.Count = _CocktailComponents[id].Item2;
Form.Count = _cocktailComponents[id].Item2;
if (Form.ShowDialog() == DialogResult.OK)
{
@ -128,7 +129,7 @@ namespace BarView.Forms
}
_logger.LogInformation("Изменение компонента: {ComponentName} - {Count}", Form.ComponentModel.ComponentName, Form.Count);
_CocktailComponents[Form.Id] = (Form.ComponentModel, Form.Count);
_cocktailComponents[Form.Id] = (Form.ComponentModel, Form.Count);
LoadData();
}
@ -147,7 +148,7 @@ namespace BarView.Forms
_logger.LogInformation("Удаление компонента: {ComponentName} - {Count}", DataGridView.SelectedRows[0].Cells[1].Value,
DataGridView.SelectedRows[0].Cells[2].Value);
_CocktailComponents?.Remove(Convert.ToInt32(DataGridView.SelectedRows[0].Cells[0].Value));
_cocktailComponents?.Remove(Convert.ToInt32(DataGridView.SelectedRows[0].Cells[0].Value));
}
catch (Exception ex)
{
@ -179,13 +180,13 @@ namespace BarView.Forms
return;
}
if (_CocktailComponents == null || _CocktailComponents.Count == 0)
if (_cocktailComponents == null || _cocktailComponents.Count == 0)
{
MessageBox.Show("Заполните компоненты", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение коктеля");
_logger.LogInformation("Сохранение коктейльа");
try
{
@ -194,7 +195,7 @@ namespace BarView.Forms
Id = _id ?? 0,
CocktailName = NameTextBox.Text,
Price = Convert.ToDouble(PriceTextBox.Text),
CocktailComponents = _CocktailComponents
CocktailComponents = _cocktailComponents
};
var OperationResult = _id.HasValue ? _logic.Update(Мodel) : _logic.Create(Мodel);
@ -210,7 +211,7 @@ namespace BarView.Forms
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения коктеля");
_logger.LogError(ex, "Ошибка сохранения коктейльа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
@ -225,17 +226,12 @@ namespace BarView.Forms
{
double Price = 0;
foreach (var Elem in _CocktailComponents)
foreach (var Elem in _cocktailComponents)
{
Price += ((Elem.Value.Item1?.Cost ?? 0) * Elem.Value.Item2);
}
return Math.Round(Price * 1, 2);
}
private void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
return Math.Round(Price * 1.1, 2);
}
}
}

View File

@ -85,7 +85,7 @@
this.DataGridView.RowTemplate.Height = 29;
this.DataGridView.Size = new System.Drawing.Size(542, 385);
this.DataGridView.TabIndex = 5;
this.DataGridView.SelectionChanged += new System.EventHandler(this.DataGridView_SelectionChanged);
//this.DataGridView.SelectionChanged += new System.EventHandler(this.DataGridView_SelectionChanged);
//
// FormCocktails
//

View File

@ -1,5 +1,6 @@
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using BarContracts.DI;
using Microsoft.Extensions.Logging;
namespace BarView.Forms
@ -26,28 +27,19 @@ namespace BarView.Forms
{
try
{
var List = _logic.ReadList(null);
if (List != null)
{
DataGridView.DataSource = List;
DataGridView.Columns["Id"].Visible = false;
DataGridView.Columns["CocktailName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
DataGridView.Columns["CocktailComponents"].Visible = false;
}
_logger.LogInformation("Загрузка коктеля");
DataGridView.FillAndConfigGrid(_logic.ReadList(null));
_logger.LogInformation("Загрузка коктейльа");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки коктеля");
_logger.LogError(ex, "Ошибка загрузки коктейльа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void AddButton_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormCocktail));
var Service = DependencyManager.Instance.Resolve<FormCocktail>();
if (Service is FormCocktail Form)
{
@ -62,7 +54,7 @@ namespace BarView.Forms
{
if (DataGridView.SelectedRows.Count == 1)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormCocktail));
var Service = DependencyManager.Instance.Resolve<FormCocktail>();
if (Service is FormCocktail Form)
{
@ -84,7 +76,7 @@ namespace BarView.Forms
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление коктеля");
_logger.LogInformation("Удаление коктейльа");
try
{
if (!_logic.Delete(new CocktailBindingModel
@ -99,7 +91,7 @@ namespace BarView.Forms
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления коктеля");
_logger.LogError(ex, "Ошибка удаления коктейльа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
@ -110,9 +102,5 @@ namespace BarView.Forms
{
LoadData();
}
private void DataGridView_SelectionChanged(object sender, EventArgs e)
{
}
}
}

View File

@ -1,5 +1,6 @@
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using BarContracts.DI;
using Microsoft.Extensions.Logging;
namespace BarView.Forms
@ -25,15 +26,7 @@ namespace BarView.Forms
{
try
{
var List = _logic.ReadList(null);
if (List != null)
{
DataGridView.DataSource = List;
DataGridView.Columns["Id"].Visible = false;
DataGridView.Columns["ComponentName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
DataGridView.FillAndConfigGrid(_logic.ReadList(null));
_logger.LogInformation("Загрузка компонентов");
}
catch (Exception ex)
@ -45,7 +38,7 @@ namespace BarView.Forms
private void AddButton_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormComponent));
var Service = DependencyManager.Instance.Resolve<FormComponent>();
if (Service is FormComponent Form)
{
@ -60,7 +53,7 @@ namespace BarView.Forms
{
if (DataGridView.SelectedRows.Count == 1)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormComponent));
var Service = DependencyManager.Instance.Resolve<FormComponent>();
if (Service is FormComponent Form)
{
Form.Id = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value);
@ -108,7 +101,5 @@ namespace BarView.Forms
{
LoadData();
}
}
}

View File

@ -1,5 +1,6 @@
using BarContracts.BindingModels;
using BarContracts.BusinessLogicsContracts;
using BarContracts.DI;
using Microsoft.Extensions.Logging;
namespace BarView.Forms
@ -21,15 +22,7 @@ namespace BarView.Forms
{
try
{
var List = _implementerLogic.ReadList(null);
if (List != null)
{
DataGridView.DataSource = List;
DataGridView.Columns["Id"].Visible = false;
DataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
DataGridView.FillAndConfigGrid(_implementerLogic.ReadList(null));
_logger.LogInformation("Загрузка исполнителей");
}
catch (Exception ex)
@ -46,7 +39,7 @@ namespace BarView.Forms
private void AddButton_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormImplementer));
var Service = DependencyManager.Instance.Resolve<FormImplementer>();
if (Service is FormImplementer Form)
{
@ -61,7 +54,7 @@ namespace BarView.Forms
{
if (DataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementer));
var service = DependencyManager.Instance.Resolve<FormImplementer>();
if (service is FormImplementer Form)
{
Form.Id = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value);

68
Bar/Bar/Forms/FormMail.Designer.cs generated Normal file
View File

@ -0,0 +1,68 @@
namespace BarView.Forms
{
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.AllowUserToAddRows = false;
DataGridView.AllowUserToDeleteRows = false;
DataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
DataGridView.Dock = DockStyle.Fill;
DataGridView.Location = new Point(0, 0);
DataGridView.Margin = new Padding(3, 2, 3, 2);
DataGridView.Name = "DataGridView";
DataGridView.ReadOnly = true;
DataGridView.RowHeadersWidth = 51;
DataGridView.RowTemplate.Height = 29;
DataGridView.Size = new Size(1084, 456);
DataGridView.TabIndex = 0;
//
// FormMail
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1084, 456);
Controls.Add(DataGridView);
Margin = new Padding(3, 2, 3, 2);
Name = "FormMail";
Text = "Письма";
Load += FormMail_Load;
((System.ComponentModel.ISupportInitialize)DataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView DataGridView;
}
}

47
Bar/Bar/Forms/FormMail.cs Normal file
View File

@ -0,0 +1,47 @@
using BarContracts.BusinessLogicContracts;
using Microsoft.Extensions.Logging;
namespace BarView.Forms
{
public partial class FormMail : Form
{
private readonly ILogger _logger;
private readonly IMessageInfoLogic _messageLogic;
public FormMail(ILogger<FormMail> Logger, IMessageInfoLogic MessageLogic)
{
InitializeComponent();
_logger = Logger;
_messageLogic = MessageLogic;
}
private void LoadData()
{
try
{
var List = _messageLogic.ReadList(null);
if (List != null)
{
DataGridView.DataSource = List;
DataGridView.Columns["MessageId"].Visible = false;
DataGridView.Columns["ClientId"].Visible = false;
DataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка почтовых собщений");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки почтовых сообщений");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FormMail_Load(object sender, EventArgs e)
{
LoadData();
}
}
}

120
Bar/Bar/Forms/FormMail.resx Normal file
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

@ -2,74 +2,87 @@ using BarBusinessLogic.BusinessLogics;
using BarBusinessLogic.OfficePackage.Implements;
using BarBusinessLogic.OfficePackage;
using BarContracts.BusinessLogicContracts;
using BarContracts.StoragesContracts;
using BarDatabaseImplement.Implements;
using BarView.Forms;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using BarContracts.BusinessLogicsContracts;
using BarContracts.BusinessLogicContracts;
using BarBusinessLogic.MailWorker;
using BarContracts.BindingModels;
using BarContracts.DI;
namespace BarView
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
InitDependency();
var Services = new ServiceCollection();
ConfigureServices(Services);
_serviceProvider = Services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
private static void ConfigureServices(ServiceCollection Services)
try
{
Services.AddLogging(option =>
var MailSender = DependencyManager.Instance.Resolve<AbstractMailWorker>();
MailSender?.MailConfig(new MailConfigBindingModel
{
option.SetMinimumLevel(LogLevel.Information);
option.AddNLog("nlog.config");
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"])
});
Services.AddTransient<IComponentStorage, ComponentStorage>();
Services.AddTransient<IOrderStorage, OrderStorage>();
Services.AddTransient<ICocktailStorage, CocktailStorage>();
var Timer = new System.Threading.Timer(new TimerCallback(MailCheck!), null, 0, 100000);
}
catch (Exception ex)
{
var Logger = DependencyManager.Instance.Resolve<ILogger>();
Logger?.LogError(ex, "Îøèáêà ðàáîòû ñ ïî÷òîé");
}
Services.AddTransient<IClientStorage, ClientStorage>();
Services.AddTransient<IImplementerStorage, ImplementerStorage>();
Application.Run(DependencyManager.Instance.Resolve<FormMain>());
}
Services.AddTransient<IComponentLogic, ComponentLogic>();
Services.AddTransient<IOrderLogic, OrderLogic>();
Services.AddTransient<ICocktailLogic, CocktailLogic>();
Services.AddTransient<IReportLogic, ReportLogic>();
Services.AddTransient<IClientLogic, ClientLogic>();
Services.AddTransient<IImplementerLogic, ImplementerLogic>();
Services.AddTransient<IWorkProcess, WorkModeling>();
private static void MailCheck(object obj) => DependencyManager.Instance.Resolve<AbstractMailWorker>()?.CheckMailAsync();
Services.AddTransient<AbstractSaveToWord, SaveToWord>();
Services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
Services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
private static void InitDependency()
{
DependencyManager.InitDependency();
DependencyManager.Instance.AddLogging(Option =>
{
Option.SetMinimumLevel(LogLevel.Information);
Option.AddNLog("nlog.config");
});
Services.AddTransient<FormMain>();
Services.AddTransient<FormComponent>();
Services.AddTransient<FormComponents>();
Services.AddTransient<FormCreateOrder>();
Services.AddTransient<FormCocktail>();
Services.AddTransient<FormCocktailComponent>();
Services.AddTransient<FormCocktails>();
Services.AddTransient<FormReportCocktailComponents>();
Services.AddTransient<FormReportOrders>();
Services.AddTransient<FormClients>();
Services.AddTransient<FormImplementers>();
Services.AddTransient<FormImplementer>();
DependencyManager.Instance.RegisterType<IComponentLogic, ComponentLogic>();
DependencyManager.Instance.RegisterType<IOrderLogic, OrderLogic>();
DependencyManager.Instance.RegisterType<ICocktailLogic, CocktailLogic>();
DependencyManager.Instance.RegisterType<IReportLogic, ReportLogic>();
DependencyManager.Instance.RegisterType<IClientLogic, ClientLogic>();
DependencyManager.Instance.RegisterType<IImplementerLogic, ImplementerLogic>();
DependencyManager.Instance.RegisterType<IWorkProcess, WorkModeling>();
DependencyManager.Instance.RegisterType<IMessageInfoLogic, MessageInfoLogic>();
DependencyManager.Instance.RegisterType<IBackUpLogic, BackUpLogic>();
DependencyManager.Instance.RegisterType<AbstractSaveToWord, SaveToWord>();
DependencyManager.Instance.RegisterType<AbstractSaveToExcel, SaveToExcel>();
DependencyManager.Instance.RegisterType<AbstractSaveToPdf, SaveToPdf>();
DependencyManager.Instance.RegisterType<AbstractMailWorker, MailKitWorker>(true);
DependencyManager.Instance.RegisterType<FormMain>();
DependencyManager.Instance.RegisterType<FormComponent>();
DependencyManager.Instance.RegisterType<FormComponents>();
DependencyManager.Instance.RegisterType<FormCreateOrder>();
DependencyManager.Instance.RegisterType<FormCocktail>();
DependencyManager.Instance.RegisterType<FormCocktailComponent>();
DependencyManager.Instance.RegisterType<FormCocktails>();
DependencyManager.Instance.RegisterType<FormReportCocktailComponents>();
DependencyManager.Instance.RegisterType<FormReportOrders>();
DependencyManager.Instance.RegisterType<FormClients>();
DependencyManager.Instance.RegisterType<FormImplementers>();
DependencyManager.Instance.RegisterType<FormImplementer>();
DependencyManager.Instance.RegisterType<FormMail>();
}
}
}

120
Bar/Bar/Program.resx Normal file
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

@ -12,6 +12,7 @@
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" />
<PackageReference Include="MailKit" Version="4.6.0" />
<PackageReference Include="NLog" Version="5.3.2" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.11" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />

View File

@ -0,0 +1,100 @@
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using BarContracts.StoragesContracts;
using BarDataModels.Models;
using Microsoft.Extensions.Logging;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.Serialization.Json;
namespace BarBusinessLogic.BusinessLogics
{
public class BackUpLogic : IBackUpLogic
{
private readonly ILogger _logger;
private readonly IBackUpInfo _backUpInfo;
public BackUpLogic(ILogger<BackUpLogic> Logger, IBackUpInfo BackUpInfo)
{
_logger = Logger;
_backUpInfo = BackUpInfo;
}
public void CreateBackUp(BackUpSaveBindingModel Model)
{
if (_backUpInfo == null)
return;
try
{
_logger.LogDebug("Clear folder");
var DirInfo = new DirectoryInfo(Model.FolderName);
if (DirInfo.Exists)
{
foreach (var File in DirInfo.GetFiles())
{
File.Delete();
}
}
_logger.LogDebug("Delete archive");
string FileName = $"{Model.FolderName}.zip";
if (File.Exists(FileName))
{
File.Delete(FileName);
}
_logger.LogDebug("Get assembly");
var TypeIId = typeof(IId);
var Assembly = TypeIId.Assembly;
if (Assembly == null)
{
throw new ArgumentNullException("Сборка не найдена", nameof(Assembly));
}
var Types = Assembly.GetTypes();
var Method = GetType().GetMethod("SaveToFile", BindingFlags.NonPublic | BindingFlags.Instance);
_logger.LogDebug("Found {count} types", Types.Length);
foreach (var Type in Types)
{
if (Type.IsInterface && Type.GetInterface(TypeIId.Name) != null)
{
var ModelType = _backUpInfo.GetTypeByModelInterface(Type.Name);
if (ModelType == null)
{
throw new InvalidOperationException($"Не найден класс - модель для { Type.Name }");
}
_logger.LogDebug("Call SaveToFile method for {name} Type", Type.Name);
Method?.MakeGenericMethod(ModelType).Invoke(this, new object[] { Model.FolderName });
}
}
_logger.LogDebug("Create zip and remove folder");
ZipFile.CreateFromDirectory(Model.FolderName, FileName);
DirInfo.Delete(true);
}
catch (Exception)
{
throw;
}
}
private void SaveToFile<T>(string FolderName) where T : class, new()
{
var Records = _backUpInfo.GetList<T>();
if (Records == null)
{
_logger.LogWarning("{type} type get null list", typeof(T).Name);
return;
}
var JsonFormatter = new DataContractJsonSerializer(typeof(List<T>));
using var fs = new FileStream(string.Format("{0}/{1}.json", FolderName, typeof(T).Name), FileMode.OpenOrCreate);
JsonFormatter.WriteObject(fs, Records);
}
}
}

View File

@ -0,0 +1,88 @@
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using BarContracts.SearchModels;
using BarContracts.StoragesContracts;
using BarContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace BarBusinessLogic.BusinessLogics
{
public class MessageInfoLogic : IMessageInfoLogic
{
private readonly ILogger _logger;
private readonly IMessageInfoStorage _messageInfoStorage;
private readonly IClientStorage _clientStorage;
public MessageInfoLogic(ILogger<MessageInfoLogic> Logger, IMessageInfoStorage MessageInfoStorage, IClientStorage ClientStorage)
{
_logger = Logger;
_messageInfoStorage = MessageInfoStorage;
_clientStorage = ClientStorage;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? Model)
{
_logger.LogDebug("ReadList. MessageId: {MessageId}, ClientId: {ClientId}", Model?.MessageId, Model?.ClientId);
var Result = Model == null ? _messageInfoStorage.GetFullList() : _messageInfoStorage.GetFilteredList(Model);
_logger.LogDebug("ReadList result. Count: {Count}", Result.Count);
return Result;
}
public bool Create(MessageInfoBindingModel Model)
{
try {
CheckModel(Model);
if (_messageInfoStorage.Insert(Model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
}
catch { }
return true;
}
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}", Model.SenderName);
}
else
{
Model.ClientId = Element.Id;
}
}
}
}

View File

@ -1,4 +1,5 @@
using BarContracts.BindingModels;
using BarBusinessLogic.MailWorker;
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using BarContracts.SearchModels;
using BarContracts.StoragesContracts;
@ -14,23 +15,28 @@ namespace BarBusinessLogic.BusinessLogics
private readonly IOrderStorage _orderStorage;
public OrderLogic(ILogger<CocktailLogic> Logger, IOrderStorage OrderStorage)
private readonly AbstractMailWorker _mailLogic;
static readonly object _locker = new object();
public OrderLogic(ILogger<CocktailLogic> Logger, IOrderStorage OrderStorage, AbstractMailWorker MailLogic)
{
_logger = Logger;
_orderStorage = OrderStorage;
_mailLogic = MailLogic;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? Model)
{
_logger.LogInformation("ReadList. Id:{Id}", Model?.Id);
var List = Model is null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(Model);
_logger.LogInformation("ReadList. ClientId: {ClientId}. Status: {Status}. ImplementerId: {ImplementerId}. DateFrom: {DateFrom}. DateTo: {DateTo}. OrderId: {Id}",
Model?.ClientId, Model?.Status, Model?.ImplementerId, Model?.DateFrom, Model?.DateTo, Model?.Id);
var List = Model is null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(Model);
if (List is null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", List.Count);
return List;
}
@ -47,21 +53,28 @@ namespace BarBusinessLogic.BusinessLogics
Model.Status = OrderStatus.Accepted;
if (_orderStorage.Insert(Model) is null)
var CreatedOrder = _orderStorage.Insert(Model);
if (CreatedOrder == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
Task.Run(() => _mailLogic.SendMailAsync(new MailSendInfoBindingModel
{
MailAddress = CreatedOrder.ClientEmail,
Subject = $"Изменение статуса заказа номер {CreatedOrder.Id}",
Text = $"Ваш заказ номер {CreatedOrder.Id} на коктейль {CreatedOrder.CocktailName} от {CreatedOrder.DateCreate} на сумму {CreatedOrder.Sum} принят."
}));
return true;
}
private bool ChangeOrderStatus(OrderBindingModel Model, OrderStatus NewStatus)
{
CheckModel(Model, false);
var Order = _orderStorage.GetElement(new OrderSearchModel { Id = Model.Id });
if (Order == null)
{
_logger.LogWarning("Change status operation failed. Order not found");
@ -94,13 +107,24 @@ namespace BarBusinessLogic.BusinessLogics
return false;
}
string DateInfo = Model.DateImplement.HasValue ? $"Дата выполнения: {Model.DateImplement}" : "";
Task.Run(() => _mailLogic.SendMailAsync(new MailSendInfoBindingModel
{
MailAddress = Order.ClientEmail,
Subject = $"Изменение статуса заказа номер {Order.Id}",
Text = $"Ваш заказ номер {Order.Id} на коктейль {Order.CocktailName} от {Order.DateCreate} на сумму {Order.Sum}. Статус изменен на {NewStatus}. {DateInfo}"
}));
return true;
}
public bool TakeOrderInWork(OrderBindingModel Model)
{
lock (_locker)
{
return ChangeOrderStatus(Model, OrderStatus.BeingProcessed);
}
}
public bool FinishOrder(OrderBindingModel Model)
{
@ -121,7 +145,7 @@ namespace BarBusinessLogic.BusinessLogics
return;
if (Model.Count <= 0)
throw new ArgumentNullException("Количество напитков в заказе быть больше 0", nameof(Model.Count));
throw new ArgumentNullException("Количество коктейльов в заказе быть больше 0", nameof(Model.Count));
if (Model.Sum <= 0)
throw new ArgumentNullException("Стоимость заказа должна быть больше 0", nameof(Model.Sum));

View File

@ -0,0 +1,84 @@
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using Microsoft.Extensions.Logging;
namespace BarBusinessLogic.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("MailConfig: {Login}, {Password}, {ClientHost}, {ClientPort}, {PopHost}, {PopPort}",
_mailLogin, _mailPassword, _smtpClientHost, _smtpClientPort, _popHost, _popPort);
}
public async void SendMailAsync(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("MailSendAsync: {To}, {Subject}", Info.MailAddress, Info.Subject);
await SendMailImpl(Info);
}
public async void CheckMailAsync()
{
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword))
return;
if (string.IsNullOrEmpty(_popHost) || _popPort == 0)
return;
if (_messageInfoLogic == null)
return;
var List = await ReceiveMailImpl();
_logger.LogDebug("CheckMailAsync: New mails: {Count}", List.Count);
foreach (var Mail in List)
{
_messageInfoLogic.Create(Mail);
}
}
protected abstract Task SendMailImpl(MailSendInfoBindingModel Info);
protected abstract Task<List<MessageInfoBindingModel>> ReceiveMailImpl();
}
}

View File

@ -0,0 +1,87 @@
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using MailKit.Net.Pop3;
using MailKit.Security;
using Microsoft.Extensions.Logging;
using System.Net;
using System.Net.Mail;
using System.Text;
namespace BarBusinessLogic.MailWorker
{
public class MailKitWorker : AbstractMailWorker
{
public MailKitWorker(ILogger<MailKitWorker> Logger, IMessageInfoLogic MessageInfoLogic)
: base(Logger, MessageInfoLogic) { }
protected override async Task SendMailImpl(MailSendInfoBindingModel Info)
{
using var MailMessage = new MailMessage();
using var SmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort);
try
{
MailMessage.From = new MailAddress(_mailLogin);
MailMessage.To.Add(new MailAddress(Info.MailAddress));
MailMessage.Subject = Info.Subject;
MailMessage.Body = Info.Text;
MailMessage.SubjectEncoding = Encoding.UTF8;
MailMessage.BodyEncoding = Encoding.UTF8;
SmtpClient.UseDefaultCredentials = false;
SmtpClient.EnableSsl = true;
SmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
SmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword);
await Task.Run(() => SmtpClient.Send(MailMessage));
}
catch (Exception)
{
throw;
}
}
protected override async Task<List<MessageInfoBindingModel>> ReceiveMailImpl()
{
var Result = 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)
{
//if (Mail.Address.Contains("o.filippova"))
Result.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 Result;
}
}
}

View File

@ -12,6 +12,7 @@
<ItemGroup>
<ProjectReference Include="..\BarBusinessLogic\BarBusinessLogic\BarBusinessLogic.csproj" />
<ProjectReference Include="..\BarContracts\BarContracts\BarContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -156,5 +156,16 @@ namespace BarClientApp.Controllers
CocktailViewModel? Cocktail = ApiClient.GetRequest<CocktailViewModel>($"api/main/getcocktail?cocktailId={cocktail}");
return count * (Cocktail?.Price ?? 1);
}
[HttpGet]
public IActionResult Mails()
{
if (ApiClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(ApiClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={ApiClient.Client.Id}"));
}
}
}

View File

@ -0,0 +1,51 @@
@using BarContracts.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">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li>
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Mails">Письма</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>

View File

@ -0,0 +1,26 @@
namespace BarContracts.Attrubites
{
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
public ColumnAttribute(string Title = "", bool Visible = true, int Width = 0,
GridViewAutoSize GridViewAutoSize = GridViewAutoSize.None, bool IsUseAutoSize = false)
{
this.Title = Title;
this.Visible = Visible;
this.Width = Width;
this.GridViewAutoSize = GridViewAutoSize;
this.IsUseAutoSize = IsUseAutoSize;
}
public string Title { get; private set; }
public bool Visible { get; private set; }
public int Width { get; private set; }
public GridViewAutoSize GridViewAutoSize { get; private set; }
public bool IsUseAutoSize { get; private set; }
}
}

View File

@ -0,0 +1,14 @@
namespace BarContracts.Attrubites
{
public enum GridViewAutoSize
{
NotSet = 0,
None = 1,
ColumnHeader = 2,
AllCellsExceptHeader = 4,
AllCells = 6,
DisplayedCellsExceptHeader = 8,
DisplayedCells = 10,
Fill = 16
}
}

View File

@ -6,6 +6,13 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Unity" Version="5.11.10" />
<PackageReference Include="Unity.Microsoft.Logging" Version="5.11.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\BarDataModels\BarDataModels\BarDataModels.csproj" />
</ItemGroup>

View File

@ -0,0 +1,7 @@
namespace BarContracts.BindingModels
{
public class BackUpSaveBindingModel
{
public string FolderName { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,17 @@
namespace BarContracts.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,11 @@
namespace BarContracts.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 BarDataModels.Models;
namespace BarContracts.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

@ -0,0 +1,9 @@
using BarContracts.BindingModels;
namespace BarContracts.BusinessLogicContracts
{
public interface IBackUpLogic
{
void CreateBackUp(BackUpSaveBindingModel Model);
}
}

View File

@ -0,0 +1,13 @@
using BarContracts.BindingModels;
using BarContracts.SearchModels;
using BarContracts.ViewModels;
namespace BarContracts.BusinessLogicContracts
{
public interface IMessageInfoLogic
{
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? Model);
bool Create(MessageInfoBindingModel Model);
}
}

View File

@ -0,0 +1,48 @@
using Microsoft.Extensions.Logging;
namespace BarContracts.DI
{
public class DependencyManager
{
private readonly IDependencyContainer _dependencyContainer;
private static DependencyManager? _manager;
private static readonly object _lock = new();
private DependencyManager()
{
_dependencyContainer = new ServiceDependencyContainer();
}
public static DependencyManager Instance
{
get
{
if (_manager == null)
{
lock (_lock) { _manager = new DependencyManager(); }
}
return _manager;
}
}
public static void InitDependency()
{
var Ext = ServiceProviderLoader.GetImplementationExtension();
if (Ext == null)
{
throw new ArgumentNullException("Отсутствуют компоненты для загрузки зависимостей по модулям");
}
Ext.RegisterServices();
}
public void AddLogging(Action<ILoggingBuilder> Configure) => _dependencyContainer.AddLogging(Configure);
public void RegisterType<T, U>(bool IsSingleton = false) where U : class, T where T : class => _dependencyContainer.RegisterType<T, U>(IsSingleton);
public void RegisterType<T>(bool IsSingleton = false) where T : class => _dependencyContainer.RegisterType<T>(IsSingleton);
public T Resolve<T>() => _dependencyContainer.Resolve<T>();
}
}

View File

@ -0,0 +1,15 @@
using Microsoft.Extensions.Logging;
namespace BarContracts.DI
{
public interface IDependencyContainer
{
void AddLogging(Action<ILoggingBuilder> Configure);
void RegisterType<T, U>(bool IsSingleton) where U : class, T where T : class;
void RegisterType<T>(bool IsSingleton) where T : class;
T Resolve<T>();
}
}

View File

@ -0,0 +1,9 @@
namespace BarContracts.DI
{
public interface IImplementationExtension
{
public int Priority { get; }
public void RegisterServices();
}
}

View File

@ -0,0 +1,59 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace BarContracts.DI
{
public class ServiceDependencyContainer : IDependencyContainer
{
private ServiceProvider? _serviceProvider;
private readonly ServiceCollection _serviceCollection;
public ServiceDependencyContainer()
{
_serviceCollection = new ServiceCollection();
}
public void AddLogging(Action<ILoggingBuilder> Configure)
{
_serviceCollection.AddLogging(Configure);
}
public void RegisterType<T, U>(bool IsSingleton) where U : class, T where T : class
{
if (IsSingleton)
{
_serviceCollection.AddSingleton<T, U>();
}
else
{
_serviceCollection.AddTransient<T, U>();
}
_serviceProvider = null;
}
public void RegisterType<T>(bool IsSingleton) where T : class
{
if (IsSingleton)
{
_serviceCollection.AddSingleton<T>();
}
else
{
_serviceCollection.AddTransient<T>();
}
_serviceProvider = null;
}
public T Resolve<T>()
{
if (_serviceProvider == null)
{
_serviceProvider = _serviceCollection.BuildServiceProvider();
}
return _serviceProvider.GetService<T>()!;
}
}
}

View File

@ -0,0 +1,50 @@
using System.Reflection;
namespace BarContracts.DI
{
public static class ServiceProviderLoader
{
public static IImplementationExtension? GetImplementationExtension()
{
IImplementationExtension? Source = null;
var Files = Directory.GetFiles(TryGetImplementationExtensionsFolder(), "*.dll", SearchOption.AllDirectories);
foreach (var File in Files.Distinct())
{
Assembly Asm = Assembly.LoadFrom(File);
foreach (var Type in Asm.GetExportedTypes())
{
if (Type.IsClass && typeof(IImplementationExtension).IsAssignableFrom(Type))
{
if (Source == null)
{
Source = (IImplementationExtension)Activator.CreateInstance(Type)!;
}
else
{
var NewSource = (IImplementationExtension)Activator.CreateInstance(Type)!;
if (NewSource.Priority > Source.Priority)
{
Source = NewSource;
}
}
}
}
}
return Source;
}
private static string TryGetImplementationExtensionsFolder()
{
var WorkingDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
while (WorkingDirectory != null && !WorkingDirectory.GetDirectories("ImplementationExtensions", SearchOption.AllDirectories).Any(x => x.Name == "ImplementationExtensions"))
{
WorkingDirectory = WorkingDirectory.Parent;
}
return $"{WorkingDirectory?.FullName}\\ImplementationExtensions";
}
}
}

View File

@ -0,0 +1,38 @@
using Microsoft.Extensions.Logging;
using Unity;
using Unity.Microsoft.Logging;
namespace BarContracts.DI
{
public class UnityDependencyContainer : IDependencyContainer
{
private readonly IUnityContainer _container;
public UnityDependencyContainer()
{
_container = new UnityContainer();
}
public void AddLogging(Action<ILoggingBuilder> Configure)
{
var Factory = LoggerFactory.Create(Configure);
_container.AddExtension(new LoggingExtension(Factory));
}
public void RegisterType<T>(bool IsSingleton) where T : class
{
_container.RegisterType<T>(IsSingleton ? TypeLifetime.Singleton : TypeLifetime.Transient);
}
public T Resolve<T>()
{
return _container.Resolve<T>();
}
void IDependencyContainer.RegisterType<T, U>(bool IsSingleton)
{
_container.RegisterType<T, U>(IsSingleton ? TypeLifetime.Singleton : TypeLifetime.Transient);
}
}
}

View File

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

View File

@ -0,0 +1,9 @@
namespace BarContracts.StoragesContracts
{
public interface IBackUpInfo
{
List<T>? GetList<T>() where T : class, new();
Type? GetTypeByModelInterface(string ModelInterfaceName);
}
}

View File

@ -0,0 +1,17 @@
using BarContracts.BindingModels;
using BarContracts.SearchModels;
using BarContracts.ViewModels;
namespace BarContracts.StoragesContracts
{
public interface IMessageInfoStorage
{
List<MessageInfoViewModel> GetFullList();
List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel Model);
MessageInfoViewModel? GetElement(MessageInfoSearchModel Model);
MessageInfoViewModel? Insert(MessageInfoBindingModel Model);
}
}

View File

@ -1,19 +1,20 @@
using BarDataModels.Models;
using System.ComponentModel;
using BarContracts.Attrubites;
using BarDataModels.Models;
namespace BarContracts.ViewModels
{
public class ClientViewModel : IClientModel
{
[Column(Visible: false)]
public int Id { get; set; }
[DisplayName("ФИО клиента")]
[Column(Title: "ФИО клиента", Width: 150)]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Логин (эл. почта)")]
[Column(Title: "Логин (эл. почта)", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public string Email { get; set; } = string.Empty;
[DisplayName("Пароль")]
[Column(Title: "Пароль", Width: 150)]
public string Password { get; set; } = string.Empty;
}
}

View File

@ -1,22 +1,20 @@
using BarDataModels.Models;
using System.ComponentModel;
using BarContracts.Attrubites;
using BarDataModels.Models;
namespace BarContracts.ViewModels
{
public class CocktailViewModel : ICocktailModel
{
[Column(Visible: false)]
public int Id { get; set; }
[DisplayName("Название Коктейльа")]
[Column(Title: "Название коктейльа", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public string CocktailName { get; set; } = string.Empty;
[DisplayName("Цена")]
[Column(Title: "Цена", Width: 70)]
public double Price { get; set; }
public Dictionary<int, (IComponentModel, int)> CocktailComponents
{
get;
set;
} = new();
[Column(Visible: false)]
public Dictionary<int, (IComponentModel, int)> CocktailComponents { get; set; } = new();
}
}

View File

@ -1,16 +1,17 @@
using BarDataModels.Models;
using System.ComponentModel;
using BarContracts.Attrubites;
using BarDataModels.Models;
namespace BarContracts.ViewModels
{
public class ComponentViewModel : IComponentModel
{
[Column(Visible: false)]
public int Id { get; set; }
[DisplayName("Название компонента")]
[Column(Title: "Название компонента", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public string ComponentName { get; set; } = string.Empty;
[DisplayName("Цена")]
[Column(Title: "Цена", Width: 150)]
public double Cost { get; set; }
}
}

View File

@ -1,22 +1,23 @@
using BarDataModels.Models;
using System.ComponentModel;
using BarContracts.Attrubites;
using BarDataModels.Models;
namespace BarContracts.ViewModels
{
public class ImplementerViewModel : IImplementerModel
{
[Column(Visible: false)]
public int Id { get; set; }
[DisplayName("ФИО исполнителя")]
[Column(Title: "ФИО исполнителя", GridViewAutoSize: GridViewAutoSize.AllCells, IsUseAutoSize: true)]
public string ImplementerFIO { get; set; } = string.Empty;
[DisplayName("Пароль")]
[Column(Title: "Пароль", Width: 100)]
public string Password { get; set; } = string.Empty;
[DisplayName("Стаж работы")]
[Column(Title: "Стаж работы", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public int WorkExperience { get; set; }
[DisplayName("Квалификация")]
[Column(Title: "Квалификация", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public int Qualification { get; set; }
}
}

View File

@ -0,0 +1,29 @@
using BarContracts.Attrubites;
using BarDataModels.Models;
namespace BarContracts.ViewModels
{
public class MessageInfoViewModel : IMessageInfoModel
{
[Column(Visible: false)]
public int Id { get; set; }
[Column(Visible: false)]
public string MessageId { get; set; } = string.Empty;
[Column(Visible: false)]
public int? ClientId { get; set; }
[Column(Title: "Отправитель", Width: 150)]
public string SenderName { get; set; } = string.Empty;
[Column(Title: "Дата доставки", Width: 120)]
public DateTime DateDelivery { get; set; }
[Column(Title: "Тема", Width: 120)]
public string Subject { get; set; } = string.Empty;
[Column(Title: "Содержание", GridViewAutoSize: GridViewAutoSize.Fill, IsUseAutoSize: true)]
public string Body { get; set; } = string.Empty;
}
}

View File

@ -1,42 +1,48 @@
using BarDataModels.Enums;
using BarContracts.Attrubites;
using BarDataModels.Enums;
using BarDataModels.Models;
using System.ComponentModel;
namespace BarContracts.ViewModels
{
public class OrderViewModel : IOrderModel
{
[DisplayName("Номер")]
[Column(Title: "Номер", GridViewAutoSize: GridViewAutoSize.AllCells, IsUseAutoSize: true)]
public int Id { get; set; }
[Column(Visible: false)]
public int CocktailId { get; set; }
[DisplayName("Коктейль")]
[Column(Title: "Коктейль", GridViewAutoSize: GridViewAutoSize.AllCells, IsUseAutoSize: true)]
public string CocktailName { get; set; } = string.Empty;
[Column(Visible: false)]
public int ClientId { get; set; }
[DisplayName("Клиент")]
[Column(Title: "Клиент", Width: 120)]
public string ClientFIO { get; set; } = string.Empty;
[Column(Title: "Почта клиента", Width: 190)]
public string ClientEmail { get; set; } = string.Empty;
[Column(Visible: false)]
public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")]
[Column(Title: "Исполнитель", Width: 120)]
public string? ImplementerFIO { get; set; }
[DisplayName("Количество")]
[Column(Title: "Количество", Width: 100)]
public int Count { get; set; }
[DisplayName("Сумма")]
[Column(Title: "Сумма", Width: 75)]
public double Sum { get; set; }
[DisplayName("Статус")]
[Column(Title: "Статус", Width: 70)]
public OrderStatus Status { get; set; } = OrderStatus.Undefined;
[DisplayName("Дата создания")]
[Column(Title: "Дата создания", Width: 120)]
public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
[Column(Title: "Дата выполнения", Width: 120)]
public DateTime? DateImplement { get; set; }
}
}

View File

@ -1,11 +0,0 @@
namespace BarContracts.ViewModels
{
public class ReportCocktailComponentViewModel
{
public string CocktailName { get; set; } = string.Empty;
public int TotalCount { get; set; }
public List<(string Component, int Count)> Components { get; set; } = new();
}
}

View File

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

View File

@ -29,5 +29,7 @@ namespace BarDatabaseImplement
public virtual DbSet<Client> Clients { set; get; }
public virtual DbSet<Implementer> Implementers { set; get; }
public virtual DbSet<MessageInfo> Messages { set; get; }
}
}

View File

@ -0,0 +1,56 @@
using BarContracts.BindingModels;
using BarContracts.SearchModels;
using BarContracts.StoragesContracts;
using BarContracts.ViewModels;
using BarDatabaseImplement.Models;
namespace BarDatabaseImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
public List<MessageInfoViewModel> GetFullList()
{
using var Context = new BarDatabase();
return Context.Messages
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel Model)
{
using var Context = new BarDatabase();
return Context.Messages
.Where(x => x.ClientId.HasValue && x.ClientId == Model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel Model)
{
if (string.IsNullOrEmpty(Model.MessageId))
return null;
using var Context = new BarDatabase();
return Context.Messages
.FirstOrDefault(x => x.MessageId == Model.MessageId)?
.GetViewModel;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel Model)
{
var NewMessageInfo = MessageInfo.Create(Model);
if (NewMessageInfo == null)
return null;
using var Context = new BarDatabase();
Context.Messages.Add(NewMessageInfo);
Context.SaveChanges();
return NewMessageInfo.GetViewModel;
}
}
}

View File

@ -0,0 +1,284 @@
// <auto-generated />
using System;
using BarDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace BarDatabaseImplement.Migrations
{
[DbContext(typeof(BarDatabase))]
[Migration("20240621172735_3")]
partial class _3
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("BarDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Cocktail", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("CocktailName")
.IsRequired()
.HasColumnType("text");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("Id");
b.ToTable("Cocktails");
});
modelBuilder.Entity("BarDatabaseImplement.Models.CocktailComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("CocktailId")
.HasColumnType("integer");
b.Property<int>("ComponentId")
.HasColumnType("integer");
b.Property<int>("Count")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CocktailId");
b.HasIndex("ComponentId");
b.ToTable("CocktailComponents");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("text");
b.Property<double>("Cost")
.HasColumnType("double precision");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Implementer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Qualification")
.HasColumnType("integer");
b.Property<int>("WorkExperience")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("Implementers");
});
modelBuilder.Entity("BarDatabaseImplement.Models.MessageInfo", b =>
{
b.Property<string>("MessageId")
.HasColumnType("text");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("ClientId")
.HasColumnType("integer");
b.Property<DateTime>("DateDelivery")
.HasColumnType("timestamp without time zone");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("text");
b.HasKey("MessageId");
b.ToTable("Messages");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("ClientId")
.HasColumnType("integer");
b.Property<int>("CocktailId")
.HasColumnType("integer");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<DateTime>("DateCreate")
.HasColumnType("timestamp without time zone");
b.Property<DateTime?>("DateImplement")
.HasColumnType("timestamp without time zone");
b.Property<int?>("ImplementerId")
.HasColumnType("integer");
b.Property<int>("Status")
.HasColumnType("integer");
b.Property<double>("Sum")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("CocktailId");
b.HasIndex("ImplementerId");
b.ToTable("Orders");
});
modelBuilder.Entity("BarDatabaseImplement.Models.CocktailComponent", b =>
{
b.HasOne("BarDatabaseImplement.Models.Cocktail", "Cocktail")
.WithMany("Components")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("BarDatabaseImplement.Models.Component", "Component")
.WithMany("CocktailComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Cocktail");
b.Navigation("Component");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Order", b =>
{
b.HasOne("BarDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("BarDatabaseImplement.Models.Cocktail", "Cocktail")
.WithMany("Orders")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("BarDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Order")
.HasForeignKey("ImplementerId");
b.Navigation("Client");
b.Navigation("Cocktail");
b.Navigation("Implementer");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Cocktail", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Component", b =>
{
b.Navigation("CocktailComponents");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Order");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,35 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BarDatabaseImplement.Migrations
{
public partial class _3 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Messages",
columns: table => new
{
MessageId = table.Column<string>(type: "text", nullable: false),
ClientId = table.Column<int>(type: "integer", nullable: true),
SenderName = table.Column<string>(type: "text", nullable: false),
DateDelivery = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
Subject = table.Column<string>(type: "text", nullable: false),
Body = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Messages", x => x.MessageId);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Messages");
}
}
}

View File

@ -140,6 +140,34 @@ namespace BarDatabaseImplement.Migrations
b.ToTable("Implementers");
});
modelBuilder.Entity("BarDatabaseImplement.Models.MessageInfo", b =>
{
b.Property<string>("MessageId")
.HasColumnType("text");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("ClientId")
.HasColumnType("integer");
b.Property<DateTime>("DateDelivery")
.HasColumnType("timestamp without time zone");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("text");
b.HasKey("MessageId");
b.ToTable("Messages");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@ -216,13 +244,15 @@ namespace BarDatabaseImplement.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("BarDatabaseImplement.Models.Implementer", null)
b.HasOne("BarDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Order")
.HasForeignKey("ImplementerId");
b.Navigation("Client");
b.Navigation("Cocktail");
b.Navigation("Implementer");
});
modelBuilder.Entity("BarDatabaseImplement.Models.Client", b =>

View File

@ -0,0 +1,49 @@
using BarContracts.BindingModels;
using BarContracts.ViewModels;
using BarDataModels.Models;
using System.ComponentModel.DataAnnotations;
namespace BarDatabaseImplement.Models
{
public class MessageInfo : IMessageInfoModel
{
[Key]
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
public string SenderName { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public static MessageInfo? Create(MessageInfoBindingModel? Model)
{
if (Model == null)
return null;
return new()
{
MessageId = Model.MessageId,
ClientId = Model.ClientId,
SenderName = Model.SenderName,
DateDelivery = Model.DateDelivery,
Subject = Model.Subject,
Body = Model.Body
};
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body
};
}
}

View File

@ -19,6 +19,7 @@ namespace BarDatabaseImplement.Models
public int ClientId { get; private set; }
public virtual Client Client { get; set; }
public int? ImplementerId { get; private set; }
public virtual Implementer? Implementer { get; set; }
@ -74,6 +75,7 @@ namespace BarDatabaseImplement.Models
ImplementerId = ImplementerId,
CocktailName = Cocktail.CocktailName,
ClientFIO = Client.ClientFIO,
ClientEmail = Client.Email,
ImplementerFIO = Implementer?.ImplementerFIO,
Count = Count,
Sum = Sum,

View File

@ -11,4 +11,8 @@
<ProjectReference Include="..\..\BarDataModels\BarDataModels\BarDataModels.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy /Y &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)ImplementationExtensions\*.dll&quot;" />
</Target>
</Project>

View File

@ -11,14 +11,21 @@ namespace BarListImplement
public List<Order> Orders { get; set; }
public List<Cocktail> Cocktails { get; set; }
public List<Client> Clients { get; set; }
public List<Implementer> Implementers { get; set; }
public List<MessageInfo> Messages { get; set; }
private DataListSingleton()
{
Components = new List<Component>();
Orders = new List<Order>();
Cocktails = new List<Cocktail>();
Clients = new List<Client>();
Implementers = new List<Implementer>();
Messages = new List<MessageInfo>();
}
public static DataListSingleton GetInstance()

View File

@ -0,0 +1,22 @@
using BarContracts.DI;
using BarContracts.StoragesContracts;
using BarListImplement.Implements;
namespace BarListImplement
{
public class ImplementationExtension : IImplementationExtension
{
public int Priority => 0;
public void RegisterServices()
{
DependencyManager.Instance.RegisterType<IClientStorage, ClientStorage>();
DependencyManager.Instance.RegisterType<IComponentStorage, ComponentStorage>();
DependencyManager.Instance.RegisterType<IImplementerStorage, ImplementerStorage>();
DependencyManager.Instance.RegisterType<IMessageInfoStorage, MessageInfoStorage>();
DependencyManager.Instance.RegisterType<IOrderStorage, OrderStorage>();
DependencyManager.Instance.RegisterType<ICocktailStorage, CocktailStorage>();
DependencyManager.Instance.RegisterType<IBackUpInfo, BackUpInfo>();
}
}
}

View File

@ -0,0 +1,17 @@
using BarContracts.StoragesContracts;
namespace BarListImplement.Implements
{
public class BackUpInfo : IBackUpInfo
{
public List<T>? GetList<T>() where T : class, new()
{
throw new NotImplementedException();
}
public Type? GetTypeByModelInterface(string ModelInterfaceName)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,104 @@
using BarContracts.BindingModels;
using BarContracts.SearchModels;
using BarContracts.StoragesContracts;
using BarContracts.ViewModels;
using BarListImplement.Models;
namespace BarListImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
private readonly DataListSingleton _source;
public ImplementerStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<ImplementerViewModel> GetFullList()
{
var Result = new List<ImplementerViewModel>();
foreach (var Implementer in _source.Implementers)
{
Result.Add(Implementer.GetViewModel);
}
return Result;
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel Model)
{
if (string.IsNullOrEmpty(Model.ImplementerFIO))
return new();
return _source.Implementers
.Where(x => (!string.IsNullOrEmpty(Model.ImplementerFIO) && x.ImplementerFIO.Contains(Model.ImplementerFIO)))
.Select(x => x.GetViewModel)
.ToList();
}
public ImplementerViewModel? GetElement(ImplementerSearchModel Model)
{
foreach (var Implementer in _source.Implementers)
{
if ((Model.Id.HasValue && Implementer.Id == Model.Id) ||
(!string.IsNullOrEmpty(Model.ImplementerFIO) && Implementer.ImplementerFIO == Model.ImplementerFIO))
{
return Implementer.GetViewModel;
}
}
return null;
}
public ImplementerViewModel? Insert(ImplementerBindingModel Model)
{
Model.Id = 1;
foreach (var Implementer in _source.Implementers)
{
if (Model.Id <= Implementer.Id)
{
Model.Id = Implementer.Id + 1;
}
}
var NewImplementer = Implementer.Create(Model);
if (NewImplementer == null)
return null;
_source.Implementers.Add(NewImplementer);
return NewImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel Model)
{
foreach (var Implementer in _source.Implementers)
{
if (Implementer.Id == Model.Id)
{
Implementer.Update(Model);
return Implementer.GetViewModel;
}
}
return null;
}
public ImplementerViewModel? Delete(ImplementerBindingModel Model)
{
for (int i = 0; i < _source.Implementers.Count; ++i)
{
if (_source.Implementers[i].Id == Model.Id)
{
var Implementer = _source.Implementers[i];
_source.Implementers.RemoveAt(i);
return Implementer.GetViewModel;
}
}
return null;
}
}
}

View File

@ -0,0 +1,54 @@
using BarContracts.BindingModels;
using BarContracts.SearchModels;
using BarContracts.StoragesContracts;
using BarContracts.ViewModels;
using BarListImplement.Models;
namespace BarListImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataListSingleton _source;
public MessageInfoStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<MessageInfoViewModel> GetFullList()
{
return _source.Messages
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel Model)
{
return _source.Messages
.Where(x => x.ClientId.HasValue && x.ClientId == Model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel Model)
{
if (string.IsNullOrEmpty(Model.MessageId))
return null;
return _source.Messages
.FirstOrDefault(x => x.MessageId == Model.MessageId)?
.GetViewModel;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel Model)
{
var NewMessageInfo = MessageInfo.Create(Model);
if (NewMessageInfo == null)
return null;
_source.Messages.Add(NewMessageInfo);
return NewMessageInfo.GetViewModel;
}
}
}

View File

@ -0,0 +1,54 @@
using BarContracts.BindingModels;
using BarContracts.ViewModels;
using BarDataModels.Models;
namespace BarListImplement.Models
{
public class Implementer : IImplementerModel
{
public int Id { get; private set; }
public string ImplementerFIO { get; private set; } = string.Empty;
public string Password { get; private set; } = string.Empty;
public int WorkExperience { get; private set; }
public int Qualification { get; private set; }
public static Implementer? Create(ImplementerBindingModel Model)
{
if (Model == null)
{
return null;
}
return new()
{
Id = Model.Id,
Password = Model.Password,
Qualification = Model.Qualification,
ImplementerFIO = Model.ImplementerFIO,
WorkExperience = Model.WorkExperience,
};
}
public void Update(ImplementerBindingModel Model)
{
if (Model == null)
return;
Password = Model.Password;
Qualification = Model.Qualification;
ImplementerFIO = Model.ImplementerFIO;
WorkExperience = Model.WorkExperience;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
Password = Password,
Qualification = Qualification,
ImplementerFIO = ImplementerFIO,
};
}
}

View File

@ -0,0 +1,49 @@
using BarContracts.BindingModels;
using BarContracts.ViewModels;
using BarDataModels.Models;
namespace BarListImplement.Models
{
public class MessageInfo : IMessageInfoModel
{
public int Id { get; set; }
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
public string SenderName { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public static MessageInfo? Create(MessageInfoBindingModel? Model)
{
if (Model == null)
return null;
return new()
{
MessageId = Model.MessageId,
ClientId = Model.ClientId,
SenderName = Model.SenderName,
DateDelivery = Model.DateDelivery,
Subject = Model.Subject,
Body = Model.Body
};
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body
};
}
}

View File

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

View File

@ -1,5 +1,8 @@
using BarBusinessLogic.BusinessLogics;
using BarBusinessLogic.MailWorker;
using BarContracts.BindingModels;
using BarContracts.BusinessLogicContracts;
using BarContracts.BusinessLogicsContracts;
using BarContracts.StoragesContracts;
using BarDatabaseImplement.Implements;
using Microsoft.OpenApi.Models;
@ -12,9 +15,17 @@ Builder.Logging.AddLog4Net("log4net.config");
Builder.Services.AddTransient<IClientStorage, ClientStorage>();
Builder.Services.AddTransient<IOrderStorage, OrderStorage>();
Builder.Services.AddTransient<ICocktailStorage, CocktailStorage>();
Builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
Builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
Builder.Services.AddTransient<IOrderLogic, OrderLogic>();
Builder.Services.AddTransient<IClientLogic, ClientLogic>();
Builder.Services.AddTransient<ICocktailLogic, CocktailLogic>();
Builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
Builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
Builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
Builder.Services.AddControllers();
Builder.Services.AddEndpointsApiExplorer();
@ -29,6 +40,18 @@ Builder.Services.AddSwaggerGen(c =>
var App = Builder.Build();
var MailSender = App.Services.GetService<AbstractMailWorker>();
MailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = Builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty,
MailPassword = Builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty,
SmtpClientHost = Builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty,
SmtpClientPort = Convert.ToInt32(Builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()),
PopHost = Builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty,
PopPort = Convert.ToInt32(Builder.Configuration?.GetSection("PopPort")?.Value?.ToString())
});
if (App.Environment.IsDevelopment())
{
App.UseSwagger();

Binary file not shown.

Binary file not shown.

Binary file not shown.