6 Commits

Author SHA1 Message Date
Marselchi
baccac7171 Микрофикс 2024-05-06 10:28:07 +04:00
Marselchi
dfbf69b305 Микрофикс формочки чтобы влезали все столбцы 2024-05-06 10:23:06 +04:00
Marselchi
330eefe852 Усё оно готово 2024-05-05 20:33:21 +04:00
Marselchi
dac2817806 Теперь точно финал (надеюсь) 2024-04-22 10:17:21 +04:00
Marselchi
cf10d844e0 Починил лютую западню от вижлы (снесла строчку) 2024-04-21 20:48:14 +04:00
Marselchi
6876fd23d9 чет не то с бдшкой 2024-04-21 20:39:51 +04:00
82 changed files with 3776 additions and 527 deletions

View File

@@ -4,6 +4,7 @@ using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using System.Text.RegularExpressions;
namespace ShipyardBusinessLogic.BusinessLogics
{
@@ -101,6 +102,14 @@ namespace ShipyardBusinessLogic.BusinessLogics
{
throw new ArgumentNullException("У клиента отсутствует пароль", nameof(model.Email));
}
if (!Regex.IsMatch(model.Email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$"))
{
throw new ArgumentException("Неправильно введенный email", nameof(model.Email));
}
if (!Regex.IsMatch(model.Password, @"^((\w+\d+\W+)|(\w+\W+\d+)|(\d+\w+\W+)|(\d+\W+\w+)|(\W+\w+\d+)|(\W+\d+\w+))[\w\d\W]*$") || model.Password.Length < 10 || model.Password.Length > 50)
{
throw new ArgumentException("Неправильно введенный пароль", nameof(model.Password));
}
_logger.LogInformation("Client. ClientID:{Id}. ClientFIO: {ClientFIO}. Email:{ Email}. Password: { Password}", model.Id, model.ClientFIO, model.Email, model.Password);
var element = _clientStorage.GetElement(new ClientSearchModel
{

View File

@@ -0,0 +1,116 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
namespace ShipyardBusinessLogic.BusinessLogics
{
public class ImplementerLogic : IImplementerLogic
{
private readonly ILogger _logger;
private readonly IImplementerStorage _implementerStorage;
public ImplementerLogic(ILogger<IImplementerLogic> logger, IImplementerStorage implementerStorage)
{
_logger = logger;
_implementerStorage = implementerStorage;
}
public bool Create(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
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;
}
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;
}
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;
}
public bool Update(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Update(model) == null)
{
_logger.LogWarning("Update 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 (model.Qualification <= 0)
{
throw new ArgumentNullException("Квалификация не может быть меньше 0", nameof(model.Qualification));
}
if (model.WorkExperience <= 0)
{
throw new ArgumentNullException("Стаж работы не может быть меньше 0", nameof(model.WorkExperience));
}
_logger.LogInformation("Implementer. ImplementerID:{Id}. ImplementerFIO: {ImplementerFIO}. Password: { Password}. Qualification: {Qualification}. WorkExperience: {WorkExperience}", model.Id, model.ImplementerFIO, model.Password, model.Qualification, model.WorkExperience);
var element = _implementerStorage.GetElement(new ImplementerSearchModel
{
ImplementerFIO = model.ImplementerFIO
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Такой исполнитель уже существует");
}
}
}
}

View File

@@ -0,0 +1,42 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
namespace ShipyardBusinessLogic.BusinessLogics
{
public class MessageInfoLogic : IMessageInfoLogic
{
private readonly ILogger _logger;
private readonly IMessageInfoStorage _messageInfoStorage;
public MessageInfoLogic(ILogger<OrderLogic> logger, IMessageInfoStorage messageInfoStorage)
{
_logger = logger;
_messageInfoStorage = messageInfoStorage;
}
public bool Create(MessageInfoBindingModel model)
{
if (_messageInfoStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{
_logger.LogInformation("ReadList. ClientId:{ClientId}. MessageId:{MessageId}", model?.ClientId, model?.MessageId);
var list = model == null ? _messageInfoStorage.GetFullList() : _messageInfoStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
}
}

View File

@@ -5,6 +5,7 @@ using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Enums;
using ShipyardBusinessLogic.MailWorker;
namespace ShipyardBusinessLogic.BusinessLogics
{
@@ -12,10 +13,15 @@ namespace ShipyardBusinessLogic.BusinessLogics
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
private readonly AbstractMailWorker _mailWorker;
private readonly IClientLogic _clientLogic;
static readonly object locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker, IClientLogic clientLogic)
{
_logger = logger;
_orderStorage = orderStorage;
_mailWorker = mailWorker;
_clientLogic = clientLogic;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
@@ -29,7 +35,23 @@ namespace ShipyardBusinessLogic.BusinessLogics
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool CreateOrder(OrderBindingModel model)
public OrderViewModel? ReadElement(OrderSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id:{Id}", model.Id);
var elem = _orderStorage.GetElement(model);
if (elem == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement found. Id:{Id}", elem.Id);
return elem;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
@@ -38,11 +60,14 @@ namespace ShipyardBusinessLogic.BusinessLogics
return false;
}
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
var result = _orderStorage.Insert(model);
if (result == null)
{
model.Status = OrderStatus.Неизвестен;
_logger.LogWarning("Insert operation failed");
return false;
}
SendOrderMessage(result.ClientId, $"Верфь, Заказ №{result.Id}", $"Заказ №{result.Id} от {result.DateCreate} на сумму {result.Sum:0.00} принят");
return true;
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
@@ -71,32 +96,41 @@ namespace ShipyardBusinessLogic.BusinessLogics
}
public bool StatusUpdate(OrderBindingModel model, OrderStatus newStatus)
{
var viewModel = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (viewModel.Status + 1 != newStatus)
CheckModel(model, false);
var viewModel = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (viewModel.Status + 1 != newStatus)
{
_logger.LogWarning("Status update to " + newStatus.ToString() + " operation failed. Order status incorrect.");
return false;
}
model.Status = newStatus;
if (model.Status == OrderStatus.Готов) model.DateImplement = DateTime.Now;
throw new InvalidOperationException("Невозможно перевести состояние заказа");
}
if (viewModel.ImplementerId.HasValue)
{
model.ImplementerId = viewModel.ImplementerId;
}
model.Status = newStatus;
if (model.Status == OrderStatus.Готов) model.DateImplement = DateTime.Now;
else
{
model.DateImplement = viewModel.DateImplement;
}
CheckModel(model, false);
if (_orderStorage.Update(model) == null)
var result = _orderStorage.Update(model);
if (result == null)
{
model.Status--;
_logger.LogWarning("Update operation failed");
return false;
}
SendOrderMessage(result.ClientId, $"Верфь, Заказ №{result.Id}", $"Заказ №{model.Id} изменен статус на {result.Status}");
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выполняется);
}
lock (locker)
{
return StatusUpdate(model, OrderStatus.Выполняется);
}
}
public bool DeliveryOrder(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выдан);
@@ -106,5 +140,20 @@ namespace ShipyardBusinessLogic.BusinessLogics
{
return StatusUpdate(model, OrderStatus.Готов);
}
private bool SendOrderMessage(int clientId, string subject, string text)
{
var client = _clientLogic.ReadElement(new() { Id = clientId });
if (client == null)
{
return false;
}
_mailWorker.MailSendAsync(new()
{
MailAddress = client.Email,
Subject = subject,
Text = text
});
return true;
}
}
}

View File

@@ -0,0 +1,155 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Enums;
namespace ShipyardBusinessLogic.BusinessLogics
{
public class WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if (implementers == null)
{
_logger.LogWarning("DoWork. Implementers is null");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel
{
Status = OrderStatus.Принят
});
if (orders == null || orders.Count == 0)
{
_logger.LogWarning("DoWork. Orders is null or empty");
return;
}
_logger.LogDebug("DoWork for {Count} orders", orders.Count);
foreach (var implementer in implementers)
{
Task.Run(() => WorkerWorkAsync(implementer, orders));
}
}
// Иммитация работы исполнителя
private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel> orders)
{
if (_orderLogic == null || implementer == null)
{
return;
}
await RunOrderInWork(implementer);
await Task.Run(() =>
{
foreach (var order in orders)
{
try
{
_logger.LogDebug("DoWork. Worker {Id} try get order {Order}", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = order.Id,
ImplementerId = implementer.Id
});
// делаем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
_orderLogic.FinishOrder(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;
}
}
});
}
//Ищем заказ, которые уже в работе (вдруг исполнителя прервали)
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.FinishOrder(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;
}
}
}
}

View File

@@ -0,0 +1,95 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
namespace ShipyardBusinessLogic.MailWorker
{
public abstract class AbstractMailWorker
{
protected string _mailLogin = string.Empty;
protected string _mailPassword = string.Empty;
protected string _smtpClientHost = string.Empty;
protected int _smtpClientPort;
protected string _popHost = string.Empty;
protected int _popPort;
private readonly IMessageInfoLogic _messageInfoLogic;
private readonly IClientLogic _clientLogic;
private readonly ILogger _logger;
public AbstractMailWorker(ILogger<AbstractMailWorker> logger, IMessageInfoLogic messageInfoLogic, IClientLogic clientLogic)
{
_logger = logger;
_messageInfoLogic = messageInfoLogic;
_clientLogic = clientLogic;
}
public void MailConfig(MailConfigBindingModel config)
{
_mailLogin = config.MailLogin;
_mailPassword = config.MailPassword;
_smtpClientHost = config.SmtpClientHost;
_smtpClientPort = config.SmtpClientPort;
_popHost = config.PopHost;
_popPort = config.PopPort;
_logger.LogDebug("Config: {login}, {password}, {clientHost}, {clientPOrt}, {popHost}, {popPort}", _mailLogin, _mailPassword, _smtpClientHost, _smtpClientPort, _popHost, _popPort);
}
public async void MailSendAsync(MailSendInfoBindingModel info)
{
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword))
{
return;
}
if (string.IsNullOrEmpty(_smtpClientHost) || _smtpClientPort == 0)
{
return;
}
if (string.IsNullOrEmpty(info.MailAddress) || string.IsNullOrEmpty(info.Subject) || string.IsNullOrEmpty(info.Text))
{
return;
}
_logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject);
await SendMailAsync(info);
}
public async void MailCheck()
{
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword))
{
return;
}
if (string.IsNullOrEmpty(_popHost) || _popPort == 0)
{
return;
}
if (_messageInfoLogic == null)
{
return;
}
var list = await ReceiveMailAsync();
_logger.LogDebug("Check Mail: {Count} new mails", list.Count);
foreach (var mail in list)
{
mail.ClientId = _clientLogic.ReadElement(new() { Email = mail.SenderName })?.Id;
_messageInfoLogic.Create(mail);
}
}
protected abstract Task SendMailAsync(MailSendInfoBindingModel info);
protected abstract Task<List<MessageInfoBindingModel>> ReceiveMailAsync();
}
}

