This commit is contained in:
5_fG 2024-12-16 20:35:48 +04:00
parent 17f5a4fa6a
commit 8f875e8a88
25 changed files with 275 additions and 77 deletions

View File

@ -1,10 +1,19 @@
namespace ProjectConfectFactory.Entities;
using System.ComponentModel;
namespace ProjectConfectFactory.Entities;
public class Component
{
public int Id { get; private set; }
[DisplayName("Наименование")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Единица Измерения")]
public string Unit { get; private set; } = string.Empty;
public string ComponentUnit => $"{Name} в {Unit}";
[DisplayName("Количество на складе")]
public decimal Count { get; private set; }
public static Component CreateEntity(int id, string name, string unit, decimal count)

View File

@ -1,14 +1,27 @@
namespace ProjectConfectFactory.Entities;
using System.ComponentModel;
namespace ProjectConfectFactory.Entities;
// заказ
public class Order
{
public int Id { get; private set; }
public string Name { get; private set; } = string.Empty;
public string Phone { get; private set; } = string.Empty;
public IEnumerable<OrderProducts> OrderProducts { get; private set;} = [];
[DisplayName("Время заказа")]
public DateTime DateTime { get; private set; }
[DisplayName("Имя заказчика")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Номер телефона")]
public string Phone { get; private set; } = string.Empty;
[DisplayName("Список продуктов")]
public string Products => OrderProducts != null ?string.Join(", ", OrderProducts.Select(x => $"{x.ProductName} {x.Count}")) : string.Empty;
[Browsable(false)]
public IEnumerable<OrderProducts> OrderProducts { get; private set;} = [];
public static Order CreateOpeartion(int id, string name, string phone, IEnumerable<OrderProducts> orderProducts)
{
return new Order
@ -33,4 +46,12 @@ public class Order
DateTime = tempOrderPoducts.DateTime
};
}
public void SetOrderProducts(IEnumerable<OrderProducts> orderProducts)
{
if (orderProducts != null && orderProducts.Any())
{
OrderProducts = orderProducts;
}
}
}

View File

@ -5,6 +5,7 @@ public class OrderProducts
{
public int Id { get; private set; }
public int ProductId { get; private set; }
public string ProductName { get; private set; } = string.Empty;
public int Count { get; private set; }
public decimal Price { get; private set; }

View File

@ -1,14 +1,26 @@
using ConfectFactory.Entities;
using ProjectConfectFactory.Entities.Enums;
using System.ComponentModel;
namespace ProjectConfectFactory.Entities;
public class Product
{
public int Id { get; private set; }
[DisplayName("Наименование")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Тип продукта")]
public ProductType ProductType { get; private set; }
[DisplayName("Рецепт")]
public string Products => Recipe != null ? string.Join(", ", Recipe.Select(x => $"{x.ComponentName} {x.CountComponent}")) : string.Empty;
[Browsable(false)]
public IEnumerable<Recipe> Recipe { get; private set; } = [];
[DisplayName("Цена")]
public decimal Price { get; private set; }
public static Product CreateEntity(int id, string name, ProductType productType, IEnumerable<Recipe> recipe, decimal price)
@ -35,4 +47,12 @@ public class Product
Price = tempRecipe.Price
};
}
public void SetRecipe(IEnumerable<Recipe> recipe)
{
if (recipe != null && recipe.Any())
{
Recipe = recipe;
}
}
}

View File

@ -1,12 +1,29 @@
namespace ProjectConfectFactory.Entities;
using System.ComponentModel;
namespace ProjectConfectFactory.Entities;
//Закупка
public class Purchase
{
public int Id { get; private set; }
public DateTime DateTime { get; private set; }
[Browsable(false)]
public int SellerId { get; private set; }
[Browsable(false)]
public int ComponentId { get; private set; }
[DisplayName("Время поставки")]
public DateTime DateTime { get; private set; }
[DisplayName("Поставщик")]
public string SellerName { get; private set; } = string.Empty;
[DisplayName("Компонент")]
public string ComponentName { get; private set; } = string.Empty;
[DisplayName("Количество")]
public decimal Count { get; private set; }
public static Purchase CreateOpeartion(int id, int sellerId, int componentId, decimal count)
{

View File

@ -5,6 +5,7 @@ public class Recipe
{
public int Id { get; private set; }
public int ComponentId { get; private set; }
public string ComponentName { get; private set; } = string.Empty;
public decimal CountComponent { get; private set; }
public static Recipe CreateElement(int id, int componentId, decimal countComponent)

View File

@ -1,12 +1,20 @@
using ProjectConfectFactory.Entities.Enums;
using MigraDoc.DocumentObjectModel;
using ProjectConfectFactory.Entities.Enums;
using System.ComponentModel;
namespace ProjectConfectFactory.Entities;
public class Seller
{
public int Id { get; private set; }
[DisplayName("Наименование")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Телефонный номер")]
public string Phone { get; private set; } = string.Empty;
[DisplayName("Тип доставки")]
public DeliveryType DeliveryTime { get; private set; }
public static Seller CreateEntity(int id, string name, string phone, DeliveryType deliveryTime)

View File

@ -13,7 +13,7 @@ public partial class FormComponentReport : Form
_container = container ?? throw new ArgumentNullException(nameof(container));
comboBoxComponent.DataSource = componentRepository.ReadComponents();
comboBoxComponent.DisplayMember = "Name";
comboBoxComponent.DisplayMember = "ComponentUnit";
comboBoxComponent.ValueMember = "Id";
}

View File

@ -23,6 +23,9 @@ public partial class FormComponents : Form
try
{
LoadList();
dataGridViewComponents.Columns["Id"].Visible = false;
dataGridViewComponents.Columns["ComponentUnit"].Visible = false;
}
catch (Exception ex)
{

View File

@ -43,7 +43,7 @@
panel1.Controls.Add(buttonDel);
panel1.Controls.Add(buttonAdd);
panel1.Dock = DockStyle.Right;
panel1.Location = new Point(657, 0);
panel1.Location = new Point(845, 0);
panel1.Name = "panel1";
panel1.Size = new Size(143, 450);
panel1.TabIndex = 1;
@ -88,14 +88,14 @@
dataGridViewOrders.RowHeadersVisible = false;
dataGridViewOrders.RowHeadersWidth = 51;
dataGridViewOrders.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewOrders.Size = new Size(657, 450);
dataGridViewOrders.Size = new Size(845, 450);
dataGridViewOrders.TabIndex = 2;
//
// FormOrders
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
ClientSize = new Size(988, 450);
Controls.Add(dataGridViewOrders);
Controls.Add(panel1);
MinimumSize = new Size(818, 497);

View File

@ -23,6 +23,8 @@ public partial class FormOrders : Form
try
{
LoadList();
dataGridViewOrders.Columns["Id"].Visible = false;
dataGridViewOrders.Columns["DateTime"].DefaultCellStyle.Format = "dd MMMM yyyy hh:mm";
}
catch (Exception ex)
{

View File

@ -21,7 +21,7 @@ public partial class FormProduct : Form
}
ColumnComponent.DataSource = componentRepository.ReadComponents();
ColumnComponent.DisplayMember = "Name";
ColumnComponent.DisplayMember = "ComponentUnit";
ColumnComponent.ValueMember = "Id";
}

View File

@ -45,7 +45,7 @@
panel1.Controls.Add(buttonDel);
panel1.Controls.Add(buttonAdd);
panel1.Dock = DockStyle.Right;
panel1.Location = new Point(780, 0);
panel1.Location = new Point(854, 0);
panel1.Name = "panel1";
panel1.Size = new Size(143, 450);
panel1.TabIndex = 2;
@ -101,14 +101,14 @@
dataGridViewProducts.RowHeadersVisible = false;
dataGridViewProducts.RowHeadersWidth = 51;
dataGridViewProducts.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewProducts.Size = new Size(780, 450);
dataGridViewProducts.Size = new Size(854, 450);
dataGridViewProducts.TabIndex = 3;
//
// FormProducts
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(923, 450);
ClientSize = new Size(997, 450);
Controls.Add(dataGridViewProducts);
Controls.Add(panel1);
MinimumSize = new Size(941, 497);

View File

@ -23,6 +23,7 @@ public partial class FormProducts : Form
try
{
LoadList();
dataGridViewProducts.Columns["Id"].Visible = false;
}
catch (Exception ex)
{

View File

@ -17,10 +17,9 @@ public partial class FormPurchase : Form
comboBoxSellerName.DataSource = sellerRepository.ReadSellers();
comboBoxSellerName.DisplayMember = "Name";
comboBoxSellerName.ValueMember = "Id";
comboBoxComponent.ValueMember = "ComponentId";
comboBoxComponent.DataSource = componentRepository.ReadComponents();
comboBoxComponent.DisplayMember = "Name";
comboBoxComponent.DisplayMember = "ComponentUnit";
comboBoxComponent.ValueMember = "Id";
}

View File

@ -40,7 +40,7 @@
panel1.BackColor = Color.Linen;
panel1.Controls.Add(buttonAdd);
panel1.Dock = DockStyle.Right;
panel1.Location = new Point(657, 0);
panel1.Location = new Point(736, 0);
panel1.Name = "panel1";
panel1.Size = new Size(143, 450);
panel1.TabIndex = 2;
@ -74,14 +74,14 @@
dataGridViewPurchases.RowHeadersVisible = false;
dataGridViewPurchases.RowHeadersWidth = 51;
dataGridViewPurchases.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewPurchases.Size = new Size(657, 450);
dataGridViewPurchases.Size = new Size(736, 450);
dataGridViewPurchases.TabIndex = 3;
//
// FormPurchases
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
ClientSize = new Size(879, 450);
Controls.Add(dataGridViewPurchases);
Controls.Add(panel1);
MinimumSize = new Size(818, 497);

View File

@ -23,6 +23,8 @@ public partial class FormPurchases : Form
try
{
LoadList();
dataGridViewPurchases.Columns["Id"].Visible = false;
dataGridViewPurchases.Columns["DateTime"].DefaultCellStyle.Format = "dd MMMM yyyy hh:mm";
}
catch (Exception ex)
{

View File

@ -22,6 +22,7 @@ public partial class FormSellers : Form
try
{
LoadList();
dataGridViewSellers.Columns["Id"].Visible = false;
}
catch (Exception ex)
{

View File

@ -22,7 +22,7 @@ internal class ChartReport
{
new PdfBuilder(filePath)
.AddHeader("Заказы")
.AddPieChart("Купленные продукты", GetData(dateTime))
.AddPieChart($"Купленные продукты на {dateTime:dd MMMM yyyy}", GetData(dateTime))
.Build();
return true;
@ -36,15 +36,14 @@ internal class ChartReport
private List<(string Caption, double Value)> GetData(DateTime dateTime)
{
return _orderRepository
.ReadOrder()
.Where(x => x.DateTime.Date == dateTime.Date)
.ReadOrder(dateForm: dateTime.Date, dateTo: dateTime.Date.AddDays(1))
.SelectMany(x => x.OrderProducts)
.GroupBy(x => x.ProductId, (key, group) => new
.GroupBy(x => x.ProductName, (key, group) => new
{
ProductId = key,
ProductName = key,
TotalCount = group.Sum(x => x.Count)
})
.Select(x => ($"{x.ProductId}", (double)x.TotalCount))
.Select(x => ($"{x.ProductName}", (double)x.TotalCount))
.ToList();
}
}

View File

@ -27,7 +27,7 @@ internal class TableReport
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по компонентам и проудктам", 0, 5)
.AddParagraph("за период", 0)
.AddParagraph($"за период c {startDate: dd.MM.yyyy} по {endDate: dd.MM.yyyy}", 0)
.AddTable([10, 10, 15, 10, 15], GetData(ComponentId, startDate, endDate))
.Build();
@ -44,24 +44,22 @@ internal class TableReport
{
var data =
_purchaseRepository
.ReadPurchases()
.Where(x => x.DateTime >= startDate && x.DateTime <= endDate && x.ComponentId == componentId)
.ReadPurchases(dateForm: startDate, dateTo: endDate, ComponentId: componentId)
.Select(x => new
{
SellerId = (int?)x.SellerId,
Date = (DateTime?)x.DateTime,
SellerName = (string?)x.SellerName,
Date = x.DateTime,
CountIn = (int?)x.Count,
ProductId = (int?)null,
ProductName = (string?)null,
CountOut = (int?)null
}).Union(
_orderRepository
.ReadOrder()
.Where(x => x.DateTime >= startDate && x.DateTime <= endDate)
.ReadOrder(dateForm: startDate, dateTo:endDate)
.Select(x => new {
SellerId = (int?)null,
Date = (DateTime?)x.DateTime,
SellerName = (string?)null,
Date = x.DateTime,
CountIn = (int?)null,
ProductId = (int?)x.OrderProducts.FirstOrDefault()?.ProductId,
ProductName = (string?)x.OrderProducts.FirstOrDefault()?.ProductName,
CountOut = (int?)x.OrderProducts.FirstOrDefault()?.Count
}))
.OrderBy(x => x.Date);
@ -69,14 +67,15 @@ internal class TableReport
return new List<string[]>() { item }
.Union(
data.Select(x => new string[] {
x.SellerId.ToString(),
x.Date.ToString(),
x.CountIn.ToString(),
x.ProductId.ToString(),
x.CountOut.ToString()
x.SellerName,
x.Date.ToString("dd.MM.yyyy"),
x.CountIn?.ToString("N0") ?? string.Empty,
x.ProductName,
x.CountOut?.ToString("N0") ?? string.Empty
}))
.Union(
[["Всего", "", data.Sum(x => x.CountIn).ToString(), "" ,data.Sum(x=> x.CountOut).ToString()]])
[["Всего", "", data.Sum(x => x.CountIn ?? 0).ToString("N0"), "" ,data.Sum(x=> x.CountOut ?? 0).ToString("N0")]])
.ToList();
}
}

View File

@ -1,16 +1,10 @@
using ProjectConfectFactory.Entities;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectConfectFactory.Repositories;
public interface IPurchaseRepository
{
IEnumerable<Purchase> ReadPurchases(DateTime? dateForm = null, DateTime? dateTo = null, int? SellerId = null, int? ComponentId = null, int? Count = null);
IEnumerable<Purchase> ReadPurchases(DateTime? dateForm = null, DateTime? dateTo = null, int? SellerId = null, int? ComponentId = null);
void CreatePurchase(Purchase purchase);
}

View File

@ -107,16 +107,39 @@ WHERE p.Id=@id";
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT p.*, pc.ComponentId, pc.CountComponent FROM Products p
INNER JOIN Recipe pc ON pc.ProductId = p.Id";
var products = connection.Query<TempRecipe>(querySelect);
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(products));
return products.GroupBy(x => x.Id, y => y,
(key, value) => Product.CreateEntity(value.First(),
value.Select(z => Recipe.
CreateElement(0, z.ComponentId, z.CountComponent)))).ToList();
var querySelect = @"SELECT
pr.*,
r.ComponentId,
r.CountComponent,
c.Name AS ""ComponentName""
FROM Products pr
LEFT JOIN recipe r ON r.productId = pr.Id
LEFT JOIN components c ON c.Id = r.ComponentId;";
var productDict = new Dictionary<int, List<Recipe>>();
var products = connection.Query<Product,
Recipe, Product>(querySelect,
(Recipes, product) =>
{
if (!productDict.TryGetValue(Recipes.Id, out var r))
{
r = [];
productDict.Add(Recipes.Id, r);
}
r.Add(product);
return Recipes;
}, splitOn: "ComponentId", param: new
{
});
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(products));
return productDict.Select(x =>
{
var fr = products.First(y => y.Id == x.Key);
fr.SetRecipe(x.Value);
return fr;
}).ToArray();
}
catch (Exception ex)
{

View File

@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectConfectFactory.Entities;
using System.ComponentModel;
namespace ProjectConfectFactory.Repositories.Implementations;
@ -80,18 +81,55 @@ WHERE Id=@id";
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateForm.HasValue)
{
builder.AddCondition("o.DateTime >= @dateForm");
}
if (dateTo.HasValue)
{
builder.AddCondition("o.DateTime <= @dateTo");
}
if (ProductId.HasValue)
{
builder.AddCondition("o.ProductId = @ProductId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT o.*, orr.ProductId, orr.Count, orr.Price FROM orders o
INNER JOIN orderProduct orr ON orr.OrderId = o.Id";
var orders =
connection.Query<TempOrderProducts>(querySelect);
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(orders));
return orders.GroupBy(x => x.Id, y => y,
(key, value) =>
Order.CreateOpeartion(value.First(),
value.Select(z => OrderProducts.CreateElement(0, z.ProductId, z.Count,z.Price)))).ToList();
var querySelect = $@"SELECT o.*,
orr.ProductId,
orr.Count,
p.Name as ""ProductName""
FROM Orders o
INNER JOIN OrderProduct orr ON orr.OrderId = o.Id
LEFT JOIN products p on p.Id = orr.ProductId
{builder.Build()}";
var orderDict = new Dictionary<int,List<OrderProducts>>();
var orders = connection.Query<Order,
OrderProducts, Order>(querySelect,
(orderProducts, order) =>
{
if (!orderDict.TryGetValue(orderProducts.Id, out var frr))
{
frr = [];
orderDict.Add(orderProducts.Id, frr);
}
frr.Add(order);
return orderProducts;}, splitOn: "ProductId", param: new {
dateForm,
dateTo,
ProductId});
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(orders));
return orderDict.Select(x =>
{
var fr = orders.First(y => y.Id == x.Key);
fr.SetOrderProducts(x.Value);
return fr;
}).ToArray();
}
catch (Exception ex)
{

View File

@ -38,15 +38,40 @@ VALUES (@DateTime, @SellerId, @ComponentId, @Count)";
}
}
public IEnumerable<Purchase> ReadPurchases(DateTime? dateForm = null, DateTime? dateTo = null, int? SellerId = null, int? ComponentId = null, int? Count = null)
public IEnumerable<Purchase> ReadPurchases(DateTime? dateForm = null, DateTime? dateTo = null, int? SellerId = null, int? ComponentId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateForm.HasValue)
{
builder.AddCondition("p.DateTime >= @dateForm");
}
if (dateTo.HasValue)
{
builder.AddCondition("p.DateTime <= @dateTo");
}
if (ComponentId.HasValue)
{
builder.AddCondition("p.ComponentId = @ComponentId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Purchases";
var querySelect = $@"SELECT p.*,
s.Name as ""SellerName"",
c.Name as ""ComponentName""
FROM Purchases p
LEFT JOIN Sellers s on s.Id = p.SellerId
LEFT JOIN Components c on c.Id = p.ComponentId
{builder.Build()}";
var purchases =
connection.Query<Purchase>(querySelect);
connection.Query<Purchase>(querySelect, new
{
dateForm,
dateTo,
ComponentId
});
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(purchases));
return purchases;

View File

@ -0,0 +1,35 @@
using System.Text;
namespace ProjectConfectFactory.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}";
}
}