121 lines
7.3 KiB
C#
121 lines
7.3 KiB
C#
using Microsoft.Extensions.Localization;
|
||
using Microsoft.Extensions.Logging;
|
||
using CandyHouseBusinessLogic.OfficePackage;
|
||
using CandyHouseContracts.BusinessLogicsContracts;
|
||
using CandyHouseContracts.DataModels;
|
||
using CandyHouseContracts.Exceptions;
|
||
using CandyHouseContracts.Extensions;
|
||
using CandyHouseContracts.Resources;
|
||
using CandyHouseContracts.StoragesContracts;
|
||
|
||
namespace CandyHouseBusinessLogic.Implementations;
|
||
|
||
internal class ReportContract : IReportContract
|
||
{
|
||
private readonly IProductStorageContract _productStorageContract;
|
||
|
||
private readonly ISaleStorageContract _saleStorageContract;
|
||
|
||
private readonly IClientDiscountStorageContract _clientDiscountStorageContract;
|
||
|
||
private readonly BaseWordBuilder _baseWordBuilder;
|
||
|
||
private readonly BaseExcelBuilder _baseExcelBuilder;
|
||
|
||
private readonly BasePdfBuilder _basePdfBuilder;
|
||
|
||
private readonly IStringLocalizer<Messages> _localizer;
|
||
|
||
private readonly ILogger _logger;
|
||
|
||
internal readonly string[] _documentHeader;
|
||
|
||
internal readonly string[] _tableHeader;
|
||
|
||
public ReportContract(IProductStorageContract productStorageContract, ISaleStorageContract saleStorageContract, IClientDiscountStorageContract clientDiscountStorageContract, BaseWordBuilder baseWordBuilder, BaseExcelBuilder baseExcelBuilder, BasePdfBuilder basePdfBuilder, IStringLocalizer<Messages> localizer, ILogger logger)
|
||
{
|
||
_productStorageContract = productStorageContract;
|
||
_saleStorageContract = saleStorageContract;
|
||
_clientDiscountStorageContract = clientDiscountStorageContract;
|
||
_baseWordBuilder = baseWordBuilder;
|
||
_baseExcelBuilder = baseExcelBuilder;
|
||
_basePdfBuilder = basePdfBuilder;
|
||
_localizer = localizer;
|
||
_logger = logger;
|
||
_documentHeader = [_localizer["DocumentDocCaptionProduct"], _localizer["DocumentDocCaptionPrice"], _localizer["DocumentDocCaptionDate"]];
|
||
_tableHeader = [_localizer["DocumentExcelCaptionDate"], _localizer["DocumentExcelCaptionSum"],
|
||
_localizer["DocumentExcelCaptionDiscount"], _localizer["DocumentExcelCaptionEmployee"], _localizer["DocumentExcelCaptionProduct"], _localizer["DocumentExcelCaptionCount"]];
|
||
}
|
||
|
||
public async Task<Stream> CreateDocumentProductHistoryPricesAsync(CancellationToken ct)
|
||
{
|
||
_logger.LogInformation("Create report ProductHistoryPrices");
|
||
var data = await GetDataByHistoryPricesAsync(ct);
|
||
return _baseWordBuilder
|
||
.AddHeader(_localizer["DocumentDocHeader"])
|
||
.AddParagraph(string.Format(_localizer["DocumentDocSubHeader"], DateTime.Now))
|
||
.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(_localizer["DocumentExcelHeader"], 0, 6)
|
||
.AddParagraph(string.Format(_localizer["DocumentExcelSubHeader"], dateStart.ToLocalTime().ToShortDateString(), dateFinish.ToLocalTime().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(_localizer["DocumentPdfHeader"])
|
||
.AddParagraph(string.Format(_localizer["DocumentPdfSubHeader"], dateStart.ToLocalTime().ToShortDateString(), dateFinish.ToLocalTime().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, _localizer);
|
||
}
|
||
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, _localizer);
|
||
}
|
||
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)];
|
||
}
|
||
} |