View File

@@ -0,0 +1,78 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using MailKit.Net.Pop3;
using System.Net.Mail;
using System.Net;
using System.Text;
using MailKit.Security;
namespace ShipyardBusinessLogic.MailWorker
{
public class MailKitWorker : AbstractMailWorker
{
public MailKitWorker(ILogger<MailKitWorker> logger, IMessageInfoLogic messageInfoLogic, IClientLogic clientLogic) : base(logger, messageInfoLogic, clientLogic) { }
protected override async Task SendMailAsync(MailSendInfoBindingModel info)
{
using var objMailMessage = new MailMessage();
using var objSmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort);
try
{
objMailMessage.From = new MailAddress(_mailLogin);
objMailMessage.To.Add(new MailAddress(info.MailAddress));
objMailMessage.Subject = info.Subject;
objMailMessage.Body = info.Text;
objMailMessage.SubjectEncoding = Encoding.UTF8;
objMailMessage.BodyEncoding = Encoding.UTF8;
objSmtpClient.UseDefaultCredentials = false;
objSmtpClient.EnableSsl = true;
objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword);
await Task.Run(() => objSmtpClient.Send(objMailMessage));
}
catch (Exception)
{
throw;
}
}
protected override async Task<List<MessageInfoBindingModel>> ReceiveMailAsync()
{
var list = new List<MessageInfoBindingModel>();
using var client = new Pop3Client();
await Task.Run(() =>
{
try
{
client.Connect(_popHost, _popPort, SecureSocketOptions.SslOnConnect);
client.Authenticate(_mailLogin, _mailPassword);
for (int i = 0; i < client.Count; i++)
{
var message = client.GetMessage(i);
foreach (var mail in message.From.Mailboxes)
{
list.Add(new MessageInfoBindingModel
{
DateDelivery = message.Date.DateTime,
MessageId = message.MessageId,
SenderName = mail.Address,
Subject = message.Subject,
Body = message.TextBody
});
}
}
}
catch (AuthenticationException)
{ }
finally
{
client.Disconnect(true);
}
});
return list;
}
}
}

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.0.2" />
<PackageReference Include="MailKit" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>

View File

@@ -143,5 +143,14 @@ namespace ShipyardClientApp.Controllers
var prod = APIClient.GetRequest<ShipViewModel>($"api/main/getship?shipId={ship}");
return count * (prod?.Price ?? 1);
}
[HttpGet]
public IActionResult Mails()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={APIClient.Client.Id}"));
}
}
}

View File

@@ -0,0 +1,53 @@
@using ShipyardContracts.ViewModels
@model List<MessageInfoViewModel>
@{
ViewData["Title"] = "Mails";
}
<div class="text-center">
<h1 class="display-4">Письма</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<table class="table">
<thead>
<tr>
<th>
Дата письма
</th>
<th>
Заголовок
</th>
<th>
Текст
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.DateDelivery)
</td>
<td>
@Html.DisplayFor(modelItem => item.Subject)
</td>
<td>
@Html.DisplayFor(modelItem => item.Body)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@@ -25,6 +25,9 @@
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Mails">Письма</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>

View File

@@ -0,0 +1,17 @@
using ShipyardDataModels.Models;
namespace ShipyardContracts.BindingModels
{
public class ImplementerBindingModel : IImplementerModel
{
public int Id { get; set; }
public string ImplementerFIO { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public int WorkExperience { get; set; }
public int Qualification { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
namespace ShipyardContracts.BindingModels
{
public class MailConfigBindingModel
{
public string MailLogin { get; set; } = string.Empty;
public string MailPassword { get; set; } = string.Empty;
public string SmtpClientHost { get; set; } = string.Empty;
public int SmtpClientPort { get; set; }
public string PopHost { get; set; } = string.Empty;
public int PopPort { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
namespace ShipyardContracts.BindingModels
{
public class MailSendInfoBindingModel
{
public string MailAddress { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;
public string Text { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,19 @@
using ShipyardDataModels.Models;
namespace ShipyardContracts.BindingModels
{
public class MessageInfoBindingModel : IMessageInfoModel
{
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
public string SenderName { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
}
}

View File

@@ -8,7 +8,8 @@ namespace ShipyardContracts.BindingModels
public int Id { get; set; }
public int ShipId { get; set; }
public int ClientId { get; set; }
public int Count { get; set; }
public int? ImplementerId { get; set; }
public int Count { get; set; }
public double Sum { get; set; }
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
public DateTime DateCreate { get; set; } = DateTime.Now;

View File

@@ -0,0 +1,19 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.BusinessLogicsContracts
{
public interface IImplementerLogic
{
List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model);
ImplementerViewModel? ReadElement(ImplementerSearchModel model);
bool Create(ImplementerBindingModel model);
bool Update(ImplementerBindingModel model);
bool Delete(ImplementerBindingModel model);
}
}

View File

@@ -0,0 +1,13 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.BusinessLogicsContracts
{
public interface IMessageInfoLogic
{
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model);
bool Create(MessageInfoBindingModel model);
}
}

View File

@@ -11,5 +11,6 @@ namespace ShipyardContracts.BusinessLogicsContracts
bool TakeOrderInWork(OrderBindingModel model);
bool FinishOrder(OrderBindingModel model);
bool DeliveryOrder(OrderBindingModel model);
}
OrderViewModel? ReadElement(OrderSearchModel model);
}
}

View File

@@ -0,0 +1,7 @@
namespace ShipyardContracts.BusinessLogicsContracts
{
public interface IWorkProcess
{
void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic);
}
}

View File

@@ -0,0 +1,11 @@
namespace ShipyardContracts.SearchModels
{
public class ImplementerSearchModel
{
public int? Id { get; set; }
public string? ImplementerFIO { get; set; }
public string? Password { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace ShipyardContracts.SearchModels
{
public class MessageInfoSearchModel
{
public int? ClientId { get; set; }
public string? MessageId { get; set; }
}
}

View File

@@ -1,10 +1,14 @@
namespace ShipyardContracts.SearchModels
using ShipyardDataModels.Enums;
namespace ShipyardContracts.SearchModels
{
public class OrderSearchModel
{
public int? Id { get; set; }
public int? ClientId { get; set; }
public DateTime? DateFrom { get; set; }
public int? ImplementerId { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
}
public OrderStatus? Status { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.StoragesContracts
{
public interface IImplementerStorage
{
List<ImplementerViewModel> GetFullList();
List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model);
ImplementerViewModel? GetElement(ImplementerSearchModel model);
ImplementerViewModel? Insert(ImplementerBindingModel model);
ImplementerViewModel? Update(ImplementerBindingModel model);
ImplementerViewModel? Delete(ImplementerBindingModel model);
}
}

View File

@@ -0,0 +1,17 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.StoragesContracts
{
public interface IMessageInfoStorage
{
List<MessageInfoViewModel> GetFullList();
List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model);
MessageInfoViewModel? GetElement(MessageInfoSearchModel model);
MessageInfoViewModel? Insert(MessageInfoBindingModel model);
}
}

View File

@@ -0,0 +1,22 @@
using ShipyardDataModels.Models;
using System.ComponentModel;
namespace ShipyardContracts.ViewModels
{
public class ImplementerViewModel : IImplementerModel
{
public int Id { get; set; }
[DisplayName("ФИО исполнителя")]
public string ImplementerFIO { get; set; } = string.Empty;
[DisplayName("Пароль")]
public string Password { get; set; } = string.Empty;
[DisplayName("Стаж работы")]
public int WorkExperience { get; set; }
[DisplayName("Квалификация")]
public int Qualification { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
using ShipyardDataModels.Models;
using System.ComponentModel;
namespace ShipyardContracts.ViewModels
{
public class MessageInfoViewModel : IMessageInfoModel
{
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
[DisplayName("Отправитель")]
public string SenderName { get; set; } = string.Empty;
[DisplayName("Дата письма")]
public DateTime DateDelivery { get; set; }
[DisplayName("Заголовок")]
public string Subject { get; set; } = string.Empty;
[DisplayName("Текст")]
public string Body { get; set; } = string.Empty;
}
}

View File

@@ -14,7 +14,10 @@ namespace ShipyardContracts.ViewModels
public int ClientId { get; set; }
[DisplayName("Клиент")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Количество")]
public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")]
public string ImplementerFIO { get; set; } = string.Empty;
[DisplayName("Количество")]
public int Count { get; set; }
[DisplayName("Сумма")]
public double Sum { get; set; }

View File

@@ -0,0 +1,101 @@
using Microsoft.EntityFrameworkCore;
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardDataBaseImplement.Models;
namespace ShipyardDataBaseImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
using var context = new ShipyardDataBase();
var element = context.Implementers
.Include(x => x.Orders)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Implementers.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
using var context = new ShipyardDataBase();
if (model.Id.HasValue)
{
return context.Implementers
.FirstOrDefault(x => (x.Id == model.Id))?.GetViewModel;
}
else if (!string.IsNullOrEmpty(model.ImplementerFIO) && !string.IsNullOrEmpty(model.Password))
{
return context.Implementers
.FirstOrDefault(x => (x.ImplementerFIO == model.ImplementerFIO && x.Password == model.Password))?.GetViewModel;
}
else if (!string.IsNullOrEmpty(model.ImplementerFIO))
{
return context.Implementers
.FirstOrDefault(x => (x.ImplementerFIO == model.ImplementerFIO))?.GetViewModel;
}
return new();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
if (model == null)
{
return new();
}
if (!string.IsNullOrEmpty(model.ImplementerFIO))
{
using var context = new ShipyardDataBase();
return context.Implementers
.Include(x => x.Orders)
.Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO))
.Select(x => x.GetViewModel)
.ToList();
}
return new();
}
public List<ImplementerViewModel> GetFullList()
{
using var context = new ShipyardDataBase();
return context.Implementers
.Include(x => x.Orders)
.Select(x => x.GetViewModel)
.ToList();
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
var newImplementer = Implementer.Create(model);
if (newImplementer == null)
{
return null;
}
using var context = new ShipyardDataBase();
context.Implementers.Add(newImplementer);
context.SaveChanges();
return newImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
using var context = new ShipyardDataBase();
var client = context.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (client == null)
{
return null;
}
client.Update(model);
context.SaveChanges();
return client.GetViewModel;
}
}
}

View File

@@ -0,0 +1,55 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardDataBaseImplement.Models;
namespace ShipyardDataBaseImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId))
{
return null;
}
using var context = new ShipyardDataBase();
return context.Messages
.FirstOrDefault(x => x.MessageId == model.MessageId)?
.GetViewModel;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (!model.ClientId.HasValue)
return new();
using var context = new ShipyardDataBase();
return context.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFullList()
{
using var context = new ShipyardDataBase();
return context.Messages
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
using var context = new ShipyardDataBase();
var newMessage = Message.Create(model);
if (newMessage == null)
{
return null;
}
context.Messages.Add(newMessage);
context.SaveChanges();
return newMessage.GetViewModel;
}
}
}

View File

@@ -19,7 +19,8 @@ namespace ShipyardDataBaseImplement.Implements
var deletedElement = context.Orders
.Include(x => x.Ship)
.Include(x => x.Client)
.FirstOrDefault(x => x.Id == model.Id)
.Include(x => x.Implementer)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel;
context.Orders.Remove(element);
context.SaveChanges();
@@ -30,14 +31,33 @@ namespace ShipyardDataBaseImplement.Implements
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
using var context = new ShipyardDataBase();
if (model.ImplementerId.HasValue && model.Status.HasValue)
{
return context.Orders
.Include(x => x.Ship)
.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.Ship)
.Include(x => x.Client)
.Include(x => x.Implementer)
.FirstOrDefault(x => x.ImplementerId == model.ImplementerId)
?.GetViewModel;
}
if (!model.Id.HasValue)
{
return null;
}
using var context = new ShipyardDataBase();
return context.Orders
.Include(x => x.Ship)
.Include(x => x.Client)
.Include(x => x.Implementer)
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
?.GetViewModel;
}
@@ -45,20 +65,12 @@ namespace ShipyardDataBaseImplement.Implements
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
using var context = new ShipyardDataBase();
if (model.Id.HasValue)
{
return context.Orders
.Include(x => x.Ship)
.Include(x => x.Client)
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.ToList();
}
else if (model.DateFrom != null && model.DateTo != null)
if (model.DateFrom.HasValue && model.DateTo.HasValue)
{
return context.Orders
.Include(x => x.Ship)
.Include(x => x.Client)
.Include(x => x.Implementer)
.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => x.GetViewModel)
.ToList();
@@ -67,16 +79,31 @@ namespace ShipyardDataBaseImplement.Implements
{
return context.Orders
.Include(x => x.Ship)
.Include(x => x.Client)
.Include(x => x.Client).Include(x => x.Implementer)
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
else
else if (model.Status.HasValue)
{
return new();
return context.Orders
.Include(x => x.Ship)
.Include(x => x.Client).Include(x => x.Implementer)
.Where(x => x.Status == model.Status)
.Select(x => x.GetViewModel)
.ToList();
}
}
else if (model.Id.HasValue)
{
return context.Orders
.Include(x => x.Ship)
.Include(x => x.Client).Include(x => x.Implementer)
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.ToList();
}
return new();
}
public List<OrderViewModel> GetFullList()
{
@@ -84,6 +111,7 @@ namespace ShipyardDataBaseImplement.Implements
return context.Orders
.Include(x => x.Ship)
.Include(x => x.Client)
.Include(x => x.Implementer)
.Select(x => x.GetViewModel)
.ToList();
}
@@ -101,6 +129,7 @@ namespace ShipyardDataBaseImplement.Implements
return context.Orders
.Include(x => x.Ship)
.Include(x => x.Client)
.Include(x => x.Implementer)
.FirstOrDefault(x => x.Id == newOrder.Id)
?.GetViewModel;
}
@@ -118,6 +147,7 @@ namespace ShipyardDataBaseImplement.Implements
return context.Orders
.Include(x => x.Ship)
.Include(x => x.Client)
.Include(x => x.Implementer)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel;
}

