This commit is contained in:
DeerElk 2024-05-08 11:57:33 +04:00
parent c9705c72f1
commit 80027002c2
36 changed files with 891 additions and 110 deletions

View File

@ -0,0 +1,81 @@
namespace ConfectioneryView
{
partial class FormClients
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer Clients = 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 && (Clients != null))
{
Clients.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();
buttonDel = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// DataGridView
//
dataGridView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
dataGridView.BackgroundColor = SystemColors.Window;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(0, 0);
dataGridView.Margin = new Padding(4);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(742, 444);
dataGridView.TabIndex = 0;
//
// buttonDel
//
buttonDel.Anchor = AnchorStyles.Top | AnchorStyles.Right;
buttonDel.Location = new Point(754, 198);
buttonDel.Margin = new Padding(4);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(112, 56);
buttonDel.TabIndex = 3;
buttonDel.Text = "Удалить";
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// FormClients
//
AutoScaleDimensions = new SizeF(10F, 25F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(878, 444);
Controls.Add(buttonDel);
Controls.Add(dataGridView);
Margin = new Padding(4);
Name = "FormPastries";
Text = "Клиенты";
Load += FormClients_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonDel;
}
}

View File

@ -0,0 +1,78 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
namespace ConfectioneryView
{
public partial class FormClients : Form
{
private readonly ILogger _logger;
private readonly IClientLogic _logic;
public FormClients(ILogger<FormClients> logger, IClientLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["ClientFIO"].AutoSizeMode =
DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["Email"].AutoSizeMode =
DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["Password"].AutoSizeMode =
DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка клиентов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки клиентов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void FormClients_Load(object sender, EventArgs e)
{
LoadData();
}
private void ButtonDel_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 ClientBindingModel
{
Id = id
}))
{
throw new Exception("Ошибка при удалении. " +
"Дополнительная информация в логах.");
}
LoadData();
}
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

@ -36,12 +36,14 @@
textBoxSum = new TextBox(); textBoxSum = new TextBox();
buttonSave = new Button(); buttonSave = new Button();
buttonCancel = new Button(); buttonCancel = new Button();
labelClient = new Label();
comboBoxClient = new ComboBox();
SuspendLayout(); SuspendLayout();
// //
// labelPastry // labelPastry
// //
labelPastry.AutoSize = true; labelPastry.AutoSize = true;
labelPastry.Location = new Point(16, 21); labelPastry.Location = new Point(16, 14);
labelPastry.Name = "labelPastry"; labelPastry.Name = "labelPastry";
labelPastry.Size = new Size(84, 25); labelPastry.Size = new Size(84, 25);
labelPastry.TabIndex = 0; labelPastry.TabIndex = 0;
@ -50,7 +52,7 @@
// labelCount // labelCount
// //
labelCount.AutoSize = true; labelCount.AutoSize = true;
labelCount.Location = new Point(16, 66); labelCount.Location = new Point(16, 61);
labelCount.Name = "labelCount"; labelCount.Name = "labelCount";
labelCount.Size = new Size(111, 25); labelCount.Size = new Size(111, 25);
labelCount.TabIndex = 1; labelCount.TabIndex = 1;
@ -59,7 +61,7 @@
// labelSum // labelSum
// //
labelSum.AutoSize = true; labelSum.AutoSize = true;
labelSum.Location = new Point(16, 112); labelSum.Location = new Point(16, 153);
labelSum.Name = "labelSum"; labelSum.Name = "labelSum";
labelSum.Size = new Size(71, 25); labelSum.Size = new Size(71, 25);
labelSum.TabIndex = 2; labelSum.TabIndex = 2;
@ -70,7 +72,7 @@
comboBoxPastry.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; comboBoxPastry.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
comboBoxPastry.DropDownStyle = ComboBoxStyle.DropDownList; comboBoxPastry.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxPastry.FormattingEnabled = true; comboBoxPastry.FormattingEnabled = true;
comboBoxPastry.Location = new Point(170, 21); comboBoxPastry.Location = new Point(170, 11);
comboBoxPastry.Name = "comboBoxPastry"; comboBoxPastry.Name = "comboBoxPastry";
comboBoxPastry.Size = new Size(396, 33); comboBoxPastry.Size = new Size(396, 33);
comboBoxPastry.TabIndex = 3; comboBoxPastry.TabIndex = 3;
@ -79,7 +81,7 @@
// textBoxCount // textBoxCount
// //
textBoxCount.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; textBoxCount.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
textBoxCount.Location = new Point(170, 66); textBoxCount.Location = new Point(170, 57);
textBoxCount.Name = "textBoxCount"; textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(396, 31); textBoxCount.Size = new Size(396, 31);
textBoxCount.TabIndex = 4; textBoxCount.TabIndex = 4;
@ -88,10 +90,10 @@
// textBoxSum // textBoxSum
// //
textBoxSum.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; textBoxSum.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
textBoxSum.Location = new Point(170, 112); textBoxSum.Location = new Point(170, 149);
textBoxSum.Name = "textBoxSum"; textBoxSum.Name = "textBoxSum";
textBoxSum.ReadOnly = true; textBoxSum.ReadOnly = true;
textBoxSum.Size = new Size(396, 31); textBoxSum.Size = new Size(159, 31);
textBoxSum.TabIndex = 5; textBoxSum.TabIndex = 5;
// //
// buttonSave // buttonSave
@ -116,6 +118,24 @@
buttonCancel.UseVisualStyleBackColor = true; buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click; buttonCancel.Click += ButtonCancel_Click;
// //
// labelClient
//
labelClient.AutoSize = true;
labelClient.Location = new Point(16, 108);
labelClient.Name = "labelClient";
labelClient.Size = new Size(71, 25);
labelClient.TabIndex = 8;
labelClient.Text = "Клиент:";
//
// comboBoxClient
//
comboBoxClient.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxClient.FormattingEnabled = true;
comboBoxClient.Location = new Point(170, 102);
comboBoxClient.Name = "comboBoxClient";
comboBoxClient.Size = new Size(396, 33);
comboBoxClient.TabIndex = 9;
//
// FormCreateOrder // FormCreateOrder
// //
AutoScaleDimensions = new SizeF(10F, 25F); AutoScaleDimensions = new SizeF(10F, 25F);
@ -129,6 +149,8 @@
Controls.Add(labelSum); Controls.Add(labelSum);
Controls.Add(labelCount); Controls.Add(labelCount);
Controls.Add(labelPastry); Controls.Add(labelPastry);
Controls.Add(comboBoxClient);
Controls.Add(labelClient);
Name = "FormCreateOrder"; Name = "FormCreateOrder";
Text = "Создание заказа"; Text = "Создание заказа";
Load += FormCreateOrder_Load; Load += FormCreateOrder_Load;
@ -146,5 +168,7 @@
private TextBox textBoxSum; private TextBox textBoxSum;
private Button buttonSave; private Button buttonSave;
private Button buttonCancel; private Button buttonCancel;
private Label labelClient;
private ComboBox comboBoxClient;
} }
} }

