Сделанная 6 лабораторная

This commit is contained in:
Максим Яковлев 2024-04-21 00:32:56 +04:00
parent 57e3974535
commit f651ef7163
35 changed files with 1818 additions and 389 deletions

View File

@ -17,6 +17,7 @@ namespace CarRepairShopBusinessLogic.BusinessLogics
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
static readonly object locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
{
@ -37,6 +38,22 @@ namespace CarRepairShopBusinessLogic.BusinessLogics
return list;
}
public OrderViewModel? ReadElement(OrderSearchModel? model)
{
if(model == null)
{
throw new ArgumentNullException(nameof(model));
}
var element = _orderStorage.GetElement(model);
if(element == null)
{
_logger.LogError("ReadElement. Элемент не найден");
return null;
}
_logger.LogInformation("ReadElement. Id:{id}", element.Id);
return element;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
@ -61,24 +78,32 @@ namespace CarRepairShopBusinessLogic.BusinessLogics
}
public bool TakeOrderInWork(OrderBindingModel model)
{
lock (locker)
{
return StatusUpdate(model, OrderStatus.Выполняется);
}
}
private bool StatusUpdate(OrderBindingModel model, OrderStatus newStatus)
{
if(model.Status + 1 != newStatus)
var element = _orderStorage.GetElement(new OrderSearchModel
{
Id = model.Id
});
if (element == null) return false;
if (element.ImplementerId.HasValue) model.ImplementerId = element.ImplementerId;
if (element.Status + 1 != newStatus)
{
_logger.LogInformation("Status update operation failed. Incorrect order status");
return false;
}
model.Status = newStatus;
if(model.Status == OrderStatus.Выдан)
if (model.Status == OrderStatus.Выдан)
{
model.DateImplement = DateTime.Now;
}
if(_orderStorage.Update(model) == null)
if (_orderStorage.Update(model) == null)
{
model.Status--;
_logger.LogWarning("Update operation failed");

View File

@ -0,0 +1,136 @@
using CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.BusinessLogicsContracts;
using CarRepairShopContracts.SearchModels;
using CarRepairShopContracts.ViewModels;
using CarRepairShopDataModels.Enums;
using DocumentFormat.OpenXml.Bibliography;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarRepairShopBusinessLogic.BusinessLogics
{
public class WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if(implementers == null)
{
_logger.LogWarning("DoWork. Исполнителей нет");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel
{
Status = OrderStatus.Принят
});
if(orders == null || orders.Count == 0)
{
_logger.LogWarning("DoWork. Заказы пусты или null");
return;
}
_logger.LogDebug("DoWork for {Count} orders", orders.Count);
foreach(var implementer in implementers)
{
Task.Run(() => WorkerWorkAsync(implementer, orders));
}
}
private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel> orders)
{
if(_orderLogic == null || implementer == null)
{
return;
}
await RunOrderInWork(implementer);
await Task.Run(() =>
{
foreach (var order in orders)
{
try
{
_logger.LogDebug("DoWork. Исполнитель {Id} пытается взять заказ {order}", implementer.Id, order.Id);
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = order.Id,
ImplementerId = implementer.Id
});
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Исполнитель {Id} закончил заказ {Order}", implementer.Id, order.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = order.Id,
});
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Ошибка с получением работы");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка во время работы");
throw;
}
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
});
}
private async Task RunOrderInWork(ImplementerViewModel implementer)
{
if(_orderLogic == null || implementer == null)
{
return;
}
try
{
var runOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = implementer.Id,
Status = OrderStatus.Выполняется
}));
if(runOrder == null)
{
return;
}
_logger.LogDebug("DoWork. Исполнитель {Id} вернулся к заказу {Order}", implementer.Id, runOrder.Id);
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
;
_logger.LogDebug("DoWork. Исполнитель {Id} закончил заказ {Order}", implementer.Id, runOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = implementer.Id
});
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
catch(InvalidOperationException ex)
{
_logger.LogWarning(ex, "Ошибка получения работы");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка во время работы");
throw;
}
}
}
}

View File

@ -13,7 +13,7 @@ namespace CarRepairShopContracts.BindingModels
public int Id { get; set; }
public int RepairId { get; set; }
public int ClientId { get; set; }
public int ImplementerId { get; set; }
public int? ImplementerId { get; set; }
public int Count { get; set; }
public double Sum { get; set; }
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;

View File

@ -12,6 +12,7 @@ namespace CarRepairShopContracts.BusinessLogicsContracts
public interface IOrderLogic
{
List<OrderViewModel>? ReadList(OrderSearchModel? model);
OrderViewModel? ReadElement(OrderSearchModel? model);
bool CreateOrder(OrderBindingModel model);
bool TakeOrderInWork(OrderBindingModel model);

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarRepairShopContracts.BusinessLogicsContracts
{
public interface IWorkProcess
{
void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic);
}
}

View File