View File

@@ -1,171 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using ShipyardDataBaseImplement;
#nullable disable
namespace ShipyardDataBaseImplement.Migrations
{
[DbContext(typeof(ShipyardDataBase))]
[Migration("20240310181644_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.16")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Detail", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Cost")
.HasColumnType("float");
b.Property<string>("DetailName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Details");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("ShipId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ShipId");
b.ToTable("Orders");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Ship", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ShipName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Ships");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShipDetail", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("DetailId")
.HasColumnType("int");
b.Property<int>("ShipId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("DetailId");
b.HasIndex("ShipId");
b.ToTable("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Order", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Orders")
.HasForeignKey("ShipId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ship");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShipDetail", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Detail", "Detail")
.WithMany("ShipDetails")
.HasForeignKey("DetailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Details")
.HasForeignKey("ShipId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Detail");
b.Navigation("Ship");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Detail", b =>
{
b.Navigation("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Ship", b =>
{
b.Navigation("Details");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,68 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ShipyardDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class ClientMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ClientId",
table: "Orders",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateTable(
name: "Clients",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ClientFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Email = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Clients", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_Orders_ClientId",
table: "Orders",
column: "ClientId");
migrationBuilder.AddForeignKey(
name: "FK_Orders_Clients_ClientId",
table: "Orders",
column: "ClientId",
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Orders_Clients_ClientId",
table: "Orders");
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropIndex(
name: "IX_Orders_ClientId",
table: "Orders");
migrationBuilder.DropColumn(
name: "ClientId",
table: "Orders");
}
}
}

View File

@@ -12,8 +12,8 @@ using ShipyardDataBaseImplement;
namespace ShipyardDataBaseImplement.Migrations
{
[DbContext(typeof(ShipyardDataBase))]
[Migration("20240405073112_ClientMigration")]
partial class ClientMigration
[Migration("20240421163132_Implementer")]
partial class Implementer
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -70,6 +70,33 @@ namespace ShipyardDataBaseImplement.Migrations
b.ToTable("Details");
});
modelBuilder.Entity("ShipyardDataBaseImplement.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("ShipyardDataBaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@@ -90,6 +117,9 @@ namespace ShipyardDataBaseImplement.Migrations
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("ShipId")
.HasColumnType("int");
@@ -103,6 +133,8 @@ namespace ShipyardDataBaseImplement.Migrations
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("ShipId");
b.ToTable("Orders");
@@ -162,6 +194,10 @@ namespace ShipyardDataBaseImplement.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ShipyardDataBaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Orders")
.HasForeignKey("ShipId")
@@ -170,6 +206,8 @@ namespace ShipyardDataBaseImplement.Migrations
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Ship");
});
@@ -202,6 +240,11 @@ namespace ShipyardDataBaseImplement.Migrations
b.Navigation("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Ship", b =>
{
b.Navigation("Details");

View File

@@ -6,11 +6,26 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace ShipyardDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
public partial class Implementer : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Clients",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ClientFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Email = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Clients", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Details",
columns: table => new
@@ -25,6 +40,22 @@ namespace ShipyardDataBaseImplement.Migrations
table.PrimaryKey("PK_Details", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Implementers",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ImplementerFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false),
WorkExperience = table.Column<int>(type: "int", nullable: false),
Qualification = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Implementers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Ships",
columns: table => new
@@ -46,6 +77,8 @@ namespace ShipyardDataBaseImplement.Migrations
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ShipId = table.Column<int>(type: "int", nullable: false),
ClientId = table.Column<int>(type: "int", nullable: false),
ImplementerId = table.Column<int>(type: "int", nullable: true),
Count = table.Column<int>(type: "int", nullable: false),
Sum = table.Column<double>(type: "float", nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
@@ -55,6 +88,17 @@ namespace ShipyardDataBaseImplement.Migrations
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Orders_Implementers_ImplementerId",
column: x => x.ImplementerId,
principalTable: "Implementers",
principalColumn: "Id");
table.ForeignKey(
name: "FK_Orders_Ships_ShipId",
column: x => x.ShipId,
@@ -90,6 +134,16 @@ namespace ShipyardDataBaseImplement.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Orders_ClientId",
table: "Orders",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_Orders_ImplementerId",
table: "Orders",
column: "ImplementerId");
migrationBuilder.CreateIndex(
name: "IX_Orders_ShipId",
table: "Orders",
@@ -115,6 +169,12 @@ namespace ShipyardDataBaseImplement.Migrations
migrationBuilder.DropTable(
name: "ShipDetails");
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropTable(
name: "Implementers");
migrationBuilder.DropTable(
name: "Details");

View File

@@ -0,0 +1,298 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using ShipyardDataBaseImplement;
#nullable disable
namespace ShipyardDataBaseImplement.Migrations
{
[DbContext(typeof(ShipyardDataBase))]
[Migration("20240505153323_Mail")]
partial class Mail
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.16")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("ShipyardDataBaseImplement.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("ShipyardDataBaseImplement.Models.Detail", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Cost")
.HasColumnType("float");
b.Property<string>("DetailName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Details");
});
modelBuilder.Entity("ShipyardDataBaseImplement.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("ShipyardDataBaseImplement.Models.Message", b =>
{
b.Property<string>("MessageId")
.HasColumnType("nvarchar(450)");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("ShipyardDataBaseImplement.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>("ShipId")
.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("ShipId");
b.ToTable("Orders");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Ship", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ShipName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Ships");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShipDetail", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("DetailId")
.HasColumnType("int");
b.Property<int>("ShipId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("DetailId");
b.HasIndex("ShipId");
b.ToTable("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Message", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Client", "Client")
.WithMany("Messages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Order", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ShipyardDataBaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Orders")
.HasForeignKey("ShipId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Ship");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShipDetail", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Detail", "Detail")
.WithMany("ShipDetails")
.HasForeignKey("DetailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Details")
.HasForeignKey("ShipId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Detail");
b.Navigation("Ship");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Client", b =>
{
b.Navigation("Messages");
b.Navigation("Orders");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Detail", b =>
{
b.Navigation("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Ship", b =>
{
b.Navigation("Details");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ShipyardDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class Mail : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Messages",
columns: table => new
{
MessageId = table.Column<string>(type: "nvarchar(450)", nullable: false),
ClientId = table.Column<int>(type: "int", nullable: true),
SenderName = table.Column<string>(type: "nvarchar(max)", nullable: false),
DateDelivery = table.Column<DateTime>(type: "datetime2", nullable: false),
Subject = table.Column<string>(type: "nvarchar(max)", nullable: false),
Body = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Messages", x => x.MessageId);
table.ForeignKey(
name: "FK_Messages_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_Messages_ClientId",
table: "Messages",
column: "ClientId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Messages");
}
}
}

View File

@@ -67,6 +67,63 @@ namespace ShipyardDataBaseImplement.Migrations
b.ToTable("Details");
});
modelBuilder.Entity("ShipyardDataBaseImplement.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("ShipyardDataBaseImplement.Models.Message", b =>
{
b.Property<string>("MessageId")
.HasColumnType("nvarchar(450)");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@@ -87,6 +144,9 @@ namespace ShipyardDataBaseImplement.Migrations
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("ShipId")
.HasColumnType("int");
@@ -100,6 +160,8 @@ namespace ShipyardDataBaseImplement.Migrations
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("ShipId");
b.ToTable("Orders");
@@ -151,6 +213,15 @@ namespace ShipyardDataBaseImplement.Migrations
b.ToTable("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Message", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Client", "Client")
.WithMany("Messages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Order", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Client", "Client")
@@ -159,6 +230,10 @@ namespace ShipyardDataBaseImplement.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ShipyardDataBaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Orders")
.HasForeignKey("ShipId")
@@ -167,6 +242,8 @@ namespace ShipyardDataBaseImplement.Migrations
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Ship");
});
@@ -191,6 +268,8 @@ namespace ShipyardDataBaseImplement.Migrations
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Client", b =>
{
b.Navigation("Messages");
b.Navigation("Orders");
});
@@ -199,6 +278,11 @@ namespace ShipyardDataBaseImplement.Migrations
b.Navigation("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Ship", b =>
{
b.Navigation("Details");

View File

@@ -17,6 +17,8 @@ namespace ShipyardDataBaseImplement.Models
public string Password { get; set; } = string.Empty;
[ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new();
[ForeignKey("ClientId")]
public virtual List<Message> Messages { get; set; } = new();
public static Client? Create(ClientBindingModel model)
{
if (model == null)

View File

@@ -0,0 +1,75 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
namespace ShipyardDataBaseImplement.Models
{
public class Implementer : IImplementerModel
{
public int Id { get; set; }
[Required]
public string ImplementerFIO { get; set; } = String.Empty;
[Required]
public string Password { get; set; } = String.Empty;
[Required]
public int WorkExperience { get; set; }
[Required]
public int Qualification { get; set; }
[ForeignKey("ImplementerId")]
public virtual List<Order> Orders { get; set; } = new();
public static Implementer? Create(ImplementerBindingModel model)
{
if (model == null)
{
return null;
}
return new Implementer()
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification
};
}
public static Implementer Create(ImplementerViewModel model)
{
return new Implementer
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification
};
}
public void Update(ImplementerBindingModel model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification
};
}
}

View File

@@ -0,0 +1,51 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
using System.ComponentModel.DataAnnotations;
namespace ShipyardDataBaseImplement.Models
{
public class Message : IMessageInfoModel
{
[Key]
public string MessageId { get; private set; } = string.Empty;
public int? ClientId { get; private set; }
public string SenderName { get; private set; } = string.Empty;
public DateTime DateDelivery { get; private set; } = DateTime.Now;
public string Subject { get; private set; } = string.Empty;
public string Body { get; private set; } = string.Empty;
public Client? Client { get; private set; }
public static Message? Create(MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new()
{
Body = model.Body,
Subject = model.Subject,
ClientId = model.ClientId,
MessageId = model.MessageId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
};
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
Subject = Subject,
ClientId = ClientId,
MessageId = MessageId,
SenderName = SenderName,
DateDelivery = DateDelivery,
};
}
}

View File

@@ -12,7 +12,8 @@ namespace ShipyardDataBaseImplement.Models
public int ShipId { get; set; }
[Required]
public int ClientId { get; set; }
[Required]
public int? ImplementerId { get; set; }
[Required]
public int Count { get; set; }
[Required]
public double Sum { get; set; }
@@ -24,7 +25,8 @@ namespace ShipyardDataBaseImplement.Models
public int Id { get; set; }
public virtual Ship Ship { get; set; }
public virtual Client Client { get; set; }
public static Order? Create(OrderBindingModel? model)
public virtual Implementer? Implementer { get; set; }
public static Order? Create(OrderBindingModel? model)
{
if (model == null)
{
@@ -35,7 +37,8 @@ namespace ShipyardDataBaseImplement.Models
Id = model.Id,
ShipId = model.ShipId,
ClientId = model.ClientId,
Count = model.Count,
ImplementerId = model.ImplementerId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
@@ -51,7 +54,8 @@ namespace ShipyardDataBaseImplement.Models
}
Status = model.Status;
DateImplement = model.DateImplement;
}
ImplementerId = model.ImplementerId;
}
public OrderViewModel GetViewModel => new()
{
@@ -59,7 +63,9 @@ namespace ShipyardDataBaseImplement.Models
ShipId = ShipId,
ClientId = ClientId,
ClientFIO = Client.ClientFIO,
Count = Count,
ImplementerId = ImplementerId,
ImplementerFIO = Implementer?.ImplementerFIO ?? string.Empty,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,

View File

@@ -18,6 +18,8 @@ namespace ShipyardDataBaseImplement
public virtual DbSet<ShipDetail> ShipDetails { set; get; }
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Client> Clients { set; get; }
public virtual DbSet<Implementer> Implementers { set; get; }
public virtual DbSet<Message> Messages { set; get; }
}
}

View File

@@ -20,4 +20,8 @@
<ProjectReference Include="..\ShipyardDataModels\ShipyardDataModels.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,13 @@
namespace ShipyardDataModels.Models
{
public interface IImplementerModel : IId
{
string ImplementerFIO { get; }
string Password { get; }
int WorkExperience { get; }
int Qualification { get; }
}
}

View File

@@ -0,0 +1,17 @@
namespace ShipyardDataModels.Models
{
public interface IMessageInfoModel
{
string MessageId { get; }
int? ClientId { get; }
string SenderName { get; }
DateTime DateDelivery { get; }
string Subject { get; }
string Body { get; }
}
}

View File

@@ -6,7 +6,8 @@ namespace ShipyardDataModels.Models
{
int ShipId { get; }
int ClientId { get; }
int Count { get; }
int? ImplementerId { get; }
int Count { get; }
double Sum { get; }
OrderStatus Status { get; }
DateTime DateCreate { get; }

View File

@@ -10,10 +10,14 @@ namespace ShipyardFileImplement
private readonly string OrderFileName = "Order.xml";
private readonly string ShipFileName = "Ship.xml";
private readonly string ClientFileName = "Client.xml";
private readonly string ImplementerFileName = "Implementer.xml";
private readonly string MessageFileName = "Message.xml";
public List<Detail> Details { get; private set; }
public List<Order> Orders { get; private set; }
public List<Ship> Ships { get; private set; }
public List<Client> Clients { get; private set; }
public List<Implementer> Implementers { get; private set; }
public List<Message> Messages { get; private set; }
public static DataFileSingleton GetInstance()
{
if (instance == null)
@@ -26,12 +30,16 @@ namespace ShipyardFileImplement
public void SaveShips() => SaveData(Ships, ShipFileName, "Ships", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
public void SaveMessages() => SaveData(Messages, MessageFileName, "Messages", x => x.GetXElement);
private DataFileSingleton()
{
Details = LoadData(DetailFileName, "Detail", x => Detail.Create(x)!)!;
Ships = LoadData(ShipFileName, "Ship", x => Ship.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
Messages = LoadData(MessageFileName, "Message", x => Message.Create(x)!)!;
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName,
Func<XElement, T> selectFunction)

View File

@@ -0,0 +1,83 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardFileImplement.Models;
namespace ShipyardFileImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
private readonly DataFileSingleton source;
public ImplementerStorage()
{
source = DataFileSingleton.GetInstance();
}
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;
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (model.Id.HasValue)
{
return source.Implementers
.FirstOrDefault(x => (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 new();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
return new();
}
return source.Implementers.Where(x =>
x.ImplementerFIO.Contains(model.ImplementerFIO)).Select(x => x.GetViewModel).ToList();
}
public List<ImplementerViewModel> GetFullList()
{
return source.Implementers.Select(x => x.GetViewModel).ToList();
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
model.Id = source.Implementers.Count > 0 ? source.Implementers.Max(x => x.Id) + 1 : 1;
var newImplementer = Implementer.Create(model);
if (newImplementer == null)
{
return null;
}
source.Implementers.Add(newImplementer);
source.SaveImplementers();
return newImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
var implementer = source.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (implementer == null)
{
return null;
}
implementer.Update(model);
source.SaveImplementers();
return implementer.GetViewModel;
}
}
}

View File

@@ -0,0 +1,53 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardFileImplement.Models;
namespace ShipyardFileImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataFileSingleton source;
public MessageInfoStorage()
{
source = DataFileSingleton.GetInstance();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId))
{
return null;
}
return source.Messages.FirstOrDefault(x =>
x.MessageId == model.MessageId)?.GetViewModel;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId))
{
return new();
}
return source.Messages.Where(x =>
x.ClientId == model.ClientId).Select(x => x.GetViewModel).ToList();
}
public List<MessageInfoViewModel> GetFullList()
{
return source.Messages.Select(x => x.GetViewModel).ToList();
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = Message.Create(model);
if (newMessage == null)
{
return null;
}
source.Messages.Add(newMessage);
source.SaveMessages();
return newMessage.GetViewModel;
}
}
}

View File

@@ -42,19 +42,30 @@ namespace ShipyardFileImplement.Implements
.Select(x => x.GetViewModel)
.ToList();
}
return new();
else if (model.ImplementerId.HasValue)
{
return source.Orders
.Where(x => x.ImplementerId == model.ImplementerId)
.Select(x => x.GetViewModel)
.ToList();
}
return new();
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
return source.Orders.FirstOrDefault(x =>
(model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
if (model.Id.HasValue)
{
return source.Orders.FirstOrDefault(x =>
(model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
else if (model.ImplementerId.HasValue)
{
return source.Orders.FirstOrDefault(x =>
(x.ImplementerId == model.ImplementerId))?.GetViewModel;
}
return null;
}
private OrderViewModel GetViewModel(Order order)
{
var viewModel = order.GetViewModel;

View File

@@ -0,0 +1,76 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
using System.Xml.Linq;
namespace ShipyardFileImplement.Models
{
public class Implementer : IImplementerModel
{
public string ImplementerFIO { get; set; } = String.Empty;
public string Password { get; set; } = String.Empty;
public int WorkExperience { get; set; }
public int Qualification { get; set; }
public int Id { get; set; }
public static Implementer? Create(ImplementerBindingModel? model)
{
if (model == null)
{
return null;
}
return new Implementer()
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification
};
}
public static Implementer? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Implementer()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ImplementerFIO = element.Element("ImplementerFIO")!.Value,
Password = element.Element("Password")!.Value,
WorkExperience = Convert.ToInt32(element.Element("WorkExperience")!.Value),
Qualification = Convert.ToInt32(element.Element("Qualification")!.Value)
};
}
public void Update(ImplementerBindingModel? model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification
};
public XElement GetXElement => new("Implementer",
new XAttribute("Id", Id),
new XElement("ImplementerFIO", ImplementerFIO),
new XElement("Password", Password),
new XElement("WorkExperience", WorkExperience),
new XElement("Qualification", Qualification));
}
}

View File

@@ -0,0 +1,74 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
using System.Xml.Linq;
namespace ShipyardFileImplement.Models
{
public class Message : IMessageInfoModel
{
public string MessageId { get; private set; } = string.Empty;
public int? ClientId { get; private set; }
public string SenderName { get; private set; } = string.Empty;
public DateTime DateDelivery { get; private set; } = DateTime.Now;
public string Subject { get; private set; } = string.Empty;
public string Body { get; private set; } = string.Empty;
public static Message? Create(MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new()
{
Body = model.Body,
Subject = model.Subject,
DateDelivery = model.DateDelivery,
SenderName = model.SenderName,
ClientId = model.ClientId,
MessageId = model.MessageId
};
}
public static Message? Create(XElement element)
{
if (element == null)
{
return null;
}
return new()
{
Body = element.Attribute("Body")!.Value,
Subject = element.Attribute("Subject")!.Value,
DateDelivery = Convert.ToDateTime(element.Attribute("DateDelivery")!.Value),
SenderName = element.Attribute("SenderName")!.Value,
ClientId = Convert.ToInt32(element.Attribute("ClientId")!.Value),
MessageId = element.Attribute("MessageId")!.Value,
};
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
Subject = Subject,
DateDelivery = DateDelivery,
SenderName = SenderName,
ClientId = ClientId,
MessageId = MessageId
};
public XElement GetXElement => new("MessageInfo",
new XAttribute("Subject", Subject),
new XAttribute("Body", Body),
new XAttribute("ClientId", ClientId),
new XAttribute("MessageId", MessageId),
new XAttribute("SenderName", SenderName),
new XAttribute("DateDelivery", DateDelivery)
);
}
}

View File

@@ -11,7 +11,8 @@ namespace ShipyardFileImplement.Models
public int Id { get; private set; }
public int ShipId { get; private set; }
public int ClientId { get; private set; }
public int Count { get; private set; }
public int? ImplementerId { get; private set; }
public int Count { get; private set; }
public double Sum { get; private set; }
public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен;
public DateTime DateCreate { get; private set; } = DateTime.Now;
@@ -27,7 +28,8 @@ namespace ShipyardFileImplement.Models
Id = model.Id,
ShipId = model.ShipId,
ClientId = model.ClientId,
Count = model.Count,
ImplementerId = model.ImplementerId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
@@ -46,7 +48,8 @@ namespace ShipyardFileImplement.Models
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ShipId = Convert.ToInt32(element.Element("ShipId")!.Value),
ClientId = Convert.ToInt32(element.Element("ClientId")!.Value),
Count = Convert.ToInt32(element.Element("Count")!.Value),
ImplementerId = Convert.ToInt32(element.Element("ImplementerId")!.Value),
Count = Convert.ToInt32(element.Element("Count")!.Value),
Sum = Convert.ToDouble(element.Element("Sum")!.Value),
DateCreate = DateTime.ParseExact(element.Element("DateCreate")!.Value, "G", null),
};
@@ -69,13 +72,15 @@ namespace ShipyardFileImplement.Models
}
Status = model.Status;
DateImplement = model.DateImplement;
}
ImplementerId = model.ImplementerId;
}
public OrderViewModel GetViewModel => new()
{
ShipId = ShipId,
ClientId = ClientId,
Count = Count,
ImplementerId = ImplementerId,
Count = Count,
Sum = Sum,
DateCreate = DateCreate,
DateImplement = DateImplement,
@@ -87,7 +92,8 @@ namespace ShipyardFileImplement.Models
new XAttribute("Id", Id),
new XElement("ShipId", ShipId),
new XElement("ClientId", ClientId),
new XElement("Count", Count.ToString()),
new XElement("ImplementerId", ImplementerId),
new XElement("Count", Count.ToString()),
new XElement("Sum", Sum.ToString()),
new XElement("Status", Status.ToString()),
new XElement("DateCreate", DateCreate.ToString()),

View File

@@ -9,12 +9,16 @@ namespace ShipyardListImplement
public List<Order> Orders { get; set; }
public List<Ship> Ships { get; set; }
public List<Client> Clients { get; set; }
public List<Implementer> Implementers { get; set; }
public List<Message> Messages { get; set; }
private DataListSingleton()
{
Details = new List<Detail>();
Orders = new List<Order>();
Ships = new List<Ship>();
Clients = new List<Client>();
Implementers = new List<Implementer>();
Messages = new List<Message>();
}
public static DataListSingleton GetInstance()
{

View File

@@ -0,0 +1,115 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardListImplement.Models;
namespace ShipyardListImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
private readonly DataListSingleton _source;
public ImplementerStorage()
{
_source = DataListSingleton.GetInstance();
}
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;
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (model.Id.HasValue)
{
foreach (var implementer in _source.Implementers)
{
if (implementer.Id == model.Id)
{
return implementer.GetViewModel;
}
}
}
else if (!string.IsNullOrEmpty(model.ImplementerFIO) && !string.IsNullOrEmpty(model.Password))
{
foreach (var implementer in _source.Implementers)
{
if (implementer.ImplementerFIO == model.ImplementerFIO && implementer.Password == model.Password)
{
return implementer.GetViewModel;
}
}
}
return null;
}
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;
}
public List<ImplementerViewModel> GetFullList()
{
var result = new List<ImplementerViewModel>();
foreach (var implementer in _source.Implementers)
{
result.Add(implementer.GetViewModel);
}
return result;
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
model.Id = 1;
foreach (var implementer in _source.Implementers)
{
if (model.Id <= implementer.Id)
{
model.Id = implementer.Id + 1;
}
}
var newImplementer = Implementer.Create(model);
if (newImplementer == null)
{
return null;
}
_source.Implementers.Add(newImplementer);
return newImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
foreach (var implementer in _source.Implementers)
{
if (implementer.Id == model.Id)
{
implementer.Update(model);
return implementer.GetViewModel;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,71 @@
using ShipyardListImplement.Models;
using ShipyardListImplement;
using ShipyardContracts.ViewModels;
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
namespace ShipyardListImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataListSingleton _source;
public MessageInfoStorage()
{
_source = DataListSingleton.GetInstance();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId))
{
return null;
}
foreach (var message in _source.Messages)
{
if (message.MessageId == model.MessageId)
{
return message.GetViewModel;
}
}
return null;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
var result = new List<MessageInfoViewModel>();
if (string.IsNullOrEmpty(model.MessageId))
{
return result;
}
foreach (var message in _source.Messages)
{
if (message.ClientId == model.ClientId)
{
result.Add(message.GetViewModel);
}
}
return result;
}
public List<MessageInfoViewModel> GetFullList()
{
var result = new List<MessageInfoViewModel>();
foreach (var message in _source.Messages)
{
result.Add(message.GetViewModel);
}
return result;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = Message.Create(model);
if (newMessage == null)
{
return null;
}
_source.Messages.Add(newMessage);
return newMessage.GetViewModel;
}
}
}

View File

@@ -56,8 +56,18 @@ namespace ShipyardListImplement.Implements
}
}
}
else if (model.ImplementerId.HasValue)
{
foreach (var order in _source.Orders)
{
if (order.ImplementerId == model.ImplementerId)
{
result.Add(GetViewModel(order));
}
}
}
return result;
return result;
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
@@ -71,7 +81,11 @@ namespace ShipyardListImplement.Implements
{
return GetViewModel(order);
}
}
else if (model.ImplementerId.HasValue && model.ImplementerId == order.ImplementerId)
{
return GetViewModel(order);
}
}
return null;
}
public OrderViewModel? Insert(OrderBindingModel model)

