Compare commits

...

52 Commits

Author SHA1 Message Date
50ff12238f убрала статус заказа из модели отчета 2024-05-20 10:55:41 +04:00
8f3b2300f3 вот теперь конфликты решены (надеюсь) и ветка для лабы создана 2024-05-19 18:41:54 +04:00
3da10810c6 создала ветку для 4 лабы сложной, но что-то идет не так.. 2024-05-19 18:36:02 +04:00
824d6c2af8 вроде готовая сложная третья лаба для показа, но напрашивается еще добавить норм отображение ошибки о количестве суши в магазинах 2024-04-21 23:51:28 +04:00
57c68d01a8 в общем, создала модели Магазин и МагазинСуши для бд 2024-04-21 17:49:53 +04:00
a9e6e02533 создала вроде... 3 сложную лабу 2024-04-21 16:25:24 +04:00
23c3187703 Merge branch 'LabWork12' into LabWork13 2024-04-21 16:21:19 +04:00
ekallin
73ff095c26 изменен способ сохранения в отчет (убрала комментарий просто) 2024-04-09 20:34:37 +03:00
ekallin
736bd45bbc готово для пул реквеста лаба 2 сложная 2024-04-08 11:28:35 +03:00
ekallin
2b09563d00 все готово для пул реквеста лаба 4 2024-04-08 10:32:57 +03:00
ekallin
2c3b04226c нк вроде все красиво и можно показывать преподу 2024-04-07 20:47:02 +03:00
ekallin
d52ddf515e добавляена форма продажи суши, исправлена ошибка при изменеянии статуса заказа на "выдан". осталось прописать красивые исключения 2024-04-07 20:17:08 +03:00
ekallin
7e2dcf663e немного изменений и добавлены классы для магазина в ...FileImplement 2024-04-07 12:19:30 +03:00
ekallin
7f2811d1cf создание 2 усложненки 2024-04-07 09:50:30 +03:00
ekallin
65704d7e48 неужели. готовая лаба 4 для показа 2024-03-30 20:23:52 +03:00
ekallin
408a86401a изменения к требованиям по сохранению в ворд и эксель 2024-03-30 18:38:45 +03:00
ekallin
9acfdd7a5b ОНО РАБОТАЕТ, ОНО ЖИВОЕ Я ПЕРЕУСТАНОВИЛА МИГРА ДОК на более раннюю версию 2024-03-29 11:44:11 +03:00
ekallin
8c41ac1719 начальные изменения в ворд по требованиям 2024-03-25 10:50:13 +04:00
ekallin
890f11f6d4 Фикс базы данных и фильтрации 2024-03-25 09:56:01 +04:00
ekallin
8ffd918013 Merge branch 'LabWork04' of https://git.is.ulstu.ru/ekallin/PIbd-21_Bakalskaya_E.D._SushiBar into LabWork04 2024-03-25 00:08:35 +04:00
ekallin
7cb45bfe43 попытки все исправить силы на исходе 2024-03-25 00:08:21 +04:00
2483708341 Решение проблемы с сохранением отчета в PDF и реализация логики фильтрации заказов 2024-03-24 23:52:35 +04:00
ekallin
f45e4cfaee переделано в List<Turple>, добавлен обработчик исключения на метод SavePdf 2024-03-24 22:25:36 +04:00
ekallin
1aa25cc87c почти готово БЕЗ УЧЕТА ТРЕБОВАНИЙ есть баг с загрузкой отчета 2024-03-24 20:42:18 +04:00
ekallin
c3c88ad6e1 изменены главная форма и еще что-то для работы с отчетами 2024-03-24 18:34:36 +04:00
ekallin
4a5bfb20da формы для отчетов и сам отчет 2024-03-24 18:34:06 +04:00
ekallin
d87458a10a логика отчета и поменяла логику в классе Order 2024-03-24 00:59:51 +04:00
ekallin
311ef7245c классы для пдф, ворд (пофиксила) 2024-03-24 00:59:16 +04:00
ekallin
910d4952d4 реализованы все классы для сохранения в эксель таблицу 2024-03-24 00:58:27 +04:00
ekallin
7d2cf9694c добавлены классы для работы с вордовским документом (какие данные передавать, как форматировать) 2024-03-23 17:52:58 +04:00
ekallin
7bd504551a добавлен интерфейс логики отчета 2024-03-23 17:39:13 +04:00
ekallin
4221a8e1d9 добавлены классы вьюМодел для заказов и изделий-компонентов 2024-03-23 17:38:43 +04:00
ekallin
f2230ee0c5 создана 4 лаба, добавлен класс ReportBindingModel 2024-03-23 17:37:52 +04:00
ekallin
0abee5b276 исправлены ошибки, работает лаба 11 (усложненка), готова к показу преподавателю 2024-03-11 12:09:55 +04:00
ekallin
c234c1a19d чистый код, готова лаба 3 для пул реквеста 2024-03-11 09:27:23 +04:00
ekallin
7f730736d9 в програм добавлены нужные зависимости, нужно изменить форму магазина и везде прописать логику 2024-03-10 23:53:01 +04:00
ekallin
85e2c1f027 Добавлена форма FormShop 2024-03-10 23:03:51 +04:00
ekallin
4c1af6acb5 добавлены нужные файлы в ...Implements, а также доделана бизнес логика. остались формы 2024-03-10 22:35:26 +04:00
ekallin
745dbe385f добавлены файлы в проект ..Contracts и начата логика магазина 2024-03-10 18:26:10 +04:00
ekallin
973afb771a создание лабы 1 усложненки, интерфейса ShopModel 2024-03-10 17:20:17 +04:00
ekallin
928feaa4c0 вроде готовая лаба 3 для показа преподавателю 2024-03-10 14:16:51 +04:00
ekallin
cb4cd1184b закончена папка Models и начата Implements 2024-03-09 21:37:08 +04:00
ekallin
2510a97130 Добавлены классы SushiComponent & Sushi 2024-03-09 01:00:32 +04:00
ekallin
dc07d5272d Создана ветка 3 лабы, установлены пакеты, добавлен класс Component ...DatabaseImplement 2024-03-09 00:35:52 +04:00
ekallin
8be30b7568 чтот какие-то изменени в лабе 2 2024-02-26 08:37:22 +04:00
ekallin
163e6ded4e Готовая лаба 2 для показа 2024-02-25 21:26:19 +04:00
ekallin
8f2115eb06 Добавлены модели в новой библиотеке SushiBarFileImplement 2024-02-25 20:30:50 +04:00
ekallin
0c5d62f563 Добавлены все оставшиеся библиотеки, классы, формы. Все распределено по папкам, готово к созданию PR 2024-02-25 19:52:48 +04:00
ekallin
db6fd2a647 Добавлены библиотеки SushiBarBusinessLogic и SushiBarListImplements 2024-02-25 19:43:57 +04:00
ekallin
09c564caae Добавлена библиотека SushiBarContracts 2024-02-25 19:29:35 +04:00
ekallin
62aa143ea2 Добавлена библиотека SushiBarModels 2024-02-25 19:28:02 +04:00
ekallin
d86ff794e0 Создание 1 лабы 2024-02-25 19:25:03 +04:00
137 changed files with 11315 additions and 13 deletions

3
.gitignore vendored
View File

@ -17,6 +17,9 @@
# Mono auto generated files
mono_crash.*
*.dll
/SushiBar/ImplementationExtensions
# Build results
[Dd]ebug/
[Dd]ebugPublic/

View File

@ -0,0 +1,128 @@
namespace SushiBarView
{
partial class FormComponent
{
/// <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()
{
labelComponentName = new Label();
labelCost = new Label();
textBoxComponentName = new TextBox();
textBoxComponentCost = new TextBox();
buttonSaveComponent = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// labelComponentName
//
labelComponentName.AutoSize = true;
labelComponentName.Font = new Font("Candara", 12F);
labelComponentName.Location = new Point(20, 29);
labelComponentName.Margin = new Padding(4, 0, 4, 0);
labelComponentName.Name = "labelComponentName";
labelComponentName.Size = new Size(93, 24);
labelComponentName.TabIndex = 0;
labelComponentName.Text = "Название";
//
// labelCost
//
labelCost.AutoSize = true;
labelCost.Font = new Font("Candara", 12F);
labelCost.Location = new Point(29, 111);
labelCost.Margin = new Padding(4, 0, 4, 0);
labelCost.Name = "labelCost";
labelCost.Size = new Size(53, 24);
labelCost.TabIndex = 1;
labelCost.Text = "Цена";
//
// textBoxComponentName
//
textBoxComponentName.Anchor = AnchorStyles.Top | AnchorStyles.Right;
textBoxComponentName.Location = new Point(134, 21);
textBoxComponentName.Name = "textBoxComponentName";
textBoxComponentName.Size = new Size(355, 32);
textBoxComponentName.TabIndex = 2;
//
// textBoxComponentCost
//
textBoxComponentCost.Anchor = AnchorStyles.Top | AnchorStyles.Right;
textBoxComponentCost.Location = new Point(134, 103);
textBoxComponentCost.Name = "textBoxComponentCost";
textBoxComponentCost.Size = new Size(355, 32);
textBoxComponentCost.TabIndex = 3;
//
// buttonSaveComponent
//
buttonSaveComponent.Anchor = AnchorStyles.Bottom;
buttonSaveComponent.Location = new Point(134, 161);
buttonSaveComponent.Name = "buttonSaveComponent";
buttonSaveComponent.Size = new Size(116, 39);
buttonSaveComponent.TabIndex = 4;
buttonSaveComponent.Text = "Сохранить";
buttonSaveComponent.UseVisualStyleBackColor = true;
buttonSaveComponent.Click += buttonSaveComponent_Click;
//
// buttonCancel
//
buttonCancel.Anchor = AnchorStyles.Bottom;
buttonCancel.Location = new Point(373, 161);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(116, 39);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// FormComponent
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(515, 230);
Controls.Add(buttonCancel);
Controls.Add(buttonSaveComponent);
Controls.Add(textBoxComponentCost);
Controls.Add(textBoxComponentName);
Controls.Add(labelCost);
Controls.Add(labelComponentName);
Font = new Font("Candara", 12F, FontStyle.Regular, GraphicsUnit.Point, 204);
Margin = new Padding(4);
Name = "FormComponent";
Text = "Компонент";
Load += FormComponents_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelComponentName;
private Label labelCost;
private TextBox textBoxComponentName;
private TextBox textBoxComponentCost;
private Button buttonSaveComponent;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,90 @@
using Microsoft.Extensions.Logging;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using System.Windows.Forms;
namespace SushiBarView
{
public partial class FormComponent : Form
{
private readonly ILogger _logger;
private readonly IComponentLogic _logic;
private int? _id;
public int Id
{
set { _id = value; }
}
public FormComponent(ILogger<FormComponent> logger, IComponentLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormComponents_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
try
{
_logger.LogInformation("Получение компонента");
var view = _logic.ReadElement(new ComponentSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxComponentName.Text = view.ComponentName;
textBoxComponentCost.Text = view.Cost.ToString();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения компонента");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
private void buttonSaveComponent_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxComponentName.Text))
{
MessageBox.Show("Заполните название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение компонента");
try
{
var model = new ComponentBindingModel
{
Id = _id ?? 0,
ComponentName = textBoxComponentName.Text,
Cost = Convert.ToDouble(textBoxComponentCost.Text)
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение",
MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения компонента");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

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

@ -0,0 +1,123 @@
namespace SushiBarView
{
partial class FormComponents
{
/// <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();
buttonAddComponent = new Button();
buttonUpdateComponent = new Button();
buttonRemoveComponent = new Button();
buttonRefreshComponents = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.BackgroundColor = SystemColors.ActiveCaption;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(569, 521);
dataGridView.TabIndex = 0;
//
// buttonAddComponent
//
buttonAddComponent.Font = new Font("Candara", 12F);
buttonAddComponent.Location = new Point(637, 35);
buttonAddComponent.Name = "buttonAddComponent";
buttonAddComponent.Size = new Size(121, 46);
buttonAddComponent.TabIndex = 1;
buttonAddComponent.Text = "Добавить";
buttonAddComponent.UseVisualStyleBackColor = true;
buttonAddComponent.Click += buttonAddComponent_Click;
//
// buttonUpdateComponent
//
buttonUpdateComponent.Font = new Font("Candara", 12F);
buttonUpdateComponent.Location = new Point(637, 167);
buttonUpdateComponent.Name = "buttonUpdateComponent";
buttonUpdateComponent.Size = new Size(121, 46);
buttonUpdateComponent.TabIndex = 2;
buttonUpdateComponent.Text = "Изменить";
buttonUpdateComponent.UseVisualStyleBackColor = true;
buttonUpdateComponent.Click += buttonUpdateComponent_Click;
//
// buttonRemoveComponent
//
buttonRemoveComponent.Font = new Font("Candara", 12F);
buttonRemoveComponent.Location = new Point(637, 307);
buttonRemoveComponent.Name = "buttonRemoveComponent";
buttonRemoveComponent.Size = new Size(121, 46);
buttonRemoveComponent.TabIndex = 3;
buttonRemoveComponent.Text = "Удалить";
buttonRemoveComponent.UseVisualStyleBackColor = true;
buttonRemoveComponent.Click += buttonRemoveComponent_Click;
//
// buttonRefreshComponents
//
buttonRefreshComponents.Font = new Font("Candara", 12F);
buttonRefreshComponents.Location = new Point(637, 444);
buttonRefreshComponents.Name = "buttonRefreshComponents";
buttonRefreshComponents.Size = new Size(121, 46);
buttonRefreshComponents.TabIndex = 4;
buttonRefreshComponents.Text = "Обновить";
buttonRefreshComponents.UseVisualStyleBackColor = true;
buttonRefreshComponents.Click += buttonRefreshComponents_Click;
//
// FormComponents
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 521);
Controls.Add(buttonRefreshComponents);
Controls.Add(buttonRemoveComponent);
Controls.Add(buttonUpdateComponent);
Controls.Add(buttonAddComponent);
Controls.Add(dataGridView);
Name = "FormComponents";
Text = "Компоненты";
Load += FormComponents_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonAddComponent;
private Button buttonUpdateComponent;
private Button buttonRemoveComponent;
private Button buttonRefreshComponents;
}
}

View File

@ -0,0 +1,124 @@
using Microsoft.Extensions.Logging;
using SushiBar;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SushiBarView
{
public partial class FormComponents : Form
{
private readonly ILogger _logger;
private readonly IComponentLogic _logic;
private int? _id;
public int Id
{
set { _id = value; }
}
public FormComponents(ILogger<FormComponents> logger, IComponentLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormComponents_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["ComponentName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка компонентов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки компонентов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonAddComponent_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormComponent));
if (service is FormComponent form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void buttonUpdateComponent_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormComponent));
if (service is FormComponent form)
{
form.Id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void buttonRemoveComponent_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление компонента");
try
{
if (!_logic.Delete(new ComponentBindingModel
{
Id = id
}))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления компонента");
MessageBox.Show(ex.Message, "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void buttonRefreshComponents_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

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>

246
SushiBar/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,246 @@
namespace SushiBarView
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#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()
{
menuStrip1 = new MenuStrip();
ToolStripMenuItemRef = new ToolStripMenuItem();
компонентыToolStripMenuItem = new ToolStripMenuItem();
сушиToolStripMenuItem = new ToolStripMenuItem();
отчетыToolStripMenuItem = new ToolStripMenuItem();
списокКомпонентовToolStripMenuItem = new ToolStripMenuItem();
компонентыПоИзделиямToolStripMenuItem = new ToolStripMenuItem();
списокЗаказовToolStripMenuItem = new ToolStripMenuItem();
магазиныToolStripMenuItem = new ToolStripMenuItem();
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonTakeOrderInWork = new Button();
buttonOrderReady = new Button();
buttonOrderIssued = new Button();
buttonRefreshOrders = new Button();
buttonAddSushiInShop = new Button();
buttonSelling = new Button();
menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// menuStrip1
//
menuStrip1.ImageScalingSize = new Size(20, 20);
menuStrip1.Items.AddRange(new ToolStripItem[] { ToolStripMenuItemRef, отчетыToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Size = new Size(1140, 28);
menuStrip1.TabIndex = 0;
menuStrip1.Text = "menuStrip1";
//
// ToolStripMenuItemRef
//
ToolStripMenuItemRef.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, сушиToolStripMenuItem, магазиныToolStripMenuItem });
ToolStripMenuItemRef.Name = "ToolStripMenuItemRef";
ToolStripMenuItemRef.Size = new Size(117, 24);
ToolStripMenuItemRef.Text = "Справочники";
//
// компонентыToolStripMenuItem
//
компонентыToolStripMenuItem.Name = омпонентыToolStripMenuItem";
компонентыToolStripMenuItem.Size = new Size(182, 26);
компонентыToolStripMenuItem.Text = "Компоненты";
компонентыToolStripMenuItem.Click += компонентыToolStripMenuItem_Click;
//
// сушиToolStripMenuItem
//
сушиToolStripMenuItem.Name = "сушиToolStripMenuItem";
сушиToolStripMenuItem.Size = new Size(182, 26);
сушиToolStripMenuItem.Text = "Суши";
сушиToolStripMenuItem.Click += сушиToolStripMenuItem_Click;
//
// отчетыToolStripMenuItem
//
отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { списокКомпонентовToolStripMenuItem, компонентыПоИзделиямToolStripMenuItem, списокЗаказовToolStripMenuItem });
отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem";
отчетыToolStripMenuItem.Size = new Size(73, 24);
отчетыToolStripMenuItem.Text = "Отчеты";
//
// списокКомпонентовToolStripMenuItem
//
списокКомпонентовToolStripMenuItem.Name = "списокКомпонентовToolStripMenuItem";
списокКомпонентовToolStripMenuItem.Size = new Size(276, 26);
списокКомпонентовToolStripMenuItem.Text = "Список компонентов";
списокКомпонентовToolStripMenuItem.Click += списокКомпонентовToolStripMenuItem_Click;
//
// компонентыПоИзделиямToolStripMenuItem
//
компонентыПоИзделиямToolStripMenuItem.Name = омпонентыПоИзделиямToolStripMenuItem";
компонентыПоИзделиямToolStripMenuItem.Size = new Size(276, 26);
компонентыПоИзделиямToolStripMenuItem.Text = "Компоненты по изделиям";
компонентыПоИзделиямToolStripMenuItem.Click += компонентыПоИзделиямToolStripMenuItem_Click;
//
// списокЗаказовToolStripMenuItem
//
списокЗаказовToolStripMenuItem.Name = "списокЗаказовToolStripMenuItem";
списокЗаказовToolStripMenuItem.Size = new Size(276, 26);
списокЗаказовToolStripMenuItem.Text = "Список заказов";
списокЗаказовToolStripMenuItem.Click += списокЗаказовToolStripMenuItem_Click;
//
// магазиныToolStripMenuItem
//
магазиныToolStripMenuItem.Name = агазиныToolStripMenuItem";
магазиныToolStripMenuItem.Size = new Size(182, 26);
магазиныToolStripMenuItem.Text = "Магазины";
магазиныToolStripMenuItem.Click += магазиныToolStripMenuItem_Click;
//
// dataGridView
//
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(0, 27);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(849, 512);
dataGridView.TabIndex = 1;
//
// buttonCreateOrder
//
buttonCreateOrder.Location = new Point(923, 43);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(171, 52);
buttonCreateOrder.TabIndex = 2;
buttonCreateOrder.Text = "Создать заказ";
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += buttonCreateOrder_Click;
//
// buttonTakeOrderInWork
//
buttonTakeOrderInWork.Location = new Point(923, 118);
buttonTakeOrderInWork.Name = "buttonTakeOrderInWork";
buttonTakeOrderInWork.Size = new Size(171, 52);
buttonTakeOrderInWork.TabIndex = 3;
buttonTakeOrderInWork.Text = "Отдать на выполнение";
buttonTakeOrderInWork.UseVisualStyleBackColor = true;
buttonTakeOrderInWork.Click += buttonTakeOrderInWork_Click_1;
//
// buttonOrderReady
//
buttonOrderReady.Location = new Point(923, 191);
buttonOrderReady.Name = "buttonOrderReady";
buttonOrderReady.Size = new Size(171, 52);
buttonOrderReady.TabIndex = 4;
buttonOrderReady.Text = "Заказ готов";
buttonOrderReady.UseVisualStyleBackColor = true;
buttonOrderReady.Click += buttonOrderReady_Click_1;
//
// buttonOrderIssued
//
buttonOrderIssued.Location = new Point(923, 264);
buttonOrderIssued.Name = "buttonOrderIssued";
buttonOrderIssued.Size = new Size(171, 52);
buttonOrderIssued.TabIndex = 5;
buttonOrderIssued.Text = "Заказ выдан";
buttonOrderIssued.UseVisualStyleBackColor = true;
buttonOrderIssued.Click += buttonOrderIssued_Click;
//
// buttonRefreshOrders
//
buttonRefreshOrders.Location = new Point(923, 476);
buttonRefreshOrders.Name = "buttonRefreshOrders";
buttonRefreshOrders.Size = new Size(171, 52);
buttonRefreshOrders.TabIndex = 6;
buttonRefreshOrders.Text = "Обновить заказы";
buttonRefreshOrders.UseVisualStyleBackColor = true;
buttonRefreshOrders.Click += ButtonRef_Click;
//
// buttonAddSushiInShop
//
buttonAddSushiInShop.Location = new Point(923, 333);
buttonAddSushiInShop.Name = "buttonAddSushiInShop";
buttonAddSushiInShop.Size = new Size(171, 52);
buttonAddSushiInShop.TabIndex = 7;
buttonAddSushiInShop.Text = "Пополнить магазин";
buttonAddSushiInShop.UseVisualStyleBackColor = true;
buttonAddSushiInShop.Click += buttonAddSushiInShop_Click;
//
// buttonSelling
//
buttonSelling.Location = new Point(923, 404);
buttonSelling.Name = "buttonSelling";
buttonSelling.Size = new Size(171, 52);
buttonSelling.TabIndex = 8;
buttonSelling.Text = "Продать суши";
buttonSelling.UseVisualStyleBackColor = true;
buttonSelling.Click += buttonSelling_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.FromArgb(210, 255, 210);
ClientSize = new Size(1140, 540);
Controls.Add(buttonSelling);
Controls.Add(buttonAddSushiInShop);
Controls.Add(buttonRefreshOrders);
Controls.Add(buttonOrderIssued);
Controls.Add(buttonOrderReady);
Controls.Add(buttonTakeOrderInWork);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(menuStrip1);
MainMenuStrip = menuStrip1;
Name = "FormMain";
Text = "Суши Бар";
Load += FormMain_Load;
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private MenuStrip menuStrip1;
private ToolStripMenuItem ToolStripMenuItemRef;
private DataGridView dataGridView;
private Button buttonCreateOrder;
private Button buttonTakeOrderInWork;
private Button buttonOrderReady;
private Button buttonOrderIssued;
private Button buttonRefreshOrders;
private ToolStripMenuItem компонентыToolStripMenuItem;
private ToolStripMenuItem сушиToolStripMenuItem;
private ToolStripMenuItem магазиныToolStripMenuItem;
private Button buttonAddSushiInShop;
private Button buttonSelling;
private ToolStripMenuItem отчетыToolStripMenuItem;
private ToolStripMenuItem списокКомпонентовToolStripMenuItem;
private ToolStripMenuItem компонентыПоИзделиямToolStripMenuItem;
private ToolStripMenuItem списокЗаказовToolStripMenuItem;
}
}

201
SushiBar/FormMain.cs Normal file
View File

@ -0,0 +1,201 @@
using Microsoft.Extensions.Logging;
using SushiBar;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarView.Shops;
using SushiBarView.Reports;
namespace SushiBarView
{
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["SushiId"].Visible = false;
dataGridView.Columns["SushiName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Произошла ошибка при загрузке заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void компонентыToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form)
{
form.ShowDialog();
}
}
private void сушиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSushis));
if (service is FormSushis formSushis) { formSushis.ShowDialog(); }
}
private void магазиныToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormShops));
if (service is FormShops formShops) { formShops.ShowDialog(); }
}
private void buttonCreateOrder_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
private void buttonTakeOrderInWork_Click_1(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ ${id}. Меняется статус на 'В работе'", id);
try
{
var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка передачи заказа в работу");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonOrderReady_Click_1(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ ${id}. Меняется статус на 'Готов'", id);
try
{
var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id, });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonOrderIssued_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ ${id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
private void списокКомпонентовToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SaveSushisToWordFile(new ReportBindingModel
{
FileName = dialog.FileName
});
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void buttonAddSushiInShop_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormAddSushiInShop));
if (service is FormAddSushiInShop form)
{
form.ShowDialog();
}
}
private void buttonSelling_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSell));
if (service is FormSell form)
{
form.ShowDialog();
}
}
private void компонентыПоИзделиямToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportSushiComponent));
if (service is FormReportSushiComponent form)
{
form.ShowDialog();
}
}
private void списокЗаказовToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
}
}
}

