Почти доделал

This commit is contained in:
2025-05-27 17:31:03 +04:00
parent da946e07ce
commit 491df32c85
279 changed files with 172737 additions and 1121 deletions

View File

@@ -7,6 +7,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ClosedXML" Version="0.105.0" />
<PackageReference Include="itext" Version="9.2.0" />
<PackageReference Include="itext7.bouncy-castle-adapter" Version="9.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.4" />
</ItemGroup>

View File

@@ -1,163 +0,0 @@
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComputerStoreBusinessLogic.Implementations;
public class AssemblyBusinessLogicContract : IAssemblyBusinessLogicContract
{
private readonly ILogger<AssemblyBusinessLogicContract> _logger;
private readonly IAssemblyStorageContract _assemblyStorage;
public AssemblyBusinessLogicContract(ILogger<AssemblyBusinessLogicContract> logger, IAssemblyStorageContract assemblyStorage)
{
_logger = logger;
_assemblyStorage = assemblyStorage;
}
public List<AssemblyViewModel>? ReadList(AssemblyBindingModel? model)
{
_logger.LogInformation("ReadList for assembly. UserID: {UserID}", model?.UserID);
List<AssemblyViewModel> list;
try
{
list = model == null ? _assemblyStorage.GetFullList() : _assemblyStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("GetFullList/GetFilteredList returned null. Returning empty list instead.");
list = new List<AssemblyViewModel>();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving assembly list from storage.");
return new List<AssemblyViewModel>();
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public AssemblyViewModel? ReadElement(AssemblyBindingModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement for assembly: {Id}, UserID: {UserID}", model.Id, model.UserID);
try
{
var element = _assemblyStorage.GetElement(model);
_logger.LogInformation("ReadElement found: {Id}", element.Id);
return element;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "ReadElement: Assembly not found for ID: {Id}", model.Id);
return null;
}
}
public void Create(AssemblyBindingModel model)
{
CheckModel(model);
try
{
_assemblyStorage.Insert(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Insert operation failed for assembly: {Name}", model.Name);
throw new Exception("Insert operation failed", ex);
}
}
public void Update(AssemblyBindingModel model)
{
CheckModel(model);
try
{
_assemblyStorage.Update(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Update operation failed for assembly: {Id}", model.Id);
throw new Exception("Update operation failed", ex);
}
}
public void Delete(AssemblyBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Assembly: {Id}", model.Id);
try
{
_assemblyStorage.Delete(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Delete operation failed for assembly: {Id}", model.Id);
throw new Exception("Delete operation failed", ex);
}
}
private void CheckModel(AssemblyBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Name))
{
throw new ArgumentNullException("Название сборки обязательно", nameof(model.Name));
}
if (model.Name.Length > 100)
{
throw new ArgumentException("Название сборки не должно превышать 100 символов", nameof(model.Name));
}
if (string.IsNullOrEmpty(model.Description))
{
throw new ArgumentNullException("Описание сборки обязательно", nameof(model.Description));
}
if (model.Description.Length > 500)
{
throw new ArgumentException("Описание сборки не должно превышать 500 символов", nameof(model.Description));
}
if (model.UserID <= 0)
{
throw new ArgumentException("ID пользователя должен быть больше 0", nameof(model.UserID));
}
if (model.OrderRequestId.HasValue && model.OrderRequestId <= 0)
{
throw new ArgumentException("ID заявки должен быть больше 0", nameof(model.OrderRequestId));
}
_logger.LogInformation("Assembly validation passed for: {Name}", model.Name);
var existingAssembly = _assemblyStorage.GetElement(new AssemblyBindingModel { Name = model.Name });
if (existingAssembly != null && existingAssembly.Id != (model.Id ?? 0))
{
throw new InvalidOperationException($"Сборка с названием {model.Name} уже существует");
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
namespace ComputerStoreBusinessLogic.Implementations;
public class AssemblyBusinessLogicImplementation : IAssemblyBusinessLogicContract
{
private readonly IAssemblyStorageContract _assemblyStorage;
public AssemblyBusinessLogicImplementation(IAssemblyStorageContract assemblyStorage)
{
_assemblyStorage = assemblyStorage;
}
public List<AssemblyViewModel> GetFullList() => _assemblyStorage.GetFullList();
public AssemblyViewModel? GetElement(int id) => _assemblyStorage.GetElement(id);
public void Create(AssemblyCreateBindingModel model) => _assemblyStorage.Create(model);
public void Update(AssemblyCreateBindingModel model) => _assemblyStorage.Update(model);
public void Delete(int id) => _assemblyStorage.Delete(id);
public List<AssemblyViewModel> GetAssembliesWithoutRequest() => _assemblyStorage.GetAssembliesWithoutRequest();
public List<AssemblyViewModel> GetAssembliesByOrders(List<int> orderIds) => _assemblyStorage.GetAssembliesByOrders(orderIds);
public List<ComponentViewModel> GetComponentsByAssembly(int assemblyId) =>
_assemblyStorage.GetComponentsByAssembly(assemblyId);
public List<AssemblyViewModel> GetUnlinkedAssemblies(int userId) =>
_assemblyStorage.GetUnlinkedAssemblies(userId);
public List<AssemblyViewModel> GetAssembliesByRequest(int requestId) =>
_assemblyStorage.GetAssembliesByRequest(requestId);
public void AttachRequestToAssembly(int assemblyId, int requestId) =>
_assemblyStorage.AttachRequestToAssembly(assemblyId, requestId);
public void DetachRequestFromAssembly(int assemblyId) =>
_assemblyStorage.DetachRequestFromAssembly(assemblyId);
}

View File

@@ -1,186 +0,0 @@
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComputerStoreBusinessLogic.Implementations;
public class ComponentBusinessLogicContract : IComponentBusinessLogicContract
{
private readonly ILogger<ComponentBusinessLogicContract> _logger;
private readonly IComponentStorageContract _componentStorage;
public ComponentBusinessLogicContract(ILogger<ComponentBusinessLogicContract> logger, IComponentStorageContract componentStorage)
{
_logger = logger;
_componentStorage = componentStorage;
}
public List<ComponentViewModel>? ReadList(ComponentBindingModel? model)
{
_logger.LogInformation("ReadList for component. UserID: {UserID}", model?.UserID);
List<ComponentViewModel> list;
try
{
list = model == null ? _componentStorage.GetFullList() : _componentStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("GetFullList/GetFilteredList returned null. Returning empty list instead.");
list = new List<ComponentViewModel>();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving component list from storage.");
return new List<ComponentViewModel>();
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public ComponentViewModel? ReadElement(ComponentBindingModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement for component: {Id}, UserID: {UserID}", model.Id, model.UserID);
try
{
var element = _componentStorage.GetElement(model);
_logger.LogInformation("ReadElement found: {Id}", element.Id);
return element;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "ReadElement: Component not found for ID: {Id}", model.Id);
return null;
}
}
public void Create(ComponentBindingModel model)
{
CheckModel(model);
try
{
_componentStorage.Insert(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Insert operation failed for component: {ComponentName}", model.ComponentName);
throw new Exception("Insert operation failed", ex);
}
}
public void Update(ComponentBindingModel model)
{
CheckModel(model);
try
{
_componentStorage.Update(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Update operation failed for component: {Id}", model.Id);
throw new Exception("Update operation failed", ex);
}
}
public void Delete(ComponentBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Component: {Id}", model.Id);
try
{
_componentStorage.Delete(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Delete operation failed for component: {Id}", model.Id);
throw new Exception("Delete operation failed", ex);
}
}
public List<ComponentRequestAssemblyReportViewModel>? GetComponentsReport(DateTime startDate, DateTime endDate, int userId)
{
_logger.LogInformation("Generating components report for user: {UserID}, Period: {StartDate} - {EndDate}", userId, startDate, endDate);
try
{
var report = _componentStorage.GetComponentsReport(startDate, endDate, userId);
if (report == null)
{
_logger.LogWarning("GetComponentsReport returned null. Returning empty list instead.");
return new List<ComponentRequestAssemblyReportViewModel>();
}
_logger.LogInformation("Components report generated. Count: {Count}", report.Count);
return report;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error generating components report for user: {UserID}", userId);
return new List<ComponentRequestAssemblyReportViewModel>();
}
}
private void CheckModel(ComponentBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ComponentName))
{
throw new ArgumentNullException("Название комплектующего обязательно", nameof(model.ComponentName));
}
if (model.ComponentName.Length > 100)
{
throw new ArgumentException("Название комплектующего не должно превышать 100 символов", nameof(model.ComponentName));
}
if (string.IsNullOrEmpty(model.Manufacturer))
{
throw new ArgumentNullException("Производитель обязателен", nameof(model.Manufacturer));
}
if (model.Manufacturer.Length > 100)
{
throw new ArgumentException("Производитель не должен превышать 100 символов", nameof(model.Manufacturer));
}
if (model.Price <= 0)
{
throw new ArgumentException("Цена должна быть больше 0", nameof(model.Price));
}
if (model.UserID <= 0)
{
throw new ArgumentException("ID пользователя должен быть больше 0", nameof(model.UserID));
}
_logger.LogInformation("Component validation passed for: {ComponentName}", model.ComponentName);
var existingComponent = _componentStorage.GetElement(new ComponentBindingModel { ComponentName = model.ComponentName });
if (existingComponent != null && existingComponent.Id != (model.Id ?? 0))
{
throw new InvalidOperationException($"Комплектующее с названием {model.ComponentName} уже существует");
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
namespace ComputerStoreBusinessLogic.Implementations;
public class ComponentBusinessLogicImplementation : IComponentBusinessLogicContract
{
private readonly IComponentStorageContract _componentStorage;
public ComponentBusinessLogicImplementation(IComponentStorageContract componentStorage)
{
_componentStorage = componentStorage;
}
public List<ComponentViewModel> GetFullList() => _componentStorage.GetFullList();
public ComponentViewModel? GetElement(int id) => _componentStorage.GetElement(id);
public void Create(ComponentCreateBindingModel model) => _componentStorage.Create(model);
public void Update(ComponentCreateBindingModel model) => _componentStorage.Update(model);
public void Delete(int id) => _componentStorage.Delete(id);
public List<ProductViewModel> GetProductsByComponents(List<int> componentIds) => _componentStorage.GetProductsByComponents(componentIds);
public List<OrderBatchViewModel> GetUnlinkedBatches(int productId) => _componentStorage.GetUnlinkedBatches(productId);
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
using iText.Commons.Actions.Contexts;
namespace ComputerStoreBusinessLogic.Implementations;
public class OrderBatchBusinessLogicImplementation : IOrderBatchBusinessLogicContract
{
private readonly IOrderBatchStorageContract _orderBatchStorage;
public OrderBatchBusinessLogicImplementation(IOrderBatchStorageContract orderBatchStorage)
{
_orderBatchStorage = orderBatchStorage;
}
public List<OrderBatchViewModel> GetFullList() => _orderBatchStorage.GetFullList();
public OrderBatchViewModel? GetElement(int id) => _orderBatchStorage.GetElement(id);
public void Create(OrderBatchCreateBindingModel model) => _orderBatchStorage.Create(model);
public void Update(OrderBatchCreateBindingModel model) => _orderBatchStorage.Update(model);
public void Delete(int id) => _orderBatchStorage.Delete(id);
public List<OrderBatchViewModel> GetBatchesWithoutProduct(int userId, int productId) =>
_orderBatchStorage.GetBatchesWithoutProduct(userId, productId);
public List<OrderBatchViewModel> GetBatchesByProduct(int userId) =>
_orderBatchStorage.GetBatchesByProduct(userId);
public void AssignProductToBatches(List<int> batchIds, int productId) =>
_orderBatchStorage.AssignProductToBatches(batchIds, productId);
public List<OrderViewModel> GetOrdersByBatch(int batchId) => _orderBatchStorage.GetOrdersByBatch(batchId);
public void AddOrdersToBatch(int batchId, List<int> orderIds) => _orderBatchStorage.AddOrdersToBatch(batchId, orderIds);
public void RemoveOrdersFromBatch(int batchId, List<int> orderIds) => _orderBatchStorage.RemoveOrdersFromBatch(batchId, orderIds);
public List<AssemblyViewModel> GetUnlinkedAssemblies(int orderId) => _orderBatchStorage.GetUnlinkedAssemblies(orderId);
public List<AssemblyViewModel> GetAssembliesByOrders(List<int> orderIds) => _orderBatchStorage.GetAssembliesByOrders(orderIds);
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
namespace ComputerStoreBusinessLogic.Implementations;
public class OrderBusinessLogicImplementation : IOrderBusinessLogicContract
{
private readonly IOrderStorageContract _orderStorage;
public OrderBusinessLogicImplementation(IOrderStorageContract orderStorage)
{
_orderStorage = orderStorage;
}
public List<OrderViewModel> GetFullList() => _orderStorage.GetFullList();
public OrderViewModel? GetElement(int id) => _orderStorage.GetElement(id);
public void Create(OrderCreateBindingModel model) => _orderStorage.Create(model);
public void Update(OrderCreateBindingModel model) => _orderStorage.Update(model);
public void Delete(int id) => _orderStorage.Delete(id);
public List<OrderReportViewModel> GetOrdersWithDetailsByDateRange(int userId, DateTime start, DateTime end) =>
_orderStorage.GetOrdersWithDetailsByDateRange(userId, start, end);
}

View File

@@ -1,163 +0,0 @@
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComputerStoreBusinessLogic.Implementations;
public class ProductBusinessLogicContract : IProductBusinessLogicContract
{
private readonly ILogger<ProductBusinessLogicContract> _logger;
private readonly IProductStorageContract _productStorage;
public ProductBusinessLogicContract(ILogger<ProductBusinessLogicContract> logger, IProductStorageContract productStorage)
{
_logger = logger;
_productStorage = productStorage;
}
public List<ProductViewModel>? ReadList(ProductBindingModel? model)
{
_logger.LogInformation("ReadList for product. UserID: {UserID}", model?.UserID);
List<ProductViewModel> list;
try
{
list = model == null ? _productStorage.GetFullList() : _productStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("GetFullList/GetFilteredList returned null. Returning empty list instead.");
list = new List<ProductViewModel>();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving product list from storage.");
return new List<ProductViewModel>();
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public ProductViewModel? ReadElement(ProductBindingModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement for product: {Id}, UserID: {UserID}", model.Id, model.UserID);
try
{
var element = _productStorage.GetElement(model);
_logger.LogInformation("ReadElement found: {Id}", element.Id);
return element;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "ReadElement: Product not found for ID: {Id}", model.Id);
return null;
}
}
public void Create(ProductBindingModel model)
{
CheckModel(model);
try
{
_productStorage.Insert(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Insert operation failed for product: {Name}", model.Name);
throw new Exception("Insert operation failed", ex);
}
}
public void Update(ProductBindingModel model)
{
CheckModel(model);
try
{
_productStorage.Update(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Update operation failed for product: {Id}", model.Id);
throw new Exception("Update operation failed", ex);
}
}
public void Delete(ProductBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Product: {Id}", model.Id);
try
{
_productStorage.Delete(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Delete operation failed for product: {Id}", model.Id);
throw new Exception("Delete operation failed", ex);
}
}
private void CheckModel(ProductBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Name))
{
throw new ArgumentNullException("Название товара обязательно", nameof(model.Name));
}
if (model.Name.Length > 100)
{
throw new ArgumentException("Название товара не должно превышать 100 символов", nameof(model.Name));
}
if (string.IsNullOrEmpty(model.Category))
{
throw new ArgumentNullException("Категория товара обязательна", nameof(model.Category));
}
if (model.Category.Length > 100)
{
throw new ArgumentException("Категория товара не должна превышать 100 символов", nameof(model.Category));
}
if (model.Price <= 0)
{
throw new ArgumentException("Цена должна быть больше 0", nameof(model.Price));
}
if (model.UserID <= 0)
{
throw new ArgumentException("ID пользователя должен быть больше 0", nameof(model.UserID));
}
_logger.LogInformation("Product validation passed for: {Name}", model.Name);
var existingProduct = _productStorage.GetElement(new ProductBindingModel { Name = model.Name });
if (existingProduct != null && existingProduct.Id != (model.Id ?? 0))
{
throw new InvalidOperationException($"Товар с названием {model.Name} уже существует");
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
namespace ComputerStoreBusinessLogic.Implementations;
public class ProductBusinessLogicImplementation : IProductBusinessLogicContract
{
private readonly IProductStorageContract _productStorage;
private readonly IOrderBatchStorageContract _orderBatchLogic;
public ProductBusinessLogicImplementation(IProductStorageContract productStorage, IOrderBatchStorageContract orderBatch)
{
_productStorage = productStorage;
_orderBatchLogic = orderBatch;
}
public List<ProductViewModel> GetFullList() => _productStorage.GetFullList();
public ProductViewModel? GetElement(int id) => _productStorage.GetElement(id);
public void Create(ProductCreateBindingModel model) => _productStorage.Create(model);
public void Update(ProductCreateBindingModel model) => _productStorage.Update(model);
public void Delete(int id) => _productStorage.Delete(id);
public void AttachBatchesToProduct(int productId, List<int> batchIds)
{
_orderBatchLogic.AssignProductToBatches(batchIds, productId);
}
public List<OrderBatchViewModel> GetBatchesByComponents(List<int> componentIds) => _productStorage.GetBatchesByComponents(componentIds);
public List<OrderBatchViewModel> GetUnlinkedBatches(int productId) => _productStorage.GetUnlinkedBatches(productId);
public List<ComponentViewModel> GetAllByComponent(int componentId) => _productStorage.GetAllByComponent(componentId);
}

View File

@@ -0,0 +1,129 @@
using System.Net.Mail;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using System.Net;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.ViewModels;
using iText.Kernel.Pdf.Canvas.Draw;
using ClosedXML.Excel;
using iText.Layout.Properties;
using iText.Kernel.Font;
using System.Net.Mime;
namespace ComputerStoreBusinessLogic.Implementations;
public class ReportService : IReportService
{
public byte[] GeneratePdf(List<OrderReportViewModel> data)
{
using var memoryStream = new MemoryStream();
var writer = new PdfWriter(memoryStream);
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
// Загружаем шрифт с поддержкой кириллицы
var fontPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/fonts", "Montserrat-VariableFont_wght.ttf");
var font = PdfFontFactory.CreateFont(fontPath, "Identity-H"); // Identity-H для Unicode
// Устанавливаем шрифт по умолчанию
document.SetFont(font);
document.Add(new Paragraph("Отчет по заказам за период").SetFontSize(12));
document.Add(new Paragraph(" "));
var table = new Table(UnitValue.CreatePercentArray(7)).UseAllAvailableWidth();
table.AddHeaderCell("Order ID");
table.AddHeaderCell("Статус");
table.AddHeaderCell("Дата");
table.AddHeaderCell("Request ID");
table.AddHeaderCell("Описание заявки");
table.AddHeaderCell("Product ID");
table.AddHeaderCell("Название товара");
foreach (var item in data)
{
if (item.ProductId == 0)
{
continue;
};
table.AddCell(item.OrderId.ToString());
table.AddCell(item.OrderStatus);
table.AddCell(item.CreatedAt.ToShortDateString());
table.AddCell(item.RequestId.ToString());
table.AddCell(item.RequestDescription);
table.AddCell(item.ProductId.ToString());
table.AddCell(item.ProductName);
}
document.Add(table);
document.Close();
return memoryStream.ToArray();
}
public byte[] GenerateExcel(List<AssemblyViewModel> data)
{
using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Сборки");
worksheet.Cell(1, 1).Value = "ID";
worksheet.Cell(1, 2).Value = "Название";
worksheet.Cell(1, 3).Value = "Описание";
for (int i = 0; i < data.Count; i++)
{
worksheet.Cell(i + 2, 1).Value = data[i].Id;
worksheet.Cell(i + 2, 2).Value = data[i].Name;
worksheet.Cell(i + 2, 3).Value = data[i].Description;
}
using var stream = new MemoryStream();
workbook.SaveAs(stream);
return stream.ToArray();
}
public byte[] GenerateExcelBatchesByComponents(List<OrderBatchViewModel> data)
{
using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Партии товаров");
worksheet.Cell(1, 1).Value = "ID";
worksheet.Cell(1, 2).Value = "Название партии";
for (int i = 0; i < data.Count; i++)
{
worksheet.Cell(i + 2, 1).Value = data[i].Id;
worksheet.Cell(i + 2, 2).Value = data[i].Name;
}
using var stream = new MemoryStream();
workbook.SaveAs(stream);
return stream.ToArray();
}
public async Task SendEmailWithReport(string email, byte[] fileData, string fileName)
{
SmtpClient _smtpClient = new SmtpClient("smtp.gmail.com")
{
Port = 587,
Credentials = new NetworkCredential("nsshipilov@gmail.com", "pftn icnc mmcf jyun"),
EnableSsl = true
};
var message = new MailMessage(
from: "nsshipilov@gmail.com",
to: email,
subject: "Отчет по визиту",
body: "Прикреплен отчет за визит в формате PDF"
)
{
IsBodyHtml = false
};
// Добавляем вложение
using var ms = new MemoryStream(fileData);
var attachment = new Attachment(ms, fileName, MediaTypeNames.Application.Pdf);
message.Attachments.Add(attachment);
await _smtpClient.SendMailAsync(message);
}
}

View File

@@ -1,142 +0,0 @@
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComputerStoreBusinessLogic.Implementations;
public class RequestBusinessLogicContract : IRequestBusinessLogicContract
{
private readonly ILogger<RequestBusinessLogicContract> _logger;
private readonly IRequestStorageContract _requestStorage;
public RequestBusinessLogicContract(ILogger<RequestBusinessLogicContract> logger, IRequestStorageContract requestStorage)
{
_logger = logger;
_requestStorage = requestStorage;
}
public List<RequestViewModel>? ReadList(RequestBindingModel? model)
{
_logger.LogInformation("ReadList for request. UserID: {UserID}", model?.UserID);
List<RequestViewModel> list;
try
{
list = model == null ? _requestStorage.GetFullList() : _requestStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("GetFullList/GetFilteredList returned null. Returning empty list instead.");
list = new List<RequestViewModel>();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving request list from storage.");
return new List<RequestViewModel>();
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public RequestViewModel? ReadElement(RequestBindingModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement for request: {Id}, UserID: {UserID}", model.Id, model.UserID);
try
{
var element = _requestStorage.GetElement(model);
_logger.LogInformation("ReadElement found: {Id}", element.Id);
return element;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "ReadElement: Request not found for ID: {Id}", model.Id);
return null;
}
}
public void Create(RequestBindingModel model)
{
CheckModel(model);
try
{
_requestStorage.Insert(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Insert operation failed for request: {Id}", model.Id);
throw new Exception("Insert operation failed", ex);
}
}
public void Update(RequestBindingModel model)
{
CheckModel(model);
try
{
_requestStorage.Update(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Update operation failed for request: {Id}", model.Id);
throw new Exception("Update operation failed", ex);
}
}
public void Delete(RequestBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Request: {Id}", model.Id);
try
{
_requestStorage.Delete(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Delete operation failed for request: {Id}", model.Id);
throw new Exception("Delete operation failed", ex);
}
}
private void CheckModel(RequestBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.DateRequest == default)
{
throw new ArgumentNullException("Дата заявки обязательна", nameof(model.DateRequest));
}
if (model.UserID <= 0)
{
throw new ArgumentException("ID пользователя должен быть больше 0", nameof(model.UserID));
}
if (model.AssemblyId.HasValue && model.AssemblyId <= 0)
{
throw new ArgumentException("ID сборки должен быть больше 0", nameof(model.AssemblyId));
}
_logger.LogInformation("Request validation passed for: {Id}", model.Id);
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
namespace ComputerStoreBusinessLogic.Implementations;
public class RequestBusinessLogicImplementation : IRequestBusinessLogicContract
{
private readonly IRequestStorageContract _requestStorage;
public RequestBusinessLogicImplementation(IRequestStorageContract requestStorage)
{
_requestStorage = requestStorage;
}
public List<RequestViewModel> GetFullList() => _requestStorage.GetFullList();
public RequestViewModel? GetElement(int id) => _requestStorage.GetElement(id);
public void Create(RequestCreateBindingModel model) => _requestStorage.Create(model);
public void Update(RequestCreateBindingModel model) => _requestStorage.Update(model);
public void Delete(int id) => _requestStorage.Delete(id);
public void AttachAssemblyToRequest(int requestId, int assemblyId) => _requestStorage.AttachAssemblyToRequest(requestId, assemblyId);
public List<OrderViewModel> GetOrdersByRequest(int requestId) => _requestStorage.GetOrdersByRequest(requestId);
public void AddOrdersToRequest(int requestId, List<int> orderIds) => _requestStorage.AddOrdersToRequest(requestId, orderIds);
public void RemoveOrdersFromRequest(int requestId, List<int> orderIds) => _requestStorage.RemoveOrdersFromRequest(requestId, orderIds);
public List<AssemblyViewModel> GetUnlinkedAssemblies(int requestId)
{
return _requestStorage.GetUnlinkedAssemblies(requestId);
}
}

View File

@@ -1,190 +0,0 @@
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComputerStoreBusinessLogic.Implementations;
public class UserBusinessLogicContract : IUserBusinessLogicContract
{
private readonly ILogger<UserBusinessLogicContract> _logger;
private readonly IUserStorageContract _userStorage;
public UserBusinessLogicContract(ILogger<UserBusinessLogicContract> logger, IUserStorageContract userStorage)
{
_logger = logger;
_userStorage = userStorage;
}
public List<UserViewModel>? ReadList(UserBindingModel? model)
{
_logger.LogInformation("ReadList for user: {Login}", model?.Login);
List<UserViewModel> list;
try
{
list = model == null ? _userStorage.GetFullList() : _userStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("GetFullList/GetFilteredList returned null. Returning empty list instead.");
list = new List<UserViewModel>();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving user list from storage.");
return new List<UserViewModel>();
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public UserViewModel? ReadElement(UserBindingModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement for user: {Login}", model.Login);
try
{
var element = _userStorage.GetElement(model);
_logger.LogInformation("ReadElement found: {Login}", element.Login);
return element;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "ReadElement: User not found for login: {Login}", model.Login);
return null;
}
}
public void Create(UserBindingModel model)
{
CheckModel(model);
try
{
_userStorage.Insert(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Insert operation failed for user: {Login}", model.Login);
throw new Exception("Insert operation failed", ex);
}
}
public void Update(UserBindingModel model)
{
CheckModel(model);
try
{
_userStorage.Update(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Update operation failed for user: {Login}", model.Login);
throw new Exception("Update operation failed", ex);
}
}
public void Delete(UserBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Login: {Login}", model.Login);
try
{
_userStorage.Delete(model);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Delete operation failed for user: {Login}", model.Login);
throw new Exception("Delete operation failed", ex);
}
}
private void CheckModel(UserBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Login))
{
throw new ArgumentNullException("Логин обязателен", nameof(model.Login));
}
if (model.Login.Length > 50)
{
throw new ArgumentException("Логин не должен превышать 50 символов", nameof(model.Login));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Пароль обязателен", nameof(model.Password));
}
if (model.Password.Length > 8)
{
throw new ArgumentException("Пароль не должен превышать 8 символов", nameof(model.Password));
}
if (!model.Password.Any(char.IsLetter) || !model.Password.Any(char.IsDigit))
{
throw new ArgumentException("Пароль должен содержать хотя бы одну букву и одну цифру", nameof(model.Password));
}
if (string.IsNullOrEmpty(model.FIO))
{
throw new ArgumentNullException("ФИО обязательно", nameof(model.FIO));
}
if (model.FIO.Length > 100)
{
throw new ArgumentException("ФИО не должно превышать 100 символов", nameof(model.FIO));
}
if (string.IsNullOrEmpty(model.Email))
{
throw new ArgumentNullException("Email обязателен", nameof(model.Email));
}
if (model.Email.Length > 100)
{
throw new ArgumentException("Email не должен превышать 100 символов", nameof(model.Email));
}
if (!new System.ComponentModel.DataAnnotations.EmailAddressAttribute().IsValid(model.Email))
{
throw new ArgumentException("Некорректный формат email", nameof(model.Email));
}
_logger.LogInformation("User validation passed for: {Login}", model.Login);
var existingUserByLogin = _userStorage.GetElement(new UserBindingModel { Login = model.Login });
var existingUserByEmail = _userStorage.GetElement(new UserBindingModel { Email = model.Email });
if (existingUserByLogin != null && existingUserByLogin.ID != (model.Id ?? 0))
{
throw new InvalidOperationException($"Пользователь с логином {model.Login} уже существует");
}
if (existingUserByEmail != null && existingUserByEmail.ID != (model.Id ?? 0))
{
throw new InvalidOperationException($"Пользователь с email {model.Email} уже существует");
}
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerStoreContracts.BindingModels;
using ComputerStoreContracts.BusinessLogicContracts;
using ComputerStoreContracts.Enums;
using ComputerStoreContracts.StoragesContracts;
using ComputerStoreContracts.ViewModels;
namespace ComputerStoreBusinessLogic.Implementations;
public class UserBusinessLogicImplementation : IUserBusinessLogicContract
{
private readonly IUserStorageContract _userStorage;
public UserBusinessLogicImplementation(IUserStorageContract userStorage)
{
_userStorage = userStorage;
}
public List<UserViewModel> GetFullList() => _userStorage.GetFullList();
public UserViewModel? GetElement(int id) => _userStorage.GetElement(id);
public void Create(UserBindingModel model)
{
if (string.IsNullOrEmpty(model.Login))
throw new ArgumentException("Логин не может быть пустым");
if (model.RoleType == UserType.Executor && model.Password.Length < 6)
throw new ArgumentException("Пароль слишком короткий");
_userStorage.Create(model);
}
public void Update(UserBindingModel model)
{
if (model.ID <= 0)
throw new ArgumentException("Неверный ID пользователя");
var existing = _userStorage.GetElement(model.ID);
if (existing == null)
throw new InvalidOperationException("Пользователь не найден");
if (string.IsNullOrEmpty(model.Login))
throw new ArgumentException("Логин не может быть пустым");
// Если пароль не указан — не меняем его
if (string.IsNullOrEmpty(model.Password))
{
var originalPassword = existing.Password;
model.Password = originalPassword;
}
_userStorage.Update(model);
}
public void Delete(int id)
{
if (id <= 0)
throw new ArgumentException("Неверный ID");
_userStorage.Delete(id);
}
public bool Authenticate(string login, string password, out UserViewModel? user)
{
user = _userStorage.GetFullList().FirstOrDefault(u => u.Login == login && u.Password == password);
return user != null;
}
public bool IsExecutor(int userId)
{
var user = _userStorage.GetElement(userId);
return user?.RoleType == UserType.Executor;
}
public bool IsGuarantor(int userId)
{
var user = _userStorage.GetElement(userId);
return user?.RoleType == UserType.Guarantor;
}
}