Compare commits
3 Commits
LabWork05_
...
LabWork06_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccec9eb320 | ||
|
|
3d5bc1dfc0 | ||
|
|
1bfb035c63 |
@@ -13,7 +13,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.2" />
|
||||
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
using FurnitureAssemblyBusinessLogic.OfficePackage;
|
||||
using FurnitureAssemblyContracts.BusinessLogicsContracts;
|
||||
using FurnitureAssemblyContracts.DataModels;
|
||||
using FurnitureAssemblyContracts.Exceptions;
|
||||
using FurnitureAssemblyContracts.Extentions;
|
||||
using FurnitureAssemblyContracts.StoragesContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace FurnitureAssemblyBusinessLogic.Implementations;
|
||||
|
||||
public class ReportContract(IComponentStorageContract componentStorageContract, IManifacturingStorageContract manifacturingStorageContract, ISalaryStorageContract salaryStorageContract, BaseWordBuilder baseWordBuilder, BaseExcelBuilder baseExcelBuilder, BasePdfBuilder basePdfBuilder, ILogger logger) : IReportContract
|
||||
{
|
||||
private readonly IComponentStorageContract _componentStorageContract = componentStorageContract;
|
||||
private readonly IManifacturingStorageContract _manifacturingStorageContract = manifacturingStorageContract;
|
||||
private readonly ISalaryStorageContract _salaryStorageContract = salaryStorageContract;
|
||||
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 Task<List<ComponentHistoryDataModel>> GetDataComponentsHistoryAsync(CancellationToken ct)
|
||||
{
|
||||
_logger.LogInformation("Get data ComponentHistory");
|
||||
return GetDataByComponentsAsync(ct);
|
||||
}
|
||||
|
||||
public Task<List<ManifacturingFurnitureDataModel>> GetDataManifacturingByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
_logger.LogInformation("Get data SalesByPeriod from {dateStart} to { dateFinish}", dateStart, dateFinish);
|
||||
return GetDataByManifacturingAsync(dateStart, dateFinish, ct);
|
||||
}
|
||||
|
||||
public async Task<Stream> CreateDocumentComponentsHistoryAsync(CancellationToken ct)
|
||||
{
|
||||
_logger.LogInformation("Create report ComponentHistory");
|
||||
var data = await GetDataByComponentsAsync(ct) ?? throw new InvalidOperationException("No found data");
|
||||
return _baseWordBuilder
|
||||
.AddHeader("История изменений компонентов")
|
||||
.AddParagraph($"Сформировано на дату {DateTime.Now}")
|
||||
.AddTable([100, 100], [.. new List<string[]>() { documentHeader }.Union([.. data.SelectMany(x => (new List<string[]>() { new string[] { x.CurrentName, "" }}).Union(x.HistoryNames!.Select(y => new string[] { "", y }))).ToList()])])
|
||||
.Build();
|
||||
}
|
||||
|
||||
private async Task<List<ComponentHistoryDataModel>> GetDataByComponentsAsync(CancellationToken ct)
|
||||
=> [.. (await _componentStorageContract.GetListAsync(ct)).Select(c =>
|
||||
new ComponentHistoryDataModel { CurrentName = c.Name, Type = c.Type, HistoryNames = new List<string> { c.PrevName ?? "N/A", c.PrevPrevName ?? "N/A" }.Where(h => h != "N/A").ToList() }).ToList()];
|
||||
|
||||
private async Task<List<ManifacturingFurnitureDataModel>> GetDataByManifacturingAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
if (dateStart.IsDateNotOlder(dateFinish))
|
||||
{
|
||||
throw new IncorrectDatesException(dateStart, dateFinish);
|
||||
}
|
||||
return [.. (await _manifacturingStorageContract.GetListAsync(dateStart, dateFinish, ct)).OrderBy(x => x.ProductuionDate)];
|
||||
}
|
||||
|
||||
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 GetDataByManifacturingAsync(dateStart, dateFinish, ct) ?? throw new InvalidOperationException("No found data");
|
||||
return _baseExcelBuilder
|
||||
.AddHeader("Изготовление за период", 0, 5)
|
||||
.AddParagraph($"c {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}", 2)
|
||||
.AddTable([10, 10, 10, 10], [.. new List<string[]>() { tableHeader }.Union(data.SelectMany(x => (new List<string[]>()
|
||||
{ new string[] { x.ProductuionDate.ToShortDateString(), x.Count.ToString("N2"), x.WorkerFIO.ToString(), x.FurnitureName } })))
|
||||
.Union([["Всего", data.Sum(x=> x.Count).ToString("N2"), "", ""]])])
|
||||
.Build();
|
||||
}
|
||||
|
||||
public Task<List<WorkerSalaryByPeriodDataModel>> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
_logger.LogInformation("Get data SalaryByPeriod from {dateStart} to { dateFinish}", dateStart, dateFinish);
|
||||
return GetDataBySalaryAsync(dateStart, dateFinish, ct);
|
||||
}
|
||||
|
||||
private async Task<List<WorkerSalaryByPeriodDataModel>> GetDataBySalaryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
if (dateStart.IsDateNotOlder(dateFinish))
|
||||
{
|
||||
throw new IncorrectDatesException(dateStart, dateFinish);
|
||||
}
|
||||
return [.. (await _salaryStorageContract.GetListAsync(dateStart, dateFinish, ct)).GroupBy(x => x.WorkerId)
|
||||
.Select(x => new WorkerSalaryByPeriodDataModel { WorkerFIO = x.First().WorkerFIO, TotalSalary = x.Sum(y =>y.Salary), FromPeriod = x.Min(y => y.SalaryDate), ToPeriod = x.Max(y =>y.SalaryDate) })
|
||||
.OrderBy(x => x.WorkerFIO)];
|
||||
}
|
||||
|
||||
public async Task<Stream> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
_logger.LogInformation("Create report SalaryByPeriod from {dateStart} to { dateFinish}", dateStart, dateFinish);
|
||||
var data = await GetDataBySalaryAsync(dateStart, dateFinish, ct) ?? throw new InvalidOperationException("No found data");
|
||||
return _basePdfBuilder
|
||||
.AddHeader("Зарплатная ведомость")
|
||||
.AddParagraph($"за период с {dateStart.ToShortDateString()} по { dateFinish.ToShortDateString()}")
|
||||
.AddPieChart("Начисления", [.. data.Select(x => (x.WorkerFIO, x.TotalSalary))])
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageC
|
||||
private readonly IManifacturingStorageContract _manifacturingStorageContract = manifacturingStorageContract;
|
||||
private readonly IWorkerStorageContract _workerStorageContract = workerStorageContract;
|
||||
private readonly IConfigurationSalary _salaryConfiguration = сonfiguration;
|
||||
//используется ли
|
||||
private readonly Lock _lockObject = new();
|
||||
|
||||
public List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace FurnitureAssemblyBusinessLogic.OfficePackage;
|
||||
|
||||
public abstract class BaseExcelBuilder
|
||||
{
|
||||
public abstract BaseExcelBuilder AddHeader(string header, int startIndex, int count);
|
||||
public abstract BaseExcelBuilder AddParagraph(string text, int columnIndex);
|
||||
public abstract BaseExcelBuilder AddTable(int[] columnsWidths, List<string[]> data);
|
||||
public abstract Stream Build();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace FurnitureAssemblyBusinessLogic.OfficePackage;
|
||||
|
||||
public abstract class BasePdfBuilder
|
||||
{
|
||||
public abstract BasePdfBuilder AddHeader(string header);
|
||||
public abstract BasePdfBuilder AddParagraph(string text);
|
||||
public abstract BasePdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data);
|
||||
public abstract Stream Build();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace FurnitureAssemblyBusinessLogic.OfficePackage;
|
||||
|
||||
public abstract class BaseWordBuilder
|
||||
{
|
||||
public abstract BaseWordBuilder AddHeader(string header);
|
||||
public abstract BaseWordBuilder AddParagraph(string text);
|
||||
public abstract BaseWordBuilder AddTable(int[] widths, List<string[]> data);
|
||||
public abstract Stream Build();
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using MigraDoc.DocumentObjectModel;
|
||||
using MigraDoc.DocumentObjectModel.Shapes.Charts;
|
||||
using MigraDoc.Rendering;
|
||||
using System.Text;
|
||||
|
||||
namespace FurnitureAssemblyBusinessLogic.OfficePackage;
|
||||
|
||||
public class MigraDocPdfBuilder : BasePdfBuilder
|
||||
{
|
||||
private readonly Document _document;
|
||||
|
||||
public MigraDocPdfBuilder()
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
_document = new Document();
|
||||
DefineStyles();
|
||||
}
|
||||
|
||||
public override BasePdfBuilder AddHeader(string header)
|
||||
{
|
||||
_document.AddSection().AddParagraph(header, "NormalBold");
|
||||
return this;
|
||||
}
|
||||
|
||||
public override BasePdfBuilder AddParagraph(string text)
|
||||
{
|
||||
_document.LastSection.AddParagraph(text, "Normal");
|
||||
return this;
|
||||
}
|
||||
|
||||
public override BasePdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data)
|
||||
{
|
||||
if (data == null || data.Count == 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
var chart = new Chart(ChartType.Pie2D);
|
||||
var series = chart.SeriesCollection.AddSeries();
|
||||
series.Add(data.Select(x => x.Value).ToArray());
|
||||
|
||||
var xseries = chart.XValues.AddXSeries();
|
||||
xseries.Add(data.Select(x => x.Caption).ToArray());
|
||||
|
||||
chart.DataLabel.Type = DataLabelType.Percent;
|
||||
chart.DataLabel.Position = DataLabelPosition.OutsideEnd;
|
||||
|
||||
chart.Width = Unit.FromCentimeter(16);
|
||||
chart.Height = Unit.FromCentimeter(12);
|
||||
|
||||
chart.TopArea.AddParagraph(title);
|
||||
|
||||
chart.XAxis.MajorTickMark = TickMarkType.Outside;
|
||||
|
||||
chart.YAxis.MajorTickMark = TickMarkType.Outside;
|
||||
chart.YAxis.HasMajorGridlines = true;
|
||||
|
||||
chart.PlotArea.LineFormat.Width = 1;
|
||||
chart.PlotArea.LineFormat.Visible = true;
|
||||
|
||||
chart.TopArea.AddLegend();
|
||||
|
||||
_document.LastSection.Add(chart);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public override Stream Build()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var renderer = new PdfDocumentRenderer(true)
|
||||
{
|
||||
Document = _document
|
||||
};
|
||||
renderer.RenderDocument();
|
||||
renderer.PdfDocument.Save(stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
private void DefineStyles()
|
||||
{
|
||||
var style = _document.Styles.AddStyle("NormalBold", "Normal");
|
||||
style.Font.Bold = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using DocumentFormat.OpenXml;
|
||||
|
||||
namespace FurnitureAssemblyBusinessLogic.OfficePackage;
|
||||
|
||||
public class OpenXmlExcelBuilder : BaseExcelBuilder
|
||||
{
|
||||
private readonly SheetData _sheetData;
|
||||
|
||||
private readonly MergeCells _mergeCells;
|
||||
|
||||
private readonly Columns _columns;
|
||||
|
||||
private uint _rowIndex = 0;
|
||||
|
||||
public OpenXmlExcelBuilder()
|
||||
{
|
||||
_sheetData = new SheetData();
|
||||
_mergeCells = new MergeCells();
|
||||
_columns = new Columns();
|
||||
_rowIndex = 1;
|
||||
}
|
||||
|
||||
public override BaseExcelBuilder AddHeader(string header, int startIndex, int count)
|
||||
{
|
||||
CreateCell(startIndex, _rowIndex, header, StyleIndex.BoldTextWithoutBorder);
|
||||
for (int i = startIndex + 1; i < startIndex + count; ++i)
|
||||
{
|
||||
CreateCell(i, _rowIndex, "", StyleIndex.SimpleTextWithoutBorder);
|
||||
}
|
||||
|
||||
_mergeCells.Append(new MergeCell()
|
||||
{
|
||||
Reference =
|
||||
new StringValue($"{GetExcelColumnName(startIndex)}{_rowIndex}:{GetExcelColumnName(startIndex + count - 1)}{_rowIndex}")
|
||||
});
|
||||
|
||||
_rowIndex++;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override BaseExcelBuilder AddParagraph(string text, int columnIndex)
|
||||
{
|
||||
CreateCell(columnIndex, _rowIndex++, text, StyleIndex.SimpleTextWithoutBorder);
|
||||
return this;
|
||||
}
|
||||
|
||||
public override BaseExcelBuilder AddTable(int[] columnsWidths, List<string[]> data)
|
||||
{
|
||||
if (columnsWidths == null || columnsWidths.Length == 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(columnsWidths));
|
||||
}
|
||||
|
||||
if (data == null || data.Count == 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
}
|
||||
|
||||
if (data.Any(x => x.Length != columnsWidths.Length))
|
||||
{
|
||||
throw new InvalidOperationException("widths.Length != data.Length");
|
||||
}
|
||||
|
||||
uint counter = 1;
|
||||
int coef = 2;
|
||||
_columns.Append(columnsWidths.Select(x => new Column
|
||||
{
|
||||
Min = counter,
|
||||
Max = counter++,
|
||||
Width = x * coef,
|
||||
CustomWidth = true
|
||||
}));
|
||||
|
||||
for (var j = 0; j < data.First().Length; ++j)
|
||||
{
|
||||
CreateCell(j, _rowIndex, data.First()[j], StyleIndex.BoldTextWithBorder);
|
||||
}
|
||||
|
||||
_rowIndex++;
|
||||
for (var i = 1; i < data.Count - 1; ++i)
|
||||
{
|
||||
for (var j = 0; j < data[i].Length; ++j)
|
||||
{
|
||||
CreateCell(j, _rowIndex, data[i][j], StyleIndex.SimpleTextWithBorder);
|
||||
}
|
||||
|
||||
_rowIndex++;
|
||||
}
|
||||
|
||||
for (var j = 0; j < data.Last().Length; ++j)
|
||||
{
|
||||
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorder);
|
||||
}
|
||||
|
||||
_rowIndex++;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override Stream Build()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
using var spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
|
||||
var workbookpart = spreadsheetDocument.AddWorkbookPart();
|
||||
GenerateStyle(workbookpart);
|
||||
workbookpart.Workbook = new Workbook();
|
||||
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
|
||||
worksheetPart.Worksheet = new Worksheet();
|
||||
if (_columns.HasChildren)
|
||||
{
|
||||
worksheetPart.Worksheet.Append(_columns);
|
||||
}
|
||||
|
||||
worksheetPart.Worksheet.Append(_sheetData);
|
||||
var sheets = spreadsheetDocument.WorkbookPart!.Workbook.AppendChild(new Sheets());
|
||||
var sheet = new Sheet()
|
||||
{
|
||||
Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
|
||||
SheetId = 1,
|
||||
Name = "Лист 1"
|
||||
};
|
||||
|
||||
sheets.Append(sheet);
|
||||
if (_mergeCells.HasChildren)
|
||||
{
|
||||
worksheetPart.Worksheet.InsertAfter(_mergeCells, worksheetPart.Worksheet.Elements<SheetData>().First());
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
private static void GenerateStyle(WorkbookPart workbookPart)
|
||||
{
|
||||
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
|
||||
workbookStylesPart.Stylesheet = new Stylesheet();
|
||||
|
||||
var fonts = new Fonts() { Count = 2, KnownFonts = BooleanValue.FromBoolean(true) };
|
||||
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
|
||||
{
|
||||
FontSize = new FontSize() { Val = 11 },
|
||||
FontName = new FontName() { Val = "Calibri" },
|
||||
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
|
||||
FontScheme = new FontScheme() { Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor) }
|
||||
});
|
||||
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
|
||||
{
|
||||
FontSize = new FontSize() { Val = 11 },
|
||||
FontName = new FontName() { Val = "Calibri" },
|
||||
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
|
||||
FontScheme = new FontScheme() { Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor) },
|
||||
Bold = new Bold()
|
||||
});
|
||||
workbookStylesPart.Stylesheet.Append(fonts);
|
||||
|
||||
// Default Fill
|
||||
var fills = new Fills() { Count = 1 };
|
||||
fills.Append(new Fill
|
||||
{
|
||||
PatternFill = new PatternFill() { PatternType = new EnumValue<PatternValues>(PatternValues.None) }
|
||||
});
|
||||
workbookStylesPart.Stylesheet.Append(fills);
|
||||
|
||||
// Default Border
|
||||
var borders = new Borders() { Count = 2 };
|
||||
borders.Append(new Border
|
||||
{
|
||||
LeftBorder = new LeftBorder(),
|
||||
RightBorder = new RightBorder(),
|
||||
TopBorder = new TopBorder(),
|
||||
BottomBorder = new BottomBorder(),
|
||||
DiagonalBorder = new DiagonalBorder()
|
||||
});
|
||||
borders.Append(new Border
|
||||
{
|
||||
LeftBorder = new LeftBorder() { Style = BorderStyleValues.Thin },
|
||||
RightBorder = new RightBorder() { Style = BorderStyleValues.Thin },
|
||||
TopBorder = new TopBorder() { Style = BorderStyleValues.Thin },
|
||||
BottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin }
|
||||
});
|
||||
workbookStylesPart.Stylesheet.Append(borders);
|
||||
|
||||
// Default cell format and a date cell format
|
||||
var cellFormats = new CellFormats() { Count = 4 };
|
||||
cellFormats.Append(new CellFormat
|
||||
{
|
||||
NumberFormatId = 0,
|
||||
FormatId = 0,
|
||||
FontId = 0,
|
||||
BorderId = 0,
|
||||
FillId = 0,
|
||||
Alignment = new Alignment()
|
||||
{
|
||||
Horizontal = HorizontalAlignmentValues.Left,
|
||||
Vertical = VerticalAlignmentValues.Center,
|
||||
WrapText = true
|
||||
}
|
||||
});
|
||||
cellFormats.Append(new CellFormat
|
||||
{
|
||||
NumberFormatId = 0,
|
||||
FormatId = 0,
|
||||
FontId = 0,
|
||||
BorderId = 1,
|
||||
FillId = 0,
|
||||
Alignment = new Alignment()
|
||||
{
|
||||
Horizontal = HorizontalAlignmentValues.Left,
|
||||
Vertical = VerticalAlignmentValues.Center,
|
||||
WrapText = true
|
||||
}
|
||||
});
|
||||
cellFormats.Append(new CellFormat
|
||||
{
|
||||
NumberFormatId = 0,
|
||||
FormatId = 0,
|
||||
FontId = 1,
|
||||
BorderId = 0,
|
||||
FillId = 0,
|
||||
Alignment = new Alignment()
|
||||
{
|
||||
Horizontal = HorizontalAlignmentValues.Center,
|
||||
Vertical = VerticalAlignmentValues.Center,
|
||||
WrapText = true
|
||||
}
|
||||
});
|
||||
cellFormats.Append(new CellFormat
|
||||
{
|
||||
NumberFormatId = 0,
|
||||
FormatId = 0,
|
||||
FontId = 1,
|
||||
BorderId = 1,
|
||||
FillId = 0,
|
||||
Alignment = new Alignment()
|
||||
{
|
||||
Horizontal = HorizontalAlignmentValues.Center,
|
||||
Vertical = VerticalAlignmentValues.Center,
|
||||
WrapText = true
|
||||
}
|
||||
});
|
||||
workbookStylesPart.Stylesheet.Append(cellFormats);
|
||||
}
|
||||
|
||||
private enum StyleIndex
|
||||
{
|
||||
SimpleTextWithoutBorder = 0,
|
||||
SimpleTextWithBorder = 1,
|
||||
BoldTextWithoutBorder = 2,
|
||||
BoldTextWithBorder = 3
|
||||
}
|
||||
|
||||
private void CreateCell(int columnIndex, uint rowIndex, string text, StyleIndex styleIndex)
|
||||
{
|
||||
var columnName = GetExcelColumnName(columnIndex);
|
||||
var cellReference = columnName + rowIndex;
|
||||
var row = _sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex! == rowIndex);
|
||||
if (row == null)
|
||||
{
|
||||
row = new Row() { RowIndex = rowIndex };
|
||||
_sheetData.Append(row);
|
||||
}
|
||||
|
||||
var newCell = row.Elements<Cell>()
|
||||
.FirstOrDefault(c => c.CellReference != null && c.CellReference.Value == columnName + rowIndex);
|
||||
if (newCell == null)
|
||||
{
|
||||
Cell? refCell = null;
|
||||
foreach (Cell cell in row.Elements<Cell>())
|
||||
{
|
||||
if (cell.CellReference?.Value != null && cell.CellReference.Value.Length == cellReference.Length)
|
||||
{
|
||||
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
|
||||
{
|
||||
refCell = cell;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
newCell = new Cell() { CellReference = cellReference };
|
||||
row.InsertBefore(newCell, refCell);
|
||||
}
|
||||
|
||||
newCell.CellValue = new CellValue(text);
|
||||
newCell.DataType = CellValues.String;
|
||||
newCell.StyleIndex = (uint)styleIndex;
|
||||
}
|
||||
|
||||
private static string GetExcelColumnName(int columnNumber)
|
||||
{
|
||||
columnNumber += 1;
|
||||
int dividend = columnNumber;
|
||||
string columnName = string.Empty;
|
||||
int modulo;
|
||||
|
||||
while (dividend > 0)
|
||||
{
|
||||
modulo = (dividend - 1) % 26;
|
||||
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
|
||||
dividend = (dividend - modulo) / 26;
|
||||
}
|
||||
|
||||
return columnName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using DocumentFormat.OpenXml;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
|
||||
namespace FurnitureAssemblyBusinessLogic.OfficePackage;
|
||||
|
||||
public class OpenXmlWordBuilder : BaseWordBuilder
|
||||
{
|
||||
private readonly Document _document;
|
||||
|
||||
private readonly Body _body;
|
||||
|
||||
public OpenXmlWordBuilder()
|
||||
{
|
||||
_document = new Document();
|
||||
_body = _document.AppendChild(new Body());
|
||||
}
|
||||
|
||||
public override BaseWordBuilder AddHeader(string header)
|
||||
{
|
||||
var paragraph = _body.AppendChild(new Paragraph());
|
||||
var run = paragraph.AppendChild(new Run());
|
||||
run.AppendChild(new RunProperties(new Bold()));
|
||||
run.AppendChild(new Text(header));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public override BaseWordBuilder AddParagraph(string text)
|
||||
{
|
||||
var paragraph = _body.AppendChild(new Paragraph());
|
||||
var run = paragraph.AppendChild(new Run());
|
||||
run.AppendChild(new Text(text));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public override BaseWordBuilder AddTable(int[] widths, List<string[]> data)
|
||||
{
|
||||
if (widths == null || widths.Length == 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(widths));
|
||||
}
|
||||
|
||||
if (data == null || data.Count == 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
}
|
||||
|
||||
if (data.Any(x => x.Length != widths.Length))
|
||||
{
|
||||
throw new InvalidOperationException("widths.Length != data.Length");
|
||||
}
|
||||
|
||||
var table = new Table();
|
||||
table.AppendChild(new TableProperties(
|
||||
new TableBorders(
|
||||
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
|
||||
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
|
||||
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
|
||||
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
|
||||
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
|
||||
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 }
|
||||
)
|
||||
));
|
||||
|
||||
// Заголовок
|
||||
var tr = new TableRow();
|
||||
for (var j = 0; j < widths.Length; ++j)
|
||||
{
|
||||
tr.Append(new TableCell(
|
||||
new TableCellProperties(new TableCellWidth() { Width = widths[j].ToString() }),
|
||||
new Paragraph(new Run(new RunProperties(new Bold()), new Text(data.First()[j])))));
|
||||
}
|
||||
table.Append(tr);
|
||||
|
||||
// Данные
|
||||
table.Append(data.Skip(1).Select(x =>
|
||||
new TableRow(x.Select(y => new TableCell(new Paragraph(new Run(new Text(y))))))));
|
||||
|
||||
_body.Append(table);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public override Stream Build()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
using var wordDocument = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document);
|
||||
var mainPart = wordDocument.AddMainDocumentPart();
|
||||
mainPart.Document = _document;
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using FurnitureAssemblyContracts.AdapterContracts.OperationResponses;
|
||||
|
||||
namespace FurnitureAssemblyContracts.AdapterContracts;
|
||||
|
||||
public interface IReportAdapter
|
||||
{
|
||||
Task<ReportOperationResponse> GetDataComponentsHistoryAsync(CancellationToken ct);
|
||||
Task<ReportOperationResponse> GetDataManifacturingByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
Task<ReportOperationResponse> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
Task<ReportOperationResponse> CreateDocumentComponentHistoryAsync(CancellationToken ct);
|
||||
Task<ReportOperationResponse> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
Task<ReportOperationResponse> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FurnitureAssemblyContracts.DataModels;
|
||||
using FurnitureAssemblyContracts.Infrastructure;
|
||||
using FurnitureAssemblyContracts.ViewModels;
|
||||
|
||||
namespace FurnitureAssemblyContracts.AdapterContracts.OperationResponses;
|
||||
|
||||
public class ReportOperationResponse : OperationResponse
|
||||
{
|
||||
public static ReportOperationResponse OK(List<ComponentHistoryViewModel> data) => OK<ReportOperationResponse, List<ComponentHistoryViewModel>>(data);
|
||||
public static ReportOperationResponse OK(List<ManifacturingFurnitureViewModel> data) => OK<ReportOperationResponse, List<ManifacturingFurnitureViewModel>>(data);
|
||||
public static ReportOperationResponse OK(List<WorkerSalaryByPeriodViewModel> data) => OK<ReportOperationResponse, List<WorkerSalaryByPeriodViewModel>>(data);
|
||||
public static ReportOperationResponse OK(Stream data, string fileName) => OK<ReportOperationResponse, Stream>(data, fileName);
|
||||
public static ReportOperationResponse BadRequest(string message) => BadRequest<ReportOperationResponse>(message);
|
||||
public static ReportOperationResponse InternalServerError(string message) => InternalServerError<ReportOperationResponse>(message);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using FurnitureAssemblyContracts.DataModels;
|
||||
|
||||
namespace FurnitureAssemblyContracts.BusinessLogicsContracts;
|
||||
|
||||
public interface IReportContract
|
||||
{
|
||||
Task<List<ComponentHistoryDataModel>> GetDataComponentsHistoryAsync(CancellationToken ct);
|
||||
Task<List<ManifacturingFurnitureDataModel>> GetDataManifacturingByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
Task<List<WorkerSalaryByPeriodDataModel>> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
Task<Stream> CreateDocumentComponentsHistoryAsync(CancellationToken ct);
|
||||
Task<Stream> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
Task<Stream> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using FurnitureAssemblyContracts.Enums;
|
||||
|
||||
namespace FurnitureAssemblyContracts.DataModels;
|
||||
public class ComponentHistoryDataModel
|
||||
{
|
||||
public required string CurrentName { get; set; }
|
||||
public required ComponentType Type { get; set; }
|
||||
public List<string>? HistoryNames { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace FurnitureAssemblyContracts.DataModels;
|
||||
|
||||
public class WorkerSalaryByPeriodDataModel
|
||||
{
|
||||
public required string WorkerFIO { get; set; }
|
||||
public double TotalSalary { get; set; }
|
||||
public DateTime FromPeriod { get; set; }
|
||||
public DateTime ToPeriod { get; set; }
|
||||
}
|
||||
@@ -10,6 +10,8 @@ public class OperationResponse
|
||||
|
||||
protected object? Result { get; set; }
|
||||
|
||||
protected string? FileName { get; set; }
|
||||
|
||||
public IActionResult GetResponse(HttpRequest request, HttpResponse response)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
@@ -19,12 +21,22 @@ public class OperationResponse
|
||||
{
|
||||
return new StatusCodeResult((int)StatusCode);
|
||||
}
|
||||
if (Result is Stream stream)
|
||||
{
|
||||
return new FileStreamResult(stream, "application/octetstream")
|
||||
{
|
||||
FileDownloadName = FileName
|
||||
};
|
||||
}
|
||||
return new ObjectResult(Result);
|
||||
}
|
||||
|
||||
protected static TResult OK<TResult, TData>(TData data) where TResult :
|
||||
OperationResponse, new() => new() { StatusCode = HttpStatusCode.OK, Result = data };
|
||||
|
||||
protected static TResult OK<TResult, TData>(TData data, string fileName) where TResult : OperationResponse, new()
|
||||
=> new() { StatusCode = HttpStatusCode.OK, Result = data, FileName = fileName };
|
||||
|
||||
protected static TResult NoContent<TResult>() where TResult : OperationResponse, new() => new() { StatusCode = HttpStatusCode.NoContent };
|
||||
|
||||
protected static TResult BadRequest<TResult>(string? errorMessage = null)
|
||||
|
||||
@@ -8,6 +8,7 @@ public interface IComponentStorageContract
|
||||
ComponentDataModel? GetElementById(string id);
|
||||
ComponentDataModel? GetElementByName(string name);
|
||||
ComponentDataModel? GetElementByOldName(string name);
|
||||
Task<List<ComponentDataModel>> GetListAsync(CancellationToken ct);
|
||||
void AddElement(ComponentDataModel manufacturerDataModel);
|
||||
void UpdElement(ComponentDataModel manufacturerDataModel);
|
||||
void DelElement(string id);
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace FurnitureAssemblyContracts.StoragesContracts;
|
||||
public interface IManifacturingStorageContract
|
||||
{
|
||||
List<ManifacturingFurnitureDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null, string? workerId = null, string? furnitureId = null);
|
||||
Task<List<ManifacturingFurnitureDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct);
|
||||
ManifacturingFurnitureDataModel? GetElementById(string id);
|
||||
void AddElement(ManifacturingFurnitureDataModel manifacturingFurnitureDataModel);
|
||||
void UpdElement(ManifacturingFurnitureDataModel manifacturingFurnitureDataModel);
|
||||
|
||||
@@ -5,5 +5,6 @@ namespace FurnitureAssemblyContracts.StoragesContracts;
|
||||
public interface ISalaryStorageContract
|
||||
{
|
||||
List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? workerId = null);
|
||||
Task<List<SalaryDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct);
|
||||
void AddElement(SalaryDataModel salaryDataModel);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using FurnitureAssemblyContracts.Enums;
|
||||
|
||||
namespace FurnitureAssemblyContracts.ViewModels;
|
||||
|
||||
public class ComponentHistoryViewModel
|
||||
{
|
||||
public required string CurrentName { get; set; }
|
||||
public required ComponentType Type { get; set; }
|
||||
public List<string>? HistoryNames { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace FurnitureAssemblyContracts.ViewModels;
|
||||
|
||||
public class WorkerSalaryByPeriodViewModel
|
||||
{
|
||||
public required string WorkerFIO { get; set; }
|
||||
public double TotalSalary { get; set; }
|
||||
public DateTime FromPeriod { get; set; }
|
||||
public DateTime ToPeriod { get; set; }
|
||||
}
|
||||
@@ -36,6 +36,19 @@ public class ComponentStorageContract : IComponentStorageContract
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<ComponentDataModel>> GetListAsync(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return [.. await _dbContext.Components.Select(x => _mapper.Map<ComponentDataModel>(x)).ToListAsync(ct)];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ComponentDataModel? GetElementById(string id)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -52,6 +52,20 @@ public class ManifacturingStorageContract : IManifacturingStorageContract
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<ManifacturingFurnitureDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return [.. await _dbContext.Manufacturing.Include(x => x.Worker).Include(x => x.Furniture).Where(x => x.ProductuionDate >= startDate && x.ProductuionDate < endDate)
|
||||
.Select(x => _mapper.Map<ManifacturingFurnitureDataModel>(x)).ToListAsync(ct)];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ManifacturingFurnitureDataModel? GetElementById(string id)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -42,6 +42,19 @@ public class SalaryStorageContract : ISalaryStorageContract
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<SalaryDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return [.. await _dbContext.Salaries.Include(x => x.Worker).Where(x => x.SalaryDate >= startDate && x.SalaryDate <= endDate).Select(x => _mapper.Map<SalaryDataModel>(x)).ToListAsync(ct)];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddElement(SalaryDataModel salaryDataModel)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
using FurnitureAssemblyBusinessLogic.Implementations;
|
||||
using FurnitureAssemblyBusinessLogic.OfficePackage;
|
||||
using FurnitureAssemblyContracts.DataModels;
|
||||
using FurnitureAssemblyContracts.Enums;
|
||||
using FurnitureAssemblyContracts.Exceptions;
|
||||
using FurnitureAssemblyContracts.Infrastructure.PostConfigurations;
|
||||
using FurnitureAssemblyContracts.StoragesContracts;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
|
||||
namespace FurnitureAssemblyTests.BusinessLogicContractsTests;
|
||||
|
||||
[TestFixture]
|
||||
internal class ReportContractTests
|
||||
{
|
||||
private ReportContract _reportContract;
|
||||
private Mock<IComponentStorageContract> _componentStorageContract;
|
||||
private Mock<IManifacturingStorageContract> _manifactiringStorageContract;
|
||||
private Mock<ISalaryStorageContract> _salaryStorageContract;
|
||||
private Mock<BaseWordBuilder> _baseWordBuilder;
|
||||
private Mock<BaseExcelBuilder> _baseExcelBuilder;
|
||||
private Mock<BasePdfBuilder> _basePdfBuilder;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_componentStorageContract = new Mock<IComponentStorageContract>();
|
||||
_manifactiringStorageContract = new Mock<IManifacturingStorageContract>();
|
||||
_salaryStorageContract = new Mock<ISalaryStorageContract>();
|
||||
_baseWordBuilder = new Mock<BaseWordBuilder>();
|
||||
_baseExcelBuilder = new Mock<BaseExcelBuilder>();
|
||||
_basePdfBuilder = new Mock<BasePdfBuilder>();
|
||||
_reportContract = new ReportContract(
|
||||
_componentStorageContract.Object,
|
||||
_manifactiringStorageContract.Object,
|
||||
_salaryStorageContract.Object,
|
||||
_baseWordBuilder.Object,
|
||||
_baseExcelBuilder.Object,
|
||||
_basePdfBuilder.Object,
|
||||
Mock.Of<ILogger>());
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_componentStorageContract.Reset();
|
||||
_manifactiringStorageContract.Reset();
|
||||
_salaryStorageContract.Reset();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetDataComponentsHistoryAsync_ReturnsCorrectData()
|
||||
{
|
||||
// Arrange
|
||||
var components = new List<ComponentDataModel>
|
||||
{
|
||||
new("1", "Component1", ComponentType.Handle, "OldName1", "VeryOldName1"),
|
||||
new("2", "Component2", ComponentType.Panel, null, null),
|
||||
new("3", "Component3", ComponentType.Legs, "OldName3", null)
|
||||
};
|
||||
_componentStorageContract.Setup(x => x.GetListAsync(It.IsAny<CancellationToken>())).ReturnsAsync(components);
|
||||
// Act
|
||||
var data = await _reportContract.GetDataComponentsHistoryAsync(CancellationToken.None);
|
||||
// Assert
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data.Count, Is.EqualTo(3));
|
||||
var first = data[0];
|
||||
Assert.That(first.CurrentName, Is.EqualTo("Component1"));
|
||||
Assert.That(first.HistoryNames, Is.EquivalentTo(new[] { "OldName1", "VeryOldName1" }));
|
||||
var second = data[1];
|
||||
Assert.That(second.CurrentName, Is.EqualTo("Component2"));
|
||||
Assert.That(second.HistoryNames, Is.Empty);
|
||||
var third = data[2];
|
||||
Assert.That(third.CurrentName, Is.EqualTo("Component3"));
|
||||
Assert.That(third.HistoryNames, Is.EquivalentTo(new[] { "OldName3" }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetDataProductsByManufacturer_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
_componentStorageContract.Setup(x => x.GetListAsync(It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<ComponentDataModel>()));
|
||||
//Act
|
||||
var data = await
|
||||
_reportContract.GetDataComponentsHistoryAsync(CancellationToken.None);
|
||||
//Assert
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
_componentStorageContract.Verify(x => x.GetListAsync(It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CreateDocumentProductsByManufacturer_ShouldeSuccess_Test()
|
||||
{
|
||||
// Arrange
|
||||
var components = new List<ComponentDataModel>
|
||||
{
|
||||
new("1", "Component1", ComponentType.Panel, "OldName1", null)
|
||||
};
|
||||
_componentStorageContract.Setup(x => x.GetListAsync(It.IsAny<CancellationToken>())).ReturnsAsync(components);
|
||||
_baseWordBuilder.Setup(x => x.AddHeader(It.IsAny<string>())).Returns(_baseWordBuilder.Object);
|
||||
_baseWordBuilder.Setup(x => x.AddParagraph(It.IsAny<string>())).Returns(_baseWordBuilder.Object);
|
||||
_baseWordBuilder.Setup(x => x.AddTable(It.IsAny<int[]>(), It.IsAny<List<string[]>>())).Returns(_baseWordBuilder.Object);
|
||||
_baseWordBuilder.Setup(x => x.Build()).Returns(new MemoryStream());
|
||||
// Act
|
||||
var result = await _reportContract.CreateDocumentComponentsHistoryAsync(CancellationToken.None);
|
||||
// Assert
|
||||
Assert.That(result, Is.Not.Null);
|
||||
_baseWordBuilder.Verify(x => x.AddHeader("История изменений компонентов"), Times.Once);
|
||||
_baseWordBuilder.Verify(x => x.AddTable(
|
||||
It.Is<int[]>(w => w.SequenceEqual(new[] { 100, 100 })),
|
||||
It.Is<List<string[]>>(d =>
|
||||
d.Count == 3 &&
|
||||
d[1].SequenceEqual(new[] { "Component1", "" }) &&
|
||||
d[2].SequenceEqual(new[] { "", "OldName1" }))),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetDataManifacturingsByPeriod_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var furniture = new FurnitureDataModel(Guid.NewGuid().ToString(), "test", 5, []);
|
||||
_manifactiringStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<ManifacturingFurnitureDataModel>()
|
||||
{
|
||||
new(Guid.NewGuid().ToString(), furniture.Id, 5, null),
|
||||
new(Guid.NewGuid().ToString(), furniture.Id, 5, null)
|
||||
}));
|
||||
//Act
|
||||
var data = await _reportContract.GetDataManifacturingByPeriodAsync(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow, CancellationToken.None);
|
||||
//Assert
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
_manifactiringStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetDataManifacturingsByPeriod_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
_manifactiringStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<ManifacturingFurnitureDataModel>()));
|
||||
//Act
|
||||
var data = await _reportContract.GetDataManifacturingByPeriodAsync(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow, CancellationToken.None);
|
||||
//Assert
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
_manifactiringStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDataManifacturingsByPeriod_WhenIncorrectDates_ShouldFail_Test()
|
||||
{
|
||||
//Arrange
|
||||
var date = DateTime.UtcNow;
|
||||
//Act&Assert
|
||||
Assert.That(async () => await _reportContract.GetDataManifacturingByPeriodAsync(date, date, CancellationToken.None), Throws.TypeOf<IncorrectDatesException>());
|
||||
Assert.That(async () => await _reportContract.GetDataManifacturingByPeriodAsync(date, DateTime.UtcNow.AddDays(-1), CancellationToken.None), Throws.TypeOf<IncorrectDatesException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDataByManifacturingsByPeriod_WhenStorageThrowError_ShouldFail_Test()
|
||||
{
|
||||
//Arrange
|
||||
_manifactiringStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
//Act&Assert
|
||||
Assert.That(async () => await _reportContract.GetDataManifacturingByPeriodAsync(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow, CancellationToken.None), Throws.TypeOf<StorageException>());
|
||||
_manifactiringStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CreateDocumentSalesByPeriod_ShouldeSuccess_Test()
|
||||
{
|
||||
// Arrange
|
||||
var furniture = new FurnitureDataModel(Guid.NewGuid().ToString(), "test", 5, []);
|
||||
var manufacturings = new List<ManifacturingFurnitureDataModel>
|
||||
{
|
||||
new(Guid.NewGuid().ToString(), furniture.Id, 5, null),
|
||||
new(Guid.NewGuid().ToString(), furniture.Id, 5, null),
|
||||
new(Guid.NewGuid().ToString(), furniture.Id, 5, null)
|
||||
};
|
||||
_manifactiringStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).ReturnsAsync(manufacturings);
|
||||
_baseExcelBuilder.Setup(x => x.AddHeader(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>())).Returns(_baseExcelBuilder.Object);
|
||||
_baseExcelBuilder.Setup(x => x.AddParagraph(It.IsAny<string>(), It.IsAny<int>())).Returns(_baseExcelBuilder.Object);
|
||||
_baseExcelBuilder.Setup(x => x.AddTable(It.IsAny<int[]>(), It.IsAny<List<string[]>>())).Returns(_baseExcelBuilder.Object);
|
||||
_baseExcelBuilder.Setup(x => x.Build()).Returns(new MemoryStream());
|
||||
var countRows = 0;
|
||||
string[] firstRow = [];
|
||||
string[] secondRow = [];
|
||||
_baseExcelBuilder.Setup(x => x.AddTable(It.IsAny<int[]>(), It.IsAny<List<string[]>>()))
|
||||
.Callback((int[] widths, List<string[]> data) =>
|
||||
{
|
||||
countRows = data.Count;
|
||||
firstRow = data[0];
|
||||
secondRow = data[1];
|
||||
}).Returns(_baseExcelBuilder.Object);
|
||||
// Act
|
||||
var data = await _reportContract.CreateDocumentSalesByPeriodAsync(DateTime.Now.AddDays(-1), DateTime.Now, CancellationToken.None);
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(countRows, Is.EqualTo(5));
|
||||
Assert.That(firstRow, Is.Not.EqualTo(default));
|
||||
Assert.That(secondRow, Is.Not.EqualTo(default));
|
||||
});
|
||||
Assert.That(data, Is.Not.Null);
|
||||
_manifactiringStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
_baseExcelBuilder.Verify(x => x.AddHeader(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>()), Times.Once);
|
||||
_baseExcelBuilder.Verify(x => x.AddParagraph(It.IsAny<string>(), It.IsAny<int>()), Times.Once);
|
||||
_baseExcelBuilder.Verify(x => x.AddTable(It.IsAny<int[]>(), It.IsAny<List<string[]>>()), Times.Once);
|
||||
_baseExcelBuilder.Verify(x => x.Build(), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetDataSalaryByPeriod_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var startDate = DateTime.UtcNow.AddDays(-20);
|
||||
var endDate = DateTime.UtcNow.AddDays(5);
|
||||
var worker1 = new WorkerDataModel(Guid.NewGuid().ToString(), "Иванов И.И.", Guid.NewGuid().ToString(), DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddDays(-3), false, new PostConfiguration());
|
||||
var worker2 = new WorkerDataModel(Guid.NewGuid().ToString(), "Ванов И.И.", Guid.NewGuid().ToString(), DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddDays(-3), false, new PostConfiguration());
|
||||
_salaryStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<SalaryDataModel>()
|
||||
{
|
||||
new(worker1.Id, DateTime.UtcNow.AddDays(-10), 100, worker1),
|
||||
new(worker1.Id, endDate, 1000, worker1),
|
||||
new(worker1.Id, startDate, 1000, worker1),
|
||||
new(worker2.Id, DateTime.UtcNow.AddDays(-10), 100, worker2),
|
||||
new(worker2.Id, DateTime.UtcNow.AddDays(-5), 200, worker2)
|
||||
}));
|
||||
//Act
|
||||
var data = await _reportContract.GetDataSalaryByPeriodAsync(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow, CancellationToken.None);
|
||||
//Assert
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
var worker1Salary = data.First(x => x.WorkerFIO == worker1.FIO);
|
||||
Assert.That(worker1Salary, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(worker1Salary.TotalSalary, Is.EqualTo(2100));
|
||||
Assert.That(worker1Salary.FromPeriod, Is.EqualTo(startDate));
|
||||
Assert.That(worker1Salary.ToPeriod, Is.EqualTo(endDate));
|
||||
});
|
||||
var worker2Salary = data.First(x => x.WorkerFIO == worker2.FIO);
|
||||
Assert.That(worker2Salary, Is.Not.Null);
|
||||
Assert.That(worker2Salary.TotalSalary, Is.EqualTo(300));
|
||||
_salaryStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetDataSalaryByPeriod_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
_salaryStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<SalaryDataModel>()));
|
||||
//Act
|
||||
var data = await _reportContract.GetDataSalaryByPeriodAsync(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow, CancellationToken.None);
|
||||
//Assert
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
_salaryStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDataSalaryByPeriod_WhenIncorrectDates_ShouldFail_Test()
|
||||
{
|
||||
//Arrange
|
||||
var date = DateTime.UtcNow;
|
||||
//Act&Assert
|
||||
Assert.That(async () => await _reportContract.GetDataSalaryByPeriodAsync(date, date, CancellationToken.None), Throws.TypeOf<IncorrectDatesException>());
|
||||
Assert.That(async () => await _reportContract.GetDataSalaryByPeriodAsync(date, DateTime.UtcNow.AddDays(-1), CancellationToken.None), Throws.TypeOf<IncorrectDatesException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDataSalaryByPeriod_WhenStorageThrowError_ShouldFail_Test()
|
||||
{
|
||||
//Arrange
|
||||
_salaryStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Throws(new StorageException(new InvalidOperationException()));
|
||||
//Act&Assert
|
||||
Assert.That(async () => await _reportContract.GetDataSalaryByPeriodAsync(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow, CancellationToken.None), Throws.TypeOf<StorageException>());
|
||||
_salaryStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CreateDocumentSalaryByPeriod_ShouldeSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var startDate = DateTime.UtcNow.AddDays(-20);
|
||||
var endDate = DateTime.UtcNow.AddDays(5);
|
||||
var worker1 = new WorkerDataModel(Guid.NewGuid().ToString(), "Ванов И.И.", Guid.NewGuid().ToString(), DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddDays(-3), false, new PostConfiguration());
|
||||
var worker2 = new WorkerDataModel(Guid.NewGuid().ToString(), "Иванов И.И.", Guid.NewGuid().ToString(), DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddDays(-3), false, new PostConfiguration());
|
||||
_salaryStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<SalaryDataModel>()
|
||||
{
|
||||
new(worker1.Id, DateTime.UtcNow.AddDays(-10), 100, worker1),
|
||||
new(worker1.Id, endDate, 1000, worker1),
|
||||
new(worker1.Id, startDate, 1000, worker1),
|
||||
new(worker2.Id, DateTime.UtcNow.AddDays(-10), 100, worker2),
|
||||
new(worker2.Id, DateTime.UtcNow.AddDays(-5), 200, worker2)
|
||||
}));
|
||||
_basePdfBuilder.Setup(x => x.AddHeader(It.IsAny<string>())).Returns(_basePdfBuilder.Object);
|
||||
_basePdfBuilder.Setup(x => x.AddParagraph(It.IsAny<string>())).Returns(_basePdfBuilder.Object);
|
||||
var countRows = 0;
|
||||
(string, double) firstRow = default;
|
||||
(string, double) secondRow = default;
|
||||
_basePdfBuilder.Setup(x => x.AddPieChart(It.IsAny<string>(), It.IsAny<List<(string, double)>>()))
|
||||
.Callback((string header, List<(string, double)> data) =>
|
||||
{
|
||||
countRows = data.Count;
|
||||
firstRow = data[0];
|
||||
secondRow = data[1];
|
||||
})
|
||||
.Returns(_basePdfBuilder.Object);
|
||||
//Act
|
||||
var data = await _reportContract.CreateDocumentSalaryByPeriodAsync(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow, CancellationToken.None);
|
||||
//Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(countRows, Is.EqualTo(2));
|
||||
Assert.That(firstRow, Is.Not.EqualTo(default));
|
||||
Assert.That(secondRow, Is.Not.EqualTo(default));
|
||||
});
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(firstRow.Item1, Is.EqualTo(worker1.FIO));
|
||||
Assert.That(firstRow.Item2, Is.EqualTo(2100));
|
||||
Assert.That(secondRow.Item1, Is.EqualTo(worker2.FIO));
|
||||
Assert.That(secondRow.Item2, Is.EqualTo(300));
|
||||
});
|
||||
_salaryStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
_basePdfBuilder.Verify(x => x.AddHeader(It.IsAny<string>()), Times.Once);
|
||||
_basePdfBuilder.Verify(x => x.AddParagraph(It.IsAny<string>()), Times.Once);
|
||||
_basePdfBuilder.Verify(x => x.AddPieChart(It.IsAny<string>(), It.IsAny<List<(string, double)>>()), Times.Once);
|
||||
_basePdfBuilder.Verify(x => x.Build(), Times.Once);
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,26 @@ internal class ComponentStorageContractTests : BaseStorageContractTest
|
||||
Assert.That(list, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Try_GetListAsync_WhenHaveRecords_Test()
|
||||
{
|
||||
var component = FurnitureAssemblyDbContext.InsertComponentToDatabaseAndReturn(Guid.NewGuid().ToString(), "Component 1");
|
||||
FurnitureAssemblyDbContext.InsertComponentToDatabaseAndReturn(Guid.NewGuid().ToString(), "Component 2");
|
||||
FurnitureAssemblyDbContext.InsertComponentToDatabaseAndReturn(name: "Component 3");
|
||||
var list = await _componentStorageContract.GetListAsync(CancellationToken.None);
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Has.Count.EqualTo(3));
|
||||
AssertElement(list.First(), component);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Try_GetListAsync_WhenNoRecords_Test()
|
||||
{
|
||||
var list = await _componentStorageContract.GetListAsync(CancellationToken.None);
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_WhenHaveRecord_Test()
|
||||
{
|
||||
|
||||
@@ -75,6 +75,25 @@ internal class ManifacturingStorageContractTests : BaseStorageContractTest
|
||||
Assert.That(list.All(x => x.FurnitureId == _furniture.Id));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Try_GetListAsyncc_ByPeriod_Test_Test()
|
||||
{
|
||||
var manufacturing = FurnitureAssemblyDbContext.InsertManifacturingToDatabaseAndReturn(_worker.Id, _furniture.Id);
|
||||
FurnitureAssemblyDbContext.InsertManifacturingToDatabaseAndReturn(_worker.Id, _furniture.Id);
|
||||
FurnitureAssemblyDbContext.InsertManifacturingToDatabaseAndReturn(_worker.Id, _furniture.Id);
|
||||
var list = await _manifacturingStorageContract.GetListAsync(startDate: DateTime.UtcNow.AddDays(-1), endDate: DateTime.UtcNow.AddDays(1), CancellationToken.None);
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Has.Count.EqualTo(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Try_GetListAsync_WhenNoRecords_Test()
|
||||
{
|
||||
var list = await _manifacturingStorageContract.GetListAsync(startDate: DateTime.UtcNow.AddDays(-1), endDate: DateTime.UtcNow.AddDays(1), CancellationToken.None);
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetElementById_WhenHaveRecord_Test()
|
||||
{
|
||||
|
||||
@@ -63,6 +63,32 @@ internal class SalaryStorageContractTests : BaseStorageContractTest
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Try_GetListAsync_ByPeriod_Test()
|
||||
{
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(_worker.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(_worker.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(-5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(_worker.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(_worker.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(_worker.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(_worker.Id,
|
||||
salaryDate: DateTime.UtcNow.AddDays(-2));
|
||||
var list = await
|
||||
_salaryStorageContract.GetListAsync(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1), CancellationToken.None);
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(list, Has.Count.EqualTo(2));
|
||||
});
|
||||
}
|
||||
[Test]
|
||||
public async Task Try_GetListAsync_WhenNoRecords_Test()
|
||||
{
|
||||
var list = await _salaryStorageContract.GetListAsync(DateTime.UtcNow.AddDays(-10), DateTime.UtcNow.AddDays(10), CancellationToken.None);
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Try_GetList_ByWorker_Test()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
using FurnitureAssemblyContracts.AdapterContracts.OperationResponses;
|
||||
using FurnitureAssemblyContracts.ViewModels;
|
||||
using FurnitureAssemblyTests.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Net;
|
||||
|
||||
namespace FurnitureAssemblyTests.WebApiControllerTests;
|
||||
|
||||
[TestFixture]
|
||||
|
||||
internal class ReportControllerTests : BaseWebApiControllerTest
|
||||
{
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
FurnitureAssemblyDbContext.RemoveComponentsFromDatabase();
|
||||
FurnitureAssemblyDbContext.RemoveManifacturingFromDatabase();
|
||||
FurnitureAssemblyDbContext.RemoveFurnituresFromDatabase();
|
||||
FurnitureAssemblyDbContext.RemoveWorkersFromDatabase();
|
||||
FurnitureAssemblyDbContext.RemovePostsFromDatabase();
|
||||
FurnitureAssemblyDbContext.RemoveSalariesFromDatabase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetComponents_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
FurnitureAssemblyDbContext.InsertComponentToDatabaseAndReturn(name: "Component1", prevName: "prevComponent1", prevPrevName: "prevPrevComponent1");
|
||||
FurnitureAssemblyDbContext.InsertComponentToDatabaseAndReturn(name: "Component2", prevName: "prevComponent2");
|
||||
FurnitureAssemblyDbContext.InsertComponentToDatabaseAndReturn(name: "Component3");
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/report/getcomponents");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<ComponentHistoryViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(3));
|
||||
Assert.That(data.First(x => x.CurrentName == "Component1").HistoryNames, Has.Count.EqualTo(2));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetComponents_WhenNoRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/report/getcomponents");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await
|
||||
GetModelFromResponseAsync<List<ComponentHistoryViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task LoadComponentsHistory_ReturnsFile()
|
||||
{
|
||||
//Arrange
|
||||
FurnitureAssemblyDbContext.InsertComponentToDatabaseAndReturn(name: "Component1", prevName: "prevComponent1", prevPrevName: "prevPrevComponent1");
|
||||
FurnitureAssemblyDbContext.InsertComponentToDatabaseAndReturn(name: "Component2", prevName: "prevComponent2");
|
||||
FurnitureAssemblyDbContext.InsertComponentToDatabaseAndReturn(name: "Component3");
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync("/api/report/LoadComponents");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
using var data = await response.Content.ReadAsStreamAsync();
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data.Length, Is.GreaterThan(0));
|
||||
await AssertStreamAsync(response, "file.docx");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetManifacturing_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var worker = FurnitureAssemblyDbContext.InsertWorkerToDatabaseAndReturn();
|
||||
var furniture = FurnitureAssemblyDbContext.InsertFurnitureToDatabaseAndReturn();
|
||||
FurnitureAssemblyDbContext.InsertManifacturingToDatabaseAndReturn(worker.Id, furniture.Id);
|
||||
FurnitureAssemblyDbContext.InsertManifacturingToDatabaseAndReturn(worker.Id, furniture.Id);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/report/getmanifacturings?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<ManifacturingFurnitureViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetManifacturing_WhenDateIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/report/getmanifacturings?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task LoadSales_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var worker = FurnitureAssemblyDbContext.InsertWorkerToDatabaseAndReturn();
|
||||
var product1 = FurnitureAssemblyDbContext.InsertFurnitureToDatabaseAndReturn(name: "name 1");
|
||||
var product2 = FurnitureAssemblyDbContext.InsertFurnitureToDatabaseAndReturn(name: "name 2");
|
||||
FurnitureAssemblyDbContext.InsertManifacturingToDatabaseAndReturn(worker.Id, product1.Id, count: 5);
|
||||
FurnitureAssemblyDbContext.InsertManifacturingToDatabaseAndReturn(worker.Id, product2.Id, count: 6);
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/report/loadsales?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
|
||||
//Assert
|
||||
await AssertStreamAsync(response, "file.xlsx");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task LoadSales_WhenDateIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/report/loadsales?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetSalary_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var post = FurnitureAssemblyDbContext.InsertPostToDatabaseAndReturn();
|
||||
var worker1 = FurnitureAssemblyDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 1", postId: post.PostId).AddPost(post);
|
||||
var worker2 = FurnitureAssemblyDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 2", postId: post.PostId).AddPost(post);
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker1.Id, workerSalary: 100, salaryDate: DateTime.UtcNow.AddDays(-10));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker1.Id, workerSalary: 1000, salaryDate: DateTime.UtcNow.AddDays(-5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker1.Id, workerSalary: 200, salaryDate: DateTime.UtcNow.AddDays(5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker2.Id, workerSalary: 500, salaryDate: DateTime.UtcNow.AddDays(-5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker2.Id, workerSalary: 300, salaryDate: DateTime.UtcNow.AddDays(-3));
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/report/getsalary?fromDate={DateTime.UtcNow.AddDays(-7):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var data = await GetModelFromResponseAsync<List<WorkerSalaryByPeriodViewModel>>(response);
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data, Has.Count.EqualTo(2));
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data.First(x => x.WorkerFIO == worker1.FIO).TotalSalary, Is.EqualTo(1000));
|
||||
Assert.That(data.First(x => x.WorkerFIO == worker2.FIO).TotalSalary, Is.EqualTo(800));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetSalary_WhenDateIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/report/getsalary?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task LoadSalary_WhenHaveRecords_ShouldSuccess_Test()
|
||||
{
|
||||
//Arrange
|
||||
var post = FurnitureAssemblyDbContext.InsertPostToDatabaseAndReturn();
|
||||
var worker1 = FurnitureAssemblyDbContext.InsertWorkerToDatabaseAndReturn(fio: "Иванов И.И", postId: post.PostId).AddPost(post);
|
||||
var worker2 = FurnitureAssemblyDbContext.InsertWorkerToDatabaseAndReturn(fio: "Ванов И.И", postId: post.PostId).AddPost(post);
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker1.Id, workerSalary: 100, salaryDate: DateTime.UtcNow.AddDays(-10));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker1.Id, workerSalary: 1000, salaryDate: DateTime.UtcNow.AddDays(-5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker1.Id, workerSalary: 200, salaryDate: DateTime.UtcNow.AddDays(5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker2.Id, workerSalary: 500, salaryDate: DateTime.UtcNow.AddDays(-5));
|
||||
FurnitureAssemblyDbContext.InsertSalaryToDatabaseAndReturn(worker2.Id, workerSalary: 300, salaryDate: DateTime.UtcNow.AddDays(-3));
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/report/loadsalary?fromDate={DateTime.UtcNow.AddDays(-7):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
|
||||
//Assert
|
||||
await AssertStreamAsync(response, "file.pdf");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task LoadSalary_WhenDateIsIncorrect_ShouldBadRequest_Test()
|
||||
{
|
||||
//Act
|
||||
var response = await HttpClient.GetAsync($"/api/report/loadsalary?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
|
||||
//Assert
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
||||
}
|
||||
|
||||
private static async Task AssertStreamAsync(HttpResponseMessage response, string fileNameForSave = "")
|
||||
{
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
using var data = await response.Content.ReadAsStreamAsync();
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.That(data.Length, Is.GreaterThan(0));
|
||||
await SaveStreamAsync(data, fileNameForSave);
|
||||
}
|
||||
|
||||
private static async Task SaveStreamAsync(Stream stream, string fileName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var path = Path.Combine(Directory.GetCurrentDirectory(), fileName);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
stream.Position = 0;
|
||||
using var fileStream = new FileStream(path, FileMode.OpenOrCreate);
|
||||
await stream.CopyToAsync(fileStream);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
using AutoMapper;
|
||||
using FurnitureAssemblyContracts.AdapterContracts;
|
||||
using FurnitureAssemblyContracts.AdapterContracts.OperationResponses;
|
||||
using FurnitureAssemblyContracts.BusinessLogicsContracts;
|
||||
using FurnitureAssemblyContracts.DataModels;
|
||||
using FurnitureAssemblyContracts.Exceptions;
|
||||
using FurnitureAssemblyContracts.ViewModels;
|
||||
|
||||
namespace FurnitureAssemblyWebApi.Adapters;
|
||||
|
||||
public class ReportAdapter : IReportAdapter
|
||||
{
|
||||
private readonly IReportContract _reportContract;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Mapper _mapper;
|
||||
|
||||
public ReportAdapter(IReportContract reportContract, ILogger logger)
|
||||
{
|
||||
_reportContract = reportContract;
|
||||
_logger = logger;
|
||||
var config = new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.CreateMap<ComponentHistoryDataModel, ComponentHistoryViewModel>();
|
||||
cfg.CreateMap<ManifacturingFurnitureDataModel, ManifacturingFurnitureViewModel>();
|
||||
cfg.CreateMap<WorkerSalaryByPeriodDataModel, WorkerSalaryByPeriodViewModel>();
|
||||
});
|
||||
_mapper = new Mapper(config);
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> GetDataComponentsHistoryAsync(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _reportContract.GetDataComponentsHistoryAsync(ct);
|
||||
return ReportOperationResponse.OK(data.Select(x =>
|
||||
_mapper.Map<ComponentHistoryViewModel>(x)).ToList());
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: { ex.InnerException!.Message}");
|
||||
}
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: { ex.InnerException!.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error getting components history");
|
||||
return ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> GetDataManifacturingByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ReportOperationResponse.OK((await _reportContract.GetDataManifacturingByPeriodAsync(dateStart, dateFinish, ct)).Select(x => _mapper.Map<ManifacturingFurnitureViewModel>(x)).ToList());
|
||||
}
|
||||
catch (IncorrectDatesException ex)
|
||||
{
|
||||
_logger.LogError(ex, "IncorrectDatesException");
|
||||
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
|
||||
}
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception");
|
||||
return ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ReportOperationResponse.OK((await
|
||||
_reportContract.GetDataSalaryByPeriodAsync(dateStart, dateFinish, ct)).Select(x => _mapper.Map<WorkerSalaryByPeriodViewModel>(x)).ToList());
|
||||
}
|
||||
catch (IncorrectDatesException ex)
|
||||
{
|
||||
_logger.LogError(ex, "IncorrectDatesException");
|
||||
return ReportOperationResponse.BadRequest($"Incorrect dates: { ex.Message} ");
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: { ex.InnerException!.Message} "); }
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: { ex.InnerException!.Message} ");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception");
|
||||
return ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> CreateDocumentComponentHistoryAsync(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SendStream(await _reportContract.CreateDocumentComponentsHistoryAsync(ct), "components.docx");
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
|
||||
}
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception");
|
||||
return ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SendStream(await _reportContract.CreateDocumentSalesByPeriodAsync(dateStart, dateFinish, ct), "sales.xslx");
|
||||
}
|
||||
catch (IncorrectDatesException ex)
|
||||
{
|
||||
_logger.LogError(ex, "IncorrectDatesException");
|
||||
return ReportOperationResponse.BadRequest($"Incorrect dates: { ex.Message} ");
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: { ex.InnerException!.Message} ");
|
||||
}
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: { ex.InnerException!.Message} ");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception");
|
||||
return
|
||||
ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ReportOperationResponse> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SendStream(await _reportContract.CreateDocumentSalaryByPeriodAsync(dateStart, dateFinish, ct), "salary.pdf");
|
||||
}
|
||||
catch (IncorrectDatesException ex)
|
||||
{
|
||||
_logger.LogError(ex, "IncorrectDatesException");
|
||||
return ReportOperationResponse.BadRequest($"Incorrect dates: { ex.Message} ");
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogError(ex, "InvalidOperationException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: { ex.InnerException!.Message} ");
|
||||
}
|
||||
catch (StorageException ex)
|
||||
{
|
||||
_logger.LogError(ex, "StorageException");
|
||||
return ReportOperationResponse.InternalServerError($"Error while working with data storage: { ex.InnerException!.Message} ");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Exception");
|
||||
return ReportOperationResponse.InternalServerError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static ReportOperationResponse SendStream(Stream stream, string fileName)
|
||||
{
|
||||
stream.Position = 0;
|
||||
return ReportOperationResponse.OK(stream, fileName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using FurnitureAssemblyContracts.AdapterContracts;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace FurnitureAssemblyWebApi.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class ReportController(IReportAdapter adapter) : ControllerBase
|
||||
{
|
||||
private readonly IReportAdapter _adapter = adapter;
|
||||
|
||||
[HttpGet]
|
||||
[Consumes("application/json")]
|
||||
public async Task<IActionResult> GetComponents(CancellationToken ct)
|
||||
{
|
||||
return (await _adapter.GetDataComponentsHistoryAsync(ct)).GetResponse(Request, Response);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Consumes("application/json")]
|
||||
public async Task<IActionResult> GetManifacturings(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
|
||||
{
|
||||
return (await _adapter.GetDataManifacturingByPeriodAsync(fromDate, toDate, cancellationToken)).GetResponse(Request, Response);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Consumes("application/json")]
|
||||
public async Task<IActionResult> GetSalary(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
|
||||
{
|
||||
return (await _adapter.GetDataSalaryByPeriodAsync(fromDate, toDate, cancellationToken)).GetResponse(Request, Response);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Consumes("application/octet-stream")]
|
||||
public async Task<IActionResult> LoadComponents(CancellationToken cancellationToken)
|
||||
{
|
||||
return (await _adapter.CreateDocumentComponentHistoryAsync(cancellationToken)).GetResponse(Request, Response);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Consumes("application/octet-stream")]
|
||||
public async Task<IActionResult> LoadSales(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
|
||||
{
|
||||
return (await _adapter.CreateDocumentSalesByPeriodAsync(fromDate, toDate, cancellationToken)).GetResponse(Request, Response);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Consumes("application/octet-stream")]
|
||||
public async Task<IActionResult> LoadSalary(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
|
||||
{
|
||||
return (await _adapter.CreateDocumentSalaryByPeriodAsync(fromDate, toDate, cancellationToken)).GetResponse(Request, Response);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using FurnitureAssemblyBusinessLogic.Implementations;
|
||||
using FurnitureAssemblyBusinessLogic.OfficePackage;
|
||||
using FurnitureAssemblyContracts.AdapterContracts;
|
||||
using FurnitureAssemblyContracts.BusinessLogicsContracts;
|
||||
using FurnitureAssemblyContracts.Infrastructure;
|
||||
@@ -72,6 +73,13 @@ builder.Services.AddTransient<IFurnitureAdapter, FurnitureAdapter>();
|
||||
builder.Services.AddTransient<IManifacturingFurnitureAdapter, ManifacturingFurnitureAdapter>();
|
||||
builder.Services.AddTransient<ISalaryAdapter, SalaryAdapter>();
|
||||
|
||||
builder.Services.AddTransient<IReportContract, ReportContract>();
|
||||
builder.Services.AddTransient<IReportAdapter, ReportAdapter>();
|
||||
|
||||
builder.Services.AddScoped<BaseWordBuilder, OpenXmlWordBuilder>();
|
||||
builder.Services.AddScoped<BaseExcelBuilder, OpenXmlExcelBuilder>();
|
||||
builder.Services.AddScoped<BasePdfBuilder, MigraDocPdfBuilder>();
|
||||
|
||||
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
||||
builder.Services.AddOpenApi();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user