View File

@@ -0,0 +1,55 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
namespace ShipyardListImplement.Models
{
public class Implementer : IImplementerModel
{
public string ImplementerFIO { get; set; } = String.Empty;
public string Password { get; set; } = String.Empty;
public int WorkExperience { get; set; }
public int Qualification { get; set; }
public int Id { get; set; }
public static Implementer? Create(ImplementerBindingModel? model)
{
if (model == null)
{
return null;
}
return new Implementer()
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification
};
}
public void Update(ImplementerBindingModel? model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification
};
}
}

View File

@@ -0,0 +1,48 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
namespace ShipyardListImplement.Models
{
public class Message : IMessageInfoModel
{
public string MessageId { get; private set; } = string.Empty;
public int? ClientId { get; private set; }
public string SenderName { get; private set; } = string.Empty;
public DateTime DateDelivery { get; private set; } = DateTime.Now;
public string Subject { get; private set; } = string.Empty;
public string Body { get; private set; } = string.Empty;
public static Message? Create(MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new()
{
Body = model.Body,
Subject = model.Subject,
DateDelivery = model.DateDelivery,
SenderName = model.SenderName,
ClientId = model.ClientId,
MessageId = model.MessageId
};
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
Subject = Subject,
DateDelivery = DateDelivery,
SenderName = SenderName,
ClientId = ClientId,
MessageId = MessageId
};
}
}

