Словил баг при поставке продуктов в магазины: у магазинов происходит коллизия записей с количество продуктов

This commit is contained in:
Никита Потапов 2024-05-20 03:54:09 +04:00
parent 5902068043
commit 131a107746
18 changed files with 832 additions and 46 deletions

View File

@ -58,6 +58,9 @@ namespace SecuritySystemBusinessLogic.BusinessLogics
_logger.LogWarning("Read operation failed");
return false;
}
model.SecureId = element.SecureId;
model.Count = element.Count;
model.Sum = element.Sum;
if (element.Status != targetStatus - 1)
{
_logger.LogWarning("Status change operation failed");

View File

@ -153,6 +153,11 @@ namespace SecuritySystemBusinessLogic.BusinessLogics
_logger.LogInformation("Shop element found. ID: {0}, Name: {1}", shopElement.Id, shopElement.Name);
if (GetFreeSpace(shopElement.Id) < count)
{
throw new InvalidOperationException("В магазине не хватает места");
}
if (shopElement.ShopSecures.TryGetValue(secure.Id, out var sameSecure))
{
shopElement.ShopSecures[secure.Id] = (secure, sameSecure.Item2 + count);
@ -187,7 +192,7 @@ namespace SecuritySystemBusinessLogic.BusinessLogics
foreach (var shop in shops)
{
int shopFreeSpace = GetFreeSpace(shop.Id);
if (shopFreeSpace >= 0)
if (shopFreeSpace > 0)
{
int min = Math.Min(count, shopFreeSpace);
count -= min;

View File

@ -10,7 +10,7 @@ namespace SecuritySystemContracts.ViewModels
public string Name { get; set; } = string.Empty;
[DisplayName("Адрес")]
public string Address { get; set; } = string.Empty;
[DisplayName("Макс. кол-во товара")]
[DisplayName("Вместимость")]
public int MaxSecuresCount { get; set; }
[DisplayName("Дата открытия")]
public DateTime OpeningDate { get; set; }

View File

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
@ -15,41 +16,25 @@ namespace SecuritySystemDatabaseImplement.Implements
return context.Secures
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<SecureViewModel> GetFilteredList(SecureSearchModel model)
{
if (string.IsNullOrEmpty(model.SecureName))
var secures = GetFullList();
if (model.Id != null)
{
return new();
secures = secures.Where(x => x.Id == model.Id).ToList();
}
using var context = new SecuritySystemDatabase();
return context.Secures
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.Where(x => x.SecureName.Contains(model.SecureName))
.ToList()
.Select(x => x.GetViewModel)
.ToList();
if (!model.SecureName.IsNullOrEmpty())
{
secures = secures.Where(x => x.SecureName == model.SecureName).ToList();
}
return secures;
}
public SecureViewModel? GetElement(SecureSearchModel model)
{
if (string.IsNullOrEmpty(model.SecureName) &&
!model.Id.HasValue)
{
return null;
}
using var context = new SecuritySystemDatabase();
return context.Secures
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.SecureName) &&
x.SecureName == model.SecureName) ||
(model.Id.HasValue && x.Id ==
model.Id))
?.GetViewModel;
return GetFilteredList(model).FirstOrDefault();
}
public SecureViewModel? Insert(SecureBindingModel model)
{

View File

@ -49,7 +49,6 @@ namespace SecuritySystemDatabaseImplement.Implements
return context.Shops
.Include(x => x.Secures)
.ThenInclude(x => x.Secure)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
@ -114,7 +113,10 @@ namespace SecuritySystemDatabaseImplement.Implements
}
shop.Update(model);
context.SaveChanges();
shop.UpdateSecures(context, model);
if (model.ShopSecures.Count > 0)
{
shop.UpdateSecures(context, model);
}
transaction.Commit();
return shop.GetViewModel;
}

View File

