PIbd-21_MasenkinMS_LabWork06_Hard #12

Closed
Factorino73 wants to merge 3 commits from LabWork06_Hard into LabWork05_Hard
46 changed files with 3359 additions and 109 deletions

View File

@ -0,0 +1,177 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.BusinessLogicsContracts;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantBusinessLogic.BusinessLogics
{
/// <summary>
/// Реализация интерфейса бизнес-логики для исполнителей
/// </summary>
public class ImplementerLogic : IImplementerLogic
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Взаимодействие с хранилищем исполнителей
/// </summary>
private readonly IImplementerStorage _implementerStorage;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="implemeneterStorage"></param>
public ImplementerLogic(ILogger<ImplementerLogic> logger, IImplementerStorage implementerStorage)
{
_logger = logger;
_implementerStorage = implementerStorage;
}
/// <summary>
/// Получение списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model)
{
_logger.LogInformation("ReadList. ImplementerFIO:{ImplementerFIO}.Id:{Id}", model?.ImplementerFIO, model?.Id);
var list = model == null ? _implementerStorage.GetFullList() : _implementerStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
/// <summary>
/// Получение отдельной записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public ImplementerViewModel? ReadElement(ImplementerSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ImplementerFIO:{ImplementerFIO}.Id:{Id}", model.ImplementerFIO, model.Id);
var element = _implementerStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
/// <summary>
/// Создание записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Create(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
/// <summary>
/// Изменение записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Update(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
/// <summary>
/// Удаление записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Delete(ImplementerBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_implementerStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ImplementerBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
throw new ArgumentNullException("У исполнителя должно быть ФИО", nameof(model.ImplementerFIO));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("У исполнителя должен быть пароль", nameof(model.Password));
}
if (model.WorkExperience <= 0)
{
throw new ArgumentNullException("У исполнителя стаж должен быть больше 0", nameof(model.WorkExperience));
}
if (model.Qualification <= 0)
{
throw new ArgumentNullException("У исполнителя квалификация должна быть больше 0", nameof(model.Qualification));
}
_logger.LogInformation("Implementer. ImplementerFIO:{ImplementerFIO}.Qualification:{Qualification}.WorkExperience:{WorkExperience} Id: {Id}", model.ImplementerFIO, model.Qualification, model.WorkExperience, model.Id);
var element = _implementerStorage.GetElement(new ImplementerSearchModel
{
ImplementerFIO = model.ImplementerFIO
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Исполнитель с таким ФИО уже есть");
}
}
}
}

View File

@ -78,6 +78,31 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
return list;
}
/// <summary>
/// Получение отдельной записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public OrderViewModel? ReadElement(OrderSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id:{ Id}", model.Id);
var element = _orderStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
/// <summary>
/// Создание заказа
/// </summary>
@ -178,7 +203,7 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
{
throw new ArgumentNullException(nameof(model));
}
if (element.Status + 1 != newStatus)
if (element.Status + 1 != newStatus && element.Status != OrderStatus.Ожидание)
{
_logger.LogWarning("Change status operation failed");
return false;
@ -186,7 +211,7 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
model.Status = newStatus;
if (newStatus == OrderStatus.Выдан)
if (model.Status == OrderStatus.Готов || element.Status == OrderStatus.Ожидание)
{
var plane = _planeStorage.GetElement(new PlaneSearchModel { Id = element.PlaneId });
if (plane == null)
@ -194,21 +219,22 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
_logger.LogWarning("Status change error. Plane not found");
return false;
}
if (!CheckSupply(plane, element.Count))
{
model.Status = OrderStatus.Ожидание;
_logger.LogWarning("Status change error. Shop is overflowed");
return false;
}
}
if (model.Status == OrderStatus.Выдан)
{
model.DateImplement = DateTime.Now;
else
{
model.DateImplement = DateTime.Now;
}
}
else
{
model.DateImplement = element.DateImplement;
}
CheckModel(model, false);
if (_orderStorage.Update(model) == null)
{

View File

@ -0,0 +1,232 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.BusinessLogicsContracts;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Enums;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantBusinessLogic.BusinessLogics
{
/// <summary>
/// Реализация интерфейса бизнес-логики для имитации деятельности исполнителей
/// </summary>
public class WorkModeling : IWorkProcess
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Рандом
/// </summary>
private readonly Random _rnd;
private readonly object orderLock = new object();
private readonly object waitingOrderLock = new object();
/// <summary>
/// Бизнес-логика для заказов
/// </summary>
private IOrderLogic? _orderLogic;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
public WorkModeling(ILogger<WorkModeling> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
/// <summary>
/// Имитация рабочего процесса
/// </summary>
/// <param name="implementerLogic"></param>
/// <param name="orderLogic"></param>
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if (implementers == null)
{
_logger.LogWarning("DoWork. Implementers is null");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Принят });
_logger.LogDebug("DoWork for {Count} orders", orders?.Count);
foreach (var implementer in implementers)
{
Task.Run(() => WorkerWorkAsync(implementer, orders));
}
}
/// <summary>
/// Имитация работы исполнителя
/// </summary>
/// <param name="implementer"></param>
/// <param name="orders"></param>
private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel> orders)
{
if (_orderLogic == null || implementer == null)
{
return;
}
// Выполняем заказы в статусе "Ожидание"
await RunOrderInWaiting(implementer);
// Выполняем заказы в статусе "Выполняется"
await RunOrderInWork(implementer);
await Task.Run(() =>
{
foreach (var order in orders)
{
try
{
_logger.LogDebug("DoWork. Worker {Id} try get order {Order}", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя
lock (orderLock)
{
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = order.Id,
ImplementerId = implementer.Id
});
}
// делаем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = order.Id
});
}
// кто-то мог уже перехватить заказ, игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// заканчиваем выполнение имитации в случае иной ошибки
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
});
}
/// <summary>
/// Ищем заказ, которые уже в работе (вдруг исполнителя прервали)
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
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. Worker {Id} back to order {Order}", implementer.Id, runOrder.Id);
// доделываем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, runOrder.Id);
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = runOrder.Id
});
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
// заказа может не быть, просто игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
/// <summary>
/// Ищем заказ, которые в ожидании
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
private async Task RunOrderInWaiting(ImplementerViewModel implementer)
{
if (_orderLogic == null || implementer == null)
{
return;
}
try
{
var orders = await Task.Run(() => _orderLogic.ReadList(new OrderSearchModel
{
ImplementerId = implementer.Id,
Status = OrderStatus.Ожидание
}));
if (orders == null)
{
return;
}
// доделываем работу
foreach (var order in orders)
{
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
lock (waitingOrderLock)
{
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = order.Id
});
}
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
}
// заказа может не быть, просто игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
}
}

