ПИбд-21. Шипилов Н.С. Лабораторная работа №4 #4

Closed
NikitaShipilov wants to merge 3 commits from LabWork_4 into LabWork_3
25 changed files with 272 additions and 81 deletions

View File

@ -1,12 +1,18 @@
using ProjectGasStation.Entities.Enums;
using System.ComponentModel;
namespace ProjectGasStation.Entities;
public class Contractor
{
public int Id { get; private set; }
[DisplayName("Название")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Поставляемое топливо")]
public ContractorFuelType Types { get; private set; }
public static Contractor CreateContractor(int id, string name, ContractorFuelType types)
{
return new Contractor { Id = id, Name = name, Types = types };

View File

@ -1,18 +1,39 @@
namespace ProjectGasStation.Entities;
using ProjectGasStation.Entities.Enums;
using System.ComponentModel;
namespace ProjectGasStation.Entities;
public class ContractorFuel
{
public int Id { get; private set; }
[Browsable(false)]
public int ContractorId { get; private set; }
[DisplayName("Поставщик")]
public string ContractorName { get; private set; } = string.Empty;
[DisplayName("Дата поставки")]
public DateTime Date { get; private set; }
[DisplayName("Топливо")]
public string Fuel => ContractorFuelFuel != null ?
string.Join(", ", ContractorFuelFuel.Select(x => $"{(FuelType)x.FuelName} {x.Quantity}")) :
string.Empty;
[Browsable(false)]
public IEnumerable<ContractorFuelFuel> ContractorFuelFuel { get; private set; } = [];
public static ContractorFuel CreateContractorFuel(int id, int contractorId, DateTime date, IEnumerable<ContractorFuelFuel> contractorFuelFuel)
{
return new ContractorFuel { Id = id, ContractorId = contractorId, Date = date, ContractorFuelFuel = contractorFuelFuel};
}
public static ContractorFuel CreateContractorFuel(TempContractorFuelFuel tempContractorFuelFuel, IEnumerable<ContractorFuelFuel> contractorFuelFuel)
public void SetContractorFuelFuel(IEnumerable<ContractorFuelFuel> contractorFuelFuel)
{
return new ContractorFuel { Id = tempContractorFuelFuel.Id, ContractorId = tempContractorFuelFuel.ContractorId, Date = tempContractorFuelFuel.Date, ContractorFuelFuel = contractorFuelFuel };
if (contractorFuelFuel != null && contractorFuelFuel.Any())
{
ContractorFuelFuel = contractorFuelFuel;
}
}
}

View File

@ -3,8 +3,13 @@
public class ContractorFuelFuel
{
public int Id { get; private set; }
public int FuelId { get; private set; }
public int FuelName { get; private set; }
public int Quantity { get; private set; }
public static ContractorFuelFuel CreateContractorFuelFuel(int id, int fuelId, int quantity)
{
return new ContractorFuelFuel { Id = id, FuelId = fuelId, Quantity = quantity };

View File

@ -1,12 +1,18 @@
using ProjectGasStation.Entities.Enums;
using System.ComponentModel;
namespace ProjectGasStation.Entities;
public class Fuel
{
public int Id { get; private set; }
[DisplayName("Тип топлива")]
public FuelType Type { get; private set; }
[DisplayName("Цена")]
public double Price { get; private set; }
public static Fuel CreateFuel(int id, FuelType type, double price)
{
return new Fuel { Id = id, Type = type, Price = price };

View File

@ -3,8 +3,13 @@
public class FuelFuelSale
{
public int Id { get; private set; }
public int FuelId { get; private set; }
public int FuelName { get; private set; }
public int Quantity { get; private set; }
public static FuelFuelSale CreateFuelFuelSale(int id, int fuelId, int quantity)
{
return new FuelFuelSale { Id = id, FuelId = fuelId, Quantity = quantity};

View File

@ -1,11 +1,36 @@
namespace ProjectGasStation.Entities;
using ProjectGasStation.Entities.Enums;
using System.ComponentModel;
namespace ProjectGasStation.Entities;
public class FuelSale
{
public int Id { get; private set; }
[Browsable(false)]
public int SalespersonId { get; private set; }
[Browsable(false)]
public int ShiftId { get; private set; }
[DisplayName("Продавец")]
public string SalespersonName { get; private set; } = string.Empty;
[Browsable(false)]
public int TypeShift { get; private set; }
[DisplayName("Смена")]
public string ShiftName => $"{SaleDate.Date.ToString("dd.MM.yyyy")} {(ShiftType)TypeShift}";
[Browsable(false)]
public DateTime SaleDate { get; private set; }
[DisplayName("Топливо")]
public string Fuel => FuelFuelSale != null ?
string.Join(", ", FuelFuelSale.Select(x => $"{(FuelType)x.FuelName} {x.Quantity}")) :
string.Empty;
[Browsable(false)]
public IEnumerable<FuelFuelSale> FuelFuelSale { get; private set; } = [];
public static FuelSale CreateFuelSale(int id, int salesPersonId, int shiftId, DateTime saleDate, IEnumerable<FuelFuelSale> fuelFuelSale)
@ -20,15 +45,11 @@ public class FuelSale
};
}
public static FuelSale CreateFuelSale(TempFuelFuelSale tempFuelFuelSale, IEnumerable<FuelFuelSale> fuelFuelSale)
public void SetFuelFuelSale(IEnumerable<FuelFuelSale> fuelFuelSale)
{
return new FuelSale
if(fuelFuelSale != null && fuelFuelSale.Any())
{
Id = tempFuelFuelSale.Id,
SalespersonId = tempFuelFuelSale.SalespersonId,
ShiftId = tempFuelFuelSale.ShiftId,
SaleDate = tempFuelFuelSale.SaleDate,
FuelFuelSale = fuelFuelSale
};
FuelFuelSale = fuelFuelSale;
}
}
}

View File

@ -1,10 +1,17 @@
namespace ProjectGasStation.Entities;
using System.ComponentModel;
namespace ProjectGasStation.Entities;
public class Salesperson
{
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 static Salesperson CreateSalesperson(int id, string firstName, string lastName)
{
return new Salesperson { Id = id, FirstName = firstName, LastName = lastName };

View File

@ -1,15 +1,26 @@
using ProjectGasStation.Entities.Enums;
using System.ComponentModel;
namespace ProjectGasStation.Entities;
public class Shift
{
public int Id { get; private set; }
[DisplayName("Время начала")]
public TimeSpan StartTime { get; private set; }
[DisplayName("Время конца")]
public TimeSpan EndTime { get; private set; }
[DisplayName("Дата")]
public DateTime Date { get; private set; }
[DisplayName("Тип смены")]
public ShiftType Type { get; private set; }
public string DisplayName => $"{Date:yyyy-MM-dd} ({Type})";
public static Shift CreateShift(int id, TimeSpan startTime, TimeSpan endTime, DateTime date, ShiftType type)
{
return new Shift { Id = id, EndTime = endTime, StartTime = startTime, Date = date, Type = type };

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities;
public class TempContractorFuelFuel
{
public int Id { get; private set; }
public int ContractorId { get; private set; }
public DateTime Date { get; private set; }
public int FuelId { get; private set; }
public int Quantity { get; private set; }
}

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities;
public class TempFuelFuelSale
{
public int Id { get; private set; }
public int SalespersonId { get; private set; }
public int ShiftId { get; private set; }
public DateTime SaleDate { get; private set; }
public int FuelId { get; private set; }
public int Quantity { get; private set; }
}

View File

@ -19,7 +19,7 @@ public partial class FormContractorFuels : Form
try
{
LoadList();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
@ -63,7 +63,11 @@ public partial class FormContractorFuels : Form
}
}
private void LoadList() => dataGridViewData.DataSource = _contractorFuelRepository.ReadContractorFuels();
private void LoadList()
{
dataGridViewData.DataSource = _contractorFuelRepository.ReadContractorFuels();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{

View File

@ -82,7 +82,11 @@ public partial class FormContractors : Form
}
}
private void LoadList() => dataGridViewData.DataSource = _contractorRepository.ReadContractors();
private void LoadList()
{
dataGridViewData.DataSource = _contractorRepository.ReadContractors();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{

View File

@ -19,7 +19,7 @@ public partial class FormFuelSales : Form
try
{
LoadList();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
@ -62,7 +62,11 @@ public partial class FormFuelSales : Form
}
}
private void LoadList() => dataGridViewData.DataSource = _fuelSaleRepository.ReadFuelSales();
private void LoadList()
{
dataGridViewData.DataSource = _fuelSaleRepository.ReadFuelSales();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{

View File

@ -19,7 +19,7 @@ public partial class FormFuels : Form
try
{
LoadList();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
@ -82,7 +82,11 @@ public partial class FormFuels : Form
}
}
private void LoadList() => dataGridViewData.DataSource = _fuelRepository.ReadFuels();
private void LoadList()
{
dataGridViewData.DataSource = _fuelRepository.ReadFuels();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{

View File

@ -82,7 +82,11 @@ public partial class FormSalespersons : Form
}
}
private void LoadList() => dataGridViewData.DataSource = _salespersonRepository.ReadSalespersons();
private void LoadList()
{
dataGridViewData.DataSource = _salespersonRepository.ReadSalespersons();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{

View File

@ -19,7 +19,7 @@ public partial class FormShifts : Form
try
{
LoadList();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
@ -82,7 +82,12 @@ public partial class FormShifts : Form
}
}
private void LoadList() => dataGridViewData.DataSource = _shiftRepository.ReadShifts();
private void LoadList()
{
dataGridViewData.DataSource = _shiftRepository.ReadShifts();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["DisplayName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{

View File

@ -23,7 +23,7 @@ internal class ChartReport
{
new PdfBuilder(filePath)
.AddHeader("Поставки топлива")
.AddPieChart("Виды топлива", GetData(dateTime))
.AddPieChart($"Поставленные виды топлива на {dateTime:dd.MM.yyyy}", GetData(dateTime))
.Build();
return true;
}
@ -39,8 +39,7 @@ internal class ChartReport
.ToDictionary(f => f.Id, f => f.Type);
return _contractorFuelRepository
.ReadContractorFuels()
.Where(x => x.Date.Date == dateTime.Date)
.ReadContractorFuels(dateFrom: dateTime.Date, dateTo: dateTime.Date.AddDays(1))
.SelectMany(x => x.ContractorFuelFuel)
.GroupBy(x => x.FuelId)
.Select(g => (Caption: fuelNames[g.Key].ToString(), Value: (double)g.Sum(x => x.Quantity)))

View File

@ -23,7 +23,7 @@ internal class TableReport
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по движению топлива", 0, 3)
.AddParagraph("за период", 0)
.AddParagraph($"за период {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0)
.AddTable([10, 15, 15], GetData(fuelId, startDate, endDate))
.Build();
return true;
@ -38,13 +38,11 @@ internal class TableReport
private List<string[]> GetData(int fuelId, DateTime startDate, DateTime endDate)
{
var data = _contractorFuelRepository
.ReadContractorFuels()
.Where(x => x.Date >= startDate && x.Date <= endDate && x.ContractorFuelFuel.Any(y => y.FuelId == fuelId))
.ReadContractorFuels(startDate, endDate, fuelId)
.Select(x => new { x.Date, CountIn = x.ContractorFuelFuel.FirstOrDefault(y => y.FuelId == fuelId)?.Quantity, CountOut = (int?)null})
.Union(
_fuelSaleRepository
.ReadFuelSales()
.Where(x => x.SaleDate >= startDate && x.SaleDate <= endDate && x.FuelFuelSale.Any(y => y.FuelId == fuelId))
.ReadFuelSales(startDate, endDate, fuelId)
.Select(x => new { Date = x.SaleDate, CountIn = (int?)null, CountOut = x.FuelFuelSale.FirstOrDefault(y => y.FuelId == fuelId)?.Quantity })
)
.OrderBy(x => x.Date);
@ -62,9 +60,9 @@ internal class TableReport
return
new List<string[]>() { item }
.Union( groupedData
.Select(x => new string[] { x.Date.ToString("dd.MM.yyyy"), x.TotalIn.ToString()!, x.TotalOut.ToString()! }))
.Select(x => new string[] { x.Date.ToString("dd.MM.yyyy"), x.TotalIn?.ToString("N0") ?? string.Empty, x.TotalOut?.ToString("N0") ?? string.Empty }))
.Union(
new[] { new string[] { "Всего", groupedData.Sum(x => x.TotalIn).ToString()!, groupedData.Sum(x => x.TotalOut).ToString()! } }
new[] { new string[] { "Всего", groupedData.Sum(x => x.TotalIn)?.ToString("N0") ?? string.Empty, groupedData.Sum(x => x.TotalOut)?.ToString("N0") ?? string.Empty } }
)
.ToList();
}

View File

@ -4,7 +4,7 @@ namespace ProjectGasStation.Repositories;
public interface IContractorFuelRepository
{
IEnumerable<ContractorFuel> ReadContractorFuels(DateTime? dateFrom = null, DateTime? dateTo = null, int? contractorId = null,
IEnumerable<ContractorFuel> ReadContractorFuels(DateTime? dateFrom = null, DateTime? dateTo = null,
int? fuelId = null);
void CreateContractorFuel(ContractorFuel contractorFuel);
void DeleteContractorFuel(int id);

View File

@ -4,8 +4,8 @@ namespace ProjectGasStation.Repositories;
public interface IFuelSaleRepository
{
IEnumerable<FuelSale> ReadFuelSales(DateTime? dateFrom = null, DateTime? dateTo = null, int? gasStationId = null,
int? fuelId = null, int? salespersonId = null, int? shiftId = null);
IEnumerable<FuelSale> ReadFuelSales(DateTime? dateFrom = null, DateTime? dateTo = null,
int? fuelId = null);
void CreateFuelSale(FuelSale fuel);
void DeleteFuelSale(int id);
}

View File

@ -4,7 +4,7 @@ namespace ProjectGasStation.Repositories;
public interface IShiftRepository
{
IEnumerable<Shift> ReadShifts(DateTime? dateFrom = null, DateTime? dateTo = null);
IEnumerable<Shift> ReadShifts();
Shift ReadShiftById(int id);
void CreateShift(Shift shift);
void UpdateShift(Shift shift);

View File

@ -1,7 +1,9 @@
using Dapper;
using DocumentFormat.OpenXml.Spreadsheet;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using PdfSharp.Pdf;
using ProjectGasStation.Entities;
using System.Transactions;
@ -84,19 +86,60 @@ public class ContractorFuelRepository : IContractorFuelRepository
}
}
public IEnumerable<ContractorFuel> ReadContractorFuels(DateTime? dateFrom = null, DateTime? dateTo = null, int? contractorId = null,
public IEnumerable<ContractorFuel> ReadContractorFuels(DateTime? dateFrom = null, DateTime? dateTo = null,
int? fuelId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateFrom.HasValue)
{
builder.AddCondition("cf.Date >= @dateFrom");
}
if (dateTo.HasValue)
{
builder.AddCondition("cf.Date <= @dateTo");
}
if (fuelId.HasValue)
{
builder.AddCondition("cff.FuelId = @fuelId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT cf.*, cff.FuelId, cff.Quantity FROM ContractorFuel cf
INNER JOIN ContractorFuelFuel cff on cff.ContractorFuelId = cf.Id";
var contractorFuels = connection.Query<TempContractorFuelFuel>(querySelect);
var querySelect = $@"SELECT
cf.*,
c.Name as ContractorName,
cff.FuelId,
cff.Quantity,
f.Type as FuelName
FROM ContractorFuel cf
LEFT JOIN Contractor c on c.Id = cf.ContractorId
INNER JOIN ContractorFuelFuel cff on cff.ContractorFuelId = cf.Id
LEFT JOIN Fuel f on f.Id = cff.FuelId
{builder.Build()}";
var contractorsDict = new Dictionary<int, List<ContractorFuelFuel>>();
var contractorFuels = connection.Query<ContractorFuel, ContractorFuelFuel, ContractorFuel>(querySelect,
(contractor, contractorFuel) =>
{
if (!contractorsDict.TryGetValue(contractor.Id, out var ccf))
{
ccf = [];
contractorsDict.Add(contractor.Id, ccf);
}
ccf.Add(contractorFuel);
return contractor;
}, splitOn: "FuelId", param: new { dateFrom, dateTo, fuelId });
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(contractorFuels));
return contractorFuels.GroupBy(x => x.Id, y => y, (key, value) => ContractorFuel.CreateContractorFuel(value.First(), value.Select(z => ContractorFuelFuel.CreateContractorFuelFuel(0, z.FuelId, z.Quantity)))).ToList();
return contractorsDict.Select(x =>
{
var cf = contractorFuels.First(y => y.Id == x.Key);
cf.SetContractorFuelFuel(x.Value);
return cf;
}).ToArray();
}
catch (Exception ex)
{

View File

@ -55,18 +55,61 @@ public class FuelSaleRepository : IFuelSaleRepository
}
}
public IEnumerable<FuelSale> ReadFuelSales(DateTime? dateFrom = null, DateTime? dateTo = null, int? gasStationId = null, int? fuelId = null, int? salespersonId = null, int? shiftId = null)
public IEnumerable<FuelSale> ReadFuelSales(DateTime? dateFrom = null, DateTime? dateTo = null, int? fuelId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateFrom.HasValue)
{
builder.AddCondition("fs.SaleDate >= @dateFrom");
}
if (dateTo.HasValue)
{
builder.AddCondition("fs.SaleDate <= @dateTo");
}
if (fuelId.HasValue)
{
builder.AddCondition("ffs.FuelId = @fuelId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT fs.*, ffs.FuelId, ffs.Quantity FROM FuelSale fs
INNER JOIN FuelFuelSale ffs on ffs.FuelSaleId = fs.Id";
var fuelSales = connection.Query<TempFuelFuelSale>(querySelect);
var querySelect = $@"SELECT
fs.*,
CONCAT(s.LastName, ' ', s.FirstName) as SalespersonName,
sh.Type as TypeShift,
ffs.FuelId,
ffs.Quantity,
f.Type as FuelName
FROM FuelSale fs
LEFT JOIN Salesperson s on s.Id = fs.SalespersonId
LEFT JOIN Shift sh on sh.id = fs.ShiftId
INNER JOIN FuelFuelSale ffs on ffs.FuelSaleId = fs.Id
LEFT JOIN Fuel f on f.id = ffs.FuelId
{builder.Build()}";
var salesDict = new Dictionary<int, List<FuelFuelSale>>();
var fuelSales = connection.Query<FuelSale, FuelFuelSale, FuelSale>(querySelect,
(sale, fuelSale) =>
{
if (!salesDict.TryGetValue(sale.Id, out var fss))
{
fss = [];
salesDict.Add(sale.Id, fss);
}
fss.Add(fuelSale);
return sale;
}, splitOn: "FuelId", param: new { dateFrom, dateTo, fuelId });
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(fuelSales));
return fuelSales.GroupBy(x => x.Id, y => y, (key, value) => FuelSale.CreateFuelSale(value.First(), value.Select(z => FuelFuelSale.CreateFuelFuelSale(0, z.FuelId, z.Quantity)))).ToList();
return salesDict.Select(x =>
{
var fs = fuelSales.First(y => y.Id == x.Key);
fs.SetFuelFuelSale(x.Value);
return fs;
}).ToArray();
}
catch (Exception ex)
{

View File

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

View File

@ -78,7 +78,7 @@ public class ShiftRepository : IShiftRepository
}
}
public IEnumerable<Shift> ReadShifts(DateTime? dateFrom = null, DateTime? dateTo = null)
public IEnumerable<Shift> ReadShifts()
{
_logger.LogInformation("Получение всех объектов");
try