This commit is contained in:
vettaql 2024-12-24 01:32:15 +04:00
parent dbd151ff41
commit 208f744ef5
20 changed files with 569 additions and 380 deletions

View File

@ -1,8 +1,16 @@
public class Client
using System.ComponentModel;
public class Client
{
public int Id { get; private set; }
[DisplayName("Имя")]
public string FirstName { get; private set; } = string.Empty;
[DisplayName("Фамилия")]
public string LastName { get; private set; } = string.Empty;
public string FullName => $"{LastName} {FirstName}";
[DisplayName("Контактная информация")]
public string ContactInformation { get; private set; } = string.Empty;
public static Client CreateEntity(int id, string firstName, string
lastName, string contactInformation)

View File

@ -1,8 +1,13 @@
public class Fabric
using System.ComponentModel;
public class Fabric
{
public int Id { get; private set; }
public FabricType FabricType { get; private set; }
public Color Color { get; private set; }
[DisplayName("Тип ткани")]
public FabricType FabricType { get; private set; }
[DisplayName("Цвет")]
public Color Color { get; private set; }
[DisplayName("Метраж")]
public double Metrage { get; private set; }
public static Fabric CreateEntity(int id, FabricType fabricType, Color color, double metrage)
{

View File

@ -3,6 +3,7 @@
public int FabricId { get; private set; }
public int ModelId { get; private set; }
public int Count { get; private set; }
public string FabricName { get; private set; } = string.Empty;
public static FabricModel CreateElement(int fabricId, int modelId, int count)
{
return new FabricModel

View File

@ -1,10 +1,19 @@
using Microsoft.VisualBasic.FileIO;
using System.ComponentModel;
public class Model
{
public int Id { get; private set; }
[DisplayName("Модель")]
public ModelType ModelType { get; private set; }
[DisplayName("Цена")]
public double Price { get; private set; }
[DisplayName("Ткань")]
public string Fabric => FabricModel != null ?
string.Join(", ", FabricModel.Select(x => $"{x.FabricName} {x.Count}")) : string.Empty;
[Browsable(false)]
public IEnumerable<FabricModel> FabricModel { get;private set;} = [];
public static Model CreateEntity(int id, ModelType modelType,double price, IEnumerable<FabricModel> fabricModel)

View File

@ -3,6 +3,7 @@
public int OrderId { get; private set; }
public int ModelId { get; private set; }
public int Count { get; private set; }
public string ModelName { get; private set; } = string.Empty;
public static ModelOrder CreateElement(int orderId, int modelId, int count)
{
return new ModelOrder

View File

@ -1,9 +1,23 @@
public class Order
using System.ComponentModel;
public class Order
{
public int Id { get; private set; }
public DateTime Date { get; private set; }
[DisplayName("Дата")]
public DateTime Date { get; private set; }
[DisplayName("Статус")]
public Status Status { get; private set; }
[Browsable(false)]
public int ClientId { get; private set; }
[DisplayName("Клиент")]
public string ClientName { get; private set; } = string.Empty;
[DisplayName("Модель")]
public string Model => ModelOrder != null ?
string.Join(", ", ModelOrder.Select(x => $"{x.ModelName} {x.Count}")) :string.Empty;
[Browsable(false)]
public IEnumerable<ModelOrder> ModelOrder { get; private set; } = [];
public static Order CreateOperation(int id,DateTime date, Status status, int clientId, IEnumerable<ModelOrder> modelOrder)
@ -18,5 +32,11 @@
};
}
public void SetModelOrder(IEnumerable<ModelOrder> modelOrders)
{
if (modelOrders != null && modelOrders.Any())
{
ModelOrder = modelOrders;
}
}
}

View File

@ -1,8 +1,16 @@
public class Storage
using System.ComponentModel;
public class Storage
{
public int Id { get; private set; }
[Browsable(false)]
public int FabricId { get; private set; }
[DisplayName("Ткань")]
public string FabricName { get; private set; } = string.Empty;
[DisplayName("Метраж")]
public double StockMetrage { get; private set; }
[DisplayName("Дата")]
public DateTime DateStorage { get; private set; }
public static Storage CreateOperation(int id, int fabricId, double stockMetrage, DateTime dateStorage)

View File

@ -92,7 +92,13 @@ namespace Atelier.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView1.DataSource = _clientRepository.ReadClients();
private void LoadList()
{
dataGridView1.DataSource = _clientRepository.ReadClients();
dataGridView1.Columns["Id"].Visible = false;
dataGridView1.Columns["FullName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -90,7 +90,13 @@ namespace Atelier.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView1.DataSource = _fabricRepository.ReadFabrics();
private void LoadList()
{
dataGridView1.DataSource = _fabricRepository.ReadFabrics();
dataGridView1.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -91,7 +91,13 @@ namespace Atelier.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView1.DataSource = _modelRepository.ReadModels();
private void LoadList()
{
dataGridView1.DataSource = _modelRepository.ReadModels();
dataGridView1.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -21,7 +21,7 @@ namespace Atelier.Forms
throw new
ArgumentNullException(nameof(orderRepository));
comboBoxClient.DataSource = clientRepository.ReadClients();
comboBoxClient.DisplayMember = "FirstName";
comboBoxClient.DisplayMember = "FullName";
comboBoxClient.ValueMember = "Id";
comboBoxStatus.DataSource = orderRepository.ReadOrders();
comboBoxStatus.DataSource = Enum.GetValues(typeof(Status));

View File

@ -73,7 +73,13 @@ namespace Atelier.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView1.DataSource = _orderRepository.ReadOrders();
private void LoadList()
{
dataGridView1.DataSource = _orderRepository.ReadOrders();
dataGridView1.Columns["Id"].Visible = false;
dataGridView1.Columns["Date"].DefaultCellStyle.Format = "dd MMMM yyyy hh:mm";
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -72,8 +72,13 @@ namespace Atelier.Forms
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView1.DataSource =
_storageRepository.ReadStorage();
private void LoadList()
{
dataGridView1.DataSource = _storageRepository.ReadStorage();
dataGridView1.Columns["Id"].Visible = false;
dataGridView1.Columns["DateStorage"].DefaultCellStyle.Format = "dd MMMM yyyy hh:mm";
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -22,11 +22,11 @@ namespace Atelier.Reports
try
{
var data = GetData(dateTime);
_logger.LogDebug("Data for chart: {Data}", System.Text.Json.JsonSerializer.Serialize(data));
_logger.LogDebug("Data for chart: {Data}", JsonSerializer.Serialize(data));
new PdfBuilder(filePath)
.AddHeader("Склад тканей")
.AddPieChart("Остатки тканей", data)
.AddHeader("Склад")
.AddPieChart($"Остатки на {dateTime:dd MMMM yyyy}", data)
.Build();
return true;
}
@ -49,6 +49,5 @@ namespace Atelier.Reports
_logger.LogDebug("Raw data: {Data}", JsonSerializer.Serialize(data));
return data;
}
}
}

View File

@ -7,304 +7,309 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Atelier.Reports;
public class ExcelBuilder
namespace Atelier.Reports
{
private readonly string _filePath;
private readonly SheetData _sheetData;
private readonly MergeCells _mergeCells;
private readonly Columns _columns;
private uint _rowIndex = 0;
public class ExcelBuilder
{
private readonly string _filePath;
private readonly SheetData _sheetData;
private readonly MergeCells _mergeCells;
private readonly Columns _columns;
private uint _rowIndex = 0;
public ExcelBuilder(string filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
public ExcelBuilder(string filePath)
{
throw new ArgumentNullException(nameof(filePath));
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
_filePath = filePath;
_sheetData = new SheetData();
_mergeCells = new MergeCells();
_columns = new Columns();
_rowIndex = 1;
}
public ExcelBuilder 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 ExcelBuilder AddParagraph(string text, int columnIndex)
{
CreateCell(columnIndex, _rowIndex++, text, StyleIndex.SimpleTextWithoutBorder);
return this;
}
public ExcelBuilder 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)
if (string.IsNullOrWhiteSpace(filePath))
{
CreateCell(j, _rowIndex, data[i][j], StyleIndex.SimpleTextWithBorder);
throw new ArgumentNullException(nameof(filePath));
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
_filePath = filePath;
_sheetData = new SheetData();
_mergeCells = new MergeCells();
_columns = new Columns();
_rowIndex = 1;
}
public ExcelBuilder 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 ExcelBuilder AddParagraph(string text, int columnIndex)
{
CreateCell(columnIndex, _rowIndex, text, StyleIndex.SimpleTextWithoutBorder);
_mergeCells.Append(new MergeCell()
{
Reference = new StringValue($"{GetExcelColumnName(columnIndex)}{_rowIndex}:{GetExcelColumnName(columnIndex + 1)}{_rowIndex}")
});
_rowIndex++;
return this;
}
public ExcelBuilder 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 j = 0; j < data.Last().Length; ++j)
{
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
return this;
}
public void Build()
{
using var spreadsheetDocument = SpreadsheetDocument.Create(_filePath, 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());
}
}
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()
for (var i = 1; i < data.Count - 1; ++i)
{
Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor)
}
});
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
Bold = new Bold(),
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme()
{
Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor)
}
});
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.Medium },
RightBorder = new RightBorder() { Style = BorderStyleValues.Medium },
TopBorder = new TopBorder() { Style = BorderStyleValues.Medium },
BottomBorder = new BottomBorder() { Style = BorderStyleValues.Medium },
DiagonalBorder = new DiagonalBorder() { Style = BorderStyleValues.Medium },
});
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 = 1,
FormatId = 0,
FontId = 0,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 2,
FormatId = 0,
FontId = 1,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 3,
FormatId = 0,
FontId = 1,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
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)
for (var j = 0; j < data[i].Length; ++j)
{
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
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 void Build()
{
using var spreadsheetDocument = SpreadsheetDocument.Create(_filePath, 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());
}
spreadsheetDocument.WorkbookPart.Workbook.Save();
}
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" },
Bold = new Bold(),
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme()
{
Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor)
}
});
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.Medium },
RightBorder = new RightBorder() { Style = BorderStyleValues.Medium },
TopBorder = new TopBorder() { Style = BorderStyleValues.Medium },
BottomBorder = new BottomBorder() { Style = BorderStyleValues.Medium },
DiagonalBorder = new DiagonalBorder() { Style = BorderStyleValues.Medium },
});
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 = 1,
FormatId = 0,
FontId = 0,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 2,
FormatId = 0,
FontId = 1,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 3,
FormatId = 0,
FontId = 1,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
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)
{
refCell = cell;
break;
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
{
refCell = cell;
break;
}
}
}
newCell = new Cell() { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
}
newCell = new Cell() { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
newCell.CellValue = new CellValue(text);
newCell.DataType = CellValues.String;
newCell.StyleIndex = (uint)styleIndex;
}
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)
private static string GetExcelColumnName(int columnNumber)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() +
columnName;
dividend = (dividend - modulo) / 26;
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;
}
return columnName;
}
}
}