@ -1,4 +1,5 @@
using System;
using CarRepairShopDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -10,6 +11,8 @@ namespace CarRepairShopContracts.SearchModels
{
public int? Id { get; set; }
public int? ClientId { get; set; }
public int? ImplementerId { get; set; }
public OrderStatus? Status { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set;}
}

View File

@ -17,11 +17,14 @@ namespace CarRepairShopContracts.ViewModels
public int RepairId { get; set; }
public int ClientId { get; set; }
public int ImplementerId { get; set; }
public int? ImplementerId { get; set; }
[DisplayName("ФИО клиента")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("ФИО исполнителя")]
public string ImplementerFIO { get; set; } = string.Empty;
[DisplayName("Ремонт")]
public string RepairName { get; set; } = string.Empty;

View File

@ -11,7 +11,7 @@ namespace CarRepairShopDataModels.Models
{
int RepairId { get; }
int ClientId { get; }
int ImplementerId { get; }
int? ImplementerId { get; }
int Count { get; }
double Sum { get; }
OrderStatus Status { get; }

View File

@ -32,10 +32,6 @@ namespace CarRepairShopDatabaseImplement.Implements
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if(string.IsNullOrEmpty(model.ImplementerFIO))
{
return null;
}
using var context = new CarRepairShopDatabase();
return context.Implementers.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ImplementerFIO)) && x.ImplementerFIO == model.ImplementerFIO || model.Id.HasValue && x.Id == model.Id)?.GetViewModel;
}

View File

