PIbd-21_Kouvshinoff_T._A._A.../AutomobilePlant/AutomobilePlantBusinessLogic/BusinessLogics/OrderLogic.cs
2024-05-05 17:51:43 +04:00

269 lines
9.7 KiB
C#
Raw 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 AutomobilePlantBusinessLogic.MailWorker;
using AutomobilePlantContracts.BindingModels;
using AutomobilePlantContracts.BusinessLogicsContracts;
using AutomobilePlantContracts.SearchModels;
using AutomobilePlantContracts.StoragesContracts;
using AutomobilePlantContracts.ViewModels;
using AutomobilePlantDataModels.Enums;
using AutomobilePlantDataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutomobilePlantBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly IShopLogic _shopLogic;
private readonly ICarStorage _carStorage;
private readonly AbstractMailWorker _mailWorker;
private readonly IClientLogic _clientLogic;
static readonly object locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker, IClientLogic clientLogic, IShopLogic shopLogic, ICarStorage carStorage, IShopStorage shopStorage)
{
_logger = logger;
_orderStorage = orderStorage;
_mailWorker = mailWorker;
_clientLogic = clientLogic;
_shopLogic = shopLogic;
_carStorage = carStorage;
_shopStorage = shopStorage;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{ Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public 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 bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
return false;
model.Status = OrderStatus.Принят;
var result = _orderStorage.Insert(model);
if (result == null)
{
model.Status = OrderStatus.Неизвестен;
_logger.LogWarning("Insert operation failed");
return false;
}
SendOrderStatusMail(result.ClientId, $"A new order has been created. Order number #{result.Id}", $"Order #{result.Id} from {result.DateCreate} for the amount {result.Sum:0.00} {result.Status}");
return true;
}
public bool CheckThenSupplyMany(ICarModel car, int count)
{
if (count <= 0)
{
_logger.LogWarning("Check then supply operation error. Car count < 0.");
return false;
}
int freeSpace = 0;
foreach (var shop in _shopStorage.GetFullList())
{
freeSpace += shop.MaxCountCars;
foreach (var c in shop.ShopCars)
{
freeSpace -= c.Value.Item2;
}
}
if (freeSpace < count)
{
_logger.LogWarning("Check then supply operation error. There's no place for new cars in shops.");
return false;
}
foreach (var shop in _shopStorage.GetFullList())
{
freeSpace = shop.MaxCountCars;
foreach (var c in shop.ShopCars)
freeSpace -= c.Value.Item2;
if (freeSpace <= 0)
continue;
if (freeSpace >= count)
{
if (_shopLogic.SupplyCars(new ShopSearchModel() { Id = shop.Id }, car, count))
count = 0;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (freeSpace < count)
{
if (_shopLogic.SupplyCars(new ShopSearchModel() { Id = shop.Id }, car, freeSpace))
count -= freeSpace;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (count <= 0)
{
return true;
}
}
return false;
}
public bool ChangeStatus(OrderBindingModel model, OrderStatus status)
{
CheckModel(model, false);
var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (element == null)
{
_logger.LogWarning("Read operation failed");
return false;
}
if (element.Status != status - 1 && element.Status != OrderStatus.Ожидание)
{
_logger.LogWarning("Status change operation failed");
throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный");
}
if (element.ImplementerId.HasValue)
model.ImplementerId = element.ImplementerId;
if (model.CarId == 0)
model.CarId = element.CarId;
if (model.Count == 0)
model.Count = element.Count;
if (status == OrderStatus.Выдан)
{
var car = _carStorage.GetElement(new CarSearchModel() { Id = model.CarId });
if (car == null)
{
_logger.LogWarning("Status change operation failed. Car not found.");
return false;
}
if (!CheckThenSupplyMany(car, model.Count))
{
_logger.LogWarning("Status change operation failed. Shop supply error.");
model.Status = OrderStatus.Ожидание;
if (_orderStorage.Update(model) == null)
_logger.LogWarning("Update operation failed");
return false;
}
}
model.Status = status;
if (model.Status == OrderStatus.Выдан)
model.DateImplement = DateTime.Now;
var result = _orderStorage.Update(model);
if (result == null)
{
model.Status = oldStatus;
_logger.LogWarning("Update operation failed");
return false;
}
SendOrderStatusMail(result.ClientId, $"Status of order #{result.Id} has been changed", $"Order #{result.Id} status has been changed to {result.Status}");
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
lock (locker)
{
return ChangeStatus(model, OrderStatus.Выполняется);
}
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выдан);
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.CarId < 0)
{
throw new ArgumentNullException("Некорректный идентификатор машин", nameof(model.CarId));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Количество машин в заказе должно быть больше 0", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentNullException("Цена заказа должна быть больше 0", nameof(model.Sum));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Количество элементов в заказе должно быть больше 0", nameof(model.Count));
}
_logger.LogInformation("Order. Sum:{ Cost}. Id: { Id}", model.Sum, model.Id);
}
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;
}
}
}