View File

@ -9,13 +9,15 @@ namespace ConfectioneryView
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IPastryLogic _logicP; private readonly IPastryLogic _logicP;
private readonly IOrderLogic _logicO; private readonly IOrderLogic _logicO;
private readonly IClientLogic _logicC;
public FormCreateOrder(ILogger<FormCreateOrder> logger, public FormCreateOrder(ILogger<FormCreateOrder> logger,
IPastryLogic logicP, IOrderLogic logicO) IPastryLogic logicP, IOrderLogic logicO, IClientLogic logicC)
{ {
InitializeComponent(); InitializeComponent();
_logger = logger; _logger = logger;
_logicP = logicP; _logicP = logicP;
_logicO = logicO; _logicO = logicO;
_logicC = logicC;
} }
private void FormCreateOrder_Load(object sender, EventArgs e) private void FormCreateOrder_Load(object sender, EventArgs e)
{ {
@ -38,6 +40,25 @@ namespace ConfectioneryView
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error); MessageBoxIcon.Error);
} }
_logger.LogInformation("Загрузка клиентов для заказа");
try
{
var list = _logicC.ReadList(null);
if (list != null)
{
comboBoxClient.DisplayMember = "ClientFIO";
comboBoxClient.ValueMember = "Id";
comboBoxClient.DataSource = list;
comboBoxClient.SelectedItem = null;
}
_logger.LogInformation("Клиенты загружены");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки клиентов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
} }
private void CalcSum() private void CalcSum()
{ {
@ -70,12 +91,12 @@ namespace ConfectioneryView
} }
private void ComboBoxPastry_SelectedIndexChanged(object sender, private void ComboBoxPastry_SelectedIndexChanged(object sender,
EventArgs e) EventArgs e)
{ {
CalcSum(); CalcSum();
} }
private void ButtonSave_Click(object sender, EventArgs e) private void ButtonSave_Click(object sender, EventArgs e)
{ {
if (string.IsNullOrEmpty(textBoxCount.Text)) if (string.IsNullOrEmpty(textBoxCount.Text))
{ {
MessageBox.Show("Заполните поле Количество", "Ошибка", MessageBox.Show("Заполните поле Количество", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBoxButtons.OK, MessageBoxIcon.Error);
@ -87,12 +108,19 @@ namespace ConfectioneryView
MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBoxButtons.OK, MessageBoxIcon.Error);
return; return;
} }
if (comboBoxClient.SelectedValue == null)
{
MessageBox.Show("Выберите клиента", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Создание заказа"); _logger.LogInformation("Создание заказа");
try try
{ {
var operationResult = _logicO.CreateOrder(new OrderBindingModel var operationResult = _logicO.CreateOrder(new OrderBindingModel
{ {
PastryId = Convert.ToInt32(comboBoxPastry.SelectedValue), PastryId = Convert.ToInt32(comboBoxPastry.SelectedValue),
ClientId = Convert.ToInt32(comboBoxClient.SelectedValue),
Count = Convert.ToInt32(textBoxCount.Text), Count = Convert.ToInt32(textBoxCount.Text),
Sum = Convert.ToDouble(textBoxSum.Text) Sum = Convert.ToDouble(textBoxSum.Text)
}); });

View File

@ -38,6 +38,7 @@
referencesToolStripMenuItem = new ToolStripMenuItem(); referencesToolStripMenuItem = new ToolStripMenuItem();
componentsToolStripMenuItem = new ToolStripMenuItem(); componentsToolStripMenuItem = new ToolStripMenuItem();
pastriesToolStripMenuItem = new ToolStripMenuItem(); pastriesToolStripMenuItem = new ToolStripMenuItem();
clientsToolStripMenuItem = new ToolStripMenuItem();
отчётыToolStripMenuItem = new ToolStripMenuItem(); отчётыToolStripMenuItem = new ToolStripMenuItem();
listOfComponentsToolStripMenuItem = new ToolStripMenuItem(); listOfComponentsToolStripMenuItem = new ToolStripMenuItem();
ComponentsByPastryToolStripMenuItem = new ToolStripMenuItem(); ComponentsByPastryToolStripMenuItem = new ToolStripMenuItem();
@ -119,13 +120,13 @@
menuStrip.Items.AddRange(new ToolStripItem[] { referencesToolStripMenuItem, отчётыToolStripMenuItem }); menuStrip.Items.AddRange(new ToolStripItem[] { referencesToolStripMenuItem, отчётыToolStripMenuItem });
menuStrip.Location = new Point(0, 0); menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip"; menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(235, 33); menuStrip.Size = new Size(415, 33);
menuStrip.TabIndex = 8; menuStrip.TabIndex = 8;
menuStrip.Text = "menuStrip1"; menuStrip.Text = "menuStrip1";
// //
// referencesToolStripMenuItem // referencesToolStripMenuItem
// //
referencesToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { componentsToolStripMenuItem, pastriesToolStripMenuItem }); referencesToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { componentsToolStripMenuItem, pastriesToolStripMenuItem, clientsToolStripMenuItem });
referencesToolStripMenuItem.Name = "referencesToolStripMenuItem"; referencesToolStripMenuItem.Name = "referencesToolStripMenuItem";
referencesToolStripMenuItem.Size = new Size(139, 29); referencesToolStripMenuItem.Size = new Size(139, 29);
referencesToolStripMenuItem.Text = "Справочники"; referencesToolStripMenuItem.Text = "Справочники";
@ -144,6 +145,13 @@
pastriesToolStripMenuItem.Text = "Кондитерские изделия"; pastriesToolStripMenuItem.Text = "Кондитерские изделия";
pastriesToolStripMenuItem.Click += PastriesToolStripMenuItem_Click; pastriesToolStripMenuItem.Click += PastriesToolStripMenuItem_Click;
// //
// clientsToolStripMenuItem
//
clientsToolStripMenuItem.Name = "clientsToolStripMenuItem";
clientsToolStripMenuItem.Size = new Size(298, 34);
clientsToolStripMenuItem.Text = "Клиенты";
clientsToolStripMenuItem.Click += ClientsToolStripMenuItem_Click;
//
// отчётыToolStripMenuItem // отчётыToolStripMenuItem
// //
отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { listOfComponentsToolStripMenuItem, ComponentsByPastryToolStripMenuItem, listOfOrdersToolStripMenuItem }); отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { listOfComponentsToolStripMenuItem, ComponentsByPastryToolStripMenuItem, listOfOrdersToolStripMenuItem });
@ -211,5 +219,6 @@
private ToolStripMenuItem listOfComponentsToolStripMenuItem; private ToolStripMenuItem listOfComponentsToolStripMenuItem;
private ToolStripMenuItem ComponentsByPastryToolStripMenuItem; private ToolStripMenuItem ComponentsByPastryToolStripMenuItem;
private ToolStripMenuItem listOfOrdersToolStripMenuItem; private ToolStripMenuItem listOfOrdersToolStripMenuItem;
private ToolStripMenuItem clientsToolStripMenuItem;
} }
} }

