2023-01-30 21:46:31 +04:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
using PrecastConcretePlantContracts.BindingModels ;
using PrecastConcretePlantContracts.BusinessLogicsContracts ;
using PrecastConcretePlantContracts.SearchModels ;
using PrecastConcretePlantContracts.StoragesContracts ;
using PrecastConcretePlantContracts.ViewModels ;
using Microsoft.Extensions.Logging ;
using PrecastConcretePlantDataModels.Enums ;
2023-04-09 22:46:55 +04:00
using DocumentFormat.OpenXml.EMMA ;
2023-04-22 16:17:59 +04:00
using PrecastConcretePlantBusinessLogic.MailWorker ;
2023-01-30 21:46:31 +04:00
namespace PrecastConcretePlantBusinessLogic.BusinessLogic
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger ;
private readonly IOrderStorage _orderStorage ;
2023-03-12 17:46:52 +04:00
private readonly IReinforcedStorage _reinforcedStorage ;
2023-04-23 20:14:53 +04:00
private readonly IShopLogic _shopLogic ;
2023-04-22 16:17:59 +04:00
private readonly AbstractMailWorker _mailWorker ;
private readonly IClientLogic _clientLogic ;
2023-05-03 21:26:28 +04:00
public OrderLogic ( ILogger < OrderLogic > logger , IOrderStorage orderStorage , IReinforcedStorage reinforcedStorage , IShopLogic shopLogic , AbstractMailWorker mailWorker , IClientLogic clientLogic )
2023-01-30 21:46:31 +04:00
{
_logger = logger ;
2023-03-12 17:46:52 +04:00
_shopLogic = shopLogic ;
_reinforcedStorage = reinforcedStorage ;
2023-01-30 21:46:31 +04:00
_orderStorage = orderStorage ;
2023-04-22 16:17:59 +04:00
_mailWorker = mailWorker ;
_clientLogic = clientLogic ;
2023-01-30 21:46:31 +04:00
}
public bool CreateOrder ( OrderBindingModel model )
{
CheckModel ( model ) ;
if ( model . Status ! = OrderStatus . Н е и з в е с т е н )
{
2023-04-23 20:14:53 +04:00
throw new ArgumentException (
$"Статус заказа должен быть {OrderStatus.Неизвестен}" , nameof ( model ) ) ;
2023-01-30 21:46:31 +04:00
}
model . Status = OrderStatus . П р и н я т ;
2023-04-23 20:14:53 +04:00
model . DateCreate = DateTime . Now ;
2023-04-22 16:17:59 +04:00
var result = _orderStorage . Insert ( model ) ;
if ( result = = null )
2023-05-03 21:26:28 +04:00
{
2023-01-30 21:46:31 +04:00
_logger . LogWarning ( "Insert operation failed" ) ;
return false ;
}
2023-05-03 21:26:28 +04:00
SendOrderStatusMail ( result . ClientId , $"Новый заказ создан. Номер заказа #{result.Id}" , $"Заказ #{result.Id} от {result.DateCreate} на сумму {result.Sum:0.00} принят" ) ;
2023-01-30 21:46:31 +04:00
return true ;
}
2023-04-23 20:14:53 +04:00
public bool TakeOrderInWork ( OrderBindingModel model ) = > SetOrderStatus ( model , OrderStatus . В ы п о л н я е т с я ) ;
public bool DeliveryOrder ( OrderBindingModel model ) = > SetOrderStatus ( model , OrderStatus . В ы д а н ) ;
public bool FinishOrder ( OrderBindingModel model )
2023-01-30 21:46:31 +04:00
{
2023-04-23 20:14:53 +04:00
model . DateImplement = DateTime . Now ;
return SetOrderStatus ( model , OrderStatus . Г о т о в ) ;
}
2023-01-30 21:46:31 +04:00
2023-04-23 20:14:53 +04:00
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 )
2023-03-28 00:27:02 +04:00
{
2023-04-23 20:14:53 +04:00
_logger . LogWarning ( "ReadList return null list" ) ;
return null ;
2023-01-30 21:46:31 +04:00
}
2023-04-23 20:14:53 +04:00
_logger . LogInformation ( "ReadList. Count:{Count}" , list . Count ) ;
return list ;
}
2023-03-28 00:27:02 +04:00
2023-04-23 20:14:53 +04:00
private bool CheckModel ( OrderBindingModel model )
2023-01-30 21:46:31 +04:00
{
2023-04-23 20:14:53 +04:00
if ( model = = null )
2023-01-30 21:46:31 +04:00
{
2023-03-12 17:46:52 +04:00
throw new ArgumentNullException ( nameof ( model ) ) ;
2023-01-30 21:46:31 +04:00
}
2023-04-23 20:14:53 +04:00
if ( model . Count < = 0 )
2023-01-30 21:46:31 +04:00
{
2023-04-23 20:14:53 +04:00
throw new ArgumentException ( "Количество изделий в заказе должно быть больше 0" , nameof ( model . Count ) ) ;
2023-01-30 21:46:31 +04:00
}
2023-04-23 20:14:53 +04:00
if ( model . Sum < = 0 )
2023-03-12 17:46:52 +04:00
{
2023-04-23 20:14:53 +04:00
throw new ArgumentException ( "Суммарная стоимость заказа должна быть больше 0" , nameof ( model . Sum ) ) ;
2023-03-12 17:46:52 +04:00
}
2023-04-23 20:14:53 +04:00
if ( model . DateCreate > model . DateImplement )
2023-03-12 17:46:52 +04:00
{
2023-04-23 20:14:53 +04:00
throw new ArgumentException ( "Время создания заказа не может быть больше времени е г о выполнения" , nameof ( model . DateImplement ) ) ;
2023-01-30 21:46:31 +04:00
}
return true ;
}
2023-04-23 20:14:53 +04:00
private bool SetOrderStatus ( OrderBindingModel model , OrderStatus orderStatus )
2023-01-30 21:46:31 +04:00
{
2023-04-24 22:23:14 +04:00
// Находим статус заказа по е г о айди
2023-04-09 22:46:55 +04:00
var vmodel = _orderStorage . GetElement ( new ( ) { Id = model . Id } ) ;
if ( vmodel = = null )
2023-03-28 00:27:02 +04:00
{
2023-04-09 22:46:55 +04:00
throw new ArgumentNullException ( nameof ( model ) ) ;
2023-03-28 00:27:02 +04:00
}
2023-04-24 22:23:14 +04:00
if ( ( int ) vmodel . Status + 1 ! = ( int ) orderStatus & & ! ( vmodel . Status = = OrderStatus . О ж и д а е т с я & & orderStatus = = OrderStatus . Г о т о в ) )
2023-03-28 00:27:02 +04:00
{
2023-04-09 22:46:55 +04:00
throw new InvalidOperationException ( $"Попытка перевести заказ не в следующий статус: " +
$"Текущий статус: {vmodel.Status} \n" +
$"Планируемый статус: {orderStatus} \n" +
$"Доступный статус: {(OrderStatus)((int)vmodel.Status + 1)}" ) ;
2023-01-30 21:46:31 +04:00
}
2023-04-24 22:23:14 +04:00
if ( orderStatus = = OrderStatus . Г о т о в | | orderStatus = = OrderStatus . О ж и д а е т с я )
2023-01-30 21:46:31 +04:00
{
2023-04-23 20:14:53 +04:00
var vreinforced = _reinforcedStorage . GetElement ( new ( ) { Id = vmodel . ReinforcedId } ) ;
if ( vreinforced = = null | | ! _shopLogic . AddReinforcediesInShops ( vreinforced , vmodel . Count ) )
{
2023-04-24 22:23:14 +04:00
_logger . LogWarning ( $"Н е удалось заполнить магазины изделием '{vreinforced?.ReinforcedName ?? string.Empty}' из заказа {vmodel.Id}" ) ;
orderStatus = OrderStatus . О ж и д а е т с я ;
}
else
{
orderStatus = OrderStatus . Г о т о в ;
2023-04-23 20:14:53 +04:00
}
2023-01-30 21:46:31 +04:00
}
2023-04-09 22:46:55 +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 . ReinforcedId = vmodel . ReinforcedId ;
model . Sum = vmodel . Sum ;
model . Count = vmodel . Count ;
2023-04-22 16:17:59 +04:00
var result = _orderStorage . Update ( model ) ;
if ( result = = null )
2023-01-30 21:46:31 +04:00
{
_logger . LogWarning ( "Update operation failed" ) ;
return false ;
}
2023-04-22 16:17:59 +04:00
SendOrderStatusMail ( result . ClientId , $"Изменен статус заказа #{result.Id}" , $"Заказ #{model.Id} изменен статус на {result.Status}" ) ;
2023-01-30 21:46:31 +04:00
return true ;
}
2023-03-28 00:27:02 +04:00
2023-04-09 21:05:06 +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 ;
}
2023-04-22 16:17:59 +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 21:46:31 +04:00
}
}