126
SushiBar/FormMain.resx Normal file
View File

@ -0,0 +1,126 @@
<?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>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>146</value>
</metadata>
</root>

129
SushiBar/FormReportOrders.Designer.cs generated Normal file
View File

@ -0,0 +1,129 @@
namespace SushiBarView.Reports
{
partial class FormReportOrders
{
/// <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()
{
panel = new Panel();
labelFrom = new Label();
buttonToPdf = new Button();
dateTimePickerDateFrom = new DateTimePicker();
labelTo = new Label();
dateTimePickerDateTo = new DateTimePicker();
buttonMake = new Button();
panel.SuspendLayout();
SuspendLayout();
//
// panel
//
panel.Controls.Add(labelFrom);
panel.Controls.Add(buttonToPdf);
panel.Controls.Add(dateTimePickerDateFrom);
panel.Controls.Add(labelTo);
panel.Controls.Add(dateTimePickerDateTo);
panel.Controls.Add(buttonMake);
panel.Dock = DockStyle.Top;
panel.Location = new Point(0, 0);
panel.Name = "panel";
panel.Size = new Size(1321, 71);
panel.TabIndex = 3;
//
// labelFrom
//
labelFrom.AutoSize = true;
labelFrom.Location = new Point(16, 31);
labelFrom.Name = "labelFrom";
labelFrom.Size = new Size(18, 20);
labelFrom.TabIndex = 3;
labelFrom.Text = "С";
//
// buttonToPdf
//
buttonToPdf.Location = new Point(1200, 27);
buttonToPdf.Name = "buttonToPdf";
buttonToPdf.Size = new Size(94, 29);
buttonToPdf.TabIndex = 4;
buttonToPdf.Text = "В PDF";
buttonToPdf.UseVisualStyleBackColor = true;
buttonToPdf.Click += ButtonToPdf_Click;
//
// dateTimePickerDateFrom
//
dateTimePickerDateFrom.Location = new Point(51, 27);
dateTimePickerDateFrom.Name = "dateTimePickerDateFrom";
dateTimePickerDateFrom.Size = new Size(250, 27);
dateTimePickerDateFrom.TabIndex = 0;
//
// labelTo
//
labelTo.AutoSize = true;
labelTo.Location = new Point(317, 31);
labelTo.Name = "labelTo";
labelTo.Size = new Size(29, 20);
labelTo.TabIndex = 4;
labelTo.Text = "По";
//
// dateTimePickerDateTo
//
dateTimePickerDateTo.Location = new Point(365, 27);
dateTimePickerDateTo.Name = "dateTimePickerDateTo";
dateTimePickerDateTo.Size = new Size(250, 27);
dateTimePickerDateTo.TabIndex = 1;
//
// buttonMake
//
buttonMake.Location = new Point(677, 27);
buttonMake.Name = "buttonMake";
buttonMake.Size = new Size(132, 29);
buttonMake.TabIndex = 3;
buttonMake.Text = "Сформировать";
buttonMake.UseVisualStyleBackColor = true;
buttonMake.Click += ButtonMake_Click;
//
// FormReportOrders
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1321, 450);
Controls.Add(panel);
Name = "FormReportOrders";
Text = "FormReportOrders";
panel.ResumeLayout(false);
panel.PerformLayout();
ResumeLayout(false);
}
#endregion
private Panel panel;
private DateTimePicker dateTimePickerDateTo;
private DateTimePicker dateTimePickerDateFrom;
private Button buttonMake;
private Button buttonToPdf;
private Label labelTo;
private Label labelFrom;
}
}

View File