View File

@ -0,0 +1,41 @@
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.BindingModels
{
/// <summary>
/// Модель для передачи данных пользователя
/// в методы для сохранения данных для исполнителей
/// </summary>
public class ImplementerBindingModel : IImplementerModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// ФИО исполнителя
/// </summary>
public string ImplementerFIO { get; set; } = string.Empty;
/// <summary>
/// Пароль
/// </summary>
public string Password { get; set; } = string.Empty;
/// <summary>
/// Опыт работы
/// </summary>
public int WorkExperience { get; set; }
/// <summary>
/// Квалификация
/// </summary>
public int Qualification { get; set; }
}
}

View File

@ -29,6 +29,11 @@ namespace AircraftPlantContracts.BindingModels
/// </summary>
public int ClientId { get; set; }
/// <summary>
/// Идентификатор исполнителя
/// </summary>
public int? ImplementerId { get; set; }
/// <summary>
/// Количество изделий
/// </summary>

View File

@ -0,0 +1,52 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.BusinessLogicsContracts
{
/// <summary>
/// Интерфейс для описания работы бизнес-логики для исполнителей
/// </summary>
public interface IImplementerLogic
{
/// <summary>
/// Получение списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model);
/// <summary>
/// Получение отдельной записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
ImplementerViewModel? ReadElement(ImplementerSearchModel? model);
/// <summary>
/// Создание записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Create(ImplementerBindingModel? model);
/// <summary>
/// Изменение записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Update(ImplementerBindingModel? model);
/// <summary>
/// Удаление записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Delete(ImplementerBindingModel? model);
}
}

View File

@ -21,6 +21,13 @@ namespace AircraftPlantContracts.BusinessLogicsContracts
/// <returns></returns>
List<OrderViewModel>? ReadList(OrderSearchModel? model);
/// <summary>
/// Получение отдельной записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderViewModel? ReadElement(OrderSearchModel model);
/// <summary>
/// Создание заказа
/// </summary>

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.BusinessLogicsContracts
{
/// <summary>
/// Интерфейс для описания работы бизнес-логики для имитации деятельности исполнителя
/// </summary>
public interface IWorkProcess
{
/// <summary>
/// Запуск работ
/// </summary>
void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic);
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.SearchModels
{
/// <summary>
/// Модель для передачи данных пользователя
/// в методы для поиска данных для исполнителей
/// </summary>
public class ImplementerSearchModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int? Id { get; set; }
/// <summary>
/// ФИО исполнителя
/// </summary>
public string? ImplementerFIO { get; set; }
/// <summary>
/// Пароль
/// </summary>
public string? Password { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using System;
using AircraftPlantDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -22,6 +23,16 @@ namespace AircraftPlantContracts.SearchModels
/// </summary>
public int? ClientId { get; set; }
/// <summary>
/// Идентификатор исполнителя
/// </summary>
public int? ImplementerId { get; set; }
/// <summary>
/// Статус выполнения заказа
/// </summary>
public OrderStatus? Status { get; set; }
/// <summary>
/// Начало периода выборки данных
/// </summary>

View File

@ -0,0 +1,58 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.StoragesContracts
{
/// <summary>
/// Интерфейс для описания работы с хранилищем для исполнителей
/// </summary>
public interface IImplementerStorage
{
/// <summary>
/// Получение полного списка
/// </summary>
/// <returns></returns>
List<ImplementerViewModel> GetFullList();
/// <summary>
/// Получение фильтрованного списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model);
/// <summary>
/// Получение элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
ImplementerViewModel? GetElement(ImplementerSearchModel model);
/// <summary>
/// Добавление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
ImplementerViewModel? Insert(ImplementerBindingModel model);
/// <summary>
/// Редактирование элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
ImplementerViewModel? Update(ImplementerBindingModel model);
/// <summary>
/// Удаление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
ImplementerViewModel? Delete(ImplementerBindingModel model);
}
}

View File

@ -0,0 +1,46 @@
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.ViewModels
{
/// <summary>
/// Модель для передачи данных пользователю
/// для отображения для исполнителей
/// </summary>
public class ImplementerViewModel : IImplementerModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// ФИО исполнителя
/// </summary>
[DisplayName("ФИО исполнителя")]
public string ImplementerFIO { get; set; } = string.Empty;
/// <summary>
/// Пароль
/// </summary>
[DisplayName("Пароль")]
public string Password { get; set; } = string.Empty;
/// <summary>
/// Опыт работы
/// </summary>
[DisplayName("Опыт работы")]
public int WorkExperience { get; set; }
/// <summary>
/// Квалификация
/// </summary>
[DisplayName("Квалификация")]
public int Qualification { get; set; }
}
}

View File

@ -43,6 +43,17 @@ namespace AircraftPlantContracts.ViewModels
[DisplayName("ФИО клиента")]
public string ClientFIO { get; set; } = string.Empty;
/// <summary>
/// Идентификатор исполнителя
/// </summary>
public int? ImplementerId { get; set; }
/// <summary>
/// ФИО клиента
/// </summary>
[DisplayName("ФИО исполнителя")]
public string ImplementerFIO { get; set; } = string.Empty;
/// <summary>
/// Количество изделий
/// </summary>

View File

@ -19,6 +19,8 @@ namespace AircraftPlantDataModels.Enums
Готов = 2,
Выдан = 3
Выдан = 3,
Ожидание = 4
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantDataModels.Models
{
/// <summary>
/// Интерфейс для модели исполнителя
/// </summary>
public interface IImplementerModel : IId
{
/// <summary>
/// ФИО исполнителя
/// </summary>
string ImplementerFIO { get; }
/// <summary>
/// Пароль
/// </summary>
string Password { get; }
/// <summary>
/// Опыт работы
/// </summary>
int WorkExperience { get; }
/// <summary>
/// Квалификация
/// </summary>
int Qualification { get; }
}
}

View File

@ -22,6 +22,11 @@ namespace AircraftPlantDataModels.Models
/// </summary>
int ClientId { get; }
/// <summary>
/// Идентификатор исполнителя
/// </summary>
int? ImplementerId { get; }
/// <summary>
/// Количество изделий
/// </summary>

View File

@ -60,5 +60,10 @@ namespace AircraftPlantDatabaseImplement
/// Таблица клиентов
/// </summary>
public virtual DbSet<Client> Clients { set; get; }
/// <summary>
/// Таблица исполнителей
/// </summary>
public virtual DbSet<Implementer> Implementers { set; get; }
}
}

View File