@ -0,0 +1,248 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SecuritySystemDatabaseImplement;
#nullable disable
namespace SecuritySystemDatabaseImplement.Migrations
{
[DbContext(typeof(SecuritySystemDatabase))]
[Migration("20240519222424_AddShops")]
partial class AddShops
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.16")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SecuritySystemDatabaseImplement.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("SecuritySystemDatabaseImplement.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>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("SecureId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("SecureId");
b.ToTable("Orders");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.Secure", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("SecureName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Secures");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.SecureComponent", 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>("SecureId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("SecureId");
b.ToTable("SecureComponents");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.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<int>("MaxSecuresCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("OpeningDate")
.HasColumnType("datetime2");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.ShopSecure", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("SecureId")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SecureId");
b.HasIndex("ShopId");
b.ToTable("ShopSecures");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.Order", b =>
{
b.HasOne("SecuritySystemDatabaseImplement.Models.Secure", "Secure")
.WithMany("Orders")
.HasForeignKey("SecureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Secure");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.SecureComponent", b =>
{
b.HasOne("SecuritySystemDatabaseImplement.Models.Component", "Component")
.WithMany("SecureComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SecuritySystemDatabaseImplement.Models.Secure", "Secure")
.WithMany("Components")
.HasForeignKey("SecureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Secure");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.ShopSecure", b =>
{
b.HasOne("SecuritySystemDatabaseImplement.Models.Secure", "Secure")
.WithMany()
.HasForeignKey("SecureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SecuritySystemDatabaseImplement.Models.Shop", "Shop")
.WithMany("Secures")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Secure");
b.Navigation("Shop");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.Component", b =>
{
b.Navigation("SecureComponents");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.Secure", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Secures");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,78 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SecuritySystemDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class AddShops : 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"),
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
Address = table.Column<string>(type: "nvarchar(max)", nullable: false),
OpeningDate = table.Column<DateTime>(type: "datetime2", nullable: false),
MaxSecuresCount = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Shops", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ShopSecures",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
SecureId = 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_ShopSecures", x => x.Id);
table.ForeignKey(
name: "FK_ShopSecures_Secures_SecureId",
column: x => x.SecureId,
principalTable: "Secures",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ShopSecures_Shops_ShopId",
column: x => x.ShopId,
principalTable: "Shops",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ShopSecures_SecureId",
table: "ShopSecures",
column: "SecureId");
migrationBuilder.CreateIndex(
name: "IX_ShopSecures_ShopId",
table: "ShopSecures",
column: "ShopId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ShopSecures");
migrationBuilder.DropTable(
name: "Shops");
}
}
}

View File

@ -121,6 +121,59 @@ namespace SecuritySystemDatabaseImplement.Migrations
b.ToTable("SecureComponents");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.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<int>("MaxSecuresCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("OpeningDate")
.HasColumnType("datetime2");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.ShopSecure", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("SecureId")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SecureId");
b.HasIndex("ShopId");
b.ToTable("ShopSecures");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.Order", b =>
{
b.HasOne("SecuritySystemDatabaseImplement.Models.Secure", "Secure")
@ -151,6 +204,25 @@ namespace SecuritySystemDatabaseImplement.Migrations
b.Navigation("Secure");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.ShopSecure", b =>
{
b.HasOne("SecuritySystemDatabaseImplement.Models.Secure", "Secure")
.WithMany()
.HasForeignKey("SecureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SecuritySystemDatabaseImplement.Models.Shop", "Shop")
.WithMany("Secures")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Secure");
b.Navigation("Shop");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.Component", b =>
{
b.Navigation("SecureComponents");
@ -162,6 +234,11 @@ namespace SecuritySystemDatabaseImplement.Migrations
b.Navigation("Orders");
});
modelBuilder.Entity("SecuritySystemDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Secures");
});
#pragma warning restore 612, 618
}
}

View File