@ -3,6 +3,7 @@ using CarRepairShopContracts.SearchModels;
using CarRepairShopContracts.StoragesContracts;
using CarRepairShopContracts.ViewModels;
using CarRepairShopDatabaseImplement.Models;
using CarRepairShopDataModels.Enums;
using DocumentFormat.OpenXml.InkML;
using Microsoft.EntityFrameworkCore;
using System;
@ -19,11 +20,11 @@ namespace CarRepairShopDatabaseImplement.Implements
public List<OrderViewModel> GetFullList()
{
using var context = new CarRepairShopDatabase();
return context.Orders.Include(x => x.Repair).Include(x => x.Client).Select(x => x.GetViewModel).ToList();
return context.Orders.Include(x=>x.Repair).Include(x => x.Client).Include(x=>x.Implementer).Select(x => x.GetViewModel).ToList();
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ClientId.HasValue)
if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ClientId.HasValue && !model.Status.HasValue)
{
return new();
}
@ -32,7 +33,8 @@ namespace CarRepairShopDatabaseImplement.Implements
return context.Orders
.Include(x => x.Repair)
.Include(x => x.Client)
.Where(x => x.Id == model.Id || x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo || x.ClientId == model.ClientId)
.Include(x => x.Implementer)
.Where(x => x.Id == model.Id || x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo || x.ClientId == model.ClientId || model.Status.Equals(x.Status))
.Select(x => x.GetViewModel).ToList();
}
public OrderViewModel? GetElement(OrderSearchModel model)
@ -42,7 +44,7 @@ namespace CarRepairShopDatabaseImplement.Implements
return null;
}
using var context = new CarRepairShopDatabase();
return context.Orders.Include(x => x.Repair).Include(x => x.Client).FirstOrDefault(x => x.Id == model.Id).GetViewModel;
return context.Orders.Include(x=>x.Repair).Include(x => x.Client).Include(x=>x.Implementer).FirstOrDefault(x => x.Id == model.Id || (x.ImplementerId == model.ImplementerId && x.Status == model.Status))?.GetViewModel;
}
public OrderViewModel? Insert(OrderBindingModel model)
{
@ -54,7 +56,7 @@ namespace CarRepairShopDatabaseImplement.Implements
using var context = new CarRepairShopDatabase();
context.Orders.Add(newOrder);
context.SaveChanges();
return context.Orders.Include(x => x.Repair).Include(x => x.Client).FirstOrDefault(x => x.Id == newOrder.Id)?.GetViewModel;
return context.Orders.Include(x=>x.Repair).Include(x => x.Client).Include(x=>x.Implementer).FirstOrDefault(x => x.Id == newOrder.Id)?.GetViewModel;
}
public OrderViewModel? Update(OrderBindingModel model)
{
@ -66,7 +68,7 @@ namespace CarRepairShopDatabaseImplement.Implements
}
order.Update(model);
context.SaveChanges();
return context.Orders.Include(x=>x.Repair).Include(x => x.Client).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
return context.Orders.Include(x=>x.Repair).Include(x => x.Client).Include(x=>x.Implementer).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
}
public OrderViewModel? Delete(OrderBindingModel model)
{

View File

@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace CarRepairShopDatabaseImplement.Migrations
{
[DbContext(typeof(CarRepairShopDatabase))]
[Migration("20240406115023_InitialCreate")]
[Migration("20240420181926_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
@ -70,6 +70,33 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.ToTable("Components");
});
modelBuilder.Entity("CarRepairShopDatabaseImplement.Models.Implementer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Implementers");
});
modelBuilder.Entity("CarRepairShopDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@ -90,6 +117,9 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("RepairId")
.HasColumnType("int");
@ -103,6 +133,8 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("RepairId");
b.ToTable("Orders");
@ -162,6 +194,10 @@ namespace CarRepairShopDatabaseImplement.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("CarRepairShopDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("CarRepairShopDatabaseImplement.Models.Repair", "Repair")
.WithMany("Orders")
.HasForeignKey("RepairId")
@ -170,6 +206,8 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Repair");
});
@ -202,6 +240,11 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.Navigation("RepairComponents");
});
modelBuilder.Entity("CarRepairShopDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("CarRepairShopDatabaseImplement.Models.Repair", b =>
{
b.Navigation("Components");

View File

@ -40,6 +40,22 @@ namespace CarRepairShopDatabaseImplement.Migrations
table.PrimaryKey("PK_Components", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Implementers",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ImplementerFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false),
WorkExperience = table.Column<int>(type: "int", nullable: false),
Qualification = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Implementers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Repairs",
columns: table => new
@ -62,6 +78,7 @@ namespace CarRepairShopDatabaseImplement.Migrations
.Annotation("SqlServer:Identity", "1, 1"),
RepairId = table.Column<int>(type: "int", nullable: false),
ClientId = table.Column<int>(type: "int", nullable: false),
ImplementerId = table.Column<int>(type: "int", nullable: true),
Count = table.Column<int>(type: "int", nullable: false),
Sum = table.Column<double>(type: "float", nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
@ -77,6 +94,11 @@ namespace CarRepairShopDatabaseImplement.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_Repairs_RepairId",
column: x => x.RepairId,
@ -117,6 +139,11 @@ namespace CarRepairShopDatabaseImplement.Migrations
table: "Orders",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_Orders_ImplementerId",
table: "Orders",
column: "ImplementerId");
migrationBuilder.CreateIndex(
name: "IX_Orders_RepairId",
table: "Orders",
@ -145,6 +172,9 @@ namespace CarRepairShopDatabaseImplement.Migrations
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropTable(
name: "Implementers");
migrationBuilder.DropTable(
name: "Components");

View File

@ -67,6 +67,33 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.ToTable("Components");
});
modelBuilder.Entity("CarRepairShopDatabaseImplement.Models.Implementer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Implementers");
});
modelBuilder.Entity("CarRepairShopDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@ -87,6 +114,9 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("RepairId")
.HasColumnType("int");
@ -100,6 +130,8 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("RepairId");
b.ToTable("Orders");
@ -159,6 +191,10 @@ namespace CarRepairShopDatabaseImplement.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("CarRepairShopDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("CarRepairShopDatabaseImplement.Models.Repair", "Repair")
.WithMany("Orders")
.HasForeignKey("RepairId")
@ -167,6 +203,8 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Repair");
});
@ -199,6 +237,11 @@ namespace CarRepairShopDatabaseImplement.Migrations
b.Navigation("RepairComponents");
});
modelBuilder.Entity("CarRepairShopDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("CarRepairShopDatabaseImplement.Models.Repair", b =>
{
b.Navigation("Components");

View File

@ -30,7 +30,7 @@ namespace CarRepairShopDatabaseImplement.Models
[Required]
public int Qualification { get; private set; }
[ForeignKey("ClientId")]
[ForeignKey("ImplementerId")]
public virtual List<Order> Orders { get; set; } = new();
public static Implementer? Create(ImplementerBindingModel model)
@ -61,7 +61,7 @@ namespace CarRepairShopDatabaseImplement.Models
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = WorkExperience
Qualification = Qualification
};
}
}

View File

@ -21,8 +21,7 @@ namespace CarRepairShopDatabaseImplement.Models
[Required]
public int ClientId { get; set; }
[Required]
public int ImplementerId { get; set; }
public int? ImplementerId { get; private set; }
[Required]
public int Count { get; set; }
@ -42,6 +41,8 @@ namespace CarRepairShopDatabaseImplement.Models
public virtual Client Client { get; set; }
public Implementer? Implementer { get; set; }
public static Order? Create(OrderBindingModel model)
{
if (model == null)
@ -53,13 +54,14 @@ namespace CarRepairShopDatabaseImplement.Models
Id = model.Id,
RepairId = model.RepairId,
ClientId = model.ClientId,
ImplementerId = model.ImplementerId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
};
}
public void Update(OrderBindingModel model)
public void Update(OrderBindingModel? model)
{
if(model == null)
{
@ -67,6 +69,7 @@ namespace CarRepairShopDatabaseImplement.Models
}
Status = model.Status;
DateImplement = model.DateImplement;
ImplementerId = model.ImplementerId;
}
public OrderViewModel GetViewModel => new()
@ -74,13 +77,15 @@ namespace CarRepairShopDatabaseImplement.Models
Id = Id,
RepairId = RepairId,
ClientId = ClientId,
ImplementerId = ImplementerId,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement,
RepairName = Repair.RepairName,
ClientFIO = Client.ClientFIO
ClientFIO = Client.ClientFIO,
ImplementerFIO = Implementer?.ImplementerFIO ?? string.Empty
};
}
}