View File

@@ -2,6 +2,7 @@
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Enums;
using ShipyardDataModels.Models;
using System.Reflection;
namespace ShipyardListImplement.Models
{
@@ -10,7 +11,8 @@ namespace ShipyardListImplement.Models
public int Id { get; private set; }
public int ShipId { get; private set; }
public int ClientId { get; private set; }
public int Count { get; private set; }
public int? ImplementerId { get; private set; }
public int Count { get; private set; }
public double Sum { get; private set; }
public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен;
public DateTime DateCreate { get; private set; } = DateTime.Now;
@@ -27,7 +29,8 @@ namespace ShipyardListImplement.Models
Id = model.Id,
ShipId = model.ShipId,
ClientId = model.ClientId,
Count = model.Count,
ImplementerId = model.ImplementerId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
@@ -42,13 +45,15 @@ namespace ShipyardListImplement.Models
}
Status = model.Status;
DateImplement = model.DateImplement;
}
ImplementerId = model.ImplementerId;
}
public OrderViewModel GetViewModel => new()
{
Id = Id,
ShipId = ShipId,
ClientId = ClientId,
Count = Count,
ImplementerId = ImplementerId,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,

View File

@@ -14,10 +14,12 @@ namespace ShipyardRestApi.Controllers
private readonly IClientLogic _logic;
public ClientController(IClientLogic logic, ILogger<ClientController> logger)
private readonly IMessageInfoLogic _mailLogic;
public ClientController(IClientLogic logic, ILogger<ClientController> logger, IMessageInfoLogic mailLogic)
{
_logger = logger;
_logic = logic;
_mailLogic = mailLogic;
}
[HttpGet]
@@ -65,5 +67,21 @@ namespace ShipyardRestApi.Controllers
throw;
}
}
[HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientId)
{
try
{
return _mailLogic.ReadList(new MessageInfoSearchModel
{
ClientId = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения писем клиента");
throw;
}
}
}
}

