ПИбд-21. Басалов А.Д. Лабораторная 4 #4

Closed
Tonby73 wants to merge 7 commits from LabWork_4 into LabWork_3
21 changed files with 325 additions and 67 deletions

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -8,10 +9,21 @@ namespace ProjectTourAgency.Enities
{
public class AddMoney
{
[Browsable(false)]
public int Id { get; private set; }
[DisplayName("ID Клиента")]
public int ClientId { get; private set; }
[DisplayName("Дата")]
public DateTime Date { get; private set; }
public int MoneyAmount{ get; private set; }
[DisplayName("Размер Пополнение")]
public int MoneyAmount { get; private set; }
[DisplayName("Клиент")]
public string ClientName { get; private set; } = string.Empty;
public static AddMoney CreateEntity(int id,int cId,
DateTime date, int money)

View File

@ -1,6 +1,7 @@
using ProjectTourAgency.Enities.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -9,11 +10,22 @@ namespace ProjectTourAgency.Enities;
public class Client
{
public int Id { get; private set; }
[DisplayName("Полное имя")]
public string FullName { get; private set; } = string.Empty;
[DisplayName("Дата рождения")]
public DateTime BirthDate { get; private set; }
[DisplayName("Номер телефона")]
public string PhoneNumber { get; private set; } = string.Empty;
[DisplayName("Статус клиента")]
public ClientStatus ClientStatus { get; private set; }
[DisplayName("Баланс")]
public int Money { get; private set; }
public static Client CreateEntity(int id, string fullName,

View File

@ -11,6 +11,8 @@ public class ClientTour
{
public int Id { get; private set; }
public int ClientId { get; private set; }
public string CLientName { get; private set; } = String.Empty;
public int TourId { get; private set; }
public int Cost { get; private set; }

View File

@ -1,6 +1,7 @@
using ProjectTourAgency.Enities.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -10,10 +11,16 @@ namespace ProjectTourAgency.Enities;
public class Employee
{
public int Id { get; private set; }
[DisplayName("Полное имя")]
public string FullName { get; private set; } = string.Empty;
public string EmployeeName => $"{EmployeeJob} {FullName}";
[DisplayName("Должность")]
public EmpoyeeJob EmployeeJob { get; private set; }
public static Employee CreateEntity(int id, string fullName,
EmpoyeeJob job)
{

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -9,9 +10,17 @@ namespace ProjectTourAgency.Enities;
public class Route
{
public int Id { get; private set; }
[DisplayName("Место назначения")]
public string Destination { get; private set; } = string.Empty;
[DisplayName("Место отбытия")]
public string Departure { get; private set; } = string.Empty;
[DisplayName("Продолжительность")]
public int Duration { get; private set; }
public string DepartureDestination => $"{Departure} - {Destination}";
public static Route CreateEntity(int id, string destination,
string departure, int duration)
{

View File

@ -1,6 +1,7 @@
using ProjectTourAgency.Enities.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -9,11 +10,34 @@ namespace ProjectTourAgency.Enities;
public class Tour
{
[DisplayName("Id Тура")]
public int Id { get; private set; }
[Browsable(false)]
public int EmployeeId { get; private set; }
[Browsable(false)]
public int RouteId { get; private set; }
[DisplayName("Сотрудник")]
public string EmployeeName { get; private set; } = string.Empty;
[DisplayName("Маршрут")]
public string RouteName { get; private set; } = string.Empty;
[DisplayName("Дата начала тура")]
public DateTime DepartureDate { get; private set; }
[Browsable(false)]
public IEnumerable<ClientTour> ClientTours { get; private set; } = [];
[DisplayName("Клиенты")]
public string Clients => ClientTours != null ?
string.Join(",", ClientTours.Select(x => $"{x.CLientName} {x.Cost}")) : string.Empty;
public static Tour CreateEntity(int id, int employeeId, int routeId,
DateTime date,IEnumerable<ClientTour> clientTours)
{
@ -38,4 +62,12 @@ public class Tour
ClientTours = clientTours
};
}
public void SetClientTours(IEnumerable<ClientTour> clientTours)
{
if(clientTours != null && clientTours.Any())
{
ClientTours = clientTours;
}
}
}

View File

@ -20,9 +20,9 @@ namespace ProjectTourAgency.Forms
InitializeComponent();
_addMoneyRepository = addMoneyRepository ??
throw new ArgumentNullException(nameof(addMoneyRepository));
comboBoxClientId.DataSource = clientRepository.ReadClients();
comboBoxClientId.DisplayMember = "Name";
comboBoxClientId.ValueMember = "Id";
comboBoxClientId.DataSource = addMoneyRepository.ReadAddMoneys();
comboBoxClientId.DisplayMember = "ClientName";
comboBoxClientId.ValueMember = "ClientId";
}
private void buttonSave_Click(object sender, EventArgs e)

View File

@ -51,7 +51,13 @@ namespace ProjectTourAgency.Forms
}
private void LoadList() => dataGridViewData.DataSource = _addMoneyRepository.ReadAddMoneys();
private void LoadList()
{
dataGridViewData.DataSource = _addMoneyRepository.ReadAddMoneys();
dataGridViewData.Columns["Date"].DefaultCellStyle.Format = "dd.MM.yy";
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{

View File

@ -25,11 +25,11 @@ namespace ProjectTourAgency.Forms
_tourRepository = tourRepository ??
throw new ArgumentNullException(nameof(tourRepository));
comboBoxEmployeeId.DataSource = employeeRepository.ReadEmployees();
comboBoxEmployeeId.DisplayMember = "FullName";
comboBoxEmployeeId.DisplayMember = "EmployeeName";
comboBoxEmployeeId.ValueMember = "Id";
comboBoxRouteId.DataSource = routeRepository.ReadRoutes();
comboBoxRouteId.DisplayMember = "Destination";
comboBoxRouteId.DisplayMember = "DepartureDestination";
comboBoxRouteId.ValueMember = "Id";
ColumnClient.DataSource = clientRepository.ReadClients();

View File

@ -1,4 +1,5 @@
using ProjectTourAgency.Repositories;
using ProjectTourAgency.Implementations;
using ProjectTourAgency.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@ -93,8 +94,13 @@ namespace ProjectTourAgency.Forms
}
}
private void LoadList() => dataGridViewData.DataSource = _clientRepository.ReadClients();
private void LoadList()
{
dataGridViewData.DataSource = _clientRepository.ReadClients();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -95,8 +95,13 @@ namespace ProjectTourAgency.Forms
}
}
private void LoadList() => dataGridViewData.DataSource = _employeeRepository.ReadEmployees();
private void LoadList()
{
dataGridViewData.DataSource = _employeeRepository.ReadEmployees();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["EmployeeName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -34,62 +34,106 @@
buttonMakeReport = new Button();
comboBoxTour = new ComboBox();
textBoxFilePath = new TextBox();
labelFilePAth = new Label();
label1 = new Label();
label2 = new Label();
label3 = new Label();
SuspendLayout();
//
// dateTimePickerDateEnd
//
dateTimePickerDateEnd.Location = new Point(58, 155);
dateTimePickerDateEnd.Location = new Point(148, 221);
dateTimePickerDateEnd.Name = "dateTimePickerDateEnd";
dateTimePickerDateEnd.Size = new Size(201, 31);
dateTimePickerDateEnd.Size = new Size(280, 31);
dateTimePickerDateEnd.TabIndex = 0;
//
// dateTimePickerDateBegin
//
dateTimePickerDateBegin.Location = new Point(58, 105);
dateTimePickerDateBegin.Location = new Point(148, 164);
dateTimePickerDateBegin.Name = "dateTimePickerDateBegin";
dateTimePickerDateBegin.Size = new Size(201, 31);
dateTimePickerDateBegin.Size = new Size(280, 31);
dateTimePickerDateBegin.TabIndex = 1;
//
// buttonSelectFilePath
//
buttonSelectFilePath.Location = new Point(148, 47);
buttonSelectFilePath.Location = new Point(396, 59);
buttonSelectFilePath.Name = "buttonSelectFilePath";
buttonSelectFilePath.Size = new Size(112, 34);
buttonSelectFilePath.Size = new Size(32, 34);
buttonSelectFilePath.TabIndex = 2;
buttonSelectFilePath.Text = "button1";
buttonSelectFilePath.Text = "..";
buttonSelectFilePath.UseVisualStyleBackColor = true;
buttonSelectFilePath.Click += buttonSelectFilePath_Click;
//
// buttonMakeReport
//
buttonMakeReport.Location = new Point(144, 234);
buttonMakeReport.Location = new Point(148, 278);
buttonMakeReport.Name = "buttonMakeReport";
buttonMakeReport.Size = new Size(112, 34);
buttonMakeReport.Size = new Size(182, 34);
buttonMakeReport.TabIndex = 3;
buttonMakeReport.Text = "button2";
buttonMakeReport.Text = "Сформировать";
buttonMakeReport.UseVisualStyleBackColor = true;
buttonMakeReport.Click += buttonMakeReport_Click;
//
// comboBoxTour
//
comboBoxTour.FormattingEnabled = true;
comboBoxTour.Location = new Point(298, 157);
comboBoxTour.Location = new Point(148, 110);
comboBoxTour.Name = "comboBoxTour";
comboBoxTour.Size = new Size(182, 33);
comboBoxTour.TabIndex = 4;
//
// textBoxFilePath
//
textBoxFilePath.Location = new Point(279, 47);
textBoxFilePath.Location = new Point(148, 59);
textBoxFilePath.Name = "textBoxFilePath";
textBoxFilePath.Size = new Size(150, 31);
textBoxFilePath.Size = new Size(242, 31);
textBoxFilePath.TabIndex = 5;
//
// labelFilePAth
//
labelFilePAth.AutoSize = true;
labelFilePAth.Location = new Point(12, 47);
labelFilePAth.Name = "labelFilePAth";
labelFilePAth.Size = new Size(118, 25);
labelFilePAth.TabIndex = 6;
labelFilePAth.Text = "Путь к файлу";
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(12, 118);
label1.Name = "label1";
label1.Size = new Size(73, 25);
label1.TabIndex = 7;
label1.Text = "ID Тура";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(12, 169);
label2.Name = "label2";
label2.Size = new Size(110, 25);
label2.TabIndex = 8;
label2.Text = "Дата начала";
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(12, 221);
label3.Name = "label3";
label3.Size = new Size(105, 25);
label3.TabIndex = 9;
label3.Text = "Дата Конца";
//
// FormExcelReport
//
AutoScaleDimensions = new SizeF(10F, 25F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
ClientSize = new Size(507, 342);
Controls.Add(label3);
Controls.Add(label2);
Controls.Add(label1);
Controls.Add(labelFilePAth);
Controls.Add(textBoxFilePath);
Controls.Add(comboBoxTour);
Controls.Add(buttonMakeReport);
@ -110,5 +154,9 @@
private Button buttonMakeReport;
private ComboBox comboBoxTour;
private TextBox textBoxFilePath;
private Label labelFilePAth;
private Label label1;
private Label label2;
private Label label3;
}
}

View File

@ -1,4 +1,5 @@
using ProjectRouteAgency.Repositories;
using ProjectTourAgency.Implementations;
using ProjectTourAgency.Repositories;
using System;
using System.Collections.Generic;
@ -94,8 +95,13 @@ namespace ProjectTourAgency.Forms
}
}
private void LoadList() => dataGridViewData.DataSource = _routeRepository.ReadRoutes();
private void LoadList()
{
dataGridViewData.DataSource = _routeRepository.ReadRoutes();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["DepartureDestination"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;

View File

@ -103,14 +103,38 @@ WHERE Id = @Id";
}
}
public IEnumerable<AddMoney> ReadAddMoneys()
public IEnumerable<AddMoney> ReadAddMoneys(DateTime? dateFrom = null, DateTime? dateTo = null, int? addMoneyId = null, int? clientId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateFrom.HasValue)
{
builder.AddCondition("am.Date >= @dateFrom");
}
if (dateTo.HasValue)
{
builder.AddCondition("am.Date <= @dateTo");
}
if (addMoneyId.HasValue)
{
builder.AddCondition("am.Id =@addMoneyId");
}
if (clientId.HasValue)
{
builder.AddCondition("am.ClientId =@clientId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT * FROM AddMoneys";
var AddMoneys = connection.Query<AddMoney>(querySelect);
var querySelect = $@"SELECT
am.*,
c.FullName AS ClientName
FROM
AddMoneys am
LEFT JOIN
Clients c ON c.Id = am.ClientId
{builder.Build()}";
var AddMoneys = connection.Query<AddMoney>(querySelect, new {dateFrom, dateTo, addMoneyId, clientId});
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(AddMoneys));
return AddMoneys;

View File

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

@ -76,22 +76,69 @@ WHERE Id = @id";
}
public IEnumerable<Tour> ReadTours()
public IEnumerable<Tour> ReadTours(DateTime? dateFrom = null, DateTime? dateTo = null, int? tourId = null, int? clientId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateFrom.HasValue)
{
builder.AddCondition("t.DepartureDate >= @dateFrom");
}
if (dateTo.HasValue)
{
builder.AddCondition("t.DepartureDate <= @dateTo");
}
if(tourId.HasValue)
{
builder.AddCondition("t.Id = @tourId");
}
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT t.*, ct.TourId, ct.Cost, ct.ClientId FROM Tour t
INNER JOIN ClientTour ct ON ct.TourId = t.Id";
var tour = connection.Query<TempClientTour>(querySelect);
_logger.LogDebug("Получение объектов {json}", JsonConvert.SerializeObject(tour));
return tour.GroupBy(
x => x.Id, y => y,
(key, value) => Tour.CreateEntity(value.First(),
value.Select(z => ClientTour.CreateEntity(0,z.ClientId, z.Id,z.Cost))
)).ToList();
var querySelect = $@"
SELECT
t.*,
CONCAT(r.Departure,'-', r.Destination) AS RouteName,
e.FullName AS EmployeeName,
ct.ClientId,
ct.Cost,
c.FullName AS ClientName
FROM
Tour t
LEFT JOIN
Routes r ON r.Id = t.RouteId
LEFT JOIN
Employees e ON e.Id = t.EmployeeId
LEFT JOIN
ClientTour ct ON ct.TourId = t.Id
LEFT JOIN
Clients c ON c.Id = ct.ClientId
{builder.Build()}";
var clientTourDict = new Dictionary<int, List<ClientTour>>();
var tours = connection.Query<Tour, ClientTour, Tour>(querySelect,
(clientTour, tours) =>
{
if (!clientTourDict.TryGetValue(clientTour.Id, out var ct))
{
ct = [];
clientTourDict.Add(clientTour.Id, ct);
}
ct.Add(tours);
return clientTour;
}, splitOn: "ClientId",param: new {dateFrom, dateTo, tourId, clientId});
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(tours));
return clientTourDict.Select(x =>
{
var t = tours.First(y => y.Id == x.Key);
t.SetClientTours(x.Value);
return t;
}).ToArray();
}
catch (Exception ex)
{

View File

@ -28,7 +28,7 @@ internal class ChartReport
{
new PdfBuilder(filePath)
.AddHeader("Операции пополнения")
.AddPieChart("Пополнения счетов клиентов", GetData(dateTime))
.AddPieChart($"Пополнения счетов клиентов за {dateTime.ToString("d MMMM yyyy")}", GetData(dateTime))
.Build();
return true;
@ -43,9 +43,8 @@ internal class ChartReport
private List<(string Caption, double Value)> GetData(DateTime dateTime)
{
return _addMoneyRepository
.ReadAddMoneys()
.Where(x => x.Date.Date == dateTime.Date)
.GroupBy(x => x.ClientId, (key, group) => new { Id = key, Count = group.Count() })
.ReadAddMoneys(dateFrom: dateTime.Date, dateTo: dateTime.Date.AddDays(1))
.GroupBy(x => x.ClientName, (key, group) => new { Id = key, Count = group.Count() })
.Select(x => (x.Id.ToString(), (double)x.Count))
.ToList();
}

View File

@ -31,7 +31,7 @@ namespace ProjectTourAgency.Reports
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по движению корма", 0, 4)
.AddParagraph("за период", 0)
.AddParagraph($"за период с {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0)
.AddTable(new[] { 10, 10, 15, 15 }, GetData(tourId, startDate, endDate))
.Build();
return true;
@ -45,49 +45,55 @@ namespace ProjectTourAgency.Reports
private List<string[]> GetData(int tourId, DateTime startDate, DateTime endDate)
{
var tourData = _tourRepository.ReadTours()
.Where(x => x.DepartureDate >= startDate && x.DepartureDate <= endDate && x.ClientTours.Any(y => y.TourId == tourId))
var tourData = _tourRepository.ReadTours(startDate, endDate, tourId)
.SelectMany(x => x.ClientTours
.Where(y => y.TourId == tourId)
.Select(y => new {
ClientId = (int?)y.ClientId,
ClientId = y.ClientId,
ClientName = y.CLientName,
Date = x.DepartureDate,
CountIn = (int?)null,
CountOut = (int?)y.Cost
}));
var clientIds = tourData.Select(x => x.ClientId).Distinct().ToList();
var clientId = tourData.Select(x => x.ClientId).Distinct().ToList();
var addMoneyData = _addMoneyRepository.ReadAddMoneys()
.Where(x => x.Date >= startDate && x.Date <= endDate && clientIds.Contains(x.ClientId))
var addMoneyData = _addMoneyRepository.ReadAddMoneys(startDate, endDate)
.Where(x => clientId.Contains(x.ClientId))
.Select(x => new {
ClientId = (int?)x.ClientId,
ClientId = x.ClientId,
ClientName = x.ClientName,
Date = x.Date,
CountIn = (int?)x.MoneyAmount,
CountOut = (int?)null
});
// Объединяем данные и группируем по клиенту и дате
var data = tourData
.Union(addMoneyData)
.GroupBy(x => new { x.ClientId, x.ClientName, x.Date })
.Select(g => new {
ClientName = g.Key.ClientName,
Date = g.Key.Date,
CountIn = g.Sum(x => x.CountIn ?? 0),
CountOut = g.Sum(x => x.CountOut ?? 0)
})
.OrderBy(x => x.Date);
return new List<string[]>() { item }
.Union(data.Select(x => new string[] {
x.ClientId.ToString(),
x.Date.ToString(),
x.CountIn?.ToString() ?? string.Empty,
x.CountOut?.ToString() ?? string.Empty }))
x.ClientName,
x.Date.ToString("dd.MM.yyyy"), // Форматируем дату
x.CountIn == 0 ? "NO" : x.CountIn.ToString(),
x.CountOut == 0 ? "NO" : x.CountOut.ToString()
}))
.Union(new[] { new string[] {
"Всего",
"",
data.Sum(x => x.CountIn ?? 0).ToString(),
data.Sum(x => x.CountOut ?? 0).ToString()
}})
"Всего",
"",
data.Sum(x => x.CountIn) == 0 ? "NO" : data.Sum(x => x.CountIn).ToString(),
data.Sum(x => x.CountOut) == 0 ? "NO" : data.Sum(x => x.CountOut).ToString()
}})
.ToList();
}
}
}

View File

@ -9,7 +9,7 @@ namespace ProjectTourAgency.Repositories;
public interface IAddMoneyRepository
{
IEnumerable<AddMoney> ReadAddMoneys();
IEnumerable<AddMoney> ReadAddMoneys(DateTime? dateFrom = null, DateTime? dateTo = null, int? addMoneyId = null, int? clientId = null);
AddMoney ReadAddMoneyById(int id);

View File

@ -9,7 +9,7 @@ namespace ProjectTourAgency.Repositories;
public interface ITourRepository
{
IEnumerable<Tour> ReadTours();
IEnumerable<Tour> ReadTours(DateTime? dateFrom = null, DateTime? dateTo = null, int? tourId = null, int? clientId = null);
void CreateTour(Tour tour);