View File

@ -15,10 +15,12 @@ namespace CarRepairShopFileImplement
private readonly string OrderFileName = "Order.xml";
private readonly string RepairFileName = "Repair.xml";
private readonly string ClientFileName = "Client.xml";
private readonly string ImplementerFileName = "Implementer.xml";
public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; }
public List<Repair> Repairs { get; private set; }
public List<Client> Clients { get; private set; }
public List<Implementer> Implementers { get; private set; }
public static DataFileSingleton GetInstance()
{
if(instance == null)
@ -31,12 +33,14 @@ namespace CarRepairShopFileImplement
public void SaveRepairs() => SaveData(Repairs, RepairFileName, "Repairs", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
Repairs = LoadData(RepairFileName, "Repair", x => Repair.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x=> Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x=> Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x=> Implementer.Create(x)!)!;
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction)
{

View File

@ -0,0 +1,72 @@
using CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.SearchModels;
using CarRepairShopContracts.StoragesContracts;
using CarRepairShopContracts.ViewModels;
using CarRepairShopFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarRepairShopFileImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
private readonly DataFileSingleton source;
public ImplementerStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<ImplementerViewModel> GetFullList()
{
return source.Implementers.Select(x => x.GetViewModel).ToList();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO)) return new();
return source.Implementers.Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO)).Select(x => x.GetViewModel).ToList();
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO) && !model.Id.HasValue) return null;
return source.Implementers.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ImplementerFIO) && x.ImplementerFIO == model.ImplementerFIO) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
model.Id = source.Implementers.Count > 0 ? source.Implementers.Max(x => x.Id) + 1 : 1;
var newImplementer = Implementer.Create(model);
if(newImplementer == null) return null;
source.Implementers.Add(newImplementer);
source.SaveImplementers();
return newImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
var implementer = source.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (implementer == null)
{
return null;
}
implementer.Update(model);
source.SaveImplementers();
return implementer.GetViewModel;
}
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
var element = source.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
source.Implementers.Remove(element);
source.SaveImplementers();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -2,6 +2,7 @@
using CarRepairShopContracts.SearchModels;
using CarRepairShopContracts.StoragesContracts;
using CarRepairShopContracts.ViewModels;
using CarRepairShopDataModels.Enums;
using CarRepairShopFileImplement.Models;
using System;
using System.Collections.Generic;
@ -28,7 +29,7 @@ namespace CarRepairShopFileImplement.Implements
{
return new();
}
return source.Orders.Where(x => x.Id == model.Id || model.DateFrom <= x.DateCreate && x.DateCreate <= model.DateTo || x.ClientId == model.ClientId).Select(x => GetFullOrder(x.GetViewModel)).ToList();
return source.Orders.Where(x => x.Id == model.Id || model.DateFrom <= x.DateCreate && x.DateCreate <= model.DateTo || x.ClientId == model.ClientId || model.Status.Equals(x.Status)).Select(x => GetFullOrder(x.GetViewModel)).ToList();
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
@ -36,7 +37,7 @@ namespace CarRepairShopFileImplement.Implements
{
return null;
}
return GetFullOrder(source.Orders.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id).GetViewModel);
return GetFullOrder(source.Orders.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id || (x.ImplementerId == model.ImplementerId && x.Status == model.Status)).GetViewModel);
}
public OrderViewModel? Insert(OrderBindingModel model)
{

View File

@ -0,0 +1,77 @@
using CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.ViewModels;
using CarRepairShopDataModels.Models;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace CarRepairShopFileImplement.Models
{
public class Implementer : IImplementerModel
{
public int Id { get; private set; }
public string ImplementerFIO { get; private set; } = string.Empty;
public string Password { get; private set; } = string.Empty;
public int WorkExperience { get; private set; }
public int Qualification { get; private set; }
public static Implementer? Create(ImplementerBindingModel model)
{
if(model == null) return null;
return new Implementer()
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification
};
}
public static Implementer? Create(XElement element)
{
if (element == null) return null;
return new Implementer()
{
Id = Convert.ToInt32(element.Attribute("id")!.Value),
ImplementerFIO = element.Element("ImplementerFIO")!.Value,
Password = element.Element("Password")!.Value,
WorkExperience = Convert.ToInt32(element.Element("WorkExperience")!.Value),
Qualification = Convert.ToInt32(element.Element("Qualification")!.Value),
};
}
public void Update(ImplementerBindingModel model)
{
if (model == null) return;
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification
};
public XElement GetXElement => new("Implementer",
new XAttribute("Id", Id),
new XElement("ImplementerFIO", ImplementerFIO),
new XElement("Password", Password),
new XElement("WorkExperience", WorkExperience),
new XElement("Qualification", Qualification));
}
}

View File

