2024-05-05 00:23:11 +04:00
using AutomobilePlantBusinessLogic.MailWorker ;
using AutomobilePlantContracts.BindingModels ;
2024-02-11 16:43:19 +04:00
using AutomobilePlantContracts.BusinessLogicsContracts ;
using AutomobilePlantContracts.SearchModels ;
using AutomobilePlantContracts.StoragesContracts ;
using AutomobilePlantContracts.ViewModels ;
using AutomobilePlantDataModels.Enums ;
2024-03-24 20:56:50 +04:00
using AutomobilePlantDataModels.Models ;
2024-02-11 16:43:19 +04:00
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 ;
2024-03-24 20:56:50 +04:00
private readonly IShopStorage _shopStorage ;
private readonly IShopLogic _shopLogic ;
private readonly ICarStorage _carStorage ;
2024-05-05 00:23:11 +04:00
private readonly AbstractMailWorker _mailWorker ;
private readonly IClientLogic _clientLogic ;
2024-04-20 00:48:41 +04:00
static readonly object locker = new object ( ) ;
2024-02-11 16:43:19 +04:00
2024-05-05 17:51:43 +04:00
public OrderLogic ( ILogger < OrderLogic > logger , IOrderStorage orderStorage , AbstractMailWorker mailWorker , IClientLogic clientLogic , IShopLogic shopLogic , ICarStorage carStorage , IShopStorage shopStorage )
2024-02-11 16:43:19 +04:00
{
_logger = logger ;
_orderStorage = orderStorage ;
2024-05-05 00:23:11 +04:00
_mailWorker = mailWorker ;
_clientLogic = clientLogic ;
2024-03-24 20:56:50 +04:00
_shopLogic = shopLogic ;
_carStorage = carStorage ;
_shopStorage = shopStorage ;
2024-02-11 16:43:19 +04:00
}
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 ;
}
2024-04-19 22:52:44 +04:00
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 ;
}
2024-02-11 16:43:19 +04:00
public bool CreateOrder ( OrderBindingModel model )
{
CheckModel ( model ) ;
2024-03-24 20:56:50 +04:00
if ( model . Status ! = OrderStatus . Н е и з в е с т е н )
return false ;
2024-02-11 16:43:19 +04:00
model . Status = OrderStatus . П р и н я т ;
2024-05-05 00:23:11 +04:00
var result = _orderStorage . Insert ( model ) ;
if ( result = = null )
2024-02-11 16:43:19 +04:00
{
2024-03-24 20:56:50 +04:00
model . Status = OrderStatus . Н е и з в е с т е н ;
2024-02-11 16:43:19 +04:00
_logger . LogWarning ( "Insert operation failed" ) ;
return false ;
}
2024-05-05 00:23:11 +04:00
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}" ) ;
2024-02-11 16:43:19 +04:00
return true ;
}
2024-03-24 20:56:50 +04:00
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 ;
}
2024-02-11 16:43:19 +04:00
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 ;
}
2024-04-20 21:35:14 +04:00
if ( element . Status ! = status - 1 & & element . Status ! = OrderStatus . О ж и д а н и е )
2024-02-11 16:43:19 +04:00
{
_logger . LogWarning ( "Status change operation failed" ) ;
throw new InvalidOperationException ( "Текущий статус заказа не может быть переведен в выбранный" ) ;
}
2024-03-24 20:56:50 +04:00
2024-04-20 21:35:14 +04:00
if ( element . ImplementerId . HasValue )
model . ImplementerId = element . ImplementerId ;
if ( model . CarId = = 0 )
model . CarId = element . CarId ;
if ( model . Count = = 0 )
model . Count = element . Count ;
2024-03-24 20:56:50 +04:00
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." ) ;
2024-04-20 21:35:14 +04:00
model . Status = OrderStatus . О ж и д а н и е ;
if ( _orderStorage . Update ( model ) = = null )
_logger . LogWarning ( "Update operation failed" ) ;
2024-03-24 20:56:50 +04:00
return false ;
}
2024-04-20 21:35:14 +04:00
2024-03-24 20:56:50 +04:00
}
2024-02-11 16:43:19 +04:00
model . Status = status ;
if ( model . Status = = OrderStatus . В ы д а н )
model . DateImplement = DateTime . Now ;
2024-05-05 00:23:11 +04:00
var result = _orderStorage . Update ( model ) ;
if ( result = = null )
2024-02-11 16:43:19 +04:00
{
model . Status = oldStatus ;
_logger . LogWarning ( "Update operation failed" ) ;
return false ;
}
2024-05-05 00:23:11 +04:00
SendOrderStatusMail ( result . ClientId , $"Status of order #{result.Id} has been changed" , $"Order #{result.Id} status has been changed to {result.Status}" ) ;
2024-02-11 16:43:19 +04:00
return true ;
}
public bool TakeOrderInWork ( OrderBindingModel model )
{
2024-04-20 00:48:41 +04:00
lock ( locker )
{
return ChangeStatus ( model , OrderStatus . В ы п о л н я е т с я ) ;
}
2024-02-11 16:43:19 +04:00
}
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 ) ;
}
2024-05-05 00:23:11 +04:00
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 ;
}
2024-02-11 16:43:19 +04:00
}
}