-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCustomReportWindow.xaml.cs
More file actions
268 lines (237 loc) · 12 KB
/
Copy pathCustomReportWindow.xaml.cs
File metadata and controls
268 lines (237 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
using MyPanelCarWashing.Models;
using MyPanelCarWashing.Services;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
namespace MyPanelCarWashing
{
public partial class CustomReportWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private SqliteDataService _SqliteDataService;
private DateTime _startDate;
private DateTime _endDate;
private CustomPeriodReport _currentReport;
public DateTime StartDate
{
get { return _startDate; }
set
{
_startDate = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(StartDate)));
}
}
public DateTime EndDate
{
get { return _endDate; }
set
{
_endDate = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(EndDate)));
}
}
public CustomReportWindow(SqliteDataService SqliteDataService)
{
InitializeComponent();
_SqliteDataService = SqliteDataService;
DataContext = this;
StartDate = DateTime.Now.AddDays(-6);
EndDate = DateTime.Now;
StartDatePicker.SelectedDate = StartDate;
EndDatePicker.SelectedDate = EndDate;
}
private void GenerateReportButton_Click(object sender, RoutedEventArgs args)
{
try
{
DateTime startDate = StartDatePicker.SelectedDate ?? StartDate;
DateTime endDate = EndDatePicker.SelectedDate ?? EndDate;
if (startDate > endDate)
{
MessageBox.Show("Дата начала не может быть позже даты окончания", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// 1. Получаем смены и клиентов
var periodReports = _SqliteDataService.GetShiftReportsFromDb(startDate, endDate);
int newClients = _SqliteDataService.GetNewClientsCount(startDate, endDate);
int uniqueClients = _SqliteDataService.GetUniqueClientsCount(startDate, endDate);
// 2. Получаем транзакции за период
var periodTransactions = _SqliteDataService.GetTransactionsByDateRange(startDate, endDate);
if (!periodReports.Any() && !periodTransactions.Any())
{
MessageBox.Show($"За период с {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy} нет данных",
"Информация", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// Итоговые суммы по заказам
var totalCars = periodReports.Sum(r => r.TotalCars);
var totalRevenue = periodReports.Sum(r => r.TotalRevenue);
var totalWasherEarnings = periodReports.Sum(r => r.TotalWasherEarnings);
var totalCompanyEarnings = periodReports.Sum(r => r.TotalCompanyEarnings);
var totalCashCount = periodReports.Sum(r => r.CashCount);
var totalCashAmount = periodReports.Sum(r => r.CashAmount);
var totalCardCount = periodReports.Sum(r => r.CardCount);
var totalCardAmount = periodReports.Sum(r => r.CardAmount);
var totalTransferCount = periodReports.Sum(r => r.TransferCount);
var totalTransferAmount = periodReports.Sum(r => r.TransferAmount);
var totalQrCount = periodReports.Sum(r => r.QrCount);
var totalQrAmount = periodReports.Sum(r => r.QrAmount);
// Итоговые суммы по транзакциям
var totalExpenses = periodTransactions.Where(t => t.Type == "Расход").Sum(t => t.Amount);
var totalAdvances = periodTransactions.Where(t => t.Type == "Аванс мойщику").Sum(t => t.Amount);
// Дневные сводки
var dailySummaries = periodReports
.OrderBy(r => r.Date)
.Select(r => new DailyReportSummary
{
Date = r.Date,
TotalCars = r.TotalCars,
TotalRevenue = r.TotalRevenue,
TotalWasherEarnings = r.TotalWasherEarnings,
TotalCompanyEarnings = r.TotalCompanyEarnings,
CashCount = r.CashCount,
CashAmount = r.CashAmount,
CardCount = r.CardCount,
CardAmount = r.CardAmount,
TransferCount = r.TransferCount,
TransferAmount = r.TransferAmount,
QrCount = r.QrCount,
QrAmount = r.QrAmount
}).ToList();
// Статистика по сотрудникам (Зарплатная ведомость)
var employeesData = new Dictionary<int, EmployeeReport>();
foreach (var report in periodReports.OrderBy(r => r.Date))
{
foreach (var emp in report.EmployeesWork)
{
if (!employeesData.ContainsKey(emp.EmployeeId))
{
employeesData[emp.EmployeeId] = new EmployeeReport
{
EmployeeId = emp.EmployeeId,
EmployeeName = emp.EmployeeName,
CarsWashed = 0,
TotalAmount = 0,
Earnings = 0,
Advances = 0,
DailyWork = new List<DailyEmployeeReport>()
};
}
employeesData[emp.EmployeeId].CarsWashed += emp.CarsWashed;
employeesData[emp.EmployeeId].TotalAmount += emp.TotalAmount;
employeesData[emp.EmployeeId].Earnings += emp.Earnings;
}
}
// Распределяем авансы по сотрудникам
foreach (var t in periodTransactions.Where(x => x.Type == "Аванс мойщику" && x.EmployeeId.HasValue))
{
int empId = t.EmployeeId.Value;
if (employeesData.ContainsKey(empId))
{
employeesData[empId].Advances += t.Amount;
}
else
{
var allUsers = _SqliteDataService.GetAllUsers();
var user = allUsers.FirstOrDefault(u => u.Id == empId);
if (user != null)
{
employeesData[empId] = new EmployeeReport
{
EmployeeId = empId,
EmployeeName = user.FullName,
Advances = t.Amount,
DailyWork = new List<DailyEmployeeReport>()
};
}
}
}
var employeesReport = employeesData.Values.OrderByDescending(e => e.Earnings).ToList();
int daysCount = (endDate - startDate).Days + 1;
// Обновляем UI
PeriodText.Text = $"Период: {startDate:dd.MM.yyyy} - {endDate:dd.MM.yyyy}";
DaysCountText.Text = $"Всего дней: {daysCount}";
TotalCarsText.Text = totalCars.ToString();
TotalRevenueText.Text = $"{totalRevenue:N0} ₽";
TotalWasherText.Text = $"{totalWasherEarnings:N0} ₽";
TotalCompanyText.Text = $"{totalCompanyEarnings:N0} ₽";
TotalAdvancesText.Text = $"{totalAdvances:N0} ₽";
TotalExpensesText.Text = $"{totalExpenses:N0} ₽";
NetProfitText.Text = $"{(totalCompanyEarnings - totalExpenses):N0} ₽";
UniqueClientsText.Text = uniqueClients.ToString();
NewClientsText.Text = newClients.ToString();
EmployeesSalaryList.ItemsSource = employeesReport;
ReportContent.Visibility = Visibility.Visible;
NoDataText.Visibility = Visibility.Collapsed;
// Сохраняем для экспорта
_currentReport = new CustomPeriodReport
{
StartDate = startDate,
EndDate = endDate,
TotalCars = totalCars,
TotalRevenue = totalRevenue,
TotalWasherEarnings = totalWasherEarnings,
TotalCompanyEarnings = totalCompanyEarnings,
TotalAdvances = totalAdvances,
TotalExpenses = totalExpenses,
CashCount = totalCashCount,
CashAmount = totalCashAmount,
CardCount = totalCardCount,
CardAmount = totalCardAmount,
TransferCount = totalTransferCount,
TransferAmount = totalTransferAmount,
QrCount = totalQrCount,
QrAmount = totalQrAmount,
UniqueClientsCount = uniqueClients,
NewClientsCount = newClients,
DailyReports = dailySummaries,
EmployeesWork = employeesReport
};
CustomCashCountText.Text = totalCashCount.ToString();
CustomCashAmountText.Text = $"{totalCashAmount:N0} ₽";
CustomCardCountText.Text = totalCardCount.ToString();
CustomCardAmountText.Text = $"{totalCardAmount:N0} ₽";
CustomTransferCountText.Text = totalTransferCount.ToString();
CustomTransferAmountText.Text = $"{totalTransferAmount:N0} ₽";
CustomQrCountText.Text = totalQrCount.ToString();
CustomQrAmountText.Text = $"{totalQrAmount:N0} ₽";
}
catch (Exception ex)
{
MessageBox.Show($"Ошибка формирования отчета: {ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void ExportButton_Click(object sender, RoutedEventArgs args)
{
if (_currentReport == null)
{
MessageBox.Show("Сначала сформируйте отчет", "Внимание", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var saveDialog = new Microsoft.Win32.SaveFileDialog
{
Filter = "Excel файл (*.xlsx)|*.xlsx",
FileName = $"Финансовый_Отчет_{_currentReport.StartDate:dd.MM.yyyy}-{_currentReport.EndDate:dd.MM.yyyy}.xlsx",
DefaultExt = ".xlsx"
};
if (saveDialog.ShowDialog() == true)
{
try
{
ExcelExporter.ExportCustomPeriodReport(_currentReport, saveDialog.FileName);
MessageBox.Show("Отчет успешно экспортирован!", "Успешно", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
MessageBox.Show($"Ошибка при экспорте:\n{ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
private void CloseButton_Click(object sender, RoutedEventArgs args)
{
Close();
}
}
}