View File

@ -32,6 +32,7 @@ namespace ConfectioneryView
{ {
dataGridView.DataSource = list; dataGridView.DataSource = list;
dataGridView.Columns["PastryId"].Visible = false; dataGridView.Columns["PastryId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["PastryName"].AutoSizeMode = dataGridView.Columns["PastryName"].AutoSizeMode =
DataGridViewAutoSizeColumnMode.None; DataGridViewAutoSizeColumnMode.None;
} }
@ -64,6 +65,15 @@ namespace ConfectioneryView
form.ShowDialog(); form.ShowDialog();
} }
} }
private void ClientsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(
typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
private void ListOfComponentsToolStripMenuItem_Click(object sender, private void ListOfComponentsToolStripMenuItem_Click(object sender,
EventArgs e) EventArgs e)
{ {
@ -203,6 +213,8 @@ namespace ConfectioneryView
Id = id, Id = id,
PastryId = Convert.ToInt32(dataGridView.SelectedRows[ PastryId = Convert.ToInt32(dataGridView.SelectedRows[
0].Cells["PastryId"].Value), 0].Cells["PastryId"].Value),
ClientId = Convert.ToInt32(dataGridView.SelectedRows[
0].Cells["ClientId"].Value),
Status = Enum.Parse<OrderStatus>(dataGridView.SelectedRows[ Status = Enum.Parse<OrderStatus>(dataGridView.SelectedRows[
0].Cells["Status"].Value.ToString()), 0].Cells["Status"].Value.ToString()),
Count = Convert.ToInt32(dataGridView.SelectedRows[ Count = Convert.ToInt32(dataGridView.SelectedRows[

View File

@ -38,10 +38,12 @@ namespace ConfectioneryView
services.AddTransient<IComponentStorage, ComponentStorage>(); services.AddTransient<IComponentStorage, ComponentStorage>();
services.AddTransient<IOrderStorage, OrderStorage>(); services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IPastryStorage, PastryStorage>(); services.AddTransient<IPastryStorage, PastryStorage>();
services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IComponentLogic, ComponentLogic>(); services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IOrderLogic, OrderLogic>(); services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IPastryLogic, PastryLogic>(); services.AddTransient<IPastryLogic, PastryLogic>();
services.AddTransient<IReportLogic, ReportLogic>(); services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<FormMain>(); services.AddTransient<FormMain>();
services.AddTransient<FormComponent>(); services.AddTransient<FormComponent>();
services.AddTransient<FormComponents>(); services.AddTransient<FormComponents>();
@ -51,6 +53,7 @@ namespace ConfectioneryView
services.AddTransient<FormPastries>(); services.AddTransient<FormPastries>();
services.AddTransient<FormReportPastryComponents>(); services.AddTransient<FormReportPastryComponents>();
services.AddTransient<FormReportOrders>(); services.AddTransient<FormReportOrders>();
services.AddTransient<FormClients>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>(); services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>(); services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToPdf, SaveToPdf>(); services.AddTransient<AbstractSaveToPdf, SaveToPdf>();

View File

@ -6,4 +6,14 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ConfectioneryBusinessLogic\ConfectioneryBusinessLogic.csproj" />
<ProjectReference Include="..\ConfectioneryContracts\ConfectioneryContracts.csproj" />
<ProjectReference Include="..\ConfectioneryDatabaseImplement\ConfectioneryDatabaseImplement.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -1,32 +1,146 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.ViewModels;
using ConfectioneryClientApp.Models; using ConfectioneryClientApp.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Diagnostics; using System.Diagnostics;
namespace ConfectioneryClientApp.Controllers namespace ConfectioneryClientApp.Controllers
{ {
public class HomeController : Controller public class HomeController : Controller
{ {
private readonly ILogger<HomeController> _logger; private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger) public HomeController(ILogger<HomeController> logger)
{ {
_logger = logger; _logger = logger;
} }
public IActionResult Index() public IActionResult Index()
{ {
return View(); if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<OrderViewModel>>
($"api/main/getorders?clientId={APIClient.Client.Id}"));
} }
[HttpGet]
public IActionResult Privacy() public IActionResult Privacy()
{ {
return View(); if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.Client);
} }
[HttpPost]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public void Privacy(string login, string password, string fio)
{
if (APIClient.Client == null)
{
throw new Exception(
"Âû êàê ñóäà ïîïàëè? Ñóäà âõîä òîëüêî àâòîðèçîâàííûì");
}
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password)
|| string.IsNullOrEmpty(fio))
{
throw new Exception("Ââåäèòå ëîãèí, ïàðîëü è ÔÈÎ");
}
APIClient.PostRequest("api/client/updatedata",
new ClientBindingModel
{
Id = APIClient.Client.Id,
ClientFIO = fio,
Email = login,
Password = password
});
APIClient.Client.ClientFIO = fio;
APIClient.Client.Email = login;
APIClient.Client.Password = password;
Response.Redirect("Index");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None,
NoStore = true)]
public IActionResult Error() public IActionResult Error()
{ {
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); return View(new ErrorViewModel
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
});
}
[HttpGet]
public IActionResult Enter()
{
return View();
}
[HttpPost]
public void Enter(string login, string password)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))
{
throw new Exception("Ââåäèòå ëîãèí è ïàðîëü");
}
APIClient.Client = APIClient.GetRequest<ClientViewModel>
($"api/client/login?login={login}&password={password}");
if (APIClient.Client == null)
{
throw new Exception("Íåâåðíûé ëîãèí/ïàðîëü");
}
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(string login, string password, string fio)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password)
|| string.IsNullOrEmpty(fio))
{
throw new Exception("Ââåäèòå ëîãèí, ïàðîëü è ÔÈÎ");
}
APIClient.PostRequest("api/client/register", new ClientBindingModel
{
ClientFIO = fio,
Email = login,
Password = password
});
Response.Redirect("Enter");
return;
}
[HttpGet]
public IActionResult Create()
{
ViewBag.Pastries = APIClient.GetRequest<List<PastryViewModel>>
("api/main/getpastrylist");
return View();
}
[HttpPost]
public void Create(int pastry, int count)
{
if (APIClient.Client == null)
{
throw new Exception(
"Âû êàê ñóäà ïîïàëè? Ñóäà âõîä òîëüêî àâòîðèçîâàííûì");
}
if (count <= 0)
{
throw new Exception("Êîëè÷åñòâî è ñóììà äîëæíû áûòü áîëüøå 0");
}
APIClient.PostRequest("api/main/createorder", new OrderBindingModel
{
ClientId = APIClient.Client.Id,
PastryId = pastry,
Count = count,
Sum = Calc(count, pastry)
});
Response.Redirect("Index");
}
[HttpPost]
public double Calc(int count, int pastry)
{
var prod = APIClient.GetRequest<PastryViewModel>
($"api/main/getpastry?pastryId={pastry}");
return count * (prod?.Price ?? 1);
} }
} }
} }

