Compare commits

...

3 Commits

24 changed files with 1015 additions and 79 deletions

1
.gitignore vendored
View File

@ -398,3 +398,4 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
ImplementationExtensions/

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);
@ -176,34 +181,44 @@ namespace SecuritySystemBusinessLogic.BusinessLogics
return true;
}
public bool SupplySecures(ISecureModel secure, int count) => throw new NotImplementedException();
public bool SellSecures(ISecureModel model, int count) => throw new NotImplementedException();
public bool CheckSecuresCount(ISecureModel model, int count)
public bool SupplySecures(ISecureModel secure, int count)
{
int securesInShops = _shopStorage.GetFullList()
.Select(x => x.ShopSecures.Select(y => y.Value.Item1.Id == model.Id ? y.Value.Item2 : 0).Sum()).Sum();
return securesInShops >= count;
}
public bool CheckSupplySecures(ShopSearchModel shopSearchModel, int count)
{
if (shopSearchModel == null)
throw new ArgumentNullException(nameof(shopSearchModel));
var shop = _shopStorage.GetElement(shopSearchModel);
if (shop == null)
if (!CheckSupplySecures(count))
{
_logger.LogWarning("Required shop element not found in storage");
return false;
throw new InvalidOperationException("Невозможно пополнить: в магазинах не хватает места");
}
int securesInShop = _shopStorage.GetFullList().Select(x => x.ShopSecures.Select(y => y.Value.Item2).Sum()).Sum();
var shops = _shopStorage.GetFullList();
foreach (var shop in shops)
{
int shopFreeSpace = GetFreeSpace(shop.Id);
if (shopFreeSpace > 0)
{
int min = Math.Min(count, shopFreeSpace);
count -= min;
SupplySecures(new ShopSearchModel { Id = shop.Id }, secure, min);
}
}
return securesInShop + count <= shop.MaxSecuresCount;
return true;
}
public bool SellSecures(ISecureModel model, int count)
{
return _shopStorage.SellSecures(model, count);
}
public bool CheckSupplySecures(int count)
{
throw new NotImplementedException();
return GetFreeSpace() >= count;
}
private int GetFreeSpace()
{
var shops = _shopStorage.GetFullList();
return shops.Select(shop => shop.MaxSecuresCount - shop.ShopSecures.Select(shopSecure => shopSecure.Value.Item2).Sum()).Sum();
}
private int GetFreeSpace(int shopId)
{
var shop = _shopStorage.GetElement(new ShopSearchModel { Id = shopId });
return shop.MaxSecuresCount - shop.ShopSecures.Select(shopSecure => shopSecure.Value.Item2).Sum();
}
}
}

View File

@ -17,14 +17,6 @@ namespace SecuritySystemContracts.BusinessLogicsContracts
/// </summary>
bool SellSecures(ISecureModel model, int count);
/// <summary>
/// Проверяет наличие определенного количества продукта суммарно по всем магазинам
/// </summary>
bool CheckSecuresCount(ISecureModel model, int count);
/// <summary>
/// Проверяет можно ли пополнить конкретный магазин продукцией в указанном количестве
/// </summary>
bool CheckSupplySecures(ShopSearchModel shopSearchModel, int count);
/// <summary>
/// Проверяет можно ли распределить во все магазины продукты в указанном количестве
/// </summary>
bool CheckSupplySecures(int count);

View File

@ -13,5 +13,6 @@ namespace SecuritySystemContracts.StoragesContracts
ShopViewModel? Insert(ShopBindingModel model);
ShopViewModel? Update(ShopBindingModel model);
ShopViewModel? Delete(ShopBindingModel model);
bool SellSecures(ISecureModel secureModel, int securesCount);
}
}

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