@ -0,0 +1,136 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantDatabaseImplement.Implements
{
/// <summary>
/// Реализация интерфейса хранилища для исполнителей
/// </summary>
public class ImplementerStorage : IImplementerStorage
{
/// <summary>
/// Получение полного списка
/// </summary>
/// <returns></returns>
public List<ImplementerViewModel> GetFullList()
{
using var context = new AircraftPlantDatabase();
return context.Implementers
.Include(x => x.Orders)
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получение фильтрованного списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
return new();
}
using var context = new AircraftPlantDatabase();
return context.Implementers
.Include(x => x.Orders)
.Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO))
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получение элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
using var context = new AircraftPlantDatabase();
if (model.Id.HasValue)
return context.Implementers
.Include(x => x.Orders)
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?
.GetViewModel;
else if (!string.IsNullOrEmpty(model.ImplementerFIO) && !string.IsNullOrEmpty(model.Password))
return context.Implementers.Include(x => x.Orders)
.FirstOrDefault(x => x.ImplementerFIO == model.ImplementerFIO && x.Password == model.Password)?
.GetViewModel;
else if (!string.IsNullOrEmpty(model.ImplementerFIO))
return context.Implementers.Include(x => x.Orders)
.FirstOrDefault(x => x.ImplementerFIO == model.ImplementerFIO)?
.GetViewModel;
return null;
}
/// <summary>
/// Добавление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
var newImplementer = Implementer.Create(model);
if (newImplementer == null)
{
return null;
}
using var context = new AircraftPlantDatabase();
context.Implementers.Add(newImplementer);
context.SaveChanges();
return newImplementer.GetViewModel;
}
/// <summary>
/// Редактирование элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
using var context = new AircraftPlantDatabase();
var implementer = context.Implementers.Include(x => x.Orders).FirstOrDefault(x => x.Id == model.Id);
if (implementer == null)
{
return null;
}
implementer.Update(model);
context.SaveChanges();
return implementer.GetViewModel;
}
/// <summary>
/// Удаление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
using var context = new AircraftPlantDatabase();
var element = context.Implementers.Include(x => x.Orders).FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
context.Implementers.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -27,6 +27,7 @@ namespace AircraftPlantDatabaseImplement.Implements
return context.Orders
.Include(x => x.Plane)
.Include(x => x.Client)
.Include(x => x.Implementer)
.Select(x => x.GetViewModel)
.ToList();
}
@ -38,7 +39,7 @@ namespace AircraftPlantDatabaseImplement.Implements
/// <returns></returns>
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue && !model.ClientId.HasValue && (!model.DateFrom.HasValue || !model.DateTo.HasValue))
if (!model.Id.HasValue && !model.ClientId.HasValue && (!model.DateFrom.HasValue || !model.DateTo.HasValue) && model.Status == null)
{
return new();
}
@ -50,6 +51,7 @@ namespace AircraftPlantDatabaseImplement.Implements
return context.Orders
.Include(x => x.Plane)
.Include(x => x.Client)
.Include(x => x.Implementer)
.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => x.GetViewModel)
.ToList();
@ -60,11 +62,23 @@ namespace AircraftPlantDatabaseImplement.Implements
return context.Orders
.Include(x => x.Plane)
.Include(x => x.Client)
.Include(x => x.Implementer)
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
if (model.Status.HasValue)
{
return context.Orders
.Include(x => x.Plane)
.Include(x => x.Client)
.Include(x => x.Implementer)
.Where(x => x.Status == model.Status)
.Select(x => x.GetViewModel)
.ToList();
}
return context.Orders
.Include(x => x.Plane)
.Include(x => x.Client)
@ -86,11 +100,37 @@ namespace AircraftPlantDatabaseImplement.Implements
}
using var context = new AircraftPlantDatabase();
return context.Orders
.Include(x => x.Plane)
.Include(x => x.Client)
.FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?
.GetViewModel;
if (model.Id.HasValue)
{
return context.Orders
.Include(x => x.Plane)
.Include(x => x.Client)
.Include(x => x.Implementer)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel;
}
if (model.ImplementerId.HasValue && model.Status.HasValue)
{
return context.Orders
.Include(x => x.Plane)
.Include(x => x.Client)
.Include(x => x.Implementer)
.FirstOrDefault(x => x.ImplementerId == model.ImplementerId && x.Status == model.Status)
?.GetViewModel;
}
if (model.ImplementerId.HasValue)
{
return context.Orders
.Include(x => x.Plane)
.Include(x => x.Client)
.Include(x => x.Implementer)
.FirstOrDefault(x => x.ImplementerId == model.ImplementerId)
?.GetViewModel;
}
return null;
}
/// <summary>

View File

