149 lines
7.0 KiB
C#
149 lines
7.0 KiB
C#
using DaisiesBuisnessLogic.OfficePackage;
|
||
using DaisiesContracts.BuisnessLogicContracts;
|
||
using DaisiesContracts.DataModels;
|
||
using DaisiesContracts.Exceptions;
|
||
using DaisiesContracts.StoragesContracts;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
namespace DaisiesBuisnessLogic.Implementations;
|
||
|
||
public class ReportContract(IProductStorageContract productStorageContract, ILogger logger, BaseWordBuilder baseWordBuilder, ISaleStorageContract saleStorageContract,
|
||
IClientDiscountStorageContract discountStorageContract, BaseExcelBuilder baseExcelBuilder, BasePdfBuilder basePdfBuilder) : IReportContract
|
||
{
|
||
private readonly ILogger _logger = logger;
|
||
private readonly IProductStorageContract _productStorageContract = productStorageContract;
|
||
private readonly BaseWordBuilder _baseWordBuilder = baseWordBuilder;
|
||
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
|
||
private readonly IClientDiscountStorageContract _discountStorageContract = discountStorageContract;
|
||
private readonly BaseExcelBuilder _baseExcelBuilder = baseExcelBuilder;
|
||
private readonly BasePdfBuilder _basePdfBuilder = basePdfBuilder;
|
||
|
||
internal static readonly string[] tableHeader = ["Дата", "Сумма", "Скидка", "Продукт", "Кол-во"];
|
||
internal static readonly string[] documentHeader = ["Название продукта", "Цены", "Дата"];
|
||
|
||
public Task<List<ProductProductHistoryDataModel>> GetDataProductPricesByProductAsync(CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Get data ProductPricesByProduct");
|
||
return GetDataByHistoriesAsync(ct);
|
||
}
|
||
private async Task<List<ProductProductHistoryDataModel>> GetDataByHistoriesAsync(CancellationToken ct)
|
||
{
|
||
return [.. (await _productStorageContract.GetListAsync(ct)).GroupBy(x => x.ProductName).Select(x => new ProductProductHistoryDataModel {
|
||
ProductName = x.Key, HistoryPriceProducts = [.. x.Select(y => y.OldPrice.ToString())], Data = [.. x.Select(y => y.ChangeDate.ToString())] })];
|
||
}
|
||
|
||
public async Task<Stream> CreateDocumentProductPricesByProductAsync(CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Create report ProductPricesByProduct");
|
||
var data = await GetDataByHistoriesAsync(ct) ?? throw new InvalidOperationException("No found data");
|
||
var tableData = new List<string[]>
|
||
{
|
||
documentHeader
|
||
};
|
||
foreach (var product in data)
|
||
{
|
||
tableData.Add(new string[] { product.ProductName, "", "" });
|
||
|
||
var pairs = product.HistoryPriceProducts.Zip(product.Data,
|
||
(price, date) => new string[] { "", price, date });
|
||
|
||
tableData.AddRange(pairs);
|
||
}
|
||
return _baseWordBuilder
|
||
.AddHeader("Истории продукта по продуктам")
|
||
.AddParagraph($"Сформировано на дату {DateTime.Now}")
|
||
.AddTable(
|
||
widths: new[] { 3000, 3000, 3000 },
|
||
data: tableData
|
||
)
|
||
.Build();
|
||
}
|
||
|
||
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);
|
||
}
|
||
|
||
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)];
|
||
}
|
||
|
||
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");
|
||
|
||
var tableHeader = new string[] { "Дата", "ФИО", "Сумма", "Продукт", "Количество" };
|
||
|
||
return _baseExcelBuilder
|
||
.AddHeader("Заказы за период", 0, 5)
|
||
.AddParagraph($"c {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}", 2)
|
||
.AddTable(
|
||
[10, 10, 10, 10, 10],
|
||
[.. new List<string[]>() { tableHeader }
|
||
.Union(data.SelectMany(x =>
|
||
(new List<string[]>() {
|
||
new string[] {
|
||
x.SaleDate.ToShortDateString(),
|
||
x.BuyerFIO,
|
||
x.Sum.ToString("N2"),
|
||
"",
|
||
""
|
||
}
|
||
})
|
||
.Union(x.Products!.Select(y => new string[] {
|
||
"",
|
||
"",
|
||
"",
|
||
y.ProductName,
|
||
y.Count.ToString("N2")
|
||
}))
|
||
.ToArray()
|
||
)
|
||
.Union([[
|
||
"Всего",
|
||
"",
|
||
data.Sum(x => x.Sum).ToString("N2"),
|
||
"",
|
||
""
|
||
]]))
|
||
])
|
||
.Build();
|
||
}
|
||
|
||
public Task<List<ClientDiscountByPeriodDataModel>> GetDataDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||
{
|
||
logger.LogInformation("Get data DiscountByPeriod from {dateStart} to { dateFinish}", dateStart, dateFinish);
|
||
return GetDataByDiscountAsync(dateStart, dateFinish, ct);
|
||
}
|
||
|
||
private async Task<List<ClientDiscountByPeriodDataModel>> GetDataByDiscountAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||
{
|
||
if (dateStart.IsDateNotOlder(dateFinish))
|
||
{
|
||
throw new IncorrectDatesException(dateStart, dateFinish);
|
||
}
|
||
|
||
return [.. (await _discountStorageContract.GetListAsync(dateStart, dateFinish, ct)).GroupBy(x => x.BuyerFIO).Select(x => new ClientDiscountByPeriodDataModel
|
||
{
|
||
BuyerFIO = x.Key,
|
||
TotalDiscount = x.Sum(y => y.PersonalDiscount),
|
||
FromPeriod = x.Min(y => y.DiscountDate),
|
||
ToPeriod = x.Max(y => y.DiscountDate) }).OrderBy(x => x.BuyerFIO)];
|
||
}
|
||
|
||
public async Task<Stream> CreateDocumentDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Create report DiscountByPeriod from {dateStart} to { dateFinish} ", dateStart, dateFinish);
|
||
var data = await GetDataByDiscountAsync(dateStart, dateFinish, ct) ?? throw new InvalidOperationException("No found data");
|
||
return _basePdfBuilder.AddHeader("Bедомость Скидок").AddParagraph($"за период с {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}")
|
||
.AddPieChart("Начисления", [.. data.Select(x => (x.BuyerFIO, x.TotalDiscount))]).Build();
|
||
}
|
||
}
|