@ -33,13 +33,14 @@
ComponentsToolStripMenuItem = new ToolStripMenuItem();
SecuresToolStripMenuItem = new ToolStripMenuItem();
магазиныToolStripMenuItem = new ToolStripMenuItem();
пополнениеМагазинаToolStripMenuItem = new ToolStripMenuItem();
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonTakeOrderInWork = new Button();
buttonOrderReady = new Button();
button4 = new Button();
buttonRefresh = new Button();
пополнениеМагазинаToolStripMenuItem = new ToolStripMenuItem();
продатьПродукциюToolStripMenuItem = new ToolStripMenuItem();
menuStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
@ -47,7 +48,7 @@
// menuStrip
//
menuStrip.ImageScalingSize = new Size(20, 20);
menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, пополнениеМагазинаToolStripMenuItem });
menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, пополнениеМагазинаToolStripMenuItem, продатьПродукциюToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1043, 28);
@ -64,24 +65,31 @@
// ComponentsToolStripMenuItem
//
ComponentsToolStripMenuItem.Name = "ComponentsToolStripMenuItem";
ComponentsToolStripMenuItem.Size = new Size(224, 26);
ComponentsToolStripMenuItem.Size = new Size(182, 26);
ComponentsToolStripMenuItem.Text = "Компоненты";
ComponentsToolStripMenuItem.Click += ComponentsToolStripMenuItem_Click;
//
// SecuresToolStripMenuItem
//
SecuresToolStripMenuItem.Name = "SecuresToolStripMenuItem";
SecuresToolStripMenuItem.Size = new Size(224, 26);
SecuresToolStripMenuItem.Size = new Size(182, 26);
SecuresToolStripMenuItem.Text = "Изделия";
SecuresToolStripMenuItem.Click += SecuresToolStripMenuItem_Click;
//
// магазиныToolStripMenuItem
//
магазиныToolStripMenuItem.Name = агазиныToolStripMenuItem";
магазиныToolStripMenuItem.Size = new Size(224, 26);
магазиныToolStripMenuItem.Size = new Size(182, 26);
магазиныToolStripMenuItem.Text = "Магазины";
магазиныToolStripMenuItem.Click += ShopsToolStripMenuItem_Click;
//
// пополнениеМагазинаToolStripMenuItem
//
пополнениеМагазинаToolStripMenuItem.Name = "пополнениеМагазинаToolStripMenuItem";
пополнениеМагазинаToolStripMenuItem.Size = new Size(182, 24);
пополнениеМагазинаToolStripMenuItem.Text = "Пополнение магазина";
пополнениеМагазинаToolStripMenuItem.Click += SupplyShopToolStripMenuItem_Click;
//
// dataGridView
//
dataGridView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
@ -151,12 +159,12 @@
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRefresh_Click;
//
// пополнениеМагазинаToolStripMenuItem
// продатьПродукциюToolStripMenuItem
//
пополнениеМагазинаToolStripMenuItem.Name = "пополнениеМагазинаToolStripMenuItem";
пополнениеМагазинаToolStripMenuItem.Size = new Size(182, 24);
пополнениеМагазинаToolStripMenuItem.Text = "Пополнение магазина";
пополнениеМагазинаToolStripMenuItem.Click += SupplyShopToolStripMenuItem_Click;
продатьПродукциюToolStripMenuItem.Name = "продатьПродукциюToolStripMenuItem";
продатьПродукциюToolStripMenuItem.Size = new Size(165, 24);
продатьПродукциюToolStripMenuItem.Text = "Продать продукцию";
продатьПродукциюToolStripMenuItem.Click += продатьПродукциюToolStripMenuItem_Click;
//
// FormMain
//
@ -195,5 +203,6 @@
private Button buttonRefresh;
private ToolStripMenuItem магазиныToolStripMenuItem;
private ToolStripMenuItem пополнениеМагазинаToolStripMenuItem;
private ToolStripMenuItem продатьПродукциюToolStripMenuItem;
}
}

View File

@ -1,6 +1,7 @@
using Microsoft.Extensions.Logging;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemView.Shop;
namespace SecuritySystemView
{
@ -154,5 +155,14 @@ namespace SecuritySystemView
form.ShowDialog();
}
}
private void продатьПродукциюToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormShopSell));
if (service is FormShopSell form)
{
form.ShowDialog();
}
}
}
}

