This commit is contained in:
Дмитрий Шурыгин 2025-02-03 20:18:36 +04:00
parent e3bd3e0f4e
commit 0f3f7c2f7d
26 changed files with 351 additions and 130 deletions

View File

@ -1,10 +1,20 @@
namespace ProjectAtelier.Entities;
using DocumentFormat.OpenXml.Wordprocessing;
using System.ComponentModel;
namespace ProjectAtelier.Entities;
public class Client
{
public int Id { get; private set; }
[DisplayName("Клиент")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Телефон")]
public string Phone { get; private set; } = string.Empty;
public string ClientName => $"{Name} {Phone}";
public static Client CreateEntity(int id, string name, string phone)
{
return new Client

View File

@ -1,12 +1,22 @@
using ProjectAtelier.Entities.Enums;
using DocumentFormat.OpenXml.Wordprocessing;
using ProjectAtelier.Entities.Enums;
using System.ComponentModel;
namespace ProjectAtelier.Entities;
public class Cloth
{
public int Id { get; private set; }
[DisplayName("Тип ткани")]
public ClothType ClothType { get; private set; }
[DisplayName("Длина")]
public double Length { get; private set; }
public string ClothName => $"{(ClothType)ClothType} {Length}";
public static Cloth CreateEntity(int id, ClothType clothType, double length)
{
return new Cloth

View File

@ -1,10 +1,23 @@
namespace ProjectAtelier.Entities;
using ProjectAtelier.Entities.Enums;
using System.ComponentModel;
namespace ProjectAtelier.Entities;
public class Entrance
{
public int Id { get; private set; }
[Browsable(false)]
public int ClothId { get; private set; }
[Browsable(false)]
public ClothType ClothType { get; private set; }
[Browsable(false)]
public double ClothLength { get; private set; }
[DisplayName("Ткань")]
public string ClothName => $"{(ClothType)ClothType} {ClothLength}";
[DisplayName("Значение")]
public double Value { get; private set; }
[DisplayName("Дата")]
public DateTime Date { get; private set; }
public static Entrance CreateOperation(int id, int clothId, int value)
{

View File

@ -1,9 +1,15 @@
namespace ProjectAtelier.Entities;
using ProjectAtelier.Entities.Enums;
using System.ComponentModel;
namespace ProjectAtelier.Entities;
public class Expenditure
{
public int Id { get; private set; }
public int ClothId { get; private set; }
public int ClothId { get; private set; }
public ClothType ClothType { get; private set; }
public double ClothLength { get; private set; }
public string FullName => $"{(ClothType)ClothType} {ClothLength}";
public double Value { get; private set; }
public static Expenditure CreateElement(int id, int clothId, double value)
{

View File

@ -1,11 +1,21 @@
using ProjectAtelier.Entities.Enums;
using System.ComponentModel;
namespace ProjectAtelier.Entities;
public class Model
{
public int Id { get; private set; }
[DisplayName("Тип модели")]
public ModelType ModelType { get; private set; }
[DisplayName("Расход")]
public string Cloth => Expenditures != null ?
string.Join(", ", Expenditures.Select(x => $"{x.FullName} - {x.Value}")) :
string.Empty;
[Browsable(false)]
public IEnumerable<Expenditure> Expenditures { get; private set; } = [];
public static Model CreateEntity(int id, ModelType modelType, IEnumerable<Expenditure> expenditures)
{
@ -17,13 +27,11 @@ public class Model
};
}
public static Model CreateEntity(TempExpenditure tempExpenditure, IEnumerable<Expenditure> expenditures)
public void SetExpenditures(IEnumerable<Expenditure> expenditures)
{
return new Model
if (expenditures != null && expenditures.Any())
{
Id = tempExpenditure.Id,
ModelType = tempExpenditure.ModelType,
Expenditures = expenditures
};
Expenditures = expenditures;
}
}
}

View File

@ -1,9 +1,14 @@
namespace ProjectAtelier.Entities;
using ProjectAtelier.Entities.Enums;
using System.ComponentModel;
namespace ProjectAtelier.Entities;
public class ModelList
{
public int Id { get; private set; }
public int ModelId { get; private set; }
public ModelType ModelType { get; private set; }
public string ModelName => $"{(ModelType)ModelType}";
public int Count { get; private set; }
public static ModelList CreateElement(int id, int modelId, int count)
{

View File

@ -1,14 +1,33 @@
using ProjectAtelier.Entities.Enums;
using System.ComponentModel;
namespace ProjectAtelier.Entities;
public class Order
{
public int Id { get; private set; }
[Browsable(false)]
public int ClientId { get; private set; }
[DisplayName("Клиент")]
public string ClientName { get; private set; } = string.Empty;
[DisplayName("Цена")]
public int Prise { get; private set; }
[DisplayName("Модели")]
public string Model => ModelLists != null ?
string.Join(", ", ModelLists.Select(x => $"{x.ModelName} {x.Count}")) :
string.Empty;
[Browsable(false)]
public IEnumerable<ModelList> ModelLists { get; private set; } = [];
[DisplayName("Дата")]
public DateTime Date { get; private set; }
[DisplayName("Принты")]
public Prints Prints { get; private set; }
public static Order CreateOperation(int id, int clientId, int prise, IEnumerable<ModelList> modelLists, Prints prints)
@ -23,16 +42,12 @@ public class Order
Prints = prints
};
}
public static Order CreateOperation(TempModelList tempModelList, IEnumerable<ModelList> modelLists)
public void SetModelLists(IEnumerable<ModelList> modelLists)
{
return new Order
if (modelLists != null && modelLists.Any())
{
Id = tempModelList.Id,
ClientId = tempModelList.ClientId,
Prise = tempModelList.Prise,
ModelLists = modelLists,
Date = tempModelList.Date,
Prints = tempModelList.Prints,
};
ModelLists = modelLists;
}
}
}

View File

@ -1,11 +0,0 @@
using ProjectAtelier.Entities.Enums;
namespace ProjectAtelier.Entities;
public class TempExpenditure
{
public int Id { get; private set; }
public ModelType ModelType { get; private set; }
public int ClothId { get; private set; }
public double Value { get; private set; }
}

View File

@ -1,21 +0,0 @@
using ProjectAtelier.Entities.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectAtelier.Entities;
public class TempModelList
{
public int Id { get; private set; }
public int ClientId { get; private set; }
public int Prise { get; private set; }
public IEnumerable<ModelList> ModelLists { get; private set; } = [];
public DateTime Date { get; private set; }
public Prints Prints { get; private set; }
public int ModelId { get; private set; }
public int Count { get; private set; }
}

View File

@ -75,7 +75,13 @@ namespace ProjectAtelier.Forms
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridViewData.DataSource = _clientRepository.ReadClients();
private void LoadList()
{
dataGridViewData.DataSource = _clientRepository.ReadClients();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["ClientName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -74,7 +74,13 @@ namespace ProjectAtelier.Forms
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridViewData.DataSource = _clothRepository.ReadCloths();
private void LoadList()
{
dataGridViewData.DataSource = _clothRepository.ReadCloths();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["ClothName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -11,7 +11,7 @@ namespace ProjectAtelier.Forms
InitializeComponent();
_entranceRepository = entranceRepository ?? throw new ArgumentNullException(nameof(entranceRepository));
comboBoxClothType.DataSource = clothRepository.ReadCloths();
comboBoxClothType.DisplayMember = "ClothType";
comboBoxClothType.DisplayMember = "ClothName";
comboBoxClothType.ValueMember = "Id";
}
private void ButtonSave_Click(object sender, EventArgs e)

View File

@ -1,4 +1,6 @@
using ProjectAtelier.Repositories;
using ProjectAtelier.Entities;
using ProjectAtelier.Entities.Enums;
using ProjectAtelier.Repositories.Implementations;
using Unity;
@ -37,6 +39,11 @@ namespace ProjectAtelier.Forms
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridViewData.DataSource = _entranceRepository.ReadEntrances();
private void LoadList()
{
dataGridViewData.DataSource = _entranceRepository.ReadEntrances();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["Date"].DefaultCellStyle.Format = "dd.MM.yyyy";
}
}
}

View File

@ -45,7 +45,7 @@ namespace ProjectAtelier.Forms
comboBoxModelType.DataSource = Enum.GetValues(typeof(ModelType));
ColumnClothType.DataSource = clothRepository.ReadCloths();
ColumnClothType.DisplayMember = "ClothType";
ColumnClothType.DisplayMember = "ClothName";
ColumnClothType.ValueMember = "Id";
}
private void ButtonSave_Click(object sender, EventArgs e)

View File

@ -74,7 +74,12 @@ namespace ProjectAtelier.Forms
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridViewData.DataSource = _modelRepository.ReadModels();
private void LoadList()
{
dataGridViewData.DataSource = _modelRepository.ReadModels();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -16,7 +16,7 @@ namespace ProjectAtelier.Forms
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
comboBoxClient.DataSource = clientRepository.ReadClients();
comboBoxClient.DisplayMember = "Name";
comboBoxClient.DisplayMember = "ClientName";
comboBoxClient.ValueMember = "Id";
ColumnModel.DataSource = modelRepository.ReadModels();

View File

@ -76,7 +76,7 @@
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(300, 29);
buttonCreate.TabIndex = 4;
buttonCreate.Text = "button1";
buttonCreate.Text = "Сформировать";
buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += ButtonCreate_Click;
//

View File

@ -56,7 +56,14 @@ namespace ProjectAtelier.Forms
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridViewData.DataSource = _orderRepository.ReadOrders();
private void LoadList()
{
dataGridViewData.DataSource = _orderRepository.ReadOrders();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["Date"].DefaultCellStyle.Format = "dd MMMM yyyy";
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -31,7 +31,7 @@ public class ChartReport
{
new PdfBuilder(filePath)
.AddHeader("Отчёт по заказам")
.AddPieChart("Заказанная продукция", GetData(dateTime))
.AddPieChart($"Заказанная продукция на {dateTime:dd MMMM\r\nyyyy}", GetData(dateTime))
.Build();
return true;
}
@ -41,24 +41,16 @@ public class ChartReport
return false;
}
}
private List<(string Caption, double Value)> GetData(DateTime dateTime)
{
var orders = _orderRepository
.ReadOrders()
.Where(x => x.Date.Date == dateTime.Date)
.SelectMany(x => x.ModelLists)
.GroupBy(y => y.ModelId, (key, group) => new
{
ModelId = key,
ModelCount = group.Sum(y => y.Count)
}).ToList();
var res = new List<(string Caption, double Value)>();
foreach (var order in orders)
{
var model = _modelRepository.
ReadModelById(order.ModelId);
res.Add((model.ModelType.ToString(), order.ModelCount));
}
return res;
return _orderRepository
.ReadOrders(dateForm: dateTime.Date, dateTo: dateTime.Date.AddDays(1))
.GroupBy(x => x.ClientName, (key, group) => new {
ClientName = key,
Count = group.Sum(x => x.Prise)
})
.Select(x => (x.ClientName, (double)x.Count))
.ToList();
}
}

View File

@ -22,14 +22,14 @@ public class TableReport
_logger = logger ??
throw new ArgumentNullException(nameof(logger));
}
public bool CreateTable(string filePath, int clothId, DateTime startDate, DateTime endDate)
public bool CreateTable(string filePath, int clothName, DateTime startDate, DateTime endDate)
{
try
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по поставкам ткани", 0, 4)
.AddParagraph("за период", 0)
.AddTable([10, 10, 15], GetData(clothId, startDate, endDate))
.AddHeader("Сводка по поставкам ткани", 0, 3)
.AddParagraph($"за период c {startDate: dd.MM.yyyy} по { endDate: dd.MM.yyyy}", 0)
.AddTable([10, 10, 15], GetData(clothName, startDate, endDate))
.Build();
return true;
}
@ -39,25 +39,23 @@ public class TableReport
return false;
}
}
private List<string[]> GetData(int clothId,
DateTime startDate, DateTime endDate)
private List<string[]> GetData(int clothName, DateTime startDate, DateTime endDate)
{
var data = _entranceRepository
.ReadEntrances(startDate, endDate, clothId)
.Where(x => x.Date >= startDate && x.Date <= endDate && x.ClothId == clothId)
.ReadEntrances(dateForm: startDate, dateTo: endDate, clothName: clothName)
.Select(x => new
{
x.ClothId,
x.ClothName,
Date = x.Date,
ClothValue = x.Value
})
})
.OrderBy(x => x.Date);
return
new List<string[]>() { item }
.Union(
data
.Select(x => new string[] {
x.ClothId.ToString(),
x.ClothName.ToString(),
x.Date.ToString(),
x.ClothValue.ToString()
}))

View File

@ -4,6 +4,6 @@ namespace ProjectAtelier.Repositories;
public interface IEntranceRepository
{
IEnumerable<Entrance> ReadEntrances(DateTime? dateForm = null, DateTime? dateTo = null, int? clothId = null);
IEnumerable<Entrance> ReadEntrances(DateTime? dateForm = null, DateTime? dateTo = null, int? clothName = null);
void CreateEntrance(Entrance entrance);
}

View File

@ -4,7 +4,7 @@ namespace ProjectAtelier.Repositories;
public interface IModelRepository
{
IEnumerable<Model> ReadModels();
IEnumerable<Model> ReadModels(int? clothId = null, int? modelId = null);
Model ReadModelById(int id);
void CreateModel(Model model);
void UpdateModel(Model model);

View File

@ -34,17 +34,39 @@ VALUES (@ClothId, @Value, @Date)";
throw;
}
}
public IEnumerable<Entrance> ReadEntrances(DateTime? dateForm = null, DateTime? dateTo = null, int? clothId = null)
public IEnumerable<Entrance> ReadEntrances(DateTime? dateForm = null, DateTime? dateTo = null, int? clothName = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateForm.HasValue)
{
builder.AddCondition("ent.Date >= @dateForm");
}
if (dateTo.HasValue)
{
builder.AddCondition("ent.Date <= @dateTo");
}
if (clothName.HasValue)
{
builder.AddCondition("ent.ClothName = @clothName");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Entrances";
var entrances = connection.Query<Entrance>(querySelect);
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(entrances));
var querySelect = @$"
SELECT
ent.*,
clo.ClothType,
clo.Length AS ClothLength
FROM Entrances ent
LEFT JOIN Cloths clo on clo.Id = ent.ClothId
{builder.Build()}";
var entrances = connection.Query<Entrance>(querySelect, new { dateForm, dateTo, clothName });
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(entrances));
return entrances;
}
catch (Exception ex)
{
@ -52,4 +74,6 @@ VALUES (@ClothId, @Value, @Date)";
throw;
}
}
}

