File size: 12,719 Bytes
fc1eb7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
import jsPDF from 'jspdf';
import autoTable from 'jspdf-autotable';
import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver';

export interface ExportData {
  tasks: any[];
  remarks: any[];
  maintenance: any[];
  equipment: any[];
}

export const exportToPDF = (data: ExportData, title: string) => {
  const doc = new jsPDF();
  
  // Заголовок на английском языке из-за ограничений jsPDF с кириллицей
  doc.setFontSize(18);
  doc.text('Equipment Management System Report', 20, 20);
  doc.text(`Generated: ${new Date().toLocaleDateString('en-US')}`, 20, 30);
  
  let yPosition = 50;
  
  // Таблица задач
  if (data.tasks.length > 0) {
    doc.setFontSize(14);
    doc.text('Tasks', 20, yPosition);
    yPosition += 10;
    
    const taskHeaders = ['ID', 'Title', 'Status', 'Priority', 'Equipment', 'Due Date'];
    const taskRows = data.tasks.map(task => [
      task.id.toString(),
      task.title ? task.title.replace(/[^\x00-\x7F]/g, "?") : '',
      getStatusTextEn(task.status),
      getPriorityTextEn(task.priority),
      task.equipmentId || '',
      task.dueDate ? new Date(task.dueDate).toLocaleDateString('en-US') : ''
    ]);
    
    autoTable(doc, {
      head: [taskHeaders],
      body: taskRows,
      startY: yPosition,
      styles: { fontSize: 8 },
      headStyles: { fillColor: [66, 139, 202] }
    });
    
    yPosition = (doc as any).lastAutoTable.finalY + 20;
  }
  
  // Таблица замечаний
  if (data.remarks.length > 0) {
    doc.setFontSize(14);
    doc.text('Remarks', 20, yPosition);
    yPosition += 10;
    
    const remarkHeaders = ['ID', 'Title', 'Status', 'Equipment', 'Created'];
    const remarkRows = data.remarks.map(remark => [
      remark.id.toString(),
      remark.title ? remark.title.replace(/[^\x00-\x7F]/g, "?") : '',
      getStatusTextEn(remark.status),
      remark.equipmentName ? remark.equipmentName.replace(/[^\x00-\x7F]/g, "?") : '',
      new Date(remark.createdAt).toLocaleDateString('en-US')
    ]);
    
    autoTable(doc, {
      head: [remarkHeaders],
      body: remarkRows,
      startY: yPosition,
      styles: { fontSize: 8 },
      headStyles: { fillColor: [66, 139, 202] }
    });
    
    yPosition = (doc as any).lastAutoTable.finalY + 20;
  }
  
  // Таблица техобслуживания
  if (data.maintenance.length > 0 && yPosition < 250) {
    doc.setFontSize(14);
    doc.text('Maintenance', 20, yPosition);
    yPosition += 10;
    
    const maintenanceHeaders = ['ID', 'Equipment', 'Type', 'Status', 'Scheduled', 'Responsible'];
    const maintenanceRows = data.maintenance.map(maintenance => [
      maintenance.id.toString(),
      maintenance.equipmentName ? maintenance.equipmentName.replace(/[^\x00-\x7F]/g, "?") : '',
      maintenance.maintenanceType || '',
      getMaintenanceStatusTextEn(maintenance.status),
      new Date(maintenance.scheduledDate).toLocaleDateString('en-US'),
      maintenance.responsible ? maintenance.responsible.replace(/[^\x00-\x7F]/g, "?") : ''
    ]);
    
    autoTable(doc, {
      head: [maintenanceHeaders],
      body: maintenanceRows,
      startY: yPosition,
      styles: { fontSize: 8 },
      headStyles: { fillColor: [66, 139, 202] }
    });
  }
  
  // Сохранение файла
  const fileName = `Equipment_Report_${new Date().toISOString().split('T')[0]}.pdf`;
  doc.save(fileName);
};

