Compare commits

...

9 Commits

Author SHA1 Message Date
nikbel2004@outlook.com
80f7910057 Правки 2024-05-03 11:42:01 +04:00
nikbel2004@outlook.com
ed48e3d27a Правки Лабораторная работа 4 2024-04-08 15:18:06 +04:00
nikbel2004@outlook.com
eefd8937e6 Правки Лабораторная работа 4 2024-04-08 14:17:05 +04:00
nikbel2004@outlook.com
195c160f71 Лабораторная работа 4 2024-04-08 14:11:47 +04:00
nikbel2004@outlook.com
20aa4971d5 Лабораторная работа 3 2024-03-11 12:12:21 +04:00
nikbel2004@outlook.com
6bcf56a3f8 Готовая лабораторная работа 2 2024-02-26 11:05:12 +04:00
nikbel2004@outlook.com
c536721707 Готовая лабораторная работа 1 2024-02-26 10:40:44 +04:00
nikbel2004@outlook.com
28fbc343b3 Готовая лабораторная работа 1 2024-02-26 10:30:01 +04:00
nikbel2004@outlook.com
5f2b668f98 Готовая лабораторная работа 1 2024-02-26 10:12:21 +04:00
111 changed files with 9060 additions and 85 deletions

View File

@ -1,9 +1,21 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34202.233
VisualStudioVersion = 17.8.34525.116
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FurnitureAssemblyView", "FurnitureAssembly\FurnitureAssemblyView.csproj", "{7A30F3E0-D8A6-436F-BB98-7C63A0AC9D1A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FurnitureAssemblyContracts", "FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj", "{A5F526DF-C1CD-4FCA-87E6-BDB447FF959C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FurnitureAssemblyDataModels", "FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj", "{7A1F9F2F-DDA5-4C97-8FAA-149D5372365D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FurnitureAssemblyBusinessLogic", "FurnitureAssemblyBusinessLogic\FurnitureAssemblyBusinessLogic.csproj", "{27F73911-7647-475A-875D-C7A4046B0958}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FurnitureAssemblyListImplement", "FurnitureAssemblyListImplement\FurnitureAssemblyListImplement.csproj", "{332092CD-AA0D-475A-88A2-2E887E29E56A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FurnitureAssemblyView", "FurnitureAssemblyView\FurnitureAssemblyView.csproj", "{77944C5A-53FC-437B-A563-E7C09C769859}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FurnitureAssemblyFileImplement", "FurnitureAssemblyFileImplement\FurnitureAssemblyFileImplement.csproj", "{2EF175D6-B6BD-442B-B81E-67E368553726}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FurnitureAssemblyDatabaseImplement", "FurnitureAssemblyDatabaseImplement\FurnitureAssemblyDatabaseImplement.csproj", "{C2302631-5038-4592-B75F-C03C3ABD510D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -11,15 +23,39 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7A30F3E0-D8A6-436F-BB98-7C63A0AC9D1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7A30F3E0-D8A6-436F-BB98-7C63A0AC9D1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A30F3E0-D8A6-436F-BB98-7C63A0AC9D1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A30F3E0-D8A6-436F-BB98-7C63A0AC9D1A}.Release|Any CPU.Build.0 = Release|Any CPU
{A5F526DF-C1CD-4FCA-87E6-BDB447FF959C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5F526DF-C1CD-4FCA-87E6-BDB447FF959C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5F526DF-C1CD-4FCA-87E6-BDB447FF959C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5F526DF-C1CD-4FCA-87E6-BDB447FF959C}.Release|Any CPU.Build.0 = Release|Any CPU
{7A1F9F2F-DDA5-4C97-8FAA-149D5372365D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7A1F9F2F-DDA5-4C97-8FAA-149D5372365D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A1F9F2F-DDA5-4C97-8FAA-149D5372365D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A1F9F2F-DDA5-4C97-8FAA-149D5372365D}.Release|Any CPU.Build.0 = Release|Any CPU
{27F73911-7647-475A-875D-C7A4046B0958}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27F73911-7647-475A-875D-C7A4046B0958}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27F73911-7647-475A-875D-C7A4046B0958}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27F73911-7647-475A-875D-C7A4046B0958}.Release|Any CPU.Build.0 = Release|Any CPU
{332092CD-AA0D-475A-88A2-2E887E29E56A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{332092CD-AA0D-475A-88A2-2E887E29E56A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{332092CD-AA0D-475A-88A2-2E887E29E56A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{332092CD-AA0D-475A-88A2-2E887E29E56A}.Release|Any CPU.Build.0 = Release|Any CPU
{77944C5A-53FC-437B-A563-E7C09C769859}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77944C5A-53FC-437B-A563-E7C09C769859}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77944C5A-53FC-437B-A563-E7C09C769859}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77944C5A-53FC-437B-A563-E7C09C769859}.Release|Any CPU.Build.0 = Release|Any CPU
{2EF175D6-B6BD-442B-B81E-67E368553726}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2EF175D6-B6BD-442B-B81E-67E368553726}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2EF175D6-B6BD-442B-B81E-67E368553726}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2EF175D6-B6BD-442B-B81E-67E368553726}.Release|Any CPU.Build.0 = Release|Any CPU
{C2302631-5038-4592-B75F-C03C3ABD510D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2302631-5038-4592-B75F-C03C3ABD510D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2302631-5038-4592-B75F-C03C3ABD510D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2302631-5038-4592-B75F-C03C3ABD510D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9E8D434F-5103-482B-B148-55812D18E11C}
SolutionGuid = {27CD86DA-500B-4657-9703-3564F0C00790}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,161 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.BussinessLogic
{
// Класс, реализующий логику для изделий
public class FurnitureLogic : IFurnitureLogic
{
private readonly ILogger _logger;
private readonly IFurnitureStorage _furnitureStorage;
// Конструктор
public FurnitureLogic(ILogger<FurnitureLogic> logger, IFurnitureStorage furnitureStorage)
{
_logger = logger;
_furnitureStorage = furnitureStorage;
}
// Вывод отфильтрованного списка
public List<FurnitureViewModel>? ReadList(FurnitureSearchModel? model)
{
_logger.LogInformation("ReadList. FurnitureName: {FurnitureName}. Id:{Id}", model?.FurnitureName, model?.Id);
// list хранит весь список в случае, если model пришло со значением null на вход метода
var list = model == null ? _furnitureStorage.GetFullList() : _furnitureStorage.GetFilteredList(model);
if(list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
// Вывод конкретного изделия
public FurnitureViewModel? ReadElement(FurnitureSearchModel model)
{
if(model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. FurnitureName: {FurnitureName}. Id:{Id}", model.FurnitureName, model.Id);
var element = _furnitureStorage.GetElement(model);
if(element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("Readelement find. Id:{Id}", model.Id);
return element;
}
// Создание изделия
public bool Create(FurnitureBindingModel model)
{
CheckModel(model);
if(_furnitureStorage.Insert(model) == null)
{
_logger.LogWarning("Create operation failed");
return false;
}
return true;
}
// Обновление изделия
public bool Update(FurnitureBindingModel model)
{
CheckModel(model);
if(_furnitureStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
// Удаление изделия
public bool Delete(FurnitureBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete, Id:{Id}", model.Id);
if(_furnitureStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
// Проверка входного аргумента для методов Insert, Update и Delete
private void CheckModel(FurnitureBindingModel model, bool withParams = true)
{
if(model == null)
{
throw new ArgumentNullException(nameof(model));
}
// При удалении параметру withParams передаём false
if (!withParams)
{
return;
}
// Проверка на наличие названия изделия
if(string.IsNullOrEmpty(model.FurnitureName))
{
throw new ArgumentNullException("Нет названия изделия", nameof(model.FurnitureName));
}
// Проверка на наличие нормальной цены у изделия
if(model.Price <= 0)
{
throw new ArgumentNullException("Цена изделия должна быть больше 0", nameof(model.Price));
}
_logger.LogInformation("Furniture. FurnitureName:{FurnitureName}. Price:{Price}. Id:{Id}",
model.FurnitureName, model.Price, model.Id);
// Проверка на наличие такого же изделия в списке
var element = _furnitureStorage.GetElement(new FurnitureSearchModel
{
FurnitureName = model.FurnitureName,
});
// Если элемент найден и его Id не совпадает с Id объекта, переданного на вход
if(element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Изделие с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,174 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Enums;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.BussinessLogic
{
// Класс, реализующий логику для заказов
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
// Конструктор
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
{
_logger = logger;
_orderStorage = orderStorage;
}
// Вывод отфильтрованного списка компонентов
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{Id}", model?.Id);
// list хранит весь список в случае, если model пришло со значением null на вход метода
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, incorrect order status");
return false;
}
model.Status = OrderStatus.Принят;
if(_orderStorage.Insert(model) == null)
{
model.Status = OrderStatus.Неизвестен;
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выполняется);
}
public bool FinishOrder(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выдан);
}
// Проверка на пустоту входного параметра
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
// При удалении параметру withParams передаём false
if (!withParams)
{
return;
}
// Проверка на наличие товаров в заказе
if(model.Count <= 0)
{
throw new ArgumentNullException("В заказе не может быть 0 изделий", nameof(model.Count));
}
// Проверка на наличие нормальной суммарной стоимости чека
if(model.Sum <= 0)
{
throw new ArgumentNullException("Суммарная стоимость заказа должна быть больше 0", nameof(model.Sum));
}
// Проверка корректности id у изделий
if(model.FurnitureId < 0)
{
throw new ArgumentNullException("Некорректный id у изделия", nameof(model.FurnitureId));
}
// Проверка корректности дат
if(model.DateCreate > model.DateImplement)
{
throw new InvalidOperationException("Дата создания должна быть более ранней, нежели дата завершения");
}
_logger.LogInformation("Order. OrderId:{Id}, Sum:{Sum}. FurnitureId:{Id}", model.Id, model.Sum, model.FurnitureId);
}
// Обновление статуса заказа
public bool StatusUpdate(OrderBindingModel model, OrderStatus newOrderStatus)
{
var viewModel = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
// Если не смогли найти указанный заказ по его Id
if(viewModel == null)
{
throw new ArgumentNullException(nameof(model));
}
// Проверка на возможность обновления статуса на следующий
if(viewModel.Status + 1 != newOrderStatus)
{
_logger.LogWarning("Status update operation failed. New status " + newOrderStatus.ToString() + "incorrect");
return false;
}
model.Status = newOrderStatus;
// Проверка на выдачу
if(model.Status == OrderStatus.Выдан)
{
model.DateImplement = DateTime.Now;
}
else
{
model.DateImplement = viewModel.DateImplement;
}
CheckModel(model, false);
// Финальная проверка на возможность обновления
if(_orderStorage.Update(model) == null)
{
model.Status--;
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,119 @@
using FurnitureAssemblyBusinessLogic.OfficePackage;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels;
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.BussinessLogic
{
// Реализация бизнес-логики отчётов
public class ReportLogic : IReportLogic
{
private readonly IFurnitureStorage _furnitureStorage;
private readonly IOrderStorage _orderStorage;
private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToPdf _saveToPdf;
// Инициализируем поля класса через контейнер
public ReportLogic(IFurnitureStorage furnitureStorage,
IOrderStorage orderStorage, AbstractSaveToExcel saveToExcel,
AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
{
_furnitureStorage = furnitureStorage;
_orderStorage = orderStorage;
_saveToExcel = saveToExcel;
_saveToWord = saveToWord;
_saveToPdf = saveToPdf;
}
// Получение списка компонент с указанием, в каких изделиях используются
public List<ReportFurnitureWorkPieceViewModel> GetFurnitureWorkPiece()
{
var furnitures = _furnitureStorage.GetFullList();
var list = new List<ReportFurnitureWorkPieceViewModel>();
foreach (var furniture in furnitures)
{
var record = new ReportFurnitureWorkPieceViewModel
{
FurnitureName = furniture.FurnitureName,
WorkPieces = new List<(string, int)>(),
TotalCount = 0
};
foreach (var workPiece in furniture.FurnitureWorkPieces)
{
record.WorkPieces.Add(new(workPiece.Value.Item1.WorkPieceName, workPiece.Value.Item2));
record.TotalCount += workPiece.Value.Item2;
}
list.Add(record);
}
return list;
}
// Получение списка заказов за определённый период
public List<ReportOrdersViewModel> GetOrders(ReportBindingModel model)
{
return _orderStorage.GetFilteredList(new OrderSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo })
.Select(x => new ReportOrdersViewModel
{
Id = x.Id,
DateCreate = x.DateCreate,
FurnitureName = x.FurnitureName,
Sum = x.Sum,
OrderStatus = x.Status.ToString()
}).ToList();
}
// Сохранение мебели в файл-Word
public void SaveFurnituresToWordFile(ReportBindingModel model)
{
_saveToWord.CreateDoc(new WordInfo
{
FileName = model.FileName,
Title = "Список изделий",
Furnitures = _furnitureStorage.GetFullList()
});
}
// Сохранение заготовок с указанием изделий в файл_Excel
public void SaveFurnitureWorkPieceToExcelFile(ReportBindingModel model)
{
_saveToExcel.CreateReport(new ExcelInfo
{
FileName = model.FileName,
Title = "Список заготовок",
FurnitureWorkPieces = GetFurnitureWorkPiece()
});
}
// Сохранение заказов в файл-Pdf
public void SaveOrdersToPdfFile(ReportBindingModel model)
{
_saveToPdf.CreateDoc(new PdfInfo
{
FileName = model.FileName,
Title = "Список заказов",
DateFrom = model.DateFrom!.Value,
DateTo = model.DateTo!.Value,
Orders = GetOrders(model)
});
}
}
}

View File

@ -0,0 +1,161 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.BussinessLogic
{
// Класс, реализующий логику для заготовок
public class WorkPieceLogic : IWorkPieceLogic
{
private readonly ILogger _logger;
private readonly IWorkPieceStorage _workPieceStorage;
// Конструктор
public WorkPieceLogic(ILogger<WorkPieceLogic> logger, IWorkPieceStorage workPieceStorage)
{
_logger = logger;
_workPieceStorage = workPieceStorage;
}
// Вывод отфильтрованного списка компонентов
public List<WorkPieceViewModel>? ReadList(WorkPieceSearchModel? model)
{
_logger.LogInformation("ReadList. WorkPieceName:{WorkPieceName}. Id:{Id}", model?.WorkPieceName, model?.Id);
// list хранит весь список в случае, если model пришло со значением null на вход метода
var list = model == null ? _workPieceStorage.GetFullList() : _workPieceStorage.GetFilteredList(model);
if(list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
// Вывод конкретной заготовки
public WorkPieceViewModel? ReadElement(WorkPieceSearchModel model)
{
if(model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. WorkPieceName:{WorkPieceName}. Id:{Id}", model.WorkPieceName, model.Id);
var element = _workPieceStorage.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(WorkPieceBindingModel model)
{
CheckModel(model);
if(_workPieceStorage.Insert(model) == null)
{
_logger.LogWarning("insert operation failed");
return false;
}
return true;
}
// Обновление заготовки
public bool Update(WorkPieceBindingModel model)
{
CheckModel(model);
if(_workPieceStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
// Удаление заготовки
public bool Delete(WorkPieceBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if(_workPieceStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
// Проверка входного аргумента для методов Insert, Update и Delete
private void CheckModel(WorkPieceBindingModel model, bool withParams = true)
{
if(model == null)
{
throw new ArgumentNullException(nameof(model));
}
// При удалении передаём как параметр false
if (!withParams)
{
return;
}
// Проверка на наличие названия заготовки
if (string.IsNullOrEmpty(model.WorkPieceName))
{
throw new ArgumentNullException("Нет названия заготовки", nameof(model.WorkPieceName));
}
// Проверка на наличие нормальной цены у заготовки
if(model.Cost <= 0)
{
throw new ArgumentNullException("Цена заготовки должна быть больше 0", nameof(model.Cost));
}
_logger.LogInformation("WorkPiece. WorkPieceName:{WorkPieceName}. Cost:{Cost}. Id{Id}",
model.WorkPieceName, model.Cost, model.Id);
// Проверка на наличие такой же заготовки в списке
var element = _workPieceStorage.GetElement(new WorkPieceSearchModel
{
WorkPieceName = model.WorkPieceName,
});
// Если элемент найден и его Id не совпадает с Id переданного объекта
if(element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Заготовка с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="MigraDocCore.DocumentObjectModel" Version="1.3.63" />
<PackageReference Include="MigraDocCore.Rendering" Version="1.3.63" />
<PackageReference Include="PDFsharp-MigraDoc-GDI" Version="1.50.5147" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,101 @@
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcel
{
// Создание отчета. Описание методов ниже
public void CreateReport(ExcelInfo info)
{
CreateExcel(info);
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = info.Title,
StyleInfo = ExcelStyleInfoType.Title
});
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "C1"
});
uint rowIndex = 2;
foreach (var fwp in info.FurnitureWorkPieces)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = fwp.FurnitureName,
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
foreach (var (WorkPiece, Count) in fwp.WorkPieces)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = WorkPiece,
StyleInfo = ExcelStyleInfoType.TextWithBorder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = Count.ToString(),
StyleInfo = ExcelStyleInfoType.TextWithBorder
});
rowIndex++;
}
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = "Итого",
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = fwp.TotalCount.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
}
SaveExcel(info);
}
// Создание Excel-файла
protected abstract void CreateExcel(ExcelInfo info);
// Добавляем новую ячейку в лист
protected abstract void InsertCellInWorksheet(ExcelCellParameters excelParams);
// Объединение ячеек
protected abstract void MergeCells(ExcelMergeParameters excelParams);
// Сохранение файла
protected abstract void SaveExcel(ExcelInfo info);
}
}

View File

@ -0,0 +1,76 @@
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdf
{
// Публичный метод создания документа. Описание методов ниже
public void CreateDoc(PdfInfo info)
{
CreatePdf(info);
CreateParagraph(new PdfParagraph
{
Text = info.Title,
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateParagraph(new PdfParagraph
{
Text = $"с {info.DateFrom.ToShortDateString()} по {info.DateTo.ToShortDateString()}",
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateTable(new List<string> { "2cm", "3cm", "6cm", "3cm", "3cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Номер", "Дата заказа", "Изделие", "Сумма", "Статус заказа" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var order in info.Orders)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { order.Id.ToString(), order.DateCreate.ToShortDateString(), order.FurnitureName, order.Sum.ToString(), order.OrderStatus },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
CreateParagraph(new PdfParagraph
{
Text = $"\nИтого: {info.Orders.Sum(x => x.Sum)}\t",
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Right
});
SavePdf(info);
}
/// Создание Pdf-файла
protected abstract void CreatePdf(PdfInfo info);
/// Создание параграфа с текстом
protected abstract void CreateParagraph(PdfParagraph paragraph);
/// Создание таблицы
protected abstract void CreateTable(List<string> columns);
/// Создание и заполнение строки
protected abstract void CreateRow(PdfRowParameters rowParameters);
/// Сохранение файла
protected abstract void SavePdf(PdfInfo info);
}
}

View File

@ -0,0 +1,56 @@
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWord
{
// Метод создания документа
public void CreateDoc(WordInfo info)
{
CreateWord(info);
// Создание ряда абзацев
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (info.Title, new WordTextProperties { Bold = true, Size = "24", }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
// Заполнение абзацев текстом
foreach (var furniture in info.Furnitures)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (furniture.FurnitureName + " ", new WordTextProperties { Bold = true, Size = "24", }),
(furniture.Price.ToString(), new WordTextProperties { Size = "24" }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
}
SaveWord(info);
}
// Создание Doc-файла
protected abstract void CreateWord(WordInfo info);
// Создание абзаца с текстом
protected abstract void CreateParagraph(WordParagraph paragraph);
// Сохранение файла
protected abstract void SaveWord(WordInfo info);
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums
{
// Вспомогательное перечисление для оформления excel
public enum ExcelStyleInfoType
{
// Заголовок
Title,
// Просто текст
Text,
// Текст в рамке
TextWithBorder
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums
{
// Вспомогательное перечисление для оформления pdf документа
public enum PdfParagraphAlignmentType
{
// Либо по центру
Center,
// Либо с левого края
Left,
// Либо с правого края
Right
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums
{
// Вспомогательное перечисление для настройки формата word документа
public enum WordJustificationType
{
// Выравниваем либо по центру
Center,
// Либо на всю ширину
Both
}
}

View File

@ -0,0 +1,28 @@
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels
{
// Информация по ячейке в таблице excel
public class ExcelCellParameters
{
// Название колонки
public string ColumnName { get; set; } = string.Empty;
// Строка
public uint RowIndex { get; set; }
// Тект в ячейке
public string Text { get; set; } = string.Empty;
// Геттер для того, чтобы не искать каждый раз
public string CellReference => $"{ColumnName}{RowIndex}";
// В каком стиле выводить информацию
public ExcelStyleInfoType StyleInfo { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels
{
// Информация по excel файлу, который хотим создать
public class ExcelInfo
{
// Название файла
public string FileName { get; set; } = string.Empty;
// Заголовок
public string Title { get; set; } = string.Empty;
// Список заготовок по изделиям
public List<ReportFurnitureWorkPieceViewModel> FurnitureWorkPieces { get; set; } = new();
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels
{
// Информация для объединения ячеек
public class ExcelMergeParameters
{
public string CellFromName { get; set; } = string.Empty;
public string CellToName { get; set; } = string.Empty;
// Геттер для указания диапазона для объединения, чтобы каждый раз его не вычислять
public string Merge => $"{CellFromName}:{CellToName}";
}
}

View File

@ -0,0 +1,24 @@
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels
{
// Общая информация по pdf файлу
public class PdfInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
// Перечень заказов за указанный период для вывода/сохранения
public List<ReportOrdersViewModel> Orders { get; set; } = new();
}
}

View File

@ -0,0 +1,20 @@
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels
{
// Информация п параграфу в pdf документе
public class PdfParagraph
{
public string Text { get; set; } = string.Empty;
public string Style { get; set; } = string.Empty;
// Информация по выравниванию текста в параграфе
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels
{
// Информация по параметрам строк таблицы
public class PdfRowParameters
{
// Набор текстов
public List<string> Texts { get; set; } = new();
// Стиль к текстам
public string Style { get; set; } = string.Empty;
// Как выравниваем
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels
{
// Общая информация по документу
public class WordInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
//список заготовок для вывода и сохранения
public List<FurnitureViewModel> Furnitures { get; set; } = new();
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels
{
// Модель параграфов, которые есть в тексте
public class WordParagraph
{
// Набор текстов в абзаце (для случая, если в абзаце текст разных стилей)
public List<(string, WordTextProperties)> Texts { get; set; } = new();
//свойства параграфа, если они есть
public WordTextProperties? TextProperties { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels
{
// Модель свойств текста, которые нам нужны в Word документе
public class WordTextProperties
{
// Размер текста
public string Size { get; set; } = string.Empty;
// Надо ли делать его жирным
public bool Bold { get; set; }
// Выравнивание
public WordJustificationType JustificationType { get; set; }
}
}

View File

@ -0,0 +1,393 @@
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.Implements
{
// Реализация абстрактного класса создания Excel документа
public class SaveToExcel : AbstractSaveToExcel
{
private SpreadsheetDocument? _spreadsheetDocument;
private SharedStringTablePart? _shareStringPart;
private Worksheet? _worksheet;
// Настройка стилей для файла
private static void CreateStyles(WorkbookPart workbookpart)
{
var sp = workbookpart.AddNewPart<WorkbookStylesPart>();
sp.Stylesheet = new Stylesheet();
// Настройка шрифта простого текста
var fonts = new Fonts() { Count = 2U, KnownFonts = true };
var fontUsual = new Font();
fontUsual.Append(new FontSize() { Val = 12D });
fontUsual.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Theme = 1U });
fontUsual.Append(new FontName() { Val = "Times New Roman" });
fontUsual.Append(new FontFamilyNumbering() { Val = 2 });
fontUsual.Append(new FontScheme() { Val = FontSchemeValues.Minor });
// Настройка шрифта заголока
var fontTitle = new Font();
fontTitle.Append(new Bold());
fontTitle.Append(new FontSize() { Val = 14D });
fontTitle.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Theme = 1U });
fontTitle.Append(new FontName() { Val = "Times New Roman" });
fontTitle.Append(new FontFamilyNumbering() { Val = 2 });
fontTitle.Append(new FontScheme() { Val = FontSchemeValues.Minor });
// Добавление созданных шрифтов
fonts.Append(fontUsual);
fonts.Append(fontTitle);
// Создание заливки
var fills = new Fills() { Count = 2U };
var fill1 = new Fill();
fill1.Append(new PatternFill()
{
PatternType = PatternValues.None
});
var fill2 = new Fill();
fill2.Append(new PatternFill()
{
PatternType = PatternValues.Gray125
});
fills.Append(fill1);
fills.Append(fill2);
// Стиль границ ячейки - незакрашенный (для заголовка) и закрашенный
var borders = new Borders() { Count = 2U };
var borderNoBorder = new Border();
borderNoBorder.Append(new LeftBorder());
borderNoBorder.Append(new RightBorder());
borderNoBorder.Append(new TopBorder());
borderNoBorder.Append(new BottomBorder());
borderNoBorder.Append(new DiagonalBorder());
var borderThin = new Border();
var leftBorder = new LeftBorder() { Style = BorderStyleValues.Thin };
leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
var rightBorder = new RightBorder()
{
Style = BorderStyleValues.Thin
};
rightBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
var topBorder = new TopBorder() { Style = BorderStyleValues.Thin };
topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
var bottomBorder = new BottomBorder()
{
Style = BorderStyleValues.Thin
};
bottomBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
borderThin.Append(leftBorder);
borderThin.Append(rightBorder);
borderThin.Append(topBorder);
borderThin.Append(bottomBorder);
borderThin.Append(new DiagonalBorder());
borders.Append(borderNoBorder);
borders.Append(borderThin);
// Формирование CellFormat из комбинаций шрифтов, заливок и т. д.
var cellStyleFormats = new CellStyleFormats() { Count = 1U };
var cellFormatStyle = new CellFormat()
{
NumberFormatId = 0U,
FontId = 0U,
FillId = 0U,
BorderId = 0U
};
cellStyleFormats.Append(cellFormatStyle);
var cellFormats = new CellFormats() { Count = 3U };
var cellFormatFont = new CellFormat()
{
NumberFormatId = 0U,
FontId = 0U,
FillId = 0U,
BorderId = 0U,
FormatId = 0U,
ApplyFont = true
};
var cellFormatFontAndBorder = new CellFormat()
{
NumberFormatId = 0U,
FontId = 0U,
FillId = 0U,
BorderId = 1U,
FormatId = 0U,
ApplyFont = true,
ApplyBorder = true
};
var cellFormatTitle = new CellFormat()
{
NumberFormatId = 0U,
FontId = 1U,
FillId = 0U,
BorderId = 0U,
FormatId = 0U,
Alignment = new Alignment()
{
Vertical = VerticalAlignmentValues.Center,
WrapText = true,
Horizontal = HorizontalAlignmentValues.Center
},
ApplyFont = true
};
// По итогу создали 3 стиля
cellFormats.Append(cellFormatFont);
cellFormats.Append(cellFormatFontAndBorder);
cellFormats.Append(cellFormatTitle);
var cellStyles = new CellStyles() { Count = 1U };
cellStyles.Append(new CellStyle()
{
Name = "Normal",
FormatId = 0U,
BuiltinId = 0U
});
var differentialFormats = new DocumentFormat.OpenXml.Office2013.Excel.DifferentialFormats() { Count = 0U };
var tableStyles = new TableStyles()
{
Count = 0U,
DefaultTableStyle = "TableStyleMedium2",
DefaultPivotStyle = "PivotStyleLight16"
};
var stylesheetExtensionList = new StylesheetExtensionList();
var stylesheetExtension1 = new StylesheetExtension()
{
Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}"
};
stylesheetExtension1.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
stylesheetExtension1.Append(new SlicerStyles()
{
DefaultSlicerStyle = "SlicerStyleLight1"
});
var stylesheetExtension2 = new StylesheetExtension()
{
Uri = "{9260A510-F301-46a8-8635-F512D64BE5F5}"
};
stylesheetExtension2.AddNamespaceDeclaration("x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
stylesheetExtension2.Append(new TimelineStyles()
{
DefaultTimelineStyle = "TimeSlicerStyleLight1"
});
stylesheetExtensionList.Append(stylesheetExtension1);
stylesheetExtensionList.Append(stylesheetExtension2);
sp.Stylesheet.Append(fonts);
sp.Stylesheet.Append(fills);
sp.Stylesheet.Append(borders);
sp.Stylesheet.Append(cellStyleFormats);
sp.Stylesheet.Append(cellFormats);
sp.Stylesheet.Append(cellStyles);
sp.Stylesheet.Append(differentialFormats);
sp.Stylesheet.Append(tableStyles);
sp.Stylesheet.Append(stylesheetExtensionList);
}
// Получение номера стиля (одного из 3-х нами созданных) из типа
private static uint GetStyleValue(ExcelStyleInfoType styleInfo)
{
return styleInfo switch
{
ExcelStyleInfoType.Title => 2U,
ExcelStyleInfoType.TextWithBorder => 1U,
ExcelStyleInfoType.Text => 0U,
_ => 0U,
};
}
protected override void CreateExcel(ExcelInfo info)
{
// Создаём документ Excel
_spreadsheetDocument = SpreadsheetDocument.Create(info.FileName, SpreadsheetDocumentType.Workbook);
// Создаем книгу (в ней хранятся листы)
var workbookpart = _spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
CreateStyles(workbookpart);
// Получаем/создаем хранилище текстов для книги
_shareStringPart = _spreadsheetDocument.WorkbookPart!.GetPartsOfType<SharedStringTablePart>().Any()
? _spreadsheetDocument.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First()
: _spreadsheetDocument.WorkbookPart.AddNewPart<SharedStringTablePart>();
// Создаем SharedStringTable, если его нет
if (_shareStringPart.SharedStringTable == null)
{
_shareStringPart.SharedStringTable = new SharedStringTable();
}
// Создаем лист в книгу
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Добавляем лист в книгу
var sheets = _spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id = _spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист"
};
sheets.Append(sheet);
_worksheet = worksheetPart.Worksheet;
}
// Метод вставки в лист книги
protected override void InsertCellInWorksheet(ExcelCellParameters excelParams)
{
if (_worksheet == null || _shareStringPart == null)
{
return;
}
var sheetData = _worksheet.GetFirstChild<SheetData>();
if (sheetData == null)
{
return;
}
// Ищем строку, либо добавляем ее
Row row;
if (sheetData.Elements<Row>().Where(r => r.RowIndex! == excelParams.RowIndex).Any())
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex! == excelParams.RowIndex).First();
}
else
{
row = new Row() { RowIndex = excelParams.RowIndex };
sheetData.Append(row);
}
// Ищем нужную ячейку
Cell cell;
if (row.Elements<Cell>().Where(c => c.CellReference!.Value == excelParams.CellReference).Any())
{
cell = row.Elements<Cell>().Where(c => c.CellReference!.Value == excelParams.CellReference).First();
}
else
{
// Все ячейки должны быть последовательно друг за другом расположены
// Нужно определить, после какой вставлять
Cell? refCell = null;
foreach (Cell rowCell in row.Elements<Cell>())
{
if (string.Compare(rowCell.CellReference!.Value, excelParams.CellReference, true) > 0)
{
refCell = rowCell;
break;
}
}
var newCell = new Cell()
{
CellReference = excelParams.CellReference
};
row.InsertBefore(newCell, refCell);
cell = newCell;
}
// Вставляем новый текст
_shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new Text(excelParams.Text)));
_shareStringPart.SharedStringTable.Save();
cell.CellValue = new CellValue((_shareStringPart.SharedStringTable.Elements<SharedStringItem>().Count() - 1).ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
cell.StyleIndex = GetStyleValue(excelParams.StyleInfo);
}
// Метод объединения ячеек
protected override void MergeCells(ExcelMergeParameters excelParams)
{
if (_worksheet == null)
{
return;
}
MergeCells mergeCells;
if (_worksheet.Elements<MergeCells>().Any())
{
mergeCells = _worksheet.Elements<MergeCells>().First();
}
else
{
mergeCells = new MergeCells();
if (_worksheet.Elements<CustomSheetView>().Any())
{
_worksheet.InsertAfter(mergeCells, _worksheet.Elements<CustomSheetView>().First());
}
else
{
_worksheet.InsertAfter(mergeCells, _worksheet.Elements<SheetData>().First());
}
}
var mergeCell = new MergeCell()
{
Reference = new StringValue(excelParams.Merge)
};
mergeCells.Append(mergeCell);
}
protected override void SaveExcel(ExcelInfo info)
{
if (_spreadsheetDocument == null)
{
return;
}
_spreadsheetDocument.WorkbookPart!.Workbook.Save();
_spreadsheetDocument.Dispose();
}
}
}

View File

@ -0,0 +1,131 @@
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.Implements
{
// Реализация абстрактного класса создания Pdf документа
public class SaveToPdf : AbstractSaveToPdf
{
private Document? _document;
private Section? _section;
private Table? _table;
// Преобразование необходимого типа выравнивания в соотвествующее выравнивание в MigraDoc
private static ParagraphAlignment GetParagraphAlignment(PdfParagraphAlignmentType type)
{
return type switch
{
PdfParagraphAlignmentType.Center => ParagraphAlignment.Center,
PdfParagraphAlignmentType.Left => ParagraphAlignment.Left,
PdfParagraphAlignmentType.Right => ParagraphAlignment.Right,
_ => ParagraphAlignment.Justify,
};
}
// Создание стилей для документа
private static void DefineStyles(Document document)
{
var style = document.Styles["Normal"];
style.Font.Name = "Times New Roman";
style.Font.Size = 14;
style = document.Styles.AddStyle("NormalTitle", "Normal");
style.Font.Bold = true;
}
protected override void CreatePdf(PdfInfo info)
{
// Создаём документ
_document = new Document();
// Передаём для него стили
DefineStyles(_document);
// Получение первой секции документа
_section = _document.AddSection();
}
protected override void CreateParagraph(PdfParagraph pdfParagraph)
{
if (_section == null)
{
return;
}
var paragraph = _section.AddParagraph(pdfParagraph.Text);
paragraph.Format.SpaceAfter = "1cm";
paragraph.Format.Alignment = GetParagraphAlignment(pdfParagraph.ParagraphAlignment);
paragraph.Style = pdfParagraph.Style;
}
protected override void CreateTable(List<string> columns)
{
if (_document == null)
{
return;
}
// Добавляем таблицу в документ как последнюю секцию (?)
_table = _document.LastSection.AddTable();
foreach (var elem in columns)
{
_table.AddColumn(elem);
}
}
protected override void CreateRow(PdfRowParameters rowParameters)
{
if (_table == null)
{
return;
}
// Добавление строки в таблицу
var row = _table.AddRow();
for (int i = 0; i < rowParameters.Texts.Count; ++i)
{
// Ячейка добавляется добавлением параграфа
row.Cells[i].AddParagraph(rowParameters.Texts[i]);
if (!string.IsNullOrEmpty(rowParameters.Style))
{
row.Cells[i].Style = rowParameters.Style;
}
Unit borderWidth = 0.5;
row.Cells[i].Borders.Left.Width = borderWidth;
row.Cells[i].Borders.Right.Width = borderWidth;
row.Cells[i].Borders.Top.Width = borderWidth;
row.Cells[i].Borders.Bottom.Width = borderWidth;
row.Cells[i].Format.Alignment = GetParagraphAlignment(rowParameters.ParagraphAlignment);
row.Cells[i].VerticalAlignment = VerticalAlignment.Center;
}
}
protected override void SavePdf(PdfInfo info)
{
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(info.FileName);
}
}
}

View File

@ -0,0 +1,159 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyBusinessLogic.OfficePackage.Implements
{
// Реализация абстрактного класса сохранения в Word документ
public class SaveToWord : AbstractSaveToWord
{
private WordprocessingDocument? _wordDocument;
private Body? _docBody;
// Получение типа выравнивания
private static JustificationValues GetJustificationValues(WordJustificationType type)
{
// Выравнивание слева будет в том случае, если передаётся неизвестный тип выравнивания
return type switch
{
WordJustificationType.Both => JustificationValues.Both,
WordJustificationType.Center => JustificationValues.Center,
_ => JustificationValues.Left,
};
}
// Настройки страницы
private static SectionProperties CreateSectionProperties()
{
var properties = new SectionProperties();
// Прописываем портретную ориентацию
var pageSize = new PageSize
{
Orient = PageOrientationValues.Portrait
};
properties.AppendChild(pageSize);
return properties;
}
// Задание форматирования для абзаца
private static ParagraphProperties? CreateParagraphProperties(WordTextProperties? paragraphProperties)
{
if (paragraphProperties == null)
{
return null;
}
var properties = new ParagraphProperties();
// Вытаскиваем выравнивание текста
properties.AppendChild(new Justification()
{
Val = GetJustificationValues(paragraphProperties.JustificationType)
});
properties.AppendChild(new SpacingBetweenLines
{
LineRule = LineSpacingRuleValues.Auto
});
properties.AppendChild(new Indentation());
var paragraphMarkRunProperties = new ParagraphMarkRunProperties();
if (!string.IsNullOrEmpty(paragraphProperties.Size))
{
paragraphMarkRunProperties.AppendChild(new FontSize
{
Val = paragraphProperties.Size
});
}
properties.AppendChild(paragraphMarkRunProperties);
return properties;
}
protected override void CreateWord(WordInfo info)
{
// Создаём документ Word
_wordDocument = WordprocessingDocument.Create(info.FileName, WordprocessingDocumentType.Document);
// Вытаскиваем главную часть из вордовского документа
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
// Генерируем тело основной части документа
_docBody = mainPart.Document.AppendChild(new Body());
}
protected override void CreateParagraph(WordParagraph paragraph)
{
// Проверка на то, был ли вызван WordprocessingDocument.Create (создался ли документ) и есть ли вообще параграф для вставки
if (_docBody == null || paragraph == null)
{
return;
}
var docParagraph = new Paragraph();
// Добавляем свойства параграфа
docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties));
// Вставляем блоки текста (их называют Run)
foreach (var run in paragraph.Texts)
{
var docRun = new Run();
var properties = new RunProperties();
// Задание свойств текста - размер и жирность
properties.AppendChild(new FontSize { Val = run.Item2.Size });
if (run.Item2.Bold)
{
properties.AppendChild(new Bold());
}
docRun.AppendChild(properties);
docRun.AppendChild(new Text
{
Text = run.Item1,
Space = SpaceProcessingModeValues.Preserve
});
docParagraph.AppendChild(docRun);
}
_docBody.AppendChild(docParagraph);
}
// Метод сохранения документа
protected override void SaveWord(WordInfo info)
{
if (_docBody == null || _wordDocument == null)
{
return;
}
// Вставляем информацию по секциям (смотри, что является входным параметром)
_docBody.AppendChild(CreateSectionProperties());
// Сохраняем документ
_wordDocument.MainDocumentPart!.Document.Save();
_wordDocument.Dispose();
}
}
}

View File

@ -0,0 +1,21 @@
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.BindingModels
{
// Реализация сущности "Изделие"
public class FurnitureBindingModel : IFurnitureModel
{
public int Id { get; set; }
public string FurnitureName { get; set; } = string.Empty;
public double Price { get; set; }
public Dictionary<int, (IWorkPieceModel, int)> FurnitureWorkPieces { get; set; } = new();
}
}

View File

@ -0,0 +1,27 @@
using FurnitureAssemblyDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.BindingModels
{
// Реализация сущности "Заказ"
public class OrderBindingModel
{
public int Id { get; set; }
public int FurnitureId { 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,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.BindingModels
{
// Реализация сущности "Отчёт"
public class ReportBindingModel
{
public string FileName { get; set; } = string.Empty;
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.BindingModels
{
// Реализация сущности "Компонент"
public class WorkPieceBindingModel
{
public int Id { get; set; }
public string WorkPieceName { get; set; } = string.Empty;
public double Cost { get; set; }
}
}

View File

@ -0,0 +1,25 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.BusinessLogicsContracts
{
// Бизнес-логика для продуктов
public interface IFurnitureLogic
{
List<FurnitureViewModel>? ReadList(FurnitureSearchModel? model);
FurnitureViewModel? ReadElement(FurnitureSearchModel model);
bool Create(FurnitureBindingModel model);
bool Update(FurnitureBindingModel model);
bool Delete(FurnitureBindingModel model);
}
}

View File

@ -0,0 +1,25 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.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,28 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.BusinessLogicsContracts
{
public interface IReportLogic
{
// Получение списка заготовок с указанием, в каких изделиях используются
List<ReportFurnitureWorkPieceViewModel> GetFurnitureWorkPiece();
// Получение списка заказов за определённый период
List<ReportOrdersViewModel> GetOrders(ReportBindingModel model);
// Сохранение изделий в файл-Word
void SaveFurnituresToWordFile(ReportBindingModel model);
// Сохранение заготовок с указанием изделий в файл-Excel
void SaveFurnitureWorkPieceToExcelFile(ReportBindingModel model);
// Сохранение заказов в файл-Pdf
void SaveOrdersToPdfFile(ReportBindingModel model);
}
}

View File

@ -0,0 +1,25 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.BusinessLogicsContracts
{
// Бизнес-логика для компонентов
public interface IWorkPieceLogic
{
List<WorkPieceViewModel>? ReadList(WorkPieceSearchModel? model);
WorkPieceViewModel? ReadElement(WorkPieceSearchModel model);
bool Create(WorkPieceBindingModel model);
bool Update(WorkPieceBindingModel model);
bool Delete(WorkPieceBindingModel model);
}
}

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="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.SearchModels
{
// Модель для поиска заготовки "Продукт" (она же изделие)
public class FurnitureSearchModel
{
// для поиска по идентификатору
public int? Id { get; set; }
// для поиска по названию
public string? FurnitureName { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.SearchModels
{
// Для поиска сущности "Заказ"
public class OrderSearchModel
{
// для поиска по идентификатору
public int? Id { get; set; }
// Два поля для возможности производить выборку
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set;}
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.SearchModels
{
// Модель для поиска сущности "Компонент" (она же заготовка)
public class WorkPieceSearchModel
{
//для поиска по идентификатору
public int? Id { get; set; }
//для поиска по названию
public string? WorkPieceName { get; set; }
}
}

View File

@ -0,0 +1,27 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.StoragesContracts
{
// Класс для хранилища продуктов (изделий)
public interface IFurnitureStorage
{
List<FurnitureViewModel> GetFullList();
List<FurnitureViewModel> GetFilteredList(FurnitureSearchModel model);
FurnitureViewModel? GetElement(FurnitureSearchModel model);
FurnitureViewModel? Insert(FurnitureBindingModel model);
FurnitureViewModel? Update(FurnitureBindingModel model);
FurnitureViewModel? Delete(FurnitureBindingModel model);
}
}

View File

@ -0,0 +1,27 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.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,27 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.StoragesContracts
{
// Класс хранилища компонентов (заготовок)
public interface IWorkPieceStorage
{
List<WorkPieceViewModel> GetFullList();
List<WorkPieceViewModel> GetFilteredList(WorkPieceSearchModel model);
WorkPieceViewModel? GetElement(WorkPieceSearchModel model);
WorkPieceViewModel? Insert(WorkPieceBindingModel model);
WorkPieceViewModel? Update(WorkPieceBindingModel model);
WorkPieceViewModel? Delete(WorkPieceBindingModel model);
}
}

View File

@ -0,0 +1,24 @@
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.ViewModels
{
// Класс для отображения пользователю информации о продуктах (изделиях)
public class FurnitureViewModel : IFurnitureModel
{
public int Id { get; set; }
[DisplayName("Название изделия")]
public string FurnitureName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Price { get; set; }
public Dictionary<int, (IWorkPieceModel, int)> FurnitureWorkPieces { get; set; } = new();
}
}

View File

@ -0,0 +1,38 @@
using FurnitureAssemblyDataModels.Enums;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.ViewModels
{
// Класс для отображения пользователю информации о заказах
public class OrderViewModel : IOrderModel
{
[DisplayName("Номер")]
public int Id { get; set; }
public int FurnitureId { get; set; }
[DisplayName("Изделие")]
public string FurnitureName { 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,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.ViewModels
{
public class ReportFurnitureWorkPieceViewModel
{
public string FurnitureName { get; set; } = string.Empty;
public int TotalCount { get; set; }
// Список кортежей
public List<(string WorkPiece, int Count)> WorkPieces { get; set; } = new();
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.ViewModels
{
public class ReportOrdersViewModel
{
public int Id { get; set; }
public DateTime DateCreate { get; set; }
public string FurnitureName { get; set; } = string.Empty;
public double Sum { get; set; }
public string OrderStatus { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyContracts.ViewModels
{
// Класс для отображения пользователю данных о заготовке (заготовках)
public class WorkPieceViewModel : IWorkPieceModel
{
public int Id { get; set; }
[DisplayName("Название заготовки")]
public string WorkPieceName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Cost { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDataModels.Enums
{
// Статус заказа
public enum OrderStatus
{
Неизвестен = -1,
Принят = 0,
Выполняется = 1,
Готов = 2,
Выдан = 3
}
}

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,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDataModels
{
// Интерфейс, отвечающий за id у компонентов, продуктов и чеков
public interface IId
{
int Id { get; }
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDataModels.Models
{
// Интерфейс, отвечающий за продукт
public interface IFurnitureModel : IId
{
// наименование изделия
string FurnitureName { get; }
// цена изделия
double Price { get; }
// словарь, хранящий пары кол-во + компонент и его цена
Dictionary<int, (IWorkPieceModel, int)> FurnitureWorkPieces { get; }
}
}

View File

@ -0,0 +1,31 @@
using FurnitureAssemblyDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDataModels.Models
{
// Интерфейс, отвечающий за заказ
public interface IOrderModel : IId
{
// id продукта
int FurnitureId { get; }
// кол-во продуктов
int Count { get; }
// суммарная стоимость продуктов
double Sum { get; }
// статус заказа
OrderStatus Status { get; }
//дата создания заказа
DateTime DateCreate { get; }
//дата завершения заказа (не обязательна к указанию сразу)
DateTime? DateImplement { get; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDataModels.Models
{
// Интерфейс, отвечающий за компоненты
public interface IWorkPieceModel : IId
{
// название составляющей (изделие состоит из составляющих)
string WorkPieceName { get; }
// цена составляющей
double Cost { get; }
}
}

View File

@ -0,0 +1,31 @@
using FurnitureAssemblyDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDatabaseImplement
{
public class FurnitureAssemblyDatabase : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseSqlServer(@"Data Source=KatanaNik\SQLEXPRESS;Initial Catalog=FurnitureAssemblyDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
}
base.OnConfiguring(optionsBuilder);
}
public virtual DbSet<WorkPiece> WorkPieces { set; get; }
public virtual DbSet<Furniture> Furnitures { set; get; }
public virtual DbSet<FurnitureWorkPiece> FurnitureWorkPieces { set; get; }
public virtual DbSet<Order> Orders { set; get; }
}
}

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.16" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.16" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.16">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" />
<ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,127 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDatabaseImplement.Implements
{
public class FurnitureStorage : IFurnitureStorage
{
public List<FurnitureViewModel> GetFullList()
{
using var context = new FurnitureAssemblyDatabase();
return context.Furnitures
.Include(x => x.WorkPieces)
.ThenInclude(x => x.WorkPiece)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<FurnitureViewModel> GetFilteredList(FurnitureSearchModel model)
{
if (string.IsNullOrEmpty(model.FurnitureName))
{
return new();
}
using var context = new FurnitureAssemblyDatabase();
return context.Furnitures
.Include(x => x.WorkPieces)
.ThenInclude(x => x.WorkPiece)
.Where(x => x.FurnitureName.Contains(model.FurnitureName))
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public FurnitureViewModel? GetElement(FurnitureSearchModel model)
{
if(string.IsNullOrEmpty(model.FurnitureName) && !model.Id.HasValue)
{
return null;
}
using var context = new FurnitureAssemblyDatabase();
return context.Furnitures
.Include(x => x.WorkPieces)
.ThenInclude(x => x.WorkPiece)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.FurnitureName) && x.FurnitureName == model.FurnitureName) ||
model.Id.HasValue && x.Id == model.Id)?.GetViewModel;
}
public FurnitureViewModel? Insert(FurnitureBindingModel model)
{
using var context = new FurnitureAssemblyDatabase();
var newFurniture = Furniture.Create(context, model);
if (newFurniture == null)
{
return null;
}
context.Furnitures.Add(newFurniture);
context.SaveChanges();
return newFurniture.GetViewModel;
}
public FurnitureViewModel? Update(FurnitureBindingModel model)
{
using var context = new FurnitureAssemblyDatabase();
using var transaction = context.Database.BeginTransaction();
try
{
var furniture = context.Furnitures.FirstOrDefault(rec => rec.Id == model.Id);
if (furniture == null)
{
return null;
}
furniture.Update(model);
context.SaveChanges();
furniture.UpdateWorkPieces(context, model);
transaction.Commit();
return furniture.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
public FurnitureViewModel? Delete(FurnitureBindingModel model)
{
using var context = new FurnitureAssemblyDatabase();
var element = context.Furnitures
.Include(x => x.WorkPieces)
.Include(x => x.Orders)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Furnitures.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,117 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDatabaseImplement.Implements
{
public class OrderStorage : IOrderStorage
{
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
using var context = new FurnitureAssemblyDatabase();
return context.Orders.Include(x => x.Furniture).
FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
?.GetViewModel;
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if(!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue)
{
return new();
}
using var context = new FurnitureAssemblyDatabase();
if (!model.Id.HasValue && model.DateFrom.HasValue && model.DateTo.HasValue)
{
return context.Orders
.Include(x => x.Furniture)
.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => x.GetViewModel)
.ToList();
}
return context.Orders
.Include(x => x.Furniture)
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.ToList();
}
public List<OrderViewModel> GetFullList()
{
using var context = new FurnitureAssemblyDatabase();
return context.Orders.Include(x => x.Furniture)
.Select(x => x.GetViewModel).ToList();
}
public OrderViewModel? Insert(OrderBindingModel model)
{
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
using var context = new FurnitureAssemblyDatabase();
context.Orders.Add(newOrder);
context.SaveChanges();
return context.Orders.Include(x => x.Furniture)
.FirstOrDefault(x => x.Id == newOrder.Id)?.GetViewModel;
}
public OrderViewModel? Update(OrderBindingModel model)
{
using var context = new FurnitureAssemblyDatabase();
var order = context.Orders.FirstOrDefault(x => x.Id == model.Id);
if (order == null)
{
return null;
}
order.Update(model);
context.SaveChanges();
return context.Orders.Include(x => x.Furniture).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
}
public OrderViewModel? Delete(OrderBindingModel model)
{
using var context = new FurnitureAssemblyDatabase();
var element = context.Orders.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
// для более корректного отображения модели
var deletedElement = context.Orders.Include(x => x.Furniture)
.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
context.Orders.Remove(element);
context.SaveChanges();
return deletedElement;
}
return null;
}
}
}

View File

@ -0,0 +1,102 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDatabaseImplement.Implements
{
public class WorkPieceStorage : IWorkPieceStorage
{
public List<WorkPieceViewModel> GetFullList()
{
using var context = new FurnitureAssemblyDatabase();
return context.WorkPieces
.Select(x => x.GetViewModel)
.ToList();
}
public List<WorkPieceViewModel> GetFilteredList(WorkPieceSearchModel model)
{
if (string.IsNullOrEmpty(model.WorkPieceName))
{
return new();
}
using var context = new FurnitureAssemblyDatabase();
return context.WorkPieces
.Where(x => x.WorkPieceName.Contains(model.WorkPieceName))
.Select(x => x.GetViewModel)
.ToList();
}
public WorkPieceViewModel? GetElement(WorkPieceSearchModel model)
{
if(string.IsNullOrEmpty(model.WorkPieceName) && !model.Id.HasValue)
{
return null;
}
using var context = new FurnitureAssemblyDatabase();
return context.WorkPieces
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.WorkPieceName) && x.WorkPieceName == model.WorkPieceName) ||
(model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public WorkPieceViewModel? Insert(WorkPieceBindingModel model)
{
var newWorkPiece = WorkPiece.Create(model);
if(newWorkPiece == null)
{
return null;
}
using var context = new FurnitureAssemblyDatabase();
context.WorkPieces.Add(newWorkPiece);
context.SaveChanges();
return newWorkPiece.GetViewModel;
}
public WorkPieceViewModel? Update(WorkPieceBindingModel model)
{
using var context = new FurnitureAssemblyDatabase();
var workPiece = context.WorkPieces.FirstOrDefault(x => x.Id == model.Id);
if (workPiece == null)
{
return null;
}
workPiece.Update(model);
context.SaveChanges();
return workPiece.GetViewModel;
}
public WorkPieceViewModel? Delete(WorkPieceBindingModel model)
{
using var context = new FurnitureAssemblyDatabase();
var element = context.WorkPieces.FirstOrDefault(rec => rec.Id == model.Id);
if(element != null)
{
context.WorkPieces.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,171 @@
// <auto-generated />
using System;
using FurnitureAssemblyDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace FurnitureAssemblyDatabaseImplement.Migrations
{
[DbContext(typeof(FurnitureAssemblyDatabase))]
[Migration("20240325045814_InitCreate")]
partial class InitCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.16")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("FurnitureName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Furnitures");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureWorkPiece", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("FurnitureId")
.HasColumnType("int");
b.Property<int>("WorkPieceId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("FurnitureId");
b.HasIndex("WorkPieceId");
b.ToTable("FurnitureWorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("FurnitureId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("FurnitureId");
b.ToTable("Orders");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Cost")
.HasColumnType("float");
b.Property<string>("WorkPieceName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("WorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureWorkPiece", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("WorkPieces")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", "WorkPiece")
.WithMany("FurnitureWorkPieces")
.HasForeignKey("WorkPieceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Furniture");
b.Navigation("WorkPiece");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("Orders")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Furniture");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Navigation("Orders");
b.Navigation("WorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", b =>
{
b.Navigation("FurnitureWorkPieces");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,125 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace FurnitureAssemblyDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Furnitures",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
FurnitureName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Price = table.Column<double>(type: "float", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Furnitures", x => x.Id);
});
migrationBuilder.CreateTable(
name: "WorkPieces",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
WorkPieceName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Cost = table.Column<double>(type: "float", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_WorkPieces", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
FurnitureId = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false),
Sum = table.Column<double>(type: "float", nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false),
DateImplement = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Furnitures_FurnitureId",
column: x => x.FurnitureId,
principalTable: "Furnitures",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "FurnitureWorkPieces",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
FurnitureId = table.Column<int>(type: "int", nullable: false),
WorkPieceId = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_FurnitureWorkPieces", x => x.Id);
table.ForeignKey(
name: "FK_FurnitureWorkPieces_Furnitures_FurnitureId",
column: x => x.FurnitureId,
principalTable: "Furnitures",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_FurnitureWorkPieces_WorkPieces_WorkPieceId",
column: x => x.WorkPieceId,
principalTable: "WorkPieces",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_FurnitureWorkPieces_FurnitureId",
table: "FurnitureWorkPieces",
column: "FurnitureId");
migrationBuilder.CreateIndex(
name: "IX_FurnitureWorkPieces_WorkPieceId",
table: "FurnitureWorkPieces",
column: "WorkPieceId");
migrationBuilder.CreateIndex(
name: "IX_Orders_FurnitureId",
table: "Orders",
column: "FurnitureId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "FurnitureWorkPieces");
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "WorkPieces");
migrationBuilder.DropTable(
name: "Furnitures");
}
}
}

View File

@ -0,0 +1,168 @@
// <auto-generated />
using System;
using FurnitureAssemblyDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace FurnitureAssemblyDatabaseImplement.Migrations
{
[DbContext(typeof(FurnitureAssemblyDatabase))]
partial class FurnitureAssemblyDatabaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.16")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("FurnitureName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Furnitures");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureWorkPiece", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("FurnitureId")
.HasColumnType("int");
b.Property<int>("WorkPieceId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("FurnitureId");
b.HasIndex("WorkPieceId");
b.ToTable("FurnitureWorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("FurnitureId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("FurnitureId");
b.ToTable("Orders");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Cost")
.HasColumnType("float");
b.Property<string>("WorkPieceName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("WorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureWorkPiece", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("WorkPieces")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", "WorkPiece")
.WithMany("FurnitureWorkPieces")
.HasForeignKey("WorkPieceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Furniture");
b.Navigation("WorkPiece");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("Orders")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Furniture");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Navigation("Orders");
b.Navigation("WorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", b =>
{
b.Navigation("FurnitureWorkPieces");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,119 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Models;
using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDatabaseImplement.Models
{
public class Furniture : IFurnitureModel
{
public int Id { get; set; }
[Required]
public string FurnitureName { get; set; } = string.Empty;
[Required]
public double Price { get; set; }
public Dictionary<int, (IWorkPieceModel, int)>? _furnitureWorkPieces = null;
// Это поле не будет "мапиться" в бд
[NotMapped]
public Dictionary<int, (IWorkPieceModel, int)> FurnitureWorkPieces
{
get
{
if(_furnitureWorkPieces == null)
{
_furnitureWorkPieces = WorkPieces
.ToDictionary(recPC => recPC.WorkPieceId, recPC => (recPC.WorkPiece as IWorkPieceModel, recPC.Count));
}
return _furnitureWorkPieces;
}
}
// Для реализации связи многие ко многим с заготовками
[ForeignKey("FurnitureId")]
public virtual List<FurnitureWorkPiece> WorkPieces { get; set; } = new();
[ForeignKey("FurnitureId")]
public virtual List<Order> Orders { get; set; } = new();
public static Furniture Create(FurnitureAssemblyDatabase context, FurnitureBindingModel model)
{
return new Furniture()
{
Id = model.Id,
FurnitureName = model.FurnitureName,
Price = model.Price,
WorkPieces = model.FurnitureWorkPieces.Select(x => new FurnitureWorkPiece
{
WorkPiece = context.WorkPieces.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList()
};
}
public void Update(FurnitureBindingModel model)
{
FurnitureName = model.FurnitureName;
Price = model.Price;
}
public FurnitureViewModel GetViewModel => new()
{
Id = Id,
FurnitureName = FurnitureName,
Price = Price,
FurnitureWorkPieces = FurnitureWorkPieces
};
Dictionary<int, (IWorkPieceModel, int)> IFurnitureModel.FurnitureWorkPieces => throw new NotImplementedException();
public void UpdateWorkPieces(FurnitureAssemblyDatabase context, FurnitureBindingModel model)
{
var furnitureWorkPieces = context.FurnitureWorkPieces.Where(rec => rec.FurnitureId == model.Id).ToList();
if(furnitureWorkPieces != null && furnitureWorkPieces.Count > 0)
{
// удалили те, которых нет в модели
context.FurnitureWorkPieces.RemoveRange(furnitureWorkPieces.Where(rec => !model.FurnitureWorkPieces.ContainsKey(rec.FurnitureId)));
context.SaveChanges();
// обновили количество у существующих записей
foreach (var updateFurniture in furnitureWorkPieces)
{
updateFurniture.Count = model.FurnitureWorkPieces[updateFurniture.FurnitureId].Item2;
model.FurnitureWorkPieces.Remove(updateFurniture.FurnitureId);
}
context.SaveChanges();
}
var furniture = context.Furnitures.First(x => x.Id == Id);
foreach(var pc in model.FurnitureWorkPieces)
{
context.FurnitureWorkPieces.Add(new FurnitureWorkPiece
{
Furniture = furniture,
WorkPiece = context.WorkPieces.First(x => x.Id == pc.Key),
Count = pc.Value.Item2
});
context.SaveChanges();
}
_furnitureWorkPieces = null;
}
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDatabaseImplement.Models
{
public class FurnitureWorkPiece
{
public int Id { get; set; }
[Required]
public int FurnitureId { get; set; }
[Required]
public int WorkPieceId { get; set; }
[Required]
public int Count { get; set; }
public virtual WorkPiece WorkPiece { get; set; } = new();
public virtual Furniture Furniture { get; set; } = new();
}
}

View File

@ -0,0 +1,80 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Enums;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDatabaseImplement.Models
{
public class Order : IOrderModel
{
public int Id { get; private set; }
[Required]
public int FurnitureId { get; private set; }
[Required]
public int Count { get; private set; }
[Required]
public double Sum { get; private set; }
[Required]
public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен;
[Required]
public DateTime DateCreate { get; private set; } = DateTime.Now;
public DateTime? DateImplement { get; private set; }
// Для передачи названия изделия
public virtual Furniture Furniture { get; set; }
public static Order? Create(OrderBindingModel model)
{
if (model == null)
{
return null;
}
return new Order()
{
Id = model.Id,
FurnitureId = model.FurnitureId,
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,
FurnitureId = FurnitureId,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement,
FurnitureName = Furniture.FurnitureName
};
}
}

View File

@ -0,0 +1,71 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyDatabaseImplement.Models
{
public class WorkPiece : IWorkPieceModel
{
public int Id { get; private set; }
[Required]
public string WorkPieceName { get; private set; } = string.Empty;
[Required]
public double Cost { get; set; }
// для реализации связи многие ко многим с изделиями
[ForeignKey("WorkPieceId")]
public virtual List<FurnitureWorkPiece> FurnitureWorkPieces { get; set; } = new();
public static WorkPiece? Create(WorkPieceBindingModel model)
{
if(model == null)
{
return null;
}
return new WorkPiece()
{
Id = model.Id,
WorkPieceName = model.WorkPieceName,
Cost = model.Cost
};
}
public static WorkPiece Create(WorkPieceViewModel model)
{
return new WorkPiece
{
Id = model.Id,
WorkPieceName = model.WorkPieceName,
Cost = model.Cost
};
}
public void Update(WorkPieceBindingModel model)
{
if(model == null)
{
return;
}
WorkPieceName = model.WorkPieceName;
Cost = model.Cost;
}
public WorkPieceViewModel GetViewModel => new()
{
Id = Id,
WorkPieceName = WorkPieceName,
Cost = Cost
};
}
}

View File

@ -0,0 +1,69 @@
using FurnitureAssemblyFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace FurnitureAssemblyFileImplement
{
internal class DataFileSingleton
{
private static DataFileSingleton? instance;
private readonly string WorkPieceFileName = "WorkPiece.xml";
private readonly string OrderFileName = "Order.xml";
private readonly string FurnitureFileName = "Furniture.xml";
public List<WorkPiece> WorkPieces { get; private set; }
public List<Order> Orders { get; private set; }
public List<Furniture> Furnitures { get; private set; }
public static DataFileSingleton GetInstance()
{
if (instance == null)
{
instance = new DataFileSingleton();
}
return instance;
}
public void SaveWorkPieces() => SaveData(WorkPieces, WorkPieceFileName, "WorkPieces", x => x.GetXElement);
public void SaveFurnitures() => SaveData(Furnitures, FurnitureFileName, "Furnitures", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
private DataFileSingleton()
{
WorkPieces = LoadData(WorkPieceFileName, "WorkPiece", x => WorkPiece.Create(x)!)!;
Furnitures = LoadData(FurnitureFileName, "Furniture", x => Furniture.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.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,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" />
<ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,97 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyFileImplement.Implements
{
// Реализация интерфейса хранилища изделий
public class FurnitureStorage : IFurnitureStorage
{
private readonly DataFileSingleton source;
public FurnitureStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<FurnitureViewModel> GetFullList()
{
return source.Furnitures.Select(x => x.GetViewModel).ToList();
}
public List<FurnitureViewModel> GetFilteredList(FurnitureSearchModel model)
{
if(string.IsNullOrEmpty(model.FurnitureName))
{
return new();
}
return source.Furnitures.Where(x => x.FurnitureName.Contains(model.FurnitureName)).Select(x => x.GetViewModel).ToList();
}
public FurnitureViewModel? GetElement(FurnitureSearchModel model)
{
if(string.IsNullOrEmpty(model.FurnitureName) && !model.Id.HasValue)
{
return null;
}
return source.Furnitures.FirstOrDefault(x => (!string.IsNullOrEmpty(model.FurnitureName) && x.FurnitureName == model.FurnitureName)
|| (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public FurnitureViewModel? Insert(FurnitureBindingModel model)
{
model.Id = source.Furnitures.Count > 0 ? source.Furnitures.Max(x => x.Id) + 1 : 1;
var newFurniture = Furniture.Create(model);
if(newFurniture == null)
{
return null;
}
source.Furnitures.Add(newFurniture);
source.SaveFurnitures();
return newFurniture.GetViewModel;
}
public FurnitureViewModel? Update(FurnitureBindingModel model)
{
var furniture = source.Furnitures.FirstOrDefault(x => x.Id == model.Id);
if(furniture == null)
{
return null;
}
furniture.Update(model);
source.SaveFurnitures();
return furniture.GetViewModel;
}
public FurnitureViewModel? Delete(FurnitureBindingModel model)
{
var element = source.Furnitures.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
source.Furnitures.Remove(element);
source.SaveFurnitures();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,112 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyFileImplement.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 && model.DateFrom.HasValue && model.DateTo.HasValue)
{
return source.Orders.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => GetViewModel(x)).ToList();
}
return source.Orders.Where(x => x.Id == 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 furniture = source.Furnitures.FirstOrDefault(x => x.Id == order.FurnitureId);
if(furniture != null)
{
viewModel.FurnitureName = furniture.FurnitureName;
}
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,97 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyFileImplement.Implements
{
// Реализация интерфейса хранилища заготовок
public class WorkPieceStorage : IWorkPieceStorage
{
private readonly DataFileSingleton source;
public WorkPieceStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<WorkPieceViewModel> GetFullList()
{
return source.WorkPieces.Select(x => x.GetViewModel).ToList();
}
public List<WorkPieceViewModel> GetFilteredList(WorkPieceSearchModel model)
{
if (string.IsNullOrEmpty(model.WorkPieceName))
{
return new();
}
return source.WorkPieces.Where(x => x.WorkPieceName.Contains(model.WorkPieceName)).Select(x => x.GetViewModel).ToList();
}
public WorkPieceViewModel? GetElement(WorkPieceSearchModel model)
{
if (string.IsNullOrEmpty(model.WorkPieceName) && !model.Id.HasValue)
{
return null;
}
return source.WorkPieces.FirstOrDefault(x => (!string.IsNullOrEmpty(model.WorkPieceName) && x.WorkPieceName == model.WorkPieceName)
|| (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public WorkPieceViewModel? Insert(WorkPieceBindingModel model)
{
model.Id = source.WorkPieces.Count > 0 ? source.WorkPieces.Max(x => x.Id) + 1 : 1;
var newWorkPiece = WorkPiece.Create(model);
if (newWorkPiece == null)
{
return null;
}
source.WorkPieces.Add(newWorkPiece);
source.SaveWorkPieces();
return newWorkPiece.GetViewModel;
}
public WorkPieceViewModel? Update(WorkPieceBindingModel model)
{
var workPiece = source.WorkPieces.FirstOrDefault(x => x.Id == model.Id);
if (workPiece == null)
{
return null;
}
workPiece.Update(model);
source.SaveWorkPieces();
return workPiece.GetViewModel;
}
public WorkPieceViewModel? Delete(WorkPieceBindingModel model)
{
var element = source.WorkPieces.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
source.WorkPieces.Remove(element);
source.SaveWorkPieces();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,107 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace FurnitureAssemblyFileImplement.Models
{
// Класс, реализующий интерфейс модели изделия
public class Furniture : IFurnitureModel
{
public int Id { get; private set; }
public string FurnitureName { get; private set; } = string.Empty;
public double Price { get; private set; }
public Dictionary<int, int> WorkPieces { get; private set; } = new();
private Dictionary<int, (IWorkPieceModel, int)>? _furnitureWorkPieces = null;
public Dictionary<int, (IWorkPieceModel, int)> FurnitureWorkPieces
{
get
{
if (_furnitureWorkPieces == null)
{
var source = DataFileSingleton.GetInstance();
_furnitureWorkPieces = WorkPieces.ToDictionary(x => x.Key,
y => ((source.WorkPieces.FirstOrDefault(z => z.Id == y.Key) as IWorkPieceModel)!, y.Value));
}
return _furnitureWorkPieces;
}
}
public static Furniture? Create(FurnitureBindingModel model)
{
if (model == null)
{
return null;
}
return new Furniture()
{
Id = model.Id,
FurnitureName = model.FurnitureName,
Price = model.Price,
WorkPieces = model.FurnitureWorkPieces.ToDictionary(x => x.Key, x => x.Value.Item2)
};
}
public static Furniture? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Furniture()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
FurnitureName = element.Element("FurnitureName")!.Value,
Price = Convert.ToDouble(element.Element("Price")!.Value),
WorkPieces = element.Element("FurnitureWorkPieces")!.Elements("FurnitureWorkPieces").ToDictionary(
x => Convert.ToInt32(x.Element("Key")?.Value),
y => Convert.ToInt32(y.Element("Value")?.Value))
};
}
public void Update(FurnitureBindingModel model)
{
if (model == null)
{
return;
}
FurnitureName = model.FurnitureName;
Price = model.Price;
WorkPieces = model.FurnitureWorkPieces.ToDictionary(x => x.Key, x => x.Value.Item2);
_furnitureWorkPieces = null;
}
public FurnitureViewModel GetViewModel => new()
{
Id = Id,
FurnitureName = FurnitureName,
Price = Price,
FurnitureWorkPieces = FurnitureWorkPieces
};
public XElement GetXElement => new("Furniture",
new XAttribute("Id", Id),
new XElement("FurnitureName", FurnitureName),
new XElement("Price", Price.ToString()),
new XElement("FurnitureWorkPieces", WorkPieces.Select(
x => new XElement("FurnitureWorkPieces",
new XElement("Key", x.Key),
new XElement("Value", x.Value))
).ToArray()));
}
}

View File

@ -0,0 +1,101 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Enums;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace FurnitureAssemblyFileImplement.Models
{
// Класс, реализующий интерфейс модели заказа
public class Order : IOrderModel
{
public int Id { get; private set; }
public int FurnitureId { 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,
FurnitureId = model.FurnitureId,
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;
}
return new Order()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
FurnitureId = Convert.ToInt32(element.Element("FurnitureId")!.Value),
Count = Convert.ToInt32(element.Element("Count")!.Value),
Sum = Convert.ToDouble(element.Element("Sum")!.Value),
Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value),
DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value),
DateImplement = string.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null :
Convert.ToDateTime(element.Element("DateImplement")!.Value)
};
}
public void Update(OrderBindingModel model)
{
if (model == null)
{
return;
}
Status = model.Status;
DateImplement = model.DateImplement;
}
public OrderViewModel GetViewModel => new()
{
Id = Id,
FurnitureId = FurnitureId,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement
};
public XElement GetXElement => new("Order",
new XAttribute("Id", Id),
new XElement("FurnitureId", FurnitureId.ToString()),
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,75 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace FurnitureAssemblyFileImplement.Models
{
// Класс, реализующий интерфейс модели заготовки
public class WorkPiece : IWorkPieceModel
{
public int Id { get; private set; }
public string WorkPieceName { get; private set; } = string.Empty;
public double Cost { get; set; }
public static WorkPiece? Create(WorkPieceBindingModel model)
{
if (model == null)
{
return null;
}
return new WorkPiece()
{
Id = model.Id,
WorkPieceName = model.WorkPieceName,
Cost = model.Cost
};
}
public static WorkPiece? Create(XElement element)
{
if (element == null)
{
return null;
}
return new WorkPiece()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
WorkPieceName = element.Element("WorkPieceName")!.Value,
Cost = Convert.ToDouble(element.Element("Cost")!.Value)
};
}
public void Update(WorkPieceBindingModel model)
{
if (model == null)
{
return;
}
WorkPieceName = model.WorkPieceName;
Cost = model.Cost;
}
public WorkPieceViewModel GetViewModel => new()
{
Id = Id,
WorkPieceName = WorkPieceName,
Cost = Cost
};
public XElement GetXElement => new("WorkPiece",
new XAttribute("Id", Id),
new XElement("WorkPieceName", WorkPieceName),
new XElement("Cost", Cost.ToString()));
}
}

View File

@ -0,0 +1,41 @@
using FurnitureAssemblyListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyListImplement
{
// Класс для списков, в которых будет храниться информация при работе приложения
public class DataListSingleton
{
private static DataListSingleton? _instance;
// Список для хранения заготовок
public List<WorkPiece> WorkPiece { get; set; }
// Список для хранения изделий
public List<Furniture> Furnitures { get; set; }
// Список для хранения заказов
public List<Order> Orders { get; set; }
public DataListSingleton()
{
WorkPiece = new List<WorkPiece>();
Furnitures = new List<Furniture>();
Orders = new List<Order>();
}
public static DataListSingleton GetInstance()
{
if(_instance == null)
{
_instance = new DataListSingleton();
}
return _instance;
}
}
}

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="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" />
<ProjectReference Include="..\FurnitureAssemblyDataModels\FurnitureAssemblyDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,138 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyListImplement.Implements
{
// Класс, реализующий интерфейс хранилища изделий
public class FurnitureStorage : IFurnitureStorage
{
// Поле для работы со списком изделий
private readonly DataListSingleton _source;
// Получение в конструкторе объекта DataListSingleton
public FurnitureStorage()
{
_source = DataListSingleton.GetInstance();
}
// Получение полного списка изделий
public List<FurnitureViewModel> GetFullList()
{
var result = new List<FurnitureViewModel>();
foreach(var furniture in _source.Furnitures)
{
result.Add(furniture.GetViewModel);
}
return result;
}
// Получение отфильтрованного списка изделий
public List<FurnitureViewModel> GetFilteredList(FurnitureSearchModel model)
{
var result = new List<FurnitureViewModel>();
if(string.IsNullOrEmpty(model.FurnitureName))
{
return result;
}
foreach(var furniture in _source.Furnitures)
{
if (furniture.FurnitureName.Contains(model.FurnitureName))
{
result.Add(furniture.GetViewModel);
}
}
return result;
}
// Получение элемента из списка изделий
public FurnitureViewModel? GetElement(FurnitureSearchModel model)
{
if (string.IsNullOrEmpty(model.FurnitureName) && !model.Id.HasValue)
{
return null;
}
foreach(var furniture in _source.Furnitures)
{
if((!string.IsNullOrEmpty(model.FurnitureName) && furniture.FurnitureName == model.FurnitureName) ||
(model.Id.HasValue && furniture.Id == model.Id))
{
return furniture.GetViewModel;
}
}
return null;
}
// При создании изделия определяем для него новый id: ищем max id и прибавлляем к нему 1
public FurnitureViewModel? Insert(FurnitureBindingModel model)
{
model.Id = 1;
foreach(var furniture in _source.Furnitures)
{
if(model.Id <= furniture.Id)
{
model.Id = furniture.Id + 1;
}
}
var newFurniture = Furniture.Create(model);
if(newFurniture == null)
{
return null;
}
_source.Furnitures.Add(newFurniture);
return newFurniture.GetViewModel;
}
// Обновление изделия
public FurnitureViewModel? Update(FurnitureBindingModel model)
{
foreach(var furniture in _source.Furnitures)
{
if(furniture.Id == model.Id)
{
furniture.Update(model);
return furniture.GetViewModel;
}
}
return null;
}
// Удаление изделия
public FurnitureViewModel? Delete(FurnitureBindingModel model)
{
for(int i = 0; i < _source.Furnitures.Count; ++i)
{
if (_source.Furnitures[i].Id == model.Id)
{
var element = _source.Furnitures[i];
_source.Furnitures.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
}
}

View File

@ -0,0 +1,163 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyListImplement.Implements
{
// Класс, реализующий интерфейс хранилища заказов
public class OrderStorage : IOrderStorage
{
// Поле для работы со списком заказов
private readonly DataListSingleton _source;
// Получение в конструкторе объекта DataListSingleton
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 && model.DateFrom.HasValue && model.DateTo.HasValue)
{
foreach (var order in _source.Orders)
{
if (order.DateCreate >= model.DateFrom && order.DateCreate <= model.DateTo)
{
result.Add(GetViewModel(order));
}
}
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;
}
// Метод для записи названия изделия на форме с заказами
private OrderViewModel GetViewModel(Order order)
{
var viewModel = order.GetViewModel;
foreach(var furniture in _source.Furnitures)
{
if (furniture.Id == order.FurnitureId)
{
viewModel.FurnitureName = furniture.FurnitureName;
break;
}
}
return viewModel;
}
// При создании заказа определяем для него новый id: ищем max id и прибавляем к нему 1
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;
}
}
}

View File

@ -0,0 +1,138 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyListImplement.Implements
{
// Класс, реализующий интерфейс хранилища заготовок
public class WorkPieceStorage : IWorkPieceStorage
{
// Поле для работы со списком заготовок
private readonly DataListSingleton _source;
// Получение в конструкторе объекта DataListSingleton
public WorkPieceStorage()
{
_source = DataListSingleton.GetInstance();
}
// Получение полного списка заготовок
public List<WorkPieceViewModel> GetFullList()
{
var result = new List<WorkPieceViewModel>();
foreach(var workPiece in _source.WorkPiece)
{
result.Add(workPiece.GetViewModel);
}
return result;
}
// Получение отфильтрованного списка заготовок
public List<WorkPieceViewModel> GetFilteredList(WorkPieceSearchModel model)
{
var result = new List<WorkPieceViewModel>();
if(string.IsNullOrEmpty(model.WorkPieceName))
{
return result;
}
foreach(var workPiece in _source.WorkPiece)
{
if (workPiece.WorkPieceName.Contains(model.WorkPieceName))
{
result.Add(workPiece.GetViewModel);
}
}
return result;
}
// Получение элемента из списка заготовок
public WorkPieceViewModel? GetElement(WorkPieceSearchModel model)
{
if(string.IsNullOrEmpty(model.WorkPieceName) && !model.Id.HasValue)
{
return null;
}
foreach(var workPiece in _source.WorkPiece)
{
if((!string.IsNullOrEmpty(model.WorkPieceName) && workPiece.WorkPieceName == model.WorkPieceName) ||
(model.Id.HasValue && workPiece.Id == model.Id))
{
return workPiece.GetViewModel;
}
}
return null;
}
// При создании заготовки определяем для него новый id: ищем max id и прибавляем к нему 1
public WorkPieceViewModel? Insert(WorkPieceBindingModel model)
{
model.Id = 1;
foreach(var workPiece in _source.WorkPiece)
{
if(model.Id <= workPiece.Id)
{
model.Id = workPiece.Id + 1;
}
}
var newWorkPiece = WorkPiece.Create(model);
if(newWorkPiece == null)
{
return null;
}
_source.WorkPiece.Add(newWorkPiece);
return newWorkPiece.GetViewModel;
}
// Обновление заготовки
public WorkPieceViewModel? Update(WorkPieceBindingModel model)
{
foreach(var workPiece in _source.WorkPiece)
{
if(workPiece.Id == model.Id)
{
workPiece.Update(model);
return workPiece.GetViewModel;
}
}
return null;
}
// Удаление заготовки
public WorkPieceViewModel? Delete(WorkPieceBindingModel model)
{
for(int i = 0; i < _source.WorkPiece.Count; i++)
{
if (_source.WorkPiece[i].Id == model.Id)
{
var element = _source.WorkPiece[i];
_source.WorkPiece.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
}
}

View File

@ -0,0 +1,63 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyListImplement.Models
{
// Класс реализующий интерфейс модели изделия
public class Furniture : IFurnitureModel
{
// Методы set делаем приватным, чтобы исключить неразрешённые манипуляции
public int Id { get; private set; }
public string FurnitureName { get; private set; } = string.Empty;
public double Price { get; private set; }
public Dictionary<int, (IWorkPieceModel, int)> FurnitureWorkPieces { get; private set; } = new Dictionary<int, (IWorkPieceModel, int)>();
// Метод для создания объекта от класса-компонента на основе класса-BindingModel
public static Furniture? Create(FurnitureBindingModel? model)
{
if(model == null)
{
return null;
}
return new Furniture()
{
Id = model.Id,
FurnitureName = model.FurnitureName,
Price = model.Price,
FurnitureWorkPieces = model.FurnitureWorkPieces
};
}
// Метод изменения существующего объекта
public void Update(FurnitureBindingModel? model)
{
if(model == null)
{
return;
}
FurnitureName = model.FurnitureName;
Price = model.Price;
FurnitureWorkPieces = model.FurnitureWorkPieces;
}
// Метод для создания объекта класса ViewModel на основе данных объекта класса-компонента
public FurnitureViewModel GetViewModel => new()
{
Id = Id,
FurnitureName = FurnitureName,
Price = Price,
FurnitureWorkPieces = FurnitureWorkPieces
};
}
}

View File

@ -0,0 +1,73 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Enums;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyListImplement.Models
{
// Класс, реализующий интерфейс модели заказа
public class Order : IOrderModel
{
// Методы set сделали приватными, чтобы исключить неразрешённые манипуляции
public int Id { get; private set; }
public int FurnitureId { get; private set; }
public int Count { get; private set; }
public double Sum { get; private set; }
public OrderStatus Status { get; private set; }
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,
FurnitureId = model.FurnitureId,
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;
}
// Метод для создания объекта класса ViewModel на основе данных объекта класса-компонента
public OrderViewModel GetViewModel => new()
{
Id = Id,
FurnitureId = FurnitureId,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement,
};
}
}

View File

@ -0,0 +1,58 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyListImplement.Models
{
// Реализация интерфейса модели заготовки
public class WorkPiece : IWorkPieceModel
{
// Методы set делаем приватным, чтобы исключить неразрешённые манипуляции
public int Id { get; private set; }
public string WorkPieceName { get; private set; } = string.Empty;
public double Cost { get; private set; }
// Метод для создания объекта от класса-компонента на основе класса-BindingModel
public static WorkPiece? Create(WorkPieceBindingModel? model)
{
if(model == null)
{
return null;
}
return new WorkPiece()
{
Id = model.Id,
WorkPieceName = model.WorkPieceName,
Cost = model.Cost
};
}
// Метод изменения существующего объекта
public void Update(WorkPieceBindingModel? model)
{
if(model == null)
{
return;
}
WorkPieceName = model.WorkPieceName;
Cost = model.Cost;
}
// Метод для создания объекта класса ViewModel на основе данных объекта класса-компонента
public WorkPieceViewModel GetViewModel => new()
{
Id = Id,
WorkPieceName = WorkPieceName,
Cost = Cost
};
}
}

View File

@ -1,39 +0,0 @@
namespace FurnitureAssembly
{
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 FurnitureAssembly
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,144 @@
namespace FurnitureAssemblyView
{
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()
{
this.labelFurniture = new System.Windows.Forms.Label();
this.labelCount = new System.Windows.Forms.Label();
this.labelSum = new System.Windows.Forms.Label();
this.comboBoxFurniture = new System.Windows.Forms.ComboBox();
this.textBoxCount = new System.Windows.Forms.TextBox();
this.textBoxSum = new System.Windows.Forms.TextBox();
this.buttonSave = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// labelFurniture
//
this.labelFurniture.AutoSize = true;
this.labelFurniture.Location = new System.Drawing.Point(24, 24);
this.labelFurniture.Name = "labelFurniture";
this.labelFurniture.Size = new System.Drawing.Size(71, 20);
this.labelFurniture.TabIndex = 0;
this.labelFurniture.Text = "Изделие:";
//
// labelCount
//
this.labelCount.AutoSize = true;
this.labelCount.Location = new System.Drawing.Point(24, 70);
this.labelCount.Name = "labelCount";
this.labelCount.Size = new System.Drawing.Size(93, 20);
this.labelCount.TabIndex = 1;
this.labelCount.Text = "Количество:";
//
// labelSum
//
this.labelSum.AutoSize = true;
this.labelSum.Location = new System.Drawing.Point(24, 113);
this.labelSum.Name = "labelSum";
this.labelSum.Size = new System.Drawing.Size(58, 20);
this.labelSum.TabIndex = 2;
this.labelSum.Text = "Сумма:";
//
// comboBoxFurniture
//
this.comboBoxFurniture.FormattingEnabled = true;
this.comboBoxFurniture.Location = new System.Drawing.Point(166, 21);
this.comboBoxFurniture.Name = "comboBoxFurniture";
this.comboBoxFurniture.Size = new System.Drawing.Size(278, 28);
this.comboBoxFurniture.TabIndex = 3;
this.comboBoxFurniture.SelectedIndexChanged += new System.EventHandler(this.ComboBoxFurniture_SelectedIndexChanged);
//
// textBoxCount
//
this.textBoxCount.Location = new System.Drawing.Point(166, 67);
this.textBoxCount.Name = "textBoxCount";
this.textBoxCount.Size = new System.Drawing.Size(278, 27);
this.textBoxCount.TabIndex = 4;
this.textBoxCount.TextChanged += new System.EventHandler(this.TextBoxCount_TextChanged);
//
// textBoxSum
//
this.textBoxSum.Location = new System.Drawing.Point(166, 110);
this.textBoxSum.Name = "textBoxSum";
this.textBoxSum.Size = new System.Drawing.Size(278, 27);
this.textBoxSum.TabIndex = 5;
//
// buttonSave
//
this.buttonSave.Location = new System.Drawing.Point(230, 155);
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(340, 155);
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);
//
// FormCreateOrder
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(479, 203);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonSave);
this.Controls.Add(this.textBoxSum);
this.Controls.Add(this.textBoxCount);
this.Controls.Add(this.comboBoxFurniture);
this.Controls.Add(this.labelSum);
this.Controls.Add(this.labelCount);
this.Controls.Add(this.labelFurniture);
this.Name = "FormCreateOrder";
this.Text = "Заказ";
this.Load += new System.EventHandler(this.FormCreateOrder_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Label labelFurniture;
private Label labelCount;
private Label labelSum;
private ComboBox comboBoxFurniture;
private TextBox textBoxCount;
private TextBox textBoxSum;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,146 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyDataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FurnitureAssemblyView
{
public partial class FormCreateOrder : Form
{
private readonly ILogger _logger;
private readonly IFurnitureLogic _logicM;
private readonly IOrderLogic _logicO;
public FormCreateOrder(ILogger<FormCreateOrder> logger, IFurnitureLogic logicM, IOrderLogic logicO)
{
InitializeComponent();
_logger = logger;
_logicM = logicM;
_logicO = logicO;
}
private void FormCreateOrder_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка изделий для заказа");
try
{
var list = _logicM.ReadList(null);
if (list != null)
{
comboBoxFurniture.DisplayMember = "FurnitureName";
comboBoxFurniture.ValueMember = "Id";
comboBoxFurniture.DataSource = list;
comboBoxFurniture.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки изделий для заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void CalcSum()
{
if (comboBoxFurniture.SelectedValue != null && !string.IsNullOrEmpty(textBoxCount.Text))
{
try
{
int id = Convert.ToInt32(comboBoxFurniture.SelectedValue);
var furniture = _logicM.ReadElement(new FurnitureSearchModel
{
Id = id
});
int count = Convert.ToInt32(textBoxCount.Text);
textBoxSum.Text = Math.Round(count * (furniture?.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 ComboBoxFurniture_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 (comboBoxFurniture.SelectedValue == null)
{
MessageBox.Show("Выберите изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Создание заказа");
try
{
var operationResult = _logicO.CreateOrder(new OrderBindingModel
{
FurnitureId = Convert.ToInt32(comboBoxFurniture.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,60 @@
<root>
<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,232 @@
namespace FurnitureAssemblyView
{
partial class FormFurniture
{
/// <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.labelName = new System.Windows.Forms.Label();
this.labelCost = new System.Windows.Forms.Label();
this.textBoxName = new System.Windows.Forms.TextBox();
this.textBoxPrice = new System.Windows.Forms.TextBox();
this.groupBoxWorkPiece = new System.Windows.Forms.GroupBox();
this.buttonRefresh = new System.Windows.Forms.Button();
this.buttonDelete = new System.Windows.Forms.Button();
this.buttonUpdate = new System.Windows.Forms.Button();
this.buttonAdd = new System.Windows.Forms.Button();
this.dataGridView = new System.Windows.Forms.DataGridView();
this.buttonSave = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
this.ColumnID = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.ColumnName = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.ColumnPrice = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.groupBoxWorkPiece.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
this.SuspendLayout();
//
// labelName
//
this.labelName.AutoSize = true;
this.labelName.Location = new System.Drawing.Point(23, 30);
this.labelName.Name = "labelName";
this.labelName.Size = new System.Drawing.Size(80, 20);
this.labelName.TabIndex = 0;
this.labelName.Text = "Название:";
//
// labelCost
//
this.labelCost.AutoSize = true;
this.labelCost.Location = new System.Drawing.Point(23, 84);
this.labelCost.Name = "labelCost";
this.labelCost.Size = new System.Drawing.Size(86, 20);
this.labelCost.TabIndex = 1;
this.labelCost.Text = "Стоимость:";
//
// textBoxName
//
this.textBoxName.Location = new System.Drawing.Point(133, 27);
this.textBoxName.Name = "textBoxName";
this.textBoxName.Size = new System.Drawing.Size(332, 27);
this.textBoxName.TabIndex = 2;
//
// textBoxPrice
//
this.textBoxPrice.Location = new System.Drawing.Point(133, 81);
this.textBoxPrice.Name = "textBoxPrice";
this.textBoxPrice.Size = new System.Drawing.Size(196, 27);
this.textBoxPrice.TabIndex = 3;
//
// groupBoxWorkPiece
//
this.groupBoxWorkPiece.Controls.Add(this.buttonRefresh);
this.groupBoxWorkPiece.Controls.Add(this.buttonDelete);
this.groupBoxWorkPiece.Controls.Add(this.buttonUpdate);
this.groupBoxWorkPiece.Controls.Add(this.buttonAdd);
this.groupBoxWorkPiece.Controls.Add(this.dataGridView);
this.groupBoxWorkPiece.Location = new System.Drawing.Point(23, 126);
this.groupBoxWorkPiece.Name = "groupBoxWorkPiece";
this.groupBoxWorkPiece.Size = new System.Drawing.Size(567, 300);
this.groupBoxWorkPiece.TabIndex = 4;
this.groupBoxWorkPiece.TabStop = false;
this.groupBoxWorkPiece.Text = "Заготовки";
//
// buttonRefresh
//
this.buttonRefresh.Location = new System.Drawing.Point(454, 196);
this.buttonRefresh.Name = "buttonRefresh";
this.buttonRefresh.Size = new System.Drawing.Size(94, 29);
this.buttonRefresh.TabIndex = 4;
this.buttonRefresh.Text = "Обновить";
this.buttonRefresh.UseVisualStyleBackColor = true;
this.buttonRefresh.Click += new System.EventHandler(this.ButtonRefresh_Click);
//
// buttonDelete
//
this.buttonDelete.Location = new System.Drawing.Point(454, 145);
this.buttonDelete.Name = "buttonDelete";
this.buttonDelete.Size = new System.Drawing.Size(94, 29);
this.buttonDelete.TabIndex = 3;
this.buttonDelete.Text = "Удалить";
this.buttonDelete.UseVisualStyleBackColor = true;
this.buttonDelete.Click += new System.EventHandler(this.ButtonDelete_Click);
//
// buttonUpdate
//
this.buttonUpdate.Location = new System.Drawing.Point(454, 95);
this.buttonUpdate.Name = "buttonUpdate";
this.buttonUpdate.Size = new System.Drawing.Size(94, 29);
this.buttonUpdate.TabIndex = 2;
this.buttonUpdate.Text = "Изменить";
this.buttonUpdate.UseVisualStyleBackColor = true;
this.buttonUpdate.Click += new System.EventHandler(this.ButtonUpdate_Click);
//
// buttonAdd
//
this.buttonAdd.Location = new System.Drawing.Point(454, 43);
this.buttonAdd.Name = "buttonAdd";
this.buttonAdd.Size = new System.Drawing.Size(94, 29);
this.buttonAdd.TabIndex = 1;
this.buttonAdd.Text = "Добавить";
this.buttonAdd.UseVisualStyleBackColor = true;
this.buttonAdd.Click += new System.EventHandler(this.ButtonAdd_Click);
//
// dataGridView
//
this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.ColumnID,
this.ColumnName,
this.ColumnPrice});
this.dataGridView.Location = new System.Drawing.Point(6, 26);
this.dataGridView.Name = "dataGridView";
this.dataGridView.RowHeadersWidth = 51;
this.dataGridView.RowTemplate.Height = 29;
this.dataGridView.Size = new System.Drawing.Size(436, 268);
this.dataGridView.TabIndex = 0;
//
// buttonSave
//
this.buttonSave.Location = new System.Drawing.Point(340, 448);
this.buttonSave.Name = "buttonSave";
this.buttonSave.Size = new System.Drawing.Size(95, 29);
this.buttonSave.TabIndex = 5;
this.buttonSave.Text = "Сохранить";
this.buttonSave.UseVisualStyleBackColor = true;
this.buttonSave.Click += new System.EventHandler(this.ButtonSave_Click);
//
// buttonCancel
//
this.buttonCancel.Location = new System.Drawing.Point(458, 448);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(94, 29);
this.buttonCancel.TabIndex = 6;
this.buttonCancel.Text = "Отмена";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
//
// ColumnID
//
this.ColumnID.HeaderText = "Id";
this.ColumnID.MinimumWidth = 6;
this.ColumnID.Name = "ColumnID";
this.ColumnID.Visible = false;
this.ColumnID.Width = 125;
//
// ColumnName
//
this.ColumnName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.ColumnName.HeaderText = "Название";
this.ColumnName.MinimumWidth = 6;
this.ColumnName.Name = "ColumnName";
//
// ColumnPrice
//
this.ColumnPrice.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.ColumnPrice.HeaderText = "Количество";
this.ColumnPrice.MinimumWidth = 6;
this.ColumnPrice.Name = "ColumnPrice";
//
// FormFurniture
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(619, 500);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonSave);
this.Controls.Add(this.groupBoxWorkPiece);
this.Controls.Add(this.textBoxPrice);
this.Controls.Add(this.textBoxName);
this.Controls.Add(this.labelCost);
this.Controls.Add(this.labelName);
this.Name = "FormFurniture";
this.Text = "Изделие";
this.Load += new System.EventHandler(this.FormFurniture_Load);
this.groupBoxWorkPiece.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Label labelName;
private Label labelCost;
private TextBox textBoxName;
private TextBox textBoxPrice;
private GroupBox groupBoxWorkPiece;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonAdd;
private DataGridView dataGridView;
private Button buttonSave;
private Button buttonCancel;
private DataGridViewTextBoxColumn ColumnID;
private DataGridViewTextBoxColumn ColumnName;
private DataGridViewTextBoxColumn ColumnPrice;
}
}

View File

@ -0,0 +1,246 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyDataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FurnitureAssemblyView
{
public partial class FormFurniture : Form
{
private readonly ILogger _logger;
private readonly IFurnitureLogic _logic;
private int? _id;
private Dictionary<int, (IWorkPieceModel, int)> _furnitureWorkPieces;
public int Id { set { _id = value; } }
public FormFurniture(ILogger<FormFurniture> logger, IFurnitureLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
_furnitureWorkPieces = new Dictionary<int, (IWorkPieceModel, int)>();
}
private void FormFurniture_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
_logger.LogInformation("Загрузка изделия");
try
{
var view = _logic.ReadElement(new FurnitureSearchModel { Id = _id.Value });
if(view != null)
{
textBoxName.Text = view.FurnitureName;
textBoxPrice.Text = view.Price.ToString();
_furnitureWorkPieces = view.FurnitureWorkPieces ?? new Dictionary<int, (IWorkPieceModel, int)>();
LoadData();
}
}
catch(Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки изделия");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LoadData()
{
_logger.LogInformation("Загрузка заготовок для изделия");
try
{
if(_furnitureWorkPieces != null)
{
dataGridView.Rows.Clear();
foreach(var awp in _furnitureWorkPieces)
{
dataGridView.Rows.Add(new object[] { awp.Key, awp.Value.Item1.WorkPieceName, awp.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(FormFurnitureWorkPiece));
if (service is FormFurnitureWorkPiece form)
{
if (form.ShowDialog() == DialogResult.OK)
{
if (form.WorkPieceModel == null)
{
return;
}
_logger.LogInformation("Добавление новой заготовки:{WorkPieceName} - {Count}", form.WorkPieceModel.WorkPieceName, form.Count);
if (_furnitureWorkPieces.ContainsKey(form.Id))
{
_furnitureWorkPieces[form.Id] = (form.WorkPieceModel, form.Count);
}
else
{
_furnitureWorkPieces.Add(form.Id, (form.WorkPieceModel, form.Count));
}
LoadData();
}
}
}
private void ButtonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormFurnitureWorkPiece));
if (service is FormFurnitureWorkPiece form)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
form.Id = id;
form.Count = _furnitureWorkPieces[id].Item2;
if (form.ShowDialog() == DialogResult.OK)
{
if (form.WorkPieceModel == null)
{
return;
}
_logger.LogInformation("Изменение компонента:{WorkPieceName} - {Count}", form.WorkPieceModel.WorkPieceName, form.Count);
_furnitureWorkPieces[form.Id] = (form.WorkPieceModel, form.Count);
LoadData();
}
}
}
}
private void ButtonDelete_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
_logger.LogInformation("Удаление заготовки:{WorkPieceName} - {Count}", dataGridView.SelectedRows[0].Cells[1].Value);
_furnitureWorkPieces?.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
}
}
private void ButtonRefresh_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 (_furnitureWorkPieces == null || _furnitureWorkPieces.Count == 0)
{
MessageBox.Show("Заполните компоненты", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение изделия");
try
{
var model = new FurnitureBindingModel
{
Id = _id ?? 0,
FurnitureName = textBoxName.Text,
Price = Convert.ToDouble(textBoxPrice.Text),
FurnitureWorkPieces = _furnitureWorkPieces
};
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();
}
// В конце умножить на 1.1, так как прибавляем к итоговой стоимости некоторый процент (в данном случае 10%)
private double CalcPrice()
{
double price = 0;
foreach (var elem in _furnitureWorkPieces)
{
price += ((elem.Value.Item1?.Cost ?? 0) * elem.Value.Item2);
}
return Math.Round(price * 1.1, 2);
}
}
}

View File

@ -0,0 +1,69 @@
<root>
<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="ColumnID.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnPrice.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 FurnitureAssemblyView
{
partial class FormFurnitureWorkPiece
{
/// <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()
{
labelWorkPiece = new Label();
labelCount = new Label();
comboBoxWorkPiece = new ComboBox();
textBoxCount = new TextBox();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// labelWorkPiece
//
labelWorkPiece.AutoSize = true;
labelWorkPiece.Location = new Point(31, 33);
labelWorkPiece.Name = "labelWorkPiece";
labelWorkPiece.Size = new Size(81, 20);
labelWorkPiece.TabIndex = 0;
labelWorkPiece.Text = "Заготовка:";
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(31, 79);
labelCount.Name = "labelCount";
labelCount.Size = new Size(93, 20);
labelCount.TabIndex = 1;
labelCount.Text = "Количество:";
//
// comboBoxWorkPiece
//
comboBoxWorkPiece.FormattingEnabled = true;
comboBoxWorkPiece.Location = new Point(156, 30);
comboBoxWorkPiece.Name = "comboBoxWorkPiece";
comboBoxWorkPiece.Size = new Size(320, 28);
comboBoxWorkPiece.TabIndex = 2;
//
// textBoxCount
//
textBoxCount.Location = new Point(156, 76);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(320, 27);
textBoxCount.TabIndex = 3;
//
// buttonSave
//
buttonSave.Location = new Point(236, 118);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(110, 38);
buttonSave.TabIndex = 4;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(363, 118);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(113, 38);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormFurnitureWorkPiece
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(526, 168);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxCount);
Controls.Add(comboBoxWorkPiece);
Controls.Add(labelCount);
Controls.Add(labelWorkPiece);
Name = "FormFurnitureWorkPiece";
Text = "Заготовки для изделия";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelWorkPiece;
private Label labelCount;
private ComboBox comboBoxWorkPiece;
private TextBox textBoxCount;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,98 @@
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FurnitureAssemblyView
{
public partial class FormFurnitureWorkPiece : Form
{
private readonly List<WorkPieceViewModel>? _list;
public int Id
{
get { return Convert.ToInt32(comboBoxWorkPiece.SelectedValue); }
set { comboBoxWorkPiece.SelectedValue = value; }
}
public IWorkPieceModel? WorkPieceModel
{
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 FormFurnitureWorkPiece(IWorkPieceLogic logic)
{
InitializeComponent();
_list = logic.ReadList(null);
if (_list != null)
{
comboBoxWorkPiece.DisplayMember = "WorkPieceName";
comboBoxWorkPiece.ValueMember = "Id";
comboBoxWorkPiece.DataSource = _list;
comboBoxWorkPiece.SelectedItem = null;
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxCount.Text))
{
MessageBox.Show("Заполните поле Количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxWorkPiece.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

@ -1,17 +1,17 @@
<?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
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>
@ -26,36 +26,36 @@
<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
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
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
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
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
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
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
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->

View File

@ -0,0 +1,114 @@
namespace FurnitureAssemblyView
{
partial class FormFurnitures
{
/// <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()
{
buttonAdd = new Button();
buttonUpdate = new Button();
buttonDelete = new Button();
buttonRefresh = new Button();
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// buttonAdd
//
buttonAdd.Location = new Point(640, 35);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(116, 50);
buttonAdd.TabIndex = 0;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(640, 105);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(116, 50);
buttonUpdate.TabIndex = 1;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += ButtonUpdate_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(640, 175);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(116, 50);
buttonDelete.TabIndex = 2;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += ButtonDelete_Click;
//
// buttonRef
//
buttonRefresh.Location = new Point(640, 245);
buttonRefresh.Name = "buttonRef";
buttonRefresh.Size = new Size(116, 50);
buttonRefresh.TabIndex = 3;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRefresh_Click;
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(12, 12);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(604, 426);
dataGridView.TabIndex = 4;
//
// FormFurnitures
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(781, 450);
Controls.Add(dataGridView);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonAdd);
Name = "FormFurnitures";
Text = "Изделия";
Load += FormFurnitures_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private Button buttonAdd;
private Button buttonUpdate;
private Button buttonDelete;
private Button buttonRefresh;
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,126 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FurnitureAssemblyView
{
public partial class FormFurnitures : Form
{
private readonly ILogger _logger;
private readonly IFurnitureLogic _logic;
public FormFurnitures(ILogger<FormFurnitures> logger, IFurnitureLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormFurnitures_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["FurnitureWorkPieces"].Visible = false;
dataGridView.Columns["FurnitureName"].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(FormFurniture));
if (service is FormFurniture form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void ButtonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormFurniture));
if (service is FormFurniture form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void ButtonDelete_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление изделия");
try
{
if (!_logic.Delete(new FurnitureBindingModel
{
Id = id
}))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления компонента");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void ButtonRefresh_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,216 @@
namespace FurnitureAssemblyView
{
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()
{
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonTakeOrderInWork = new Button();
buttonOrderReady = new Button();
buttonIssuedOrder = new Button();
buttonRefresh = new Button();
menuStrip = new MenuStrip();
toolStripMenuItem = new ToolStripMenuItem();
workPieceToolStripMenuItem = new ToolStripMenuItem();
furnitureToolStripMenuItem = new ToolStripMenuItem();
reportsToolStripMenuItem = new ToolStripMenuItem();
workPiecesToolStripMenuItem = new ToolStripMenuItem();
workPieceFurnituresToolStripMenuItem = new ToolStripMenuItem();
ordersToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
menuStrip.SuspendLayout();
SuspendLayout();
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(10, 27);
dataGridView.Margin = new Padding(3, 2, 3, 2);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(820, 302);
dataGridView.TabIndex = 0;
//
// buttonCreateOrder
//
buttonCreateOrder.Location = new Point(887, 50);
buttonCreateOrder.Margin = new Padding(3, 2, 3, 2);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(206, 34);
buttonCreateOrder.TabIndex = 1;
buttonCreateOrder.Text = "Создать заказ";
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += ButtonCreateOrder_Click;
//
// buttonTakeOrderInWork
//
buttonTakeOrderInWork.Location = new Point(887, 107);
buttonTakeOrderInWork.Margin = new Padding(3, 2, 3, 2);
buttonTakeOrderInWork.Name = "buttonTakeOrderInWork";
buttonTakeOrderInWork.Size = new Size(206, 36);
buttonTakeOrderInWork.TabIndex = 2;
buttonTakeOrderInWork.Text = "Отдать на выполнение";
buttonTakeOrderInWork.UseVisualStyleBackColor = true;
buttonTakeOrderInWork.Click += ButtonTakeOrderInWork_Click;
//
// buttonOrderReady
//
buttonOrderReady.Location = new Point(887, 165);
buttonOrderReady.Margin = new Padding(3, 2, 3, 2);
buttonOrderReady.Name = "buttonOrderReady";
buttonOrderReady.Size = new Size(206, 31);
buttonOrderReady.TabIndex = 3;
buttonOrderReady.Text = "Заказ готов";
buttonOrderReady.UseVisualStyleBackColor = true;
buttonOrderReady.Click += ButtonOrderReady_Click;
//
// buttonIssuedOrder
//
buttonIssuedOrder.Location = new Point(887, 217);
buttonIssuedOrder.Margin = new Padding(3, 2, 3, 2);
buttonIssuedOrder.Name = "buttonIssuedOrder";
buttonIssuedOrder.Size = new Size(206, 33);
buttonIssuedOrder.TabIndex = 4;
buttonIssuedOrder.Text = "Заказ выдан";
buttonIssuedOrder.UseVisualStyleBackColor = true;
buttonIssuedOrder.Click += ButtonIssuedOrder_Click;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(887, 269);
buttonRefresh.Margin = new Padding(3, 2, 3, 2);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(206, 29);
buttonRefresh.TabIndex = 5;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRef_Click;
//
// menuStrip
//
menuStrip.ImageScalingSize = new Size(20, 20);
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem, reportsToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Padding = new Padding(5, 2, 0, 2);
menuStrip.Size = new Size(1135, 24);
menuStrip.TabIndex = 6;
menuStrip.Text = "menuStrip";
//
// toolStripMenuItem
//
toolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { workPieceToolStripMenuItem, furnitureToolStripMenuItem });
toolStripMenuItem.Name = "toolStripMenuItem";
toolStripMenuItem.Size = new Size(94, 20);
toolStripMenuItem.Text = "Справочники";
//
// workPieceToolStripMenuItem
//
workPieceToolStripMenuItem.Name = "workPieceToolStripMenuItem";
workPieceToolStripMenuItem.Size = new Size(130, 22);
workPieceToolStripMenuItem.Text = "Заготовки";
workPieceToolStripMenuItem.Click += WorkPieceToolStripMenuItem_Click;
//
// furnitureToolStripMenuItem
//
furnitureToolStripMenuItem.Name = "furnitureToolStripMenuItem";
furnitureToolStripMenuItem.Size = new Size(130, 22);
furnitureToolStripMenuItem.Text = "Изделия";
furnitureToolStripMenuItem.Click += FurnitureToolStripMenuItem_Click;
//
// reportsToolStripMenuItem
//
reportsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { workPiecesToolStripMenuItem, workPieceFurnituresToolStripMenuItem, ordersToolStripMenuItem });
reportsToolStripMenuItem.Name = "reportsToolStripMenuItem";
reportsToolStripMenuItem.Size = new Size(60, 20);
reportsToolStripMenuItem.Text = "Отчёты";
//
// workPiecesToolStripMenuItem
//
workPiecesToolStripMenuItem.Name = "workPiecesToolStripMenuItem";
workPiecesToolStripMenuItem.Size = new Size(203, 22);
workPiecesToolStripMenuItem.Text = "Список заготовок";
workPiecesToolStripMenuItem.Click += WorkPiecesToolStripMenuItem_Click;
//
// workPieceFurnituresToolStripMenuItem
//
workPieceFurnituresToolStripMenuItem.Name = "workPieceFurnituresToolStripMenuItem";
workPieceFurnituresToolStripMenuItem.Size = new Size(203, 22);
workPieceFurnituresToolStripMenuItem.Text = "Заготовки по изделиям";
workPieceFurnituresToolStripMenuItem.Click += WorkPieceFurnituresToolStripMenuItem_Click;
//
// ordersToolStripMenuItem
//
ordersToolStripMenuItem.Name = "ordersToolStripMenuItem";
ordersToolStripMenuItem.Size = new Size(203, 22);
ordersToolStripMenuItem.Text = "Список заказов";
ordersToolStripMenuItem.Click += OrdersToolStripMenuItem_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1135, 338);
Controls.Add(buttonRefresh);
Controls.Add(buttonIssuedOrder);
Controls.Add(buttonOrderReady);
Controls.Add(buttonTakeOrderInWork);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Margin = new Padding(3, 2, 3, 2);
Name = "FormMain";
Text = "Сборка мебели";
Load += FormMain_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private DataGridView dataGridView;
private Button buttonCreateOrder;
private Button buttonTakeOrderInWork;
private Button buttonOrderReady;
private Button buttonIssuedOrder;
private Button buttonRefresh;
private MenuStrip menuStrip;
private ToolStripMenuItem toolStripMenuItem;
private ToolStripMenuItem workPieceToolStripMenuItem;
private ToolStripMenuItem furnitureToolStripMenuItem;
private ToolStripMenuItem reportsToolStripMenuItem;
private ToolStripMenuItem workPiecesToolStripMenuItem;
private ToolStripMenuItem workPieceFurnituresToolStripMenuItem;
private ToolStripMenuItem ordersToolStripMenuItem;
}
}

View File

@ -0,0 +1,224 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using FurnitureAssemblyDataModels.Enums;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FurnitureAssemblyView
{
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
_logger.LogInformation("Загрузка заказов");
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["FurnitureId"].Visible = false;
dataGridView.Columns["FurnitureName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void WorkPieceToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormWorkPieces));
if (service is FormWorkPieces form)
{
form.ShowDialog();
}
}
private void FurnitureToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormFurnitures));
if (service is FormFurnitures 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("Заказ №{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("Заказ №{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("Заказ №{id}. Меняется статус на 'Выдан'", id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = id
});
if (!operationResult)
{
throw new Exception("Заказ не в статусе готовности. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ №{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void WorkPiecesToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SaveFurnituresToWordFile(new ReportBindingModel
{
FileName = dialog.FileName
});
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void WorkPieceFurnituresToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportFurnitureWorkPieces));
if (service is FormReportFurnitureWorkPieces form)
{
form.ShowDialog();
}
}
private void OrdersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

@ -0,0 +1,123 @@
<?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="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,108 @@
namespace FurnitureAssemblyView
{
partial class FormReportFurnitureWorkPieces
{
/// <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.buttonSaveToExcel = new System.Windows.Forms.Button();
this.dataGridView = new System.Windows.Forms.DataGridView();
this.ColumWorkPiece = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.ColumnFurniture = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.ColumnCount = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
this.SuspendLayout();
//
// buttonSaveToExcel
//
this.buttonSaveToExcel.Location = new System.Drawing.Point(33, 25);
this.buttonSaveToExcel.Name = "buttonSaveToExcel";
this.buttonSaveToExcel.Size = new System.Drawing.Size(256, 29);
this.buttonSaveToExcel.TabIndex = 0;
this.buttonSaveToExcel.Text = "Сохранить в Excel";
this.buttonSaveToExcel.UseVisualStyleBackColor = true;
this.buttonSaveToExcel.Click += new System.EventHandler(this.ButtonSaveToExcel_Click);
//
// dataGridView
//
this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.ColumWorkPiece,
this.ColumnFurniture,
this.ColumnCount});
this.dataGridView.Dock = System.Windows.Forms.DockStyle.Bottom;
this.dataGridView.Location = new System.Drawing.Point(0, 73);
this.dataGridView.Name = "dataGridView";
this.dataGridView.RowHeadersWidth = 51;
this.dataGridView.RowTemplate.Height = 29;
this.dataGridView.Size = new System.Drawing.Size(800, 395);
this.dataGridView.TabIndex = 1;
//
// ColumWorkPiece
//
this.ColumWorkPiece.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.ColumWorkPiece.HeaderText = "Заготовка";
this.ColumWorkPiece.MinimumWidth = 6;
this.ColumWorkPiece.Name = "ColumWorkPiece";
//
// ColumnFurniture
//
this.ColumnFurniture.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.ColumnFurniture.HeaderText = "Изделие";
this.ColumnFurniture.MinimumWidth = 6;
this.ColumnFurniture.Name = "ColumnFurniture";
//
// ColumnCount
//
this.ColumnCount.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.ColumnCount.HeaderText = "Количество";
this.ColumnCount.MinimumWidth = 6;
this.ColumnCount.Name = "ColumnCount";
//
// FormReportFurnitureWorkPieces
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 468);
this.Controls.Add(this.dataGridView);
this.Controls.Add(this.buttonSaveToExcel);
this.Name = "FormReportFurnitureWorkPieces";
this.Text = "Заготовки по изделиям";
this.Load += new System.EventHandler(this.FormReportFurnitureWorkPieces_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
this.ResumeLayout(false);
}
#endregion
private Button buttonSaveToExcel;
private DataGridView dataGridView;
private DataGridViewTextBoxColumn ColumWorkPiece;
private DataGridViewTextBoxColumn ColumnFurniture;
private DataGridViewTextBoxColumn ColumnCount;
}
}

View File

@ -0,0 +1,94 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FurnitureAssemblyView
{
public partial class FormReportFurnitureWorkPieces : Form
{
private readonly ILogger _logger;
private readonly IReportLogic _logic;
public FormReportFurnitureWorkPieces(ILogger<FormReportFurnitureWorkPieces> logger, IReportLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormReportFurnitureWorkPieces_Load(object sender, EventArgs e)
{
try
{
var dict = _logic.GetFurnitureWorkPiece();
if (dict != null)
{
dataGridView.Rows.Clear();
foreach (var elem in dict)
{
dataGridView.Rows.Add(new object[] { elem.FurnitureName, "", "" });
foreach (var listElem in elem.WorkPieces)
{
dataGridView.Rows.Add(new object[] { "", listElem.Item1, listElem.Item2 });
}
dataGridView.Rows.Add(new object[] { "Итого", "", elem.TotalCount });
dataGridView.Rows.Add(Array.Empty<object>());
}
}
_logger.LogInformation("Загрузка списка изделий по заготовкам");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка изделий по заготовкам");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonSaveToExcel_Click(object sender, EventArgs e)
{
// Фильтрация файлов для диалогового окна
using var dialog = new SaveFileDialog
{
Filter = "xlsx|*.xlsx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
_logic.SaveFurnitureWorkPieceToExcelFile(new ReportBindingModel
{
FileName = dialog.FileName
});
_logger.LogInformation("Сохранение списка изделий по заготовкам");
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения списка изделий по заготовкам");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}

View File

@ -0,0 +1,130 @@
<?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>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="ColumWorkPiece.UserAddedColumn" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="ColumnFurniture.UserAddedColumn" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="ColumnCount.UserAddedColumn" type="System.Boolean, mscorlib">
<value>True</value>
</data>
</root>

View File

@ -0,0 +1,131 @@
namespace FurnitureAssemblyView
{
partial class FormReportOrders
{
/// <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()
{
panel = new Panel();
buttonToPdf = new Button();
buttonMake = new Button();
label2 = new Label();
label1 = new Label();
dateTimePickerTo = new DateTimePicker();
dateTimePickerFrom = new DateTimePicker();
panel.SuspendLayout();
SuspendLayout();
//
// panel
//
panel.Controls.Add(buttonToPdf);
panel.Controls.Add(buttonMake);
panel.Controls.Add(label2);
panel.Controls.Add(label1);
panel.Controls.Add(dateTimePickerTo);
panel.Controls.Add(dateTimePickerFrom);
panel.Dock = DockStyle.Top;
panel.Location = new Point(0, 0);
panel.Name = "panel";
panel.Size = new Size(1112, 51);
panel.TabIndex = 0;
//
// buttonToPdf
//
buttonToPdf.Location = new Point(894, 10);
buttonToPdf.Name = "buttonToPdf";
buttonToPdf.Size = new Size(157, 29);
buttonToPdf.TabIndex = 5;
buttonToPdf.Text = "В Pdf";
buttonToPdf.UseVisualStyleBackColor = true;
buttonToPdf.Click += ButtonToPdf_Click;
//
// buttonMake
//
buttonMake.Location = new Point(612, 10);
buttonMake.Name = "buttonMake";
buttonMake.Size = new Size(157, 29);
buttonMake.TabIndex = 4;
buttonMake.Text = "Сформировать";
buttonMake.UseVisualStyleBackColor = true;
buttonMake.Click += ButtonMake_Click;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(263, 17);
label2.Name = "label2";
label2.Size = new Size(27, 20);
label2.TabIndex = 3;
label2.Text = "по";
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(25, 17);
label1.Name = "label1";
label1.Size = new Size(18, 20);
label1.TabIndex = 2;
label1.Text = "С";
//
// dateTimePickerTo
//
dateTimePickerTo.Location = new Point(313, 12);
dateTimePickerTo.Name = "dateTimePickerTo";
dateTimePickerTo.Size = new Size(169, 27);
dateTimePickerTo.TabIndex = 1;
//
// dateTimePickerFrom
//
dateTimePickerFrom.Location = new Point(65, 12);
dateTimePickerFrom.Name = "dateTimePickerFrom";
dateTimePickerFrom.Size = new Size(176, 27);
dateTimePickerFrom.TabIndex = 0;
//
// FormReportOrders
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1112, 450);
Controls.Add(panel);
Name = "FormReportOrders";
Text = "Заказы";
Load += FormReportOrders_Load;
panel.ResumeLayout(false);
panel.PerformLayout();
ResumeLayout(false);
}
#endregion
private Panel panel;
private Button buttonMake;
private Label label2;
private Label label1;
private DateTimePicker dateTimePickerTo;
private DateTimePicker dateTimePickerFrom;
private Button buttonToPdf;
}
}

View File

@ -0,0 +1,127 @@
using FurnitureAssemblyContracts.BindingModels;
using FurnitureAssemblyContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FurnitureAssemblyView
{
// Форма с отчётом
public partial class FormReportOrders : Form
{
private readonly ReportViewer reportViewer;
private readonly ILogger _logger;
private readonly IReportLogic _logic;
public FormReportOrders(ILogger<FormReportOrders> logger, IReportLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
reportViewer = new ReportViewer
{
Dock = DockStyle.Fill
};
reportViewer.LocalReport.LoadReportDefinition(new FileStream("ReportOrders.rdlc", FileMode.Open));
Controls.Clear();
Controls.Add(reportViewer);
Controls.Add(panel);
}
private void ButtonMake_Click(object sender, EventArgs e)
{
if (dateTimePickerFrom.Value.Date >= dateTimePickerTo.Value.Date)
{
MessageBox.Show("Дата начала должна быть меньше даты окончания", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
var dataSource = _logic.GetOrders(new ReportBindingModel
{
DateFrom = dateTimePickerFrom.Value,
DateTo = dateTimePickerTo.Value
});
var source = new ReportDataSource("DataSetOrders", dataSource);
reportViewer.LocalReport.DataSources.Clear();
reportViewer.LocalReport.DataSources.Add(source);
var parameters = new[] { new ReportParameter("ReportParameterPeriod",
$"c {dateTimePickerFrom.Value.ToShortDateString()} по {dateTimePickerTo.Value.ToShortDateString()}") };
reportViewer.LocalReport.SetParameters(parameters);
reportViewer.RefreshReport();
_logger.LogInformation("Загрузка списка заказов на период {From}-{To}", dateTimePickerFrom.Value.ToShortDateString(),
dateTimePickerTo.Value.ToShortDateString());
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка заказов на период");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonToPdf_Click(object sender, EventArgs e)
{
if (dateTimePickerFrom.Value.Date >= dateTimePickerTo.Value.Date)
{
MessageBox.Show("Дата начала должна быть меньше даты окончания", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using var dialog = new SaveFileDialog
{
Filter = "pdf|*.pdf"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
_logic.SaveOrdersToPdfFile(new ReportBindingModel
{
FileName = dialog.FileName,
DateFrom = dateTimePickerFrom.Value,
DateTo = dateTimePickerTo.Value
});
_logger.LogInformation("Сохранение списка заказов на период {From}-{To}",
dateTimePickerFrom.Value.ToShortDateString(), dateTimePickerTo.Value.ToShortDateString());
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения списка заказов на период");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void FormReportOrders_Load(object sender, EventArgs e)
{
}
}
}

Some files were not shown because too many files have changed in this diff Show More