View File

@ -1,5 +1,6 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Atelier.Repositories;
using DocumentFormat.OpenXml.Office2010.Excel;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
@ -11,7 +12,7 @@ namespace Atelier.Reports
private readonly IOrderRepository _orderRepository;
private readonly IModelRepository _modelRepository;
private readonly ILogger<TableReport> _logger;
internal static readonly string[] item = ["Клиент", "Дата", "Модель", "Статус", "Новые заказы", "Заказы в работе", "Выполненные заказы"];
internal static readonly string[] Headers = { "Клиент", "Дата", "Модель", "Статус", "Новые заказы", "Заказы в работе", "Выполненные заказы" };
public TableReport(IOrderRepository orderRepository, IModelRepository modelRepository, ILogger<TableReport> logger)
{
@ -20,14 +21,14 @@ namespace Atelier.Reports
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateTable(string filePath, int modelId, DateTime startDate, DateTime endDate)
public bool CreateTable(string filePath, int? modelId = null, DateTime? startDate = null, DateTime? endDate = null, Status? status = null, int? clientId = null)
{
try
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по заказам", 0, 4)
.AddParagraph("за период", 0)
.AddTable(new[] { 15, 15, 15, 15, 15, 15, 15 }, GetData(modelId, startDate, endDate))
.AddParagraph($"за период с {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0)
.AddTable(new[] { 15, 15, 15, 15, 15, 15, 15 }, GetData(modelId, startDate, endDate, status, clientId))
.Build();
return true;
}
@ -38,15 +39,11 @@ namespace Atelier.Reports
}
}
private List<string[]> GetData(int modelId, DateTime startDate, DateTime endDate)
private List<string[]> GetData(int? modelId, DateTime? startDate, DateTime? endDate, Status? status, int? clientId)
{
var orders = _orderRepository
.ReadOrders(modelId, startDate, endDate)
.ToList();
var orders = _orderRepository.ReadOrders(modelId, startDate, endDate, status, clientId).ToList();
_logger.LogDebug("Orders: {Orders}", JsonConvert.SerializeObject(orders));
var result = new List<string[]>() { item };
var result = new List<string[]>() { Headers };
var newOrdersCount = 0;
var inProcessOrdersCount = 0;
@ -54,17 +51,20 @@ namespace Atelier.Reports
foreach (var order in orders)
{
var model = _modelRepository.ReadModelById(modelId);
var modelName = model?.ModelType.ToString() ?? "Неизвестно";
var newOrder = order.Status == Status.Waiting ? "1" : "0";
var inProcessOrder = order.Status == Status.InProcess ? "1" : "0";
var doneOrder = order.Status == Status.Done ? "1" : "0";
foreach (var modelOrder in order.ModelOrder)
{
var model = _modelRepository.ReadModelById(modelOrder.ModelId);
var modelName = model?.ModelType.ToString() ?? "Неизвестно";
var newOrder = order.Status == Status.Waiting ? "1" : "0";
var inProcessOrder = order.Status == Status.InProcess ? "1" : "0";
var doneOrder = order.Status == Status.Done ? "1" : "0";
result.Add(new string[] { order.ClientId.ToString(), order.Date.ToString("yyyy-MM-dd"), modelName, order.Status.ToString(), newOrder, inProcessOrder, doneOrder });
result.Add(new string[] { order.ClientName, order.Date.ToString("yyyy-MM-dd"), modelName, order.Status.ToString(), newOrder, inProcessOrder, doneOrder });
if (order.Status == Status.Waiting) newOrdersCount++;
if (order.Status == Status.InProcess) inProcessOrdersCount++;
if (order.Status == Status.Done) doneOrdersCount++;
if (order.Status == Status.Waiting) newOrdersCount++;
if (order.Status == Status.InProcess) inProcessOrdersCount++;
if (order.Status == Status.Done) doneOrdersCount++;
}
}
result.Add(new[] { "Всего", "", "", "", newOrdersCount.ToString(), inProcessOrdersCount.ToString(), doneOrdersCount.ToString() });

View File

@ -1,6 +1,6 @@
public interface IStorageRepository
{
IEnumerable<Storage> ReadStorage(int? fabricId = null, double ? StockMetrage = null, double? maxStockMetrage = null);
IEnumerable<Storage> ReadStorage(int? fabricId = null, double? StockMetrage = null, DateTime? startDate = null, DateTime? endDate = null);
void CreateStorage(Storage storage);
void DeleteStorage(int id);
}

View File

@ -1,9 +1,12 @@
using Atelier.Repositories;
using Dapper;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.Office2010.Excel;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using System.Collections.Generic;
using System.Windows.Forms;
internal class ModelRepository : IModelRepository
{
@ -160,7 +163,14 @@ internal class ModelRepository : IModelRepository
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Models";
var querySelect = @$"SELECT
m.*,
fm.FabricId,
fm.Count,
f.FabricType as FabricName
FROM Models m
INNER JOIN FabricModel fm on fm.ModelId = m.Id
LEFT JOIN Fabrics f ON f.Id = fm.FabricId;";
var models = connection.Query<Model>(querySelect).ToList();
foreach (var model in models)

View File

@ -3,15 +3,16 @@ using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using Serilog.Core;
using System.Text;
using System.Collections.Generic;
using System.Linq;
internal class OrderRepository : IOrderRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<Order> _logger;
public OrderRepository(IConnectionString connectionString,
ILogger<Order> logger)
public OrderRepository(IConnectionString connectionString, ILogger<Order> logger)
{
_connectionString = connectionString;
_logger = logger;
@ -20,23 +21,20 @@ internal class OrderRepository : IOrderRepository
public void CreateOrder(Order order)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}",
JsonConvert.SerializeObject(order));
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(order));
try
{
using var connection = new
NpgsqlConnection(_connectionString.ConnectionString);
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
var queryInsert = @"
INSERT INTO Orders (Date, Status, ClientId)
VALUES (@Date, @Status, @ClientId);
SELECT MAX(Id) FROM Orders";
var orderId =
connection.QueryFirst<int>(queryInsert, order, transaction);
var orderId = connection.QueryFirst<int>(queryInsert, order, transaction);
var querySubInsert = @"
INSERT INTO ModelOrder (OrderId, ModelId, Count)
VALUES (@OrderId,@ModelId, @Count)";
VALUES (@OrderId, @ModelId, @Count)";
foreach (var elem in order.ModelOrder)
{
connection.Execute(querySubInsert, new
@ -53,19 +51,18 @@ VALUES (@OrderId,@ModelId, @Count)";
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void DeleteOrder(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new
NpgsqlConnection(_connectionString.ConnectionString);
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Orders
WHERE Id=@id";
WHERE Id = @id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
@ -73,70 +70,106 @@ WHERE Id=@id";
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
internal class QueryBuilder
{
private readonly StringBuilder _builder;
public QueryBuilder()
{
_builder = new();
}
public QueryBuilder AddCondition(string condition)
{
if (_builder.Length > 0)
{
_builder.Append(" AND ");
}
_builder.Append(condition);
return this;
}
public string Build()
{
return _builder.Length == 0 ? string.Empty : $"WHERE {_builder}";
}
}
public IEnumerable<Order> ReadOrders(int? modelId = null, DateTime? startDate = null, DateTime? endDate = null, Status? status = null, int? clientId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT o.Id, o.Date, o.Status, o.ClientId, m.ModelId, m.Count, m.OrderId
FROM Orders o
LEFT JOIN ModelOrder m ON o.Id = m.OrderId";
var parameters = new DynamicParameters();
if (modelId.HasValue)
{
querySelect += " WHERE m.ModelId = @ModelId";
parameters.Add("@ModelId", modelId.Value);
}
var builder = new QueryBuilder();
if (startDate.HasValue)
{
querySelect += " AND o.Date >= @StartDate";
parameters.Add("@StartDate", startDate.Value);
builder.AddCondition("o.Date >= @startDate");
}
if (endDate.HasValue)
{
querySelect += " AND o.Date <= @EndDate";
parameters.Add("@EndDate", endDate.Value);
builder.AddCondition("o.Date <= @endDate");
}
if (modelId.HasValue)
{
builder.AddCondition("mo.ModelId = @modelId");
}
if (status.HasValue)
{
querySelect += " AND o.Status = @Status";
parameters.Add("@Status", status.Value);
builder.AddCondition("o.Status = @status");
}
if (clientId.HasValue)
{
querySelect += " AND o.ClientId = @ClientId";
parameters.Add("@ClientId", clientId.Value);
builder.AddCondition("o.ClientId = @clientId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @$"
SELECT
o.*,
CONCAT(c.LastName, ' ', c.FirstName) as ClientName,
mo.ModelId,
mo.Count,
m.ModelType as ModelName
FROM Orders o
LEFT JOIN Clients c on c.Id = o.ClientId
INNER JOIN ModelOrder mo on mo.OrderId = o.Id
LEFT JOIN Models m ON m.Id = mo.ModelId
{builder.Build()}";
var orderDict = new Dictionary<int, List<ModelOrder>>();
var orders = connection.Query<Order, ModelOrder, Order>(
querySelect,
(order, modelOrder) =>
{
var newOrder = Order.CreateOperation(order.Id, order.Date, order.Status, order.ClientId, new List<ModelOrder>());
if (modelOrder != null)
if (!orderDict.TryGetValue(order.Id, out var modelOrders))
{
var modelOrders = new List<ModelOrder>(newOrder.ModelOrder);
modelOrders.Add(modelOrder);
newOrder = Order.CreateOperation(order.Id, order.Date, order.Status, order.ClientId, modelOrders);
modelOrders = new List<ModelOrder>();
orderDict.Add(order.Id, modelOrders);
}
return newOrder;
modelOrders.Add(modelOrder);
return order;
},
param: parameters,
splitOn: "OrderId").ToList();
splitOn: "ModelId",
param: new
{
startDate,
endDate,
modelId,
status,
clientId
});
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(orders));
return orders;
return orderDict.Select(x =>
{
var o = orders.First(y => y.Id == x.Key);
o.SetModelOrder(x.Value);
return o;
}).ToArray();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении данных о заказах");
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}

View File

@ -3,6 +3,8 @@ using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using System.Text;
using static System.Runtime.InteropServices.JavaScript.JSType;
internal class StorageRepository : IStorageRepository
{
@ -52,22 +54,81 @@ WHERE Id=@id";
throw;
}
}
public IEnumerable<Storage> ReadStorage(int? fabricId = null, double? minStockMetrage = null, double? StockMetrage = null)
internal class QueryBuilder
{
private readonly StringBuilder _builder;
public QueryBuilder()
{
_builder = new();
}
public QueryBuilder AddCondition(string condition)
{
if (_builder.Length > 0)
{
_builder.Append(" AND ");
}
_builder.Append(condition);
return this;
}
public string Build()
{
if (_builder.Length == 0)
{
return string.Empty;
}
return $"WHERE {_builder}";
}
}
public IEnumerable<Storage> ReadStorage(int? fabricId = null, double? stockMetrage = null, DateTime? startDate = null, DateTime? endDate = null)
{
_logger.LogInformation("Получение всех данных о складе");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Storages";
var storages = connection.Query<Storage>(querySelect).ToList();
var builder = new QueryBuilder();
if (startDate.HasValue)
{
builder.AddCondition("s.DateStorage >= @startDate");
}
if (endDate.HasValue)
{
builder.AddCondition("s.DateStorage <= @endDate");
}
if (fabricId.HasValue)
{
builder.AddCondition("s.FabricId = @fabricId");
}
if (stockMetrage.HasValue)
{
builder.AddCondition("s.StockMetrage = @stockMetrage");
}
_logger.LogDebug("Полученные данные о складе: {json}", JsonConvert.SerializeObject(storages));
return storages;
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @$"
SELECT
s.*,
f.FabricType as FabricName
FROM Storages s
LEFT JOIN Fabrics f on f.Id = s.FabricId
{builder.Build()}";
var storage = connection.Query<Storage>(querySelect, new
{
startDate,
endDate,
fabricId,
stockMetrage
});
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(storage));
return storage;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении данных о складе");
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}