View File

@ -18,7 +18,7 @@
<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="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>

View File

@ -5,6 +5,7 @@ using SecuritySystemBusinessLogic.BusinessLogics;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemDatabaseImplement.Implements;
using SecuritySystemView.Shop;
namespace SecuritySystemView
{
@ -51,6 +52,7 @@ namespace SecuritySystemView
services.AddTransient<FormShop>();
services.AddTransient<FormShops>();
services.AddTransient<FormShopSupply>();
services.AddTransient<FormShopSell>();
}
}
}

View File

@ -38,10 +38,12 @@
ColumnId = new DataGridViewTextBoxColumn();
ColumnName = new DataGridViewTextBoxColumn();
ColumnCount = new DataGridViewTextBoxColumn();
colorDialog1 = new ColorDialog();
buttonSave = new Button();
buttonCancel = new Button();
numericUpDownCapacity = new NumericUpDown();
labelCapacity = new Label();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownCapacity).BeginInit();
SuspendLayout();
//
// labelName
@ -153,11 +155,30 @@
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// numericUpDownCapacity
//
numericUpDownCapacity.Location = new Point(510, 71);
numericUpDownCapacity.Maximum = new decimal(new int[] { 1000, 0, 0, 0 });
numericUpDownCapacity.Name = "numericUpDownCapacity";
numericUpDownCapacity.Size = new Size(150, 27);
numericUpDownCapacity.TabIndex = 7;
//
// labelCapacity
//
labelCapacity.AutoSize = true;
labelCapacity.Location = new Point(398, 76);
labelCapacity.Name = "labelCapacity";
labelCapacity.Size = new Size(103, 20);
labelCapacity.TabIndex = 8;
labelCapacity.Text = "Вместимость:";
//
// FormShop
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(672, 450);
Controls.Add(labelCapacity);
Controls.Add(numericUpDownCapacity);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(dataGridView);
@ -171,6 +192,7 @@
Text = "Магазин";
Load += FormShop_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownCapacity).EndInit();
ResumeLayout(false);
PerformLayout();
}
@ -187,8 +209,9 @@
private DataGridViewTextBoxColumn ColumnId;
private DataGridViewTextBoxColumn ColumnName;
private DataGridViewTextBoxColumn ColumnCount;
private ColorDialog colorDialog1;
private Button buttonSave;
private Button buttonCancel;
private NumericUpDown numericUpDownCapacity;
private Label labelCapacity;
}
}

View File