View File

@ -3,7 +3,6 @@ namespace ConfectioneryClientApp.Models
public class ErrorViewModel public class ErrorViewModel
{ {
public string? RequestId { get; set; } public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
} }
} }

View File

@ -1,15 +1,19 @@
using ConfectioneryClientApp;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Add services to the container. // Add services to the container.
builder.Services.AddControllersWithViews(); builder.Services.AddControllersWithViews();
var app = builder.Build(); var app = builder.Build();
APIClient.Connect(builder.Configuration);
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment()) if (!app.Environment.IsDevelopment())
{ {
app.UseExceptionHandler("/Home/Error"); app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. // The default HSTS value is 30 days. You may want to change
// this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts(); app.UseHsts();
} }

View File

@ -9,16 +9,7 @@
} }
}, },
"profiles": { "profiles": {
"http": { "ConfectioneryClientApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5290",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": true, "launchBrowser": true,

View File

@ -0,0 +1,56 @@
@{
ViewData["Title"] = "Создание заказа";
}
<div class="text-center">
<h2 class="display-4">Создание заказа</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Кондитерское изделие:</div>
<div class="col-8">
<select id="pastry" name="pastry" class="form-control"
asp-items="@(new SelectList(@ViewBag.Pastries,"Id",
"PastryName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Количество:</div>
<div class="col-8">
<input type="text" name="count" id="count" />
</div>
</div>
<div class="row">
<div class="col-4">Сумма:</div>
<div class="col-8">
<input type="text" id="sum" name="sum" readonly />
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4">
<input type="submit" value="Создать" class="btn btn-primary" />
</div>
</div>
</form>
<script>
$('#pastry').on('change', function () {
check();
});
$('#count').on('change', function () {
check();
});
function check() {
var count = $('#count').val();
var pastry = $('#pastry').val();
if (count && pastry) {
$.ajax({
method: "POST",
url: "/Home/Calc",
data: { count: count, pastry: pastry },
success: function (result) {
$("#sum").val(result);
}
});
};
}
</script>

View File

@ -0,0 +1,21 @@
@{
ViewData["Title"] = "Вход в приложение";
}
<div class="text-center">
<h2 class="display-4">Вход в приложение</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="login" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Вход"
class="btn btn-primary" /></div>
</div>
</form>

View File

@ -1,8 +1,75 @@
@{ @using ConfectioneryContracts.ViewModels
ViewData["Title"] = "Home Page"; @model List<OrderViewModel>
@{
ViewData["Title"] = "Главная страница";
} }
<div class="text-center"> <div class="text-center">
<h1 class="display-4">Welcome</h1> <h1 class="display-4">Заказы</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div> </div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<p>
<a asp-action="Create">Создать заказ</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Кондитерское изделие
</th>
<th>
Дата создания
</th>
<th>
Количество
</th>
<th>
Сумма
</th>
<th>
Статус
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem =>
item.Id)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.PastryName)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.DateCreate)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Count)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Sum)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Status)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -1,6 +1,35 @@
@{ @using ConfectioneryContracts.ViewModels
ViewData["Title"] = "Privacy Policy"; @model ClientViewModel
@{
ViewData["Title"] = "Личные данные";
} }
<h1>@ViewData["Title"]</h1> <div class="text-center">
<h2 class="display-4">Личные данные</h2>
<p>Use this page to detail your site's privacy policy.</p> </div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8">
<input type="text" name="login"
value="@Model.Email" />
</div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8">
<input type="password" name="password" value="@Model.Password" />
</div>
</div>
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8">
<input type="text" name="fio" value="@Model.ClientFIO" />
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4">
<input type="submit" value="Сохранить" class="btn btn-primary" />
</div>
</div>
</form>