View File

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

View File

@@ -3,6 +3,8 @@ using ShipyardBusinessLogic.BusinessLogics;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.StoragesContracts;
using ShipyardDataBaseImplement.Implements;
using ShipyardBusinessLogic.MailWorker;
using ShipyardContracts.BindingModels;
var builder = WebApplication.CreateBuilder(args);
@@ -13,10 +15,13 @@ builder.Logging.AddLog4Net("log4net.config");
builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IShipStorage, ShipStorage>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IShipLogic, ShipLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
@@ -27,6 +32,17 @@ builder.Services.AddSwaggerGen(c =>
var app = builder.Build();
var mailSender = app.Services.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty,
MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty,
SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty,
SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()),
PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty,
PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString())
});
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{

View File

@@ -5,5 +5,11 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"SmtpClientHost": "smtp.gmail.com",
"SmtpClientPort": "587",
"PopHost": "pop.gmail.com",
"PopPort": "995",
"MailLogin": "labaratotnaya@gmail.com",
"MailPassword": "slxd cyur sfpt chwf"
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SmtpClientHost" value="smtp.gmail.com" />
<add key="SmtpClientPort" value="587" />
<add key="PopHost" value="pop.gmail.com" />
<add key="PopPort" value="995" />
<add key="MailLogin" value="labaratotnaya@gmail.com" />
<add key="MailPassword" value="slxd cyur sfpt chwf" />
</appSettings>
</configuration>

View File

@@ -115,8 +115,8 @@ namespace ShipyardView
var operationResult = _logicO.CreateOrder(new OrderBindingModel
{
ShipId = Convert.ToInt32(comboBoxShips.SelectedValue),
Count = Convert.ToInt32(textBoxCount.Text),
ClientId = Convert.ToInt32(comboBoxClients.SelectedValue),
Count = Convert.ToInt32(textBoxCount.Text),
Sum = Convert.ToDouble(textBoxSum.Text)
});
if (!operationResult)

View File

@@ -0,0 +1,163 @@
namespace ShipyardView
{
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()
{
this.labelFIO = new System.Windows.Forms.Label();
this.labelPassword = new System.Windows.Forms.Label();
this.labelExperience = new System.Windows.Forms.Label();
this.labelQualification = new System.Windows.Forms.Label();
this.textBoxFIO = new System.Windows.Forms.TextBox();
this.textBoxPassword = new System.Windows.Forms.TextBox();
this.textBoxExperience = new System.Windows.Forms.TextBox();
this.textBoxQualification = new System.Windows.Forms.TextBox();
this.buttonSave = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// labelFIO
//
this.labelFIO.AutoSize = true;
this.labelFIO.Location = new System.Drawing.Point(32, 9);
this.labelFIO.Name = "labelFIO";
this.labelFIO.Size = new System.Drawing.Size(45, 20);
this.labelFIO.TabIndex = 0;
this.labelFIO.Text = "ФИО:";
//
// labelPassword
//
this.labelPassword.AutoSize = true;
this.labelPassword.Location = new System.Drawing.Point(32, 50);
this.labelPassword.Name = "labelPassword";
this.labelPassword.Size = new System.Drawing.Size(65, 20);
this.labelPassword.TabIndex = 1;
this.labelPassword.Text = "Пароль:";
//
// labelExperience
//
this.labelExperience.AutoSize = true;
this.labelExperience.Location = new System.Drawing.Point(32, 105);
this.labelExperience.Name = "labelExperience";
this.labelExperience.Size = new System.Drawing.Size(102, 20);
this.labelExperience.TabIndex = 2;
this.labelExperience.Text = "Стаж работы:";
//
// labelQualification
//
this.labelQualification.AutoSize = true;
this.labelQualification.Location = new System.Drawing.Point(270, 105);
this.labelQualification.Name = "labelQualification";
this.labelQualification.Size = new System.Drawing.Size(114, 20);
this.labelQualification.TabIndex = 3;
this.labelQualification.Text = "Квалификация:";
//
// textBoxFIO
//
this.textBoxFIO.Location = new System.Drawing.Point(102, 6);
this.textBoxFIO.Name = "textBoxFIO";
this.textBoxFIO.Size = new System.Drawing.Size(282, 27);
this.textBoxFIO.TabIndex = 4;
//
// textBoxPassword
//
this.textBoxPassword.Location = new System.Drawing.Point(103, 50);
this.textBoxPassword.Name = "textBoxPassword";
this.textBoxPassword.Size = new System.Drawing.Size(281, 27);
this.textBoxPassword.TabIndex = 5;
//
// textBoxExperience
//
this.textBoxExperience.Location = new System.Drawing.Point(140, 105);
this.textBoxExperience.Name = "textBoxExperience";
this.textBoxExperience.Size = new System.Drawing.Size(124, 27);
this.textBoxExperience.TabIndex = 6;
//
// textBoxQualification
//
this.textBoxQualification.Location = new System.Drawing.Point(390, 105);
this.textBoxQualification.Name = "textBoxQualification";
this.textBoxQualification.Size = new System.Drawing.Size(96, 27);
this.textBoxQualification.TabIndex = 7;
//
// buttonSave
//
this.buttonSave.Location = new System.Drawing.Point(270, 157);
this.buttonSave.Name = "buttonSave";
this.buttonSave.Size = new System.Drawing.Size(94, 29);
this.buttonSave.TabIndex = 8;
this.buttonSave.Text = "Сохранить";
this.buttonSave.UseVisualStyleBackColor = true;
this.buttonSave.Click += new System.EventHandler(this.ButtonSave_Click);
//
// buttonCancel
//
this.buttonCancel.Location = new System.Drawing.Point(392, 157);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(94, 29);
this.buttonCancel.TabIndex = 9;
this.buttonCancel.Text = "Отмена";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
//
// FormImplementer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(498, 202);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonSave);
this.Controls.Add(this.textBoxQualification);
this.Controls.Add(this.textBoxExperience);
this.Controls.Add(this.textBoxPassword);
this.Controls.Add(this.textBoxFIO);
this.Controls.Add(this.labelQualification);
this.Controls.Add(this.labelExperience);
this.Controls.Add(this.labelPassword);
this.Controls.Add(this.labelFIO);
this.Name = "FormImplementer";
this.Text = "Исполнитель";
this.Load += new System.EventHandler(this.FormImplementer_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Label labelFIO;
private Label labelPassword;
private Label labelExperience;
private Label labelQualification;
private TextBox textBoxFIO;
private TextBox textBoxPassword;
private TextBox textBoxExperience;
private TextBox textBoxQualification;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@@ -0,0 +1,91 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
namespace ShipyardView
{
public partial class FormImplementer : Form
{
private readonly ILogger _logger;
private readonly IImplementerLogic _logic;
private int? _id;
public int Id { set { _id = value; } }
public FormImplementer(ILogger<FormDetail> logger, IImplementerLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormImplementer_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
try
{
_logger.LogInformation("Получение исполнителя");
var view = _logic.ReadElement(new ImplementerSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxFIO.Text = view.ImplementerFIO;
textBoxExperience.Text = view.WorkExperience.ToString();
textBoxPassword.Text = view.Password;
textBoxQualification.Text = view.Qualification.ToString();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения исполнителя");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxFIO.Text))
{
MessageBox.Show("Заполните ФИО", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение исполнителя");
try
{
var model = new ImplementerBindingModel
{
Id = _id ?? 0,
ImplementerFIO = textBoxFIO.Text,
Password = textBoxPassword.Text,
WorkExperience = Convert.ToInt32(textBoxExperience.Text),
Qualification = Convert.ToInt32(textBoxQualification.Text),
};
var operationResult = _id.HasValue ? _logic.Update(model) :
_logic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения компонента");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void 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,121 @@
namespace ShipyardView
{
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()
{
dataGridView = new DataGridView();
buttonAdd = new Button();
buttonUpd = new Button();
buttonDel = new Button();
buttonRef = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AllowUserToResizeColumns = false;
dataGridView.AllowUserToResizeRows = false;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(564, 450);
dataGridView.TabIndex = 0;
//
// buttonAdd
//
buttonAdd.Location = new Point(637, 37);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(94, 29);
buttonAdd.TabIndex = 1;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// buttonUpd
//
buttonUpd.Location = new Point(637, 100);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(94, 29);
buttonUpd.TabIndex = 2;
buttonUpd.Text = "Изменить";
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonDel
//
buttonDel.Location = new Point(637, 164);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(94, 29);
buttonDel.TabIndex = 3;
buttonDel.Text = "Удалить";
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonRef
//
buttonRef.Location = new Point(637, 228);
buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(94, 29);
buttonRef.TabIndex = 4;
buttonRef.Text = "Обновить";
buttonRef.UseVisualStyleBackColor = true;
buttonRef.Click += ButtonRef_Click;
//
// FormImplementers
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(buttonRef);
Controls.Add(buttonDel);
Controls.Add(buttonUpd);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormImplementers";
Text = "Исполнители";
Load += FormImplementers_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonAdd;
private Button buttonUpd;
private Button buttonDel;
private Button buttonRef;
}
}

View File

@@ -0,0 +1,107 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using System.Windows.Forms;
namespace ShipyardView
{
public partial class FormImplementers : Form
{
private readonly ILogger _logger;
private readonly IImplementerLogic _logic;
public FormImplementers(ILogger<FormDetails> logger, IImplementerLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormImplementers_Load(object sender, EventArgs e)
{
LoadData();
}
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;
dataGridView.Columns["Password"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["WorkExperience"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["Qualification"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка исполнителей");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки исполнителей");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
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();
}
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementer));
if (service is FormImplementer form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void ButtonDel_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);
}
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

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

View File

@@ -0,0 +1,67 @@
namespace ShipyardView
{
partial class FormMails
{
/// <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()
{
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AllowUserToResizeRows = false;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(800, 450);
dataGridView.TabIndex = 0;
//
// FormMails
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridView);
Name = "FormMails";
Text = "Письма";
Load += FormMails_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
}
}

View File

@@ -0,0 +1,41 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BusinessLogicsContracts;
using System.Windows.Forms;
namespace ShipyardView
{
public partial class FormMails : Form
{
private readonly ILogger _logger;
private readonly IMessageInfoLogic _logic;
public FormMails(ILogger<FormMails> logger, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormMails_Load(object sender, EventArgs e)
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["MessageId"].Visible = false;
dataGridView.Columns["Body"].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

@@ -33,17 +33,18 @@
toolStripMenu = new ToolStripDropDownButton();
деталиToolStripMenuItem = new ToolStripMenuItem();
кораблиToolStripMenuItem = new ToolStripMenuItem();
clientsToolStripMenuItem = new ToolStripMenuItem();
исполнителиToolStripMenuItem = new ToolStripMenuItem();
отчетыToolStripMenuItem = new ToolStripDropDownButton();
ShipsToolStripMenuItem = new ToolStripMenuItem();
shipsDetailsToolStripMenuItem = new ToolStripMenuItem();
ordersToolStripMenuItem = new ToolStripMenuItem();
startWorkToolStripMenuItem = new ToolStripButton();
mailsToolStripMenuItem = new ToolStripButton();
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonTakeInWork = new Button();
buttonReady = new Button();
buttonIssue = new Button();
buttonRefresh = new Button();
clientsToolStripMenuItem = new ToolStripMenuItem();
toolStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
@@ -51,17 +52,17 @@
// toolStrip
//
toolStrip.ImageScalingSize = new Size(20, 20);
toolStrip.Items.AddRange(new ToolStripItem[] { toolStripMenu, отчетыToolStripMenuItem });
toolStrip.Items.AddRange(new ToolStripItem[] { toolStripMenu, отчетыToolStripMenuItem, startWorkToolStripMenuItem, mailsToolStripMenuItem });
toolStrip.Location = new Point(0, 0);
toolStrip.Name = "toolStrip";
toolStrip.Size = new Size(1251, 27);
toolStrip.Size = new Size(1522, 27);
toolStrip.TabIndex = 0;
toolStrip.Text = "Справочники";
//
// toolStripMenu
//
toolStripMenu.DisplayStyle = ToolStripItemDisplayStyle.Text;
toolStripMenu.DropDownItems.AddRange(new ToolStripItem[] { деталиToolStripMenuItem, кораблиToolStripMenuItem, clientsToolStripMenuItem });
toolStripMenu.DropDownItems.AddRange(new ToolStripItem[] { деталиToolStripMenuItem, кораблиToolStripMenuItem, clientsToolStripMenuItem, исполнителиToolStripMenuItem });
toolStripMenu.Image = (Image)resources.GetObject("toolStripMenu.Image");
toolStripMenu.ImageTransparentColor = Color.Magenta;
toolStripMenu.Name = "toolStripMenu";
@@ -71,17 +72,31 @@
// деталиToolStripMenuItem
//
деталиToolStripMenuItem.Name = еталиToolStripMenuItem";
деталиToolStripMenuItem.Size = new Size(224, 26);
деталиToolStripMenuItem.Size = new Size(185, 26);
деталиToolStripMenuItem.Text = "Детали";
деталиToolStripMenuItem.Click += ДеталиToolStripMenuItem_Click;
//
// кораблиToolStripMenuItem
//
кораблиToolStripMenuItem.Name = ораблиToolStripMenuItem";
кораблиToolStripMenuItem.Size = new Size(224, 26);
кораблиToolStripMenuItem.Size = new Size(185, 26);
кораблиToolStripMenuItem.Text = "Корабли";
кораблиToolStripMenuItem.Click += КораблиToolStripMenuItem_Click;
//
// clientsToolStripMenuItem
//
clientsToolStripMenuItem.Name = "clientsToolStripMenuItem";
clientsToolStripMenuItem.Size = new Size(185, 26);
clientsToolStripMenuItem.Text = "Клиенты";
clientsToolStripMenuItem.Click += clientsToolStripMenuItem_Click;
//
// исполнителиToolStripMenuItem
//
исполнителиToolStripMenuItem.Name = сполнителиToolStripMenuItem";
исполнителиToolStripMenuItem.Size = new Size(185, 26);
исполнителиToolStripMenuItem.Text = "Исполнители";
исполнителиToolStripMenuItem.Click += ImplementerToolStripMenuItem_Click;
//
// отчетыToolStripMenuItem
//
отчетыToolStripMenuItem.DisplayStyle = ToolStripItemDisplayStyle.Text;
@@ -113,12 +128,33 @@
ordersToolStripMenuItem.Text = "Список заказов";
ordersToolStripMenuItem.Click += ordersToolStripMenuItem_Click;
//
// startWorkToolStripMenuItem
//
startWorkToolStripMenuItem.DisplayStyle = ToolStripItemDisplayStyle.Text;
startWorkToolStripMenuItem.Image = (Image)resources.GetObject("startWorkToolStripMenuItem.Image");
startWorkToolStripMenuItem.ImageTransparentColor = Color.Magenta;
startWorkToolStripMenuItem.Name = "startWorkToolStripMenuItem";
startWorkToolStripMenuItem.Size = new Size(104, 24);
startWorkToolStripMenuItem.Text = "Запуск работ";
startWorkToolStripMenuItem.Click += startWorkToolStripMenuItem_Click;
//
// mailsToolStripMenuItem
//
mailsToolStripMenuItem.DisplayStyle = ToolStripItemDisplayStyle.Text;
mailsToolStripMenuItem.Image = (Image)resources.GetObject("mailsToolStripMenuItem.Image");
mailsToolStripMenuItem.ImageTransparentColor = Color.Magenta;
mailsToolStripMenuItem.Name = "mailsToolStripMenuItem";
mailsToolStripMenuItem.Size = new Size(67, 24);
mailsToolStripMenuItem.Text = "Письма";
mailsToolStripMenuItem.Click += mailsToolStripMenuItem_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AllowUserToResizeColumns = false;
dataGridView.AllowUserToResizeRows = false;
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(0, 28);
dataGridView.Name = "dataGridView";
@@ -126,12 +162,12 @@
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(984, 366);
dataGridView.Size = new Size(1287, 366);
dataGridView.TabIndex = 1;
//
// buttonCreateOrder
//
buttonCreateOrder.Location = new Point(1032, 51);
buttonCreateOrder.Location = new Point(1323, 46);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(178, 29);
buttonCreateOrder.TabIndex = 2;
@@ -139,29 +175,9 @@
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += ButtonCreateOrder_Click;
//
// buttonTakeInWork
//
buttonTakeInWork.Location = new Point(1032, 110);
buttonTakeInWork.Name = "buttonTakeInWork";
buttonTakeInWork.Size = new Size(178, 29);
buttonTakeInWork.TabIndex = 3;
buttonTakeInWork.Text = "Отдать на выполнение";
buttonTakeInWork.UseVisualStyleBackColor = true;
buttonTakeInWork.Click += ButtonTakeOrderInWork_Click;
//
// buttonReady
//
buttonReady.Location = new Point(1032, 171);
buttonReady.Name = "buttonReady";
buttonReady.Size = new Size(178, 29);
buttonReady.TabIndex = 4;
buttonReady.Text = "Заказ готов";
buttonReady.UseVisualStyleBackColor = true;
buttonReady.Click += ButtonOrderReady_Click;
//
// buttonIssue
//
buttonIssue.Location = new Point(1032, 236);
buttonIssue.Location = new Point(1323, 113);
buttonIssue.Name = "buttonIssue";
buttonIssue.Size = new Size(178, 29);
buttonIssue.TabIndex = 5;
@@ -171,7 +187,7 @@
//
// buttonRefresh
//
buttonRefresh.Location = new Point(1032, 303);
buttonRefresh.Location = new Point(1323, 180);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(178, 29);
buttonRefresh.TabIndex = 6;
@@ -179,22 +195,13 @@
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRef_Click;
//
// clientsToolStripMenuItem
//
clientsToolStripMenuItem.Name = "clientsToolStripMenuItem";
clientsToolStripMenuItem.Size = new Size(224, 26);
clientsToolStripMenuItem.Text = "Клиенты";
clientsToolStripMenuItem.Click += clientsToolStripMenuItem_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1251, 391);
ClientSize = new Size(1522, 391);
Controls.Add(buttonRefresh);
Controls.Add(buttonIssue);
Controls.Add(buttonReady);
Controls.Add(buttonTakeInWork);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(toolStrip);
@@ -213,8 +220,6 @@
private ToolStrip toolStrip;
private DataGridView dataGridView;
private Button buttonCreateOrder;
private Button buttonTakeInWork;
private Button buttonReady;
private Button buttonIssue;
private Button buttonRefresh;
private ToolStripDropDownButton toolStripMenu;
@@ -225,5 +230,8 @@
private ToolStripMenuItem shipsDetailsToolStripMenuItem;
private ToolStripMenuItem ordersToolStripMenuItem;
private ToolStripMenuItem clientsToolStripMenuItem;
private ToolStripMenuItem исполнителиToolStripMenuItem;
private ToolStripButton startWorkToolStripMenuItem;
private ToolStripButton mailsToolStripMenuItem;
}
}

View File

@@ -7,173 +7,152 @@ using System.Windows.Forms;
namespace ShipyardView
{
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ShipId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["ShipName"].AutoSizeMode =
DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ДеталиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormDetails));
if (service is FormDetails form)
{
form.ShowDialog();
}
}
private void КораблиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormShips));
if (service is FormShips form)
{
form.ShowDialog();
}
}
private void ButtonCreateOrder_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
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("Заказ No{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);
}
}
}
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("Заказ No{id}. Меняется статус на 'Готов'", id);
try
{
var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ButtonIssuedOrder_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ No{id}. Меняется статус на 'Выдан'", id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ No{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
private void ShipsToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SaveComponentsToWordFile(new ReportBindingModel { FileName = dialog.FileName });
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
private readonly IWorkProcess _workProcess;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
_workProcess = workProcess;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ShipId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ДеталиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormDetails));
if (service is FormDetails form)
{
form.ShowDialog();
}
}
private void КораблиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormShips));
if (service is FormShips form)
{
form.ShowDialog();
}
}
private void ButtonCreateOrder_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
private void ButtonIssuedOrder_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ No{id}. Меняется статус на 'Выдан'", id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ No{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
private void ShipsToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SaveComponentsToWordFile(new ReportBindingModel { FileName = dialog.FileName });
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void shipDetailsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportShipDetails));
if (service is FormReportShipDetails form)
{
form.ShowDialog();
}
}
private void shipDetailsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportShipDetails));
if (service is FormReportShipDetails form)
{
form.ShowDialog();
}
}
private void ordersToolStripMenuItem_Click(object sender, EventArgs e)
private void ordersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
}
private void clientsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
private void mailsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
var service = Program.ServiceProvider?.GetService(typeof(FormMails));
if (service is FormMails form)
{
form.ShowDialog();
}
}
private void clientsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
}
private void ImplementerToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if (service is FormImplementers form)
{
form.ShowDialog();
}
}
private void startWorkToolStripMenuItem_Click(object sender, EventArgs e)
{
_workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}

