Compare commits

..

6 Commits

Author SHA1 Message Date
Marselchi
415df9030b залил 2024-06-17 21:08:40 +04:00
83143fffa4 Merge pull request 'накидываю первую' (#11) from lab1_hard into lab2_hard
Reviewed-on: #11
2024-06-17 20:35:35 +04:00
Marselchi
926a9fa37e Первая сложная типа 2024-04-21 17:13:29 +04:00
Marselchi
8820635bd5 Всё без форм 2024-04-07 20:30:19 +04:00
Marselchi
22eda2809c Фулл вторая лаба получается 2024-03-10 21:25:34 +04:00
Marselchi
f94e335f3d Ультракоммит всей лабы 2024-02-25 20:02:29 +04:00
94 changed files with 6697 additions and 82 deletions

View File

@ -3,7 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34408.163
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shipyard", "Shipyard\Shipyard.csproj", "{0CDFD76A-8254-473F-8285-FF7A15F16F31}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShipyardDataModels", "ShipyardDataModels\ShipyardDataModels.csproj", "{260F4D58-9D03-457C-B522-CE27360CDD31}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShipyardContracts", "ShipyardContracts\ShipyardContracts.csproj", "{C2E0380E-51D2-4B27-A385-459E91DC75CD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShipyardBusinessLogic", "ShipyardBusinessLogic\ShipyardBusinessLogic.csproj", "{652CC6F7-1097-46F4-B516-A010D6D747EA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShipyardListImplement", "ShipyardListImplement\ShipyardListImplement.csproj", "{0F6E8B4C-CD20-4371-8316-E13FDA31AE57}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShipyardView", "ShipyardView\ShipyardView.csproj", "{BE881F13-7D8F-43B7-AA58-18BBE668FA79}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShipyardFileImplement", "ShipyardFileImplement\ShipyardFileImplement.csproj", "{804C4D1B-2098-4653-8CBA-F5931605A28D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -11,10 +21,30 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0CDFD76A-8254-473F-8285-FF7A15F16F31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CDFD76A-8254-473F-8285-FF7A15F16F31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CDFD76A-8254-473F-8285-FF7A15F16F31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CDFD76A-8254-473F-8285-FF7A15F16F31}.Release|Any CPU.Build.0 = Release|Any CPU
{260F4D58-9D03-457C-B522-CE27360CDD31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{260F4D58-9D03-457C-B522-CE27360CDD31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{260F4D58-9D03-457C-B522-CE27360CDD31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{260F4D58-9D03-457C-B522-CE27360CDD31}.Release|Any CPU.Build.0 = Release|Any CPU
{C2E0380E-51D2-4B27-A385-459E91DC75CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2E0380E-51D2-4B27-A385-459E91DC75CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2E0380E-51D2-4B27-A385-459E91DC75CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2E0380E-51D2-4B27-A385-459E91DC75CD}.Release|Any CPU.Build.0 = Release|Any CPU
{652CC6F7-1097-46F4-B516-A010D6D747EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{652CC6F7-1097-46F4-B516-A010D6D747EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{652CC6F7-1097-46F4-B516-A010D6D747EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{652CC6F7-1097-46F4-B516-A010D6D747EA}.Release|Any CPU.Build.0 = Release|Any CPU
{0F6E8B4C-CD20-4371-8316-E13FDA31AE57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F6E8B4C-CD20-4371-8316-E13FDA31AE57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F6E8B4C-CD20-4371-8316-E13FDA31AE57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F6E8B4C-CD20-4371-8316-E13FDA31AE57}.Release|Any CPU.Build.0 = Release|Any CPU
{BE881F13-7D8F-43B7-AA58-18BBE668FA79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE881F13-7D8F-43B7-AA58-18BBE668FA79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE881F13-7D8F-43B7-AA58-18BBE668FA79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE881F13-7D8F-43B7-AA58-18BBE668FA79}.Release|Any CPU.Build.0 = Release|Any CPU
{804C4D1B-2098-4653-8CBA-F5931605A28D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{804C4D1B-2098-4653-8CBA-F5931605A28D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{804C4D1B-2098-4653-8CBA-F5931605A28D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{804C4D1B-2098-4653-8CBA-F5931605A28D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,39 +0,0 @@
namespace Shipyard
{
partial class Form1
{
/// <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.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace Shipyard
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -1,17 +0,0 @@
namespace Shipyard
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
}
}
}

View File

@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,108 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace ShipyardBusinessLogic.BusinessLogics
{
public class DetailLogic : IDetailLogic
{
private readonly ILogger _logger;
private readonly IDetailStorage _detailStorage;
public DetailLogic(ILogger<DetailLogic> logger, IDetailStorage detailStorage)
{
_logger = logger;
_detailStorage = detailStorage;
}
public List<DetailViewModel>? ReadList(DetailSearchModel? model)
{
_logger.LogInformation("ReadList. DetailName:{DetailName}. Id:{Id}", model?.DetailName, model?.Id);
var list = model == null ? _detailStorage.GetFullList() : _detailStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public DetailViewModel? ReadElement(DetailSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. DetailName:{DetailName}. Id:{ Id}", model.DetailName, model.Id);
var element = _detailStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(DetailBindingModel model)
{
CheckModel(model);
if (_detailStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(DetailBindingModel model)
{
CheckModel(model);
if (_detailStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(DetailBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_detailStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(DetailBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.DetailName))
{
throw new ArgumentNullException("Нет названия детали",
nameof(model.DetailName));
}
if (model.Cost <= 0)
{
throw new ArgumentNullException("Цена детали должна быть больше 0", nameof(model.Cost));
}
_logger.LogInformation("Detail. DetailName:{DetailName}. Cost:{ Cost}. Id: { Id}", model.DetailName, model.Cost, model.Id);
var element = _detailStorage.GetElement(new DetailSearchModel
{
DetailName = model.DetailName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Деталь с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,130 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Enums;
namespace ShipyardBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IShopLogic _shopLogic;
private readonly IShipStorage _shipStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IShopLogic shopLogic, IShipStorage shipStorage)
{
_logger = logger;
_orderStorage = orderStorage;
_shopLogic = shopLogic;
_shipStorage = shipStorage;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Insert operation failed. Order status incorrect.");
return false;
}
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.ShipId < 0)
{
throw new ArgumentNullException("Некорректный идентификатор у корабля", nameof(model.ShipId));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Количество кораблей в заказе должно быть больше 0", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentNullException("Сумма заказа должна быть больше 0", nameof(model.Sum));
}
_logger.LogInformation("Order. OrderID:{Id}. Sum:{ Sum}. ShipId: { ShipId}", model.Id, model.Sum, model.ShipId);
}
public bool StatusUpdate(OrderBindingModel model, OrderStatus newStatus)
{
var viewModel = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (viewModel == null)
{
throw new ArgumentNullException(nameof(model));
}
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;
var ship = _shipStorage.GetElement(new() { Id = viewModel.ShipId });
if (ship == null)
{
throw new ArgumentNullException(nameof(ship));
}
if (!_shopLogic.AddShips(ship, viewModel.Count))
{
throw new Exception($"AddShips operation failed");
}
}
else
{
model.DateImplement = viewModel.DateImplement;
}
CheckModel(model, false);
if (_orderStorage.Update(model) == null)
{
model.Status--;
_logger.LogWarning("Change status operation failed");
return false;
}
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выполняется);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выдан);
}
public bool FinishOrder(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Готов);
}
}
}

View File

@ -0,0 +1,108 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
namespace ShipyardBusinessLogic.BusinessLogics
{
public class ShipLogic : IShipLogic
{
private readonly ILogger _logger;
private readonly IShipStorage _shipStorage;
public ShipLogic(ILogger<ShipLogic> logger, IShipStorage shipStorage)
{
_logger = logger;
_shipStorage = shipStorage;
}
public List<ShipViewModel>? ReadList(ShipSearchModel? model)
{
_logger.LogInformation("ReadList. ShipName:{ShipName}. Id:{Id}", model?.ShipName, model?.Id);
var list = model == null ? _shipStorage.GetFullList() : _shipStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public ShipViewModel? ReadElement(ShipSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ShipName:{ShipName}. Id:{ Id}", model.ShipName, model.Id);
var element = _shipStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(ShipBindingModel model)
{
CheckModel(model);
if (_shipStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ShipBindingModel model)
{
CheckModel(model);
if (_shipStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ShipBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_shipStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ShipBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ShipName))
{
throw new ArgumentNullException("Нет названия коробля",
nameof(model.ShipName));
}
if (model.Price <= 0)
{
throw new ArgumentNullException("Цена коробля должна быть больше 0", nameof(model.Price));
}
_logger.LogInformation("Ship. ShipName:{ShipName}. Price:{Price}. Id: {Id}", model.ShipName, model.Price, model.Id);
var element = _shipStorage.GetElement(new ShipSearchModel
{
ShipName = model.ShipName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Корабль с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,206 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
using ShipyardContracts.StoragesContracts;
using ShipyardDataModels.Models;
namespace ShipyardBusinessLogic.BusinessLogics
{
public class ShopLogic : IShopLogic
{
private readonly ILogger _logger;
private readonly IShopStorage _shopStorage;
public ShopLogic(ILogger<ShopLogic> logger, IShopStorage shopStorage)
{
_logger = logger;
_shopStorage = shopStorage;
}
public List<ShopViewModel>? ReadList(ShopSearchModel? model)
{
_logger.LogInformation("ReadList. ShopName: {ShopName}. Id: {Id}", model?.ShopName, model?.Id);
var list = model == null ? _shopStorage.GetFullList() : _shopStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public ShopViewModel? ReadElement(ShopSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ShopName: {ShopName}. Id: {Id}", model.ShopName, model.Id);
var element = _shopStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
return element;
}
public bool Create(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ShopBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id: {Id}", model.Id);
if (_shopStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ShopBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ShopName))
{
throw new ArgumentNullException("Нет названия магазина", nameof(model.ShopName));
}
_logger.LogInformation("Shop. ShopName:{0}. Address:{1}. Id:{2}",
model.ShopName, model.Address, model.Id);
var element = _shopStorage.GetElement(new ShopSearchModel
{
ShopName = model.ShopName
});
if (element != null && element.Id != model.Id && element.ShopName == model.ShopName)
{
throw new InvalidOperationException("Магазин с таким названием уже есть");
}
}
public bool AddShip(ShopSearchModel model, IShipModel ship, int count)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (count <= 0)
{
return false;
throw new ArgumentException("Количество кораблей должно быть больше 0", nameof(count));
}
_logger.LogInformation("AddShip. ShopName:{ShopName}. Id:{Id}", model.ShopName, model.Id);
var element = _shopStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("AddShip element not found");
return false;
}
if (element.Capacity - element.ShopShips.Select(x => x.Value.Item2).Sum() < count)
{
throw new ArgumentNullException("В магазине не хватает места", nameof(count));
}
if (element.ShopShips.TryGetValue(ship.Id, out var pair))
{
element.ShopShips[ship.Id] = (ship, count + pair.Item2);
_logger.LogInformation("AddShip. Added {count} {ship} to '{ShopName}' shop",
count, ship.ShipName, element.ShopName);
}
else
{
element.ShopShips[ship.Id] = (ship, count);
_logger.LogInformation("AddShip. Added {count} new ship {ship} to '{ShopName}' shop",
count, ship.ShipName, element.ShopName);
}
_shopStorage.Update(new()
{
Id = element.Id,
Address = element.Address,
ShopName = element.ShopName,
DateOpen = element.DateOpen,
Capacity = element.Capacity,
ShopShips = element.ShopShips
});
return true;
}
public bool AddShips(IShipModel model, int count)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (count <= 0)
{
throw new ArgumentException("Количество кораблей должно быть больше 0", nameof(count));
}
_logger.LogInformation("AddShips. ShopName:{ShopName}. Id:{Id}", model.ShipName, model.Id);
var allFreeQuantity = _shopStorage.GetFullList().Select(x => x.Capacity - x.ShopShips.Select(x => x.Value.Item2).Sum()).Sum();
if (allFreeQuantity < count)
{
_logger.LogWarning("AddTravels operation failed.");
return false;
}
foreach (var shop in _shopStorage.GetFullList())
{
int freeQuantity = shop.Capacity - shop.ShopShips.Select(x => x.Value.Item2).Sum();
if (freeQuantity <= 0)
{
continue;
}
if (freeQuantity < count)
{
if (!AddShip(new() { Id = shop.Id }, model, freeQuantity))
{
_logger.LogWarning("AddShips operation failed.");
return false;
}
count -= freeQuantity;
}
else
{
if (!AddShip(new() { Id = shop.Id }, model, count))
{
_logger.LogWarning("AddShips operation failed.");
return false;
}
count = 0;
}
if (count == 0)
{
return true;
}
}
_logger.LogWarning("AddShips operation failed.");
return false;
}
public bool SellShips(IShipModel model, int count)
{
return _shopStorage.SellShips(model, count);
}
}
}

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ShipyardContracts\ShipyardContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,11 @@
using ShipyardDataModels.Models;
namespace ShipyardContracts.BindingModels
{
public class DetailBindingModel : IDetailModel
{
public int Id { get; set; }
public string DetailName { get; set; } = string.Empty;
public double Cost { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using ShipyardDataModels.Enums;
using ShipyardDataModels.Models;
namespace ShipyardContracts.BindingModels
{
public class OrderBindingModel : IOrderModel
{
public int Id { get; set; }
public int ShipId { 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;
public DateTime? DateImplement { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using ShipyardDataModels.Models;
namespace ShipyardContracts.BindingModels
{
public class ShipBindingModel : IShipModel
{
public int Id { get; set; }
public string ShipName { get; set; } = String.Empty;
public double Price { get; set; }
public Dictionary<int, (IDetailModel, int)> ShipDetails { get; set; } = new();
}
}

View File

@ -0,0 +1,14 @@
using ShipyardDataModels.Models;
namespace ShipyardContracts.BindingModels
{
public class ShopBindingModel : IShopModel
{
public string ShopName { get; set; } = string.Empty;
public string Address { get; set; } = string.Empty;
public DateTime DateOpen { get; set; } = DateTime.Now;
public int Capacity { get; set; }
public Dictionary<int, (IShipModel, int)> ShopShips { get; set; } = new();
public int Id { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.BusinessLogicsContracts
{
public interface IDetailLogic
{
List<DetailViewModel>? ReadList(DetailSearchModel? model);
DetailViewModel? ReadElement(DetailSearchModel model);
bool Create(DetailBindingModel model);
bool Update(DetailBindingModel model);
bool Delete(DetailBindingModel model);
}
}

View File

@ -0,0 +1,15 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.BusinessLogicsContracts
{
public interface IOrderLogic
{
List<OrderViewModel>? ReadList(OrderSearchModel? model);
bool CreateOrder(OrderBindingModel model);
bool TakeOrderInWork(OrderBindingModel model);
bool FinishOrder(OrderBindingModel model);
bool DeliveryOrder(OrderBindingModel model);
}
}

View File

@ -0,0 +1,15 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.BusinessLogicsContracts
{
public interface IShipLogic
{
List<ShipViewModel>? ReadList(ShipSearchModel? model);
ShipViewModel? ReadElement(ShipSearchModel model);
bool Create(ShipBindingModel model);
bool Update(ShipBindingModel model);
bool Delete(ShipBindingModel model);
}
}

View File

@ -0,0 +1,19 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
namespace ShipyardContracts.BusinessLogicsContracts
{
public interface IShopLogic
{
List<ShopViewModel>? ReadList(ShopSearchModel? model);
ShopViewModel? ReadElement(ShopSearchModel model);
bool Create(ShopBindingModel model);
bool Update(ShopBindingModel model);
bool Delete(ShopBindingModel model);
bool AddShip(ShopSearchModel model, IShipModel ship, int count);
bool AddShips(IShipModel model, int count);
bool SellShips(IShipModel model, int count);
}
}

View File

@ -0,0 +1,8 @@
namespace ShipyardContracts.SearchModels
{
public class DetailSearchModel
{
public int? Id { get; set; }
public string? DetailName { get; set; }
}
}

View File

@ -0,0 +1,7 @@
namespace ShipyardContracts.SearchModels
{
public class OrderSearchModel
{
public int? Id { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace ShipyardContracts.SearchModels
{
public class ShipSearchModel
{
public int? Id { get; set; }
public string? ShipName { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace ShipyardContracts.SearchModels
{
public class ShopSearchModel
{
public int? Id { get; set; }
public string? ShopName { get; set; }
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ShipyardDataModels\ShipyardDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,17 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.StoragesContracts
{
public interface IDetailStorage
{
List<DetailViewModel> GetFullList();
List<DetailViewModel> GetFilteredList(DetailSearchModel model);
DetailViewModel? GetElement(DetailSearchModel model);
DetailViewModel? Insert(DetailBindingModel model);
DetailViewModel? Update(DetailBindingModel model);
DetailViewModel? Delete(DetailBindingModel model);
}
}

View File

@ -0,0 +1,16 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.StoragesContracts
{
public interface IOrderStorage
{
List<OrderViewModel> GetFullList();
List<OrderViewModel> GetFilteredList(OrderSearchModel model);
OrderViewModel? GetElement(OrderSearchModel model);
OrderViewModel? Insert(OrderBindingModel model);
OrderViewModel? Update(OrderBindingModel model);
OrderViewModel? Delete(OrderBindingModel model);
}
}

View File

@ -0,0 +1,16 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
namespace ShipyardContracts.StoragesContracts
{
public interface IShipStorage
{
List<ShipViewModel> GetFullList();
List<ShipViewModel> GetFilteredList(ShipSearchModel model);
ShipViewModel? GetElement(ShipSearchModel model);
ShipViewModel? Insert(ShipBindingModel model);
ShipViewModel? Update(ShipBindingModel model);
ShipViewModel? Delete(ShipBindingModel model);
}
}

View File

@ -0,0 +1,18 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
namespace ShipyardContracts.StoragesContracts
{
public interface IShopStorage
{
List<ShopViewModel> GetFullList();
List<ShopViewModel> GetFilteredList(ShopSearchModel model);
ShopViewModel? GetElement(ShopSearchModel model);
ShopViewModel? Insert(ShopBindingModel model);
ShopViewModel? Update(ShopBindingModel model);
ShopViewModel? Delete(ShopBindingModel model);
bool SellShips(IShipModel model, int count);
}
}

View File

@ -0,0 +1,15 @@
using ShipyardDataModels.Models;
using System.ComponentModel;
namespace ShipyardContracts.ViewModels
{
public class DetailViewModel : IDetailModel
{
public int Id { get; set; }
[DisplayName("Название детали")]
public string DetailName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Cost { get; set; }
}
}

View File

@ -0,0 +1,25 @@
using ShipyardDataModels.Enums;
using ShipyardDataModels.Models;
using System.ComponentModel;
namespace ShipyardContracts.ViewModels
{
public class OrderViewModel : IOrderModel
{
[DisplayName("Номер")]
public int Id { get; set; }
public int ShipId { get; set; }
[DisplayName("Название")]
public string ShipName { get; set; } = string.Empty;
[DisplayName("Количество")]
public int Count { get; set; }
[DisplayName("Сумма")]
public double Sum { get; set; }
[DisplayName("Статус")]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[DisplayName("Дата создания")]
public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
public DateTime? DateImplement { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using ShipyardDataModels.Models;
using System.ComponentModel;
namespace ShipyardContracts.ViewModels
{
public class ShipViewModel : IShipModel
{
public int Id { get; set; }
[DisplayName("Название корабля")]
public string ShipName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Price { get; set; }
public Dictionary<int, (IDetailModel, int)> ShipDetails { get; set; } = new();
}
}

View File

@ -0,0 +1,21 @@
using ShipyardDataModels.Models;
using System.ComponentModel;
namespace ShipyardContracts.ViewModels
{
public class ShopViewModel : IShopModel
{
[DisplayName("Название магазина")]
public string ShopName { get; set; } = string.Empty;
[DisplayName("Адрес магазина")]
public string Address { get; set; } = string.Empty;
[DisplayName("Дата открытия")]
public DateTime DateOpen { get; set; } = DateTime.Now;
[DisplayName("Вместимость магазина")]
public int Capacity { get; set; }
public Dictionary<int, (IShipModel, int)> ShopShips { get; set; } = new();
public int Id { get; set; }
}
}

View File

@ -0,0 +1,12 @@

namespace ShipyardDataModels.Enums
{
public enum OrderStatus
{
Неизвестен = -1,
Принят = 0,
Выполняется = 1,
Готов = 2,
Выдан = 3
}
}

View File

@ -0,0 +1,7 @@
namespace ShipyardDataModels
{
public interface IId
{
int Id { get; }
}
}

View File

@ -0,0 +1,8 @@
namespace ShipyardDataModels.Models
{
public interface IDetailModel : IId
{
string DetailName { get; }
double Cost { get; }
}
}

View File

@ -0,0 +1,14 @@
using ShipyardDataModels.Enums;
namespace ShipyardDataModels.Models
{
public interface IOrderModel : IId
{
int ShipId { get; }
int Count { get; }
double Sum { get; }
OrderStatus Status { get; }
DateTime DateCreate { get; }
DateTime? DateImplement { get; }
}
}

View File

@ -0,0 +1,9 @@
namespace ShipyardDataModels.Models
{
public interface IShipModel : IId
{
string ShipName { get; }
double Price { get; }
Dictionary<int, (IDetailModel, int)> ShipDetails { get; }
}
}

View File

@ -0,0 +1,11 @@
namespace ShipyardDataModels.Models
{
public interface IShopModel : IId
{
string ShopName { get; }
string Address { get; }
DateTime DateOpen { get; }
public int Capacity { get; }
Dictionary<int, (IShipModel, int)> ShopShips { get; }
}
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,55 @@
using ShipyardFileImplement.Models;
using System.Xml.Linq;
namespace ShipyardFileImplement
{
public class DataFileSingleton
{
private static DataFileSingleton? instance;
private readonly string DetailFileName = "Detail.xml";
private readonly string OrderFileName = "Order.xml";
private readonly string ShipFileName = "Ship.xml";
private readonly string ShopFileName = "Shop.xml";
public List<Detail> Details { get; private set; }
public List<Order> Orders { get; private set; }
public List<Ship> Ships { get; private set; }
public List<Shop> Shops { get; private set; }
public static DataFileSingleton GetInstance()
{
if (instance == null)
{
instance = new DataFileSingleton();
}
return instance;
}
public void SaveDetails() => SaveData(Details, DetailFileName, "Details", x => x.GetXElement);
public void SaveShips() => SaveData(Ships, ShipFileName, "Ships", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", 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)!)!;
Shops = LoadData(ShopFileName, "Shop", x => Shop.Create(x)!)!;
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName,
Func<XElement, T> selectFunction)
{
if (File.Exists(filename))
{
return XDocument.Load(filename)?.Root?.Elements(xmlNodeName)?.Select(selectFunction)?.ToList();
}
return new List<T>();
}
private static void SaveData<T>(List<T> data, string filename, string
xmlNodeName, Func<T, XElement> selectFunction)
{
if (data != null)
{
new XDocument(new XElement(xmlNodeName,
data.Select(selectFunction).ToArray())).Save(filename);
}
}
}
}

View File

@ -0,0 +1,81 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardContracts.SearchModels;
using ShipyardFileImplement.Models;
namespace ShipyardFileImplement.Implements
{
public class DetailStorage : IDetailStorage
{
private readonly DataFileSingleton source;
public DetailStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<DetailViewModel> GetFullList()
{
return source.Details.Select(x => x.GetViewModel).ToList();
}
public List<DetailViewModel> GetFilteredList(DetailSearchModel model)
{
if (string.IsNullOrEmpty(model.DetailName))
{
return new();
}
return source.Details
.Where(x => x.DetailName.Contains(model.DetailName))
.Select(x => x.GetViewModel)
.ToList();
}
public DetailViewModel? GetElement(DetailSearchModel model)
{
if (string.IsNullOrEmpty(model.DetailName) && !model.Id.HasValue)
{
return null;
}
return source.Details
.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.DetailName) && x.DetailName ==
model.DetailName) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
}
public DetailViewModel? Insert(DetailBindingModel model)
{
model.Id = source.Details.Count > 0 ? source.Details.Max(x => x.Id) + 1 : 1;
var newComponent = Detail.Create(model);
if (newComponent == null)
{
return null;
}
source.Details.Add(newComponent);
source.SaveDetails();
return newComponent.GetViewModel;
}
public DetailViewModel? Update(DetailBindingModel model)
{
var component = source.Details.FirstOrDefault(x => x.Id ==
model.Id);
if (component == null)
{
return null;
}
component.Update(model);
source.SaveDetails();
return component.GetViewModel;
}
public DetailViewModel? Delete(DetailBindingModel model)
{
var element = source.Details.FirstOrDefault(x => x.Id ==
model.Id);
if (element != null)
{
source.Details.Remove(element);
source.SaveDetails();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,88 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardContracts.SearchModels;
using ShipyardFileImplement.Models;
namespace ShipyardFileImplement.Implements
{
public class OrderStorage : IOrderStorage
{
private readonly DataFileSingleton source;
public OrderStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<OrderViewModel> GetFullList()
{
return source.Orders.Select(x => GetViewModel(x)).ToList();
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return new();
}
return source.Orders.Where(x => x.Id.Equals(model.Id)).Select(x => GetViewModel(x)).ToList();
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
return source.Orders.FirstOrDefault(x =>
(model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
private OrderViewModel GetViewModel(Order order)
{
var viewModel = order.GetViewModel;
var ship = source.Ships.FirstOrDefault(x => x.Id == order.ShipId);
if (ship != null)
{
viewModel.ShipName = ship.ShipName;
}
return viewModel;
}
public OrderViewModel? Insert(OrderBindingModel model)
{
model.Id = source.Orders.Count > 0 ? source.Orders.Max(x => x.Id) + 1 : 1;
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
source.Orders.Add(newOrder);
source.SaveOrders();
return GetViewModel(newOrder);
}
public OrderViewModel? Update(OrderBindingModel model)
{
var order = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (order == null)
{
return null;
}
order.Update(model);
source.SaveOrders();
return GetViewModel(order);
}
public OrderViewModel? Delete(OrderBindingModel model)
{
var element = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
source.Orders.Remove(element);
source.SaveOrders();
return GetViewModel(element);
}
return null;
}
}
}

View File

@ -0,0 +1,74 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardContracts.SearchModels;
using ShipyardFileImplement.Models;
namespace ShipyardFileImplement.Implements
{
public class ShipStorage : IShipStorage
{
private readonly DataFileSingleton source;
public ShipStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<ShipViewModel> GetFullList()
{
return source.Ships.Select(x => x.GetViewModel).ToList();
}
public List<ShipViewModel> GetFilteredList(ShipSearchModel model)
{
if (string.IsNullOrEmpty(model.ShipName))
{
return new();
}
return source.Ships.Where(x =>
x.ShipName.Contains(model.ShipName)).Select(x => x.GetViewModel).ToList();
}
public ShipViewModel? GetElement(ShipSearchModel model)
{
if (string.IsNullOrEmpty(model.ShipName) && !model.Id.HasValue)
{
return null;
}
return source.Ships.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.ShipName) && x.ShipName ==
model.ShipName) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public ShipViewModel? Insert(ShipBindingModel model)
{
model.Id = source.Ships.Count > 0 ? source.Ships.Max(x => x.Id) + 1 : 1;
var newShip = Ship.Create(model);
if (newShip == null)
{
return null;
}
source.Ships.Add(newShip);
source.SaveShips();
return newShip.GetViewModel;
}
public ShipViewModel? Update(ShipBindingModel model)
{
var ship = source.Ships.FirstOrDefault(x => x.Id == model.Id);
if (ship == null)
{
return null;
}
ship.Update(model);
source.SaveShips();
return ship.GetViewModel;
}
public ShipViewModel? Delete(ShipBindingModel model)
{
var element = source.Ships.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
source.Ships.Remove(element);
source.SaveShips();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,119 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardFileImplement.Models;
using ShipyardDataModels.Models;
namespace ShipyardFileImplement.Implements
{
public class ShopStorage : IShopStorage
{
private readonly DataFileSingleton source;
public ShopStorage()
{
source = DataFileSingleton.GetInstance();
}
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue)
{
return null;
}
return source.Shops
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) && x.ShopName == model.ShopName) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName))
{
return new();
}
return source.Shops
.Where(x => x.ShopName.Contains(model.ShopName))
.Select(x => x.GetViewModel)
.ToList();
}
public List<ShopViewModel> GetFullList()
{
return source.Shops.Select(x => x.GetViewModel).ToList();
}
public ShopViewModel? Insert(ShopBindingModel model)
{
model.Id = source.Shops.Count > 0 ? source.Shops.Max(x => x.Id) + 1 : 1;
var newShop = Shop.Create(model);
if (newShop == null)
{
return null;
}
source.Shops.Add(newShop);
source.SaveShops();
return newShop.GetViewModel;
}
public ShopViewModel? Update(ShopBindingModel model)
{
var shop = source.Shops.FirstOrDefault(x => x.Id == model.Id);
if (shop == null)
{
return null;
}
shop.Update(model);
source.SaveShops();
return shop.GetViewModel;
}
public ShopViewModel? Delete(ShopBindingModel model)
{
var shop = source.Shops.FirstOrDefault(x => x.Id == model.Id);
if (shop != null)
{
source.Shops.Remove(shop);
source.SaveShops();
return shop.GetViewModel;
}
return null;
}
public bool SellShips(IShipModel model, int count)
{
int availableQuantity = source.Shops.Select(x => x.ShopShips.FirstOrDefault(y => y.Key == model.Id).Value.Item2).Sum();
if (availableQuantity < count)
{
return false;
}
var shops = source.Shops.Where(x => x.ShopShips.ContainsKey(model.Id));
foreach (var shop in shops)
{
int countInCurrentShop = shop.ShopShips[model.Id].Item2;
if (countInCurrentShop <= count)
{
shop.ShopShips[model.Id] = (shop.ShopShips[model.Id].Item1, 0);
count -= countInCurrentShop;
}
else
{
shop.ShopShips[model.Id] = (shop.ShopShips[model.Id].Item1, countInCurrentShop - count);
count = 0;
}
Update(new ShopBindingModel
{
Id = shop.Id,
ShopName = shop.ShopName,
Address = shop.Address,
DateOpen = shop.DateOpen,
ShopShips = shop.ShopShips,
Capacity = shop.Capacity
});
if (count == 0)
{
return true;
}
}
return false;
}
}
}

View File

@ -0,0 +1,60 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
using System.Xml.Linq;
namespace ShipyardFileImplement.Models
{
public class Detail : IDetailModel
{
public int Id { get; private set; }
public string DetailName { get; private set; } = string.Empty;
public double Cost { get; set; }
public static Detail? Create(DetailBindingModel model)
{
if (model == null)
{
return null;
}
return new Detail()
{
Id = model.Id,
DetailName = model.DetailName,
Cost = model.Cost
};
}
public static Detail? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Detail()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
DetailName = element.Element("DetailName")!.Value,
Cost = Convert.ToDouble(element.Element("Cost")!.Value)
};
}
public void Update(DetailBindingModel model)
{
if (model == null)
{
return;
}
DetailName = model.DetailName;
Cost = model.Cost;
}
public DetailViewModel GetViewModel => new()
{
Id = Id,
DetailName = DetailName,
Cost = Cost
};
public XElement GetXElement => new("Detail",
new XAttribute("Id", Id),
new XElement("DetailName", DetailName),
new XElement("Cost", Cost.ToString()));
}
}

View File

@ -0,0 +1,91 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Enums;
using ShipyardDataModels.Models;
using System.Xml.Linq;
namespace ShipyardFileImplement.Models
{
public class Order : IOrderModel
{
public int Id { get; private set; }
public int ShipId { 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;
public DateTime? DateImplement { get; private set; }
public static Order? Create(OrderBindingModel? model)
{
if (model == null)
{
return null;
}
return new Order()
{
Id = model.Id,
ShipId = model.ShipId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement,
};
}
public static Order? Create(XElement element)
{
if (element == null)
{
return null;
}
var order = new Order()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ShipId = Convert.ToInt32(element.Element("ShipId")!.Value),
Count = Convert.ToInt32(element.Element("Count")!.Value),
Sum = Convert.ToDouble(element.Element("Sum")!.Value),
DateCreate = DateTime.ParseExact(element.Element("DateCreate")!.Value, "G", null),
};
DateTime.TryParse(element.Element("DateImplement")!.Value, out DateTime dateImpl);
order.DateImplement = dateImpl;
if (!Enum.TryParse(element.Element("Status")!.Value, out OrderStatus status))
{
return null;
}
order.Status = status;
return order;
}
public void Update(OrderBindingModel? model)
{
if (model == null)
{
return;
}
Status = model.Status;
DateImplement = model.DateImplement;
}
public OrderViewModel GetViewModel => new()
{
ShipId = ShipId,
Count = Count,
Sum = Sum,
DateCreate = DateCreate,
DateImplement = DateImplement,
Id = Id,
Status = Status,
};
public XElement GetXElement => new("Order",
new XAttribute("Id", Id),
new XElement("ShipId", ShipId),
new XElement("Count", Count.ToString()),
new XElement("Sum", Sum.ToString()),
new XElement("Status", Status.ToString()),
new XElement("DateCreate", DateCreate.ToString()),
new XElement("DateImplement", DateImplement.ToString()));
}
}

View File

@ -0,0 +1,80 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
using System.Xml.Linq;
namespace ShipyardFileImplement.Models
{
public class Ship : IShipModel
{
public int Id { get; private set; }
public string ShipName { get; private set; } = string.Empty;
public double Price { get; private set; }
public Dictionary<int, int> Details { get; private set; } = new();
private Dictionary<int, (IDetailModel, int)>? _shipDetails = null;
public Dictionary<int, (IDetailModel, int)> ShipDetails
{
get
{
if (_shipDetails == null)
{
var source = DataFileSingleton.GetInstance();
_shipDetails = Details.ToDictionary(x => x.Key, y => ((source.Details.FirstOrDefault(z => z.Id == y.Key) as IDetailModel)!, y.Value));
}
return _shipDetails;
}
}
public static Ship? Create(ShipBindingModel model)
{
if (model == null)
{
return null;
}
return new Ship()
{
Id = model.Id,
ShipName = model.ShipName,
Price = model.Price,
Details = model.ShipDetails.ToDictionary(x => x.Key, x => x.Value.Item2)
};
}
public static Ship? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Ship()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ShipName = element.Element("ShipName")!.Value,
Price = Convert.ToDouble(element.Element("Price")!.Value),
Details = element.Element("ShipDetails")!.Elements("ShipDetail").ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value))
};
}
public void Update(ShipBindingModel model)
{
if (model == null)
{
return;
}
ShipName = model.ShipName;
Price = model.Price;
Details = model.ShipDetails.ToDictionary(x => x.Key, x => x.Value.Item2);
_shipDetails = null;
}
public ShipViewModel GetViewModel => new()
{
Id = Id,
ShipName = ShipName,
Price = Price,
ShipDetails = ShipDetails
};
public XElement GetXElement => new("Ship",
new XAttribute("Id", Id),
new XElement("ShipName", ShipName),
new XElement("Price", Price.ToString()),
new XElement("ShipDetails", ShipDetails.Select(x => new XElement("ShipDetails",
new XElement("Key", x.Key), new XElement("Value", x.Value))).ToArray()));
}
}

View File

@ -0,0 +1,103 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
using System.Xml.Linq;
namespace ShipyardFileImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; private set; }
public string ShopName { get; private set; } = string.Empty;
public string Address { get; private set; } = string.Empty;
public DateTime DateOpen { get; private set; }
public int Capacity { get; private set; }
public Dictionary<int, int> ShipsCount = new();
public Dictionary<int, (IShipModel, int)>? _ships = null;
public Dictionary<int, (IShipModel, int)> ShopShips
{
get
{
if (_ships == null)
{
var source = DataFileSingleton.GetInstance();
_ships = ShipsCount.ToDictionary(
x => x.Key,
y => ((source.Ships.FirstOrDefault(z => z.Id == y.Key) as IShipModel)!,
y.Value)
);
}
return _ships;
}
}
public static Shop? Create(ShopBindingModel? model)
{
if (model == null)
{
return null;
}
return new Shop()
{
Id = model.Id,
ShopName = model.ShopName,
Address = model.Address,
DateOpen = model.DateOpen,
Capacity = model.Capacity,
ShipsCount = model.ShopShips.ToDictionary(x => x.Key, x => x.Value.Item2)
};
}
public static Shop? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Shop()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ShopName = element.Element("ShopName")!.Value,
Address = element.Element("Address")!.Value,
DateOpen = Convert.ToDateTime(element.Element("DateOpening")!.Value),
Capacity = Convert.ToInt32(element.Element("Capacity")!.Value),
ShipsCount = element.Element("Ships")!.Elements("Ship")
.ToDictionary(
x => Convert.ToInt32(x.Element("Key")?.Value),
x => Convert.ToInt32(x.Element("Value")?.Value))
};
}
public void Update(ShopBindingModel? model)
{
if (model == null)
{
return;
}
ShopName = model.ShopName;
Address = model.Address;
DateOpen = model.DateOpen;
Capacity = model.Capacity;
ShipsCount = model.ShopShips.ToDictionary(x => x.Key, x => x.Value.Item2);
_ships = null;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
DateOpen = DateOpen,
Capacity = Capacity,
ShopShips = ShopShips
};
public XElement GetXElement => new("Shop",
new XAttribute("Id", Id),
new XElement("ShopName", ShopName),
new XElement("Address", Address),
new XElement("DateOpening", DateOpen.ToString()),
new XElement("Capacity", Capacity.ToString()),
new XElement("Ships", ShipsCount.Select(x =>
new XElement("Ship",
new XElement("Key", x.Key),
new XElement("Value", x.Value)))
.ToArray()));
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ShipyardContracts\ShipyardContracts.csproj" />
<ProjectReference Include="..\ShipyardDataModels\ShipyardDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,28 @@
using ShipyardListImplement.Models;
namespace ShipyardListImplement
{
public class DataListSingleton
{
private static DataListSingleton? _instance;
public List<Detail> Details { get; set; }
public List<Order> Orders { get; set; }
public List<Ship> Ships { get; set; }
public List<Shop> Shops { get; set; }
private DataListSingleton()
{
Details = new List<Detail>();
Orders = new List<Order>();
Ships = new List<Ship>();
Shops = new List<Shop>();
}
public static DataListSingleton GetInstance()
{
if (_instance == null)
{
_instance = new DataListSingleton();
}
return _instance;
}
}
}

View File

@ -0,0 +1,103 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardListImplement.Models;
namespace ShipyardListImplement.Implements
{
public class DetailStorage : IDetailStorage
{
private readonly DataListSingleton _source;
public DetailStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<DetailViewModel> GetFullList()
{
var result = new List<DetailViewModel>();
foreach (var detail in _source.Details)
{
result.Add(detail.GetViewModel);
}
return result;
}
public List<DetailViewModel> GetFilteredList(DetailSearchModel model)
{
var result = new List<DetailViewModel>();
if (string.IsNullOrEmpty(model.DetailName))
{
return result;
}
foreach (var detail in _source.Details)
{
if (detail.DetailName.Contains(model.DetailName))
{
result.Add(detail.GetViewModel);
}
}
return result;
}
public DetailViewModel? GetElement(DetailSearchModel model)
{
if (string.IsNullOrEmpty(model.DetailName) && !model.Id.HasValue)
{
return null;
}
foreach (var detail in _source.Details)
{
if ((!string.IsNullOrEmpty(model.DetailName) &&
detail.DetailName == model.DetailName) ||
(model.Id.HasValue && detail.Id == model.Id))
{
return detail.GetViewModel;
}
}
return null;
}
public DetailViewModel? Insert(DetailBindingModel model)
{
model.Id = 1;
foreach (var component in _source.Details)
{
if (model.Id <= component.Id)
{
model.Id = component.Id + 1;
}
}
var newDetail = Detail.Create(model);
if (newDetail == null)
{
return null;
}
_source.Details.Add(newDetail);
return newDetail.GetViewModel;
}
public DetailViewModel? Update(DetailBindingModel model)
{
foreach (var detail in _source.Details)
{
if (detail.Id == model.Id)
{
detail.Update(model);
return detail.GetViewModel;
}
}
return null;
}
public DetailViewModel? Delete(DetailBindingModel model)
{
for (int i = 0; i < _source.Details.Count; ++i)
{
if (_source.Details[i].Id == model.Id)
{
var element = _source.Details[i];
_source.Details.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
}
}

View File

@ -0,0 +1,113 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardListImplement.Models;
namespace ShipyardListImplement.Implements
{
public class OrderStorage : IOrderStorage
{
private readonly DataListSingleton _source;
public OrderStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<OrderViewModel> GetFullList()
{
var result = new List<OrderViewModel>();
foreach (var order in _source.Orders)
{
result.Add(GetViewModel(order));
}
return result;
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
var result = new List<OrderViewModel>();
if (!model.Id.HasValue)
{
return result;
}
foreach (var order in _source.Orders)
{
if (order.Id == model.Id)
{
result.Add(GetViewModel(order));
}
}
return result;
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
foreach (var order in _source.Orders)
{
if (model.Id.HasValue && order.Id == model.Id)
{
return GetViewModel(order);
}
}
return null;
}
public OrderViewModel? Insert(OrderBindingModel model)
{
model.Id = 1;
foreach (var order in _source.Orders)
{
if (model.Id <= order.Id)
{
model.Id = order.Id + 1;
}
}
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
_source.Orders.Add(newOrder);
return GetViewModel(newOrder);
}
public OrderViewModel? Update(OrderBindingModel model)
{
foreach (var order in _source.Orders)
{
if (order.Id == model.Id)
{
order.Update(model);
return GetViewModel(order);
}
}
return null;
}
public OrderViewModel? Delete(OrderBindingModel model)
{
for (int i = 0; i < _source.Orders.Count; ++i)
{
if (_source.Orders[i].Id == model.Id)
{
var element = _source.Orders[i];
_source.Orders.RemoveAt(i);
return GetViewModel(element);
}
}
return null;
}
private OrderViewModel GetViewModel(Order order)
{
var viewModel = order.GetViewModel;
foreach (var ship in _source.Ships)
{
if (ship.Id == order.ShipId)
{
viewModel.ShipName = ship.ShipName;
break;
}
}
return viewModel;
}
}
}

View File

@ -0,0 +1,102 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardListImplement.Models;
namespace ShipyardListImplement.Implements
{
public class ShipStorage : IShipStorage
{
private readonly DataListSingleton _source;
public ShipStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<ShipViewModel> GetFullList()
{
var result = new List<ShipViewModel>();
foreach (var ship in _source.Ships)
{
result.Add(ship.GetViewModel);
}
return result;
}
public List<ShipViewModel> GetFilteredList(ShipSearchModel model)
{
var result = new List<ShipViewModel>();
if (string.IsNullOrEmpty(model.ShipName))
{
return result;
}
foreach (var ship in _source.Ships)
{
if (ship.ShipName.Contains(model.ShipName))
{
result.Add(ship.GetViewModel);
}
}
return result;
}
public ShipViewModel? GetElement(ShipSearchModel model)
{
if (string.IsNullOrEmpty(model.ShipName) && !model.Id.HasValue)
{
return null;
}
foreach (var ship in _source.Ships)
{
if ((!string.IsNullOrEmpty(model.ShipName) &&
ship.ShipName == model.ShipName) ||
(model.Id.HasValue && ship.Id == model.Id))
{
return ship.GetViewModel;
}
}
return null;
}
public ShipViewModel? Insert(ShipBindingModel model)
{
model.Id = 1;
foreach (var ship in _source.Ships)
{
if (model.Id <= ship.Id)
{
model.Id = ship.Id + 1;
}
}
var newShip = Ship.Create(model);
if (newShip == null)
{
return null;
}
_source.Ships.Add(newShip);
return newShip.GetViewModel;
}
public ShipViewModel? Update(ShipBindingModel model)
{
foreach (var ship in _source.Ships)
{
if (ship.Id == model.Id)
{
ship.Update(model);
return ship.GetViewModel;
}
}
return null;
}
public ShipViewModel? Delete(ShipBindingModel model)
{
for (int i = 0; i < _source.Ships.Count; ++i)
{
if (_source.Ships[i].Id == model.Id)
{
var element = _source.Ships[i];
_source.Ships.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
}
}

View File

@ -0,0 +1,113 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
using ShipyardListImplement.Models;
namespace ShipyardListImplement.Implements
{
public class ShopStorage : IShopStorage
{
private readonly DataListSingleton _source;
public ShopStorage()
{
_source = DataListSingleton.GetInstance();
}
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue)
{
return null;
}
foreach (var shop in _source.Shops)
{
if ((!string.IsNullOrEmpty(model.ShopName) && shop.ShopName == model.ShopName) || (model.Id.HasValue && shop.Id == model.Id))
{
return shop.GetViewModel;
}
}
return null;
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
{
var result = new List<ShopViewModel>();
if (string.IsNullOrEmpty(model.ShopName))
{
return result;
}
foreach (var shop in _source.Shops)
{
if (shop.ShopName.Contains(model.ShopName))
{
result.Add(shop.GetViewModel);
}
}
return result;
}
public List<ShopViewModel> GetFullList()
{
var result = new List<ShopViewModel>();
foreach (var shop in _source.Shops)
{
result.Add(shop.GetViewModel);
}
return result;
}
public ShopViewModel? Insert(ShopBindingModel model)
{
model.Id = 1;
foreach (var shop in _source.Shops)
{
if (model.Id <= shop.Id)
{
model.Id = shop.Id + 1;
}
}
var newShop = Shop.Create(model);
if (newShop == null)
{
return null;
}
_source.Shops.Add(newShop);
return newShop.GetViewModel;
}
public ShopViewModel? Update(ShopBindingModel model)
{
foreach (var shop in _source.Shops)
{
if (shop.Id == model.Id)
{
shop.Update(model);
return shop.GetViewModel;
}
}
return null;
}
public ShopViewModel? Delete(ShopBindingModel model)
{
for (int i = 0; i < _source.Shops.Count; ++i)
{
if (_source.Shops[i].Id == model.Id)
{
var element = _source.Shops[i];
_source.Shops.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
public bool SellShips(IShipModel model, int count)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,42 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
namespace ShipyardListImplement.Models
{
public class Detail : IDetailModel
{
public int Id { get; private set; }
public string DetailName { get; private set; } = string.Empty;
public double Cost { get; set; }
public static Detail? Create(DetailBindingModel? model)
{
if (model == null)
{
return null;
}
return new Detail()
{
Id = model.Id,
DetailName = model.DetailName,
Cost = model.Cost
};
}
public void Update(DetailBindingModel? model)
{
if (model == null)
{
return;
}
DetailName = model.DetailName;
Cost = model.Cost;
}
public DetailViewModel GetViewModel => new()
{
Id = Id,
DetailName = DetailName,
Cost = Cost
};
}
}

View File

@ -0,0 +1,56 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Enums;
using ShipyardDataModels.Models;
namespace ShipyardListImplement.Models
{
public class Order : IOrderModel
{
public int Id { get; private set; }
public int ShipId { 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;
public DateTime? DateImplement { get; private set; }
public static Order? Create(OrderBindingModel? model)
{
if (model == null)
{
return null;
}
return new Order()
{
Id = model.Id,
ShipId = model.ShipId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement
};
}
public void Update(OrderBindingModel? model)
{
if (model == null)
{
return;
}
Status = model.Status;
DateImplement = model.DateImplement;
}
public OrderViewModel GetViewModel => new()
{
Id = Id,
ShipId = ShipId,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement
};
}
}

View File

@ -0,0 +1,46 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
namespace ShipyardListImplement.Models
{
public class Ship : IShipModel
{
public int Id { get; private set; }
public string ShipName { get; private set; } = string.Empty;
public double Price { get; private set; }
public Dictionary<int, (IDetailModel, int)> ShipDetails { get; private set; } = new Dictionary<int, (IDetailModel, int)>();
public static Ship? Create(ShipBindingModel? model)
{
if (model == null)
{
return null;
}
return new Ship()
{
Id = model.Id,
ShipName = model.ShipName,
Price = model.Price,
ShipDetails = model.ShipDetails
};
}
public void Update(ShipBindingModel? model)
{
if (model == null)
{
return;
}
ShipName = model.ShipName;
Price = model.Price;
ShipDetails = model.ShipDetails;
}
public ShipViewModel GetViewModel => new()
{
Id = Id,
ShipName = ShipName,
Price = Price,
ShipDetails = ShipDetails
};
}
}

View File

@ -0,0 +1,55 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
namespace ShipyardListImplement.Models
{
public class Shop : IShopModel
{
public string ShopName { get; set; } = string.Empty;
public string Address { get; set; } = string.Empty;
public DateTime DateOpen { get; set; }
public int Capacity { get; private set; }
public int Id { get; set; }
public Dictionary<int, (IShipModel, int)> ShopShips { get; private set; } = new Dictionary<int, (IShipModel, int)>();
public static Shop? Create(ShopBindingModel? model)
{
if (model == null)
{
return null;
}
return new Shop()
{
Id = model.Id,
ShopName = model.ShopName,
Address = model.Address,
DateOpen = model.DateOpen,
ShopShips = model.ShopShips
};
}
public void Update(ShopBindingModel? model)
{
if (model == null)
{
return;
}
ShopName = model.ShopName;
Address = model.Address;
DateOpen = model.DateOpen;
ShopShips = model.ShopShips;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
DateOpen = DateOpen,
ShopShips = ShopShips
};
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ShipyardContracts\ShipyardContracts.csproj" />
<ProjectReference Include="..\ShipyardDataModels\ShipyardDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,145 @@
namespace ShipyardView
{
partial class FormAddShip
{
/// <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.labelShop = new System.Windows.Forms.Label();
this.labelShip = new System.Windows.Forms.Label();
this.labelCount = new System.Windows.Forms.Label();
this.comboBoxShop = new System.Windows.Forms.ComboBox();
this.comboBoxShip = new System.Windows.Forms.ComboBox();
this.numericUpDownCount = new System.Windows.Forms.NumericUpDown();
this.ButtonSave = new System.Windows.Forms.Button();
this.ButtonCancel = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownCount)).BeginInit();
this.SuspendLayout();
//
// labelShop
//
this.labelShop.AutoSize = true;
this.labelShop.Location = new System.Drawing.Point(12, 31);
this.labelShop.Name = "labelShop";
this.labelShop.Size = new System.Drawing.Size(69, 20);
this.labelShop.TabIndex = 0;
this.labelShop.Text = "Магазин";
//
// labelShip
//
this.labelShip.AutoSize = true;
this.labelShip.Location = new System.Drawing.Point(12, 76);
this.labelShip.Name = "labelShip";
this.labelShip.Size = new System.Drawing.Size(69, 20);
this.labelShip.TabIndex = 1;
this.labelShip.Text = "Корабль";
//
// labelCount
//
this.labelCount.AutoSize = true;
this.labelCount.Location = new System.Drawing.Point(12, 127);
this.labelCount.Name = "labelCount";
this.labelCount.Size = new System.Drawing.Size(90, 20);
this.labelCount.TabIndex = 2;
this.labelCount.Text = "Количество";
//
// comboBoxShop
//
this.comboBoxShop.FormattingEnabled = true;
this.comboBoxShop.Location = new System.Drawing.Point(111, 31);
this.comboBoxShop.Name = "comboBoxShop";
this.comboBoxShop.Size = new System.Drawing.Size(369, 28);
this.comboBoxShop.TabIndex = 3;
//
// comboBoxShip
//
this.comboBoxShip.FormattingEnabled = true;
this.comboBoxShip.Location = new System.Drawing.Point(111, 76);
this.comboBoxShip.Name = "comboBoxShip";
this.comboBoxShip.Size = new System.Drawing.Size(369, 28);
this.comboBoxShip.TabIndex = 4;
//
// numericUpDownCount
//
this.numericUpDownCount.Location = new System.Drawing.Point(111, 120);
this.numericUpDownCount.Name = "numericUpDownCount";
this.numericUpDownCount.Size = new System.Drawing.Size(369, 27);
this.numericUpDownCount.TabIndex = 5;
//
// ButtonSave
//
this.ButtonSave.Location = new System.Drawing.Point(279, 167);
this.ButtonSave.Name = "ButtonSave";
this.ButtonSave.Size = new System.Drawing.Size(94, 29);
this.ButtonSave.TabIndex = 6;
this.ButtonSave.Text = "Сохранить";
this.ButtonSave.UseVisualStyleBackColor = true;
this.ButtonSave.Click += new System.EventHandler(this.ButtonSave_Click);
//
// ButtonCancel
//
this.ButtonCancel.Location = new System.Drawing.Point(386, 167);
this.ButtonCancel.Name = "ButtonCancel";
this.ButtonCancel.Size = new System.Drawing.Size(94, 29);
this.ButtonCancel.TabIndex = 7;
this.ButtonCancel.Text = "Отмена";
this.ButtonCancel.UseVisualStyleBackColor = true;
this.ButtonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
//
// FormAddShip
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(492, 207);
this.Controls.Add(this.ButtonCancel);
this.Controls.Add(this.ButtonSave);
this.Controls.Add(this.numericUpDownCount);
this.Controls.Add(this.comboBoxShip);
this.Controls.Add(this.comboBoxShop);
this.Controls.Add(this.labelCount);
this.Controls.Add(this.labelShip);
this.Controls.Add(this.labelShop);
this.Name = "FormAddShip";
this.Text = "Добавление корабля в магазин";
this.Load += new System.EventHandler(this.FormAddShip_Load);
((System.ComponentModel.ISupportInitialize)(this.numericUpDownCount)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Label labelShop;
private Label labelShip;
private Label labelCount;
private ComboBox comboBoxShop;
private ComboBox comboBoxShip;
private NumericUpDown numericUpDownCount;
private Button ButtonSave;
private Button ButtonCancel;
}
}

View File

@ -0,0 +1,108 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
namespace ShipyardView
{
public partial class FormAddShip : Form
{
private readonly ILogger _logger;
private readonly IShipLogic _logicShip;
private readonly IShopLogic _logicShop;
public FormAddShip(ILogger<FormAddShip> logger, IShipLogic logicShip, IShopLogic logicShop)
{
InitializeComponent();
_logger = logger;
_logicShip = logicShip;
_logicShop = logicShop;
}
private void FormAddShip_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка списка кораблей для пополнения");
try
{
var list = _logicShip.ReadList(null);
if (list != null)
{
comboBoxShip.DisplayMember = "ShipName";
comboBoxShip.ValueMember = "Id";
comboBoxShip.DataSource = list;
comboBoxShip.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка кораблей");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
_logger.LogInformation("Загрузка списка магазинов для пополнения");
try
{
var list = _logicShop.ReadList(null);
if (list != null)
{
comboBoxShop.DisplayMember = "ShopName";
comboBoxShop.ValueMember = "Id";
comboBoxShop.DataSource = list;
comboBoxShop.SelectedItem = null;
}
}
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(numericUpDownCount.Text))
{
MessageBox.Show("Заполните поле Количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxShip.SelectedValue == null)
{
MessageBox.Show("Выберите корабль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxShop.SelectedValue == null)
{
MessageBox.Show("Выберите магазин", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Пополнение магазина");
try
{
var operationResult = _logicShop.AddShip(new ShopSearchModel
{
Id = Convert.ToInt32(comboBoxShop.SelectedValue)
},
_logicShip.ReadElement(new ShipSearchModel()
{
Id = Convert.ToInt32(comboBoxShip.SelectedValue)
})!, Convert.ToInt32(numericUpDownCount.Text));
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,144 @@
namespace ShipyardView
{
partial class FormCreateOrder
{
/// <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()
{
labelShip = new Label();
labelCount = new Label();
labelSum = new Label();
comboBoxShips = new ComboBox();
textBoxCount = new TextBox();
textBoxSum = new TextBox();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// labelShip
//
labelShip.AutoSize = true;
labelShip.Location = new Point(40, 23);
labelShip.Name = "labelShip";
labelShip.Size = new Size(72, 20);
labelShip.TabIndex = 0;
labelShip.Text = "Корабль:";
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(40, 63);
labelCount.Name = "labelCount";
labelCount.Size = new Size(93, 20);
labelCount.TabIndex = 1;
labelCount.Text = "Количество:";
//
// labelSum
//
labelSum.AutoSize = true;
labelSum.Location = new Point(40, 105);
labelSum.Name = "labelSum";
labelSum.Size = new Size(58, 20);
labelSum.TabIndex = 2;
labelSum.Text = "Сумма:";
//
// comboBoxShips
//
comboBoxShips.FormattingEnabled = true;
comboBoxShips.Location = new Point(144, 20);
comboBoxShips.Name = "comboBoxShips";
comboBoxShips.Size = new Size(360, 28);
comboBoxShips.TabIndex = 3;
comboBoxShips.SelectedIndexChanged += ComboBoxShips_SelectedIndexChanged;
//
// textBoxCount
//
textBoxCount.Location = new Point(144, 60);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(360, 27);
textBoxCount.TabIndex = 4;
textBoxCount.TextChanged += TextBoxCount_TextChanged;
//
// textBoxSum
//
textBoxSum.Location = new Point(144, 102);
textBoxSum.Name = "textBoxSum";
textBoxSum.ReadOnly = true;
textBoxSum.Size = new Size(360, 27);
textBoxSum.TabIndex = 5;
//
// buttonSave
//
buttonSave.Location = new Point(236, 149);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(111, 40);
buttonSave.TabIndex = 6;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(372, 149);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(111, 40);
buttonCancel.TabIndex = 7;
buttonCancel.Text = "Отменить";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormCreateOrder
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(540, 201);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxSum);
Controls.Add(textBoxCount);
Controls.Add(comboBoxShips);
Controls.Add(labelSum);
Controls.Add(labelCount);
Controls.Add(labelShip);
Name = "FormCreateOrder";
Text = "FormCreateOrder";
Load += FormCreateOrder_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelShip;
private Label labelCount;
private Label labelSum;
private ComboBox comboBoxShips;
private TextBox textBoxCount;
private TextBox textBoxSum;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,117 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
namespace ShipyardView
{
public partial class FormCreateOrder : Form
{
private readonly ILogger _logger;
private readonly IShipLogic _logicS;
private readonly IOrderLogic _logicO;
public FormCreateOrder(ILogger<FormCreateOrder> logger, IShipLogic logicS, IOrderLogic logicO)
{
InitializeComponent();
_logger = logger;
_logicS = logicS;
_logicO = logicO;
}
private void FormCreateOrder_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка кораблей для заказа");
try
{
var list = _logicS.ReadList(null);
if (list != null)
{
comboBoxShips.DisplayMember = "ShipName";
comboBoxShips.ValueMember = "Id";
comboBoxShips.DataSource = list;
comboBoxShips.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка кораблей");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void CalcSum()
{
if (comboBoxShips.SelectedValue != null &&
!string.IsNullOrEmpty(textBoxCount.Text))
{
try
{
int id = Convert.ToInt32(comboBoxShips.SelectedValue);
var product = _logicS.ReadElement(new ShipSearchModel
{
Id = id
});
int count = Convert.ToInt32(textBoxCount.Text);
textBoxSum.Text = Math.Round(count * (product?.Price ?? 0), 2).ToString();
_logger.LogInformation("Расчет суммы заказа");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка расчета суммы заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void TextBoxCount_TextChanged(object sender, EventArgs e)
{
CalcSum();
}
private void ComboBoxShips_SelectedIndexChanged(object sender, EventArgs e)
{
CalcSum();
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxCount.Text))
{
MessageBox.Show("Заполните поле Количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxShips.SelectedValue == null)
{
MessageBox.Show("Выберите корабль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Создание заказа");
try
{
var operationResult = _logicO.CreateOrder(new OrderBindingModel
{
ShipId = Convert.ToInt32(comboBoxShips.SelectedValue),
Count = Convert.ToInt32(textBoxCount.Text),
Sum = Convert.ToDouble(textBoxSum.Text)
});
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,120 @@
namespace ShipyardView
{
partial class FormDetail
{
/// <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()
{
textBoxName = new TextBox();
textBoxCost = new TextBox();
labelName = new Label();
labelCost = new Label();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// textBoxName
//
textBoxName.Location = new Point(152, 27);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(342, 27);
textBoxName.TabIndex = 0;
//
// textBoxCost
//
textBoxCost.Location = new Point(152, 60);
textBoxCost.Name = "textBoxCost";
textBoxCost.Size = new Size(142, 27);
textBoxCost.TabIndex = 1;
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(49, 30);
labelName.Name = "labelName";
labelName.Size = new Size(80, 20);
labelName.TabIndex = 2;
labelName.Text = "Название:";
//
// labelCost
//
labelCost.AutoSize = true;
labelCost.Location = new Point(49, 67);
labelCost.Name = "labelCost";
labelCost.Size = new Size(48, 20);
labelCost.TabIndex = 3;
labelCost.Text = "Цена:";
//
// buttonSave
//
buttonSave.BackColor = SystemColors.Control;
buttonSave.Location = new Point(313, 95);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(109, 37);
buttonSave.TabIndex = 4;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = false;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.BackColor = SystemColors.Control;
buttonCancel.Location = new Point(428, 95);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(109, 37);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = false;
buttonCancel.Click += ButtonCancel_Click;
//
// FormDetail
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(572, 144);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(labelCost);
Controls.Add(labelName);
Controls.Add(textBoxCost);
Controls.Add(textBoxName);
Name = "FormDetail";
Text = "Деталь";
Load += FormDetail_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxName;
private TextBox textBoxCost;
private Label labelName;
private Label labelCost;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,88 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using System.Windows.Forms;
namespace ShipyardView
{
public partial class FormDetail : Form
{
private readonly ILogger _logger;
private readonly IDetailLogic _logic;
private int? _id;
public int Id { set { _id = value; } }
public FormDetail(ILogger<FormDetail> logger, IDetailLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormDetail_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
try
{
_logger.LogInformation("Получение детали");
var view = _logic.ReadElement(new DetailSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxName.Text = view.DetailName;
textBoxCost.Text = view.Cost.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(textBoxName.Text))
{
MessageBox.Show("Заполните название", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение детали");
try
{
var model = new DetailBindingModel
{
Id = _id ?? 0,
DetailName = textBoxName.Text,
Cost = Convert.ToDouble(textBoxCost.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,120 @@
namespace ShipyardView
{
partial class FormDetails
{
/// <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();
buttonUpdate = new Button();
buttonDelete = new Button();
buttonRefresh = 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.Location = new Point(-2, -1);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(477, 473);
dataGridView.TabIndex = 0;
//
// buttonAdd
//
buttonAdd.Location = new Point(499, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(125, 41);
buttonAdd.TabIndex = 1;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(499, 79);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(125, 41);
buttonUpdate.TabIndex = 2;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += ButtonUpd_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(499, 149);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(125, 41);
buttonDelete.TabIndex = 3;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += ButtonDel_Click;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(499, 221);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(125, 41);
buttonRefresh.TabIndex = 4;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRef_Click;
//
// FormDetails
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(636, 471);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormDetails";
Text = " Детали";
Load += FormDetails_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonAdd;
private Button buttonUpdate;
private Button buttonDelete;
private Button buttonRefresh;
}
}

View File

@ -0,0 +1,104 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using System.Windows.Forms;
namespace ShipyardView
{
public partial class FormDetails : Form
{
private readonly ILogger _logger;
private readonly IDetailLogic _logic;
public FormDetails(ILogger<FormDetails> logger, IDetailLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormDetails_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["DetailName"].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(FormDetail));
if (service is FormDetail 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(FormDetail));
if (service is FormDetail 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 DetailBindingModel
{
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>

216
Shipyard/ShipyardView/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,216 @@
namespace ShipyardView
{
partial class FormMain
{
/// <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()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
toolStrip = new ToolStrip();
toolStripMenu = new ToolStripDropDownButton();
деталиToolStripMenuItem = new ToolStripMenuItem();
кораблиToolStripMenuItem = new ToolStripMenuItem();
магазиныToolStripMenuItem = new ToolStripMenuItem();
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonTakeInWork = new Button();
buttonReady = new Button();
buttonIssue = new Button();
buttonRefresh = new Button();
buttonAddShip = new Button();
buttonSellShip = new Button();
toolStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// toolStrip
//
toolStrip.ImageScalingSize = new Size(20, 20);
toolStrip.Items.AddRange(new ToolStripItem[] { toolStripMenu });
toolStrip.Location = new Point(0, 0);
toolStrip.Name = "toolStrip";
toolStrip.Size = new Size(1251, 27);
toolStrip.TabIndex = 0;
toolStrip.Text = "Справочники";
//
// toolStripMenu
//
toolStripMenu.DisplayStyle = ToolStripItemDisplayStyle.Text;
toolStripMenu.DropDownItems.AddRange(new ToolStripItem[] { деталиToolStripMenuItem, кораблиToolStripMenuItem, магазиныToolStripMenuItem });
toolStripMenu.Image = (Image)resources.GetObject("toolStripMenu.Image");
toolStripMenu.ImageTransparentColor = Color.Magenta;
toolStripMenu.Name = "toolStripMenu";
toolStripMenu.Size = new Size(117, 24);
toolStripMenu.Text = "Справочники";
//
// деталиToolStripMenuItem
//
деталиToolStripMenuItem.Name = еталиToolStripMenuItem";
деталиToolStripMenuItem.Size = new Size(224, 26);
деталиToolStripMenuItem.Text = "Детали";
деталиToolStripMenuItem.Click += ДеталиToolStripMenuItem_Click;
//
// кораблиToolStripMenuItem
//
кораблиToolStripMenuItem.Name = ораблиToolStripMenuItem";
кораблиToolStripMenuItem.Size = new Size(224, 26);
кораблиToolStripMenuItem.Text = "Корабли";
кораблиToolStripMenuItem.Click += КораблиToolStripMenuItem_Click;
//
// магазиныToolStripMenuItem
//
магазиныToolStripMenuItem.Name = агазиныToolStripMenuItem";
магазиныToolStripMenuItem.Size = new Size(224, 26);
магазиныToolStripMenuItem.Text = "Магазины";
магазиныToolStripMenuItem.Click += МагазиныToolStripMenuItem_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AllowUserToResizeColumns = false;
dataGridView.AllowUserToResizeRows = false;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(0, 28);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(984, 417);
dataGridView.TabIndex = 1;
//
// buttonCreateOrder
//
buttonCreateOrder.Location = new Point(1032, 51);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(178, 29);
buttonCreateOrder.TabIndex = 2;
buttonCreateOrder.Text = "Создать заказ";
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.Name = "buttonIssue";
buttonIssue.Size = new Size(178, 29);
buttonIssue.TabIndex = 5;
buttonIssue.Text = "Заказ выдан";
buttonIssue.UseVisualStyleBackColor = true;
buttonIssue.Click += ButtonIssuedOrder_Click;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(1032, 350);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(178, 29);
buttonRefresh.TabIndex = 6;
buttonRefresh.Text = "Обновить список";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRef_Click;
//
// buttonAddShip
//
buttonAddShip.Location = new Point(1032, 293);
buttonAddShip.Name = "buttonAddShip";
buttonAddShip.Size = new Size(178, 29);
buttonAddShip.TabIndex = 7;
buttonAddShip.Text = "Добавить корабль";
buttonAddShip.UseVisualStyleBackColor = true;
buttonAddShip.Click += ButtonAddShip_Click;
//
// buttonSellShip
//
buttonSellShip.Location = new Point(1032, 396);
buttonSellShip.Name = "buttonSellShip";
buttonSellShip.Size = new Size(178, 29);
buttonSellShip.TabIndex = 8;
buttonSellShip.Text = "Продать корабль";
buttonSellShip.UseVisualStyleBackColor = true;
buttonSellShip.Click += ButtonSellShip_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1251, 446);
Controls.Add(buttonSellShip);
Controls.Add(buttonAddShip);
Controls.Add(buttonRefresh);
Controls.Add(buttonIssue);
Controls.Add(buttonReady);
Controls.Add(buttonTakeInWork);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(toolStrip);
Name = "FormMain";
Text = "FormMain";
Load += FormMain_Load;
toolStrip.ResumeLayout(false);
toolStrip.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private ToolStrip toolStrip;
private DataGridView dataGridView;
private Button buttonCreateOrder;
private Button buttonTakeInWork;
private Button buttonReady;
private Button buttonIssue;
private Button buttonRefresh;
private ToolStripDropDownButton toolStripMenu;
private ToolStripMenuItem деталиToolStripMenuItem;
private ToolStripMenuItem кораблиToolStripMenuItem;
private ToolStripMenuItem магазиныToolStripMenuItem;
private Button buttonAddShip;
private Button buttonSellShip;
}
}

View File

@ -0,0 +1,168 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardDataModels.Enums;
using ShipyardView;
using System.Windows.Forms;
namespace ShipyardView
{
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
}
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["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 МагазиныToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormShops));
if (service is FormShops form)
{
form.ShowDialog();
}
}
private void ButtonAddShip_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormAddShip));
if (service is FormAddShip form)
{
form.ShowDialog();
LoadData();
}
}
private void ButtonSellShip_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSellShips));
if (service is FormSellShips form)
{
form.ShowDialog();
LoadData();
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

@ -0,0 +1,135 @@
<?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>
<metadata name="toolStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="toolStripMenu.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

@ -0,0 +1,120 @@
namespace ShipyardView
{
partial class FormSellShips
{
/// <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.ButtonCancel = new System.Windows.Forms.Button();
this.comboBoxShips = new System.Windows.Forms.ComboBox();
this.numericUpDownCount = new System.Windows.Forms.NumericUpDown();
this.labelShip = new System.Windows.Forms.Label();
this.labelCount = new System.Windows.Forms.Label();
this.ButtonSave = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownCount)).BeginInit();
this.SuspendLayout();
//
// ButtonCancel
//
this.ButtonCancel.Location = new System.Drawing.Point(266, 153);
this.ButtonCancel.Name = "ButtonCancel";
this.ButtonCancel.Size = new System.Drawing.Size(94, 29);
this.ButtonCancel.TabIndex = 1;
this.ButtonCancel.Text = "Отмена";
this.ButtonCancel.UseVisualStyleBackColor = true;
this.ButtonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
//
// comboBoxShips
//
this.comboBoxShips.FormattingEnabled = true;
this.comboBoxShips.Location = new System.Drawing.Point(144, 38);
this.comboBoxShips.Name = "comboBoxShips";
this.comboBoxShips.Size = new System.Drawing.Size(216, 28);
this.comboBoxShips.TabIndex = 2;
//
// numericUpDownCount
//
this.numericUpDownCount.Location = new System.Drawing.Point(144, 102);
this.numericUpDownCount.Name = "numericUpDownCount";
this.numericUpDownCount.Size = new System.Drawing.Size(216, 27);
this.numericUpDownCount.TabIndex = 3;
//
// labelShip
//
this.labelShip.AutoSize = true;
this.labelShip.Location = new System.Drawing.Point(34, 38);
this.labelShip.Name = "labelShip";
this.labelShip.Size = new System.Drawing.Size(69, 20);
this.labelShip.TabIndex = 4;
this.labelShip.Text = "Корабль";
//
// labelCount
//
this.labelCount.AutoSize = true;
this.labelCount.Location = new System.Drawing.Point(34, 109);
this.labelCount.Name = "labelCount";
this.labelCount.Size = new System.Drawing.Size(90, 20);
this.labelCount.TabIndex = 5;
this.labelCount.Text = "Количество";
//
// ButtonSave
//
this.ButtonSave.Location = new System.Drawing.Point(144, 153);
this.ButtonSave.Name = "ButtonSave";
this.ButtonSave.Size = new System.Drawing.Size(94, 29);
this.ButtonSave.TabIndex = 6;
this.ButtonSave.Text = "Сохранить";
this.ButtonSave.UseVisualStyleBackColor = true;
this.ButtonSave.Click += new System.EventHandler(this.ButtonSave_Click);
//
// FormSellShips
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(373, 194);
this.Controls.Add(this.ButtonSave);
this.Controls.Add(this.labelCount);
this.Controls.Add(this.labelShip);
this.Controls.Add(this.numericUpDownCount);
this.Controls.Add(this.comboBoxShips);
this.Controls.Add(this.ButtonCancel);
this.Name = "FormSellShips";
this.Text = "Продажа кораблей";
((System.ComponentModel.ISupportInitialize)(this.numericUpDownCount)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Button ButtonCancel;
private ComboBox comboBoxShips;
private NumericUpDown numericUpDownCount;
private Label labelShip;
private Label labelCount;
private Button ButtonSave;
}
}

View File

@ -0,0 +1,77 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.ViewModels;
namespace ShipyardView
{
public partial class FormSellShips : Form
{
private readonly ILogger _logger;
private readonly IShopLogic _shopLogic;
private readonly IShipLogic _shipLogic;
private readonly List<ShipViewModel>? _listShip;
public FormSellShips(ILogger<FormSellShips> logger, IShopLogic shopLogic, IShipLogic shipLogic)
{
InitializeComponent();
_logger = logger;
_shopLogic = shopLogic;
_shipLogic = shipLogic;
_listShip = shipLogic.ReadList(null);
if (_listShip != null)
{
comboBoxShips.DisplayMember = "ShipName";
comboBoxShips.ValueMember = "Id";
comboBoxShips.DataSource = _listShip;
comboBoxShips.SelectedItem = null;
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (comboBoxShips.SelectedValue == null)
{
MessageBox.Show("Выберите корабль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(numericUpDownCount.Text))
{
MessageBox.Show("Заполните количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Продажа поездок");
try
{
var ship = _shipLogic.ReadElement(new()
{
Id = (int)comboBoxShips.SelectedValue
});
if (ship == null)
{
throw new Exception("Корабль не найден. Дополнительная информация в логах.");
}
var operationResult = _shopLogic.SellShips(
model: ship,
count: (int)numericUpDownCount.Value
);
if (!operationResult)
{
throw new Exception("Ошибка при продаже корабля. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения корабля");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

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

233
Shipyard/ShipyardView/FormShip.Designer.cs generated Normal file
View File

@ -0,0 +1,233 @@
namespace ShipyardView
{
partial class FormShip
{
/// <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()
{
labelName = new Label();
labelPrice = new Label();
textBoxName = new TextBox();
textBoxPrice = new TextBox();
groupBoxDetails = new GroupBox();
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
id = new DataGridViewTextBoxColumn();
Detail = new DataGridViewTextBoxColumn();
Count = new DataGridViewTextBoxColumn();
buttonSave = new Button();
buttonCancel = new Button();
groupBoxDetails.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(33, 15);
labelName.Name = "labelName";
labelName.Size = new Size(80, 20);
labelName.TabIndex = 0;
labelName.Text = "Название:";
//
// labelPrice
//
labelPrice.AutoSize = true;
labelPrice.Location = new Point(33, 47);
labelPrice.Name = "labelPrice";
labelPrice.Size = new Size(86, 20);
labelPrice.TabIndex = 1;
labelPrice.Text = "Стоимость:";
//
// textBoxName
//
textBoxName.Location = new Point(125, 14);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(333, 27);
textBoxName.TabIndex = 2;
//
// textBoxPrice
//
textBoxPrice.Location = new Point(125, 47);
textBoxPrice.Name = "textBoxPrice";
textBoxPrice.ReadOnly = true;
textBoxPrice.Size = new Size(188, 27);
textBoxPrice.TabIndex = 3;
//
// groupBoxDetails
//
groupBoxDetails.Controls.Add(buttonRefresh);
groupBoxDetails.Controls.Add(buttonDelete);
groupBoxDetails.Controls.Add(buttonUpdate);
groupBoxDetails.Controls.Add(buttonAdd);
groupBoxDetails.Controls.Add(dataGridView);
groupBoxDetails.Location = new Point(33, 130);
groupBoxDetails.Name = "groupBoxDetails";
groupBoxDetails.Size = new Size(669, 328);
groupBoxDetails.TabIndex = 4;
groupBoxDetails.TabStop = false;
groupBoxDetails.Text = "Детали";
//
// buttonRefresh
//
buttonRefresh.Location = new Point(549, 193);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(99, 37);
buttonRefresh.TabIndex = 4;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRef_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(549, 143);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(99, 44);
buttonDelete.TabIndex = 3;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += ButtonDel_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(549, 93);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(99, 44);
buttonUpdate.TabIndex = 2;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += ButtonUpd_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(549, 45);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(99, 42);
buttonAdd.TabIndex = 1;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AllowUserToResizeColumns = false;
dataGridView.AllowUserToResizeRows = false;
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { id, Detail, Count });
dataGridView.Location = new Point(6, 26);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(517, 296);
dataGridView.TabIndex = 0;
//
// id
//
id.HeaderText = "Id";
id.MinimumWidth = 6;
id.Name = "id";
id.Visible = false;
//
// Detail
//
Detail.HeaderText = "Деталь";
Detail.MinimumWidth = 6;
Detail.Name = "Detail";
//
// Count
//
Count.HeaderText = "Количество";
Count.MinimumWidth = 6;
Count.Name = "Count";
//
// buttonSave
//
buttonSave.Location = new Point(409, 478);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(127, 39);
buttonSave.TabIndex = 5;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(554, 478);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(127, 39);
buttonCancel.TabIndex = 6;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormShip
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(726, 529);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(groupBoxDetails);
Controls.Add(textBoxPrice);
Controls.Add(textBoxName);
Controls.Add(labelPrice);
Controls.Add(labelName);
Name = "FormShip";
Text = "Корабль";
Load += FormShip_Load;
groupBoxDetails.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelName;
private Label labelPrice;
private TextBox textBoxName;
private TextBox textBoxPrice;
private GroupBox groupBoxDetails;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonAdd;
private DataGridView dataGridView;
private Button buttonSave;
private Button buttonCancel;
private DataGridViewTextBoxColumn id;
private DataGridViewTextBoxColumn Detail;
private DataGridViewTextBoxColumn Count;
}
}

View File

@ -0,0 +1,208 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardDataModels.Models;
using System.Windows.Forms;
namespace ShipyardView
{
public partial class FormShip : Form
{
private readonly ILogger _logger;
private readonly IShipLogic _logic;
private int? _id;
private Dictionary<int, (IDetailModel, int)> _shipDetails;
public int Id { set { _id = value; } }
public FormShip(ILogger<FormShip> logger, IShipLogic logic)
{
InitializeComponent();
Console.WriteLine(dataGridView.RowCount);
dataGridView.Rows.Clear();
Console.WriteLine(dataGridView.RowCount);
_logger = logger;
_logic = logic;
_shipDetails = new Dictionary<int, (IDetailModel, int)>();
}
private void FormShip_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
_logger.LogInformation("Загрузка корабля");
try
{
var view = _logic.ReadElement(new ShipSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxName.Text = view.ShipName;
textBoxPrice.Text = view.Price.ToString();
_shipDetails = view.ShipDetails ?? new Dictionary<int, (IDetailModel, int)>();
LoadData();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки корабля");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LoadData()
{
_logger.LogInformation("Загрузка деталей корабля");
try
{
if (_shipDetails != null)
{
dataGridView.Rows.Clear();
foreach (var pc in _shipDetails)
{
dataGridView.Rows.Add(new object[] { pc.Key, pc.Value.Item1.DetailName, pc.Value.Item2 });
}
textBoxPrice.Text = CalcPrice().ToString();
}
}
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(FormShipDetail));
if (service is FormShipDetail form)
{
if (form.ShowDialog() == DialogResult.OK)
{
if (form.DetailModel == null)
{
return;
}
_logger.LogInformation("Добавление новой детали:{ DetailName} - { Count}", form.DetailModel.DetailName, form.Count);
if (_shipDetails.ContainsKey(form.Id))
{
_shipDetails[form.Id] = (form.DetailModel, form.Count);
}
else
{
_shipDetails.Add(form.Id, (form.DetailModel, form.Count));
}
LoadData();
}
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormShipDetail));
if (service is FormShipDetail form)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
form.Id = id;
form.Count = _shipDetails[id].Item2;
if (form.ShowDialog() == DialogResult.OK)
{
if (form.DetailModel == null)
{
return;
}
_logger.LogInformation("Изменение детали: { DetailName} - { Count}", form.DetailModel.DetailName, form.Count);
_shipDetails[form.Id] = (form.DetailModel, form.Count);
LoadData();
}
}
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
_logger.LogInformation("Удаление детали:{ DetailName} - { Count}", dataGridView.SelectedRows[0].Cells[1].Value);
_shipDetails?.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxName.Text))
{
MessageBox.Show("Заполните название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxPrice.Text))
{
MessageBox.Show("Заполните цену", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (_shipDetails == null || _shipDetails.Count == 0)
{
MessageBox.Show("Заполните компоненты", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение корабля");
try
{
var model = new ShipBindingModel
{
Id = _id ?? 0,
ShipName = textBoxName.Text,
Price = Convert.ToDouble(textBoxPrice.Text),
ShipDetails = _shipDetails
};
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();
}
private double CalcPrice()
{
double price = 0;
foreach (var elem in _shipDetails)
{
price += ((elem.Value.Item1?.Cost ?? 0) * elem.Value.Item2);
}
return Math.Round(price * 1.1, 2);
}
}
}

View File

@ -0,0 +1,129 @@
<?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>
<metadata name="id.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Detail.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Count.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,118 @@
namespace ShipyardView
{
partial class FormShipDetail
{
/// <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()
{
labelDetail = new Label();
labelCount = new Label();
textBoxCount = new TextBox();
comboBoxDetail = new ComboBox();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// labelDetail
//
labelDetail.AutoSize = true;
labelDetail.Location = new Point(41, 26);
labelDetail.Name = "labelDetail";
labelDetail.Size = new Size(60, 20);
labelDetail.TabIndex = 0;
labelDetail.Text = "Деталь:";
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(41, 66);
labelCount.Name = "labelCount";
labelCount.Size = new Size(90, 20);
labelCount.TabIndex = 1;
labelCount.Text = "Количество";
//
// textBoxCount
//
textBoxCount.Location = new Point(145, 63);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(328, 27);
textBoxCount.TabIndex = 2;
//
// comboBoxDetail
//
comboBoxDetail.FormattingEnabled = true;
comboBoxDetail.Location = new Point(145, 23);
comboBoxDetail.Name = "comboBoxDetail";
comboBoxDetail.Size = new Size(328, 28);
comboBoxDetail.TabIndex = 3;
//
// buttonSave
//
buttonSave.Location = new Point(190, 96);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(118, 40);
buttonSave.TabIndex = 4;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(329, 96);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(118, 40);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отменить";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormShipDetail
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(484, 148);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(comboBoxDetail);
Controls.Add(textBoxCount);
Controls.Add(labelCount);
Controls.Add(labelDetail);
Name = "FormShipDetail";
Text = "Деталь коробля";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelDetail;
private Label labelCount;
private TextBox textBoxCount;
private ComboBox comboBoxDetail;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,79 @@
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.Models;
namespace ShipyardView
{
public partial class FormShipDetail : Form
{
private readonly List<DetailViewModel>? _list;
public int Id
{
get
{
return Convert.ToInt32(comboBoxDetail.SelectedValue);
}
set
{
comboBoxDetail.SelectedValue = value;
}
}
public IDetailModel? DetailModel
{
get
{
if (_list == null)
{
return null;
}
foreach (var elem in _list)
{
if (elem.Id == Id)
{
return elem;
}
}
return null;
}
}
public int Count
{
get { return Convert.ToInt32(textBoxCount.Text); }
set { textBoxCount.Text = value.ToString(); }
}
public FormShipDetail(IDetailLogic logic)
{
InitializeComponent();
_list = logic.ReadList(null);
if (_list != null)
{
comboBoxDetail.DisplayMember = "DetailName";
comboBoxDetail.ValueMember = "Id";
comboBoxDetail.DataSource = _list;
comboBoxDetail.SelectedItem = null;
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxCount.Text))
{
MessageBox.Show("Заполните поле Количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxDetail.SelectedValue == null)
{
MessageBox.Show("Выберите компонент", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
DialogResult = DialogResult.OK;
Close();
}
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,120 @@
namespace ShipyardView
{
partial class FormShips
{
/// <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();
buttonUpdate = new Button();
buttonDelete = new Button();
buttonRefresh = 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.Location = new Point(-1, -2);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(477, 478);
dataGridView.TabIndex = 1;
//
// buttonAdd
//
buttonAdd.Location = new Point(505, 23);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(125, 41);
buttonAdd.TabIndex = 2;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(505, 87);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(125, 41);
buttonUpdate.TabIndex = 3;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += ButtonUpd_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(505, 158);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(125, 41);
buttonDelete.TabIndex = 4;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += ButtonDel_Click;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(505, 226);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(125, 41);
buttonRefresh.TabIndex = 5;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRef_Click;
//
// FormShips
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(659, 477);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormShips";
Text = "Корабли";
Load += FormShips_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonAdd;
private Button buttonUpdate;
private Button buttonDelete;
private Button buttonRefresh;
}
}

View File

@ -0,0 +1,105 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using System.Windows.Forms;
namespace ShipyardView
{
public partial class FormShips : Form
{
private readonly ILogger _logger;
private readonly IShipLogic _logic;
public FormShips(ILogger<FormShips> logger, IShipLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormShips_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["ShipName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["ShipDetails"].Visible = false;
}
_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(FormShip));
if (service is FormShip 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(FormShip));
if (service is FormShip 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 ShipBindingModel
{
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>

213
Shipyard/ShipyardView/FormShop.Designer.cs generated Normal file
View File

@ -0,0 +1,213 @@
namespace ShipyardView
{
partial class FormShop
{
/// <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()
{
labelShop = new Label();
labelAddress = new Label();
labelDate = new Label();
textBoxName = new TextBox();
textBoxAddress = new TextBox();
dateTimePickerDateOpen = new DateTimePicker();
dataGridView = new DataGridView();
ID = new DataGridViewTextBoxColumn();
ShipName = new DataGridViewTextBoxColumn();
Count = new DataGridViewTextBoxColumn();
ButtonSave = new Button();
ButtonCancel = new Button();
numericUpDownCapacity = new NumericUpDown();
labelCapacity = new Label();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownCapacity).BeginInit();
SuspendLayout();
//
// labelShop
//
labelShop.AutoSize = true;
labelShop.Location = new Point(12, 21);
labelShop.Name = "labelShop";
labelShop.Size = new Size(69, 20);
labelShop.TabIndex = 0;
labelShop.Text = "Магазин";
//
// labelAddress
//
labelAddress.AutoSize = true;
labelAddress.Location = new Point(195, 21);
labelAddress.Name = "labelAddress";
labelAddress.Size = new Size(51, 20);
labelAddress.TabIndex = 1;
labelAddress.Text = "Адрес";
//
// labelDate
//
labelDate.AutoSize = true;
labelDate.Location = new Point(474, 21);
labelDate.Name = "labelDate";
labelDate.Size = new Size(110, 20);
labelDate.TabIndex = 2;
labelDate.Text = "Дата открытия";
//
// textBoxName
//
textBoxName.Location = new Point(12, 44);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(160, 27);
textBoxName.TabIndex = 3;
//
// textBoxAddress
//
textBoxAddress.Location = new Point(195, 44);
textBoxAddress.Name = "textBoxAddress";
textBoxAddress.Size = new Size(246, 27);
textBoxAddress.TabIndex = 4;
//
// dateTimePickerDateOpen
//
dateTimePickerDateOpen.Location = new Point(474, 44);
dateTimePickerDateOpen.Name = "dateTimePickerDateOpen";
dateTimePickerDateOpen.Size = new Size(195, 27);
dateTimePickerDateOpen.TabIndex = 5;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AllowUserToResizeColumns = false;
dataGridView.AllowUserToResizeRows = false;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { ID, ShipName, Count });
dataGridView.Location = new Point(12, 77);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersVisible = false;
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(870, 370);
dataGridView.TabIndex = 6;
//
// ID
//
ID.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
ID.HeaderText = "ID";
ID.MinimumWidth = 6;
ID.Name = "ID";
ID.Visible = false;
//
// ShipName
//
ShipName.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
ShipName.HeaderText = "Название корабля";
ShipName.MinimumWidth = 6;
ShipName.Name = "ShipName";
//
// Count
//
Count.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
Count.HeaderText = "Количество";
Count.MinimumWidth = 6;
Count.Name = "Count";
//
// ButtonSave
//
ButtonSave.Location = new Point(652, 453);
ButtonSave.Name = "ButtonSave";
ButtonSave.Size = new Size(111, 29);
ButtonSave.TabIndex = 7;
ButtonSave.Text = "Сохранить";
ButtonSave.UseVisualStyleBackColor = true;
ButtonSave.Click += ButtonSave_Click;
//
// ButtonCancel
//
ButtonCancel.Location = new Point(788, 453);
ButtonCancel.Name = "ButtonCancel";
ButtonCancel.Size = new Size(94, 29);
ButtonCancel.TabIndex = 8;
ButtonCancel.Text = "Отмена";
ButtonCancel.UseVisualStyleBackColor = true;
ButtonCancel.Click += ButtonCancel_Click;
//
// numericUpDownCapacity
//
numericUpDownCapacity.Location = new Point(701, 44);
numericUpDownCapacity.Name = "numericUpDownCapacity";
numericUpDownCapacity.Size = new Size(181, 27);
numericUpDownCapacity.TabIndex = 9;
//
// labelCapacity
//
labelCapacity.AutoSize = true;
labelCapacity.Location = new Point(701, 21);
labelCapacity.Name = "labelCapacity";
labelCapacity.Size = new Size(100, 20);
labelCapacity.TabIndex = 10;
labelCapacity.Text = "Вместимость";
//
// FormShop
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(906, 494);
Controls.Add(labelCapacity);
Controls.Add(numericUpDownCapacity);
Controls.Add(ButtonCancel);
Controls.Add(ButtonSave);
Controls.Add(dataGridView);
Controls.Add(dateTimePickerDateOpen);
Controls.Add(textBoxAddress);
Controls.Add(textBoxName);
Controls.Add(labelDate);
Controls.Add(labelAddress);
Controls.Add(labelShop);
Name = "FormShop";
Text = "Магазин";
Load += FormShop_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownCapacity).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelShop;
private Label labelAddress;
private Label labelDate;
private TextBox textBoxName;
private TextBox textBoxAddress;
private DateTimePicker dateTimePickerDateOpen;
private DataGridView dataGridView;
private Button ButtonSave;
private Button ButtonCancel;
private DataGridViewTextBoxColumn ID;
private DataGridViewTextBoxColumn ShipName;
private DataGridViewTextBoxColumn Count;
private NumericUpDown numericUpDownCapacity;
private Label labelCapacity;
}
}

View File

@ -0,0 +1,129 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.SearchModels;
using ShipyardDataModels.Models;
namespace ShipyardView
{
public partial class FormShop : Form
{
private readonly ILogger _logger;
private readonly IShopLogic _logic;
private int? _id;
private Dictionary<int, (IShipModel, int)> _shopShips;
public int Id { set { _id = value; } }
public FormShop(ILogger<FormShop> logger, IShopLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
_shopShips = new Dictionary<int, (IShipModel, int)>();
}
private void FormShop_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
_logger.LogInformation("Загрузка магазина");
try
{
var view = _logic.ReadElement(new ShopSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxName.Text = view.ShopName;
textBoxAddress.Text = view.Address.ToString();
dateTimePickerDateOpen.Text = view.DateOpen.ToString();
numericUpDownCapacity.Value = view.Capacity;
_shopShips = view.ShopShips ?? new Dictionary<int, (IShipModel, int)>();
LoadData();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки магазина");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LoadData()
{
_logger.LogInformation("Загрузка кораблей магазина");
try
{
if (_shopShips != null)
{
dataGridView.Rows.Clear();
foreach (var element in _shopShips)
{
dataGridView.Rows.Add(new object[] { element.Key, element.Value.Item1.ShipName, element.Value.Item2 });
}
}
}
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(textBoxName.Text))
{
MessageBox.Show("Заполните название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxAddress.Text))
{
MessageBox.Show("Заполните адрес", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(dateTimePickerDateOpen.Text))
{
MessageBox.Show("Заполните дату", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (numericUpDownCapacity.Value <= 0)
{
MessageBox.Show("Вместимость должна быть больше нуля", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение магазина");
try
{
var model = new ShopBindingModel
{
Id = _id ?? 0,
ShopName = textBoxName.Text,
Address = textBoxAddress.Text,
DateOpen = DateTime.Parse(dateTimePickerDateOpen.Text),
Capacity = (int)numericUpDownCapacity.Value,
ShopShips = _shopShips
};
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,117 @@
namespace ShipyardView
{
partial class FormShops
{
/// <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.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(631, 450);
dataGridView.TabIndex = 0;
//
// ButtonAdd
//
ButtonAdd.Location = new Point(670, 33);
ButtonAdd.Name = "ButtonAdd";
ButtonAdd.Size = new Size(106, 48);
ButtonAdd.TabIndex = 1;
ButtonAdd.Text = "Создать";
ButtonAdd.UseVisualStyleBackColor = true;
ButtonAdd.Click += ButtonAdd_Click;
//
// ButtonUpd
//
ButtonUpd.Location = new Point(670, 102);
ButtonUpd.Name = "ButtonUpd";
ButtonUpd.Size = new Size(106, 48);
ButtonUpd.TabIndex = 2;
ButtonUpd.Text = "Изменить";
ButtonUpd.UseVisualStyleBackColor = true;
ButtonUpd.Click += ButtonUpd_Click;
//
// ButtonDel
//
ButtonDel.Location = new Point(670, 165);
ButtonDel.Name = "ButtonDel";
ButtonDel.Size = new Size(106, 48);
ButtonDel.TabIndex = 3;
ButtonDel.Text = "Удалить";
ButtonDel.UseVisualStyleBackColor = true;
ButtonDel.Click += ButtonDel_Click;
//
// ButtonRef
//
ButtonRef.Location = new Point(670, 229);
ButtonRef.Name = "ButtonRef";
ButtonRef.Size = new Size(106, 48);
ButtonRef.TabIndex = 4;
ButtonRef.Text = "Обновить";
ButtonRef.UseVisualStyleBackColor = true;
ButtonRef.Click += ButtonRef_Click;
//
// FormShops
//
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 = "FormShops";
Text = "Магазины";
Load += FormShops_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,105 @@
using Microsoft.Extensions.Logging;
using ShipyardContracts.BindingModels;
using ShipyardContracts.BusinessLogicsContracts;
using System.Windows.Forms;
namespace ShipyardView
{
public partial class FormShops : Form
{
private readonly ILogger _logger;
private readonly IShopLogic _logic;
public FormShops(ILogger<FormShops> logger, IShopLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormShops_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["ShopShips"].Visible = false;
dataGridView.Columns["ShopName"].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(FormShop));
if (service is FormShop 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(FormShop));
if (service is FormShop 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 ShopBindingModel
{
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,18 @@
<?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">
<targets>
<target xsi:type="File" name="tofile" fileName="logs/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" />
</rules>
</nlog>
</configuration>

View File

@ -0,0 +1,55 @@
using Microsoft.Extensions.DependencyInjection;
using ShipyardBusinessLogic.BusinessLogics;
using ShipyardContracts.BusinessLogicsContracts;
using ShipyardContracts.StoragesContracts;
using ShipyardFileImplement.Implements;
using NLog.Extensions.Logging;
namespace ShipyardView
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
private static void ConfigureServices(ServiceCollection services)
{
services.AddLogging(option =>
{
option.AddNLog("NLog.config");
});
services.AddTransient<IDetailStorage, DetailStorage>();
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IShipStorage, ShipStorage>();
services.AddTransient<IDetailLogic, DetailLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IShopStorage, ShopStorage>();
services.AddTransient<IShipLogic, ShipLogic>();
services.AddTransient<IShopLogic, ShopLogic>();
services.AddTransient<FormMain>();
services.AddTransient<FormDetail>();
services.AddTransient<FormDetails>();
services.AddTransient<FormCreateOrder>();
services.AddTransient<FormShip>();
services.AddTransient<FormShipDetail>();
services.AddTransient<FormShips>();
services.AddTransient<FormShop>();
services.AddTransient<FormShops>();
services.AddTransient<FormAddShip>();
services.AddTransient<FormSellShips>();
}
}
}

View File

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<None Remove="C:\Users\Марсель\.nuget\packages\nlog.config\4.7.15\contentFiles\any\any\NLog.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ShipyardBusinessLogic\ShipyardBusinessLogic.csproj" />
<ProjectReference Include="..\ShipyardFileImplement\ShipyardFileImplement.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>