View File

@ -0,0 +1,26 @@
@{
ViewData["Title"] = "Регистрация";
}
<div class="text-center">
<h2 class="display-4">Регистрация</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="login" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8"><input type="text" name="fio" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4">
<input type="submit" value="Регистрация" class="btn btn-primary" />
</div>
</div>
</form>

View File

@ -1,6 +1,6 @@
@model ErrorViewModel @model ErrorViewModel
@{ @{
ViewData["Title"] = "Error"; ViewData["Title"] = "Ошибка";
} }
<h1 class="text-danger">Error.</h1> <h1 class="text-danger">Error.</h1>

View File

@ -3,27 +3,34 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - ConfectioneryClientApp</title> <title>@ViewData["Title"] - Кондитерская</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" /> <link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/ConfectioneryClientApp.styles.css" asp-append-version="true" /> <script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
</head> </head>
<body> <body>
<header> <header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bgwhite border-bottom box-shadow mb-3">
<div class="container-fluid"> <div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ConfectioneryClientApp</a> <a class="navbar-brand" asp-area="" asp-controller="Home" aspaction="Index">Кондитерская</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" <button class="navbar-toggler" type="button" datatoggle="collapse" data-target=".navbar-collapse" ariacontrols="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation"> aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between"> <div class="navbar-collapse collapse d-sm-inline-flex flex-smrow-reverse">
<ul class="navbar-nav flex-grow-1"> <ul class="navbar-nav flex-grow-1">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a> <a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Index">Заказы</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> <a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Register">Регистрация</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -35,15 +42,12 @@
@RenderBody() @RenderBody()
</main> </main>
</div> </div>
<footer class="border-top footer text-muted"> <footer class="border-top footer text-muted">
<div class="container"> <div class="container">
&copy; 2024 - ConfectioneryClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> &copy; 2024 - Кондитерская - <a asp-area="" aspcontroller="Home" asp-action="Privacy">Личные данные</a>
</div> </div>
</footer> </footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script> <script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false) @RenderSection("Scripts", required: false)
</body> </body>
</html> </html>