export const exportToExcel = (data: ExportData, title: string) => {
  const workbook = XLSX.utils.book_new();
  
  // Лист с задачами
  if (data.tasks.length > 0) {
    const taskData = data.tasks.map(task => ({
      'ID': task.id,
      'Название': task.title || '',
      'Описание': task.description || '',
      'Статус': getStatusText(task.status),
      'Приоритет': getPriorityText(task.priority),
      'Оборудование': task.equipmentId || '',
      'Тип ТО': task.maintenanceType || '',
      'Срок выполнения': task.dueDate ? new Date(task.dueDate).toLocaleDateString('ru-RU') : '',
      'Создал': task.createdBy || '',
      'Дата создания': new Date(task.createdAt).toLocaleDateString('ru-RU'),
      'Изменил': task.modifiedBy || '',
      'Дата изменения': task.modifiedAt ? new Date(task.modifiedAt).toLocaleDateString('ru-RU') : '',
      'Закрыл': task.closedBy || '',
      'Дата закрытия': task.closedAt ? new Date(task.closedAt).toLocaleDateString('ru-RU') : ''
    }));
    
    const taskSheet = XLSX.utils.json_to_sheet(taskData);
    XLSX.utils.book_append_sheet(workbook, taskSheet, 'Задачи');
  }
  
  // Лист с замечаниями
  if (data.remarks.length > 0) {
    const remarkData = data.remarks.map(remark => ({
      'ID': remark.id,
      'Название': remark.title || '',
      'Описание': remark.description || '',
      'Статус': getStatusText(remark.status),
      'Оборудование ID': remark.equipmentId || '',
      'Оборудование': remark.equipmentName || '',
      'Источник': remark.source || '',
      'Создал': remark.createdBy || '',
      'Дата создания': new Date(remark.createdAt).toLocaleDateString('ru-RU'),
      'Изменил': remark.modifiedBy || '',
      'Дата изменения': remark.modifiedAt ? new Date(remark.modifiedAt).toLocaleDateString('ru-RU') : '',
      'Закрыл': remark.closedBy || '',
      'Дата закрытия': remark.closedAt ? new Date(remark.closedAt).toLocaleDateString('ru-RU') : ''
    }));
    
    const remarkSheet = XLSX.utils.json_to_sheet(remarkData);
    XLSX.utils.book_append_sheet(workbook, remarkSheet, 'Замечания');
  }
  
  // Лист с техобслуживанием
  if (data.maintenance.length > 0) {
    const maintenanceData = data.maintenance.map(maintenance => ({
      'ID': maintenance.id,
      'Оборудование ID': maintenance.equipmentId || '',
      'Оборудование': maintenance.equipmentName || '',
      'Тип ТО': maintenance.maintenanceType || '',
      'Статус': getMaintenanceStatusText(maintenance.status),
      'Приоритет': maintenance.priority || '',
      'Плановая дата': new Date(maintenance.scheduledDate).toLocaleDateString('ru-RU'),
      'Дата выполнения': maintenance.completedDate ? new Date(maintenance.completedDate).toLocaleDateString('ru-RU') : '',
      'Ответственный': maintenance.responsible || '',
      'Заметки': maintenance.notes || '',
      'Длительность': maintenance.duration || '',
      'Дата создания': new Date(maintenance.createdAt).toLocaleDateString('ru-RU'),
      'Дата обновления': maintenance.updatedAt ? new Date(maintenance.updatedAt).toLocaleDateString('ru-RU') : ''
    }));
    
    const maintenanceSheet = XLSX.utils.json_to_sheet(maintenanceData);
    XLSX.utils.book_append_sheet(workbook, maintenanceSheet, 'Техобслуживание');
  }
  
  // Лист с оборудованием
  if (data.equipment.length > 0) {
    const equipmentData = data.equipment.map(equipment => ({
      'ID': equipment.id,
      'Название': equipment.name || '',
      'Тип': equipment.type || '',
      'Производитель': equipment.manufacturer || '',
      'Модель': equipment.model || '',
      'Серийный номер': equipment.serialNumber || '',
      'Расположение': equipment.location || '',
      'Статус': equipment.status || '',
      'Дата установки': equipment.installationDate ? new Date(equipment.installationDate).toLocaleDateString('ru-RU') : '',
      'Описание': equipment.description || ''
    }));
    
    const equipmentSheet = XLSX.utils.json_to_sheet(equipmentData);
    XLSX.utils.book_append_sheet(workbook, equipmentSheet, 'Оборудование');
  }
  
  // Сохранение файла
  const fileName = `Отчет_система_управления_оборудованием_${new Date().toISOString().split('T')[0]}.xlsx`;
  const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
  const file = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
  saveAs(file, fileName);
};