View File

@@ -141,6 +141,28 @@
U87f4aUApcXhnrI9Jzg/laQKFntXlHM+lSQK5psL5fvbp/JvJLGCQqmSWM5JkiCT84igXGtSrruKLQ0T
luAdmZxHBG37FFuWBC/j5XKOmX8WAH7rcI6ZMffPgjQwN2bXJgDo/COBTpjneQ2dML0PY3cISreGe8HM
qgAAAABJRU5ErkJggg==
</value>
</data>
<data name="startWorkToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAEKSURBVEhL3ZG9DsFQHMXvczDZvIOtXsHObuhqkViI3Quw
6CYmNoMYJJ0NBiFFIoIytOuf0+TeXP3yde+iyS+3OcP53Z4y3/dJJ4HAsiwyTVMp6BQCBIZhKAWdEcHV
vSlBmeB82NFy1KLluEWOPRC5MoHdMWhazwi4RJlALgf4EuT6BI+5kCsTrGddUY658E+QvyXYHq9UnRyC
U87f4aUApcXhnrI9Jzg/laQKFntXlHM+lSQK5psL5fvbp/JvJLGCQqmSWM5JkiCT84igXGtSrruKLQ0T
luAdmZxHBG37FFuWBC/j5XKOmX8WAH7rcI6ZMffPgjQwN2bXJgDo/COBTpjneQ2dML0PY3cISreGe8HM
qgAAAABJRU5ErkJggg==
</value>
</data>
<data name="mailsToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAEKSURBVEhL3ZG9DsFQHMXvczDZvIOtXsHObuhqkViI3Quw
6CYmNoMYJJ0NBiFFIoIytOuf0+TeXP3yde+iyS+3OcP53Z4y3/dJJ4HAsiwyTVMp6BQCBIZhKAWdEcHV
vSlBmeB82NFy1KLluEWOPRC5MoHdMWhazwi4RJlALgf4EuT6BI+5kCsTrGddUY658E+QvyXYHq9UnRyC
U87f4aUApcXhnrI9Jzg/laQKFntXlHM+lSQK5psL5fvbp/JvJLGCQqmSWM5JkiCT84igXGtSrruKLQ0T
luAdmZxHBG37FFuWBC/j5XKOmX8WAH7rcI6ZMffPgjQwN2bXJgDo/COBTpjneQ2dML0PY3cISreGe8HM
qgAAAABJRU5ErkJggg==
</value>
</data>
</root>