View File

@ -6,5 +6,5 @@
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"IPAddress": "http://localhost:5159/" "IPAddress": "http://localhost:5041/"
} }

View File

@ -11,8 +11,8 @@ namespace ConfectioneryDatabaseImplement.Implements
{ {
using var context = new ConfectioneryDatabase(); using var context = new ConfectioneryDatabase();
return context.Clients return context.Clients
.Select(x => x.GetViewModel) .Select(x => x.GetViewModel)
.ToList(); .ToList();
} }
public List<ClientViewModel> GetFilteredList(ClientSearchModel model) public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{ {
@ -25,13 +25,13 @@ namespace ConfectioneryDatabaseImplement.Implements
using var context = new ConfectioneryDatabase(); using var context = new ConfectioneryDatabase();
return context.Clients return context.Clients
.Where(x => (string.IsNullOrEmpty(model.ClientFIO) || .Where(x => (string.IsNullOrEmpty(model.ClientFIO) ||
x.ClientFIO.Contains(model.ClientFIO) && x.ClientFIO.Contains(model.ClientFIO) &&
(string.IsNullOrEmpty(model.Email) || (string.IsNullOrEmpty(model.Email) ||
x.Email.Contains(model.Email)) && x.Email.Contains(model.Email)) &&
(string.IsNullOrEmpty(model.Password) || (string.IsNullOrEmpty(model.Password) ||
x.Password.Contains(model.Password)))) x.Password.Contains(model.Password))))
.Select(x => x.GetViewModel) .Select(x => x.GetViewModel)
.ToList(); .ToList();
} }
public ClientViewModel? GetElement(ClientSearchModel model) public ClientViewModel? GetElement(ClientSearchModel model)
{ {
@ -43,13 +43,13 @@ namespace ConfectioneryDatabaseImplement.Implements
using var context = new ConfectioneryDatabase(); using var context = new ConfectioneryDatabase();
return context.Clients return context.Clients
.FirstOrDefault(x => (string.IsNullOrEmpty(model.ClientFIO) || .FirstOrDefault(x => (string.IsNullOrEmpty(model.ClientFIO) ||
x.ClientFIO == model.ClientFIO) && x.ClientFIO == model.ClientFIO) &&
(!model.Id.HasValue || x.Id == model.Id) && (!model.Id.HasValue || x.Id == model.Id) &&
(string.IsNullOrEmpty(model.Email) || (string.IsNullOrEmpty(model.Email) ||
x.Email == model.Email) && x.Email == model.Email) &&
(string.IsNullOrEmpty(model.Password) || (string.IsNullOrEmpty(model.Password) ||
x.Password == model.Password)) x.Password == model.Password))
?.GetViewModel; ?.GetViewModel;
} }
public ClientViewModel? Insert(ClientBindingModel model) public ClientViewModel? Insert(ClientBindingModel model)
{ {

View File

@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace ConfectioneryDatabaseImplement.Migrations namespace ConfectioneryDatabaseImplement.Migrations
{ {
[DbContext(typeof(ConfectioneryDatabase))] [DbContext(typeof(ConfectioneryDatabase))]
[Migration("20240410062130_InitialCreate")] [Migration("20240508053013_InitialCreate")]
partial class InitialCreate partial class InitialCreate
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -20,11 +20,36 @@ namespace ConfectioneryDatabaseImplement.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("PastryVersion", "8.0.3") .HasAnnotation("ProductVersion", "8.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 128); .HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -53,6 +78,9 @@ namespace ConfectioneryDatabaseImplement.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id")); SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count") b.Property<int>("Count")
.HasColumnType("int"); .HasColumnType("int");
@ -73,6 +101,8 @@ namespace ConfectioneryDatabaseImplement.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("PastryId"); b.HasIndex("PastryId");
b.ToTable("Orders"); b.ToTable("Orders");
@ -126,12 +156,20 @@ namespace ConfectioneryDatabaseImplement.Migrations
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b =>
{ {
b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ConfectioneryDatabaseImplement.Models.Pastry", "Pastries") b.HasOne("ConfectioneryDatabaseImplement.Models.Pastry", "Pastries")
.WithMany("Orders") .WithMany("Orders")
.HasForeignKey("PastryId") .HasForeignKey("PastryId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("Client");
b.Navigation("Pastries"); b.Navigation("Pastries");
}); });
@ -154,6 +192,11 @@ namespace ConfectioneryDatabaseImplement.Migrations
b.Navigation("Pastry"); b.Navigation("Pastry");
}); });
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b =>
{ {
b.Navigation("PastryComponents"); b.Navigation("PastryComponents");

View File

@ -11,6 +11,21 @@ namespace ConfectioneryDatabaseImplement.Migrations
/// <inheritdoc /> /// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.CreateTable(
name: "Clients",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ClientFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Email = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Clients", x => x.Id);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "Components", name: "Components",
columns: table => new columns: table => new
@ -50,11 +65,18 @@ namespace ConfectioneryDatabaseImplement.Migrations
Status = table.Column<int>(type: "int", nullable: false), Status = table.Column<int>(type: "int", nullable: false),
DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false), DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false),
DateImplement = table.Column<DateTime>(type: "datetime2", nullable: true), DateImplement = table.Column<DateTime>(type: "datetime2", nullable: true),
PastryId = table.Column<int>(type: "int", nullable: false) PastryId = table.Column<int>(type: "int", nullable: false),
ClientId = table.Column<int>(type: "int", nullable: false)
}, },
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_Orders", x => x.Id); table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "FK_Orders_Pastries_PastryId", name: "FK_Orders_Pastries_PastryId",
column: x => x.PastryId, column: x => x.PastryId,
@ -90,6 +112,11 @@ namespace ConfectioneryDatabaseImplement.Migrations
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.CreateIndex(
name: "IX_Orders_ClientId",
table: "Orders",
column: "ClientId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_Orders_PastryId", name: "IX_Orders_PastryId",
table: "Orders", table: "Orders",
@ -115,6 +142,9 @@ namespace ConfectioneryDatabaseImplement.Migrations
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "PastryComponents"); name: "PastryComponents");
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Components"); name: "Components");

