Compare commits

...

17 Commits

117 changed files with 9516 additions and 62 deletions

View File

@ -1,39 +0,0 @@
namespace GarmentFactory
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace GarmentFactory
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

144
GarmentFactory/FormAddTextile.Designer.cs generated Normal file
View File

@ -0,0 +1,144 @@
namespace GarmentFactoryView
{
partial class FormAddTextile
{
/// <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()
{
labelShop = new Label();
labelCount = new Label();
labelTextile = new Label();
comboBoxShop = new ComboBox();
textBoxCount = new TextBox();
comboBoxTextile = new ComboBox();
buttonCancel = new Button();
buttonSave = new Button();
SuspendLayout();
//
// labelShop
//
labelShop.AutoSize = true;
labelShop.Location = new Point(38, 37);
labelShop.Name = "labelShop";
labelShop.Size = new Size(72, 20);
labelShop.TabIndex = 0;
labelShop.Text = "Магазин:";
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(29, 123);
labelCount.Name = "labelCount";
labelCount.Size = new Size(93, 20);
labelCount.TabIndex = 3;
labelCount.Text = "Количество:";
//
// labelTextile
//
labelTextile.AutoSize = true;
labelTextile.Location = new Point(38, 79);
labelTextile.Name = "labelTextile";
labelTextile.Size = new Size(71, 20);
labelTextile.TabIndex = 2;
labelTextile.Text = "Изделие:";
//
// comboBoxShop
//
comboBoxShop.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxShop.FormattingEnabled = true;
comboBoxShop.Location = new Point(140, 37);
comboBoxShop.Name = "comboBoxShop";
comboBoxShop.Size = new Size(262, 28);
comboBoxShop.TabIndex = 11;
//
// textBoxCount
//
textBoxCount.Location = new Point(140, 123);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(262, 27);
textBoxCount.TabIndex = 10;
//
// comboBoxTextile
//
comboBoxTextile.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxTextile.FormattingEnabled = true;
comboBoxTextile.Location = new Point(140, 79);
comboBoxTextile.Name = "comboBoxTextile";
comboBoxTextile.Size = new Size(262, 28);
comboBoxTextile.TabIndex = 9;
//
// buttonCancel
//
buttonCancel.Location = new Point(342, 181);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(94, 29);
buttonCancel.TabIndex = 13;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(242, 181);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(94, 29);
buttonSave.TabIndex = 12;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// FormAddTextile
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(455, 222);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(comboBoxShop);
Controls.Add(textBoxCount);
Controls.Add(comboBoxTextile);
Controls.Add(labelCount);
Controls.Add(labelTextile);
Controls.Add(labelShop);
Name = "FormAddTextile";
Text = "Пополнение магазина";
Load += FormAddTextile_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelShop;
private Label labelCount;
private Label labelTextile;
private ComboBox comboBoxShop;
private TextBox textBoxCount;
private ComboBox comboBoxTextile;
private Button buttonCancel;
private Button buttonSave;
}
}

View File

@ -0,0 +1,109 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using Microsoft.Extensions.Logging;
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 GarmentFactoryView
{
public partial class FormAddTextile : Form
{
private readonly ILogger _logger;
private readonly ITextileLogic _logicT;
private readonly IShopLogic _logicS;
//Списки для ComboBox
private List<ShopViewModel> _shopList = new List<ShopViewModel>();
private List<TextileViewModel> _textileList = new List<TextileViewModel>();
public FormAddTextile(ILogger<FormAddTextile> logger, ITextileLogic logicT, IShopLogic logicS)
{
InitializeComponent();
_logger = logger;
_logicT = logicT;
_logicS = logicS;
}
private void FormAddTextile_Load(object sender, EventArgs e)
{
_shopList = _logicS.ReadList(null);
_textileList = _logicT.ReadList(null);
_logger.LogInformation("Загрузка списка магазинов при пополнении");
if (_shopList != null)
{
comboBoxShop.DisplayMember = "ShopName";
comboBoxShop.ValueMember = "Id";
comboBoxShop.DataSource = _shopList;
comboBoxShop.SelectedItem = null;
}
_logger.LogInformation("Загрузка списка товаров при пополнении");
if (_textileList != null)
{
comboBoxTextile.DisplayMember = "TextileName";
comboBoxTextile.ValueMember = "Id";
comboBoxTextile.DataSource = _textileList;
comboBoxTextile.SelectedItem = null;
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (comboBoxShop.SelectedValue == null)
{
MessageBox.Show("Выберите магазин", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxTextile.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 = _logicS.MakeSupply(new SupplyBindingModel
{
ShopId = Convert.ToInt32(comboBoxShop.SelectedValue),
TextileId = Convert.ToInt32(comboBoxTextile.SelectedValue),
Count = Convert.ToInt32(textBoxCount.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();
}
}
}

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>

118
GarmentFactory/FormComponent.Designer.cs generated Normal file
View File

@ -0,0 +1,118 @@
namespace GarmentFactoryView
{
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()
{
labelName = new Label();
labelCost = new Label();
textBoxName = new TextBox();
textBoxCost = new TextBox();
buttonSave = new Button();
button2 = new Button();
SuspendLayout();
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(12, 34);
labelName.Name = "labelName";
labelName.Size = new Size(80, 20);
labelName.TabIndex = 0;
labelName.Text = "Название:";
//
// labelCost
//
labelCost.AutoSize = true;
labelCost.Location = new Point(12, 85);
labelCost.Name = "labelCost";
labelCost.Size = new Size(48, 20);
labelCost.TabIndex = 1;
labelCost.Text = "Цена:";
//
// textBoxName
//
textBoxName.Location = new Point(104, 31);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(215, 27);
textBoxName.TabIndex = 2;
//
// textBoxCost
//
textBoxCost.Location = new Point(104, 82);
textBoxCost.Name = "textBoxCost";
textBoxCost.Size = new Size(125, 27);
textBoxCost.TabIndex = 3;
//
// buttonSave
//
buttonSave.Location = new Point(187, 138);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(94, 29);
buttonSave.TabIndex = 4;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// button2
//
button2.Location = new Point(288, 138);
button2.Name = "button2";
button2.Size = new Size(94, 29);
button2.TabIndex = 5;
button2.Text = "Отмена";
button2.UseVisualStyleBackColor = true;
button2.Click += ButtonCancel_Click;
//
// FormComponent
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(394, 179);
Controls.Add(button2);
Controls.Add(buttonSave);
Controls.Add(textBoxCost);
Controls.Add(textBoxName);
Controls.Add(labelCost);
Controls.Add(labelName);
Name = "FormComponent";
Text = "Компонент";
Load += FormComponent_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelName;
private Label labelCost;
private TextBox textBoxName;
private TextBox textBoxCost;
private Button buttonSave;
private Button button2;
}
}

View File

@ -0,0 +1,88 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using Microsoft.Extensions.Logging;
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 GarmentFactoryView
{
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 FormComponent_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
try
{
_logger.LogInformation("Получение компонента");
var view = _logic.ReadElement(new ComponentSearchModel {Id = _id.Value});
if (view != null)
{
textBoxName.Text = view.ComponentName;
textBoxCost.Text = view.Cost.ToString();
}
}
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;
}
_logger.LogInformation("Сохранение компонента");
try
{
var model = new ComponentBindingModel
{
Id = _id ?? 0,
ComponentName = textBoxName.Text,
Cost = Convert.ToDouble(textBoxCost.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>

117
GarmentFactory/FormComponents.Designer.cs generated Normal file
View File

@ -0,0 +1,117 @@
namespace GarmentFactoryView
{
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();
buttonAdd = new Button();
buttonUpdate = new Button();
buttonDelete = new Button();
buttonRefresh = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(620, 450);
dataGridView.TabIndex = 0;
//
// buttonAdd
//
buttonAdd.Location = new Point(656, 48);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(120, 40);
buttonAdd.TabIndex = 1;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(656, 113);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(120, 40);
buttonUpdate.TabIndex = 2;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += ButtonUpdate_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(656, 181);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(120, 40);
buttonDelete.TabIndex = 3;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += ButtonDelete_Click;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(656, 250);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(120, 40);
buttonRefresh.TabIndex = 4;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRefresh_Click;
//
// FormComponents
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormComponents";
Text = "Компоненты";
Load += FormComponents_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonAdd;
private Button buttonUpdate;
private Button buttonDelete;
private Button buttonRefresh;
}
}

View File

@ -0,0 +1,112 @@
using GarmentFactory;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
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 GarmentFactoryView
{
public partial class FormComponents : Form
{
private readonly ILogger _logger;
private readonly IComponentLogic _logic;
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 ButtonAdd_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 ButtonUpdate_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 ButtonDelete_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 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>

147
GarmentFactory/FormCreateOrder.Designer.cs generated Normal file
View File

@ -0,0 +1,147 @@
namespace GarmentFactoryView
{
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()
{
buttonSave = new Button();
buttonCancel = new Button();
labelTextile = new Label();
labelCount = new Label();
labelSum = new Label();
textBoxCount = new TextBox();
textBoxSum = new TextBox();
comboBoxTextile = new ComboBox();
SuspendLayout();
//
// buttonSave
//
buttonSave.Location = new Point(238, 168);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(94, 29);
buttonSave.TabIndex = 0;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(347, 168);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(94, 29);
buttonCancel.TabIndex = 1;
buttonCancel.Text = "Отменить";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// labelTextile
//
labelTextile.AutoSize = true;
labelTextile.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
labelTextile.Location = new Point(35, 24);
labelTextile.Name = "labelTextile";
labelTextile.Size = new Size(71, 20);
labelTextile.TabIndex = 2;
labelTextile.Text = "Текстиль:";
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
labelCount.Location = new Point(35, 67);
labelCount.Name = "labelCount";
labelCount.Size = new Size(93, 20);
labelCount.TabIndex = 3;
labelCount.Text = "Количество:";
//
// labelSum
//
labelSum.AutoSize = true;
labelSum.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
labelSum.Location = new Point(35, 111);
labelSum.Name = "labelSum";
labelSum.Size = new Size(58, 20);
labelSum.TabIndex = 4;
labelSum.Text = "Сумма:";
//
// textBoxCount
//
textBoxCount.Location = new Point(134, 67);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(247, 27);
textBoxCount.TabIndex = 5;
textBoxCount.TextChanged += TextBoxCount_TextChanged;
//
// textBoxSum
//
textBoxSum.Enabled = false;
textBoxSum.Location = new Point(134, 111);
textBoxSum.Name = "textBoxSum";
textBoxSum.Size = new Size(247, 27);
textBoxSum.TabIndex = 6;
//
// comboBoxTextile
//
comboBoxTextile.FormattingEnabled = true;
comboBoxTextile.Location = new Point(134, 24);
comboBoxTextile.Name = "comboBoxTextile";
comboBoxTextile.Size = new Size(247, 28);
comboBoxTextile.TabIndex = 7;
comboBoxTextile.SelectedIndexChanged += ComboBoxProduct_SelectedIndexChanged;
//
// FormCreateOrder
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(453, 209);
Controls.Add(comboBoxTextile);
Controls.Add(textBoxSum);
Controls.Add(textBoxCount);
Controls.Add(labelSum);
Controls.Add(labelCount);
Controls.Add(labelTextile);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Name = "FormCreateOrder";
Text = "Заказ";
Load += FormCreateOrder_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Button buttonSave;
private Button buttonCancel;
private Label labelTextile;
private Label labelCount;
private Label labelSum;
private TextBox textBoxCount;
private TextBox textBoxSum;
private ComboBox comboBoxTextile;
}
}

View File

@ -0,0 +1,124 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using Microsoft.Extensions.Logging;
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 GarmentFactoryView
{
public partial class FormCreateOrder : Form
{
private readonly ILogger _logger;
private readonly ITextileLogic _logicT;
private readonly IOrderLogic _logicO;
public FormCreateOrder(ILogger<FormCreateOrder> logger, ITextileLogic logicT, IOrderLogic logicO)
{
InitializeComponent();
_logger = logger;
_logicT = logicT;
_logicO = logicO;
}
private void FormCreateOrder_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка текстилей для заказа");
try
{
var textileList = _logicT.ReadList(null);
if (textileList != null)
{
comboBoxTextile.DisplayMember = "TextileName";
comboBoxTextile.ValueMember = "Id";
comboBoxTextile.DataSource = textileList;
comboBoxTextile.SelectedItem = null;
_logger.LogInformation("Загрузка текстиля для заказа");
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка во время загрузки текстиля для заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
//Суммарная стоимость чека
private void CalcSum()
{
if (comboBoxTextile.SelectedValue != null && !string.IsNullOrEmpty(textBoxCount.Text))
{
try
{
int id = Convert.ToInt32(comboBoxTextile.SelectedValue);
var textile = _logicT.ReadElement(new TextileSearchModel { Id = id });
int count = Convert.ToInt32(textBoxCount.Text);
textBoxSum.Text = Math.Round(count * (textile?.Price ?? 0), 2).ToString();
_logger.LogInformation("Расчет суммы заказа");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка расчета суммы заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void TextBoxCount_TextChanged(object sender, EventArgs e)
{
CalcSum();
}
private void ComboBoxProduct_SelectedIndexChanged(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 (comboBoxTextile.SelectedValue == null)
{
MessageBox.Show("Выберите текстиль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Создание заказа");
try
{
var operationResult = _logicO.CreateOrder(new OrderBindingModel
{
TextileId = Convert.ToInt32(comboBoxTextile.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();
}
}
}

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>

219
GarmentFactory/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,219 @@
namespace GarmentFactoryView
{
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()
{
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonTakeOrderInWork = new Button();
buttonOrderReady = new Button();
buttonCompletedOrder = new Button();
buttonRefresh = new Button();
menuStrip1 = new MenuStrip();
справочникиToolStripMenuItem = new ToolStripMenuItem();
компонентыToolStripMenuItem = new ToolStripMenuItem();
текстилиToolStripMenuItem = new ToolStripMenuItem();
магазиныToolStripMenuItem = new ToolStripMenuItem();
операцииToolStripMenuItem = new ToolStripMenuItem();
пополнениеМагазинаToolStripMenuItem1 = new ToolStripMenuItem();
продажаТовараToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
menuStrip1.SuspendLayout();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(0, 31);
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(950, 425);
dataGridView.TabIndex = 0;
//
// buttonCreateOrder
//
buttonCreateOrder.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
buttonCreateOrder.Location = new Point(977, 80);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(180, 40);
buttonCreateOrder.TabIndex = 1;
buttonCreateOrder.Text = "Создать заказ";
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += ButtonCreateOrder_Click;
//
// buttonTakeOrderInWork
//
buttonTakeOrderInWork.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
buttonTakeOrderInWork.Location = new Point(977, 147);
buttonTakeOrderInWork.Name = "buttonTakeOrderInWork";
buttonTakeOrderInWork.Size = new Size(180, 40);
buttonTakeOrderInWork.TabIndex = 2;
buttonTakeOrderInWork.Text = "Отдать на выполнение";
buttonTakeOrderInWork.UseVisualStyleBackColor = true;
buttonTakeOrderInWork.Click += ButtonTakeOrderInWork_Click;
//
// buttonOrderReady
//
buttonOrderReady.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
buttonOrderReady.Location = new Point(977, 217);
buttonOrderReady.Name = "buttonOrderReady";
buttonOrderReady.Size = new Size(180, 40);
buttonOrderReady.TabIndex = 3;
buttonOrderReady.Text = "Заказ готов";
buttonOrderReady.UseVisualStyleBackColor = true;
buttonOrderReady.Click += ButtonOrderReady_Click;
//
// buttonCompletedOrder
//
buttonCompletedOrder.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
buttonCompletedOrder.Location = new Point(977, 285);
buttonCompletedOrder.Name = "buttonCompletedOrder";
buttonCompletedOrder.Size = new Size(180, 40);
buttonCompletedOrder.TabIndex = 4;
buttonCompletedOrder.Text = "Заказ выдан";
buttonCompletedOrder.UseVisualStyleBackColor = true;
buttonCompletedOrder.Click += ButtonCompletedOrder_Click;
//
// buttonRefresh
//
buttonRefresh.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
buttonRefresh.Location = new Point(977, 363);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(180, 40);
buttonRefresh.TabIndex = 5;
buttonRefresh.Text = "Обновить список";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRefresh_Click;
//
// menuStrip1
//
menuStrip1.ImageScalingSize = new Size(20, 20);
menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, операцииToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Size = new Size(1169, 28);
menuStrip1.TabIndex = 7;
menuStrip1.Text = "menuStrip1";
//
// справочникиToolStripMenuItem
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, текстилиToolStripMenuItem, магазиныToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(117, 24);
справочникиToolStripMenuItem.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.Name = агазиныToolStripMenuItem";
магазиныToolStripMenuItem.Size = new Size(182, 26);
магазиныToolStripMenuItem.Text = "Магазины";
магазиныToolStripMenuItem.Click += магазиныToolStripMenuItem_Click;
//
// операцииToolStripMenuItem
//
операцииToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { пополнениеМагазинаToolStripMenuItem1, продажаТовараToolStripMenuItem });
операцииToolStripMenuItem.Name = "операцииToolStripMenuItem";
операцииToolStripMenuItem.Size = new Size(95, 24);
операцииToolStripMenuItem.Text = "Операции";
//
// пополнениеМагазинаToolStripMenuItem1
//
пополнениеМагазинаToolStripMenuItem1.Name = "пополнениеМагазинаToolStripMenuItem1";
пополнениеМагазинаToolStripMenuItem1.Size = new Size(251, 26);
пополнениеМагазинаToolStripMenuItem1.Text = "Пополнение магазина";
пополнениеМагазинаToolStripMenuItem1.Click += пополнениеМагазинаToolStripMenuItem1_Click;
//
// продажаТовараToolStripMenuItem
//
продажаТовараToolStripMenuItem.Name = "продажаТовараToolStripMenuItem";
продажаТовараToolStripMenuItem.Size = new Size(251, 26);
продажаТовараToolStripMenuItem.Text = "Продажа товара";
продажаТовараToolStripMenuItem.Click += продажаТовараToolStripMenuItem_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1169, 453);
Controls.Add(menuStrip1);
Controls.Add(buttonRefresh);
Controls.Add(buttonCompletedOrder);
Controls.Add(buttonOrderReady);
Controls.Add(buttonTakeOrderInWork);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
MainMenuStrip = menuStrip1;
Name = "FormMain";
Text = "Швейная фабрика";
Load += FormMain_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private DataGridView dataGridView;
private Button buttonCreateOrder;
private Button buttonTakeOrderInWork;
private Button buttonOrderReady;
private Button buttonCompletedOrder;
private Button buttonRefresh;
private MenuStrip menuStrip1;
private ToolStripMenuItem справочникиToolStripMenuItem;
private ToolStripMenuItem компонентыToolStripMenuItem;
private ToolStripMenuItem текстилиToolStripMenuItem;
private ToolStripMenuItem магазиныToolStripMenuItem;
private ToolStripMenuItem операцииToolStripMenuItem;
private ToolStripMenuItem пополнениеМагазинаToolStripMenuItem1;
private ToolStripMenuItem продажаТовараToolStripMenuItem;
}
}

181
GarmentFactory/FormMain.cs Normal file
View File

@ -0,0 +1,181 @@
using GarmentFactory;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
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 GarmentFactoryView
{
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
}
private void LoadData()
{
_logger.LogInformation("Загрузка заказов");
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["TextileId"].Visible = false;
dataGridView.Columns["TextileName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
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(FormTextiles));
if (service is FormTextiles form)
{
form.ShowDialog();
}
}
private void магазиныToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormShops));
if (service is FormShops form)
{
form.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(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(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 ButtonCompletedOrder_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 ButtonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
private void пополнениеМагазинаToolStripMenuItem1_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormAddTextile));
if (service is FormAddTextile form)
{
form.ShowDialog();
}
}
private void продажаТовараToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSellTextile));
if (service is FormSellTextile form)
{
form.ShowDialog();
}
}
}
}

View File

@ -0,0 +1,123 @@
<?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>143, 17</value>
</metadata>
</root>

119
GarmentFactory/FormSellTextile.Designer.cs generated Normal file
View File

@ -0,0 +1,119 @@
namespace GarmentFactoryView
{
partial class FormSellTextile
{
/// <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()
{
labelTextile = new Label();
comboBoxTextile = new ComboBox();
labelCount = new Label();
textBoxCount = new TextBox();
buttonSell = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// labelTextile
//
labelTextile.AutoSize = true;
labelTextile.Location = new Point(12, 14);
labelTextile.Name = "labelTextile";
labelTextile.Size = new Size(77, 20);
labelTextile.TabIndex = 0;
labelTextile.Text = "Текстиль: ";
//
// comboBoxTextile
//
comboBoxTextile.FormattingEnabled = true;
comboBoxTextile.Location = new Point(115, 11);
comboBoxTextile.Name = "comboBoxTextile";
comboBoxTextile.Size = new Size(239, 28);
comboBoxTextile.TabIndex = 1;
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(12, 55);
labelCount.Name = "labelCount";
labelCount.Size = new Size(97, 20);
labelCount.TabIndex = 2;
labelCount.Text = "Количество: ";
//
// textBoxCount
//
textBoxCount.Location = new Point(115, 52);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(239, 27);
textBoxCount.TabIndex = 3;
//
// buttonSell
//
buttonSell.Location = new Point(128, 99);
buttonSell.Name = "buttonSell";
buttonSell.Size = new Size(94, 29);
buttonSell.TabIndex = 4;
buttonSell.Text = "Продать";
buttonSell.UseVisualStyleBackColor = true;
buttonSell.Click += ButtonSell_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(242, 99);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(94, 29);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormSellTextile
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(366, 140);
Controls.Add(buttonCancel);
Controls.Add(buttonSell);
Controls.Add(textBoxCount);
Controls.Add(labelCount);
Controls.Add(comboBoxTextile);
Controls.Add(labelTextile);
Name = "FormSellTextile";
Text = "Продажа текстиля";
Load += FormSellingTextile_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelTextile;
private ComboBox comboBoxTextile;
private Label labelCount;
private TextBox textBoxCount;
private Button buttonSell;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,87 @@
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using Microsoft.Extensions.Logging;
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 GarmentFactoryView
{
public partial class FormSellTextile : Form
{
private readonly ILogger _logger;
private readonly ITextileLogic _logicT;
private readonly IShopLogic _logicS;
private List<TextileViewModel> _TextileList = new List<TextileViewModel>();
public FormSellTextile(ILogger<FormSellTextile> logger, ITextileLogic logicT, IShopLogic logicS)
{
InitializeComponent();
_logger = logger;
_logicT = logicT;
_logicS = logicS;
}
private void FormSellingTextile_Load(object sender, EventArgs e)
{
_TextileList = _logicT.ReadList(null);
if (_TextileList != null)
{
comboBoxTextile.DisplayMember = "TextileName";
comboBoxTextile.ValueMember = "Id";
comboBoxTextile.DataSource = _TextileList;
comboBoxTextile.SelectedItem = null;
_logger.LogInformation("Загрузка пиццы для продажи");
}
}
private void ButtonSell_Click(object sender, EventArgs e)
{
if (comboBoxTextile.SelectedValue == null)
{
MessageBox.Show("Выберите пиццу", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Создание покупки");
try
{
bool resout = _logicS.Sell(new SupplySearchModel
{
TextileId = Convert.ToInt32(comboBoxTextile.SelectedValue),
Count = Convert.ToInt32(textBoxCount.Text)
});
if (resout)
{
_logger.LogInformation("Проверка была выполнена");
MessageBox.Show("Продажа выполнена", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
else
{
_logger.LogInformation("Проверка не пройдена");
MessageBox.Show("Продажа не может быть выполнена.", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
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>

230
GarmentFactory/FormShop.Designer.cs generated Normal file
View File

@ -0,0 +1,230 @@
namespace GarmentFactoryView
{
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()
{
labelName = new Label();
labelAddress = new Label();
labelDateOpen = new Label();
textBoxName = new TextBox();
textBoxAddress = new TextBox();
dateTimePicker = new DateTimePicker();
groupBoxTextiles = new GroupBox();
dataGridView = new DataGridView();
ID = new DataGridViewTextBoxColumn();
ColumnTextileName = new DataGridViewTextBoxColumn();
ColumnCount = new DataGridViewTextBoxColumn();
buttonCancel = new Button();
buttonSave = new Button();
numericUpTextileMaxCount = new NumericUpDown();
label2 = new Label();
groupBoxTextiles.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpTextileMaxCount).BeginInit();
SuspendLayout();
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(30, 21);
labelName.Name = "labelName";
labelName.Size = new Size(84, 20);
labelName.TabIndex = 0;
labelName.Text = "Название: ";
//
// labelAddress
//
labelAddress.AutoSize = true;
labelAddress.Location = new Point(40, 71);
labelAddress.Name = "labelAddress";
labelAddress.Size = new Size(58, 20);
labelAddress.TabIndex = 1;
labelAddress.Text = "Адрес: ";
//
// labelDateOpen
//
labelDateOpen.AutoSize = true;
labelDateOpen.Location = new Point(12, 118);
labelDateOpen.Name = "labelDateOpen";
labelDateOpen.Size = new Size(117, 20);
labelDateOpen.TabIndex = 2;
labelDateOpen.Text = "Дата открытия: ";
//
// textBoxName
//
textBoxName.Location = new Point(135, 21);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(243, 27);
textBoxName.TabIndex = 3;
//
// textBoxAddress
//
textBoxAddress.Location = new Point(135, 68);
textBoxAddress.Name = "textBoxAddress";
textBoxAddress.Size = new Size(243, 27);
textBoxAddress.TabIndex = 4;
//
// dateTimePicker
//
dateTimePicker.Location = new Point(135, 113);
dateTimePicker.Name = "dateTimePicker";
dateTimePicker.Size = new Size(243, 27);
dateTimePicker.TabIndex = 5;
//
// groupBoxTextiles
//
groupBoxTextiles.Controls.Add(dataGridView);
groupBoxTextiles.Location = new Point(12, 209);
groupBoxTextiles.Name = "groupBoxTextiles";
groupBoxTextiles.Size = new Size(651, 306);
groupBoxTextiles.TabIndex = 6;
groupBoxTextiles.TabStop = false;
groupBoxTextiles.Text = "Изделия";
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { ID, ColumnTextileName, ColumnCount });
dataGridView.Location = new Point(6, 26);
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(633, 274);
dataGridView.TabIndex = 0;
//
// ID
//
ID.HeaderText = "ID";
ID.MinimumWidth = 6;
ID.Name = "ID";
ID.ReadOnly = true;
ID.Visible = false;
//
// ColumnTextileName
//
ColumnTextileName.HeaderText = "Изделие";
ColumnTextileName.MinimumWidth = 6;
ColumnTextileName.Name = "ColumnTextileName";
ColumnTextileName.ReadOnly = true;
//
// ColumnCount
//
ColumnCount.HeaderText = "Количество";
ColumnCount.MinimumWidth = 6;
ColumnCount.Name = "ColumnCount";
ColumnCount.ReadOnly = true;
//
// buttonCancel
//
buttonCancel.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point);
buttonCancel.Location = new Point(550, 532);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(103, 40);
buttonCancel.TabIndex = 9;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// buttonSave
//
buttonSave.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point);
buttonSave.Location = new Point(432, 532);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(103, 40);
buttonSave.TabIndex = 8;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// numericUpTextileMaxCount
//
numericUpTextileMaxCount.Location = new Point(135, 163);
numericUpTextileMaxCount.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
numericUpTextileMaxCount.Name = "numericUpTextileMaxCount";
numericUpTextileMaxCount.Size = new Size(243, 27);
numericUpTextileMaxCount.TabIndex = 13;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(19, 165);
label2.Name = "label2";
label2.Size = new Size(103, 20);
label2.TabIndex = 12;
label2.Text = "Вместимость:";
//
// FormShop
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(682, 584);
Controls.Add(numericUpTextileMaxCount);
Controls.Add(label2);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(groupBoxTextiles);
Controls.Add(dateTimePicker);
Controls.Add(textBoxAddress);
Controls.Add(textBoxName);
Controls.Add(labelDateOpen);
Controls.Add(labelAddress);
Controls.Add(labelName);
Name = "FormShop";
Text = "Магазин";
Load += FormShop_Load;
groupBoxTextiles.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpTextileMaxCount).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelName;
private Label labelAddress;
private Label labelDateOpen;
private TextBox textBoxName;
private TextBox textBoxAddress;
private DateTimePicker dateTimePicker;
private GroupBox groupBoxTextiles;
private DataGridView dataGridView;
private DataGridViewTextBoxColumn ID;
private DataGridViewTextBoxColumn ColumnTextileName;
private DataGridViewTextBoxColumn ColumnCount;
private Button buttonCancel;
private Button buttonSave;
private NumericUpDown numericUpTextileMaxCount;
private Label label2;
}
}

135
GarmentFactory/FormShop.cs Normal file
View File

@ -0,0 +1,135 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryDataModels.Models;
using Microsoft.Extensions.Logging;
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 GarmentFactoryView
{
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, (ITextileModel, int)> _shopTextiles;
public FormShop(ILogger<FormShop> logger, IShopLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
_shopTextiles = new Dictionary<int, (ITextileModel, int)>();
}
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.ToString();
dateTimePicker.Value = view.DateOpen;
numericUpTextileMaxCount.Value = view.TextileMaxCount;
_shopTextiles = view.ShopTextiles ?? new Dictionary<int, (ITextileModel, int)>();
LoadData();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки магазина");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LoadData()
{
_logger.LogInformation("Загрузка изделий в магазине");
try
{
if (_shopTextiles != null)
{
dataGridView.Rows.Clear();
foreach (var element in _shopTextiles)
{
dataGridView.Rows.Add(new object[] { element.Key, element.Value.Item1.TextileName, element.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("Сохранение магазина");
try
{
var model = new ShopBindingModel
{
Id = _id ?? 0,
ShopName = textBoxName.Text,
Address = textBoxAddress.Text,
DateOpen = dateTimePicker.Value.Date,
ShopTextiles = _shopTextiles,
TextileMaxCount = (int)numericUpTextileMaxCount.Value
};
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="ID.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnTextileName.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>

116
GarmentFactory/FormShops.Designer.cs generated Normal file
View File

@ -0,0 +1,116 @@
namespace GarmentFactoryView
{
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();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonAdd = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(-3, -4);
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(640, 455);
dataGridView.TabIndex = 0;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(658, 252);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(120, 40);
buttonRefresh.TabIndex = 12;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRefresh_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(658, 183);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(120, 40);
buttonDelete.TabIndex = 11;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += ButtonDelete_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(658, 115);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(120, 40);
buttonUpdate.TabIndex = 10;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += ButtonUpdate_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(658, 50);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(120, 40);
buttonAdd.TabIndex = 9;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// FormShops
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormShops";
Text = "Магазины";
Load += FormShops_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonAdd;
}
}

115
GarmentFactory/FormShops.cs Normal file
View File

@ -0,0 +1,115 @@
using GarmentFactory;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
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 GarmentFactoryView
{
public partial class FormShops : Form
{
private readonly ILogger _logger;
private readonly IShopLogic _logic;
public FormShops(ILogger<FormShops> logger, IShopLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormShops_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["ShopTextiles"].Visible = false;
dataGridView.Columns["ShopName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка магазинов");
}
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(FormShop));
if (service is FormShop form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
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 ButtonDelete_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 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>

239
GarmentFactory/FormTextile.Designer.cs generated Normal file
View File

@ -0,0 +1,239 @@
namespace GarmentFactoryView
{
partial class FormTextile
{
/// <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()
{
label1 = new Label();
label2 = new Label();
textBoxName = new TextBox();
textBoxPrice = new TextBox();
groupBoxTextileComponents = new GroupBox();
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
Column1 = new DataGridViewTextBoxColumn();
Column2 = new DataGridViewTextBoxColumn();
Column3 = new DataGridViewTextBoxColumn();
buttonSave = new Button();
buttonCancel = new Button();
groupBoxTextileComponents.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(12, 21);
label1.Name = "label1";
label1.Size = new Size(80, 20);
label1.TabIndex = 0;
label1.Text = "Название:";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(12, 63);
label2.Name = "label2";
label2.Size = new Size(86, 20);
label2.TabIndex = 1;
label2.Text = "Стоимость:";
//
// textBoxName
//
textBoxName.Location = new Point(110, 21);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(358, 27);
textBoxName.TabIndex = 2;
//
// textBoxPrice
//
textBoxPrice.Enabled = false;
textBoxPrice.Location = new Point(110, 63);
textBoxPrice.Name = "textBoxPrice";
textBoxPrice.Size = new Size(209, 27);
textBoxPrice.TabIndex = 3;
//
// groupBoxTextileComponents
//
groupBoxTextileComponents.Controls.Add(buttonRefresh);
groupBoxTextileComponents.Controls.Add(buttonDelete);
groupBoxTextileComponents.Controls.Add(buttonUpdate);
groupBoxTextileComponents.Controls.Add(buttonAdd);
groupBoxTextileComponents.Controls.Add(dataGridView);
groupBoxTextileComponents.Location = new Point(12, 115);
groupBoxTextileComponents.Name = "groupBoxTextileComponents";
groupBoxTextileComponents.Size = new Size(776, 323);
groupBoxTextileComponents.TabIndex = 5;
groupBoxTextileComponents.TabStop = false;
groupBoxTextileComponents.Text = "Компоненты";
//
// buttonRefresh
//
buttonRefresh.Location = new Point(623, 254);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(120, 40);
buttonRefresh.TabIndex = 4;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRefresh_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(623, 174);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(120, 40);
buttonDelete.TabIndex = 3;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += ButtonDelete_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(623, 97);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(120, 40);
buttonUpdate.TabIndex = 2;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += ButtonUpdate_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(623, 26);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(120, 40);
buttonAdd.TabIndex = 1;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { Column1, Column2, Column3 });
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(3, 23);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(574, 297);
dataGridView.TabIndex = 0;
//
// Column1
//
Column1.HeaderText = "Id";
Column1.MinimumWidth = 6;
Column1.Name = "Column1";
Column1.ReadOnly = true;
Column1.Visible = false;
//
// Column2
//
Column2.HeaderText = "Компонент";
Column2.MinimumWidth = 6;
Column2.Name = "Column2";
Column2.ReadOnly = true;
//
// Column3
//
Column3.HeaderText = "Количество";
Column3.MinimumWidth = 6;
Column3.Name = "Column3";
Column3.ReadOnly = true;
//
// buttonSave
//
buttonSave.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point);
buttonSave.Location = new Point(547, 472);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(103, 40);
buttonSave.TabIndex = 6;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point);
buttonCancel.Location = new Point(665, 472);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(103, 40);
buttonCancel.TabIndex = 7;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormTextile
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 545);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(groupBoxTextileComponents);
Controls.Add(textBoxPrice);
Controls.Add(textBoxName);
Controls.Add(label2);
Controls.Add(label1);
Name = "FormTextile";
Text = "Текстиль";
Load += FormTextile_Load;
groupBoxTextileComponents.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label label1;
private Label label2;
private TextBox textBoxName;
private TextBox textBoxPrice;
private GroupBox groupBoxTextileComponents;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonAdd;
private DataGridView dataGridView;
private Button buttonSave;
private Button buttonCancel;
private DataGridViewTextBoxColumn Column1;
private DataGridViewTextBoxColumn Column2;
private DataGridViewTextBoxColumn Column3;
}
}

View File

@ -0,0 +1,217 @@
using GarmentFactory;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryDataModels.Models;
using Microsoft.Extensions.Logging;
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 GarmentFactoryView
{
public partial class FormTextile : Form
{
private readonly ILogger _logger;
private readonly ITextileLogic _logic;
private int? _id;
private Dictionary<int, (IComponentModel, int)> _textileComponents;
public int Id { set { _id = value; } }
public FormTextile(ILogger<FormTextile> logger, ITextileLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
_textileComponents = new Dictionary<int, (IComponentModel, int)>();
}
//Загрузка данных в таблицу
private void LoadData()
{
_logger.LogInformation("Загрузка компонента текстиля");
try
{
var list = _logic.ReadList(null);
if (_textileComponents != null)
{
dataGridView.Rows.Clear();
foreach (var textileC in _textileComponents)
{
dataGridView.Rows.Add(new object[] { textileC.Key, textileC.Value.Item1.ComponentName, textileC.Value.Item2 });
}
textBoxPrice.Text = CalcPrice().ToString();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки компонента текстиля");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FormTextile_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
_logger.LogInformation("Загрузка текстиля");
try
{
var view = _logic.ReadElement(new TextileSearchModel { Id = _id.Value });
if (view != null)
{
textBoxName.Text = view.TextileName;
textBoxPrice.Text = view.Price.ToString();
_textileComponents = view.TextileComponents ?? new Dictionary<int, (IComponentModel, int)>();
LoadData();
}
}
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(FormTextileComponent));
if (service is FormTextileComponent form)
{
if (form.ShowDialog() == DialogResult.OK)
{
if (form.ComponentModel == null)
{
return;
}
_logger.LogInformation("Добавление нового компонента: {ComponentName} - {Count}", form.ComponentModel.ComponentName, form.Count);
if (_textileComponents.ContainsKey(form.Id))
{
_textileComponents[form.Id] = (form.ComponentModel, form.Count);
}
else
{
_textileComponents.Add(form.Id, (form.ComponentModel, form.Count));
}
LoadData();
}
}
}
private void ButtonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormTextileComponent));
if (service is FormTextileComponent form)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
form.Id = id;
form.Count = _textileComponents[id].Item2;
if (form.ShowDialog() == DialogResult.OK)
{
if (form.ComponentModel == null)
{
return;
}
_logger.LogInformation("Изменение компонента: {ComponentName} - { Count}", form.ComponentModel.ComponentName, form.Count);
_textileComponents[form.Id] = (form.ComponentModel, form.Count);
LoadData();
}
}
}
}
private void ButtonDelete_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);
_textileComponents?.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
}
}
private void ButtonRefresh_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 (_textileComponents == null || _textileComponents.Count == 0)
{
MessageBox.Show("Заполните компоненты", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение текстиля");
try
{
var model = new TextileBindingModel
{
Id = _id ?? 0,
TextileName = textBoxName.Text,
Price = Convert.ToDouble(textBoxPrice.Text),
TextileComponents = _textileComponents
};
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 _textileComponents)
{
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="Column1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column3.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,118 @@
namespace GarmentFactoryView
{
partial class FormTextileComponent
{
/// <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();
labelCount = new Label();
buttonSave = new Button();
buttonCancel = new Button();
textBoxCount = new TextBox();
comboBoxComponent = new ComboBox();
SuspendLayout();
//
// labelComponent
//
labelComponent.AutoSize = true;
labelComponent.Location = new Point(23, 36);
labelComponent.Name = "labelComponent";
labelComponent.Size = new Size(91, 20);
labelComponent.TabIndex = 0;
labelComponent.Text = "Компонент:";
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(23, 85);
labelCount.Name = "labelCount";
labelCount.Size = new Size(93, 20);
labelCount.TabIndex = 1;
labelCount.Text = "Количество:";
//
// buttonSave
//
buttonSave.Location = new Point(222, 124);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(94, 29);
buttonSave.TabIndex = 2;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(322, 124);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(94, 29);
buttonCancel.TabIndex = 3;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// textBoxCount
//
textBoxCount.Location = new Point(122, 82);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(142, 27);
textBoxCount.TabIndex = 4;
//
// comboBoxComponent
//
comboBoxComponent.FormattingEnabled = true;
comboBoxComponent.Location = new Point(122, 36);
comboBoxComponent.Name = "comboBoxComponent";
comboBoxComponent.Size = new Size(285, 28);
comboBoxComponent.TabIndex = 5;
//
// FormTextileComponent
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(428, 166);
Controls.Add(comboBoxComponent);
Controls.Add(textBoxCount);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(labelCount);
Controls.Add(labelComponent);
Name = "FormTextileComponent";
Text = "Компонент текстиля";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelComponent;
private Label labelCount;
private Button buttonSave;
private Button buttonCancel;
private TextBox textBoxCount;
private ComboBox comboBoxComponent;
}
}

View File

@ -0,0 +1,90 @@
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDataModels.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 GarmentFactoryView
{
public partial class FormTextileComponent : 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(textBoxCount.Text); }
set { textBoxCount.Text = value.ToString(); }
}
public FormTextileComponent(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(textBoxCount.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>

118
GarmentFactory/FormTextiles.Designer.cs generated Normal file
View File

@ -0,0 +1,118 @@
namespace GarmentFactoryView
{
partial class FormTextiles
{
/// <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();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonAdd = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(620, 450);
dataGridView.TabIndex = 0;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(654, 254);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(120, 40);
buttonRefresh.TabIndex = 8;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRefresh_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(654, 185);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(120, 40);
buttonDelete.TabIndex = 7;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += ButtonDelete_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(654, 117);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(120, 40);
buttonUpdate.TabIndex = 6;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += ButtonUpdate_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(654, 52);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(120, 40);
buttonAdd.TabIndex = 5;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// FormTextiles
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormTextiles";
Text = "Текстили";
Load += FormTextiles_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonAdd;
}
}

View File

@ -0,0 +1,111 @@
using Microsoft.Extensions.Logging;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.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;
using Microsoft.VisualBasic.Logging;
using GarmentFactory;
namespace GarmentFactoryView
{
public partial class FormTextiles : Form
{
private readonly ILogger _logger;
private readonly ITextileLogic _logic;
public FormTextiles(ILogger<FormTextiles> logger, ITextileLogic 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["TextileName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["TextileComponents"].Visible = false;
}
_logger.LogInformation("Загрузка текстилей");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки текстилей");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FormTextiles_Load(object sender, EventArgs e)
{
LoadData();
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormTextile));
if (service is FormTextile form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void ButtonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormTextile));
if (service is FormTextile form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void ButtonDelete_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 TextileBindingModel { 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>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@ -3,7 +3,27 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34024.191
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GarmentFactory", "GarmentFactory.csproj", "{B47623E0-C32E-437D-869B-71BBC6994D83}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GarmentFactoryView", "GarmentFactoryView.csproj", "{B47623E0-C32E-437D-869B-71BBC6994D83}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GarmentFactoryDataModels", "..\GarmentFactoryDataModels\GarmentFactoryDataModels.csproj", "{1B91BCBE-E608-4D05-A14D-51B1765D5203}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GarmentFactoryContracts", "..\GarmentFactoryContracts\GarmentFactoryContracts.csproj", "{DB84150A-FB0D-4FCB-90DD-2CAC6845E1AF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GarmentFactoryBusinessLogic", "..\GarmentFactoryBusinessLogic\GarmentFactoryBusinessLogic.csproj", "{218ABE4A-FF68-43EF-B257-09FCB727A3B7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GarmentFactoryListImplement", "..\GarmentFactoryListImplement\GarmentFactoryListImplement.csproj", "{DEDDF6CC-7C47-4A10-A011-77395F4B7F30}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GarmentFactoryFileImplement", "..\GarmentFactoryFileImplement\GarmentFactoryFileImplement.csproj", "{93AAEAF2-0725-44DE-9EC9-72701506D1F4}"
ProjectSection(ProjectDependencies) = postProject
{1B91BCBE-E608-4D05-A14D-51B1765D5203} = {1B91BCBE-E608-4D05-A14D-51B1765D5203}
{DB84150A-FB0D-4FCB-90DD-2CAC6845E1AF} = {DB84150A-FB0D-4FCB-90DD-2CAC6845E1AF}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GarmentFactoryDatabaseImplement", "..\GarmentFactoryDatabaseImplement\GarmentFactoryDatabaseImplement.csproj", "{AF7C72AA-02C7-4B8F-9182-D6192E2C3D42}"
ProjectSection(ProjectDependencies) = postProject
{1B91BCBE-E608-4D05-A14D-51B1765D5203} = {1B91BCBE-E608-4D05-A14D-51B1765D5203}
{DB84150A-FB0D-4FCB-90DD-2CAC6845E1AF} = {DB84150A-FB0D-4FCB-90DD-2CAC6845E1AF}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -15,6 +35,30 @@ Global
{B47623E0-C32E-437D-869B-71BBC6994D83}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B47623E0-C32E-437D-869B-71BBC6994D83}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B47623E0-C32E-437D-869B-71BBC6994D83}.Release|Any CPU.Build.0 = Release|Any CPU
{1B91BCBE-E608-4D05-A14D-51B1765D5203}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1B91BCBE-E608-4D05-A14D-51B1765D5203}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B91BCBE-E608-4D05-A14D-51B1765D5203}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B91BCBE-E608-4D05-A14D-51B1765D5203}.Release|Any CPU.Build.0 = Release|Any CPU
{DB84150A-FB0D-4FCB-90DD-2CAC6845E1AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB84150A-FB0D-4FCB-90DD-2CAC6845E1AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB84150A-FB0D-4FCB-90DD-2CAC6845E1AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB84150A-FB0D-4FCB-90DD-2CAC6845E1AF}.Release|Any CPU.Build.0 = Release|Any CPU
{218ABE4A-FF68-43EF-B257-09FCB727A3B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{218ABE4A-FF68-43EF-B257-09FCB727A3B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{218ABE4A-FF68-43EF-B257-09FCB727A3B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{218ABE4A-FF68-43EF-B257-09FCB727A3B7}.Release|Any CPU.Build.0 = Release|Any CPU
{DEDDF6CC-7C47-4A10-A011-77395F4B7F30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DEDDF6CC-7C47-4A10-A011-77395F4B7F30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DEDDF6CC-7C47-4A10-A011-77395F4B7F30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DEDDF6CC-7C47-4A10-A011-77395F4B7F30}.Release|Any CPU.Build.0 = Release|Any CPU
{93AAEAF2-0725-44DE-9EC9-72701506D1F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93AAEAF2-0725-44DE-9EC9-72701506D1F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93AAEAF2-0725-44DE-9EC9-72701506D1F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93AAEAF2-0725-44DE-9EC9-72701506D1F4}.Release|Any CPU.Build.0 = Release|Any CPU
{AF7C72AA-02C7-4B8F-9182-D6192E2C3D42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF7C72AA-02C7-4B8F-9182-D6192E2C3D42}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF7C72AA-02C7-4B8F-9182-D6192E2C3D42}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF7C72AA-02C7-4B8F-9182-D6192E2C3D42}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.17">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GarmentFactoryBusinessLogic\GarmentFactoryBusinessLogic.csproj" />
<ProjectReference Include="..\GarmentFactoryDatabaseImplement\GarmentFactoryDatabaseImplement.csproj" />
<ProjectReference Include="..\GarmentFactoryFileImplement\GarmentFactoryFileImplement.csproj" />
<ProjectReference Include="..\GarmentFactoryListImplement\GarmentFactoryListImplement.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@ -1,7 +1,19 @@
using GarmentFactoryBusinessLogic;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryDatabaseImplement.Implements;
using GarmentFactoryView;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
namespace GarmentFactory
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary>
/// The main entry point for the application.
/// </summary>
@ -11,7 +23,40 @@ namespace GarmentFactory
// 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();
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<ITextileStorage, TextileStorage>();
services.AddTransient<IShopStorage, ShopStorage>();
services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<ITextileLogic, TextileLogic>();
services.AddTransient<IShopLogic, ShopLogic>();
services.AddTransient<FormMain>();
services.AddTransient<FormComponent>();
services.AddTransient<FormComponents>();
services.AddTransient<FormCreateOrder>();
services.AddTransient<FormTextile>();
services.AddTransient<FormTextileComponent>();
services.AddTransient<FormTextiles>();
services.AddTransient<FormShop>();
services.AddTransient<FormShops>();
services.AddTransient<FormAddTextile>();
services.AddTransient<FormSellTextile>();
}
}
}

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace GarmentFactoryView.Properties {
using System;
/// <summary>
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
/// </summary>
// Этот класс создан автоматически классом StronglyTypedResourceBuilder
// с помощью такого средства, как ResGen или Visual Studio.
// Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen
// с параметром /str или перестройте свой проект VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GarmentFactoryView.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,7 @@
{
"profiles": {
"GarmentFactoryView": {
"commandName": "Project"
}
}
}

View File

@ -0,0 +1,117 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace GarmentFactoryBusinessLogic
{
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 ArgumentException("Цена компонента должна быть больше 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,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GarmentFactoryContracts\GarmentFactoryContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,152 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDataModels.Enums;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace GarmentFactoryBusinessLogic
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
//Хранение всех заказов
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IShopStorage shopStorage)
{
_logger = logger;
_orderStorage = orderStorage;
_shopStorage = shopStorage;
}
//Чтение всего списка заказов
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. OrderId:{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;
}
//Проверка данных заказа при добавлении
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.Sum <= 0)
{
throw new ArgumentException("Сумма чека должна быть больше 0", nameof(model.Sum));
}
if (model.Count <= 0)
{
throw new ArgumentException("В чеке должен быть хотя бы 1 товар", nameof(model.Count));
}
if (model.DateComplete.HasValue && model.DateComplete < model.DateCreate)
{
throw new ArgumentException($"Дата выдачи заказа {model.DateComplete} не может быть раньше даты его создания {model.DateCreate}");
}
_logger.LogInformation("Order. Id: {Id}. Sum: {Sum}. TextileId: {TextileId}. TextileCount: {Count}", model.Id, model.Sum, model.TextileId, model.Count);
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Invalid order status");
return false;
}
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
//Общий метод изменения статуса заказа
private bool ChangeStatus(OrderBindingModel model, OrderStatus newStatus)
{
CheckModel(model, false);
var order = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (order == null)
{
throw new ArgumentNullException(nameof(order));
}
model.DateCreate = order.DateCreate;
model.TextileId = order.TextileId;
model.DateComplete = order.DateComplete;
model.Status = order.Status;
model.Count = order.Count;
model.Sum = order.Sum;
if (newStatus - model.Status == 1)
{
model.Status = newStatus;
if (model.Status == OrderStatus.Выдан)
{
model.DateComplete = DateTime.Now;
}
if (_orderStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
if (order.Status + 1 != newStatus)
{
_logger.LogWarning("Change status operation failed. Incorrect new status: {newStatus}. Current status: {currStatus}", newStatus, order.Status);
return false;
}
_logger.LogWarning("Changing status operation faled: current:{Status}: required:{newStatus}.", model.Status, newStatus);
throw new ArgumentException($"Невозможно присвоить статус {newStatus} заказу с текущим статусом {model.Status}");
}
//Перевод заказа в состояние выполнения
public bool TakeOrderInWork(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выполняется);
}
//Перевод заказа в состояние готовности
public bool FinishOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Готов);
}
//Перевод заказа в состояние выдачи (окончательное завершение)
public bool DeliveryOrder(OrderBindingModel model)
{
var order = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (order == null)
{
throw new ArgumentNullException(nameof(order));
}
//Если нельзя пополнить магазины таким кол-вом товаров (не хавтает места), то статус не меняем
if (!_shopStorage.RestockShops(new SupplyBindingModel { TextileId = order.TextileId, Count = order.Count }))
{
throw new ArgumentException("Недостаточно места");
}
return ChangeStatus(model, OrderStatus.Выдан);
}
}
}

View File

@ -0,0 +1,221 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic
{
public class ShopLogic : IShopLogic
{
private readonly ILogger _logger;
// Хранилище всех магазинов
private readonly IShopStorage _shopStorage;
private readonly ITextileStorage _textileStorage;
public ShopLogic(ILogger<ShopLogic> logger, IShopStorage shopStorage, ITextileStorage textileStorage)
{
_logger = logger;
_shopStorage = shopStorage;
_textileStorage = textileStorage;
}
// Чтение конкретного магазина
public ShopViewModel? ReadElement(ShopSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ShopName:{ShopName}. Id:{Id}", model.ShopName, model.Id);
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 List<ShopViewModel>? ReadList(ShopSearchModel? model)
{
_logger.LogInformation("ReadList. ShopName:{ShopName}. Id: {Id}", model?.ShopName, model?.Id);
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 bool Create(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
// Обновление магазина
public bool Update(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
// Удаление магазина
public bool Delete(ShopBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_shopStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
// Пополнение магазина
public bool MakeSupply(SupplyBindingModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Количество добавляемых изделий должно быть больше 0");
}
var textile = _textileStorage.GetElement(new TextileSearchModel { Id = model.TextileId });
if (textile == null)
{
throw new ArgumentException($"При добавлении товара в магазин товар с id={model.TextileId} не найден");
}
var shop = _shopStorage.GetElement(new ShopSearchModel { Id = model.ShopId });
if (shop == null)
{
throw new ArgumentException($"При добавлении товара в магазин магазин c id={model.ShopId} не найден");
}
int countTextilesInShop = shop.ShopTextiles.Select(x => x.Value.Item2).Sum();
//Если в текущий магазин помещается столько товаров
if (countTextilesInShop + model.Count <= shop.TextileMaxCount)
{
// Если такой товар есть, то прибавление переданного кол-ва
if (shop.ShopTextiles.ContainsKey(model.TextileId))
{
var oldValue = shop.ShopTextiles[model.TextileId];
oldValue.Item2 += model.Count;
shop.ShopTextiles[model.TextileId] = oldValue;
}
// Если такого товара нет, то кол-во такого товара равно переданному кол-ву
else
{
shop.ShopTextiles.Add(model.TextileId, (textile, model.Count));
}
_shopStorage.Update(new()
{
Id = shop.Id,
ShopName = shop.ShopName,
Address = shop.Address,
DateOpen = shop.DateOpen,
ShopTextiles = shop.ShopTextiles,
TextileMaxCount = shop.TextileMaxCount,
});
return true;
}
//Если не поместилось столько товара
_logger.LogWarning("Required shop is overflowed");
return false;
}
// Проверка данных магазина при добавлении/удалении/обновлении
private void CheckModel(ShopBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
// При удалении проверка дальше не нужна
if (!withParams)
{
return;
}
// Проверка наличия названия
if (string.IsNullOrEmpty(model.ShopName))
{
throw new ArgumentNullException("Отсутствует название магазина", nameof(model.ShopName));
}
// Проверка наличия адреса
if (string.IsNullOrEmpty(model.Address))
{
throw new ArgumentNullException("Отсутствует адреса магазина", nameof(model.Address));
}
_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)
{
throw new InvalidOperationException("Магазин с таким названием уже есть");
}
}
public bool Sell(SupplySearchModel model)
{
if (!model.TextileId.HasValue || !model.Count.HasValue)
{
return false;
}
if (_shopStorage.Sell(model))
{
_logger.LogInformation("Selling sucsess");
return true;
}
_logger.LogInformation("Selling failed");
return false;
}
}
}

View File

@ -0,0 +1,126 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic
{
public class TextileLogic : ITextileLogic
{
private readonly ILogger _logger;
//Хранение всех изделий
private readonly ITextileStorage _textileStorage;
public TextileLogic(ILogger<TextileLogic> logger, ITextileStorage textileStorage)
{
_logger = logger;
_textileStorage = textileStorage;
}
//Чтение всего списка изделий
public List<TextileViewModel>? ReadList(TextileSearchModel? model)
{
_logger.LogInformation("ReadList.TextileName:{TextileName} .Id:{Id}", model?.TextileName, model?.Id);
var list = model == null ? _textileStorage.GetFullList() : _textileStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList.Count:{Count}", list.Count);
return list;
}
//Чтение одного изделия
public TextileViewModel? ReadElement(TextileSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement.TextileName:{TextileName} .Id:{ Id}", model.TextileName, model.Id);
var element = _textileStorage.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(TextileBindingModel model)
{
CheckModel(model);
if (_textileStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
//Обновление данных изделия
public bool Update(TextileBindingModel model)
{
CheckModel(model);
if (_textileStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
//Удаление изделия
public bool Delete(TextileBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete.Id:{Id}", model.Id);
if (_textileStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
//Проверка данных текстиля при добавлении/удалении/обновлении
private void CheckModel(TextileBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.TextileName))
{
throw new ArgumentNullException("Нет названия текстиля", nameof(model.TextileName));
}
if (model.Price <= 0)
{
throw new ArgumentException("Цена текстиля должна быть больше 0", nameof(model.Price));
}
if (model.TextileComponents == null || model.TextileComponents.Count == 0)
{
throw new ArgumentNullException("Список кмопонентов не может быть пустым", nameof(model.TextileComponents));
}
_logger.LogInformation("Textile. TextileName:{TextileName} .Price:{Price} .Id:{Id}", model.TextileName, model.Price, model.Id);
var element = _textileStorage.GetElement(new TextileSearchModel { TextileName = model.TextileName });
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Текстиль с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,16 @@
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.BindingModels
{
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,21 @@
using GarmentFactoryDataModels.Enums;
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.BindingModels
{
public class OrderBindingModel : IOrderModel
{
public int Id { get; set; }
public int TextileId { 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? DateComplete { get; set; }
}
}

View File

@ -0,0 +1,23 @@
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.BindingModels
{
public class ShopBindingModel : IShopModel
{
public int Id { get; set; }
public string ShopName { get; set; } = string.Empty;
public string Address { get; set; } = string.Empty;
public DateTime DateOpen { get; set; } = DateTime.Now;
public Dictionary<int, (ITextileModel, int)> ShopTextiles { get; set; } = new();
public int TextileMaxCount { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.BindingModels
{
public class SupplyBindingModel : ISupplyModel
{
public int ShopId { get; set; }
public int TextileId { get; set; }
public int Count { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.BindingModels
{
public class TextileBindingModel : ITextileModel
{
public int Id { get; set; }
public string TextileName { get; set; } = string.Empty;
public double Price { get; set; }
public Dictionary<int, (IComponentModel, int)> TextileComponents { get; set; } = new();
}
}

View File

@ -0,0 +1,21 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.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,20 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.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,29 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.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 MakeSupply(SupplyBindingModel model);
bool Sell(SupplySearchModel model);
}
}

View File

@ -0,0 +1,20 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.BusinessLogicsContracts
{
public interface ITextileLogic
{
List<TextileViewModel>? ReadList(TextileSearchModel? model);
TextileViewModel? ReadElement(TextileSearchModel model);
bool Create(TextileBindingModel model);
bool Update(TextileBindingModel model);
bool Delete(TextileBindingModel model);
}
}

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GarmentFactoryDataModels\GarmentFactoryDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.SearchModels
{
public class ComponentSearchModel
{
public int? Id { get; set; }
public string? ComponentName { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.SearchModels
{
public class OrderSearchModel
{
public int? Id { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.SearchModels
{
public class ShopSearchModel
{
public int? Id { get; set; }
public string? ShopName { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.SearchModels
{
public class SupplySearchModel
{
public int? TextileId { get; set; }
public int? Count { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.SearchModels
{
public class TextileSearchModel
{
public int? Id { get; set; }
public string? TextileName { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.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,21 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.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,25 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.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 Sell(SupplySearchModel model);
//Пополнение магаз-ов
bool RestockShops(SupplyBindingModel model);
}
}

View File

@ -0,0 +1,21 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.StoragesContracts
{
public interface ITextileStorage
{
List<TextileViewModel> GetFullList();
List<TextileViewModel> GetFilteredList(TextileSearchModel model);
TextileViewModel? GetElement(TextileSearchModel model);
TextileViewModel? Insert(TextileBindingModel model);
TextileViewModel? Update(TextileBindingModel model);
TextileViewModel? Delete(TextileBindingModel model);
}
}

View File

@ -0,0 +1,21 @@
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.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,37 @@
using GarmentFactoryDataModels.Enums;
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.ViewModels
{
public class OrderViewModel : IOrderModel
{
[DisplayName("Номер")]
public int Id { get; set; }
public int TextileId { get; set; }
[DisplayName("Текстиль")]
public string TextileName { 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? DateComplete { get; set; }
}
}

View File

@ -0,0 +1,29 @@
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.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 DateTime DateOpen { get; set; } = DateTime.Now;
public Dictionary<int, (ITextileModel, int)> ShopTextiles { get; set; } = new();
[DisplayName("Вместимость")]
public int TextileMaxCount { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryContracts.ViewModels
{
public class TextileViewModel : ITextileModel
{
public int Id { get; set; }
[DisplayName("Название текстиля")]
public string TextileName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Price { get; set; }
public Dictionary<int, (IComponentModel, int)> TextileComponents { get; set; } = new();
}
}

View File

@ -0,0 +1,11 @@
namespace GarmentFactoryDataModels.Enums
{
public enum OrderStatus
{
Неизвестен = -1,
Принят = 0,
Выполняется = 1,
Готов = 2,
Выдан = 3
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDataModels
{
public interface IId
{
int Id { get; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDataModels.Models
{
public interface IComponentModel : IId
{
string ComponentName { get; }
double Cost { get; }
}
}

View File

@ -0,0 +1,19 @@
using GarmentFactoryDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDataModels.Models
{
public interface IOrderModel : IId
{
int TextileId { get; }
int Count { get; }
double Sum { get; }
OrderStatus Status { get; }
DateTime DateCreate { get; }
DateTime? DateComplete { get; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDataModels.Models
{
public interface IShopModel : IId
{
string ShopName { get; }
string Address { get; }
DateTime DateOpen { get; }
//Изделия в магазине
Dictionary<int, (ITextileModel, int)> ShopTextiles { get; }
//макс. кол-во изделий
int TextileMaxCount { get; }
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDataModels.Models
{
//Сущность для связи многие-ко-многим между товарами и магазинами
public class ISupplyModel
{
int ShopId { get; }
int TextileId { get; }
int Count { get; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDataModels.Models
{
public interface ITextileModel : IId
{
string TextileName { get; }
double Price { get; }
Dictionary<int, (IComponentModel, int)> TextileComponents { get; }
}
}

View File

@ -0,0 +1,35 @@
using GarmentFactoryDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDatabaseImplement
{
public class GarmentFactoryDatabase : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-1I7RVNF\SQLEXPRESS;Initial Catalog=GarmentFactoryDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
}
base.OnConfiguring(optionsBuilder);
}
public virtual DbSet<Component> Components { set; get; }
public virtual DbSet<Textile> Textiles { set; get; }
public virtual DbSet<TextileComponent> TextileComponents { set; get; }
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Shop> Shops { get; set; }
public virtual DbSet<ShopTextile> ShopTextiles { get; set; }
}
}

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.17" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.17" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.17">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GarmentFactoryContracts\GarmentFactoryContracts.csproj" />
<ProjectReference Include="..\GarmentFactoryDataModels\GarmentFactoryDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,85 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDatabaseImplement.Implements
{
public class ComponentStorage : IComponentStorage
{
public List<ComponentViewModel> GetFullList()
{
using var context = new GarmentFactoryDatabase();
return context.Components.Select(x => x.GetViewModel).ToList();
}
public List<ComponentViewModel> GetFilteredList(ComponentSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName))
{
return new();
}
using var context = new GarmentFactoryDatabase();
return context.Components
.Where(x => x.ComponentName.Contains(model.ComponentName))
.Select(x => x.GetViewModel).ToList();
}
public ComponentViewModel? GetElement(ComponentSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName) && !model.Id.HasValue)
{
return null;
}
using var context = new GarmentFactoryDatabase();
return context.Components
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ComponentName) && x.ComponentName == model.ComponentName)
|| (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public ComponentViewModel? Insert(ComponentBindingModel model)
{
var newComponent = Component.Create(model);
if (newComponent == null)
{
return null;
}
using var context = new GarmentFactoryDatabase();
context.Components.Add(newComponent);
context.SaveChanges();
return newComponent.GetViewModel;
}
public ComponentViewModel? Update(ComponentBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var component = context.Components.FirstOrDefault(x => x.Id == model.Id);
if (component == null)
{
return null;
}
component.Update(model);
context.SaveChanges();
return component.GetViewModel;
}
public ComponentViewModel? Delete(ComponentBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var element = context.Components.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Components.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,97 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDatabaseImplement.Implements
{
public class OrderStorage : IOrderStorage
{
public List<OrderViewModel> GetFullList()
{
using var context = new GarmentFactoryDatabase();
return context.Orders.Include(x => x.Textile).Select(x => x.GetViewModel).ToList();
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return new();
}
using var context = new GarmentFactoryDatabase();
return context.Orders
.Include(x => x.Textile)
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel).ToList();
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
using var context = new GarmentFactoryDatabase();
return context.Orders.Include(x => x.Textile).FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel;
}
public OrderViewModel? Insert(OrderBindingModel model)
{
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
using var context = new GarmentFactoryDatabase();
context.Orders.Add(newOrder);
context.SaveChanges();
return context.Orders.Include(x => x.Textile).FirstOrDefault(x => x.Id == newOrder.Id)?.GetViewModel;
}
public OrderViewModel? Update(OrderBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var order = context.Orders.FirstOrDefault(x => x.Id == model.Id);
if (order == null)
{
return null;
}
order.Update(model);
context.SaveChanges();
return context.Orders.Include(x => x.Textile).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
}
public OrderViewModel? Delete(OrderBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var element = context.Orders.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Orders.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,243 @@
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryDatabaseImplement.Models;
namespace GarmentFactoryDatabaseImplement.Implements
{
public class ShopStorage : IShopStorage
{
public List<ShopViewModel> GetFullList()
{
using var context = new GarmentFactoryDatabase();
return context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName))
{
return new();
}
using var context = new GarmentFactoryDatabase();
return context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.Where(x => x.ShopName.Contains(model.ShopName))
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue)
{
return new();
}
using var context = new GarmentFactoryDatabase();
return context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) && x.ShopName == model.ShopName)
|| (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public ShopViewModel? Insert(ShopBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var newShop = Shop.Create(context, model);
if (newShop == null)
{
return null;
}
context.Shops.Add(newShop);
context.SaveChanges();
return newShop.GetViewModel;
}
public ShopViewModel? Update(ShopBindingModel model)
{
using var context = new GarmentFactoryDatabase();
using var transaction = context.Database.BeginTransaction();
try
{
var shop = context.Shops.FirstOrDefault(x => x.Id == model.Id);
if (shop == null)
return null;
shop.Update(model);
context.SaveChanges();
shop.UpdateTextiles(context, model);
transaction.Commit();
return shop.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
public ShopViewModel? Delete(ShopBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var element = context.Shops
.Include(x => x.Textiles)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Shops.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
//продажа текстиля из магазинов
public bool Sell(SupplySearchModel model)
{
using var context = new GarmentFactoryDatabase();
using var transaction = context.Database.BeginTransaction();
try
{
//поиск всех магаз-ов, в кот. есть нужный текстиль (сортировка: сначала те, где его больше)
var shopsWithThisTextile = context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.ToList()
.Where(x => x.ShopTextiles.ContainsKey(model.TextileId.Value))
.OrderByDescending(x => x.ShopTextiles[model.TextileId.Value].Item2)
.ToList();
foreach (var shop in shopsWithThisTextile)
{
//сколько надо будет этого текстиля, если продать все из текущего магазина
int thisTextileNeeded = model.Count.Value - shop.ShopTextiles[model.TextileId.Value].Item2;
//если ещё надо будет
if (thisTextileNeeded > 0)
{
//полное удаление этого текстиля из этого магазина
shop.ShopTextiles.Remove(model.TextileId.Value);
shop.DictionaryTextilesUpdate(context);
context.SaveChanges();
model.Count = thisTextileNeeded;
}
else
{
//если в этом магазине ровно столько, сколько надо
if (thisTextileNeeded == 0)
{
shop.ShopTextiles.Remove(model.TextileId.Value);
}
//если в этом магазине больше, чем надо
else
{
//уменьшение в этом магазине этого текстиля на нужное кол-во
var textileAndCount = shop.ShopTextiles[model.TextileId.Value];
textileAndCount.Item2 = -thisTextileNeeded;
shop.ShopTextiles[model.TextileId.Value] = textileAndCount;
}
shop.DictionaryTextilesUpdate(context);
transaction.Commit();
return true;
}
}
transaction.Rollback();
return false;
}
catch
{
transaction.Rollback();
throw;
}
}
//пополнение магазинов текстилем
public bool RestockShops(SupplyBindingModel model)
{
using var context = new GarmentFactoryDatabase();
using var transaction = context.Database.BeginTransaction();
//все магазины, где ещё есть свободное место (занятое кол-во < максимально допустимого)
var shops = context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.ToList()
.Where(x => x.ShopTextiles.Select(x => x.Value.Item2).Sum() < x.TextileMaxCount)
.ToList();
try
{
foreach (Shop shop in shops)
{
//свободное место в этом магазине
int freeSpace = shop.TextileMaxCount - shop.ShopTextiles.Select(x => x.Value.Item2).Sum();
//кол-во кот. надо для этого магазина (либо до макс. кол-ва, либо кол-во, кот. осталось в "поставке" (что меньше))
int restock = Math.Min(freeSpace, model.Count);
model.Count -= restock;
//если в этом магазине есть этот текстиль, то изменение его кол-ва
if (shop.ShopTextiles.ContainsKey(model.TextileId))
{
var textileAndCount = shop.ShopTextiles[model.TextileId];
textileAndCount.Item2 += restock;
shop.ShopTextiles[model.TextileId] = textileAndCount;
}
//если нет, то добавление в этом кол-ве
else
{
var textile = context.Textiles.First(x => x.Id == model.TextileId);
shop.ShopTextiles.Add(model.TextileId, (textile, restock));
}
shop.DictionaryTextilesUpdate(context);
//если в "поставке" закончились товары, то всё ок
if (model.Count == 0)
{
transaction.Commit();
return true;
}
}
transaction.Rollback();
return false;
}
catch
{
transaction.Rollback();
throw;
}
}
}
}

View File

@ -0,0 +1,109 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDatabaseImplement.Implements
{
public class TextileStorage : ITextileStorage
{
public List<TextileViewModel> GetFullList()
{
using var context = new GarmentFactoryDatabase();
return context.Textiles
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<TextileViewModel> GetFilteredList(TextileSearchModel model)
{
if (string.IsNullOrEmpty(model.TextileName))
{
return new();
}
using var context = new GarmentFactoryDatabase();
return context.Textiles
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.Where(x => x.TextileName.Contains(model.TextileName))
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public TextileViewModel? GetElement(TextileSearchModel model)
{
if (string.IsNullOrEmpty(model.TextileName) && !model.Id.HasValue)
{
return null;
}
using var context = new GarmentFactoryDatabase();
return context.Textiles
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.TextileName) && x.TextileName == model.TextileName) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public TextileViewModel? Insert(TextileBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var newTextile = Textile.Create(context, model);
if (newTextile == null)
{
return null;
}
context.Textiles.Add(newTextile);
context.SaveChanges();
return newTextile.GetViewModel;
}
public TextileViewModel? Update(TextileBindingModel model)
{
using var context = new GarmentFactoryDatabase();
using var transaction = context.Database.BeginTransaction();
try
{
var textile = context.Textiles.FirstOrDefault(rec => rec.Id == model.Id);
if (textile == null)
{
return null;
}
textile.Update(model);
context.SaveChanges();
textile.UpdateComponents(context, model);
transaction.Commit();
return textile.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
public TextileViewModel? Delete(TextileBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var element = context.Textiles
.Include(x => x.Components)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Textiles.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,171 @@
// <auto-generated />
using System;
using GarmentFactoryDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace GarmentFactoryDatabaseImplement.Migrations
{
[DbContext(typeof(GarmentFactoryDatabase))]
[Migration("20240316194255_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.17")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime?>("DateComplete")
.HasColumnType("datetime2");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TextileId");
b.ToTable("Orders");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("TextileName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Textiles");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ComponentId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("TextileId");
b.ToTable("TextileComponents");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany("Orders")
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Component", "Component")
.WithMany("ProductComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany("Components")
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b =>
{
b.Navigation("ProductComponents");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,125 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace GarmentFactoryDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Components",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ComponentName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Cost = table.Column<double>(type: "float", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Components", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Textiles",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
TextileName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Price = table.Column<double>(type: "float", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Textiles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
TextileId = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false),
Sum = table.Column<double>(type: "float", nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false),
DateComplete = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Textiles_TextileId",
column: x => x.TextileId,
principalTable: "Textiles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "TextileComponents",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
TextileId = table.Column<int>(type: "int", nullable: false),
ComponentId = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TextileComponents", x => x.Id);
table.ForeignKey(
name: "FK_TextileComponents_Components_ComponentId",
column: x => x.ComponentId,
principalTable: "Components",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_TextileComponents_Textiles_TextileId",
column: x => x.TextileId,
principalTable: "Textiles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Orders_TextileId",
table: "Orders",
column: "TextileId");
migrationBuilder.CreateIndex(
name: "IX_TextileComponents_ComponentId",
table: "TextileComponents",
column: "ComponentId");
migrationBuilder.CreateIndex(
name: "IX_TextileComponents_TextileId",
table: "TextileComponents",
column: "TextileId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "TextileComponents");
migrationBuilder.DropTable(
name: "Components");
migrationBuilder.DropTable(
name: "Textiles");
}
}
}

View File

@ -0,0 +1,171 @@
// <auto-generated />
using System;
using GarmentFactoryDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace GarmentFactoryDatabaseImplement.Migrations
{
[DbContext(typeof(GarmentFactoryDatabase))]
[Migration("20240320054624_Changed")]
partial class Changed
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.17")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime?>("DateComplete")
.HasColumnType("datetime2");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TextileId");
b.ToTable("Orders");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("TextileName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Textiles");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ComponentId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("TextileId");
b.ToTable("TextileComponents");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany("Orders")
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Component", "Component")
.WithMany("TextileComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany("Components")
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b =>
{
b.Navigation("TextileComponents");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

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

View File

@ -0,0 +1,248 @@
// <auto-generated />
using System;
using GarmentFactoryDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace GarmentFactoryDatabaseImplement.Migrations
{
[DbContext(typeof(GarmentFactoryDatabase))]
[Migration("20240515060701_Lab3_Hard_AddedShops")]
partial class Lab3_Hard_AddedShops
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.17")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime?>("DateComplete")
.HasColumnType("datetime2");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TextileId");
b.ToTable("Orders");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Shop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DateOpen")
.HasColumnType("datetime2");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("TextileMaxCount")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.ShopTextile", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ShopId");
b.HasIndex("TextileId");
b.ToTable("ShopTextiles");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("TextileName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Textiles");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ComponentId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("TextileId");
b.ToTable("TextileComponents");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany("Orders")
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.ShopTextile", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Shop", "Shop")
.WithMany("Textiles")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany()
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Shop");
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Component", "Component")
.WithMany("TextileComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany("Components")
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b =>
{
b.Navigation("TextileComponents");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Textiles");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,78 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace GarmentFactoryDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class Lab3_Hard_AddedShops : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Shops",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ShopName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Address = table.Column<string>(type: "nvarchar(max)", nullable: false),
DateOpen = table.Column<DateTime>(type: "datetime2", nullable: false),
TextileMaxCount = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Shops", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ShopTextiles",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
TextileId = table.Column<int>(type: "int", nullable: false),
ShopId = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ShopTextiles", x => x.Id);
table.ForeignKey(
name: "FK_ShopTextiles_Shops_ShopId",
column: x => x.ShopId,
principalTable: "Shops",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ShopTextiles_Textiles_TextileId",
column: x => x.TextileId,
principalTable: "Textiles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ShopTextiles_ShopId",
table: "ShopTextiles",
column: "ShopId");
migrationBuilder.CreateIndex(
name: "IX_ShopTextiles_TextileId",
table: "ShopTextiles",
column: "TextileId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ShopTextiles");
migrationBuilder.DropTable(
name: "Shops");
}
}
}

View File

@ -0,0 +1,245 @@
// <auto-generated />
using System;
using GarmentFactoryDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace GarmentFactoryDatabaseImplement.Migrations
{
[DbContext(typeof(GarmentFactoryDatabase))]
partial class GarmentFactoryDatabaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.17")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime?>("DateComplete")
.HasColumnType("datetime2");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TextileId");
b.ToTable("Orders");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Shop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DateOpen")
.HasColumnType("datetime2");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("TextileMaxCount")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.ShopTextile", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ShopId");
b.HasIndex("TextileId");
b.ToTable("ShopTextiles");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("TextileName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Textiles");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ComponentId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("TextileId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("TextileId");
b.ToTable("TextileComponents");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Order", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany("Orders")
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.ShopTextile", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Shop", "Shop")
.WithMany("Textiles")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany()
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Shop");
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.TextileComponent", b =>
{
b.HasOne("GarmentFactoryDatabaseImplement.Models.Component", "Component")
.WithMany("TextileComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GarmentFactoryDatabaseImplement.Models.Textile", "Textile")
.WithMany("Components")
.HasForeignKey("TextileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Textile");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Component", b =>
{
b.Navigation("TextileComponents");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Textiles");
});
modelBuilder.Entity("GarmentFactoryDatabaseImplement.Models.Textile", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.ViewModels;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using GarmentFactoryDataModels.Models;
namespace GarmentFactoryDatabaseImplement.Models
{
public class Component : IComponentModel
{
public int Id { get; private set; }
[Required]
public string ComponentName { get; private set; } = string.Empty;
[Required]
public double Cost { get; set; }
[ForeignKey("ComponentId")]
public virtual List<TextileComponent> TextileComponents { get; set; } = new();
public static Component? Create(ComponentBindingModel model)
{
if (model == null)
{
return null;
}
return new Component()
{
Id = model.Id,
ComponentName = model.ComponentName,
Cost = model.Cost
};
}
public static Component Create(ComponentViewModel model)
{
return new Component
{
Id = model.Id,
ComponentName = model.ComponentName,
Cost = model.Cost
};
}
public void Update(ComponentBindingModel model)
{
if (model == null)
{
return;
}
ComponentName = model.ComponentName;
Cost = model.Cost;
}
public ComponentViewModel GetViewModel => new()
{
Id = Id,
ComponentName = ComponentName,
Cost = Cost
};
}
}

View File

@ -0,0 +1,80 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDataModels.Enums;
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDatabaseImplement.Models
{
public class Order : IOrderModel
{
public int Id { get; set; }
[Required]
public int TextileId { get; private set; }
[Required]
public int Count { get; set; }
[Required]
public double Sum { get; private set; }
[Required]
public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен;
[Required]
public DateTime DateCreate { get; private set; } = DateTime.Now;
public DateTime? DateComplete { get; private set; }
// Для передачи названия изделия
public virtual Textile Textile { get; set; }
public static Order? Create(OrderBindingModel model)
{
if (model == null)
{
return null;
}
return new Order()
{
Id = model.Id,
TextileId = model.TextileId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateComplete = model.DateComplete,
};
}
public void Update(OrderBindingModel model)
{
if (model == null)
{
return;
}
Status = model.Status;
DateComplete = model.DateComplete;
}
public OrderViewModel GetViewModel => new()
{
Id = Id,
TextileId = TextileId,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateComplete = DateComplete,
TextileName = Textile.TextileName
};
}
}

View File

@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using GarmentFactoryDataModels.Models;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.ViewModels;
namespace GarmentFactoryDatabaseImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; set; }
[Required]
public string ShopName { get; set; } = string.Empty;
[Required]
public string Address { get; set; } = string.Empty;
[Required]
public DateTime DateOpen { get; set; }
[Required]
public int TextileMaxCount { get; set; }
[ForeignKey("ShopId")]
public List<ShopTextile> Textiles { get; set; } = new();
private Dictionary<int, (ITextileModel, int)>? _shopTextiles = null;
[NotMapped]
public Dictionary<int, (ITextileModel, int)> ShopTextiles
{
get
{
if (_shopTextiles == null)
{
if (_shopTextiles == null)
{
_shopTextiles = Textiles.ToDictionary(x => x.TextileId, y => (y.Textile as ITextileModel, y.Count));
}
return _shopTextiles;
}
return _shopTextiles;
}
}
public static Shop Create(GarmentFactoryDatabase context, ShopBindingModel model)
{
return new Shop()
{
Id = model.Id,
ShopName = model.ShopName,
Address = model.Address,
DateOpen = model.DateOpen,
TextileMaxCount = model.TextileMaxCount,
Textiles = model.ShopTextiles.Select(x => new ShopTextile
{
Textile = context.Textiles.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList(),
};
}
public void Update(ShopBindingModel model)
{
ShopName = model.ShopName;
Address = model.Address;
DateOpen = model.DateOpen;
TextileMaxCount = model.TextileMaxCount;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
DateOpen = DateOpen,
ShopTextiles = ShopTextiles,
TextileMaxCount = TextileMaxCount
};
public void UpdateTextiles(GarmentFactoryDatabase context, ShopBindingModel model)
{
var ShopTextiles = context.ShopTextiles
.Where(rec => rec.ShopId == model.Id)
.ToList();
if (ShopTextiles != null && ShopTextiles.Count > 0)
{
context.ShopTextiles.RemoveRange(ShopTextiles.Where(rec => !model.ShopTextiles.ContainsKey(rec.TextileId)));
context.SaveChanges();
ShopTextiles = context.ShopTextiles.Where(rec => rec.ShopId == model.Id).ToList();
foreach (var textileToUpdate in ShopTextiles)
{
textileToUpdate.Count = model.ShopTextiles[textileToUpdate.TextileId].Item2;
model.ShopTextiles.Remove(textileToUpdate.TextileId);
}
context.SaveChanges();
}
var Shop = context.Shops.First(x => x.Id == Id);
foreach (var ShopTextile in model.ShopTextiles)
{
context.ShopTextiles.Add(new ShopTextile
{
Shop = Shop,
Textile = context.Textiles.First(x => x.Id == ShopTextile.Key),
Count = ShopTextile.Value.Item2
});
context.SaveChanges();
}
_shopTextiles = null;
}
public void DictionaryTextilesUpdate(GarmentFactoryDatabase context)
{
UpdateTextiles(context, new ShopBindingModel
{
Id = Id,
ShopTextiles = ShopTextiles
});
}
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDatabaseImplement.Models
{
public class ShopTextile
{
public int Id { get; set; }
[Required]
public int TextileId { get; set; }
[Required]
public int ShopId { get; set; }
[Required]
public int Count { get; set; }
public virtual Shop Shop { get; set; } = new();
public virtual Textile Textile { get; set; } = new();
}
}

View File

@ -0,0 +1,108 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDatabaseImplement.Models
{
public class Textile : ITextileModel
{
public int Id { get; set; }
[Required]
public string TextileName { get; set; } = string.Empty;
[Required]
public double Price { get; set; }
private Dictionary<int, (IComponentModel, int)>? _textileComponents = null;
[NotMapped]
public Dictionary<int, (IComponentModel, int)> TextileComponents
{
get
{
if (_textileComponents == null)
{
_textileComponents = Components
.ToDictionary(recPC => recPC.ComponentId, recPC =>
(recPC.Component as IComponentModel, recPC.Count));
}
return _textileComponents;
}
}
[ForeignKey("TextileId")]
public virtual List<TextileComponent> Components { get; set; } = new();
[ForeignKey("TextileId")]
public virtual List<Order> Orders { get; set; } = new();
public static Textile Create(GarmentFactoryDatabase context, TextileBindingModel model)
{
return new Textile()
{
Id = model.Id,
TextileName = model.TextileName,
Price = model.Price,
Components = model.TextileComponents.Select(x => new TextileComponent
{
Component = context.Components.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList()
};
}
public void Update(TextileBindingModel model)
{
TextileName = model.TextileName;
Price = model.Price;
}
public TextileViewModel GetViewModel => new()
{
Id = Id,
TextileName = TextileName,
Price = Price,
TextileComponents = TextileComponents
};
public void UpdateComponents(GarmentFactoryDatabase context, TextileBindingModel model)
{
var textileComponents = context.TextileComponents.Where(rec =>rec.TextileId == model.Id).ToList();
if (textileComponents != null && textileComponents.Count > 0)
{
// удалили те, которых нет в модели
context.TextileComponents.RemoveRange(textileComponents.Where(rec => !model.TextileComponents.ContainsKey(rec.ComponentId)));
context.SaveChanges();
// обновили количество у существующих записей
foreach (var updateComponent in textileComponents)
{
updateComponent.Count =
model.TextileComponents[updateComponent.ComponentId].Item2;
model.TextileComponents.Remove(updateComponent.ComponentId);
}
context.SaveChanges();
}
var textile = context.Textiles.First(x => x.Id == Id);
foreach (var pc in model.TextileComponents)
{
context.TextileComponents.Add(new TextileComponent
{
Textile = textile,
Component = context.Components.First(x => x.Id == pc.Key),
Count = pc.Value.Item2
});
context.SaveChanges();
}
_textileComponents = null;
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace GarmentFactoryDatabaseImplement.Models
{
public class TextileComponent
{
public int Id { get; set; }
[Required]
public int TextileId { get; set; }
[Required]
public int ComponentId { get; set; }
[Required]
public int Count { get; set; }
public virtual Component Component { get; set; } = new();
public virtual Textile Textile { get; set; } = new();
}
}

View File

@ -0,0 +1,59 @@
using GarmentFactoryFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace GarmentFactoryFileImplement
{
internal class DataFileSingleton
{
private static DataFileSingleton? instance;
private readonly string ComponentFileName = "Component.xml";
private readonly string OrderFileName = "Order.xml";
private readonly string TextileFileName = "Textile.xml";
private readonly string ShopFileName = "Shop.xml";
public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; }
public List<Textile> Textiles { get; private set; }
public List<Shop> Shops { get; private set; }
public static DataFileSingleton GetInstance()
{
if (instance == null)
{
instance = new DataFileSingleton();
}
return instance;
}
public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement);
public void SaveTextiles() => SaveData(Textiles, TextileFileName, "Textiles", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", x => x.GetXElement);
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
Textiles = LoadData(TextileFileName, "Textile", x => Textile.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Shops = LoadData(ShopFileName, "Shop", x => Shop.Create(x)!)!;
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction)
{
if (File.Exists(filename))
{
return XDocument.Load(filename)?.Root?.Elements(xmlNodeName)?.Select(selectFunction)?.ToList();
}
return new List<T>();
}
private static void SaveData<T>(List<T> data, string filename, string xmlNodeName, Func<T, XElement> selectFunction)
{
if (data != null)
{
new XDocument(new XElement(xmlNodeName, data.Select(selectFunction).ToArray())).Save(filename);
}
}
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\GarmentFactoryContracts\GarmentFactoryContracts.csproj" />
<ProjectReference Include="..\GarmentFactoryDataModels\GarmentFactoryDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,82 @@
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryFileImplement.Implements
{
public class ComponentStorage : IComponentStorage
{
private readonly DataFileSingleton source;
public ComponentStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<ComponentViewModel> GetFullList()
{
return source.Components.Select(x => x.GetViewModel).ToList();
}
public List<ComponentViewModel> GetFilteredList(ComponentSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName))
{
return new();
}
return source.Components.Where(x => x.ComponentName.Contains(model.ComponentName)).Select(x => x.GetViewModel).ToList();
}
public ComponentViewModel? GetElement(ComponentSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName) && !model.Id.HasValue)
{
return null;
}
return source.Components.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.ComponentName) && x.ComponentName == model.ComponentName) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
}
public ComponentViewModel? Insert(ComponentBindingModel model)
{
model.Id = source.Components.Count > 0 ? source.Components.Max(x => x.Id) + 1 : 1;
var newComponent = Component.Create(model);
if (newComponent == null)
{
return null;
}
source.Components.Add(newComponent);
source.SaveComponents();
return newComponent.GetViewModel;
}
public ComponentViewModel? Update(ComponentBindingModel model)
{
var component = source.Components.FirstOrDefault(x => x.Id == model.Id);
if (component == null)
{
return null;
}
component.Update(model);
source.SaveComponents();
return component.GetViewModel;
}
public ComponentViewModel? Delete(ComponentBindingModel model)
{
var element = source.Components.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
source.Components.Remove(element);
source.SaveComponents();
return element.GetViewModel;
}
return null;
}
}
}

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