185 lines
7.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using SoftwareInstallationContracts.BindingModels;
using SoftwareInstallationContracts.BusinessLogicsContracts;
using SoftwareInstallationContracts.SearchModels;
using SoftwareInstallationContracts.StoragesContracts;
using SoftwareInstallationContracts.ViewModels;
using SoftwareInstallationDataModels.Enums;
using Microsoft.Extensions.Logging;
using DocumentFormat.OpenXml.EMMA;
using SoftwareInstallationBusinessLogic.MailWorker;
namespace SoftwareInstallationBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IPackageStorage _packageStorage;
private readonly IShopLogic _shopLogic;
private readonly AbstractMailWorker _mailWorker;
private readonly IClientLogic _clientLogic;
private static bool _finished = false;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IPackageStorage packageStorage, IShopLogic shopLogic, IClientLogic clientLogic, AbstractMailWorker mailWorker)
{
_logger = logger;
_shopLogic = shopLogic;
_packageStorage = packageStorage;
_orderStorage = orderStorage;
_mailWorker = mailWorker;
_clientLogic = clientLogic;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
{
throw new ArgumentException(
$"Статус заказа должен быть {OrderStatus.Неизвестен}", nameof(model));
}
model.Status = OrderStatus.Принят;
model.DateCreate = DateTime.Now;
var result = _orderStorage.Insert(model);
if (result == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
SendOrderStatusMail(result.ClientId, $"Новый заказ создан. Номер заказа #{result.Id}", $"Заказ #{result.Id} от {result.DateCreate} на сумму {result.Sum:0.00} принят");
return true;
}
public bool DeliveryOrder(OrderBindingModel model)
{
return SetOrderStatus(model, OrderStatus.Выдан);
}
public bool FinishOrder(OrderBindingModel model)
{
if (_finished)
{
return false;
}
_finished = true;
model.DateImplement = DateTime.Now;
var res = SetOrderStatus(model, OrderStatus.Готов);
_finished = false;
return res;
}
public OrderViewModel? ReadElement(OrderSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id:{ Id}", model.Id);
var element = _orderStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. OrderName.Id:{ Id} ", model?.Id);
var list = (model == null) ? _orderStorage.GetFullList() :
_orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
return SetOrderStatus(model, OrderStatus.Выполняется);
}
private bool CheckModel(OrderBindingModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (model.Count <= 0)
{
throw new ArgumentException("Количество изделий в заказе должно быть больше 0", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentException("Суммарная стоимость заказа должна быть больше 0", nameof(model.Sum));
}
if (model.DateCreate > model.DateImplement)
{
throw new ArgumentException("Время создания заказа не может быть больше времени его выполнения", nameof(model.DateImplement));
}
return true;
}
private bool SetOrderStatus(OrderBindingModel model, OrderStatus orderStatus)
{
var viewModel = _orderStorage.GetElement(new() { Id = model.Id });
if (viewModel == null)
{
throw new ArgumentNullException(nameof(model));
}
if ((int)viewModel.Status + 1 != (int)orderStatus && !(viewModel.Status == OrderStatus.Ожидается && orderStatus == OrderStatus.Готов))
{
throw new InvalidOperationException($"Попытка перевести заказ не в следующий статус: " +
$"Текущий статус: {viewModel.Status} \n" +
$"Планируемый статус: {orderStatus} \n" +
$"Доступный статус: {(OrderStatus)((int)viewModel.Status + 1)}");
}
if (orderStatus == OrderStatus.Готов || orderStatus == OrderStatus.Ожидается)
{
var vpackage = _packageStorage.GetElement(new() { Id = viewModel.PackageId });
if (vpackage == null || !_shopLogic.AddPackagesInShops(vpackage, viewModel.Count))
{
_logger.LogWarning($"Не удалось заполнить магазины изделием '{vpackage?.PackageName ?? string.Empty}' из заказа {viewModel.Id}");
orderStatus = OrderStatus.Ожидается;
}
else
{
orderStatus = OrderStatus.Готов;
}
}
if (model.DateImplement == null) model.DateImplement = viewModel.DateImplement;
if (viewModel.ImplementerId.HasValue) model.ImplementerId = viewModel.ImplementerId;
model.Status = orderStatus;
model.Sum = viewModel.Sum;
model.Count = viewModel.Count;
model.PackageId = viewModel.PackageId;
var result = _orderStorage.Update(model);
if (result == null)
{
_logger.LogWarning("Ошибка операции обновления");
return false;
}
SendOrderStatusMail(result.ClientId, $"Изменен статус заказа #{result.Id}", $"Заказ #{model.Id} изменен статус на {result.Status}");
return true;
}
private bool SendOrderStatusMail(int clientId, string subject, string text)
{
var client = _clientLogic.ReadElement(new() { Id = clientId });
if (client == null)
{
return false;
}
_mailWorker.MailSendAsync(new()
{
MailAddress = client.Email,
Subject = subject,
Text = text
});
return true;
}
}
}