View File

@ -17,11 +17,36 @@ namespace ConfectioneryDatabaseImplement.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("PastryVersion", "8.0.3") .HasAnnotation("ProductVersion", "8.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 128); .HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -50,6 +75,9 @@ namespace ConfectioneryDatabaseImplement.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id")); SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count") b.Property<int>("Count")
.HasColumnType("int"); .HasColumnType("int");
@ -70,6 +98,8 @@ namespace ConfectioneryDatabaseImplement.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("PastryId"); b.HasIndex("PastryId");
b.ToTable("Orders"); b.ToTable("Orders");
@ -123,12 +153,20 @@ namespace ConfectioneryDatabaseImplement.Migrations
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b =>
{ {
b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ConfectioneryDatabaseImplement.Models.Pastry", "Pastries") b.HasOne("ConfectioneryDatabaseImplement.Models.Pastry", "Pastries")
.WithMany("Orders") .WithMany("Orders")
.HasForeignKey("PastryId") .HasForeignKey("PastryId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("Client");
b.Navigation("Pastries"); b.Navigation("Pastries");
}); });
@ -151,6 +189,11 @@ namespace ConfectioneryDatabaseImplement.Migrations
b.Navigation("Pastry"); b.Navigation("Pastry");
}); });
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b => modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b =>
{ {
b.Navigation("PastryComponents"); b.Navigation("PastryComponents");

View File

@ -60,7 +60,7 @@ namespace ConfectioneryDatabaseImplement.Models
DateImplement = DateImplement, DateImplement = DateImplement,
Id = Id, Id = Id,
PastryName = Pastries?.PastryName ?? string.Empty, PastryName = Pastries?.PastryName ?? string.Empty,
ClientFIO = Client?.ClientFIO ?? string.Empty, ClientFIO = Client?.ClientFIO ?? string.Empty
}; };
} }
} }

View File