@ -16,7 +16,7 @@ namespace CarRepairShopFileImplement.Models
public int Id { get; private set; }
public int RepairId { get; private set; }
public int ClientId { get; private set; }
public int ImplementerId { get; set; }
public int? ImplementerId { get; set; }
public int Count { get; private set; }
public double Sum { get; private set; }
public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен;

View File

@ -9,6 +9,7 @@ namespace CarRepairShopListImplement
public List<Repair> Repairs { get; set; }
public List<Order> Orders { get; set; }
public List<Client> Clients { get; set; }
public List<Implementer> Implementers { get; set; }
private DataListSingleton()
{
@ -16,6 +17,7 @@ namespace CarRepairShopListImplement
Repairs = new List<Repair>();
Orders = new List<Order>();
Clients = new List<Client>();
Implementers = new List<Implementer>();
}
public static DataListSingleton GetInstance()

View File

@ -0,0 +1,101 @@
using CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.SearchModels;
using CarRepairShopContracts.StoragesContracts;
using CarRepairShopContracts.ViewModels;
using CarRepairShopListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace CarRepairShopListImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
private readonly DataListSingleton _source;
public ImplementerStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<ImplementerViewModel> GetFullList()
{
var result = new List<ImplementerViewModel>();
foreach(var implementer in _source.Implementers)
{
result.Add(implementer.GetViewModel);
}
return result;
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
var result = new List<ImplementerViewModel>();
if (string.IsNullOrEmpty(model.ImplementerFIO)) return result;
var implementer = GetElement(model);
if(implementer == null) return result;
result.Add(implementer);
return result;
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO) && !model.Id.HasValue) return null;
foreach(var implementer in _source.Implementers)
{
if ((!string.IsNullOrEmpty(model.ImplementerFIO) && implementer.ImplementerFIO == model.ImplementerFIO) || (model.Id.HasValue && implementer.Id == model.Id))
{
return implementer.GetViewModel;
}
}
return null;
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
model.Id = 1;
foreach(var implementer in _source.Implementers)
{
if(model.Id <= implementer.Id)
{
model.Id = implementer.Id + 1;
}
}
var newImplementer = Implementer.Create(model);
if(newImplementer == null) return null;
_source.Implementers.Add(newImplementer);
return newImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
foreach (var implementer in _source.Implementers)
{
if (implementer.Id == model.Id)
{
implementer.Update(model);
return implementer.GetViewModel;
}
}
return null;
}
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
for (int i = 0; i < _source.Implementers.Count; i++)
{
if (_source.Implementers[i].Id == model.Id)
{
var element = _source.Implementers[i];
_source.Implementers.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
}
}

View File