@ -1,7 +1,11 @@
using SecuritySystemContracts.BindingModels;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
using SecuritySystemDatabaseImplement.Models;
using SecuritySystemDataModels.Models;
namespace SecuritySystemDatabaseImplement.Implements
{
@ -9,32 +13,118 @@ namespace SecuritySystemDatabaseImplement.Implements
{
public ShopViewModel? Delete(ShopBindingModel model)
{
throw new NotImplementedException();
using var context = new SecuritySystemDatabase();
var shop = context.Shops.Include(x => x.Secures).FirstOrDefault(x => x.Id == model.Id);
if (shop != null)
{
context.Shops.Remove(shop);
context.SaveChanges();
return shop.GetViewModel;
}
return null;
}
public ShopViewModel? GetElement(ShopSearchModel model)
{
throw new NotImplementedException();
return GetFilteredList(model).FirstOrDefault();
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
{
throw new NotImplementedException();
var elements = GetFullList();
if (model.Id != null)
{
elements = elements.Where(x => x.Id == model.Id).ToList();
}
if (!model.Name.IsNullOrEmpty())
{
elements = elements.Where(x => x.Name == model.Name).ToList();
}
return elements;
}
public List<ShopViewModel> GetFullList()
{
throw new NotImplementedException();
using var context = new SecuritySystemDatabase();
return context.Shops
.Include(x => x.Secures)
.ThenInclude(x => x.Secure)
.Select(x => x.GetViewModel)
.ToList();
}
public ShopViewModel? Insert(ShopBindingModel model)
{
throw new NotImplementedException();
using var context = new SecuritySystemDatabase();
var newShop = Shop.Create(context, model);
if (newShop == null)
{
return null;
}
context.Shops.Add(newShop);
context.SaveChanges();
return newShop.GetViewModel;
}
public bool SellSecures(ISecureModel secureModel, int securesCount)
{
using var context = new SecuritySystemDatabase();
using var transaction = context.Database.BeginTransaction();
foreach (var shopSecure in context.ShopSecures.Where(x => x.SecureId == secureModel.Id))
{
var min = Math.Min(securesCount, shopSecure.Count);
shopSecure.Count -= min;
securesCount -= min;
if (securesCount <= 0)
{
break;
}
}
if (securesCount == 0)
{
context.SaveChanges();
transaction.Commit();
}
else
{
transaction.Rollback();
}
if (securesCount > 0)
{
return false;
}
return true;
}
public ShopViewModel? Update(ShopBindingModel model)
{
throw new NotImplementedException();
using var context = new SecuritySystemDatabase();
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();
if (model.ShopSecures.Count > 0)
{
shop.UpdateSecures(context, model);
}
transaction.Commit();
return shop.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
}
}

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

@ -66,7 +66,7 @@ namespace SecuritySystemDatabaseImplement.Models
ShopSecures = ShopSecures
};
public void UpdateComponents(SecuritySystemDatabase context, ShopBindingModel model)
public void UpdateSecures(SecuritySystemDatabase context, ShopBindingModel model)
{
var shopSecures = context.ShopSecures.Where(rec => rec.SecureId == model.Id).ToList();
if (shopSecures != null && shopSecures.Count > 0)

View File

@ -4,6 +4,7 @@ using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
using SecuritySystemDataModels.Models;
using SecuritySystemFileImplement.Models;
using System.Reflection;
namespace SecuritySystemFileImplement.Implements
{
@ -75,5 +76,56 @@ namespace SecuritySystemFileImplement.Implements
source.SaveShops();
return shop.GetViewModel;
}
public bool SellSecures(ISecureModel secureModel, int securesCount)
{
var secure = source.Secures.FirstOrDefault(x => x.Id == secureModel.Id);
if (secure == null)
{
return false;
}
var shopSecures = source.Shops.SelectMany(shop => shop.ShopSecures.Where(c => c.Value.Item1.Id == secure.Id));
int countStore = 0;
foreach (var it in shopSecures)
countStore += it.Value.Item2;
if (securesCount > countStore)
return false;
foreach (var shop in source.Shops)
{
var secures = shop.ShopSecures;
foreach (var c in secures.Where(x => x.Value.Item1.Id == secure.Id))
{
int min = Math.Min(c.Value.Item2, securesCount);
secures[c.Value.Item1.Id] = (c.Value.Item1, c.Value.Item2 - min);
securesCount -= min;
if (securesCount <= 0)
break;
}
shop.Update(new ShopBindingModel
{
Id = shop.Id,
Name = shop.Name,
Address = shop.Address,
MaxSecuresCount = shop.MaxSecuresCount,
OpeningDate = shop.OpeningDate,
ShopSecures = secures
});
source.SaveShops();
if (securesCount <= 0)
return true;
}
return true;
}
}
}

View File

@ -2,6 +2,7 @@
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
using SecuritySystemDataModels.Models;
using SecuritySystemListImplement.Models;
namespace SecuritySystemListImplement.Implements
@ -117,5 +118,10 @@ namespace SecuritySystemListImplement.Implements
return null;
}
public bool SellSecures(ISecureModel secureModel, int securesCount)
{
throw new NotImplementedException();
}
}
}

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>