View File

@@ -1,18 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true" internalLogLevel="Info">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true" internalLogLevel="Info">
<targets>
<target xsi:type="File" name="tofile" fileName="logs/log-${shortdate}.log" />
<target xsi:type="File" name="tofile" fileName="log-${shortdate}.log" />
</targets>
<target name="console" xsi:type="Console" layout="Access Log|${level:uppercase=true}|${logger}|${message}">
<highlight-row condition="true" foregroundColor="red"/>
</target>
<rules>
<logger name="*" minlevel="Info" writeTo="tofile,console" />
<logger name="*" minlevel="Debug" writeTo="tofile" />
</rules>
</nlog>
</configuration>

View File

@@ -2,10 +2,14 @@ using Microsoft.Extensions.DependencyInjection;
using ShipyardBusinessLogic.BusinessLogics;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.BindingModels;
using ShipyardBusinessLogic.MailWorker;
using ShipyardDataBaseImplement.Implements;
using ShipyardBusinessLogic.OfficePackage.Implements;
using ShipyardBusinessLogic.OfficePackage;
using NLog.Extensions.Logging;
using Microsoft.Extensions.Logging;
namespace ShipyardView
{
@@ -23,6 +27,26 @@ namespace ShipyardView
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
try
{
var mailSender = _serviceProvider.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty,
MailPassword = System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty,
SmtpClientHost = System.Configuration.ConfigurationManager.AppSettings["SmtpClientHost"] ?? string.Empty,
SmtpClientPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SmtpClientPort"]),
PopHost = System.Configuration.ConfigurationManager.AppSettings["PopHost"] ?? string.Empty,
PopPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PopPort"])
});
var timer = new System.Threading.Timer(new TimerCallback(MailCheck!), null, 0, 100000);
}
catch (Exception ex)
{
var logger = _serviceProvider.GetService<ILogger>();
logger?.LogError(ex, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
private static void ConfigureServices(ServiceCollection services)
@@ -35,14 +59,20 @@ namespace ShipyardView
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IShipStorage, ShipStorage>();
services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
services.AddTransient<IDetailLogic, DetailLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IShipLogic, ShipLogic>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
services.AddTransient<IWorkProcess, WorkModeling>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
services.AddSingleton<AbstractMailWorker, MailKitWorker>();
services.AddTransient<FormMain>();
services.AddTransient<FormDetail>();
services.AddTransient<FormDetails>();
@@ -51,10 +81,13 @@ namespace ShipyardView
services.AddTransient<FormShip>();
services.AddTransient<FormShipDetail>();
services.AddTransient<FormShips>();
services.AddTransient<FormReportShipDetails>();
services.AddTransient<FormImplementer>();
services.AddTransient<FormImplementers>();
services.AddTransient<FormReportShipDetails>();
services.AddTransient<FormReportOrders>();
services.AddTransient<FormMails>();
}
private static void MailCheck(object obj) => ServiceProvider?.GetService<AbstractMailWorker>()?.MailCheck();
}
}

View File

@@ -43,6 +43,9 @@
</ItemGroup>
<ItemGroup>
<None Update="App.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>