@ -0,0 +1,260 @@
// <auto-generated />
using System;
using AircraftPlantDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace AircraftPlantDatabaseImplement.Migrations
{
[DbContext(typeof(AircraftPlantDatabase))]
[Migration("20240419180448_AddImplementers")]
partial class AddImplementers
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.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("AircraftPlantDatabaseImplement.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("AircraftPlantDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.IsRequired()
.HasColumnType("int");
b.Property<int>("PlaneId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("PlaneId");
b.ToTable("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Plane", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("PlaneName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Planes");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.PlaneComponent", 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>("PlaneId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("PlaneId");
b.ToTable("PlaneComponents");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Order", b =>
{
b.HasOne("AircraftPlantDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AircraftPlantDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
.WithMany("Orders")
.HasForeignKey("PlaneId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Plane");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.PlaneComponent", b =>
{
b.HasOne("AircraftPlantDatabaseImplement.Models.Component", "Component")
.WithMany("PlaneComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
.WithMany("Components")
.HasForeignKey("PlaneId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Plane");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Component", b =>
{
b.Navigation("PlaneComponents");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Plane", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,69 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AircraftPlantDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class AddImplementers : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ImplementerId",
table: "Orders",
type: "int",
nullable: false,
defaultValue: 0);
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.CreateIndex(
name: "IX_Orders_ImplementerId",
table: "Orders",
column: "ImplementerId");
migrationBuilder.AddForeignKey(
name: "FK_Orders_Implementers_ImplementerId",
table: "Orders",
column: "ImplementerId",
principalTable: "Implementers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
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");
}
}
}

View File

@ -0,0 +1,257 @@
// <auto-generated />
using System;
using AircraftPlantDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace AircraftPlantDatabaseImplement.Migrations
{
[DbContext(typeof(AircraftPlantDatabase))]
[Migration("20240420181402_FixImplementers")]
partial class FixImplementers
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.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("AircraftPlantDatabaseImplement.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("AircraftPlantDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("PlaneId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("PlaneId");
b.ToTable("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Plane", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("PlaneName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Planes");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.PlaneComponent", 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>("PlaneId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("PlaneId");
b.ToTable("PlaneComponents");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Order", b =>
{
b.HasOne("AircraftPlantDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AircraftPlantDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
.WithMany("Orders")
.HasForeignKey("PlaneId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Plane");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.PlaneComponent", b =>
{
b.HasOne("AircraftPlantDatabaseImplement.Models.Component", "Component")
.WithMany("PlaneComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
.WithMany("Components")
.HasForeignKey("PlaneId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Plane");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Component", b =>
{
b.Navigation("PlaneComponents");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Plane", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,59 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AircraftPlantDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class FixImplementers : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Orders_Implementers_ImplementerId",
table: "Orders");
migrationBuilder.AlterColumn<int>(
name: "ImplementerId",
table: "Orders",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AddForeignKey(
name: "FK_Orders_Implementers_ImplementerId",
table: "Orders",
column: "ImplementerId",
principalTable: "Implementers",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Orders_Implementers_ImplementerId",
table: "Orders");
migrationBuilder.AlterColumn<int>(
name: "ImplementerId",
table: "Orders",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_Orders_Implementers_ImplementerId",
table: "Orders",
column: "ImplementerId",
principalTable: "Implementers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -67,6 +67,33 @@ namespace AircraftPlantDatabaseImplement.Migrations
b.ToTable("Components");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.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("AircraftPlantDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@ -87,6 +114,9 @@ namespace AircraftPlantDatabaseImplement.Migrations
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("PlaneId")
.HasColumnType("int");
@ -100,6 +130,8 @@ namespace AircraftPlantDatabaseImplement.Migrations
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("PlaneId");
b.ToTable("Orders");
@ -212,6 +244,10 @@ namespace AircraftPlantDatabaseImplement.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AircraftPlantDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
.WithMany("Orders")
.HasForeignKey("PlaneId")
@ -220,6 +256,8 @@ namespace AircraftPlantDatabaseImplement.Migrations
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Plane");
});
@ -271,6 +309,11 @@ namespace AircraftPlantDatabaseImplement.Migrations
b.Navigation("PlaneComponents");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Plane", b =>
{
b.Navigation("Components");

View File

@ -0,0 +1,105 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantDatabaseImplement.Models
{
/// <summary>
/// Сущность "Исполнитель"
/// </summary>
public class Implementer : IImplementerModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; private set; }
/// <summary>
/// ФИО исполнителя
/// </summary>
[Required]
public string ImplementerFIO { get; private set; } = string.Empty;
/// <summary>
/// Пароль
/// </summary>
[Required]
public string Password { get; private set; } = string.Empty;
/// <summary>
/// Опыт работы
/// </summary>
[Required]
public int WorkExperience { get; private set; }
/// <summary>
/// Квалификация
/// </summary>
[Required]
public int Qualification { get; private set; }
/// <summary>
/// Связь с заказами
/// </summary>
[ForeignKey("ImplementerId")]
public virtual List<Order> Orders { get; set; } = new();
/// <summary>
/// Создание модели исполнителя
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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
};
}
/// <summary>
/// Изменение модели исполнителя
/// </summary>
/// <param name="model"></param>
public void Update(ImplementerBindingModel model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
/// <summary>
/// Получение модели исполнителя
/// </summary>
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification,
};
}
}

View File

@ -43,6 +43,16 @@ namespace AircraftPlantDatabaseImplement.Models
/// </summary>
public Client Client { get; set; } = new();
/// <summary>
/// Идентификатор исполнителя
/// </summary>
public int? ImplementerId { get; set; }
/// <summary>
/// Сущность "Исполнитель"
/// </summary>
public virtual Implementer? Implementer { get; set; } = new();
/// <summary>
/// Количество изделий
/// </summary>
@ -91,6 +101,8 @@ namespace AircraftPlantDatabaseImplement.Models
Plane = context.Planes.First(x => x.Id == model.PlaneId),
ClientId = model.ClientId,
Client = context.Clients.First(x => x.Id == model.ClientId),
ImplementerId = model.ImplementerId,
Implementer = model.ImplementerId.HasValue ? context.Implementers.First(x => x.Id == model.ImplementerId) : null,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
@ -112,6 +124,8 @@ namespace AircraftPlantDatabaseImplement.Models
Status = model.Status;
DateImplement = model.DateImplement;
if (model.ImplementerId.HasValue)
ImplementerId = model.ImplementerId;
}
/// <summary>
@ -124,6 +138,8 @@ namespace AircraftPlantDatabaseImplement.Models
PlaneName = Plane.PlaneName,
ClientId = ClientId,
ClientFIO = Client.ClientFIO,
ImplementerId = ImplementerId,
ImplementerFIO = Implementer?.ImplementerFIO ?? string.Empty,
Count = Count,
Sum = Sum,
Status = Status,

View File

@ -43,6 +43,11 @@ namespace AircraftPlantFileImplement
/// </summary>
private readonly string ShopFileName = "Shop.xml";
/// <summary>
/// Название файла для хранения информации о исполнителях
/// </summary>
private readonly string ImplementerFileName = "Implementer.xml";
/// <summary>
/// Список классов-моделей компонентов
/// </summary>
@ -68,6 +73,11 @@ namespace AircraftPlantFileImplement
/// </summary>
public List<Client> Clients { get; set; }
/// <summary>
/// Список классов-моделей исполнителей
/// </summary>
public List<Implementer> Implementers { get; set; }
/// <summary>
/// Конструктор
/// </summary>
@ -78,6 +88,7 @@ namespace AircraftPlantFileImplement
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Shops = LoadData(ShopFileName, "Shop", x => Shop.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
}
/// <summary>
@ -118,6 +129,11 @@ namespace AircraftPlantFileImplement
/// </summary>
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
/// <summary>
/// Сохранение исполнителей
/// </summary>
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
/// <summary>
/// Метод для загрузки данных из xml-файла
/// </summary>

View File

@ -0,0 +1,137 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using AircraftPlantFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantFileImplement.Implements
{
/// <summary>
/// Реализация интерфейса хранилища для исполнителей
/// </summary>
public class ImplementerStorage : IImplementerStorage
{
/// <summary>
/// Хранилище
/// </summary>
private readonly DataFileSingleton _source;
/// <summary>
/// Конструктор
/// </summary>
public ImplementerStorage()
{
_source = DataFileSingleton.GetInstance();
}
/// <summary>
/// Получение полного списка
/// </summary>
/// <returns></returns>
public List<ImplementerViewModel> GetFullList()
{
return _source.Implementers
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получение фильтрованного списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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();
}
/// <summary>
/// Получение элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (!string.IsNullOrEmpty(model.ImplementerFIO) || model.Id.HasValue)
{
return _source.Implementers.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.ImplementerFIO) && x.ImplementerFIO == model.ImplementerFIO) ||
(model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
else if (!string.IsNullOrEmpty(model.ImplementerFIO) && !string.IsNullOrEmpty(model.Password))
return _source.Implementers.FirstOrDefault(x =>
x.ImplementerFIO == model.ImplementerFIO && x.Password == model.Password)?.GetViewModel;
return null;
}
/// <summary>
/// Добавление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Редактирование элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Удаление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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

@ -0,0 +1,126 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace AircraftPlantFileImplement.Models
{
/// <summary>
/// Сущность "Исполнитель"
/// </summary>
public class Implementer : IImplementerModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; private set; }
/// <summary>
/// ФИО исполнителя
/// </summary>
public string ImplementerFIO { get; private set; } = string.Empty;
/// <summary>
/// Пароль
/// </summary>
public string Password { get; private set; } = string.Empty;
/// <summary>
/// Опыт работы
/// </summary>
public int WorkExperience { get; private set; }
/// <summary>
/// Квалификация
/// </summary>
public int Qualification { get; private set; }
/// <summary>
/// Создание модели исполнителя
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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,
};
}
/// <summary>
/// Создание модели исполнителя из данных файла
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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)
};
}
/// <summary>
/// Изменение модели исполнителя
/// </summary>
/// <param name="model"></param>
public void Update(ImplementerBindingModel? model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
/// <summary>
/// Получение модели исполнителя
/// </summary>
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification
};
/// <summary>
/// Запись данных о модели исполнителя в файл
/// </summary>
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

@ -31,6 +31,11 @@ namespace AircraftPlantFileImplement.Models
/// </summary>
public int ClientId { get; private set; }
/// <summary>
/// Идентификатор исполнителя
/// </summary>
public int? ImplementerId { get; private set; }
/// <summary>
/// Количество изделий
/// </summary>
@ -73,6 +78,7 @@ namespace AircraftPlantFileImplement.Models
Id = model.Id,
PlaneId = model.PlaneId,
ClientId = model.ClientId,
ImplementerId = model.ImplementerId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
@ -98,6 +104,7 @@ namespace AircraftPlantFileImplement.Models
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
PlaneId = Convert.ToInt32(element.Element("PlaneId")!.Value),
ClientId = Convert.ToInt32(element.Element("ClientId")!.Value),
ImplementerId = Convert.ToInt32(element.Element("ImplementerId")!.Value),
Sum = Convert.ToDouble(element.Element("Sum")!.Value),
Count = Convert.ToInt32(element.Element("Count")!.Value),
Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value),
@ -119,6 +126,8 @@ namespace AircraftPlantFileImplement.Models
Status = model.Status;
DateImplement = model.DateImplement;
if (model.ImplementerId.HasValue)
ImplementerId = model.ImplementerId;
}
/// <summary>
@ -129,6 +138,7 @@ namespace AircraftPlantFileImplement.Models
Id = Id,
PlaneId = PlaneId,
ClientId = ClientId,
ImplementerId = ImplementerId,
Count = Count,
Sum = Sum,
Status = Status,
@ -143,6 +153,7 @@ namespace AircraftPlantFileImplement.Models
new XAttribute("Id", Id),
new XElement("PlaneId", PlaneId),
new XElement("ClientId", ClientId),
new XElement("ImplementerId", ImplementerId),
new XElement("Count", Count.ToString()),
new XElement("Sum", Sum.ToString()),
new XElement("Status", Status.ToString()),

View File

@ -42,6 +42,11 @@ namespace AircraftPlantListImplement
/// </summary>
public List<Client> Clients { get; set; }
/// <summary>
/// Список классов-моделей исполнителей
/// </summary>
public List<Implementer> Implementers { get; set; }
/// <summary>
/// Конструктор
/// </summary>
@ -52,6 +57,7 @@ namespace AircraftPlantListImplement
Planes = new List<Plane>();
Shops = new List<Shop>();
Clients = new List<Client>();
Implementers = new List<Implementer>();
}
/// <summary>

View File

@ -0,0 +1,157 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using AircraftPlantListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantListImplement.Implements
{
/// <summary>
/// Реализация интерфейса хранилища для исполнителей
/// </summary>
public class ImplementerStorage : IImplementerStorage
{
/// <summary>
/// Хранилище
/// </summary>
private readonly DataListSingleton _source;
/// <summary>
/// Конструктор
/// </summary>
public ImplementerStorage()
{
_source = DataListSingleton.GetInstance();
}
/// <summary>
/// Получение полного списка
/// </summary>
/// <returns></returns>
public List<ImplementerViewModel> GetFullList()
{
var result = new List<ImplementerViewModel>();
foreach (var implementer in _source.Implementers)
{
result.Add(implementer.GetViewModel);
}
return result;
}
/// <summary>
/// Получение фильтрованного списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
var result = new List<ImplementerViewModel>();
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
return result;
}
foreach (var implementer in _source.Implementers)
{
if (implementer.ImplementerFIO.Contains(model.ImplementerFIO))
{
result.Add(implementer.GetViewModel);
}
}
return result;
}
/// <summary>
/// Получение элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO) && string.IsNullOrEmpty(model.Password) && !model.Id.HasValue)
{
return null;
}
foreach (var implementer in _source.Implementers)
{
if (model.Id.HasValue && model.Id == implementer.Id)
return implementer.GetViewModel;
if (!string.IsNullOrEmpty(model.ImplementerFIO) && !string.IsNullOrEmpty(model.Password) &&
implementer.ImplementerFIO.Equals(model.ImplementerFIO) && implementer.Password.Equals(model.Password))
return implementer.GetViewModel;
if (!string.IsNullOrEmpty(model.ImplementerFIO) && implementer.ImplementerFIO.Equals(model.ImplementerFIO))
return implementer.GetViewModel;
}
return null;
}
/// <summary>
/// Добавление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Редактирование элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
foreach (var implementer in _source.Implementers)
{
if (implementer.Id == model.Id)
{
implementer.Update(model);
return implementer.GetViewModel;
}
}
return null;
}
/// <summary>
/// Удаление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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

@ -0,0 +1,93 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantListImplement.Models
{
/// <summary>
/// Сущность "Исполнитель"
/// </summary>
public class Implementer : IImplementerModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; private set; }
/// <summary>
/// ФИО исполнителя
/// </summary>
public string ImplementerFIO { get; private set; } = string.Empty;
/// <summary>
/// Пароль
/// </summary>
public string Password { get; private set; } = string.Empty;
/// <summary>
/// Опыт работы
/// </summary>
public int WorkExperience { get; private set; }
/// <summary>
/// Квалификация
/// </summary>
public int Qualification { get; private set; }
/// <summary>
/// Создание модели исполнителя
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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,
};
}
/// <summary>
/// Изменение модели исполнителя
/// </summary>
/// <param name="model"></param>
public void Update(ImplementerBindingModel? model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
/// <summary>
/// Получение модели исполнителя
/// </summary>
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification
};
}
}