View File

@ -3,7 +3,10 @@ using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectAtelier.Entities;
using ProjectAtelier.Entities.Enums;
using System.Data.SqlClient;
using System.Transactions;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace ProjectAtelier.Repositories.Implementations;
@ -110,24 +113,53 @@ WHERE Id=@id";
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT p.*, pc.ClothId, pc.Value FROM Models p
INNER JOIN Expenditures pc ON pc.ModelId = p.Id
WHERE p.Id=@id";
var model = connection.Query<TempExpenditure>(querySelect, new
SELECT
mod.*,
CONCAT(clo.ClothType, ' ', clo.Length) as ClothName,
clo.ClothType,
exp.ClothId,
exp.Value
FROM Models mod
INNER JOIN Expenditures exp ON mod.Id = exp.ModelId
LEFT JOIN Cloths clo ON clo.Id = exp.ClothId
WHERE mod.Id = @id";
var expenditureDict = new Dictionary<int, List<Expenditure>>();
var models = connection.Query<Model, Expenditure, Model>(
querySelect,
(model, expenditure) =>
{
if (!expenditureDict.TryGetValue(model.Id, out var expenditures))
{
expenditures = new List<Expenditure>();
expenditureDict.Add(model.Id, expenditures);
}
expenditures.Add(expenditure);
return model;
},
splitOn: "ClothId",
param: new { id });
var modelEntity = models.FirstOrDefault();
if (modelEntity == null)
{
id
});
_logger.LogDebug("Найденный объект: {json}",
JsonConvert.SerializeObject(model));
return model.GroupBy(x => x.Id, y => y,
(key, value) => Model.CreateEntity(value.First(),
value.Select(z => Expenditure.
CreateElement(0, z.ClothId, z.Value)))).ToList().First();
;
_logger.LogWarning("Объект с ID {id} не найден", id);
return null;
}
if (expenditureDict.TryGetValue(modelEntity.Id, out var expendituresForModel))
{
modelEntity.SetExpenditures(expendituresForModel);
}
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(modelEntity));
return modelEntity;
}
catch (Exception ex)
{
@ -135,22 +167,55 @@ WHERE p.Id=@id";
throw;
}
}
public IEnumerable<Model> ReadModels()
public IEnumerable<Model> ReadModels(int? clothId = null, int? modelId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (clothId.HasValue)
{
builder.AddCondition("mo.ClothtId = @clothId");
}
if (modelId.HasValue)
{
builder.AddCondition("mo.ModelId = @modelId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT p.*, pc.ClothId, pc.Value FROM Models p
INNER JOIN Expenditures pc ON pc.ModelId = p.Id";
var models = connection.Query<TempExpenditure>(querySelect);
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(models));
return models.GroupBy(x => x.Id, y => y,
(key, value) => Model.CreateEntity(value.First(),
value.Select(z => Expenditure.
CreateElement(0, z.ClothId, z.Value)))).ToList();
var querySelect = @$"
SELECT
mod.*,
exp.ClothId,
exp.Value,
clo.ClothType,
clo.Length AS ClothLength
FROM Models mod
INNER JOIN Expenditures exp ON exp.ModelId = mod.Id
LEFT JOIN Cloths clo ON clo.Id = exp.ClothId
{builder.Build()}";
var clothDict = new Dictionary<int, List<Expenditure>>();
var models = connection.Query<Model, Expenditure, Model>(querySelect,
(model, cloth) =>
{
if (!clothDict.TryGetValue(model.Id, out var ex))
{
ex = [];
clothDict.Add(model.Id, ex);
}
ex.Add(cloth);
return model;
}, splitOn: "ClothId", param: new { modelId, clothId });
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(models));
return clothDict.Select(x =>
{
var mo = models.First(y => y.Id == x.Key);
mo.SetExpenditures(x.Value);
return mo;
}).ToArray();
}
catch (Exception ex)
{

View File

@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectAtelier.Entities;
using System.Data.SqlClient;
namespace ProjectAtelier.Repositories.Implementations;
@ -73,18 +74,60 @@ WHERE Id=@id";
int? clientId = null, int? modelId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateForm.HasValue)
{
builder.AddCondition("ord.Date >= @dateForm");
}
if (dateTo.HasValue)
{
builder.AddCondition("ord.Date <= @dateTo");
}
if (clientId.HasValue)
{
builder.AddCondition("ord.ClientId = @clientId");
}
if (modelId.HasValue)
{
builder.AddCondition("ord.ModelId = @modelId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT o.*, op.ModelId, op.Count FROM Orders o
INNER JOIN ModelLists op ON op.OrderId = o.Id";
var orders = connection.Query<TempModelList>(querySelect);
var querySelect = @$"
SELECT
ord.*,
CONCAT(cli.Name, ' ', cli.Phone) as ClientName,
ml.ModelId,
ml.Count,
mod.ModelType
FROM Orders ord
LEFT JOIN Clients cli on cli.Id = ord.ClientId
INNER JOIN ModelLists ml ON ml.OrderId = ord.Id
LEFT JOIN Models mod ON mod.Id = ml.ModelId
{builder.Build()}";
var modelDict = new Dictionary<int, List<ModelList>>();
var orders = connection.Query<Order, ModelList, Order>(querySelect,
(order, model) =>
{
if (!modelDict.TryGetValue(order.Id, out var ml))
{
ml = [];
modelDict.Add(order.Id, ml);
}
ml.Add(model);
return order;
}, splitOn: "ModelId", param: new { dateForm, dateTo, modelId, clientId });
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(orders));
return orders.GroupBy(x => x.Id, y => y,
(key, value) => Order.CreateOperation(value.First(),
value.Select(z => ModelList.
CreateElement(0, z.ModelId, z.Count)))).ToList();
return modelDict.Select(x =>
{
var ord = orders.First(y => y.Id == x.Key);
ord.SetModelLists(x.Value);
return ord;
}).ToArray();
}
catch (Exception ex)
{

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectAtelier.Repositories.Implementations;
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}";
}
}