@ -36,11 +36,11 @@ namespace CarRepairShopListImplement.Implements
{
return result;
}
if (model.DateFrom.HasValue && model.DateTo.HasValue)
if (model.DateFrom.HasValue && model.DateTo.HasValue || model.Status.HasValue)
{
foreach (var order in _source.Orders)
{
if (order.Id == model.Id || model.DateFrom <= order.DateCreate && order.DateCreate <= model.DateTo)
if (order.Id == model.Id || model.DateFrom <= order.DateCreate && order.DateCreate <= model.DateTo || model.Status.Equals(order.Status))
{
result.Add(order.GetViewModel);
}
@ -67,7 +67,7 @@ namespace CarRepairShopListImplement.Implements
}
foreach(var order in _source.Orders)
{
if(order.Id == model.Id)
if(order.Id == model.Id || order.ImplementerId == model.ImplementerId && order.Status == model.Status)
{
return AccessRepairStorage(order.GetViewModel);
}

View File

@ -0,0 +1,55 @@
using CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.ViewModels;
using CarRepairShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarRepairShopListImplement.Models
{
public class Implementer : IImplementerModel
{
public int Id { get; private set; }
public string ImplementerFIO { get; private set; } = string.Empty;
public string Password { get; private set; } = string.Empty;
public int WorkExperience { get; private set; }
public int Qualification { get; private set; }
public static Implementer? Create(ImplementerBindingModel? model)
{
if (model == null) return null;
return new Implementer()
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification,
};
}
public void Update(ImplementerBindingModel? model)
{
if(model == null) return;
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification,
};
}
}

View File

@ -18,7 +18,7 @@ namespace CarRepairShopListImplement.Models
public int RepairId { get; private set; }
public int ClientId { get; private set; }
public int ImplementerId { get; set; }
public int? ImplementerId { get; set; }
public int Count { get; private set; }

View File

@ -0,0 +1,106 @@
using CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.BusinessLogicsContracts;
using CarRepairShopContracts.SearchModels;
using CarRepairShopContracts.ViewModels;
using CarRepairShopDataModels.Enums;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace CarRepairShopRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ImplementerController : Controller
{
private readonly ILogger _logger;
private readonly IOrderLogic _order;
private readonly IImplementerLogic _logic;
public ImplementerController(IOrderLogic order, IImplementerLogic logic, ILogger<ImplementerController> logger)
{
_order = order;
_logic = logic;
_logger = logger;
}
[HttpGet]
public ImplementerViewModel? Login(string login, string password)
{
try
{
return _logic.ReadElement(new ImplementerSearchModel
{
ImplementerFIO = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка авторизаци");
throw;
}
}
[HttpGet]
public List<OrderViewModel>? GetNeworders()
{
try
{
return _order.ReadList(new OrderSearchModel
{
Status = OrderStatus.Принят
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения новых заказов");
throw;
}
}
[HttpGet]
public OrderViewModel? GetImplementerOrder(int implementerId)
{
try
{
return _order.ReadElement(new OrderSearchModel
{
ImplementerId = implementerId
});
}
catch(Exception ex)
{
_logger.LogError(ex, "Ошибка получения текущего заказа исполнителя");
throw;
}
}
[HttpPost]
public void TakeOrderInWork(OrderBindingModel model)
{
try
{
_order.TakeOrderInWork(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка перевода заказа №{id} в работу", model.Id);
throw;
}
}
[HttpPost]
public void FinishOrder(OrderBindingModel model)
{
try
{
_order.FinishOrder(model);
}
catch(Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа №{id}", model.Id);
throw;
}
}
}
}

View File

@ -0,0 +1,166 @@
namespace CarRepairShopView
{
partial class FormImplementer
{
/// <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()
{
textBoxFIO = new TextBox();
label1 = new Label();
label2 = new Label();
label3 = new Label();
label4 = new Label();
textBoxPassword = new TextBox();
numericUpDownWorkExpirience = new NumericUpDown();
numericUpDownQualification = new NumericUpDown();
buttonSave = new Button();
buttonClose = new Button();
((System.ComponentModel.ISupportInitialize)numericUpDownWorkExpirience).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownQualification).BeginInit();
SuspendLayout();
//
// textBoxFIO
//
textBoxFIO.Location = new Point(103, 5);
textBoxFIO.Name = "textBoxFIO";
textBoxFIO.Size = new Size(181, 23);
textBoxFIO.TabIndex = 0;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(60, 9);
label1.Name = "label1";
label1.Size = new Size(37, 15);
label1.TabIndex = 1;
label1.Text = "ФИО:";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(45, 45);
label2.Name = "label2";
label2.Size = new Size(52, 15);
label2.TabIndex = 2;
label2.Text = "Пароль:";
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(13, 85);
label3.Name = "label3";
label3.Size = new Size(84, 15);
label3.TabIndex = 3;
label3.Text = "Опыт работы:";
//
// label4
//
label4.AutoSize = true;
label4.Location = new Point(6, 128);
label4.Name = "label4";
label4.Size = new Size(91, 15);
label4.TabIndex = 4;
label4.Text = "Квалификация:";
//
// textBoxPassword
//
textBoxPassword.Location = new Point(103, 41);
textBoxPassword.Name = "textBoxPassword";
textBoxPassword.Size = new Size(181, 23);
textBoxPassword.TabIndex = 5;
//
// numericUpDownWorkExpirience
//
numericUpDownWorkExpirience.Location = new Point(103, 82);
numericUpDownWorkExpirience.Name = "numericUpDownWorkExpirience";
numericUpDownWorkExpirience.Size = new Size(122, 23);
numericUpDownWorkExpirience.TabIndex = 6;
//
// numericUpDownQualification
//
numericUpDownQualification.Location = new Point(103, 125);
numericUpDownQualification.Name = "numericUpDownQualification";
numericUpDownQualification.Size = new Size(122, 23);
numericUpDownQualification.TabIndex = 7;
//
// buttonSave
//
buttonSave.Location = new Point(220, 154);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(94, 35);
buttonSave.TabIndex = 8;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonClose
//
buttonClose.Location = new Point(120, 154);
buttonClose.Name = "buttonClose";
buttonClose.Size = new Size(94, 35);
buttonClose.TabIndex = 9;
buttonClose.Text = "Отмена";
buttonClose.UseVisualStyleBackColor = true;
buttonClose.Click += buttonClose_Click;
//
// FormImplementer
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(320, 196);
Controls.Add(buttonClose);
Controls.Add(buttonSave);
Controls.Add(numericUpDownQualification);
Controls.Add(numericUpDownWorkExpirience);
Controls.Add(textBoxPassword);
Controls.Add(label4);
Controls.Add(label3);
Controls.Add(label2);
Controls.Add(label1);
Controls.Add(textBoxFIO);
Name = "FormImplementer";
Text = "Создание исполнителя";
Load += FormImplementer_Load;
((System.ComponentModel.ISupportInitialize)numericUpDownWorkExpirience).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownQualification).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxFIO;
private Label label1;
private Label label2;
private Label label3;
private Label label4;
private TextBox textBoxPassword;
private NumericUpDown numericUpDownWorkExpirience;
private NumericUpDown numericUpDownQualification;
private Button buttonSave;
private Button buttonClose;
}
}

View File

@ -0,0 +1,103 @@
using CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.BusinessLogicsContracts;
using CarRepairShopContracts.SearchModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CarRepairShopView
{
public partial class FormImplementer : Form
{
private readonly ILogger _logger;
private readonly IImplementerLogic _logic;
private int? _id;
public int Id { set { _id = value; } }
public FormImplementer(ILogger<FormImplementer> logger, IImplementerLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormImplementer_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
try
{
_logger.LogInformation("Получение информации исполнителя");
var view = _logic.ReadElement(new ImplementerSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxFIO.Text = view.ImplementerFIO;
textBoxPassword.Text = view.Password;
numericUpDownWorkExpirience.Value = view.WorkExperience;
numericUpDownQualification.Value = view.Qualification;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения исполнителя");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxFIO.Text))
{
MessageBox.Show("Заполните пароль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxFIO.Text))
{
MessageBox.Show("Заполните ФИО", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение исполнителя");
try
{
var model = new ImplementerBindingModel
{
Id = _id ?? 0,
ImplementerFIO = textBoxFIO.Text,
Password = textBoxPassword.Text,
WorkExperience = (int)numericUpDownWorkExpirience.Value,
Qualification = (int)numericUpDownQualification.Value,
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения исполнителя");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonClose_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>

View File

@ -0,0 +1,107 @@
namespace CarRepairShopView
{
partial class FormImplementers
{
/// <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()
{
buttonRef = new Button();
buttonCreate = new Button();
dataGridView = new DataGridView();
buttonUpdate = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// buttonRef
//
buttonRef.Location = new Point(636, 115);
buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(152, 36);
buttonRef.TabIndex = 6;
buttonRef.Text = "Обновить";
buttonRef.UseVisualStyleBackColor = true;
buttonRef.Click += buttonRef_Click;
//
// buttonCreate
//
buttonCreate.Location = new Point(636, 12);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(152, 36);
buttonCreate.TabIndex = 5;
buttonCreate.Text = "Создать";
buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += buttonCreate_Click;
//
// dataGridView
//
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(618, 450);
dataGridView.TabIndex = 4;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(636, 65);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(152, 36);
buttonUpdate.TabIndex = 7;
buttonUpdate.Text = "Редактировать";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// FormImplementers
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(buttonUpdate);
Controls.Add(buttonRef);
Controls.Add(buttonCreate);
Controls.Add(dataGridView);
Name = "FormImplementers";
Text = "Исполнители";
Load += FormImplementers_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private Button buttonRef;
private Button buttonCreate;
private DataGridView dataGridView;
private Button buttonUpdate;
}
}

View File

@ -0,0 +1,84 @@
using CarRepairShopContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CarRepairShopView
{
public partial class FormImplementers : Form
{
private readonly ILogger _logger;
private readonly IImplementerLogic _logic;
public FormImplementers(ILogger<FormImplementers> logger, IImplementerLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка исполнителей");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки исполнителей");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FormImplementers_Load(object sender, EventArgs e)
{
LoadData();
}
private void buttonCreate_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementer));
if (service is FormImplementer form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementer));
if (service is FormImplementer form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void buttonRef_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -36,20 +36,20 @@
ComponentsToolStripMenuItem = new ToolStripMenuItem();
ComponentRepairsToolStripMenuItem = new ToolStripMenuItem();
OrdersToolStripMenuItem = new ToolStripMenuItem();
ClientsToolStripMenuItem = new ToolStripMenuItem();
workStartToolStripMenuItem = new ToolStripMenuItem();
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonTakeOrderInWork = new Button();
buttonOrderReady = new Button();
buttonIssuedOrder = new Button();
buttonRef = new Button();
ClientsToolStripMenuItem = new ToolStripMenuItem();
implementersToolStripMenuItem = new ToolStripMenuItem();
menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// menuStrip1
//
menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчетыToolStripMenuItem, ClientsToolStripMenuItem });
menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчетыToolStripMenuItem, ClientsToolStripMenuItem, workStartToolStripMenuItem, implementersToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Size = new Size(1059, 24);
@ -105,6 +105,20 @@
OrdersToolStripMenuItem.Text = "Список заказов";
OrdersToolStripMenuItem.Click += OrdersToolStripMenuItem_Click;
//
// ClientsToolStripMenuItem
//
ClientsToolStripMenuItem.Name = "ClientsToolStripMenuItem";
ClientsToolStripMenuItem.Size = new Size(67, 20);
ClientsToolStripMenuItem.Text = "Клиенты";
ClientsToolStripMenuItem.Click += ClientsToolStripMenuItem_Click;
//
// workStartToolStripMenuItem
//
workStartToolStripMenuItem.Name = "workStartToolStripMenuItem";
workStartToolStripMenuItem.Size = new Size(92, 20);
workStartToolStripMenuItem.Text = "Запуск работ";
workStartToolStripMenuItem.Click += workStartToolStripMenuItem_Click;
//
// dataGridView
//
dataGridView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
@ -131,32 +145,10 @@
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += buttonCreateOrder_Click;
//
// buttonTakeOrderInWork
//
buttonTakeOrderInWork.Anchor = AnchorStyles.Top | AnchorStyles.Right;
buttonTakeOrderInWork.Location = new Point(844, 108);
buttonTakeOrderInWork.Name = "buttonTakeOrderInWork";
buttonTakeOrderInWork.Size = new Size(198, 28);
buttonTakeOrderInWork.TabIndex = 3;
buttonTakeOrderInWork.Text = "Отдать на выполнение";
buttonTakeOrderInWork.UseVisualStyleBackColor = true;
buttonTakeOrderInWork.Click += buttonTakeOrderInWork_Click;
//
// buttonOrderReady
//
buttonOrderReady.Anchor = AnchorStyles.Top | AnchorStyles.Right;
buttonOrderReady.Location = new Point(844, 162);
buttonOrderReady.Name = "buttonOrderReady";
buttonOrderReady.Size = new Size(198, 28);
buttonOrderReady.TabIndex = 4;
buttonOrderReady.Text = "Заказ готов";
buttonOrderReady.UseVisualStyleBackColor = true;
buttonOrderReady.Click += buttonOrderReady_Click;
//
// buttonIssuedOrder
//
buttonIssuedOrder.Anchor = AnchorStyles.Top | AnchorStyles.Right;
buttonIssuedOrder.Location = new Point(844, 214);
buttonIssuedOrder.Location = new Point(844, 109);
buttonIssuedOrder.Name = "buttonIssuedOrder";
buttonIssuedOrder.Size = new Size(198, 28);
buttonIssuedOrder.TabIndex = 5;
@ -167,7 +159,7 @@
// buttonRef
//
buttonRef.Anchor = AnchorStyles.Top | AnchorStyles.Right;
buttonRef.Location = new Point(844, 269);
buttonRef.Location = new Point(844, 164);
buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(198, 28);
buttonRef.TabIndex = 6;
@ -175,12 +167,12 @@
buttonRef.UseVisualStyleBackColor = true;
buttonRef.Click += buttonRef_Click;
//
// ClientsToolStripMenuItem
// implementersToolStripMenuItem
//
ClientsToolStripMenuItem.Name = "ClientsToolStripMenuItem";
ClientsToolStripMenuItem.Size = new Size(67, 20);
ClientsToolStripMenuItem.Text = "Клиенты";
ClientsToolStripMenuItem.Click += ClientsToolStripMenuItem_Click;
implementersToolStripMenuItem.Name = "implementersToolStripMenuItem";
implementersToolStripMenuItem.Size = new Size(94, 20);
implementersToolStripMenuItem.Text = "Исполнители";
implementersToolStripMenuItem.Click += implementersToolStripMenuItem_Click;
//
// FormMain
//
@ -189,8 +181,6 @@
ClientSize = new Size(1059, 377);
Controls.Add(buttonRef);
Controls.Add(buttonIssuedOrder);
Controls.Add(buttonOrderReady);
Controls.Add(buttonTakeOrderInWork);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(menuStrip1);
@ -213,8 +203,6 @@
private ToolStripMenuItem изделияToolStripMenuItem;
private DataGridView dataGridView;
private Button buttonCreateOrder;
private Button buttonTakeOrderInWork;
private Button buttonOrderReady;
private Button buttonIssuedOrder;
private Button buttonRef;
private ToolStripMenuItem отчетыToolStripMenuItem;
@ -222,5 +210,7 @@
private ToolStripMenuItem ComponentRepairsToolStripMenuItem;
private ToolStripMenuItem OrdersToolStripMenuItem;
private ToolStripMenuItem ClientsToolStripMenuItem;
private ToolStripMenuItem workStartToolStripMenuItem;
private ToolStripMenuItem implementersToolStripMenuItem;
}
}

View File

@ -19,12 +19,14 @@ namespace CarRepairShopView
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic)
private readonly IWorkProcess _workProcess;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
_workProcess = workProcess;
}
private void FormMain_Load(object sender, EventArgs e)
@ -40,6 +42,7 @@ namespace CarRepairShopView
{
dataGridView.DataSource = _list;
dataGridView.Columns["RepairId"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
}
}
@ -195,5 +198,20 @@ namespace CarRepairShopView
form.ShowDialog();
}
}
private void workStartToolStripMenuItem_Click(object sender, EventArgs e)
{
_workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void implementersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if(service is FormImplementers form)
{
form.ShowDialog();
}
}
}
}

View File

@ -51,6 +51,7 @@ namespace CarRepairShopView
services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IWorkProcess, WorkModeling>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();
@ -66,6 +67,8 @@ namespace CarRepairShopView
services.AddTransient<FormReportRepairComponents>();
services.AddTransient<FormReportOrders>();
services.AddTransient<FormClients>();
services.AddTransient<FormImplementer>();
services.AddTransient<FormImplementers>();
}
}
}