View File

@ -30,6 +30,11 @@ namespace AircraftPlantListImplement.Models
/// </summary>
public int ClientId { get; private set; }
/// <summary>
/// Идентификатор исполнителя
/// </summary>
public int? ImplementerId { get; private set; }
/// <summary>
/// Количество изделий
/// </summary>
@ -72,6 +77,7 @@ namespace AircraftPlantListImplement.Models
Id = model.Id,
PlaneId = model.PlaneId,
ClientId = model.ClientId,
ImplementerId = model.ImplementerId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
@ -93,6 +99,8 @@ namespace AircraftPlantListImplement.Models
Status = model.Status;
DateImplement = model.DateImplement;
if (model.ImplementerId.HasValue)
ImplementerId = model.ImplementerId;
}
/// <summary>
@ -103,6 +111,7 @@ namespace AircraftPlantListImplement.Models
Id = Id,
PlaneId = PlaneId,
ClientId = ClientId,
ImplementerId = ImplementerId,
Count = Count,
Sum = Sum,
Status = Status,

View File

@ -0,0 +1,148 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.BusinessLogicsContracts;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Enums;
using Microsoft.AspNetCore.Mvc;
namespace AircraftPlantRestApi.Controllers
{
/// <summary>
/// Контроллер для работы с исполнителями
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
public class ImplementerController : Controller
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика для заказов
/// </summary>
private readonly IOrderLogic _orderLogic;
/// <summary>
/// Бизнес-логика для исполнителей
/// </summary>
private readonly IImplementerLogic _implementerLogic;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="orderLogic"></param>
/// <param name="implementerLogic"></param>
/// <param name="logger"></param>
public ImplementerController(IOrderLogic orderLogic, IImplementerLogic implementerLogic, ILogger<ImplementerController> logger)
{
_logger = logger;
_orderLogic = orderLogic;
_implementerLogic = implementerLogic;
}
/// <summary>
/// Авторизация исполнителя
/// </summary>
/// <param name="login"></param>
/// <param name="password"></param>
/// <returns></returns>
[HttpGet]
public ImplementerViewModel? Login(string login, string password)
{
try
{
return _implementerLogic.ReadElement(new ImplementerSearchModel
{
ImplementerFIO = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа сотрудника");
throw;
}
}
/// <summary>
/// Получение новых заказов
/// </summary>
/// <returns></returns>
[HttpGet]
public List<OrderViewModel>? GetNewOrders()
{
try
{
return _orderLogic.ReadList(new OrderSearchModel
{
Status = OrderStatus.Принят
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения новых заказов");
throw;
}
}
/// <summary>
/// Получение текущего заказа исполнителя
/// </summary>
/// <param name="implementerId"></param>
/// <returns></returns>
[HttpGet]
public OrderViewModel? GetImplementerOrder(int implementerId)
{
try
{
return _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = implementerId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения текущего заказа исполнителя");
throw;
}
}
/// <summary>
/// Смена статуса заказа (Выполняется)
/// </summary>
/// <param name="model"></param>
[HttpPost]
public void TakeOrderInWork(OrderBindingModel model)
{
try
{
_orderLogic.TakeOrderInWork(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка перевода заказа с №{Id} в работу", model.Id);
throw;
}
}
/// <summary>
/// Смена статуса заказа (Выдан)
/// </summary>
/// <param name="model"></param>
[HttpPost]
public void FinishOrder(OrderBindingModel model)
{
try
{
_orderLogic.FinishOrder(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа с №{Id}", model.Id);
throw;
}
}
}
}

View File

@ -11,12 +11,14 @@ builder.Logging.AddLog4Net("log4net.config");
// Add services to the container.
builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IPlaneStorage, PlaneStorage>();
builder.Services.AddTransient<IShopStorage, ShopStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IPlaneLogic, PlaneLogic>();
builder.Services.AddTransient<IShopLogic, ShopLogic>();

View File

@ -0,0 +1,166 @@
namespace AircraftPlantView
{
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()
{
textBoxImplementerFIO = new TextBox();
textBoxPassword = new TextBox();
numericUpDownWorkExperience = new NumericUpDown();
numericUpDownQualification = new NumericUpDown();
buttonCancel = new Button();
labelImplementerFIO = new Label();
labelPassword = new Label();
labelWorkExperience = new Label();
labelQualification = new Label();
buttonSave = new Button();
((System.ComponentModel.ISupportInitialize)numericUpDownWorkExperience).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownQualification).BeginInit();
SuspendLayout();
//
// textBoxImplementerFIO
//
textBoxImplementerFIO.Location = new Point(108, 12);
textBoxImplementerFIO.Name = "textBoxImplementerFIO";
textBoxImplementerFIO.Size = new Size(264, 23);
textBoxImplementerFIO.TabIndex = 0;
//
// textBoxPassword
//
textBoxPassword.Location = new Point(108, 41);
textBoxPassword.Name = "textBoxPassword";
textBoxPassword.Size = new Size(264, 23);
textBoxPassword.TabIndex = 1;
//
// numericUpDownWorkExperience
//
numericUpDownWorkExperience.Location = new Point(108, 70);
numericUpDownWorkExperience.Name = "numericUpDownWorkExperience";
numericUpDownWorkExperience.Size = new Size(264, 23);
numericUpDownWorkExperience.TabIndex = 2;
//
// numericUpDownQualification
//
numericUpDownQualification.Location = new Point(108, 99);
numericUpDownQualification.Name = "numericUpDownQualification";
numericUpDownQualification.Size = new Size(264, 23);
numericUpDownQualification.TabIndex = 3;
//
// buttonCancel
//
buttonCancel.Location = new Point(297, 134);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 4;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// labelImplementerFIO
//
labelImplementerFIO.AutoSize = true;
labelImplementerFIO.Location = new Point(12, 15);
labelImplementerFIO.Name = "labelImplementerFIO";
labelImplementerFIO.Size = new Size(37, 15);
labelImplementerFIO.TabIndex = 5;
labelImplementerFIO.Text = "ФИО:";
//
// labelPassword
//
labelPassword.AutoSize = true;
labelPassword.Location = new Point(11, 44);
labelPassword.Name = "labelPassword";
labelPassword.Size = new Size(52, 15);
labelPassword.TabIndex = 6;
labelPassword.Text = "Пароль:";
//
// labelWorkExperience
//
labelWorkExperience.AutoSize = true;
labelWorkExperience.Location = new Point(12, 72);
labelWorkExperience.Name = "labelWorkExperience";
labelWorkExperience.Size = new Size(38, 15);
labelWorkExperience.TabIndex = 7;
labelWorkExperience.Text = "label1";
//
// labelQualification
//
labelQualification.AutoSize = true;
labelQualification.Location = new Point(11, 101);
labelQualification.Name = "labelQualification";
labelQualification.Size = new Size(91, 15);
labelQualification.TabIndex = 8;
labelQualification.Text = "Квалификация:";
//
// buttonSave
//
buttonSave.Location = new Point(216, 134);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 9;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// FormImplementer
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 169);
Controls.Add(buttonSave);
Controls.Add(labelQualification);
Controls.Add(labelWorkExperience);
Controls.Add(labelPassword);
Controls.Add(labelImplementerFIO);
Controls.Add(buttonCancel);
Controls.Add(numericUpDownQualification);
Controls.Add(numericUpDownWorkExperience);
Controls.Add(textBoxPassword);
Controls.Add(textBoxImplementerFIO);
Name = "FormImplementer";
Text = "Исполнитель";
Load += FormImplementer_Load;
((System.ComponentModel.ISupportInitialize)numericUpDownWorkExperience).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownQualification).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxImplementerFIO;
private TextBox textBoxPassword;
private NumericUpDown numericUpDownWorkExperience;
private NumericUpDown numericUpDownQualification;
private Button buttonCancel;
private Label labelImplementerFIO;
private Label labelPassword;
private Label labelWorkExperience;
private Label labelQualification;
private Button buttonSave;
}
}

View File

@ -0,0 +1,140 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.BusinessLogicsContracts;
using AircraftPlantContracts.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 AircraftPlantView
{
/// <summary>
/// Форма для работы с компонентами
/// </summary>
public partial class FormImplementer : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика для исполнителей
/// </summary>
private readonly IImplementerLogic _logic;
/// <summary>
/// Идентификатор
/// </summary>
private int? _id;
public int Id { set { _id = value; } }
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="logic"></param>
public FormImplementer(ILogger<FormImplementer> logger, IImplementerLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
/// <summary>
/// Загрузка информации о исполнителе
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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)
{
textBoxImplementerFIO.Text = view.ImplementerFIO;
textBoxPassword.Text = view.Password;
numericUpDownQualification.Value = view.Qualification;
numericUpDownWorkExperience.Value = view.WorkExperience;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения исполнителя");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
/// <summary>
/// Кнопка "Сохранить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxPassword.Text))
{
MessageBox.Show("Заполните пароль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxImplementerFIO.Text))
{
MessageBox.Show("Заполните ФИО", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение исполнителя");
try
{
var model = new ImplementerBindingModel
{
Id = _id ?? 0,
ImplementerFIO = textBoxImplementerFIO.Text,
Password = textBoxPassword.Text,
Qualification = (int)numericUpDownQualification.Value,
WorkExperience = (int)numericUpDownWorkExperience.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);
}
}
/// <summary>
/// Кнопка "Отмена"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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>

View File

@ -0,0 +1,122 @@
namespace AircraftPlantView
{
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()
{
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// buttonRefresh
//
buttonRefresh.Location = new Point(480, 102);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(75, 23);
buttonRefresh.TabIndex = 9;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(480, 73);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(75, 23);
buttonDelete.TabIndex = 8;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(480, 44);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(75, 23);
buttonUpdate.TabIndex = 7;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(480, 15);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(75, 23);
buttonAdd.TabIndex = 6;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.GridColor = Color.White;
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(450, 361);
dataGridView.TabIndex = 5;
//
// FormImplementers
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(584, 361);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormImplementers";
Text = "Исполнители";
Load += FormImplementers_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonAdd;
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,154 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.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 AircraftPlantView
{
/// <summary>
/// Форма для вывода всех исполнителей
/// </summary>
public partial class FormImplementers : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика для исполнителей
/// </summary>
private readonly IImplementerLogic _logic;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="logic"></param>
public FormImplementers(ILogger<FormImplementers> logger, IImplementerLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
/// <summary>
/// Загрузка списка исполнителей
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormImplementers_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Кнопка "Добавить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementer));
if (service is FormImplementer form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
/// <summary>
/// Кнопка "Изменить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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();
}
}
}
}
/// <summary>
/// Кнопка "Удалить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonDelete_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление исполнителя");
try
{
if (!_logic.Delete(new ImplementerBindingModel { Id = id }))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления исполнителя");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
/// <summary>
/// Кнопка "Обновить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Метод загрузки списка исполнителей
/// </summary>
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);
}
}
}
}

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

@ -30,8 +30,6 @@
{
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonTakeOrderInWork = new Button();
buttonOrderReady = new Button();
buttonIssuedOrder = new Button();
buttonRefresh = new Button();
menuStrip = new MenuStrip();
@ -39,6 +37,7 @@
компонентыToolStripMenuItem = new ToolStripMenuItem();
изделияToolStripMenuItem = new ToolStripMenuItem();
магазиныToolStripMenuItem = new ToolStripMenuItem();
клиентыToolStripMenuItem = new ToolStripMenuItem();
отчетыToolStripMenuItem = new ToolStripMenuItem();
изделияToolStripMenuItem1 = new ToolStripMenuItem();
изделияСКомпонентамиToolStripMenuItem = new ToolStripMenuItem();
@ -49,6 +48,8 @@
списокМагазиновToolStripMenuItem = new ToolStripMenuItem();
ассортиментМагазиновToolStripMenuItem = new ToolStripMenuItem();
клиентыToolStripMenuItem = new ToolStripMenuItem();
запускРаботToolStripMenuItem = new ToolStripMenuItem();
исполнителиToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
menuStrip.SuspendLayout();
SuspendLayout();
@ -81,29 +82,9 @@
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += buttonCreateOrder_Click;
//
// buttonTakeOrderInWork
//
buttonTakeOrderInWork.Location = new Point(822, 76);
buttonTakeOrderInWork.Name = "buttonTakeOrderInWork";
buttonTakeOrderInWork.Size = new Size(150, 23);
buttonTakeOrderInWork.TabIndex = 2;
buttonTakeOrderInWork.Text = "Отдать на выполнение";
buttonTakeOrderInWork.UseVisualStyleBackColor = true;
buttonTakeOrderInWork.Click += buttonTakeOrderInWork_Click;
//
// buttonOrderReady
//
buttonOrderReady.Location = new Point(822, 105);
buttonOrderReady.Name = "buttonOrderReady";
buttonOrderReady.Size = new Size(150, 23);
buttonOrderReady.TabIndex = 3;
buttonOrderReady.Text = "Заказ готов";
buttonOrderReady.UseVisualStyleBackColor = true;
buttonOrderReady.Click += buttonOrderReady_Click;
//
// buttonIssuedOrder
//
buttonIssuedOrder.Location = new Point(822, 134);
buttonIssuedOrder.Location = new Point(822, 65);
buttonIssuedOrder.Name = "buttonIssuedOrder";
buttonIssuedOrder.Size = new Size(150, 23);
buttonIssuedOrder.TabIndex = 4;
@ -113,7 +94,7 @@
//
// buttonRefresh
//
buttonRefresh.Location = new Point(822, 172);
buttonRefresh.Location = new Point(822, 94);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(150, 23);
buttonRefresh.TabIndex = 5;
@ -123,7 +104,7 @@
//
// menuStrip
//
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(984, 24);
@ -134,6 +115,7 @@
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, изделияToolStripMenuItem, магазиныToolStripMenuItem });
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, изделияToolStripMenuItem, клиентыToolStripMenuItem });
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, изделияToolStripMenuItem, клиентыToolStripMenuItem, исполнителиToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(94, 20);
справочникиToolStripMenuItem.Text = "Справочники";
@ -159,6 +141,13 @@
магазиныToolStripMenuItem.Text = "Магазины";
магазиныToolStripMenuItem.Click += магазиныToolStripMenuItem_Click;
//
// клиентыToolStripMenuItem
//
клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem";
клиентыToolStripMenuItem.Size = new Size(180, 22);
клиентыToolStripMenuItem.Text = "Клиенты";
клиентыToolStripMenuItem.Click += клиентыToolStripMenuItem_Click;
//
// отчетыToolStripMenuItem
//
отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { изделияToolStripMenuItem1, изделияСКомпонентамиToolStripMenuItem, списокЗаказовToolStripMenuItem, заказыСГруппировкойToolStripMenuItem, списокМагазиновToolStripMenuItem, ассортиментМагазиновToolStripMenuItem });
@ -229,11 +218,19 @@
ассортиментМагазиновToolStripMenuItem.Click += ассортиментМагазиновToolStripMenuItem_Click;
//
// клиентыToolStripMenuItem
// запускРаботToolStripMenuItem
//
клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem";
клиентыToolStripMenuItem.Size = new Size(180, 22);
клиентыToolStripMenuItem.Text = "Клиенты";
клиентыToolStripMenuItem.Click += клиентыToolStripMenuItem_Click;
запускРаботToolStripMenuItem.Name = апускРаботToolStripMenuItem";
запускРаботToolStripMenuItem.Size = new Size(92, 20);
запускРаботToolStripMenuItem.Text = "Запуск работ";
запускРаботToolStripMenuItem.Click += запускРаботToolStripMenuItem_Click;
//
// исполнителиToolStripMenuItem
//
исполнителиToolStripMenuItem.Name = сполнителиToolStripMenuItem";
исполнителиToolStripMenuItem.Size = new Size(180, 22);
исполнителиToolStripMenuItem.Text = "Исполнители";
исполнителиToolStripMenuItem.Click += исполнителиToolStripMenuItem_Click;
//
// FormMain
//
@ -244,8 +241,6 @@
Controls.Add(buttonAddPlaneInShop);
Controls.Add(buttonRefresh);
Controls.Add(buttonIssuedOrder);
Controls.Add(buttonOrderReady);
Controls.Add(buttonTakeOrderInWork);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(menuStrip);
@ -264,8 +259,6 @@
private DataGridView dataGridView;
private Button buttonCreateOrder;
private Button buttonTakeOrderInWork;
private Button buttonOrderReady;
private Button buttonIssuedOrder;
private Button buttonRefresh;
private MenuStrip menuStrip;
@ -283,5 +276,7 @@
private ToolStripMenuItem списокМагазиновToolStripMenuItem;
private ToolStripMenuItem ассортиментМагазиновToolStripMenuItem;
private ToolStripMenuItem клиентыToolStripMenuItem;
private ToolStripMenuItem запускРаботToolStripMenuItem;
private ToolStripMenuItem исполнителиToolStripMenuItem;
}
}

