Files
PIBD-23_Coursach_YouAreProg…/YouAreProgrammerShop/YAPBusinessLogic/Implementations/ReportBusinessLogicContract.cs
2025-10-02 19:41:13 +04:00

241 lines
10 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YAPBusinessLogic.OfficePackage;
using YAPContracts.BusinessLogicContracts;
using YAPContracts.StorageContracts;
using YAPDatabase.Implementations;
namespace YAPBusinessLogic.Implementations
{
internal class ReportBusinessLogicContract : IReportBusinessLogicContract
{
private readonly IProductStorageContract _productStorageContract;
private readonly IPurchaseStorageContract _purchaseStorageContract;
private readonly IProductSetStorageContract _productSetStorageContract;
private readonly IComponentStorageContract _componentStorageContract;
private readonly BasePdfBuilder _pdfBuilder;
public ReportBusinessLogicContract(IProductStorageContract productStorageContract, IPurchaseStorageContract purchaseStorageContract, IProductSetStorageContract productSetStorageContract, IComponentStorageContract componentStorageContract, BasePdfBuilder pdfBuilder)
{
_productStorageContract = productStorageContract;
_purchaseStorageContract = purchaseStorageContract;
_productSetStorageContract = productSetStorageContract;
_componentStorageContract = componentStorageContract;
_pdfBuilder = pdfBuilder;
}
/// <summary>
/// Список товаров по выбранным сборкам в формате текстового документа или электронной таблицы
/// </summary>
/// <param name="setsIds">Id соборок</param>
/// <param name="format">doc/xls</param>
public Stream MakeReportProductsByProductSets(List<string> setsIds, string format)
{
// Получаем продукты по сборкам
var products = _productStorageContract.GetListProductsByProductSet(setsIds);
if (string.Equals(format, "xls", StringComparison.OrdinalIgnoreCase))
{
var excel = new OpenXmlExcelBuilder();
excel.AddHeader("Products by Sets", 0, 4);
// таблица
var rows = new List<string[]>();
rows.Add(new[] { "Product", "Included in Sets" });
foreach (var prod in products)
{
var setNames = prod.Sets.Any()
? string.Join(", ", prod.Sets.Select(s => s.SetName))
: "No Sets.";
rows.Add(new[] { prod.Product?.Name ?? "-", setNames });
}
excel.AddTable([10, 10], rows);
return excel.Build();
}
else if (string.Equals(format, "doc", StringComparison.OrdinalIgnoreCase))
{
StringBuilder sb = new StringBuilder();
var word = new OpenXmlWordBuilder();
word.AddHeader("Products by Sets");
foreach (var prod in products)
{
word.AddParagraph($"Product: {prod.Product?.Name}");
sb.Append("Sets: ");
var setNames = prod.Sets.Any()
? string.Join(", ", prod.Sets.Select(s => s.SetName))
: "No Sets.";
sb.Append(setNames);
word.AddParagraph(sb.ToString());
sb.Clear();
}
return word.Build();
}
else
{
throw new ArgumentException("Only «doc» and «xls» formats are supported", nameof(format));
}
}
/// <summary>
/// Список сборок по выбранным товарам в формате текстового документа или электронной таблицы
/// </summary>
/// <param name="productIds">Id товаров</param>
/// <param name="format">doc/xls</param>
public Stream MakeReportProductSetsByProducts(List<string> productIds, string format)
{
// Получаем продукты по сборкам
var productSets = _productSetStorageContract.GetListProductSetsByProducts(productIds);
if (string.Equals(format, "xls", StringComparison.OrdinalIgnoreCase))
{
var excel = new OpenXmlExcelBuilder();
excel.AddHeader("Product Sets by Products", 0, 4);
var rows = new List<string[]>();
rows.Add(new[] { "Product Set", "Products" });
foreach (var set in productSets)
{
var productNames = set.Products.Any()
? string.Join(", ", set.Products.Select(p => p.Name))
: "Нет товаров";
rows.Add(new[] { set.Set?.SetName ?? "-", productNames });
}
excel.AddTable([10, 10], rows);
return excel.Build();
}
else if (string.Equals(format, "doc", StringComparison.OrdinalIgnoreCase))
{
StringBuilder sb = new StringBuilder();
var word = new OpenXmlWordBuilder();
word.AddHeader("Product Sets by Products");
foreach (var set in productSets)
{
word.AddParagraph($"Сборка: {set.Set?.SetName}");
sb.Append("Товары: ");
var productNames = set.Products.Any()
? string.Join(", ", set.Products.Select(p => p.Name))
: "Нет товаров";
sb.Append(productNames);
word.AddParagraph(sb.ToString());
sb.Clear();
}
return word.Build();
}
else
{
throw new ArgumentException("Only «doc» and «xls» formats are supported", nameof(format));
}
}
/// <summary>
/// Отчет по продажам за период с расшифровкой по комментариям и комплектющим
/// </summary>
/// <param name="dateStart">Начало периода</param>
/// <param name="dateEnd">Конец периода</param>
public Stream MakeReportByPurchases(DateTime dateStart, DateTime dateEnd)
{
_pdfBuilder.AddHeader("Purchases report");
var reportData = _purchaseStorageContract.GetDataForReport(dateStart, dateEnd);
_pdfBuilder.AddParagraph($"Period: {dateStart.ToLocalTime()} — {dateEnd.ToLocalTime()}");
foreach (var sale in reportData)
{
_pdfBuilder.AddParagraph($"----------------------------------");
_pdfBuilder.AddParagraph($"Purchase date: {sale.Purchase.PurchaseDate}");
_pdfBuilder.AddParagraph($"Total: {sale.Purchase.TotalPrice}");
_pdfBuilder.AddParagraph($"");
_pdfBuilder.AddParagraph($"Components");
if (sale.Components is { Count: > 0 })
{
_pdfBuilder.AddTable(
new[] { "Name", "Type" },
sale.Components.Select(p => new[] { p.Name, p.ComponentType.ToString() }).ToList()
);
}
else
{
_pdfBuilder.AddParagraph("No components found.");
}
_pdfBuilder.AddParagraph($"Comments");
if (sale.Comments is { Count: > 0 })
{
_pdfBuilder.AddTable(
new[] { "Text", "Date" },
sale.Comments.Select(p => new[] { p.Text, p.Date.ToString("dd.MM.yyyy") }).ToList()
);
}
else
{
_pdfBuilder.AddParagraph("No comments found.");
}
}
return _pdfBuilder.Build();
}
/// <summary>
/// Отчет по комплектующим за период с расшифровкой по покупкам и заказам
/// </summary>
/// <param name="dateStart">Начало периода</param>
/// <param name="dateEnd">Конец периода</param>
public Stream MakeReportByComponents(DateTime dateStart, DateTime dateEnd)
{
if (dateEnd < dateStart)
{
throw new ArgumentException("End date must be later than start date.");
}
_pdfBuilder.AddHeader("Components report");
var reportData = _componentStorageContract.GetDataForReport(dateStart, dateEnd);
_pdfBuilder.AddParagraph($"Period: {dateStart.ToLocalTime()} — {dateEnd.ToLocalTime()}");
foreach (var comp in reportData)
{
_pdfBuilder.AddParagraph($"----------------------------------");
_pdfBuilder.AddParagraph($"Name: {comp.Component.Name}");
_pdfBuilder.AddParagraph($"Type: {comp.Component.ComponentType}");
_pdfBuilder.AddParagraph($"");
_pdfBuilder.AddParagraph($"Purchases");
if (comp.Purchases is { Count: > 0 })
{
_pdfBuilder.AddTable(
new[] { "Date", "Sum" },
comp.Purchases.Select(p => new[] { p.PurchaseDate.ToString("MM/dd/yy"), p.TotalPrice.ToString() }).ToList()
);
}
else
{
_pdfBuilder.AddParagraph("No purchases found.");
}
_pdfBuilder.AddParagraph($"Orders");
if (comp.Orders is { Count: > 0 })
{
_pdfBuilder.AddTable(
new[] { "Date", "Dealer Name" },
comp.Orders.Select(p => new[] { p.OrderDate.ToString("dd.MM.yyyy"), p.DealerName }).ToList()
);
}
else
{
_pdfBuilder.AddParagraph("No orders found.");
}
}
return _pdfBuilder.Build();
}
}
}