@ -37,6 +37,7 @@ namespace SecuritySystemView
textBoxName.Text = view.Name;
textBoxAddress.Text = view.Address;
dateTimePickerOpeningDate.Value = view.OpeningDate;
numericUpDownCapacity.Value = view.MaxSecuresCount;
_shopSecures = view.ShopSecures ?? new Dictionary<int, (ISecureModel, int)>();
LoadData();
}
@ -85,6 +86,12 @@ namespace SecuritySystemView
return;
}
if (numericUpDownCapacity.Value <= 0)
{
MessageBox.Show("Вместимость должна быть больше нуля", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение магазина");
try
@ -95,7 +102,8 @@ namespace SecuritySystemView
Name = textBoxName.Text,
Address = textBoxAddress.Text,
OpeningDate = dateTimePickerOpeningDate.Value.Date,
ShopSecures = _shopSecures
ShopSecures = _shopSecures,
MaxSecuresCount = (int)numericUpDownCapacity.Value
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);

View File

@ -18,7 +18,7 @@
<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="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>
@ -126,7 +126,13 @@
<metadata name="ColumnCount.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="colorDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
<metadata name="ColumnId.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnCount.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,125 @@
namespace SecuritySystemView.Shop
{
partial class FormShopSell
{
/// <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()
{
buttonSell = new Button();
buttonCancel = new Button();
comboBoxSecure = new ComboBox();
numericUpDownCount = new NumericUpDown();
labelSecure = new Label();
labelCount = new Label();
((System.ComponentModel.ISupportInitialize)numericUpDownCount).BeginInit();
SuspendLayout();
//
// buttonSell
//
buttonSell.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonSell.Location = new Point(573, 89);
buttonSell.Name = "buttonSell";
buttonSell.Size = new Size(94, 29);
buttonSell.TabIndex = 0;
buttonSell.Text = "Продать";
buttonSell.UseVisualStyleBackColor = true;
buttonSell.Click += buttonSell_Click;
//
// buttonCancel
//
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonCancel.Location = new Point(673, 89);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(94, 29);
buttonCancel.TabIndex = 1;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// comboBoxSecure
//
comboBoxSecure.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
comboBoxSecure.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxSecure.FormattingEnabled = true;
comboBoxSecure.Location = new Point(84, 9);
comboBoxSecure.Name = "comboBoxSecure";
comboBoxSecure.Size = new Size(683, 28);
comboBoxSecure.TabIndex = 2;
//
// numericUpDownCount
//
numericUpDownCount.Location = new Point(108, 43);
numericUpDownCount.Name = "numericUpDownCount";
numericUpDownCount.Size = new Size(150, 27);
numericUpDownCount.TabIndex = 3;
//
// labelSecure
//
labelSecure.AutoSize = true;
labelSecure.Location = new Point(12, 12);
labelSecure.Name = "labelSecure";
labelSecure.Size = new Size(66, 20);
labelSecure.TabIndex = 4;
labelSecure.Text = "Продукт";
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(12, 45);
labelCount.Name = "labelCount";
labelCount.Size = new Size(90, 20);
labelCount.TabIndex = 5;
labelCount.Text = "Количество";
//
// FormShopSell
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(779, 130);
Controls.Add(labelCount);
Controls.Add(labelSecure);
Controls.Add(numericUpDownCount);
Controls.Add(comboBoxSecure);
Controls.Add(buttonCancel);
Controls.Add(buttonSell);
Name = "FormShopSell";
Text = "Продажа товара";
Load += FormShopSell_Load;
((System.ComponentModel.ISupportInitialize)numericUpDownCount).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Button buttonSell;
private Button buttonCancel;
private ComboBox comboBoxSecure;
private NumericUpDown numericUpDownCount;
private Label labelSecure;
private Label labelCount;
}
}

View File

@ -0,0 +1,85 @@
using Microsoft.Extensions.Logging;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
namespace SecuritySystemView.Shop
{
public partial class FormShopSell : Form
{
private readonly IShopLogic _shopLogic;
private readonly ISecureLogic _secureLogic;
private readonly ILogger _logger;
public FormShopSell(ILogger<FormShopSell> logger, IShopLogic shopLogic, ISecureLogic secureLogic)
{
InitializeComponent();
_logger = logger;
_shopLogic = shopLogic;
_secureLogic = secureLogic;
}
private void FormShopSell_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка продукции для продажи");
try
{
var list = _secureLogic.ReadList(null);
if (list != null)
{
comboBoxSecure.DisplayMember = "SecureName";
comboBoxSecure.ValueMember = "Id";
comboBoxSecure.DataSource = list;
comboBoxSecure.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка продукции");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonSell_Click(object sender, EventArgs e)
{
if (numericUpDownCount.Value < 1)
{
MessageBox.Show("Количество продукта должно быть больше нуля", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxSecure.SelectedValue == null)
{
MessageBox.Show("Выберите продукт", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Создание продажи");
try
{
var operationResult = _shopLogic.SellSecures(
new SecureBindingModel
{
Id = Convert.ToInt32(comboBoxSecure.SelectedValue)
},
Convert.ToInt32(numericUpDownCount.Value)
);
if (!operationResult)
{
throw new Exception("Ошибка при создании продажи. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания продажи");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void 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>