export const exportToCSV = (data: ExportData, title: string) => {
  let csvContent = `${title}\n`;
  csvContent += `Дата формирования: ${new Date().toLocaleDateString('ru-RU')}\n\n`;
  
  // Задачи
  if (data.tasks.length > 0) {
    csvContent += 'ЗАДАЧИ\n';
    csvContent += 'ID,Название,Статус,Приоритет,Оборудование,Срок выполнения,Создал,Дата создания\n';
    
    data.tasks.forEach(task => {
      csvContent += `${task.id},"${task.title || ''}","${getStatusText(task.status)}","${getPriorityText(task.priority)}","${task.equipmentId || ''}","${task.dueDate ? new Date(task.dueDate).toLocaleDateString('ru-RU') : ''}","${task.createdBy || ''}","${new Date(task.createdAt).toLocaleDateString('ru-RU')}"\n`;
    });
    csvContent += '\n';
  }
  
  // Замечания
  if (data.remarks.length > 0) {
    csvContent += 'ЗАМЕЧАНИЯ\n';
    csvContent += 'ID,Название,Статус,Оборудование,Источник,Создал,Дата создания\n';
    
    data.remarks.forEach(remark => {
      csvContent += `${remark.id},"${remark.title || ''}","${getStatusText(remark.status)}","${remark.equipmentName || ''}","${remark.source || ''}","${remark.createdBy || ''}","${new Date(remark.createdAt).toLocaleDateString('ru-RU')}"\n`;
    });
    csvContent += '\n';
  }
  
  // Техобслуживание
  if (data.maintenance.length > 0) {
    csvContent += 'ТЕХНИЧЕСКОЕ ОБСЛУЖИВАНИЕ\n';
    csvContent += 'ID,Оборудование,Тип ТО,Статус,Плановая дата,Ответственный\n';
    
    data.maintenance.forEach(maintenance => {
      csvContent += `${maintenance.id},"${maintenance.equipmentName || ''}","${maintenance.maintenanceType || ''}","${getMaintenanceStatusText(maintenance.status)}","${new Date(maintenance.scheduledDate).toLocaleDateString('ru-RU')}","${maintenance.responsible || ''}"\n`;
    });
  }
  
  // Сохранение файла с BOM для корректного отображения кириллицы
  const fileName = `Отчет_система_управления_оборудованием_${new Date().toISOString().split('T')[0]}.csv`;
  const BOM = '\uFEFF';
  const file = new Blob([BOM + csvContent], { type: 'text/csv;charset=utf-8;' });
  saveAs(file, fileName);
};

// Вспомогательные функции для перевода статусов
function getStatusText(status: string): string {
  const statusMap: { [key: string]: string } = {
    'pending': 'Ожидает',
    'in-progress': 'В работе',
    'completed': 'Завершено',
    'open': 'Открыто',
    'resolved': 'Решено'
  };
  return statusMap[status] || status;
}

function getStatusTextEn(status: string): string {
  const statusMap: { [key: string]: string } = {
    'pending': 'Pending',
    'in-progress': 'In Progress',
    'completed': 'Completed',
    'open': 'Open',
    'resolved': 'Resolved'
  };
  return statusMap[status] || status;
}

function getPriorityText(priority: string): string {
  const priorityMap: { [key: string]: string } = {
    'low': 'Низкий',
    'medium': 'Средний',
    'high': 'Высокий',
    'critical': 'Критический'
  };
  return priorityMap[priority] || priority;
}

function getPriorityTextEn(priority: string): string {
  const priorityMap: { [key: string]: string } = {
    'low': 'Low',
    'medium': 'Medium',
    'high': 'High',
    'critical': 'Critical'
  };
  return priorityMap[priority] || priority;
}

function getMaintenanceStatusText(status: string): string {
  const statusMap: { [key: string]: string } = {
    'scheduled': 'Запланировано',
    'in-progress': 'В работе',
    'completed': 'Завершено',
    'overdue': 'Просрочено',
    'cancelled': 'Отменено'
  };
  return statusMap[status] || status;
}

function getMaintenanceStatusTextEn(status: string): string {
  const statusMap: { [key: string]: string } = {
    'scheduled': 'Scheduled',
    'in-progress': 'In Progress',
    'completed': 'Completed',
    'overdue': 'Overdue',
    'cancelled': 'Cancelled'
  };
  return statusMap[status] || status;
}