2023-01-30 11:43:43 +04:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
using Microsoft.Extensions.Logging ;
using IceCreamShopContracts.BindingModels ;
using IceCreamShopContracts.BusinessLogicsContracts ;
using IceCreamShopContracts.SearchModels ;
using IceCreamShopContracts.StoragesContracts ;
using IceCreamShopContracts.ViewModels ;
using AbstractIceCreamShopDataModels.Enums ;
2023-04-11 15:29:05 +04:00
using IceCreamBusinessLogic.MailWorker ;
2023-03-13 13:25:55 +04:00
using AbstractIceCreamShopDataModels.Models ;
2023-01-30 11:43:43 +04:00
namespace IceCreamBusinessLogic.BusinessLogics
{
2023-01-30 15:02:38 +04:00
public class OrderLogic : IOrderLogic
2023-01-30 11:43:43 +04:00
{
2023-01-30 15:02:38 +04:00
private readonly ILogger _logger ;
2023-01-30 11:43:43 +04:00
private readonly IOrderStorage _orderStorage ;
2023-04-11 15:29:05 +04:00
private readonly AbstractMailWorker _mailWorker ;
private readonly IClientLogic _clientLogic ;
2023-03-13 13:25:55 +04:00
private readonly IShopStorage _shopStorage ;
2023-03-12 21:19:02 +04:00
private readonly IShopLogic _shopLogic ;
private readonly IIceCreamStorage _iceCreamStorage ;
2023-01-30 11:43:43 +04:00
2023-04-11 15:29:05 +04:00
public OrderLogic ( ILogger < OrderLogic > logger , IOrderStorage orderStorage , AbstractMailWorker mailWorker , IClientLogic clientLogic )
{
2023-03-13 13:25:55 +04:00
public OrderLogic ( IOrderStorage orderStorage , IShopStorage shopStorage , IShopLogic shopLogic , IIceCreamStorage iceCreamStorage , ILogger < OrderLogic > logger )
2023-01-30 11:43:43 +04:00
{
_orderStorage = orderStorage ;
2023-03-13 13:25:55 +04:00
_shopStorage = shopStorage ;
2023-01-30 15:02:38 +04:00
_logger = logger ;
2023-04-11 15:29:05 +04:00
_mailWorker = mailWorker ;
_clientLogic = clientLogic ;
}
2023-03-12 21:19:02 +04:00
_shopLogic = shopLogic ;
_iceCreamStorage = iceCreamStorage ;
2023-01-30 11:43:43 +04:00
}
public bool CreateOrder ( OrderBindingModel model )
{
2023-01-30 15:02:38 +04:00
CheckModel ( model ) ;
if ( model . Status ! = OrderStatus . Н е и з в е с т е н )
2023-01-30 11:43:43 +04:00
{
2023-01-30 15:02:38 +04:00
_logger . LogWarning ( "Insert operation failed. Order status incorrect." ) ;
return false ;
}
model . Status = OrderStatus . П р и н я т ;
2023-04-11 15:29:05 +04:00
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 ;
}
2023-01-30 11:43:43 +04:00
public bool DeliveryOrder ( OrderBindingModel model )
{
2023-01-30 15:29:32 +04:00
return SetNewStatus ( model , OrderStatus . Г о т о в ) ;
2023-01-30 11:43:43 +04:00
}
public bool FinishOrder ( OrderBindingModel model )
{
2023-01-30 15:29:32 +04:00
return SetNewStatus ( model , OrderStatus . В ы д а н ) ;
2023-01-30 11:43:43 +04:00
}
2023-01-30 15:29:32 +04:00
public bool TakeOrderInWork ( OrderBindingModel model )
2023-01-30 11:43:43 +04:00
{
2023-01-30 15:29:32 +04:00
return SetNewStatus ( model , OrderStatus . В ы п о л н я е т с я ) ;
2023-01-30 11:43:43 +04:00
}
2023-01-30 15:29:32 +04:00
public List < OrderViewModel > ? ReadList ( OrderSearchModel ? model )
2023-01-30 11:43:43 +04:00
{
2023-01-31 10:40:59 +04:00
_logger . LogInformation ( "ReadList. OrderID:{Id}" , model ? . Id ) ;
2023-01-30 15:29:32 +04:00
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 ;
2023-01-30 11:43:43 +04:00
}
2023-01-30 15:02:38 +04:00
2023-01-30 15:29:32 +04:00
private void CheckModel ( OrderBindingModel model )
2023-01-30 15:02:38 +04:00
{
if ( model = = null )
{
throw new ArgumentNullException ( nameof ( model ) ) ;
}
2023-01-30 15:29:32 +04:00
if ( model . Id < 0 )
2023-01-30 15:02:38 +04:00
{
2023-01-30 15:29:32 +04:00
throw new ArgumentNullException ( "Некорректный идентификатор заказа" , nameof ( model . Id ) ) ;
2023-01-30 15:02:38 +04:00
}
if ( model . IceCreamId < 0 )
{
2023-01-31 10:40:59 +04:00
throw new ArgumentNullException ( "Некорректный идентификатор мороженого" , nameof ( model . IceCreamId ) ) ;
2023-01-30 15:02:38 +04:00
}
if ( model . Count < = 0 )
{
2023-01-31 10:40:59 +04:00
throw new ArgumentNullException ( "Количество мороженого в заказе должно быть больше 0" , nameof ( model . Count ) ) ;
2023-01-30 15:02:38 +04:00
}
if ( model . Sum < = 0 )
{
throw new ArgumentNullException ( "Сумма заказа должна быть больше 0" , nameof ( model . Sum ) ) ;
}
_logger . LogInformation ( "Order. OrderID:{Id}.Sum:{ Sum}. DocumentId: { DocumentId}" , model . Id , model . Sum , model . IceCreamId ) ;
}
2023-01-30 15:29:32 +04:00
2023-04-25 11:18:23 +04:00
public bool SetNewStatus ( OrderBindingModel rawModel , OrderStatus newStatus )
2023-01-30 15:29:32 +04:00
{
2023-04-25 11:18:23 +04:00
var viewModel = _orderStorage . GetElement ( new OrderSearchModel
2023-02-13 14:57:26 +04:00
{
2023-04-25 11:18:23 +04:00
Id = rawModel . Id
} ) ;
if ( viewModel = = null )
{
_logger . LogWarning ( "Order model not found" ) ;
return false ;
2023-03-12 21:19:02 +04:00
}
2023-04-25 11:18:23 +04:00
OrderBindingModel model = new OrderBindingModel
{
Id = viewModel . Id ,
IceCreamId = viewModel . IceCreamId ,
Status = viewModel . Status ,
DateCreate = viewModel . DateCreate ,
DateImplement = viewModel . DateImplement ,
Count = viewModel . Count ,
Sum = viewModel . Sum ,
ImplementerId = viewModel . ImplementerId
} ;
if ( rawModel . ImplementerId . HasValue )
2023-01-30 15:29:32 +04:00
{
2023-04-25 11:18:23 +04:00
model . ImplementerId = rawModel . ImplementerId ;
2023-01-30 15:29:32 +04:00
}
2023-04-09 20:36:57 +04:00
model . Status = orderStatus ;
model . DateCreate = vmodel . DateCreate ;
if ( model . DateImplement = = null )
model . DateImplement = vmodel . DateImplement ;
if ( vmodel . ImplementerId . HasValue )
model . ImplementerId = vmodel . ImplementerId ;
model . IceCreamId = vmodel . IceCreamId ;
model . Sum = vmodel . Sum ;
model . Count = vmodel . Count ;
2023-04-11 15:29:05 +04:00
var result = _orderStorage . Update ( model ) ;
if ( result = = null )
{
_logger . LogWarning ( "Update operation failed" ) ;
return false ;
}
SendOrderStatusMail ( result . ClientId , $"Изменен статус заказа #{result.Id}" , $"Заказ #{model.Id} изменен статус на {result.Status}" ) ;
return true ;
}
2023-04-09 14:49:06 +04:00
2023-04-25 11:18:23 +04:00
CheckModel ( model ) ;
if ( model . Status + 1 ! = newStatus & & model . Status ! = OrderStatus . О ж и д а е т с я )
2023-04-25 08:54:06 +04:00
{
2023-04-25 11:18:23 +04:00
_logger . LogWarning ( "Status update to " + newStatus . ToString ( ) + " operation failed. Order status incorrect." ) ;
return false ;
}
2023-04-25 08:54:06 +04:00
2023-04-25 11:18:23 +04:00
if ( newStatus = = OrderStatus . Г о т о в )
{
var icecream = _iceCreamStorage . GetElement ( new IceCreamSearchModel ( ) { Id = model . IceCreamId } ) ;
if ( icecream = = null )
2023-04-25 08:54:06 +04:00
{
2023-04-25 11:18:23 +04:00
_logger . LogWarning ( "Status update to " + newStatus . ToString ( ) + " operation failed. Icecream not found." ) ;
return false ;
2023-04-25 08:54:06 +04:00
}
2023-04-25 11:18:23 +04:00
if ( CheckSupply ( icecream , model . Count ) = = false )
2023-04-25 08:54:06 +04:00
{
2023-04-25 11:18:23 +04:00
_logger . LogWarning ( "Status update to " + newStatus . ToString ( ) + " operation failed. Shop supply error." ) ;
model . Status = OrderStatus . О ж и д а е т с я ;
_orderStorage . Update ( model ) ;
return false ;
2023-04-25 08:54:06 +04:00
}
}
2023-04-25 11:18:23 +04:00
model . Status = newStatus ;
if ( model . Status = = OrderStatus . В ы д а н ) model . DateImplement = DateTime . Now ;
2023-03-13 13:25:55 +04:00
if ( _orderStorage . Update ( model ) = = null )
2023-01-30 15:29:32 +04:00
{
2023-04-25 11:18:23 +04:00
model . Status - - ;
2023-01-30 15:29:32 +04:00
_logger . LogWarning ( "Update operation failed" ) ;
return false ;
}
return true ;
}
2023-04-25 11:18:23 +04:00
public bool CheckSupply ( IIceCreamModel model , int count )
{
if ( count < = 0 )
{
_logger . LogWarning ( "Check then supply operation error. icecream count < 0." ) ;
return false ;
}
int freeSpace = 0 ;
foreach ( var shop in _shopStorage . GetFullList ( ) )
{
freeSpace + = shop . IceCreamMaxCount ;
foreach ( var icecream in shop . ShopIceCreams )
{
freeSpace - = icecream . Value . Item2 ;
}
}
if ( freeSpace - count < 0 )
{
_logger . LogWarning ( "Check then supply operation error. There's no place for new icecreams in shops." ) ;
return false ;
}
foreach ( var shop in _shopStorage . GetFullList ( ) )
{
freeSpace = shop . IceCreamMaxCount ;
foreach ( var icecream in shop . ShopIceCreams )
{
freeSpace - = icecream . Value . Item2 ;
}
if ( freeSpace = = 0 )
{
continue ;
}
if ( freeSpace - count > = 0 )
{
if ( _shopLogic . SupplyIceCreams ( new ( ) { Id = shop . Id } , model , count ) ) count = 0 ;
else
{
_logger . LogWarning ( "Supply error" ) ;
return false ;
}
}
if ( freeSpace - count < 0 )
{
if ( _shopLogic . SupplyIceCreams ( new ( ) { Id = shop . Id } , model , freeSpace ) ) count - = freeSpace ;
else
{
_logger . LogWarning ( "Supply error" ) ;
return false ;
}
}
if ( count < = 0 )
{
return true ;
}
}
return false ;
}
2023-04-08 18:30:16 +04:00
public OrderViewModel ? ReadElement ( OrderSearchModel model )
2023-03-28 10:02:32 +04:00
{
2023-04-08 18:30:16 +04:00
if ( model = = null )
2023-03-28 10:02:32 +04:00
{
2023-04-08 18:30:16 +04:00
throw new ArgumentNullException ( nameof ( model ) ) ;
2023-03-28 10:02:32 +04:00
}
2023-04-08 18:30:16 +04:00
_logger . LogInformation ( "ReadElement. Id:{ Id}" , model . Id ) ;
var element = _orderStorage . GetElement ( model ) ;
if ( element = = null )
2023-03-28 10:02:32 +04:00
{
2023-04-08 18:30:16 +04:00
_logger . LogWarning ( "ReadElement element not found" ) ;
return null ;
2023-03-28 10:02:32 +04:00
}
2023-04-08 18:30:16 +04:00
_logger . LogInformation ( "ReadElement find. Id:{Id}" , element . Id ) ;
return element ;
2023-03-28 10:02:32 +04:00
}
2023-04-11 15:29:05 +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 ;
}
}
2023-01-30 11:43:43 +04:00
}