View File

@ -34,17 +34,23 @@ namespace AircraftPlantView
/// </summary>
private readonly IReportLogic _reportLogic;
/// <summary>
/// Имитация деятельности исполнителей
/// </summary>
private readonly IWorkProcess _workProcess;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="logic"></param>
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic)
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
_workProcess = workProcess;
}
/// <summary>
@ -113,6 +119,20 @@ namespace AircraftPlantView
}
}
/// <summary>
/// Вывести список всех исполнителей
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void исполнителиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if (service is FormImplementers form)
{
form.ShowDialog();
}
}
/// <summary>
/// Вывести отчет по изделиям
/// </summary>
@ -199,6 +219,19 @@ namespace AircraftPlantView
}
}
/// <summary>
/// Кнопка "Создать заказ"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void запускРаботToolStripMenuItem_Click(object sender, EventArgs e)
{
_workProcess.DoWork((
Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!,
_orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// Кнопка "Создать заказ"
/// </summary>
@ -214,62 +247,6 @@ namespace AircraftPlantView
}
}
/// <summary>
/// Кнопка "Отдать на выполнение"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonTakeOrderInWork_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id);
try
{
var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка передачи заказа в работу");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
/// <summary>
/// Кнопка "Заказ готов"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonOrderReady_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
/// <summary>
/// Кнопка "Заказ выдан"
/// </summary>
@ -349,9 +326,9 @@ namespace AircraftPlantView
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["PlaneName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["PlaneId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false;
}
_logger.LogInformation("Загрузка заказов");
}

View File

@ -49,17 +49,20 @@ namespace AircraftPlantView
});
services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<IComponentStorage, ComponentStorage>();
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IPlaneStorage, PlaneStorage>();
services.AddTransient<IShopStorage, ShopStorage>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IPlaneLogic, PlaneLogic>();
services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IShopLogic, ShopLogic>();
services.AddTransient<IWorkProcess, WorkModeling>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
@ -67,6 +70,8 @@ namespace AircraftPlantView
services.AddTransient<FormMain>();
services.AddTransient<FormClients>();
services.AddTransient<FormImplementers>();
services.AddTransient<FormImplementer>();
services.AddTransient<FormComponent>();
services.AddTransient<FormComponents>();
services.AddTransient<FormCreateOrder>();

View File

@ -5,7 +5,7 @@
autoReload="true" internalLogLevel="Info">
<targets>
<target xsi:type="File" name="tofile" fileName="log-$(shortdate).log" />
<target xsi:type="File" name="tofile" fileName="log-${shortdate}.log" />
</targets>
<rules>