Files
ChamomileProject/DaisiesBusinessLogic/Implementations/ReportContract.cs

149 lines
7.0 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 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();
}
}