@ -0,0 +1,94 @@
using Microsoft.Extensions.Logging;
using Microsoft.Reporting.WinForms;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
namespace SushiBarView.Reports
{
public partial class FormReportOrders : Form
{
private readonly ReportViewer reportViewer;
private readonly ILogger _logger;
private readonly IReportLogic _logic;
public FormReportOrders(ILogger<FormReportOrders> logger, IReportLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
reportViewer = new ReportViewer
{
Dock = DockStyle.Fill
};
var path = Directory.GetParent(Directory.GetCurrentDirectory())?.Parent?.Parent?.ToString() + "\\ReportOrders.rdlc";
reportViewer.LocalReport.LoadReportDefinition(new FileStream(path, FileMode.Open));
Controls.Clear();
Controls.Add(reportViewer);
Controls.Add(panel);
}
private void ButtonMake_Click(object sender, EventArgs e)
{
if (dateTimePickerDateFrom.Value.Date >= dateTimePickerDateTo.Value.Date)
{
MessageBox.Show("Дата начала должна быть меньше даты окончания",
"Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
var dataSource = _logic.GetOrders(new ReportBindingModel
{
DateFrom = dateTimePickerDateFrom.Value,
DateTo = dateTimePickerDateTo.Value
});
var source = new ReportDataSource("DataSetOrders", dataSource);
reportViewer.LocalReport.DataSources.Clear();
reportViewer.LocalReport.DataSources.Add(source);
var parameters = new[] { new ReportParameter("ReportParameterPeriod", $"c {dateTimePickerDateFrom.Value.ToShortDateString()} по {dateTimePickerDateTo.Value.ToShortDateString()}") };
// ЗДЕСЬ ПРОИСХОДИТ ОШИБКА И ВЫБРАСЫВАЕТСЯ ИСКЛЮЧЕНИЕ
reportViewer.LocalReport.SetParameters(parameters);
reportViewer.RefreshReport();
_logger.LogInformation("Загрузка списка заказов на период {From}-{To}",
dateTimePickerDateFrom.Value.ToShortDateString(), dateTimePickerDateTo.Value.ToShortDateString());
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка заказов на период");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonToPdf_Click(object sender, EventArgs e)
{
if (dateTimePickerDateFrom.Value.Date >= dateTimePickerDateTo.Value.Date)
{
MessageBox.Show("Дата начала должна быть меньше даты окончания", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using var dialog = new SaveFileDialog
{
Filter = "pdf|*.pdf"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
// ВОТ ЗДЕСЬ ТОЖЕ СРАЗУ ИСКЛЮЧЕНИЕ
_logic.SaveOrdersToPdfFile(new ReportBindingModel
{
FileName = dialog.FileName,
DateFrom = dateTimePickerDateFrom.Value,
DateTo = dateTimePickerDateTo.Value
});
_logger.LogInformation("Сохранение списка заказов на период {From}-{To} ",
dateTimePickerDateFrom.Value.ToShortDateString(), dateTimePickerDateTo.Value.ToShortDateString());
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения списка заказов на период");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}

View File

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

View File

@ -0,0 +1,104 @@
namespace SushiBarView
{
partial class FormReportSushiComponent
{
/// <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()
{
dataGridView1 = new DataGridView();
buttonSaveToExcel = new Button();
Sushi = new DataGridViewTextBoxColumn();
Component = new DataGridViewTextBoxColumn();
Count = new DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
SuspendLayout();
//
// dataGridView1
//
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView1.BackgroundColor = Color.LightGoldenrodYellow;
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView1.Columns.AddRange(new DataGridViewColumn[] { Sushi, Component, Count });
dataGridView1.Dock = DockStyle.Bottom;
dataGridView1.Location = new Point(0, 57);
dataGridView1.Name = "dataGridView1";
dataGridView1.RowHeadersVisible = false;
dataGridView1.RowHeadersWidth = 51;
dataGridView1.Size = new Size(800, 448);
dataGridView1.TabIndex = 0;
//
// buttonSaveToExcel
//
buttonSaveToExcel.BackColor = Color.Goldenrod;
buttonSaveToExcel.Location = new Point(319, 9);
buttonSaveToExcel.Name = "buttonSaveToExcel";
buttonSaveToExcel.Size = new Size(170, 36);
buttonSaveToExcel.TabIndex = 1;
buttonSaveToExcel.Text = "Сохранить в Excel";
buttonSaveToExcel.UseVisualStyleBackColor = false;
buttonSaveToExcel.Click += ButtonSaveToExcel_Click;
//
// Sushi
//
Sushi.HeaderText = "Суши";
Sushi.MinimumWidth = 6;
Sushi.Name = "Sushi";
//
// Component
//
Component.HeaderText = "Компонент";
Component.MinimumWidth = 6;
Component.Name = "Component";
//
// Count
//
Count.HeaderText = "Количество";
Count.MinimumWidth = 6;
Count.Name = "Count";
//
// FormReportSushiComponent
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 505);
Controls.Add(buttonSaveToExcel);
Controls.Add(dataGridView1);
Name = "FormReportSushiComponent";
Text = "Компоненты по изделиям";
Load += FormReportSushiComponents_Load;
((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView1;
private Button buttonSaveToExcel;
private DataGridViewTextBoxColumn Sushi;
private DataGridViewTextBoxColumn Component;
private DataGridViewTextBoxColumn Count;
}
}

View File

@ -0,0 +1,73 @@
using Microsoft.Extensions.Logging;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
namespace SushiBarView
{
public partial class FormReportSushiComponent : Form
{
private readonly ILogger _logger;
private readonly IReportLogic _logic;
public FormReportSushiComponent(ILogger<FormReportSushiComponent> logger, IReportLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormReportSushiComponents_Load(object sender, EventArgs e)
{
try
{
var dict = _logic.GetSushiComponent();
if (dict != null)
{
dataGridView1.Rows.Clear();
foreach (var elem in dict)
{
dataGridView1.Rows.Add(new object[] { elem.SushiName, "", "" });
foreach (var listElem in elem.Components)
{
dataGridView1.Rows.Add(new object[] { "", listElem.Item1, listElem.Item2 });
}
dataGridView1.Rows.Add(new object[] { "Итого", "", elem.TotalCount });
dataGridView1.Rows.Add(Array.Empty<object>());
}
}
_logger.LogInformation("Загрузка списка изделий по компонентам");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка изделий по компонентам");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonSaveToExcel_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog
{
Filter = "xlsx|*.xlsx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
_logic.SaveSushiComponentToExcelFile(new
ReportBindingModel
{
FileName = dialog.FileName
});
_logger.LogInformation("Сохранение списка изделий по компонентам");
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения списка изделий по компонентам");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}

View File

@ -0,0 +1,129 @@
<?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>
<metadata name="Sushi.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Component.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Count.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,151 @@
namespace SushiBarView
{
partial class FormCreateOrder
{
/// <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()
{
labelSushi = new Label();
labelCount = new Label();
labelSum = new Label();
textBoxCount = new TextBox();
textBoxSum = new TextBox();
comboBoxSushi = new ComboBox();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// labelSushi
//
labelSushi.AutoSize = true;
labelSushi.Location = new Point(30, 30);
labelSushi.Margin = new Padding(4, 0, 4, 0);
labelSushi.Name = "labelSushi";
labelSushi.Size = new Size(85, 24);
labelSushi.TabIndex = 0;
labelSushi.Text = "Изделие";
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(30, 102);
labelCount.Margin = new Padding(4, 0, 4, 0);
labelCount.Name = "labelCount";
labelCount.Size = new Size(112, 24);
labelCount.TabIndex = 1;
labelCount.Text = "Количество";
//
// labelSum
//
labelSum.AutoSize = true;
labelSum.Location = new Point(30, 174);
labelSum.Margin = new Padding(4, 0, 4, 0);
labelSum.Name = "labelSum";
labelSum.Size = new Size(68, 24);
labelSum.TabIndex = 2;
labelSum.Text = "Сумма";
//
// textBoxCount
//
textBoxCount.Location = new Point(227, 94);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(326, 32);
textBoxCount.TabIndex = 3;
textBoxCount.TextChanged += textBoxCount_TextChanged;
//
// textBoxSum
//
textBoxSum.Enabled = false;
textBoxSum.Location = new Point(227, 166);
textBoxSum.Name = "textBoxSum";
textBoxSum.Size = new Size(326, 32);
textBoxSum.TabIndex = 4;
//
// comboBoxSushi
//
comboBoxSushi.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxSushi.FormattingEnabled = true;
comboBoxSushi.Location = new Point(227, 22);
comboBoxSushi.Name = "comboBoxSushi";
comboBoxSushi.Size = new Size(326, 32);
comboBoxSushi.TabIndex = 5;
comboBoxSushi.SelectedIndexChanged += comboBoxSushi_SelectedIndexChanged;
//
// buttonSave
//
buttonSave.Location = new Point(227, 231);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(140, 49);
buttonSave.TabIndex = 6;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(413, 231);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(140, 49);
buttonCancel.TabIndex = 7;
buttonCancel.Text = "Отменить";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// FormCreateOrder
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.FromArgb(192, 192, 255);
ClientSize = new Size(595, 302);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(comboBoxSushi);
Controls.Add(textBoxSum);
Controls.Add(textBoxCount);
Controls.Add(labelSum);
Controls.Add(labelCount);
Controls.Add(labelSushi);
Font = new Font("Candara", 12F, FontStyle.Regular, GraphicsUnit.Point, 204);
Margin = new Padding(4);
Name = "FormCreateOrder";
Text = "Создание заказа";
Load += FormCreateOrder_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelSushi;
private Label labelCount;
private Label labelSum;
private TextBox textBoxCount;
private TextBox textBoxSum;
private ComboBox comboBoxSushi;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,118 @@
using Microsoft.Extensions.Logging;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
namespace SushiBarView
{
public partial class FormCreateOrder : Form
{
private readonly ILogger _logger;
private readonly ISushiLogic _logicSushi;
private readonly IOrderLogic _logicO;
public FormCreateOrder(ILogger<FormCreateOrder> logger, ISushiLogic logicSushi, IOrderLogic logicO)
{
InitializeComponent();
_logger = logger;
_logicSushi = logicSushi;
_logicO = logicO;
}
private void FormCreateOrder_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка изделий для заказа");
try
{
var list = _logicSushi.ReadList(null);
if (list != null)
{
comboBoxSushi.DisplayMember = "SushiName";
comboBoxSushi.ValueMember = "Id";
comboBoxSushi.DataSource = list;
comboBoxSushi.SelectedItem = null;
_logger.LogInformation("Загрузка изделий для заказа");
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка изделий");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// прописать логику
}
private void comboBoxSushi_SelectedIndexChanged(object sender, EventArgs e)
{
CalcSum();
}
private void textBoxCount_TextChanged(object sender, EventArgs e)
{
CalcSum();
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxCount.Text))
{
MessageBox.Show("Заполните поле Количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxSushi.SelectedValue == null)
{
MessageBox.Show("Выберите изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Создание заказа");
try
{
var operationResult = _logicO.CreateOrder(new OrderBindingModel
{
SushiId = Convert.ToInt32(comboBoxSushi.SelectedValue),
Count = Convert.ToInt32(textBoxCount.Text),
Sum = Convert.ToDouble(textBoxSum.Text)
});
if (!operationResult)
{
throw new Exception("Ошибка при создании заказа. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void CalcSum()
{
if (comboBoxSushi.SelectedValue != null && !string.IsNullOrEmpty(textBoxCount.Text))
{
try
{
int id = Convert.ToInt32(comboBoxSushi.SelectedValue);
var product = _logicSushi.ReadElement(new SushiSearchModel { Id = id });
int count = Convert.ToInt32(textBoxCount.Text);
textBoxSum.Text = Math.Round(count * (product?.Price ?? 0), 2).ToString();
_logger.LogInformation("Расчет суммы заказа");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка расчета суммы заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
}
}

View File

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

View File

@ -1,7 +1,26 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using SushiBarBusinessLogic;
using SushiBarBusinessLogic.BusinessLogic;
using SushiBarBusinessLogic.OfficePackage;
using SushiBarBusinessLogic.OfficePackage.Implements;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.StoragesContracts;
using SushiBarDatabaseImplement.Implements;
using SushiBarView;
using SushiBarView.Shops;
using SushiBarView.Reports;
using System.Text;
namespace SushiBar
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary>
/// The main entry point for the application.
/// </summary>
@ -11,7 +30,52 @@ namespace SushiBar
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
var services = new ServiceCollection();
// Äîáàâëåíî äëÿ óñòðàíåíèÿ îøèáêè ñ êîäèðîâêîé ïðè ñîõðàíåíèè â PDF
// ÷òîáû çàðàáîòàëî íóæíî ïîñòàâèòü NuGet ïàêåò System.Text.Encoding.CodePages
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
private static void ConfigureServices(ServiceCollection services)
{
services.AddLogging(option =>
{
option.SetMinimumLevel(LogLevel.Information);
option.AddNLog("nlog.config");
});
services.AddTransient<IComponentStorage, ComponentStorage>();
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<ISushiStorage, SushiStorage>();
services.AddTransient<IShopStorage, ShopStorage>();
services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<ISushiLogic, SushiLogic>();
services.AddTransient<IShopLogic, ShopLogic>();
services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
services.AddTransient<FormMain>();
services.AddTransient<FormComponent>();
services.AddTransient<FormComponents>();
services.AddTransient<FormCreateOrder>();
services.AddTransient<FormSushi>();
services.AddTransient<FormSushiComponent>();
services.AddTransient<FormSushis>();
services.AddTransient<FormReportOrders>();
services.AddTransient<FormReportSushiComponent>();
services.AddTransient<FormShop>();
services.AddTransient<FormShops>();
services.AddTransient<FormAddSushiInShop>();
services.AddTransient<FormSell>();
}
}
}

602
SushiBar/ReportOrders.rdlc Normal file
View File

@ -0,0 +1,602 @@
<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<AutoRefresh>0</AutoRefresh>
<DataSources>
<DataSource Name="SushiBarContractsViewModels">
<ConnectionProperties>
<DataProvider>System.Data.DataSet</DataProvider>
<ConnectString>/* Local Connection */</ConnectString>
</ConnectionProperties>
<rd:DataSourceID>10791c83-cee8-4a38-bbd0-245fc17cefb3</rd:DataSourceID>
</DataSource>
</DataSources>
<DataSets>
<DataSet Name="DataSetOrders">
<Query>
<DataSourceName>SushiBarContractsViewModels</DataSourceName>
<CommandText>/* Local Query */</CommandText>
</Query>
<Fields>
<Field Name="Id">
<DataField>Id</DataField>
<rd:TypeName>System.Int32</rd:TypeName>
</Field>
<Field Name="DateCreate">
<DataField>DateCreate</DataField>
<rd:TypeName>System.DateTime</rd:TypeName>
</Field>
<Field Name="Status">
<DataField>Status</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
<Field Name="SushiName">
<DataField>SushiName</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
<Field Name="Sum">
<DataField>Sum</DataField>
<rd:TypeName>System.Decimal</rd:TypeName>
</Field>
</Fields>
<rd:DataSetInfo>
<rd:DataSetName>SushiBarContracts.ViewModels</rd:DataSetName>
<rd:TableName>ReportOrdersViewModel</rd:TableName>
<rd:ObjectDataSourceType>SushiBarContracts.ViewModels.ReportOrdersViewModel, SushiBarContracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</rd:ObjectDataSourceType>
</rd:DataSetInfo>
</DataSet>
</DataSets>
<ReportSections>
<ReportSection>
<Body>
<ReportItems>
<Textbox Name="ReportParameterPeriod">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Parameters!ReportParameterPeriod.Value</Value>
<Style>
<FontSize>14pt</FontSize>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style>
<TextAlign>Center</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<rd:DefaultName>ReportParameterPeriod</rd:DefaultName>
<Top>1cm</Top>
<Height>1cm</Height>
<Width>21cm</Width>
<Style>
<Border>
<Style>None</Style>
</Border>
<VerticalAlign>Middle</VerticalAlign>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
<Textbox Name="TextboxTitle">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Заказы</Value>
<Style>
<FontSize>16pt</FontSize>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style>
<TextAlign>Center</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<Height>1cm</Height>
<Width>21cm</Width>
<ZIndex>1</ZIndex>
<Style>
<Border>
<Style>None</Style>
</Border>
<VerticalAlign>Middle</VerticalAlign>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
<Tablix Name="Tablix1">
<TablixBody>
<TablixColumns>
<TablixColumn>
<Width>2.5cm</Width>
</TablixColumn>
<TablixColumn>
<Width>3.21438cm</Width>
</TablixColumn>
<TablixColumn>
<Width>4.21438cm</Width>
</TablixColumn>
<TablixColumn>
<Width>7.23317cm</Width>
</TablixColumn>
<TablixColumn>
<Width>2.5cm</Width>
</TablixColumn>
</TablixColumns>
<TablixRows>
<TablixRow>
<Height>0.6cm</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="Textbox1">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Номер</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox1</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox2">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Дата создания</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox2</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox3">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Статус</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox3</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox4">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Суши</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox4</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox5">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Сумма</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox5</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
<TablixRow>
<Height>0.6cm</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="Id">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Id.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Id</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="DateCreate">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!DateCreate.Value</Value>
<Style>
<Format>d</Format>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>DateCreate</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Status">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Status.Value.ToString()</Value>
<Style>
<Format>d</Format>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Status</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
<rd:Selected>true</rd:Selected>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="SushiName">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!SushiName.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>SushiName</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Sum">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Sum.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Sum</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
</TablixRows>
</TablixBody>
<TablixColumnHierarchy>
<TablixMembers>
<TablixMember />
<TablixMember />
<TablixMember />
<TablixMember />
<TablixMember />
</TablixMembers>
</TablixColumnHierarchy>
<TablixRowHierarchy>
<TablixMembers>
<TablixMember>
<KeepWithGroup>After</KeepWithGroup>
</TablixMember>
<TablixMember>
<Group Name="Подробности" />
</TablixMember>
</TablixMembers>
</TablixRowHierarchy>
<DataSetName>DataSetOrders</DataSetName>
<Top>2.48391cm</Top>
<Left>0.55245cm</Left>
<Height>1.2cm</Height>
<Width>20.66193cm</Width>
<ZIndex>2</ZIndex>
<Style>
<Border>
<Style>Double</Style>
</Border>
</Style>
</Tablix>
<Textbox Name="TextboxTotalSum">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Итого:</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style>
<TextAlign>Right</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<Top>4cm</Top>
<Left>12cm</Left>
<Height>0.6cm</Height>
<Width>2.5cm</Width>
<ZIndex>3</ZIndex>
<Style>
<Border>
<Style>None</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
<Textbox Name="SumTotal">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Sum(Fields!Sum.Value, "DataSetOrders")</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style>
<TextAlign>Right</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<Top>4cm</Top>
<Left>14.5cm</Left>
<Height>0.6cm</Height>
<Width>2.5cm</Width>
<ZIndex>4</ZIndex>
<Style>
<Border>
<Style>None</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</ReportItems>
<Height>5.72875cm</Height>
<Style />
</Body>
<Width>21.21438cm</Width>
<Page>
<PageHeight>29.7cm</PageHeight>
<PageWidth>21cm</PageWidth>
<LeftMargin>2cm</LeftMargin>
<RightMargin>2cm</RightMargin>
<TopMargin>2cm</TopMargin>
<BottomMargin>2cm</BottomMargin>
<ColumnSpacing>0.13cm</ColumnSpacing>
<Style />
</Page>
</ReportSection>
</ReportSections>
<ReportParameters>
<ReportParameter Name="ReportParameterPeriod">
<DataType>String</DataType>
<Nullable>true</Nullable>
<Prompt>ReportParameter1</Prompt>
</ReportParameter>
</ReportParameters>
<ReportParametersLayout>
<GridLayoutDefinition>
<NumberOfColumns>4</NumberOfColumns>
<NumberOfRows>2</NumberOfRows>
<CellDefinitions>
<CellDefinition>
<ColumnIndex>0</ColumnIndex>
<RowIndex>0</RowIndex>
<ParameterName>ReportParameterPeriod</ParameterName>
</CellDefinition>
</CellDefinitions>
</GridLayoutDefinition>
</ReportParametersLayout>
<rd:ReportUnitType>Cm</rd:ReportUnitType>
<rd:ReportID>2de0031a-4d17-449d-922d-d9fc54572312</rd:ReportID>
</Report>

View File

@ -0,0 +1,149 @@
namespace SushiBarView.Shops
{
partial class FormAddSushiInShop
{
/// <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()
{
comboBoxSushi = new ComboBox();
labelSushi = new Label();
labelShop = new Label();
comboBoxShop = new ComboBox();
textBoxCount = new TextBox();
labelCount = new Label();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// comboBoxSushi
//
comboBoxSushi.FormattingEnabled = true;
comboBoxSushi.Location = new Point(212, 49);
comboBoxSushi.Margin = new Padding(4);
comboBoxSushi.Name = "comboBoxSushi";
comboBoxSushi.Size = new Size(188, 30);
comboBoxSushi.TabIndex = 0;
//
// labelSushi
//
labelSushi.AutoSize = true;
labelSushi.Location = new Point(42, 57);
labelSushi.Margin = new Padding(4, 0, 4, 0);
labelSushi.Name = "labelSushi";
labelSushi.Size = new Size(60, 22);
labelSushi.TabIndex = 1;
labelSushi.Text = "Суши: ";
//
// labelShop
//
labelShop.AutoSize = true;
labelShop.Location = new Point(42, 188);
labelShop.Margin = new Padding(4, 0, 4, 0);
labelShop.Name = "labelShop";
labelShop.Size = new Size(86, 22);
labelShop.TabIndex = 3;
labelShop.Text = "Магазин: ";
//
// comboBoxShop
//
comboBoxShop.FormattingEnabled = true;
comboBoxShop.Location = new Point(212, 188);
comboBoxShop.Margin = new Padding(4);
comboBoxShop.Name = "comboBoxShop";
comboBoxShop.Size = new Size(188, 30);
comboBoxShop.TabIndex = 2;
//
// textBoxCount
//
textBoxCount.Location = new Point(212, 118);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(188, 29);
textBoxCount.TabIndex = 4;
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(42, 121);
labelCount.Margin = new Padding(4, 0, 4, 0);
labelCount.Name = "labelCount";
labelCount.Size = new Size(154, 22);
labelCount.TabIndex = 5;
labelCount.Text = "Количество суши: ";
//
// buttonSave
//
buttonSave.Location = new Point(471, 174);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(107, 44);
buttonSave.TabIndex = 6;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(617, 174);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(107, 44);
buttonCancel.TabIndex = 7;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// FormAddSushiInShop
//
AutoScaleDimensions = new SizeF(10F, 22F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(762, 267);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(labelCount);
Controls.Add(textBoxCount);
Controls.Add(labelShop);
Controls.Add(comboBoxShop);
Controls.Add(labelSushi);
Controls.Add(comboBoxSushi);
Font = new Font("Candara", 10.8F, FontStyle.Regular, GraphicsUnit.Point, 204);
Margin = new Padding(4);
Name = "FormAddSushiInShop";
Text = "Пополняем магазинчик";
Load += FormAddSushiInShop_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox comboBoxSushi;
private Label labelSushi;
private Label labelShop;
private ComboBox comboBoxShop;
private TextBox textBoxCount;
private Label labelCount;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,114 @@
using Microsoft.Extensions.Logging;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
namespace SushiBarView.Shops
{
public partial class FormAddSushiInShop : Form
{
private readonly ILogger _logger;
private readonly IShopLogic _shopLogic;
private readonly ISushiLogic _sushiLogic;
public FormAddSushiInShop(ILogger<FormAddSushiInShop> logger, IShopLogic shopLogic, ISushiLogic sushiLogic)
{
InitializeComponent();
_logger = logger;
_shopLogic = shopLogic;
_sushiLogic = sushiLogic;
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (comboBoxShop.SelectedValue == null)
{
MessageBox.Show("Выберите магазин", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxSushi.SelectedValue == null)
{
MessageBox.Show("Выберите изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxCount.Text))
{
MessageBox.Show("Введите количество изделий", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Добавление изделия в магазин");
try
{
var operationResult = _shopLogic.AddSushiInShop(
new ShopSearchModel { Id = Convert.ToInt32(comboBoxShop.SelectedValue), ShopName = comboBoxShop.Text },
new SushiBindingModel { Id = Convert.ToInt32(comboBoxSushi.SelectedValue), SushiName = comboBoxSushi.Text },
Convert.ToInt32(textBoxCount.Text)
);
if (!operationResult)
{
MessageBox.Show("Не получилось почему-то добавить суши", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания поставки");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FormAddSushiInShop_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка магазинов");
try
{
var listShops = _shopLogic.ReadList(null);
if (listShops != null)
{
comboBoxShop.DisplayMember = "ShopName";
comboBoxShop.ValueMember = "Id";
comboBoxShop.DataSource = listShops;
comboBoxShop.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка магазинов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
_logger.LogInformation("Загрузка суши");
try
{
var list = _sushiLogic.ReadList(null);
if (list != null)
{
comboBoxSushi.DisplayMember = "SushiName";
comboBoxSushi.ValueMember = "Id";
comboBoxSushi.DataSource = list;
comboBoxSushi.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка авто");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

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>

128
SushiBar/Shops/FormSell.Designer.cs generated Normal file
View File

@ -0,0 +1,128 @@
namespace SushiBarView.Shops
{
partial class FormSell
{
/// <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()
{
comboBoxSushis = new ComboBox();
labelSushi = new Label();
numericUpDownCountForSelling = new NumericUpDown();
labelCountForSelling = new Label();
buttonSell = new Button();
buttonCancel = new Button();
((System.ComponentModel.ISupportInitialize)numericUpDownCountForSelling).BeginInit();
SuspendLayout();
//
// comboBoxSushis
//
comboBoxSushis.FormattingEnabled = true;
comboBoxSushis.Location = new Point(342, 41);
comboBoxSushis.Margin = new Padding(4);
comboBoxSushis.Name = "comboBoxSushis";
comboBoxSushis.Size = new Size(206, 32);
comboBoxSushis.TabIndex = 0;
//
// labelSushi
//
labelSushi.AutoSize = true;
labelSushi.Location = new Point(45, 50);
labelSushi.Margin = new Padding(4, 0, 4, 0);
labelSushi.Name = "labelSushi";
labelSushi.Size = new Size(56, 24);
labelSushi.TabIndex = 1;
labelSushi.Text = "Суши";
//
// numericUpDownCountForSelling
//
numericUpDownCountForSelling.Location = new Point(342, 124);
numericUpDownCountForSelling.Margin = new Padding(4);
numericUpDownCountForSelling.Name = "numericUpDownCountForSelling";
numericUpDownCountForSelling.Size = new Size(208, 32);
numericUpDownCountForSelling.TabIndex = 2;
//
// labelCountForSelling
//
labelCountForSelling.AutoSize = true;
labelCountForSelling.Location = new Point(45, 126);
labelCountForSelling.Margin = new Padding(4, 0, 4, 0);
labelCountForSelling.Name = "labelCountForSelling";
labelCountForSelling.Size = new Size(229, 24);
labelCountForSelling.TabIndex = 3;
labelCountForSelling.Text = "Количество для продажи";
//
// buttonSell
//
buttonSell.Location = new Point(60, 259);
buttonSell.Name = "buttonSell";
buttonSell.Size = new Size(135, 51);
buttonSell.TabIndex = 4;
buttonSell.Text = "Продать";
buttonSell.UseVisualStyleBackColor = true;
buttonSell.Click += buttonSell_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(515, 259);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(160, 51);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Не продавать ";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// FormSell
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.RosyBrown;
ClientSize = new Size(716, 369);
Controls.Add(buttonCancel);
Controls.Add(buttonSell);
Controls.Add(labelCountForSelling);
Controls.Add(numericUpDownCountForSelling);
Controls.Add(labelSushi);
Controls.Add(comboBoxSushis);
Font = new Font("Candara", 12F, FontStyle.Regular, GraphicsUnit.Point, 204);
Margin = new Padding(4);
Name = "FormSell";
Text = "Продажа суши";
Load += FormSell_Load;
((System.ComponentModel.ISupportInitialize)numericUpDownCountForSelling).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox comboBoxSushis;
private Label labelSushi;
private NumericUpDown numericUpDownCountForSelling;
private Label labelCountForSelling;
private Button buttonSell;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,89 @@
using Microsoft.Extensions.Logging;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SushiBarView.Shops
{
public partial class FormSell : Form
{
private readonly ISushiLogic _sushiLogic;
private readonly IShopLogic _shopLogic;
private readonly ILogger _logger;
public FormSell(ILogger<FormSell> logger, IShopLogic shopLogic, ISushiLogic sushiLogic)
{
_logger = logger;
_shopLogic = shopLogic;
_sushiLogic = sushiLogic;
InitializeComponent();
}
private void buttonSell_Click(object sender, EventArgs e)
{
if (numericUpDownCountForSelling.Value == 0)
{
MessageBox.Show("Мы не можем продать ноль изделий", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxSushis.SelectedValue == null)
{
MessageBox.Show("Выберите изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Продажа изделий");
try
{
var operationResult = _shopLogic.SellSushis(_sushiLogic.ReadElement(new() { Id = Convert.ToInt32(comboBoxSushis.SelectedValue) }),
Convert.ToInt32(numericUpDownCountForSelling.Value)
);
if (!operationResult)
{
throw new Exception("Ошибка при продаже изделий. Дополнительная информация в логах.");
}
MessageBox.Show("Продажа прошла успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка продажи изделий");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FormSell_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка изделий для продажи");
try
{
var list = _sushiLogic.ReadList(null);
if (list != null)
{
comboBoxSushis.DisplayMember = "SushiName";
comboBoxSushis.ValueMember = "Id";
comboBoxSushis.DataSource = list;
comboBoxSushis.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка изделий");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

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>

292
SushiBar/Shops/FormShop.Designer.cs generated Normal file
View File

@ -0,0 +1,292 @@
namespace SushiBarView.Shops
{
partial class FormShop
{
/// <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()
{
buttonCancel = new Button();
buttonSave = new Button();
textBoxAddress = new TextBox();
labelAddress = new Label();
labelName = new Label();
dateTimePickerDateOpening = new DateTimePicker();
groupBoxComponents = new GroupBox();
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
ColumnId = new DataGridViewTextBoxColumn();
ColumnSushiName = new DataGridViewTextBoxColumn();
ColumnCount = new DataGridViewTextBoxColumn();
textBoxName = new TextBox();
labelDateOpening = new Label();
labelMaxCount = new Label();
numericUpDownMaxCount = new NumericUpDown();
groupBoxComponents.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownMaxCount).BeginInit();
SuspendLayout();
//
// buttonCancel
//
buttonCancel.Anchor = AnchorStyles.None;
buttonCancel.Location = new Point(710, 431);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(116, 39);
buttonCancel.TabIndex = 11;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Anchor = AnchorStyles.None;
buttonSave.Location = new Point(471, 431);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(116, 39);
buttonSave.TabIndex = 10;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// textBoxAddress
//
textBoxAddress.Anchor = AnchorStyles.None;
textBoxAddress.Location = new Point(124, 46);
textBoxAddress.Name = "textBoxAddress";
textBoxAddress.Size = new Size(330, 27);
textBoxAddress.TabIndex = 9;
//
// labelAddress
//
labelAddress.Anchor = AnchorStyles.None;
labelAddress.AutoSize = true;
labelAddress.Font = new Font("Candara", 12F);
labelAddress.Location = new Point(24, 46);
labelAddress.Margin = new Padding(4, 0, 4, 0);
labelAddress.Name = "labelAddress";
labelAddress.Size = new Size(63, 24);
labelAddress.TabIndex = 7;
labelAddress.Text = "Адрес";
//
// labelName
//
labelName.Anchor = AnchorStyles.None;
labelName.AutoSize = true;
labelName.Font = new Font("Candara", 12F);
labelName.Location = new Point(24, 9);
labelName.Margin = new Padding(4, 0, 4, 0);
labelName.Name = "labelName";
labelName.Size = new Size(93, 24);
labelName.TabIndex = 6;
labelName.Text = "Название";
//
// dateTimePickerDateOpening
//
dateTimePickerDateOpening.Location = new Point(471, 46);
dateTimePickerDateOpening.Name = "dateTimePickerDateOpening";
dateTimePickerDateOpening.Size = new Size(355, 27);
dateTimePickerDateOpening.TabIndex = 12;
//
// groupBoxComponents
//
groupBoxComponents.Controls.Add(buttonRefresh);
groupBoxComponents.Controls.Add(buttonDelete);
groupBoxComponents.Controls.Add(buttonUpdate);
groupBoxComponents.Controls.Add(buttonAdd);
groupBoxComponents.Controls.Add(dataGridView);
groupBoxComponents.Location = new Point(11, 93);
groupBoxComponents.Margin = new Padding(2, 3, 2, 3);
groupBoxComponents.Name = "groupBoxComponents";
groupBoxComponents.Padding = new Padding(2, 3, 2, 3);
groupBoxComponents.Size = new Size(443, 396);
groupBoxComponents.TabIndex = 18;
groupBoxComponents.TabStop = false;
//
// buttonRefresh
//
buttonRefresh.BackColor = Color.FromArgb(255, 192, 192);
buttonRefresh.Location = new Point(483, 330);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(127, 47);
buttonRefresh.TabIndex = 9;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = false;
//
// buttonDelete
//
buttonDelete.BackColor = Color.FromArgb(255, 192, 192);
buttonDelete.Location = new Point(483, 228);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(127, 47);
buttonDelete.TabIndex = 8;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = false;
//
// buttonUpdate
//
buttonUpdate.BackColor = Color.FromArgb(255, 192, 192);
buttonUpdate.Location = new Point(483, 125);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(127, 47);
buttonUpdate.TabIndex = 7;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = false;
//
// buttonAdd
//
buttonAdd.BackColor = Color.FromArgb(255, 192, 192);
buttonAdd.Location = new Point(483, 27);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(127, 47);
buttonAdd.TabIndex = 6;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = false;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToResizeRows = false;
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.BackgroundColor = Color.FromArgb(255, 192, 192);
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { ColumnId, ColumnSushiName, ColumnCount });
dataGridView.Location = new Point(13, 27);
dataGridView.Margin = new Padding(2, 3, 2, 3);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(419, 350);
dataGridView.TabIndex = 5;
//
// ColumnId
//
ColumnId.HeaderText = "id";
ColumnId.MinimumWidth = 6;
ColumnId.Name = "ColumnId";
ColumnId.Visible = false;
//
// ColumnSushiName
//
ColumnSushiName.HeaderText = "Название Суши";
ColumnSushiName.MinimumWidth = 6;
ColumnSushiName.Name = "ColumnSushiName";
//
// ColumnCount
//
ColumnCount.HeaderText = "Количество";
ColumnCount.MinimumWidth = 6;
ColumnCount.Name = "ColumnCount";
//
// textBoxName
//
textBoxName.Anchor = AnchorStyles.None;
textBoxName.Location = new Point(124, 6);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(330, 27);
textBoxName.TabIndex = 19;
//
// labelDateOpening
//
labelDateOpening.Anchor = AnchorStyles.None;
labelDateOpening.AutoSize = true;
labelDateOpening.Font = new Font("Candara", 12F);
labelDateOpening.Location = new Point(471, 6);
labelDateOpening.Margin = new Padding(4, 0, 4, 0);
labelDateOpening.Name = "labelDateOpening";
labelDateOpening.Size = new Size(140, 24);
labelDateOpening.TabIndex = 13;
labelDateOpening.Text = "Дата открытия";
//
// labelMaxCount
//
labelMaxCount.AutoSize = true;
labelMaxCount.Font = new Font("Candara", 12F, FontStyle.Regular, GraphicsUnit.Point, 204);
labelMaxCount.Location = new Point(471, 120);
labelMaxCount.Name = "labelMaxCount";
labelMaxCount.Size = new Size(261, 24);
labelMaxCount.TabIndex = 20;
labelMaxCount.Text = "Сколько изделий максимум?";
//
// numericUpDownMaxCount
//
numericUpDownMaxCount.Location = new Point(471, 154);
numericUpDownMaxCount.Name = "numericUpDownMaxCount";
numericUpDownMaxCount.Size = new Size(355, 27);
numericUpDownMaxCount.TabIndex = 21;
//
// FormShop
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(849, 522);
Controls.Add(numericUpDownMaxCount);
Controls.Add(labelMaxCount);
Controls.Add(textBoxName);
Controls.Add(groupBoxComponents);
Controls.Add(labelDateOpening);
Controls.Add(dateTimePickerDateOpening);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxAddress);
Controls.Add(labelAddress);
Controls.Add(labelName);
Name = "FormShop";
Text = "Магазин";
Load += FormShop_Load;
groupBoxComponents.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownMaxCount).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Button buttonCancel;
private Button buttonSave;
private TextBox textBoxAddress;
private Label labelAddress;
private Label labelName;
private DateTimePicker dateTimePickerDateOpening;
private GroupBox groupBoxComponents;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonAdd;
private DataGridView dataGridView;
private TextBox textBoxName;
private DataGridViewTextBoxColumn ColumnId;
private DataGridViewTextBoxColumn ColumnSushiName;
private DataGridViewTextBoxColumn ColumnCount;
private Label labelDateOpening;
private Label labelMaxCount;
private NumericUpDown numericUpDownMaxCount;
}
}

128
SushiBar/Shops/FormShop.cs Normal file
View File

@ -0,0 +1,128 @@
using Microsoft.Extensions.Logging;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using SushiBarDataModels.Models;
using System.Windows.Forms;
namespace SushiBarView.Shops
{
public partial class FormShop : Form
{
private readonly ILogger _logger;
private readonly IShopLogic _logic;
private int? _id;
public int Id
{
set { _id = value; }
}
private Dictionary<int, (ISushiModel, int)> _shopSushis;
public FormShop(ILogger<FormShop> logger, IShopLogic shopLogic)
{
_logger = logger;
_logic = shopLogic;
_shopSushis = new Dictionary<int, (ISushiModel, int)>();
InitializeComponent();
}
private void FormShop_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
_logger.LogInformation("Загрузка магазина");
try
{
var view = _logic.ReadElement(new ShopSearchModel { Id = _id.Value });
if (view != null)
{
textBoxName.Text = view.ShopName;
textBoxAddress.Text = view.Address;
dateTimePickerDateOpening.Text = view.DateOpening.ToString();
numericUpDownMaxCount.Value = view.MaxCountSushis;
_shopSushis = view.ShopSushis ?? new Dictionary<int, (ISushiModel, int)>();
LoadData();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки магазина");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LoadData()
{
_logger.LogInformation("Загрузка изделий магазина");
try
{
if (_shopSushis != null)
{
dataGridView.Rows.Clear();
foreach (var elem in _shopSushis)
{
dataGridView.Rows.Add(new object[]
{
elem.Key,
elem.Value.Item1.SushiName,
elem.Value.Item2
});
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки изделий магазина");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxName.Text))
{
MessageBox.Show("Введите название магазина", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxAddress.Text))
{
MessageBox.Show("Введите название магазина", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation($"Сохранение магазина {textBoxName.Text}");
try
{
var model = new ShopBindingModel
{
Id = _id ?? 0,
ShopName = textBoxName.Text,
Address = textBoxAddress.Text,
DateOpening = dateTimePickerDateOpening.Value.Date,
MaxCountSushis = Convert.ToInt32(numericUpDownMaxCount.Value),
ShopSushis = _shopSushis
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения магазина");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

@ -0,0 +1,129 @@
<?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>
<metadata name="ColumnId.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnSushiName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnCount.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

125
SushiBar/Shops/FormShops.Designer.cs generated Normal file
View File

@ -0,0 +1,125 @@
namespace SushiBarView.Shops
{
partial class FormShops
{
/// <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();
buttonRefresh = new Button();
buttonRemove = new Button();
buttonUpdate = new Button();
buttonAdd = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.BackgroundColor = Color.FromArgb(150, 190, 255);
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(566, 543);
dataGridView.TabIndex = 0;
//
// buttonRefresh
//
buttonRefresh.Font = new Font("Candara", 12F);
buttonRefresh.Location = new Point(626, 453);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(121, 46);
buttonRefresh.TabIndex = 8;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// buttonRemove
//
buttonRemove.Font = new Font("Candara", 12F);
buttonRemove.Location = new Point(626, 316);
buttonRemove.Name = "buttonRemove";
buttonRemove.Size = new Size(121, 46);
buttonRemove.TabIndex = 7;
buttonRemove.Text = "Удалить";
buttonRemove.UseVisualStyleBackColor = true;
buttonRemove.Click += buttonRemove_Click;
//
// buttonUpdate
//
buttonUpdate.Font = new Font("Candara", 12F);
buttonUpdate.Location = new Point(626, 176);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(121, 46);
buttonUpdate.TabIndex = 6;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonAdd
//
buttonAdd.Font = new Font("Candara", 12F);
buttonAdd.Location = new Point(626, 44);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(121, 46);
buttonAdd.TabIndex = 5;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// FormShops
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.FromArgb(190, 220, 255);
ClientSize = new Size(800, 543);
Controls.Add(buttonRefresh);
Controls.Add(buttonRemove);
Controls.Add(buttonUpdate);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormShops";
Text = "Магазины";
Load += FormShops_LoadData;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonRefresh;
private Button buttonRemove;
private Button buttonUpdate;
private Button buttonAdd;
}
}

107
SushiBar/Shops/FormShops.cs Normal file
View File

@ -0,0 +1,107 @@
using Microsoft.Extensions.Logging;
using SushiBar;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using SushiBarDataModels.Models;
using System.Windows.Forms;
namespace SushiBarView.Shops
{
public partial class FormShops : Form
{
private readonly ILogger _logger;
private readonly IShopLogic _shopLogic;
public FormShops(ILogger<FormShops> logger, IShopLogic shopLogic)
{
InitializeComponent();
_logger = logger;
_shopLogic = shopLogic;
}
private void FormShops_LoadData(object sender, EventArgs e)
{
LoadData();
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormShop));
if (service is FormShop form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void LoadData()
{
try
{
var list = _shopLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["ShopName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["ShopSushis"].Visible = false;
}
_logger.LogInformation("Загрузка магазинов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки магазинов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormShop));
if (service is FormShop form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void buttonRemove_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление магазина");
try
{
if (!_shopLogic.Delete(new ShopBindingModel { Id = id }))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления магазина");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

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

View File

@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@ -3,7 +3,19 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34525.116
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SushiBar", "SushiBar.csproj", "{E1025CC0-5650-4509-93C8-BF4FA2D506E0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SushiBarView", "SushiBarView.csproj", "{E1025CC0-5650-4509-93C8-BF4FA2D506E0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SushiBarDataModels", "..\SushiBarDataModels\SushiBarDataModels.csproj", "{98946D8E-A8FC-40DC-9FC8-BCBBC6BD6688}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SushiBarContracts", "..\SushiBarContracts\SushiBarContracts.csproj", "{0C8B928F-ACD2-4196-8F2B-5190914911D8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SushiBarBusinessLogic", "..\SushiBarBusinessLogic\SushiBarBusinessLogic.csproj", "{B4061C5A-A7C4-4F49-A1AC-083877203CD8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SushiBarListImplements", "..\SushiBarListImplements\SushiBarListImplements.csproj", "{BAA05DBA-C77F-4CF6-9998-4C150FA5797C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SushiBarFileImplement", "..\SushiBarFileImplement\SushiBarFileImplement.csproj", "{15B17431-20EB-4A87-9088-C19E5C2DD209}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SushiBarDatabaseImplement", "..\SushiBarDatabaseImplement\SushiBarDatabaseImplement.csproj", "{920F7D63-E1A0-4629-8322-AAD4A5F5ECAF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -15,6 +27,30 @@ Global
{E1025CC0-5650-4509-93C8-BF4FA2D506E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1025CC0-5650-4509-93C8-BF4FA2D506E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1025CC0-5650-4509-93C8-BF4FA2D506E0}.Release|Any CPU.Build.0 = Release|Any CPU
{98946D8E-A8FC-40DC-9FC8-BCBBC6BD6688}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98946D8E-A8FC-40DC-9FC8-BCBBC6BD6688}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98946D8E-A8FC-40DC-9FC8-BCBBC6BD6688}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98946D8E-A8FC-40DC-9FC8-BCBBC6BD6688}.Release|Any CPU.Build.0 = Release|Any CPU
{0C8B928F-ACD2-4196-8F2B-5190914911D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C8B928F-ACD2-4196-8F2B-5190914911D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C8B928F-ACD2-4196-8F2B-5190914911D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C8B928F-ACD2-4196-8F2B-5190914911D8}.Release|Any CPU.Build.0 = Release|Any CPU
{B4061C5A-A7C4-4F49-A1AC-083877203CD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B4061C5A-A7C4-4F49-A1AC-083877203CD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4061C5A-A7C4-4F49-A1AC-083877203CD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4061C5A-A7C4-4F49-A1AC-083877203CD8}.Release|Any CPU.Build.0 = Release|Any CPU
{BAA05DBA-C77F-4CF6-9998-4C150FA5797C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAA05DBA-C77F-4CF6-9998-4C150FA5797C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAA05DBA-C77F-4CF6-9998-4C150FA5797C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BAA05DBA-C77F-4CF6-9998-4C150FA5797C}.Release|Any CPU.Build.0 = Release|Any CPU
{15B17431-20EB-4A87-9088-C19E5C2DD209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{15B17431-20EB-4A87-9088-C19E5C2DD209}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15B17431-20EB-4A87-9088-C19E5C2DD209}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15B17431-20EB-4A87-9088-C19E5C2DD209}.Release|Any CPU.Build.0 = Release|Any CPU
{920F7D63-E1A0-4629-8322-AAD4A5F5ECAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{920F7D63-E1A0-4629-8322-AAD4A5F5ECAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{920F7D63-E1A0-4629-8322-AAD4A5F5ECAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{920F7D63-E1A0-4629-8322-AAD4A5F5ECAF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.8.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.12" />
<PackageReference Include="ReportViewerCore.WinForms" Version="15.1.19" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SushiBarBusinessLogic\SushiBarBusinessLogic.csproj" />
<ProjectReference Include="..\SushiBarContracts\SushiBarContracts.csproj" />
<ProjectReference Include="..\SushiBarDatabaseImplement\SushiBarDatabaseImplement.csproj" />
<ProjectReference Include="..\SushiBarFileImplement\SushiBarFileImplement.csproj" />
<ProjectReference Include="..\SushiBarListImplements\SushiBarListImplements.csproj" />
</ItemGroup>
</Project>

247
SushiBar/Sushis/FormSushi.Designer.cs generated Normal file
View File

@ -0,0 +1,247 @@
namespace SushiBarView
{
partial class FormSushi
{
/// <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()
{
labelName = new Label();
labelPrice = new Label();
textBoxName = new TextBox();
textBoxPrice = new TextBox();
groupBoxComponents = new GroupBox();
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
ColumnId = new DataGridViewTextBoxColumn();
ColumnName = new DataGridViewTextBoxColumn();
ColumnCount = new DataGridViewTextBoxColumn();
buttonSave = new Button();
buttonCancel = new Button();
groupBoxComponents.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(26, 16);
labelName.Margin = new Padding(2, 0, 2, 0);
labelName.Name = "labelName";
labelName.Size = new Size(79, 21);
labelName.TabIndex = 0;
labelName.Text = "Название";
//
// labelPrice
//
labelPrice.AutoSize = true;
labelPrice.Location = new Point(26, 53);
labelPrice.Margin = new Padding(2, 0, 2, 0);
labelPrice.Name = "labelPrice";
labelPrice.Size = new Size(90, 21);
labelPrice.TabIndex = 1;
labelPrice.Text = "Стоимость";
//
// textBoxName
//
textBoxName.Location = new Point(124, 9);
textBoxName.Margin = new Padding(2, 3, 2, 3);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(261, 28);
textBoxName.TabIndex = 2;
//
// textBoxPrice
//
textBoxPrice.Enabled = false;
textBoxPrice.Location = new Point(124, 53);
textBoxPrice.Margin = new Padding(2, 3, 2, 3);
textBoxPrice.Name = "textBoxPrice";
textBoxPrice.Size = new Size(261, 28);
textBoxPrice.TabIndex = 3;
//
// groupBoxComponents
//
groupBoxComponents.Controls.Add(buttonRefresh);
groupBoxComponents.Controls.Add(buttonDelete);
groupBoxComponents.Controls.Add(buttonUpdate);
groupBoxComponents.Controls.Add(buttonAdd);
groupBoxComponents.Controls.Add(dataGridView);
groupBoxComponents.Location = new Point(26, 94);
groupBoxComponents.Margin = new Padding(2, 3, 2, 3);
groupBoxComponents.Name = "groupBoxComponents";
groupBoxComponents.Padding = new Padding(2, 3, 2, 3);
groupBoxComponents.Size = new Size(674, 396);
groupBoxComponents.TabIndex = 5;
groupBoxComponents.TabStop = false;
groupBoxComponents.Text = "Компоненты";
//
// buttonRefresh
//
buttonRefresh.BackColor = Color.FromArgb(255, 192, 192);
buttonRefresh.Location = new Point(483, 330);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(127, 47);
buttonRefresh.TabIndex = 9;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = false;
buttonRefresh.Click += ButtonRef_Click;
//
// buttonDelete
//
buttonDelete.BackColor = Color.FromArgb(255, 192, 192);
buttonDelete.Location = new Point(483, 228);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(127, 47);
buttonDelete.TabIndex = 8;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = false;
buttonDelete.Click += ButtonDel_Click;
//
// buttonUpdate
//
buttonUpdate.BackColor = Color.FromArgb(255, 192, 192);
buttonUpdate.Location = new Point(483, 125);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(127, 47);
buttonUpdate.TabIndex = 7;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = false;
buttonUpdate.Click += ButtonUpd_Click;
//
// buttonAdd
//
buttonAdd.BackColor = Color.FromArgb(255, 192, 192);
buttonAdd.Location = new Point(483, 27);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(127, 47);
buttonAdd.TabIndex = 6;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = false;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToResizeRows = false;
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.BackgroundColor = Color.FromArgb(255, 192, 192);
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { ColumnId, ColumnName, ColumnCount });
dataGridView.Location = new Point(13, 27);
dataGridView.Margin = new Padding(2, 3, 2, 3);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(381, 350);
dataGridView.TabIndex = 5;
//
// ColumnId
//
ColumnId.HeaderText = "id";
ColumnId.MinimumWidth = 6;
ColumnId.Name = "ColumnId";
ColumnId.Visible = false;
//
// ColumnName
//
ColumnName.HeaderText = "Компонент";
ColumnName.MinimumWidth = 6;
ColumnName.Name = "ColumnName";
//
// ColumnCount
//
ColumnCount.HeaderText = "Количество";
ColumnCount.MinimumWidth = 6;
ColumnCount.Name = "ColumnCount";
//
// buttonSave
//
buttonSave.BackColor = Color.FromArgb(255, 192, 192);
buttonSave.Location = new Point(428, 521);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(127, 47);
buttonSave.TabIndex = 10;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = false;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.BackColor = Color.FromArgb(255, 192, 192);
buttonCancel.Location = new Point(572, 520);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(127, 47);
buttonCancel.TabIndex = 11;
buttonCancel.Text = "Отменить";
buttonCancel.UseVisualStyleBackColor = false;
buttonCancel.Click += ButtonCancel_Click;
//
// FormSushi
//
AutoScaleDimensions = new SizeF(9F, 21F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.Cornsilk;
ClientSize = new Size(723, 580);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(groupBoxComponents);
Controls.Add(textBoxPrice);
Controls.Add(textBoxName);
Controls.Add(labelPrice);
Controls.Add(labelName);
Font = new Font("Candara", 10.2F, FontStyle.Regular, GraphicsUnit.Point, 204);
Margin = new Padding(3, 4, 3, 4);
Name = "FormSushi";
Text = "Суши";
Load += FormSushi_Load;
groupBoxComponents.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelName;
private Label labelPrice;
private TextBox textBoxName;
private TextBox textBoxPrice;
private GroupBox groupBoxComponents;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonAdd;
private DataGridView dataGridView;
private DataGridViewTextBoxColumn ColumnId;
private DataGridViewTextBoxColumn ColumnName;
private DataGridViewTextBoxColumn ColumnCount;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,204 @@
using Microsoft.Extensions.Logging;
using SushiBar;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using SushiBarDataModels.Models;
namespace SushiBarView
{
public partial class FormSushi : Form
{
private readonly ILogger _logger;
private readonly ISushiLogic _logic;
private int? _id;
private Dictionary<int, (IComponentModel, int)> _sushiComponents;
public int Id { set { _id = value; } }
public FormSushi(ILogger<FormSushi> logger, ISushiLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
_sushiComponents = new Dictionary<int, (IComponentModel, int)>();
}
private void FormSushi_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
_logger.LogInformation("Загрузка изделия");
try
{
var view = _logic.ReadElement(new SushiSearchModel{ Id = _id.Value });
if (view != null)
{
textBoxName.Text = view.SushiName;
textBoxPrice.Text = view.Price.ToString();
_sushiComponents = view.SushiComponents ?? new Dictionary<int, (IComponentModel, int)>();
LoadData();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки изделия");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LoadData()
{
_logger.LogInformation("Загрузка компонент изделия");
try
{
if (_sushiComponents != null)
{
dataGridView.Rows.Clear();
foreach (var pc in _sushiComponents)
{
dataGridView.Rows.Add(new object[] { pc.Key, pc.Value.Item1.ComponentName, pc.Value.Item2 });
}
textBoxPrice.Text = CalcPrice().ToString();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки компонент изделия");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSushiComponent));
if (service is FormSushiComponent form)
{
if (form.ShowDialog() == DialogResult.OK)
{
if (form.ComponentModel == null)
{
return;
}
_logger.LogInformation("Добавление нового компонента: { ComponentName} - { Count}",
form.ComponentModel.ComponentName, form.Count);
if (_sushiComponents.ContainsKey(form.Id))
{
_sushiComponents[form.Id] = (form.ComponentModel, form.Count);
}
else
{
_sushiComponents.Add(form.Id, (form.ComponentModel, form.Count));
}
LoadData();
}
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSushiComponent));
if (service is FormSushiComponent form)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
form.Id = id;
form.Count = _sushiComponents[id].Item2;
if (form.ShowDialog() == DialogResult.OK)
{
if (form.ComponentModel == null)
{
return;
}
_logger.LogInformation("Изменение компонента: { ComponentName} - { Count} ",
form.ComponentModel.ComponentName, form.Count);
_sushiComponents[form.Id] = (form.ComponentModel, form.Count);
LoadData();
}
}
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
_logger.LogInformation("Удаление компонента: { ComponentName} - { Count}",
dataGridView.SelectedRows[0].Cells[1].Value);
_sushiComponents?.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxName.Text))
{
MessageBox.Show("Заполните название", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxPrice.Text))
{
MessageBox.Show("Заполните цену", "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
if (_sushiComponents == null || _sushiComponents.Count == 0)
{
MessageBox.Show("Заполните компоненты", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение изделия");
try
{
var model = new SushiBindingModel
{
Id = _id ?? 0,
SushiName = textBoxName.Text,
Price = Convert.ToDouble(textBoxPrice.Text),
SushiComponents = _sushiComponents
};
var operationResult = _id.HasValue ? _logic.Update(model) :
_logic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения изделия");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private double CalcPrice()
{
double price = 0;
foreach (var elem in _sushiComponents)
{
price += ((elem.Value.Item1?.Cost ?? 0) * elem.Value.Item2);
}
return Math.Round(price * 1.1, 2);
}
}
}

View File

@ -0,0 +1,129 @@
<?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>
<metadata name="ColumnId.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnCount.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,137 @@
namespace SushiBarView
{
partial class FormSushiComponent
{
/// <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()
{
labelComponent = new Label();
labelCountComponent = new Label();
buttonSave = new Button();
textBoxComponentCount = new TextBox();
comboBoxComponent = new ComboBox();
buttonCancel = new Button();
SuspendLayout();
//
// labelComponent
//
labelComponent.AutoSize = true;
labelComponent.Location = new Point(35, 39);
labelComponent.Margin = new Padding(4, 0, 4, 0);
labelComponent.Name = "labelComponent";
labelComponent.Size = new Size(107, 24);
labelComponent.TabIndex = 0;
labelComponent.Text = "Компонент";
//
// labelCountComponent
//
labelCountComponent.AutoSize = true;
labelCountComponent.Location = new Point(35, 128);
labelCountComponent.Margin = new Padding(4, 0, 4, 0);
labelCountComponent.Name = "labelCountComponent";
labelCountComponent.Size = new Size(112, 24);
labelCountComponent.TabIndex = 1;
labelCountComponent.Text = "Количество";
//
// buttonSave
//
buttonSave.BackColor = Color.Green;
buttonSave.BackgroundImageLayout = ImageLayout.Center;
buttonSave.Cursor = Cursors.Hand;
buttonSave.ForeColor = SystemColors.ControlLightLight;
buttonSave.Location = new Point(205, 197);
buttonSave.Margin = new Padding(4);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(132, 54);
buttonSave.TabIndex = 2;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = false;
buttonSave.Click += ButtonSave_Click;
//
// textBoxComponentCount
//
textBoxComponentCount.Location = new Point(205, 125);
textBoxComponentCount.Margin = new Padding(4);
textBoxComponentCount.Name = "textBoxComponentCount";
textBoxComponentCount.Size = new Size(293, 32);
textBoxComponentCount.TabIndex = 3;
//
// comboBoxComponent
//
comboBoxComponent.Cursor = Cursors.Hand;
comboBoxComponent.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxComponent.FormattingEnabled = true;
comboBoxComponent.Location = new Point(205, 36);
comboBoxComponent.Margin = new Padding(4);
comboBoxComponent.Name = "comboBoxComponent";
comboBoxComponent.Size = new Size(293, 32);
comboBoxComponent.TabIndex = 4;
//
// buttonCancel
//
buttonCancel.BackColor = Color.Green;
buttonCancel.BackgroundImageLayout = ImageLayout.Center;
buttonCancel.Cursor = Cursors.Hand;
buttonCancel.ForeColor = SystemColors.ControlLightLight;
buttonCancel.Location = new Point(362, 197);
buttonCancel.Margin = new Padding(4);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(136, 54);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = false;
buttonCancel.Click += ButtonCancel_Click;
//
// FormSushiComponent
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.FromArgb(210, 255, 200);
ClientSize = new Size(542, 280);
Controls.Add(buttonCancel);
Controls.Add(comboBoxComponent);
Controls.Add(textBoxComponentCount);
Controls.Add(buttonSave);
Controls.Add(labelCountComponent);
Controls.Add(labelComponent);
Font = new Font("Candara", 12F, FontStyle.Regular, GraphicsUnit.Point, 204);
Margin = new Padding(4);
Name = "FormSushiComponent";
Text = "Компонент изделия";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelComponent;
private Label labelCountComponent;
private Button buttonSave;
private TextBox textBoxComponentCount;
private ComboBox comboBoxComponent;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,80 @@
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Models;
namespace SushiBarView
{
public partial class FormSushiComponent : Form
{
private readonly List<ComponentViewModel>? _list;
public int Id
{
get
{
return Convert.ToInt32(comboBoxComponent.SelectedValue);
}
set
{
comboBoxComponent.SelectedValue = value;
}
}
public IComponentModel? ComponentModel
{
get
{
if (_list == null)
{
return null;
}
foreach (var elem in _list)
{
if (elem.Id == Id)
{
return elem;
}
}
return null;
}
}
public int Count
{
get { return Convert.ToInt32(textBoxComponentCount.Text); }
set
{ textBoxComponentCount.Text = value.ToString(); }
}
public FormSushiComponent(IComponentLogic logic)
{
InitializeComponent();
_list = logic.ReadList(null);
if (_list != null)
{
comboBoxComponent.DisplayMember = "ComponentName";
comboBoxComponent.ValueMember = "Id";
comboBoxComponent.DataSource = _list;
comboBoxComponent.SelectedItem = null;
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxComponentCount.Text))
{
MessageBox.Show("Заполните поле Количество", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxComponent.SelectedValue == null)
{
MessageBox.Show("Выберите компонент", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
DialogResult = DialogResult.OK;
Close();
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

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>

123
SushiBar/Sushis/FormSushis.Designer.cs generated Normal file
View File

@ -0,0 +1,123 @@
namespace SushiBarView
{
partial class FormSushis
{
/// <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()
{
buttonRefreshSushi = new Button();
buttonRemoveSushi = new Button();
buttonUpdateSushi = new Button();
buttonAddSushi = new Button();
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// buttonRefreshSushi
//
buttonRefreshSushi.Font = new Font("Candara", 12F);
buttonRefreshSushi.Location = new Point(658, 424);
buttonRefreshSushi.Name = "buttonRefreshSushi";
buttonRefreshSushi.Size = new Size(121, 46);
buttonRefreshSushi.TabIndex = 9;
buttonRefreshSushi.Text = "Обновить";
buttonRefreshSushi.UseVisualStyleBackColor = true;
buttonRefreshSushi.Click += buttonRefreshSushis_Click;
//
// buttonRemoveSushi
//
buttonRemoveSushi.Font = new Font("Candara", 12F);
buttonRemoveSushi.Location = new Point(658, 287);
buttonRemoveSushi.Name = "buttonRemoveSushi";
buttonRemoveSushi.Size = new Size(121, 46);
buttonRemoveSushi.TabIndex = 8;
buttonRemoveSushi.Text = "Удалить";
buttonRemoveSushi.UseVisualStyleBackColor = true;
buttonRemoveSushi.Click += buttonRemoveSushi_Click;
//
// buttonUpdateSushi
//
buttonUpdateSushi.Font = new Font("Candara", 12F);
buttonUpdateSushi.Location = new Point(658, 147);
buttonUpdateSushi.Name = "buttonUpdateSushi";
buttonUpdateSushi.Size = new Size(121, 46);
buttonUpdateSushi.TabIndex = 7;
buttonUpdateSushi.Text = "Изменить";
buttonUpdateSushi.UseVisualStyleBackColor = true;
buttonUpdateSushi.Click += buttonUpdateSushi_Click;
//
// buttonAddSushi
//
buttonAddSushi.Font = new Font("Candara", 12F);
buttonAddSushi.Location = new Point(658, 15);
buttonAddSushi.Name = "buttonAddSushi";
buttonAddSushi.Size = new Size(121, 46);
buttonAddSushi.TabIndex = 6;
buttonAddSushi.Text = "Добавить";
buttonAddSushi.UseVisualStyleBackColor = true;
buttonAddSushi.Click += buttonAddSushi_Click;
//
// dataGridView
//
dataGridView.BackgroundColor = Color.DarkSalmon;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(569, 509);
dataGridView.TabIndex = 5;
//
// FormSushis
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(851, 509);
Controls.Add(buttonRefreshSushi);
Controls.Add(buttonRemoveSushi);
Controls.Add(buttonUpdateSushi);
Controls.Add(buttonAddSushi);
Controls.Add(dataGridView);
Name = "FormSushis";
Text = "Суши";
Load += FormSushis_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private Button buttonRefreshSushi;
private Button buttonRemoveSushi;
private Button buttonUpdateSushi;
private Button buttonAddSushi;
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,122 @@
using Microsoft.Extensions.Logging;
using SushiBar;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SushiBarView
{
public partial class FormSushis : Form
{
private readonly ILogger _logger;
private readonly ISushiLogic _logic;
private int? _id;
public int Id
{
set { _id = value; }
}
public FormSushis(ILogger<FormSushis> logger, ISushiLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormSushis_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["SushiName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["SushiComponents"].Visible = false;
}
_logger.LogInformation("Загрузка списка суш");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки суш");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonAddSushi_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSushi));
if (service is FormSushi form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void buttonUpdateSushi_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormSushi));
if (service is FormSushi form)
{
form.Id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void buttonRemoveSushi_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление компонента");
try
{
if (!_logic.Delete(new SushiBindingModel
{
Id = id
}))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления компонента");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void buttonRefreshSushis_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

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>

16
SushiBar/nlog.config Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<nlog xmlns="https://www.nlog-project.org/schenas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true" internalLogLevel="Info">
<targets>
<target xsi:type="File" name="tofile" fileName="log-${shortdate}.log"></target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="tofile"></logger>
</rules>
</nlog>
</configuration>

View File

@ -0,0 +1,113 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using SushiBarContracts.StoragesContracts;
using SushiBarContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace SushiBarBusinessLogic.BusinessLogic
{
public class ComponentLogic : IComponentLogic
{
private readonly ILogger _logger;
private readonly IComponentStorage _componentStorage;
public ComponentLogic(ILogger<ComponentLogic> logger, IComponentStorage componentStorage)
{
_logger = logger;
_componentStorage = componentStorage;
}
public List<ComponentViewModel>? ReadList(ComponentSearchModel? model)
{
_logger.LogInformation("ReadList. ComponentName:{ComponentName}. Id:{ Id}", model?.ComponentName, model?.Id);
var list = model == null ? _componentStorage.GetFullList() : _componentStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public ComponentViewModel? ReadElement(ComponentSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ComponentName:{ComponentName}.Id:{ Id}", model.ComponentName, model.Id);
var element = _componentStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(ComponentBindingModel model)
{
CheckModel(model);
if (_componentStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ComponentBindingModel model)
{
CheckModel(model);
if (_componentStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ComponentBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_componentStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ComponentBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ComponentName))
{
throw new ArgumentNullException("Нет названия компонента",
nameof(model.ComponentName));
}
if (model.Cost <= 0)
{
throw new ArgumentNullException("Цена компонента должна быть больше 0", nameof(model.Cost));
}
_logger.LogInformation("Component. ComponentName:{ComponentName}. Cost:{ Cost}. Id: { Id}",
model.ComponentName, model.Cost, model.Id);
var element = _componentStorage.GetElement(new ComponentSearchModel {
ComponentName = model.ComponentName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Компонент с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,97 @@
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
using SushiBarBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcel
{
public void CreateReport(ExcelInfo info)
{
CreateExcel(info);
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = info.Title,
StyleInfo = ExcelStyleInfoType.Title
});
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "C1"
});
uint rowIndex = 2;
foreach (var sc in info.SushiComponents)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = sc.SushiName,
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
foreach (var component in sc.Components)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = component.Item1,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = component.Item2.ToString(),
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
rowIndex++;
}
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = "Итого",
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = sc.TotalCount.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
}
SaveExcel(info);
}
/// <summary>
/// Создание excel-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateExcel(ExcelInfo info);
/// <summary>
/// Добавляем новую ячейку в лист
/// </summary>
/// <param name="cellParameters"></param>
protected abstract void InsertCellInWorksheet(ExcelCellParameters
excelParams);
/// <summary>
/// Объединение ячеек
/// </summary>
/// <param name="mergeParameters"></param>
protected abstract void MergeCells(ExcelMergeParameters excelParams);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SaveExcel(ExcelInfo info);
}
}

View File

@ -0,0 +1,79 @@
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
using SushiBarBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdf
{
public void CreateDoc(PdfInfo info)
{
CreatePdf(info);
CreateParagraph(new PdfParagraph
{
Text = info.Title,
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateParagraph(new PdfParagraph
{
Text = $"с { info.DateFrom.ToShortDateString() } по { info.DateTo.ToShortDateString() }", Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateTable(new List<string> { "1cm", "3cm", "4cm", "6cm", "3cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Номер", "Дата заказа", "Статус", "Изделие", "Сумма" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var order in info.Orders)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { order.Id.ToString(), order.DateCreate.ToShortDateString(), order.Status.ToString(), order.SushiName, order.Sum.ToString() },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
CreateParagraph(new PdfParagraph
{
Text = $"Итого: {info.Orders.Sum(x => x.Sum)}\t",
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Rigth
});
SavePdf(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreatePdf(PdfInfo info);
/// <summary>
/// Создание параграфа с текстом
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateParagraph(PdfParagraph paragraph);
/// <summary>
/// Создание таблицы
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateTable(List<string> columns);
/// <summary>
/// Создание и заполнение строки
/// </summary>
/// <param name="rowParameters"></param>
protected abstract void CreateRow(PdfRowParameters rowParameters);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SavePdf(PdfInfo info);
}
}

View File

@ -0,0 +1,58 @@
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
using SushiBarBusinessLogic.OfficePackage.HelperModels;
namespace SushiBarBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWord
{
public void CreateDoc(WordInfo info)
{
CreateWord(info);
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)>
{
(info.Title, new WordTextProperties { Bold = true, Size = "24", })
},
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
foreach (var sushi in info.Sushi)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> {
(sushi.SushiName, new WordTextProperties { Bold = true, Size = "24", }),
(" цена: " + sushi.Price.ToString() + " рублей", new WordTextProperties { Size = "24", })
},
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
}
SaveWord(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateWord(WordInfo info);
/// <summary>
/// Создание абзаца с текстом
/// </summary>
/// <param name="paragraph"></param>
/// <returns></returns>
protected abstract void CreateParagraph(WordParagraph paragraph);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SaveWord(WordInfo info);
}
}

View File

@ -0,0 +1,9 @@
namespace SushiBarBusinessLogic.OfficePackage.HelperEnums
{
public enum ExcelStyleInfoType
{
Title,
Text,
TextWithBroder
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic.OfficePackage.HelperEnums
{
public enum PdfParagraphAlignmentType
{
Center,
Left,
Rigth
}
}

View File

@ -0,0 +1,8 @@
namespace SushiBarBusinessLogic.OfficePackage.HelperEnums
{
public enum WordJustificationType
{
Center,
Both
}
}

View File

@ -0,0 +1,14 @@
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
namespace SushiBarBusinessLogic.OfficePackage.HelperModels
{
public class ExcelCellParameters
{
public string ColumnName { get; set; } = string.Empty;
public uint RowIndex { get; set; }
public string Text { get; set; } = string.Empty;
public string CellReference => $"{ColumnName}{RowIndex}";
public ExcelStyleInfoType StyleInfo { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using SushiBarContracts.ViewModels;
namespace SushiBarBusinessLogic.OfficePackage.HelperModels
{
public class ExcelInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportSushiComponentViewModel> SushiComponents
{
get;
set;
} = new();
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic.OfficePackage.HelperModels
{
public class ExcelMergeParameters
{
public string CellFromName { get; set; } = string.Empty;
public string CellToName { get; set; } = string.Empty;
public string Merge => $"{CellFromName}:{CellToName}";
}
}

View File

@ -0,0 +1,21 @@
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic.OfficePackage.HelperModels
{
public class PdfInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
public List<ReportOrdersViewModel> Orders { get; set; } = new();
}
}

View File

@ -0,0 +1,17 @@
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic.OfficePackage.HelperModels
{
public class PdfParagraph
{
public string Text { get; set; } = string.Empty;
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic.OfficePackage.HelperModels
{
public class PdfRowParameters
{
public List<string> Texts { get; set; } = new();
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using SushiBarContracts.ViewModels;
namespace SushiBarBusinessLogic.OfficePackage.HelperModels
{
public class WordInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<SushiViewModel> Sushi { get; set; } = new();
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic.OfficePackage.HelperModels
{
public class WordParagraph
{
public List<(string, WordTextProperties)> Texts { get; set; } = new();
public WordTextProperties? TextProperties { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
namespace SushiBarBusinessLogic.OfficePackage.HelperModels
{
public class WordTextProperties
{
public string Size { get; set; } = string.Empty;
public bool Bold { get; set; }
public WordJustificationType JustificationType { get; set; }
}
}

View File

@ -0,0 +1,335 @@
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Office2016.Excel;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
using SushiBarBusinessLogic.OfficePackage.HelperModels;
namespace SushiBarBusinessLogic.OfficePackage.Implements
{
public class SaveToExcel : AbstractSaveToExcel
{
private SpreadsheetDocument? _spreadsheetDocument;
private SharedStringTablePart? _shareStringPart;
private Worksheet? _worksheet;
/// <summary>
/// Настройка стилей для файла
/// </summary>
/// <param name="workbookpart"></param>
private static void CreateStyles(WorkbookPart workbookpart)
{
var sp = workbookpart.AddNewPart<WorkbookStylesPart>();
sp.Stylesheet = new Stylesheet();
var fonts = new Fonts() { Count = 2U, KnownFonts = true };
var fontUsual = new Font();
fontUsual.Append(new FontSize() { Val = 12D });
fontUsual.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Theme = 1U });
fontUsual.Append(new FontName() { Val = "Times New Roman" });
fontUsual.Append(new FontFamilyNumbering() { Val = 2 });
fontUsual.Append(new FontScheme() { Val = FontSchemeValues.Minor });
var fontTitle = new Font();
fontTitle.Append(new Bold());
fontTitle.Append(new FontSize() { Val = 14D });
fontTitle.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Theme = 1U });
fontTitle.Append(new FontName() { Val = "Times New Roman" });
fontTitle.Append(new FontFamilyNumbering() { Val = 2 });
fontTitle.Append(new FontScheme() { Val = FontSchemeValues.Minor });
fonts.Append(fontUsual);
fonts.Append(fontTitle);
var fills = new Fills() { Count = 2U };
var fill1 = new Fill();
fill1.Append(new PatternFill() { PatternType = PatternValues.None });
var fill2 = new Fill();
fill2.Append(new PatternFill()
{
PatternType = PatternValues.Gray125
});
fills.Append(fill1);
fills.Append(fill2);
var borders = new Borders() { Count = 2U };
var borderNoBorder = new Border();
borderNoBorder.Append(new LeftBorder());
borderNoBorder.Append(new RightBorder());
borderNoBorder.Append(new TopBorder());
borderNoBorder.Append(new BottomBorder());
borderNoBorder.Append(new DiagonalBorder());
var borderThin = new Border();
var leftBorder = new LeftBorder() { Style = BorderStyleValues.Thin };
leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
var rightBorder = new RightBorder()
{
Style = BorderStyleValues.Thin
};
rightBorder.Append(new
DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
var topBorder = new TopBorder() { Style = BorderStyleValues.Thin };
topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
var bottomBorder = new BottomBorder()
{
Style =
BorderStyleValues.Thin
};
bottomBorder.Append(new
DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
borderThin.Append(leftBorder);
borderThin.Append(rightBorder);
borderThin.Append(topBorder);
borderThin.Append(bottomBorder);
borderThin.Append(new DiagonalBorder());
borders.Append(borderNoBorder);
borders.Append(borderThin);
var cellStyleFormats = new CellStyleFormats() { Count = 1U };
var cellFormatStyle = new CellFormat()
{
NumberFormatId = 0U,
FontId
= 0U,
FillId = 0U,
BorderId = 0U
};
cellStyleFormats.Append(cellFormatStyle);
var cellFormats = new CellFormats() { Count = 3U };
var cellFormatFont = new CellFormat()
{
NumberFormatId = 0U,
FontId =
0U,
FillId = 0U,
BorderId = 0U,
FormatId = 0U,
ApplyFont = true
};
var cellFormatFontAndBorder = new CellFormat()
{
NumberFormatId = 0U,
FontId = 0U,
FillId = 0U,
BorderId = 1U,
FormatId = 0U,
ApplyFont = true,
ApplyBorder = true
};
var cellFormatTitle = new CellFormat()
{
NumberFormatId = 0U,
FontId
= 1U,
FillId = 0U,
BorderId = 0U,
FormatId = 0U,
Alignment = new Alignment()
{
Vertical = VerticalAlignmentValues.Center,
WrapText = true,
Horizontal =
HorizontalAlignmentValues.Center
},
ApplyFont = true
};
cellFormats.Append(cellFormatFont);
cellFormats.Append(cellFormatFontAndBorder);
cellFormats.Append(cellFormatTitle);
var cellStyles = new CellStyles() { Count = 1U };
cellStyles.Append(new CellStyle()
{
Name = "Normal",
FormatId = 0U,
BuiltinId = 0U
});
var differentialFormats = new
DocumentFormat.OpenXml.Office2013.Excel.DifferentialFormats()
{ Count = 0U };
var tableStyles = new TableStyles()
{
Count = 0U,
DefaultTableStyle = "TableStyleMedium2",
DefaultPivotStyle = "PivotStyleLight16"
};
var stylesheetExtensionList = new StylesheetExtensionList();
var stylesheetExtension1 = new StylesheetExtension()
{
Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}"
};
stylesheetExtension1.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
stylesheetExtension1.Append(new SlicerStyles()
{
DefaultSlicerStyle = "SlicerStyleLight1"
});
var stylesheetExtension2 = new StylesheetExtension()
{
Uri = "{9260A510-F301-46a8-8635-F512D64BE5F5}"
};
stylesheetExtension2.AddNamespaceDeclaration("x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
stylesheetExtension2.Append(new TimelineStyles()
{
DefaultTimelineStyle = "TimeSlicerStyleLight1"
});
stylesheetExtensionList.Append(stylesheetExtension1);
stylesheetExtensionList.Append(stylesheetExtension2);
sp.Stylesheet.Append(fonts);
sp.Stylesheet.Append(fills);
sp.Stylesheet.Append(borders);
sp.Stylesheet.Append(cellStyleFormats);
sp.Stylesheet.Append(cellFormats);
sp.Stylesheet.Append(cellStyles);
sp.Stylesheet.Append(differentialFormats);
sp.Stylesheet.Append(tableStyles);
sp.Stylesheet.Append(stylesheetExtensionList);
}
/// <summary>
/// Получение номера стиля из типа
/// </summary>
/// <param name="styleInfo"></param>
/// <returns></returns>
private static uint GetStyleValue(ExcelStyleInfoType styleInfo)
{
return styleInfo switch
{
ExcelStyleInfoType.Title => 2U,
ExcelStyleInfoType.TextWithBroder => 1U,
ExcelStyleInfoType.Text => 0U,
_ => 0U,
};
}
protected override void CreateExcel(ExcelInfo info)
{
_spreadsheetDocument = SpreadsheetDocument.Create(info.FileName,
SpreadsheetDocumentType.Workbook);
// Создаем книгу (в ней хранятся листы)
var workbookpart = _spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
CreateStyles(workbookpart);
// Получаем/создаем хранилище текстов для книги
_shareStringPart =
_spreadsheetDocument.WorkbookPart!.GetPartsOfType<SharedStringTablePart>().Any()
?
_spreadsheetDocument.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First()
:
_spreadsheetDocument.WorkbookPart.AddNewPart<SharedStringTablePart>();
// Создаем SharedStringTable, если его нет
if (_shareStringPart.SharedStringTable == null)
{
_shareStringPart.SharedStringTable = new SharedStringTable();
}
// Создаем лист в книгу
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Добавляем лист в книгу
var sheets =
_spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id =
_spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист"
};
sheets.Append(sheet);
_worksheet = worksheetPart.Worksheet;
}
protected override void InsertCellInWorksheet(ExcelCellParameters excelParams)
{
if (_worksheet == null || _shareStringPart == null)
{
return;
}
var sheetData = _worksheet.GetFirstChild<SheetData>();
if (sheetData == null)
{
return;
}
// Ищем строку, либо добавляем ее
Row row;
if (sheetData.Elements<Row>().Where(r => r.RowIndex! == excelParams.RowIndex).Any())
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex! == excelParams.RowIndex).First();
}
else
{
row = new Row() { RowIndex = excelParams.RowIndex };
sheetData.Append(row);
}
// Ищем нужную ячейку
Cell cell;
if (row.Elements<Cell>().Where(c => c.CellReference!.Value == excelParams.CellReference).Any())
{
cell = row.Elements<Cell>().Where(c => c.CellReference!.Value == excelParams.CellReference).First();
}
else
{
// Все ячейки должны быть последовательно друг за другом расположены
// нужно определить, после какой вставлять
Cell? refCell = null;
foreach (Cell rowCell in row.Elements<Cell>())
{
if (string.Compare(rowCell.CellReference!.Value, excelParams.CellReference, true) > 0)
{
refCell = rowCell;
break;
}
}
var newCell = new Cell()
{
CellReference = excelParams.CellReference
};
row.InsertBefore(newCell, refCell);
cell = newCell;
}
// вставляем новый текст
_shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new Text(excelParams.Text)));
_shareStringPart.SharedStringTable.Save();
cell.CellValue = new CellValue((_shareStringPart.SharedStringTable.Elements<SharedStringItem>().Count() - 1).ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
cell.StyleIndex = GetStyleValue(excelParams.StyleInfo);
}
protected override void MergeCells(ExcelMergeParameters excelParams)
{
if (_worksheet == null)
{
return;
}
MergeCells mergeCells;
if (_worksheet.Elements<MergeCells>().Any())
{
mergeCells = _worksheet.Elements<MergeCells>().First();
}
else
{
mergeCells = new MergeCells();
if (_worksheet.Elements<CustomSheetView>().Any())
{
_worksheet.InsertAfter(mergeCells,
_worksheet.Elements<CustomSheetView>().First());
}
else
{
_worksheet.InsertAfter(mergeCells,
_worksheet.Elements<SheetData>().First());
}
}
var mergeCell = new MergeCell()
{
Reference = new StringValue(excelParams.Merge)
};
mergeCells.Append(mergeCell);
}
protected override void SaveExcel(ExcelInfo info)
{
if (_spreadsheetDocument == null)
{
return;
}
_spreadsheetDocument.WorkbookPart!.Workbook.Save();
_spreadsheetDocument.Dispose();
}
}
}

View File

@ -0,0 +1,98 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
using SushiBarBusinessLogic.OfficePackage.HelperModels;
namespace SushiBarBusinessLogic.OfficePackage.Implements
{
public class SaveToPdf : AbstractSaveToPdf
{
private Document? _document;
private Section? _section;
private Table? _table;
private static ParagraphAlignment GetParagraphAlignment(PdfParagraphAlignmentType type)
{
return type switch
{
PdfParagraphAlignmentType.Center => ParagraphAlignment.Center,
PdfParagraphAlignmentType.Left => ParagraphAlignment.Left,
PdfParagraphAlignmentType.Rigth => ParagraphAlignment.Right,
_ => ParagraphAlignment.Justify,
};
}
/// <summary>
/// Создание стилей для документа
/// </summary>
/// <param name="document"></param>
private static void DefineStyles(Document document)
{
var style = document.Styles["Normal"];
style.Font.Name = "Times New Roman";
style.Font.Size = 14;
style = document.Styles.AddStyle("NormalTitle", "Normal");
style.Font.Bold = true;
}
protected override void CreatePdf(PdfInfo info)
{
_document = new Document();
DefineStyles(_document);
_section = _document.AddSection();
}
protected override void CreateParagraph(PdfParagraph pdfParagraph)
{
if (_section == null)
{
return;
}
var paragraph = _section.AddParagraph(pdfParagraph.Text);
paragraph.Format.SpaceAfter = "1cm";
paragraph.Format.Alignment = GetParagraphAlignment(pdfParagraph.ParagraphAlignment);
paragraph.Style = pdfParagraph.Style;
}
protected override void CreateTable(List<string> columns)
{
if (_document == null)
{
return;
}
_table = _document.LastSection.AddTable();
foreach (var elem in columns)
{
_table.AddColumn(elem);
}
}
protected override void CreateRow(PdfRowParameters rowParameters)
{
if (_table == null)
{
return;
}
var row = _table.AddRow();
for (int i = 0; i < rowParameters.Texts.Count; ++i)
{
row.Cells[i].AddParagraph(rowParameters.Texts[i]);
if (!string.IsNullOrEmpty(rowParameters.Style))
{
row.Cells[i].Style = rowParameters.Style;
}
Unit borderWidth = 0.5;
row.Cells[i].Borders.Left.Width = borderWidth;
row.Cells[i].Borders.Right.Width = borderWidth;
row.Cells[i].Borders.Top.Width = borderWidth;
row.Cells[i].Borders.Bottom.Width = borderWidth;
row.Cells[i].Format.Alignment = GetParagraphAlignment(rowParameters.ParagraphAlignment);
row.Cells[i].VerticalAlignment = VerticalAlignment.Center;
}
}
protected override void SavePdf(PdfInfo info)
{
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(info.FileName);
}
}
}

View File

@ -0,0 +1,121 @@
using SushiBarBusinessLogic.OfficePackage.HelperEnums;
using SushiBarBusinessLogic.OfficePackage.HelperModels;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace SushiBarBusinessLogic.OfficePackage.Implements
{
public class SaveToWord : AbstractSaveToWord
{
private WordprocessingDocument? _wordDocument;
private Body? _docBody;
/// <summary>
/// Получение типа выравнивания
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static JustificationValues
GetJustificationValues(WordJustificationType type)
{
return type switch
{
WordJustificationType.Both => JustificationValues.Both,
WordJustificationType.Center => JustificationValues.Center,
_ => JustificationValues.Left,
};
}
/// <summary>
/// Настройки страницы
/// </summary>
/// <returns></returns>
private static SectionProperties CreateSectionProperties()
{
var properties = new SectionProperties();
var pageSize = new PageSize
{
Orient = PageOrientationValues.Portrait
};
properties.AppendChild(pageSize);
return properties;
}
/// <summary>
/// Задание форматирования для абзаца
/// </summary>
/// <param name="paragraphProperties"></param>
/// <returns></returns>
private static ParagraphProperties? CreateParagraphProperties(WordTextProperties? paragraphProperties)
{
if (paragraphProperties == null)
{
return null;
}
var properties = new ParagraphProperties();
properties.AppendChild(new Justification()
{
Val = GetJustificationValues(paragraphProperties.JustificationType)
});
properties.AppendChild(new SpacingBetweenLines
{
LineRule = LineSpacingRuleValues.Auto
});
properties.AppendChild(new Indentation());
var paragraphMarkRunProperties = new ParagraphMarkRunProperties();
if (!string.IsNullOrEmpty(paragraphProperties.Size))
{
paragraphMarkRunProperties.AppendChild(new FontSize
{
Val = paragraphProperties.Size
});
}
properties.AppendChild(paragraphMarkRunProperties);
return properties;
}
protected override void CreateWord(WordInfo info)
{
_wordDocument = WordprocessingDocument.Create(info.FileName, WordprocessingDocumentType.Document);
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
_docBody = mainPart.Document.AppendChild(new Body());
}
protected override void CreateParagraph(WordParagraph paragraph)
{
if (_docBody == null || paragraph == null)
{
return;
}
var docParagraph = new Paragraph();
docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties));
foreach (var run in paragraph.Texts)
{
var docRun = new Run();
var properties = new RunProperties();
properties.AppendChild(new FontSize { Val = run.Item2.Size });
if (run.Item2.Bold)
{
properties.AppendChild(new Bold());
}
docRun.AppendChild(properties);
docRun.AppendChild(new Text
{
Text = run.Item1,
Space = SpaceProcessingModeValues.Preserve
});
docParagraph.AppendChild(docRun);
}
_docBody.AppendChild(docParagraph);
}
protected override void SaveWord(WordInfo info)
{
if (_docBody == null || _wordDocument == null)
{
return;
}
_docBody.AppendChild(CreateSectionProperties());
_wordDocument.MainDocumentPart!.Document.Save();
_wordDocument.Dispose();
}
}
}

View File

@ -0,0 +1,211 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using SushiBarContracts.StoragesContracts;
using SushiBarContracts.ViewModels;
using Microsoft.Extensions.Logging;
using SushiBarDataModels.Enums;
using SushiBarDataModels.Models;
using System.Xml.Linq;
namespace SushiBarBusinessLogic.BusinessLogic
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly IShopLogic _shopLogic;
private readonly ISushiStorage _sushiStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage,
IShopLogic shopLogic, IShopStorage shopStorage, ISushiStorage sushiStorage)
{
_logger = logger;
_orderStorage = orderStorage;
_shopStorage = shopStorage;
_shopLogic = shopLogic;
_sushiStorage = sushiStorage;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{ Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен) return false;
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выполняется);
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выдан);
}
private bool ChangeStatus(OrderBindingModel model, OrderStatus orderStatus)
{
var order = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (order == null)
{
_logger.LogWarning("Change status operation failed. Order not found");
throw new ArgumentNullException("Не найден заказ... ");
}
if (order.Status + 1 != orderStatus)
{
_logger.LogWarning("Change status operation failed. Incorrect new status: {orderStatus}. Current status: {Status}",
orderStatus, order.Status);
throw new ArgumentException("Вы не можете перевести заказ в статус ", nameof(orderStatus));
}
if(order.Status == OrderStatus.Готов)
{
var sushi = _sushiStorage.GetElement(new SushiSearchModel { Id = order.SushiId });
if (sushi == null)
{
_logger.LogWarning("Status change error. Sushi not found");
throw new ArgumentNullException("Суши не нашлись такие... ");
}
if (!CheckSupply(sushi, order.Count))
{
_logger.LogWarning("Status change error. Shop is overflowed");
throw new ArgumentOutOfRangeException("Вы не можете выдать заказ, амбары переполнены ");
}
}
model.Status = orderStatus;
if (model.Status == OrderStatus.Готов)
{
model.DateImplement = DateTime.Now;
}
else
{
model.DateImplement = order.DateImplement;
}
if (_orderStorage.Update(model) == null)
{
_logger.LogWarning("Change status operation failed");
return false;
}
return true;
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
throw new ArgumentNullException(nameof(model));
if (!withParams) return;
if (model.SushiId <= 0)
throw new ArgumentNullException("Неверный идентификатор суши", nameof(model.SushiId));
if (model.Count <= 0)
throw new ArgumentNullException("Количество суш в заказе не может быть меньше нуля или равно нулю", nameof(model.Count));
if (model.Sum <= 0)
throw new ArgumentNullException("Стоимость заказа не может быть меньше нуля", nameof(model.Sum));
if (model.DateImplement.HasValue && model.DateImplement < model.DateCreate)
throw new ArithmeticException("Заказ должен быть выдан позже, чем был создан");
_logger.LogInformation("Sushi. SushiId:{SushiId}. Count:{ Count}. Sum:{ Sum}. Id: { Id}",
model.SushiId, model.Count, model.Sum, model.Id);
}
public bool CheckSupply(ISushiModel model, int count)
{
if (count <= 0)
{
_logger.LogWarning("Check supply operation error. Planes count < 0");
return false;
}
int sumCapacity = _shopStorage.GetFullList().Select(x => x.MaxCountSushis).Sum();
int sumCount = _shopStorage.GetFullList().Select(x => x.ShopSushis.Select(y => y.Value.Item2).Sum()).Sum();
int free = sumCapacity - sumCount;
if (free < count)
{
_logger.LogWarning("Check supply error. No place for new sushis");
return false;
}
foreach (var shop in _shopStorage.GetFullList())
{
free = shop.MaxCountSushis;
foreach (var sushi in shop.ShopSushis)
{
free -= sushi.Value.Item2;
}
if (free == 0)
{
continue;
}
if (free >= count)
{
if (_shopLogic.AddSushiInShop(new()
{
Id = shop.Id
}, model, count))
{
count = 0;
}
else
{
_logger.LogWarning("Supply error");
return false;
}
}
else
{
if (_shopLogic.AddSushiInShop(new()
{
Id = shop.Id
}, model, free))
{
count -= free;
}
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (count <= 0)
{
return true;
}
}
return false;
}
}
}

View File

@ -0,0 +1,123 @@
using SushiBarBusinessLogic.OfficePackage.HelperModels;
using SushiBarBusinessLogic.OfficePackage;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using SushiBarContracts.StoragesContracts;
using SushiBarContracts.ViewModels;
namespace SushiBarBusinessLogic
{
public class ReportLogic : IReportLogic
{
private readonly IComponentStorage _componentStorage;
private readonly ISushiStorage _sushiStorage;
private readonly IOrderStorage _orderStorage;
private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToPdf _saveToPdf;
public ReportLogic(ISushiStorage sushiStorage, IComponentStorage componentStorage,
IOrderStorage orderStorage, AbstractSaveToExcel saveToExcel,
AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
{
_sushiStorage = sushiStorage;
_componentStorage = componentStorage;
_orderStorage = orderStorage;
_saveToExcel = saveToExcel;
_saveToWord = saveToWord;
_saveToPdf = saveToPdf;
}
/// <summary>
/// Получение списка компонент с указанием, в каких изделиях используются
/// </summary>
/// <returns></returns>
public List<ReportSushiComponentViewModel> GetSushiComponent()
{
var components = _componentStorage.GetFullList();
var sushis = _sushiStorage.GetFullList();
var list = new List<ReportSushiComponentViewModel>();
foreach (var sushi in sushis)
{
var record = new ReportSushiComponentViewModel
{
SushiName = sushi.SushiName,
Components = new List<Tuple<string, int>>(),
TotalCount = 0
};
foreach (var component in components)
{
if (sushi.SushiComponents.ContainsKey(component.Id))
{
record.Components.Add(new Tuple<string, int>(component.ComponentName, sushi.SushiComponents[component.Id].Item2));
record.TotalCount += sushi.SushiComponents[component.Id].Item2;
}
}
list.Add(record);
}
return list;
}
/// <summary>
/// Получение списка заказов за определенный период
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<ReportOrdersViewModel> GetOrders(ReportBindingModel model)
{
return _orderStorage.GetFilteredList(new OrderSearchModel
{
DateFrom = model.DateFrom,
DateTo = model.DateTo
}).Select(x => new ReportOrdersViewModel
{
Id = x.Id,
DateCreate = x.DateCreate,
SushiName = x.SushiName,
Status = x.Status.ToString(),
Sum = x.Sum
}).ToList();
}
/// <summary>
/// Сохранение компонент в файл-Word
/// </summary>
/// <param name="model"></param>
public void SaveSushisToWordFile(ReportBindingModel model)
{
_saveToWord.CreateDoc(new WordInfo
{
FileName = model.FileName,
Title = "Список суши",
Sushi = _sushiStorage.GetFullList()
});
}
/// <summary>
/// Сохранение компонент с указаеним продуктов в файл-Excel
/// </summary>
/// <param name="model"></param>
public void SaveSushiComponentToExcelFile(ReportBindingModel model)
{
_saveToExcel.CreateReport(new ExcelInfo
{
FileName = model.FileName,
Title = "Список изделий",
SushiComponents = GetSushiComponent()
});
}
/// <summary>
/// Сохранение заказов в файл-Pdf
/// </summary>
/// <param name="model"></param>
public void SaveOrdersToPdfFile(ReportBindingModel model)
{
_saveToPdf.CreateDoc(new PdfInfo
{
FileName = model.FileName,
Title = "Список заказов",
DateFrom = model.DateFrom!.Value,
DateTo = model.DateTo!.Value,
Status = model.Status,
Orders = GetOrders(model)
});
}
}
}

View File

@ -0,0 +1,173 @@
using Microsoft.Extensions.Logging;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using SushiBarContracts.StoragesContracts;
using SushiBarContracts.ViewModels;
using SushiBarDataModels;
using SushiBarDataModels.Models;
using System.Numerics;
namespace SushiBarBusinessLogic
{
public class ShopLogic : IShopLogic
{
private readonly ILogger _logger;
private readonly IShopStorage _shopStorage;
public ShopLogic(ILogger<ShopLogic> logger, IShopStorage shopStorage)
{
_logger = logger;
_shopStorage = shopStorage;
}
public List<ShopViewModel>? ReadList(ShopSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{ Id}, ShopName:{ ShopName}", model?.Id, model?.ShopName);
var list = model == null ? _shopStorage.GetFullList() : _shopStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public ShopViewModel? ReadElement(ShopSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadList. Id:{ Id}, ShopName:{ ShopName}", model.Id, model.ShopName);
var element = _shopStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Insert(model) == null)
{
_logger.LogWarning("Вставка в хранилище прервана");
return false;
}
return true;
}
public bool Update(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Update(model) == null)
{
_logger.LogWarning("Обновление прервано");
return false;
}
return true;
}
public bool Delete(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage?.Delete(model) == null)
{
_logger.LogWarning("Удаление прервано");
return false;
}
return true;
}
public bool AddSushiInShop(ShopSearchModel model, ISushiModel sushi, int count)
{
if (model == null)
throw new ArgumentNullException("Не найден такой магазин... \n", nameof(model));
if (count <= 0)
throw new ArgumentException("Количество суши должно быть больше нуля, ало \n", nameof(count));
_logger.LogInformation("Добавлены суши в магазин: {ShopName}.Id:{ Id}", model.ShopName, model.Id);
var element = _shopStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("Не добавлено, магазин не найден с таким названием");
return false;
}
var countSushis = element.ShopSushis.Select(x => x.Value.Item2).Sum();
if (element.MaxCountSushis - countSushis < count)
{
_logger.LogWarning("В магазине не хватает места");
throw new ArgumentOutOfRangeException("Не зватает места в магазине, увы... кушать меньше надо ", nameof(countSushis));
}
if (element.ShopSushis.TryGetValue(sushi.Id, out var samesushi))
{
element.ShopSushis[sushi.Id] = (sushi, samesushi.Item2 + count);
_logger.LogInformation("Same sushi found by supply. Added {0} of {1} in {2} shop", count, sushi.SushiName, element.ShopName);
}
else
{
element.ShopSushis[sushi.Id] = (sushi, count);
_logger.LogInformation("New sushi added by supply. Added {0} of {1} in {2} shop", count, sushi.SushiName, element.ShopName);
}
_shopStorage.Update(new()
{
Id = element.Id,
ShopName = element.ShopName,
Address = element.Address,
DateOpening = element.DateOpening,
ShopSushis = element.ShopSushis,
MaxCountSushis = element.MaxCountSushis,
});
return true;
}
public bool SellSushis(ISushiModel sushi, int count)
{
if (sushi == null)
{
throw new ArgumentNullException("Не найдены такие суши, их нет в магазинах... \n", nameof(sushi));
}
if (count <= 0)
{
throw new ArgumentNullException("Количество суши должно быть больше нуля! алло!\n", nameof(count));
}
if (_shopStorage.SellSushis(sushi, count))
{
_logger.LogInformation("Selling sucsess");
return true;
}
_logger.LogInformation("Selling failed");
return false;
}
private void CheckModel(ShopBindingModel model, bool withParams = true)
{
if (model == null)
throw new ArgumentNullException($"{nameof(model)} является null");
if (!withParams) return;
if (string.IsNullOrEmpty(model.ShopName))
{
throw new ArgumentNullException("Нет такого магазина ", nameof(model.ShopName));
}
_logger.LogInformation("Shop. ShopName:{ShopName}.Address:{ Address}. Id:{ Id}",
model.ShopName, model.Address, model.Id);
var element = _shopStorage.GetElement(new ShopSearchModel
{
ShopName = model.ShopName,
});
if (element != null && element.Id != model.Id && element.ShopName == model.ShopName)
{
throw new InvalidOperationException("Такой магазин с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.12" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SushiBarContracts\SushiBarContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,109 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using SushiBarContracts.StoragesContracts;
using SushiBarContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace SushiBarBusinessLogic.BusinessLogic
{
public class SushiLogic : ISushiLogic
{
private readonly ILogger _logger;
private readonly ISushiStorage _sushiStorage;
public SushiLogic(ILogger<SushiLogic> logger, ISushiStorage sushiStorage)
{
_logger = logger;
_sushiStorage = sushiStorage;
}
public List<SushiViewModel>? ReadList(SushiSearchModel? model)
{
_logger.LogInformation("ReadList. SushiName:{SushiName}. Id:{ Id}", model?.SushiName, model?.Id);
var list = model == null ? _sushiStorage.GetFullList() : _sushiStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public SushiViewModel? ReadElement(SushiSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. SushiName:{SushiName}.Id:{ Id}", model.SushiName, model.Id);
var element = _sushiStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(SushiBindingModel model)
{
CheckModel(model);
if (_sushiStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(SushiBindingModel model)
{
CheckModel(model);
if (_sushiStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(SushiBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_sushiStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(SushiBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.SushiName))
{
throw new ArgumentNullException("Нет названия компонента", nameof(model.SushiName));
}
if (model.Price <= 0)
{
throw new ArgumentNullException("Цена продукта должна быть больше 0", nameof(model.Price));
}
_logger.LogInformation("Sushi. SushiName:{SushiName}. Price:{ Price}. Id: { Id}",
model.SushiName, model.Price, model.Id);
var element = _sushiStorage.GetElement(new SushiSearchModel{SushiName = model.SushiName});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Компонент с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,11 @@
using SushiBarDataModels.Models;
namespace SushiBarContracts.BindingModel
{
public class ComponentBindingModel : IComponentModel
{
public int Id { get; set; }
public string ComponentName { get; set; } = string.Empty;
public double Cost { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using SushiBarDataModels;
using SushiBarDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarContracts.BindingModel
{
public class OrderBindingModel : IOrderModel
{
public int Id { get; set; }
public int SushiId { get; set; }
public int Count { get; set; }
public double Sum { get; set; }
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
public DateTime DateCreate { get; set; } = DateTime.Now;
public DateTime? DateImplement { get; set; }
}
}

View File

@ -0,0 +1,11 @@
using SushiBarDataModels.Enums;
namespace SushiBarContracts.BindingModel
{
public class ReportBindingModel
{
public string FileName { get; set; } = string.Empty;
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using SushiBarDataModels;
using SushiBarDataModels.Models;
namespace SushiBarContracts.BindingModel
{
public class ShopBindingModel : IShopModel
{
public int Id { get; set; }
public int MaxCountSushis { get; set; }
public string ShopName { get; set; }
public string Address { get; set; }
public DateTime DateOpening { get; set; } = DateTime.Now;
public Dictionary<int, (ISushiModel, int)> ShopSushis { get; set; } = new();
}
}

View File

@ -0,0 +1,12 @@
using SushiBarDataModels.Models;
namespace SushiBarContracts.BindingModel
{
public class SushiBindingModel : ISushiModel
{
public int Id { get; set; }
public string SushiName { get; set; } = string.Empty;
public double Price { get; set; }
public Dictionary<int, (IComponentModel, int)> SushiComponents { get; set; } = new();
}
}

View File

@ -0,0 +1,15 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.SearchModel;
using SushiBarContracts.ViewModels;
namespace SushiBarContracts.BusinessLogicsContracts
{
public interface IComponentLogic
{
List<ComponentViewModel>? ReadList(ComponentSearchModel? model);
ComponentViewModel? ReadElement(ComponentSearchModel model);
bool Create(ComponentBindingModel model);
bool Update(ComponentBindingModel model);
bool Delete(ComponentBindingModel model);
}
}

View File

@ -0,0 +1,15 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.SearchModel;
using SushiBarContracts.ViewModels;
namespace SushiBarContracts.BusinessLogicsContracts
{
public interface IOrderLogic
{
List<OrderViewModel>? ReadList(OrderSearchModel? model);
bool CreateOrder(OrderBindingModel model);
bool TakeOrderInWork(OrderBindingModel model);
bool FinishOrder(OrderBindingModel model);
bool DeliveryOrder(OrderBindingModel model);
}
}

View File

@ -0,0 +1,35 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.ViewModels;
namespace SushiBarContracts.BusinessLogicsContracts
{
public interface IReportLogic
{
/// <summary>
/// Получение списка компонент с указанием, в каких изделиях используются
/// </summary>
/// <returns></returns>
List<ReportSushiComponentViewModel> GetSushiComponent();
/// <summary>
/// Получение списка заказов за определенный период
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<ReportOrdersViewModel> GetOrders(ReportBindingModel model);
/// <summary>
/// Сохранение компонент в файл-Word
/// </summary>
/// <param name="model"></param>
void SaveSushisToWordFile(ReportBindingModel model);
/// <summary>
/// Сохранение компонент с указаеним продуктов в файл-Excel
/// </summary>
/// <param name="model"></param>
void SaveSushiComponentToExcelFile(ReportBindingModel model);
/// <summary>
/// Сохранение заказов в файл-Pdf
/// </summary>
/// <param name="model"></param>
void SaveOrdersToPdfFile(ReportBindingModel model);
}
}

View File

@ -0,0 +1,18 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.SearchModel;
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Models;
namespace SushiBarContracts.BusinessLogicsContracts
{
public interface IShopLogic
{
List<ShopViewModel>? ReadList(ShopSearchModel? model);
ShopViewModel? ReadElement(ShopSearchModel model);
bool Create(ShopBindingModel model);
bool Update(ShopBindingModel model);
bool Delete(ShopBindingModel model);
bool AddSushiInShop(ShopSearchModel model, ISushiModel sushi, int count);
bool SellSushis(ISushiModel sushi, int count);
}
}

View File

@ -0,0 +1,16 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.SearchModel;
using SushiBarContracts.ViewModels;
namespace SushiBarContracts.BusinessLogicsContracts
{
public interface ISushiLogic
{
List<SushiViewModel>? ReadList(SushiSearchModel? model);
SushiViewModel? ReadElement(SushiSearchModel model);
bool Create(SushiBindingModel model);
bool Update(SushiBindingModel model);
bool Delete(SushiBindingModel model);
}
}

View File

@ -0,0 +1,9 @@

namespace SushiBarContracts.SearchModel
{
public class ComponentSearchModel
{
public int? Id { get; set; }
public string? ComponentName { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarContracts.SearchModel
{
public class OrderSearchModel
{
public int? Id { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace SushiBarContracts.SearchModel
{
public class ShopSearchModel
{
public int? Id { get; set; }
public string? ShopName { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace SushiBarContracts.SearchModel
{
public class SushiSearchModel
{
public int? Id { get; set; }
public string? SushiName { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.SearchModel;
using SushiBarContracts.ViewModels;
namespace SushiBarContracts.StoragesContracts
{
public interface IComponentStorage
{
List<ComponentViewModel> GetFullList();
List<ComponentViewModel> GetFilteredList(ComponentSearchModel model);
ComponentViewModel? GetElement(ComponentSearchModel model);
ComponentViewModel? Insert(ComponentBindingModel model);
ComponentViewModel? Update(ComponentBindingModel model);
ComponentViewModel? Delete(ComponentBindingModel model);
}
}

View File

@ -0,0 +1,16 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.SearchModel;
using SushiBarContracts.ViewModels;
namespace SushiBarContracts.StoragesContracts
{
public interface IOrderStorage
{
List<OrderViewModel> GetFullList();
List<OrderViewModel> GetFilteredList(OrderSearchModel model);
OrderViewModel? GetElement(OrderSearchModel model);
OrderViewModel? Insert(OrderBindingModel model);
OrderViewModel? Update(OrderBindingModel model);
OrderViewModel? Delete(OrderBindingModel model);
}
}

View File

@ -0,0 +1,19 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.SearchModel;
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Models;
namespace SushiBarContracts.StoragesContracts
{
public interface IShopStorage
{
List<ShopViewModel> GetFullList();
List<ShopViewModel> GetFilteredList(ShopSearchModel model);
ShopViewModel? GetElement(ShopSearchModel model);
ShopViewModel? Insert(ShopBindingModel model);
ShopViewModel? Update(ShopBindingModel model);
ShopViewModel? Delete(ShopBindingModel model);
bool SellSushis(ISushiModel model, int count);
bool CheckCountSushi(ISushiModel model, int count);
}
}

View File

@ -0,0 +1,16 @@
using SushiBarContracts.BindingModel;
using SushiBarContracts.SearchModel;
using SushiBarContracts.ViewModels;
namespace SushiBarContracts.StoragesContracts
{
public interface ISushiStorage
{
List<SushiViewModel> GetFullList();
List<SushiViewModel> GetFilteredList(SushiSearchModel model);
SushiViewModel? GetElement(SushiSearchModel model);
SushiViewModel? Insert(SushiBindingModel model);
SushiViewModel? Update(SushiBindingModel model);
SushiViewModel? Delete(SushiBindingModel model);
}
}

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.12" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SushiBarDataModels\SushiBarDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,18 @@
using System.ComponentModel;
using SushiBarDataModels.Models;
namespace SushiBarContracts.ViewModels
{
public class ComponentViewModel : IComponentModel
{
public int Id { get; set; }
[DisplayName("Название компонента")]
public string ComponentName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Cost { get; set; }
}
}

View File

@ -0,0 +1,38 @@
using System.ComponentModel;
using SushiBarDataModels.Models;
using SushiBarDataModels.Enums;
using SushiBarDataModels;
namespace SushiBarContracts.ViewModels
{
public class OrderViewModel : IOrderModel
{
[DisplayName("Номер")]
public int Id { get; set; }
public int SushiId { get; set; }
[DisplayName("Изделие")]
public string SushiName { get; set; } = string.Empty;
[DisplayName("Количество")]
public int Count { get; set; }
[DisplayName("Сумма")]
public double Sum { get; set; }
[DisplayName("Статус")]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[DisplayName("Дата создания")]
public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
public DateTime? DateImplement { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using SushiBarDataModels.Enums;
namespace SushiBarContracts.ViewModels
{
public class ReportOrdersViewModel
{
public int Id { get; set; }
public DateTime DateCreate { get; set; }
public string SushiName { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public double Sum { get; set; }
}
}

View File

@ -0,0 +1,10 @@
namespace SushiBarContracts.ViewModels
{
public class ReportSushiComponentViewModel
{
public string SushiName { get; set; } = string.Empty;
public int TotalCount { get; set; }
public List<Tuple<string, int>> Components { get; set; } = new();
}
}

View File

@ -0,0 +1,24 @@
using SushiBarDataModels;
using SushiBarDataModels.Models;
using System.ComponentModel;
namespace SushiBarContracts.ViewModels
{
public class ShopViewModel : IShopModel
{
public int Id { get; set; }
[DisplayName("Название магазина")]
public string ShopName { get; set; } = string.Empty;
[DisplayName("Адрес")]
public string Address { get; set; } = string.Empty;
[DisplayName("Максимальное количество суши")]
public int MaxCountSushis { get; set; }
[DisplayName("Дата открытия")]
public DateTime DateOpening { get; set; } = DateTime.Now;
public Dictionary<int, (ISushiModel, int)> ShopSushis { get; set; } = new();
}
}

View File

@ -0,0 +1,23 @@
using System.ComponentModel;
using SushiBarDataModels.Models;
namespace SushiBarContracts.ViewModels
{
public class SushiViewModel : ISushiModel
{
public int Id { get; set; }
[DisplayName("Название изделия")]
public string SushiName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Price { get; set; }
public Dictionary<int, (IComponentModel, int)> SushiComponents
{
get;
set;
} = new();
}
}

View File

@ -0,0 +1,8 @@
namespace SushiBarDataModels.Models
{
public interface IComponentModel
{
string ComponentName { get; }
double Cost { get; }
}
}

View File

@ -0,0 +1,7 @@
namespace SushiBarDataModels
{
public interface IId
{
int Id { get; }
}
}

View File

@ -0,0 +1,14 @@
using SushiBarDataModels.Enums;
namespace SushiBarDataModels
{
public interface IOrderModel : IId
{
int SushiId { get; }
int Count { get; }
double Sum { get; }
OrderStatus Status { get; }
DateTime DateCreate { get; }
DateTime? DateImplement { get; }
}
}

View File

@ -0,0 +1,13 @@
using SushiBarDataModels.Models;
namespace SushiBarDataModels
{
public interface IShopModel : IId
{
int MaxCountSushis { get; }
string ShopName { get; }
string Address { get; }
DateTime DateOpening { get; }
Dictionary<int, (ISushiModel, int)> ShopSushis{ get; }
}
}

View File

@ -0,0 +1,9 @@
namespace SushiBarDataModels.Models
{
public interface ISushiModel : IId
{
string SushiName { get; }
double Price { get; }
Dictionary<int, (IComponentModel, int)> SushiComponents { get; }
}
}

Some files were not shown because too many files have changed in this diff Show More