165 lines
7.2 KiB
C#
165 lines
7.2 KiB
C#
using CandyHouseBusinessLogic.OfficePackage;
|
||
using CandyHouseContracts.BusinessLogicContracts;
|
||
using CandyHouseContracts.DataModels;
|
||
using CandyHouseContracts.Exceptions;
|
||
using CandyHouseContracts.Extensions;
|
||
using CandyHouseContracts.StoragesContracts;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
namespace CandyHouseBusinessLogic.Implementations;
|
||
|
||
internal class ReportContract(
|
||
IProductStorageContract productStorageContract,
|
||
ISaleStorageContract saleStorageContract,
|
||
IClientDiscountStorageContract clientDiscountStorageContract,
|
||
BaseWordBuilder baseWordBuilder,
|
||
BaseExcelBuilder baseExcelBuilder,
|
||
BasePdfBuilder basePdfBuilder,
|
||
ILogger logger) : IReportContract
|
||
{
|
||
private readonly IProductStorageContract _productStorageContract = productStorageContract;
|
||
|
||
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
|
||
|
||
private readonly IClientDiscountStorageContract _clientDiscountStorageContract = clientDiscountStorageContract;
|
||
|
||
private readonly BaseWordBuilder _baseWordBuilder = baseWordBuilder;
|
||
|
||
private readonly BaseExcelBuilder _baseExcelBuilder = baseExcelBuilder;
|
||
|
||
private readonly BasePdfBuilder _basePdfBuilder = basePdfBuilder;
|
||
|
||
private readonly ILogger _logger = logger;
|
||
|
||
internal static readonly string[] documentHeader = ["Продукт", "Цена", "Дата"];
|
||
|
||
internal static readonly string[] tableHeader = ["Дата", "Сумма", "Скидка", "Продавец", "Товар", "Кол-во"];
|
||
|
||
public async Task<Stream> CreateDocumentProductHistoryPricesAsync(CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Create report ProductHistoryPrices");
|
||
var data = await GetDataByHistoryPricesAsync(ct);
|
||
return _baseWordBuilder
|
||
.AddHeader("История цен на продукцию")
|
||
.AddParagraph($"Сформировано на дату {DateTime.UtcNow}")
|
||
.AddTable([3000, 5000, 4000],
|
||
[
|
||
.. new List<string[]>() { documentHeader }.Union([
|
||
.. data.SelectMany(x =>
|
||
(new List<string[]>() { new string[] { x.ProductName, "", "" } }).Union(x.Prices.Select(y =>
|
||
new string[] { "", y.Split(" (")[0], y.Split(" (")[1].TrimEnd(')') })))
|
||
])
|
||
])
|
||
.Build();
|
||
}
|
||
|
||
public async Task<Stream> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish,
|
||
CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Create report SalesByPeriod from {dateStart} to {dateFinish}", dateStart, dateFinish);
|
||
var data = await GetDataBySalesAsync(dateStart, dateFinish, ct) ??
|
||
throw new InvalidOperationException("No found data");
|
||
return _baseExcelBuilder
|
||
.AddHeader("Продажи за период", 0, 6)
|
||
.AddParagraph($"c {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}", 2)
|
||
.AddTable([10, 10, 10, 10, 10, 10],
|
||
[
|
||
.. new List<string[]>() { tableHeader }.Union(data.SelectMany(x =>
|
||
(new List<string[]>()
|
||
{
|
||
new string[]
|
||
{
|
||
x.SaleDate.ToShortDateString(), x.Sum.ToString("N2"), x.Discount.ToString("N2"),
|
||
x.EmployeeFIO, "", ""
|
||
}
|
||
}).Union(x.Products!.Select(y => new string[]
|
||
{ "", "", "", "", y.ProductName, y.Count.ToString("N2") })).ToArray())).Union([
|
||
["Всего", data.Sum(x => x.Sum).ToString("N2"), data.Sum(x => x.Discount).ToString("N2"), "", "", ""]
|
||
])
|
||
])
|
||
.Build();
|
||
}
|
||
|
||
public async Task<Stream> CreateDocumentClientDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish,
|
||
CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Create report ClientDiscountByPeriod from {dateStart} to {dateFinish}", dateStart,
|
||
dateFinish);
|
||
var data = await GetDataByClientDiscountAsync(dateStart, dateFinish, ct) ??
|
||
throw new InvalidOperationException("No found data");
|
||
return _basePdfBuilder
|
||
.AddHeader("Скидочная ведомость")
|
||
.AddParagraph($"за период с {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}")
|
||
.AddPieChart("Начисления", [.. data.Select(x => (x.ClientFIO, x.TotalDiscount))])
|
||
.Build();
|
||
}
|
||
|
||
public Task<List<ProductHistoryPricesDataModel>> GetDataProductHistoryPricesAsync(CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Get data ProductHistoryPrices");
|
||
return GetDataByHistoryPricesAsync(ct);
|
||
}
|
||
|
||
public Task<List<SaleDataModel>> GetDataSaleByPeriodAsync(DateTime dateStart, DateTime dateFinish,
|
||
CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Get data SalesByPeriod from {dateStart} to {dateFinish}", dateStart, dateFinish);
|
||
return GetDataBySalesAsync(dateStart, dateFinish, ct);
|
||
}
|
||
|
||
public Task<List<ClientDiscountByPeriodDataModel>> GetDataClientDiscountByPeriodAsync(DateTime dateStart,
|
||
DateTime dateFinish, CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Get data ClientDiscountByPeriod from {dateStart} to {dateFinish}", dateStart,
|
||
dateFinish);
|
||
return GetDataByClientDiscountAsync(dateStart, dateFinish, ct);
|
||
}
|
||
|
||
private async Task<List<ProductHistoryPricesDataModel>> GetDataByHistoryPricesAsync(CancellationToken ct) =>
|
||
[
|
||
.. (await _productStorageContract.GetListAsync(ct))
|
||
.Select(async product => new
|
||
{
|
||
ProductName = product.ProductName,
|
||
History = await Task.Run(() => _productStorageContract.GetHistoryByProductId(product.Id))
|
||
}).Select(t => t.Result).Select(x => new ProductHistoryPricesDataModel
|
||
{
|
||
ProductName = x.ProductName,
|
||
Prices =
|
||
[
|
||
.. x.History.OrderByDescending(h => h.ChangeDate)
|
||
.Select(h => $"{h.OldPrice:N2} ({h.ChangeDate:dd.MM.yyyy})")
|
||
]
|
||
})
|
||
];
|
||
|
||
private async Task<List<SaleDataModel>> GetDataBySalesAsync(DateTime dateStart, DateTime dateFinish,
|
||
CancellationToken ct)
|
||
{
|
||
if (dateStart.IsDateNotOlder(dateFinish))
|
||
{
|
||
throw new IncorrectDatesException(dateStart, dateFinish);
|
||
}
|
||
|
||
return [.. (await _saleStorageContract.GetListAsync(dateStart, dateFinish, ct)).OrderBy(x => x.SaleDate)];
|
||
}
|
||
|
||
private async Task<List<ClientDiscountByPeriodDataModel>> GetDataByClientDiscountAsync(DateTime dateStart,
|
||
DateTime dateFinish, CancellationToken ct)
|
||
{
|
||
if (dateStart.IsDateNotOlder(dateFinish))
|
||
{
|
||
throw new IncorrectDatesException(dateStart, dateFinish);
|
||
}
|
||
|
||
return
|
||
[
|
||
.. (await _clientDiscountStorageContract.GetListAsync(dateStart, dateFinish, ct)).GroupBy(x => x.ClientFIO)
|
||
.Select(x => new ClientDiscountByPeriodDataModel
|
||
{
|
||
ClientFIO = x.Key, TotalDiscount = x.Sum(y => y.DiscountAmount),
|
||
FromPeriod = x.Min(y => y.DiscountDate), ToPeriod = x.Max(y => y.DiscountDate)
|
||
}).OrderBy(x => x.ClientFIO)
|
||
];
|
||
}
|
||
} |