PIbd-22_Chernyshev_G.J._30_.../GarmentFactoryBusinessLogic/BusinessLogics/OrderLogic.cs
2024-05-05 18:46:39 +04:00

187 lines
7.5 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 GarmentFactoryBusinessLogic.MailWorker;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.BusinessLogicsContracts;
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using GarmentFactoryDataModels.Enums;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace GarmentFactoryBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
//Хранение всех заказов
private readonly IOrderStorage _orderStorage;
private readonly AbstractMailWorker _mailWorker;
static readonly object _locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker)
{
_logger = logger;
_orderStorage = orderStorage;
_mailWorker = mailWorker;
}
public OrderViewModel? ReadElement(OrderSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", model.ClientId, model.Status, model.ImplementerId, model.DateFrom, model.DateTo, 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. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}",model?.ClientId, model?.Status, model?.ImplementerId, model?.DateFrom, model?.DateTo, 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;
}
//Проверка данных заказа при добавлении
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.Sum <= 0)
{
throw new ArgumentException("Сумма чека должна быть больше 0", nameof(model.Sum));
}
if (model.Count <= 0)
{
throw new ArgumentException("В чеке должен быть хотя бы 1 товар", nameof(model.Count));
}
if (model.DateComplete.HasValue && model.DateComplete < model.DateCreate)
{
throw new ArgumentException($"Дата выдачи заказа {model.DateComplete} не может быть раньше даты его создания {model.DateCreate}");
}
_logger.LogInformation("Order. Id: {Id}. Sum: {Sum}. TextileId: {TextileId}. TextileCount: {Count}", model.Id, model.Sum, model.TextileId, model.Count);
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Invalid order status");
return false;
}
model.Status = OrderStatus.Принят;
var order = _orderStorage.Insert(model);
if (order == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel
{
MailAddress = order.ClientEmail,
Subject = $"Новый заказ создан. Номер заказа - {order.Id}",
Text = $"Ваш заказ номер {order.Id} на текстиль {order.TextileName} от {order.DateCreate} на сумму {order.Sum} принят."
}));
return true;
}
//Общий метод изменения статуса заказа
private bool ChangeStatus(OrderBindingModel model, OrderStatus newStatus)
{
CheckModel(model, false);
var order = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (order == null)
{
throw new ArgumentNullException(nameof(order));
}
model.DateCreate = order.DateCreate;
model.TextileId = order.TextileId;
model.DateComplete = order.DateComplete;
model.Status = order.Status;
model.Count = order.Count;
model.Sum = order.Sum;
model.ClientId = order.ClientId;
if (!model.ImplementerId.HasValue)
{
model.ImplementerId = order.ImplementerId;
}
if (newStatus - model.Status == 1)
{
model.Status = newStatus;
if (model.Status == OrderStatus.Готов)
{
model.DateComplete = DateTime.Now;
}
if (_orderStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
//Отправка письма на почту
Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel
{
MailAddress = order.ClientEmail,
Subject = $"Изменение статуса заказа номер {order.Id}",
Text = $"У заказа номер {order.Id} изменен статус на {newStatus}"
}));
return true;
}
if (order.Status + 1 != newStatus)
{
_logger.LogWarning("Change status operation failed. Incorrect new status: {newStatus}. Current status: {currStatus}", newStatus, order.Status);
return false;
}
_logger.LogWarning("Changing status operation faled: current:{Status}: required:{newStatus}.", model.Status, newStatus);
throw new ArgumentException($"Невозможно присвоить статус {newStatus} заказу с текущим статусом {model.Status}");
}
//Перевод заказа в состояние выполнения
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.Выдан);
}
}
}