@ -24,8 +24,9 @@ namespace ConfectioneryFileImplement.Implements
.Where(x => ( .Where(x => (
(!model.Id.HasValue || x.Id == model.Id) && (!model.Id.HasValue || x.Id == model.Id) &&
(!model.DateFrom.HasValue || x.DateCreate >= model.DateFrom) && (!model.DateFrom.HasValue || x.DateCreate >= model.DateFrom) &&
(!model.DateTo.HasValue || x.DateCreate <= model.DateTo) (!model.DateTo.HasValue || x.DateCreate <= model.DateTo) &&
) (!model.ClientId.HasValue || x.ClientId == model.ClientId)
)
) )
.Select(x => AccessPastryStorage(x.GetViewModel)) .Select(x => AccessPastryStorage(x.GetViewModel))
.ToList(); .ToList();

View File

@ -56,8 +56,7 @@ namespace ConfectioneryFileImplement.Models
Password = Password Password = Password
}; };
public XElement GetXElement => new( public XElement GetXElement => new("Client",
"Client",
new XAttribute("Id", Id), new XAttribute("Id", Id),
new XElement("ClientFIO", ClientFIO), new XElement("ClientFIO", ClientFIO),
new XElement("Email", Email.ToString()), new XElement("Email", Email.ToString()),

View File

@ -28,7 +28,8 @@ namespace ConfectioneryListImplement.Implements
{ {
if ((!model.Id.HasValue || order.Id == model.Id) && if ((!model.Id.HasValue || order.Id == model.Id) &&
(!model.DateFrom.HasValue || order.DateCreate >= model.DateFrom) && (!model.DateFrom.HasValue || order.DateCreate >= model.DateFrom) &&
(!model.DateTo.HasValue || order.DateCreate <= model.DateTo)) (!model.DateTo.HasValue || order.DateCreate <= model.DateTo) &&
(!model.ClientId.HasValue || order.ClientId == model.ClientId))
{ {
result.Add(AccessPastryStorage(order.GetViewModel)); result.Add(AccessPastryStorage(order.GetViewModel));
} }

View File

@ -13,6 +13,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ConfectioneryBusinessLogic\ConfectioneryBusinessLogic.csproj" /> <ProjectReference Include="..\ConfectioneryBusinessLogic\ConfectioneryBusinessLogic.csproj" />
<ProjectReference Include="..\ConfectioneryContracts\ConfectioneryContracts.csproj" />
<ProjectReference Include="..\ConfectioneryDatabaseImplement\ConfectioneryDatabaseImplement.csproj" /> <ProjectReference Include="..\ConfectioneryDatabaseImplement\ConfectioneryDatabaseImplement.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,6 +0,0 @@
@ConfectioneryRestApi_HostAddress = http://localhost:5041
GET {{ConfectioneryRestApi_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@ -40,15 +40,14 @@ namespace ConfectioneryRestApi.Controllers
{ {
return _pastry.ReadElement(new PastrySearchModel return _pastry.ReadElement(new PastrySearchModel
{ {
Id = Id = pastryId
pastryId
}); });
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError( _logger.LogError(
ex, "Ошибка получения кондитерского изделия по id={Id}", ex, "Ошибка получения кондитерского изделия по id = {Id}",
pastryId); pastryId);
throw; throw;
} }
} }
@ -65,7 +64,7 @@ namespace ConfectioneryRestApi.Controllers
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError( _logger.LogError(
ex, "Ошибка получения списка заказов клиента id ={ Id}", ex, "Ошибка получения списка заказов клиента id = {Id}",
clientId); clientId);
throw; throw;
} }

View File

@ -3,9 +3,11 @@ using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.StoragesContracts; using ConfectioneryContracts.StoragesContracts;
using ConfectioneryDatabaseImplement.Implements; using ConfectioneryDatabaseImplement.Implements;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Trace); builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddLog4Net("log4net.config"); builder.Logging.AddLog4Net("log4net.config");
// Add services to the container. // Add services to the container.
builder.Services.AddTransient<IClientStorage, ClientStorage>(); builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>(); builder.Services.AddTransient<IOrderStorage, OrderStorage>();
@ -14,8 +16,9 @@ builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IPastryLogic, PastryLogic>(); builder.Services.AddTransient<IPastryLogic, PastryLogic>();
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at // Learn more about configuring Swagger/OpenAPI at
https://aka.ms/aspnetcore/swashbuckle // https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(c =>
{ {
@ -26,6 +29,7 @@ builder.Services.AddSwaggerGen(c =>
}); });
}); });
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
{ {

View File

@ -9,17 +9,7 @@
} }
}, },
"profiles": { "profiles": {
"http": { "ConfectioneryRestApi": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5041",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": true, "launchBrowser": true,

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<log4net> <log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="c:/temp/ComputersShopRestApi.log" /> <file value="c:/temp/ConfectioneryRestApi.log" />
<appendToFile value="true" /> <appendToFile value="true" />
<maximumFileSize value="100KB" /> <maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" /> <maxSizeRollBackups value="2" />