diff --git a/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs index 6dfe092..021f969 100644 --- a/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs +++ b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs @@ -18,7 +18,7 @@ namespace SushiBarBusinessLogic.BusinessLogics private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; static readonly object _locker = new object(); - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + private readonly IShopStorage _shopStorage; public OrderLogic(ILogger logger, IOrderStorage orderStorage, IShopStorage shopStorage) @@ -67,28 +67,60 @@ namespace SushiBarBusinessLogic.BusinessLogics 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.RestockingShops(new SupplyBindingModel - { - SushiId = order.SushiId, - Count = order.Count - })) - { - throw new ArgumentException("Недостаточно места"); - } - return ChangeStatus(model, OrderStatus.Выдан); - } + public bool DeliveryOrder(OrderBindingModel model) + { + lock (_locker) + { + model = FillOrderBindingModel(model); + if (model.Status != OrderStatus.Готов && model.Status != OrderStatus.Ожидает) + { + _logger.LogWarning("Changing status operation faled: Current-{Status}:required-Выдан.", model.Status); + throw new InvalidOperationException($"Невозможно приствоить статус выдан заказу с текущим статусом {model.Status}"); + } + if (!_shopStorage.RestockingShops(new SupplyBindingModel + { + SushiId = model.SushiId, + Count = model.Count + })) + { + if (model.Status == OrderStatus.Готов || model.Status == OrderStatus.Ожидает) + { + model.Status = OrderStatus.Ожидает; + return UpdateOrder(model); + } + } + model.Status = OrderStatus.Выдан; + return UpdateOrder(model); + } + } - private void CheckModel(OrderBindingModel model, bool withParams = true) + private OrderBindingModel FillOrderBindingModel(OrderBindingModel model) + { + CheckModel(model, false); + var element = _orderStorage.GetElement(new OrderSearchModel() + { + Id = model.Id + }); + if (element == null) + { + throw new InvalidOperationException(nameof(element)); + } + model.Id = element.Id; + model.DateCreate = element.DateCreate; + model.SushiId = element.SushiId; + model.DateImplement = element.DateImplement; + model.ClientId = element.ClientId; + model.Status = element.Status; + model.Count = element.Count; + model.Sum = element.Sum; + if (!model.ImplementerId.HasValue) + { + model.ImplementerId = element.ImplementerId; + } + return model; + } + + private void CheckModel(OrderBindingModel model, bool withParams = true) { if (model == null) { @@ -172,5 +204,16 @@ namespace SushiBarBusinessLogic.BusinessLogics _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); return element; } - } + + private bool UpdateOrder(OrderBindingModel model) + { + if (_orderStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + _logger.LogWarning("Update operation sucsess"); + return true; + } + } } diff --git a/SushiBar/SushiBarBusinessLogic_/WorkModeling .cs b/SushiBar/SushiBarBusinessLogic_/WorkModeling .cs index 14802a4..65ae540 100644 --- a/SushiBar/SushiBarBusinessLogic_/WorkModeling .cs +++ b/SushiBar/SushiBarBusinessLogic_/WorkModeling .cs @@ -54,7 +54,8 @@ namespace SushiBarBusinessLogic { return; } - await RunOrderInWork(implementer); + await DeliverWaitingOrder(implementer); + await RunOrderInWork(implementer); await Task.Run(() => { @@ -135,5 +136,47 @@ namespace SushiBarBusinessLogic throw; } } - } + + private async Task DeliverWaitingOrder(ImplementerViewModel implementer) + { + if (_orderLogic == null || implementer == null) + { + return; + } + var waitingOrders = await Task.Run(() => _orderLogic.ReadList(new OrderSearchModel + { + ImplementerId = implementer.Id, + Status = OrderStatus.Ожидает + })); + if (waitingOrders == null || waitingOrders.Count == 0) + { + return; + } + _logger.LogInformation("DeliverWaitingOrder. Find some waitig order for implementer:{id}.Count:{count}", implementer.Id, waitingOrders.Count); + foreach (var waitingOrder in waitingOrders) + { + try + { + _logger.LogInformation("DeliverWaitingOrder. Trying to deliver order id:{id}", waitingOrder.Id); + var res = _orderLogic.DeliveryOrder(new OrderBindingModel + { + Id = waitingOrder.Id + }); + } + catch (ArgumentException ex) + { + _logger.LogWarning(ex, "DeliverWaitingOrder. Fault"); + } + catch (InvalidOperationException ex) + { + _logger.LogWarning(ex, "Error try deliver order"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while do work"); + throw; + } + } + } + } } diff --git a/SushiBar/SushiBarDataModels/Enums/OrderStatus.cs b/SushiBar/SushiBarDataModels/Enums/OrderStatus.cs index c1b6d91..42b2070 100644 --- a/SushiBar/SushiBarDataModels/Enums/OrderStatus.cs +++ b/SushiBar/SushiBarDataModels/Enums/OrderStatus.cs @@ -12,6 +12,7 @@ namespace SushiBarDataModels.Enums Принят = 0, Выполняется = 1, Готов = 2, - Выдан = 3 - } + Ожидает = 3, + Выдан = 4 + } } diff --git a/SushiBar/SushiBarDatabaseImplement/Migrations/20240423172527_implementors.Designer.cs b/SushiBar/SushiBarDatabaseImplement/Migrations/20240423172527_implementors.Designer.cs deleted file mode 100644 index 13ff894..0000000 --- a/SushiBar/SushiBarDatabaseImplement/Migrations/20240423172527_implementors.Designer.cs +++ /dev/null @@ -1,257 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SushiBarDatabaseImplement; - -#nullable disable - -namespace SushiBarDatabaseImplement.Migrations -{ - [DbContext(typeof(SushiBarDatabase))] - [Migration("20240423172527_implementors")] - partial class implementors - { - /// - 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("SushiBarDataModels.Models.Implementer", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ImplementerFIO") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Password") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Qualification") - .HasColumnType("int"); - - b.Property("WorkExperience") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.ToTable("Implementers"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClientFIO") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Email") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Password") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.ToTable("Clients"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.Component", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ComponentName") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Cost") - .HasColumnType("float"); - - b.HasKey("Id"); - - b.ToTable("Components"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClientId") - .HasColumnType("int"); - - b.Property("Count") - .HasColumnType("int"); - - b.Property("DateCreate") - .HasColumnType("datetime2"); - - b.Property("DateImplement") - .HasColumnType("datetime2"); - - b.Property("ImplementerId") - .HasColumnType("int"); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("Sum") - .HasColumnType("float"); - - b.Property("SushiId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("ClientId"); - - b.HasIndex("ImplementerId"); - - b.HasIndex("SushiId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.Sushi", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Price") - .HasColumnType("float"); - - b.Property("SushiName") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.ToTable("Sushis"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.SushiComponent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ComponentId") - .HasColumnType("int"); - - b.Property("Count") - .HasColumnType("int"); - - b.Property("SushiId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("ComponentId"); - - b.HasIndex("SushiId"); - - b.ToTable("SushiComponents"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.Order", b => - { - b.HasOne("SushiBarDatabaseImplement.Models.Client", "Client") - .WithMany("Orders") - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SushiBarDataModels.Models.Implementer", "Implementer") - .WithMany("Order") - .HasForeignKey("ImplementerId"); - - b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi") - .WithMany("Orders") - .HasForeignKey("SushiId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Client"); - - b.Navigation("Implementer"); - - b.Navigation("Sushi"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.SushiComponent", b => - { - b.HasOne("SushiBarDatabaseImplement.Models.Component", "Component") - .WithMany("SushiComponents") - .HasForeignKey("ComponentId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi") - .WithMany("Components") - .HasForeignKey("SushiId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Component"); - - b.Navigation("Sushi"); - }); - - modelBuilder.Entity("SushiBarDataModels.Models.Implementer", b => - { - b.Navigation("Order"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b => - { - b.Navigation("Orders"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.Component", b => - { - b.Navigation("SushiComponents"); - }); - - modelBuilder.Entity("SushiBarDatabaseImplement.Models.Sushi", b => - { - b.Navigation("Components"); - - b.Navigation("Orders"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/SushiBar/SushiBarDatabaseImplement/Migrations/20240423172527_implementors.cs b/SushiBar/SushiBarDatabaseImplement/Migrations/20240423172527_implementors.cs deleted file mode 100644 index c4c8f91..0000000 --- a/SushiBar/SushiBarDatabaseImplement/Migrations/20240423172527_implementors.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace SushiBarDatabaseImplement.Migrations -{ - /// - public partial class implementors : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "ImplementerId", - table: "Orders", - type: "int", - nullable: true); - - migrationBuilder.CreateTable( - name: "Implementers", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - ImplementerFIO = table.Column(type: "nvarchar(max)", nullable: false), - Password = table.Column(type: "nvarchar(max)", nullable: false), - WorkExperience = table.Column(type: "int", nullable: false), - Qualification = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Implementers", x => x.Id); - }); - - migrationBuilder.CreateIndex( - name: "IX_Orders_ImplementerId", - table: "Orders", - column: "ImplementerId"); - - migrationBuilder.AddForeignKey( - name: "FK_Orders_Implementers_ImplementerId", - table: "Orders", - column: "ImplementerId", - principalTable: "Implementers", - principalColumn: "Id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Orders_Implementers_ImplementerId", - table: "Orders"); - - migrationBuilder.DropTable( - name: "Implementers"); - - migrationBuilder.DropIndex( - name: "IX_Orders_ImplementerId", - table: "Orders"); - - migrationBuilder.DropColumn( - name: "ImplementerId", - table: "Orders"); - } - } -} diff --git a/SushiBar/SushiBarDatabaseImplement/Migrations/20240508053719_InitCreate.Designer.cs b/SushiBar/SushiBarDatabaseImplement/Migrations/20240522094128_InitCreate.Designer.cs similarity index 86% rename from SushiBar/SushiBarDatabaseImplement/Migrations/20240508053719_InitCreate.Designer.cs rename to SushiBar/SushiBarDatabaseImplement/Migrations/20240522094128_InitCreate.Designer.cs index c5b1482..f3d474e 100644 --- a/SushiBar/SushiBarDatabaseImplement/Migrations/20240508053719_InitCreate.Designer.cs +++ b/SushiBar/SushiBarDatabaseImplement/Migrations/20240522094128_InitCreate.Designer.cs @@ -12,7 +12,7 @@ using SushiBarDatabaseImplement; namespace SushiBarDatabaseImplement.Migrations { [DbContext(typeof(SushiBarDatabase))] - [Migration("20240508053719_InitCreate")] + [Migration("20240522094128_InitCreate")] partial class InitCreate { /// @@ -25,6 +25,33 @@ namespace SushiBarDatabaseImplement.Migrations SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + modelBuilder.Entity("SushiBarDataModels.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Qualification") + .HasColumnType("int"); + + b.Property("WorkExperience") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b => { b.Property("Id") @@ -90,6 +117,9 @@ namespace SushiBarDatabaseImplement.Migrations b.Property("DateImplement") .HasColumnType("datetime2"); + b.Property("ImplementerId") + .HasColumnType("int"); + b.Property("Status") .HasColumnType("int"); @@ -103,6 +133,8 @@ namespace SushiBarDatabaseImplement.Migrations b.HasIndex("ClientId"); + b.HasIndex("ImplementerId"); + b.HasIndex("SushiId"); b.ToTable("Orders"); @@ -215,6 +247,10 @@ namespace SushiBarDatabaseImplement.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("SushiBarDataModels.Models.Implementer", "Implementer") + .WithMany("Order") + .HasForeignKey("ImplementerId"); + b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi") .WithMany("Orders") .HasForeignKey("SushiId") @@ -223,6 +259,8 @@ namespace SushiBarDatabaseImplement.Migrations b.Navigation("Client"); + b.Navigation("Implementer"); + b.Navigation("Sushi"); }); @@ -264,6 +302,11 @@ namespace SushiBarDatabaseImplement.Migrations b.Navigation("Sushi"); }); + modelBuilder.Entity("SushiBarDataModels.Models.Implementer", b => + { + b.Navigation("Order"); + }); + modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b => { b.Navigation("Orders"); diff --git a/SushiBar/SushiBarDatabaseImplement/Migrations/20240508053719_InitCreate.cs b/SushiBar/SushiBarDatabaseImplement/Migrations/20240522094128_InitCreate.cs similarity index 86% rename from SushiBar/SushiBarDatabaseImplement/Migrations/20240508053719_InitCreate.cs rename to SushiBar/SushiBarDatabaseImplement/Migrations/20240522094128_InitCreate.cs index c5057d4..e0a7621 100644 --- a/SushiBar/SushiBarDatabaseImplement/Migrations/20240508053719_InitCreate.cs +++ b/SushiBar/SushiBarDatabaseImplement/Migrations/20240522094128_InitCreate.cs @@ -40,6 +40,22 @@ namespace SushiBarDatabaseImplement.Migrations table.PrimaryKey("PK_Components", x => x.Id); }); + migrationBuilder.CreateTable( + name: "Implementers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ImplementerFIO = table.Column(type: "nvarchar(max)", nullable: false), + Password = table.Column(type: "nvarchar(max)", nullable: false), + WorkExperience = table.Column(type: "int", nullable: false), + Qualification = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Implementers", x => x.Id); + }); + migrationBuilder.CreateTable( name: "Shops", columns: table => new @@ -82,7 +98,8 @@ namespace SushiBarDatabaseImplement.Migrations Sum = table.Column(type: "float", nullable: false), Status = table.Column(type: "int", nullable: false), DateCreate = table.Column(type: "datetime2", nullable: false), - DateImplement = table.Column(type: "datetime2", nullable: true) + DateImplement = table.Column(type: "datetime2", nullable: true), + ImplementerId = table.Column(type: "int", nullable: true) }, constraints: table => { @@ -93,6 +110,11 @@ namespace SushiBarDatabaseImplement.Migrations principalTable: "Clients", principalColumn: "Id", onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Orders_Implementers_ImplementerId", + column: x => x.ImplementerId, + principalTable: "Implementers", + principalColumn: "Id"); table.ForeignKey( name: "FK_Orders_Sushis_SushiId", column: x => x.SushiId, @@ -160,6 +182,11 @@ namespace SushiBarDatabaseImplement.Migrations table: "Orders", column: "ClientId"); + migrationBuilder.CreateIndex( + name: "IX_Orders_ImplementerId", + table: "Orders", + column: "ImplementerId"); + migrationBuilder.CreateIndex( name: "IX_Orders_SushiId", table: "Orders", @@ -201,6 +228,9 @@ namespace SushiBarDatabaseImplement.Migrations migrationBuilder.DropTable( name: "Clients"); + migrationBuilder.DropTable( + name: "Implementers"); + migrationBuilder.DropTable( name: "Shops");