vv-iiko-pp-parser 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +151 -0
  2. package/README.md +582 -0
  3. package/dist/clients/clients.fetcher.d.ts +102 -0
  4. package/dist/clients/clients.fetcher.d.ts.map +1 -0
  5. package/dist/clients/clients.fetcher.js +196 -0
  6. package/dist/clients/clients.fetcher.js.map +1 -0
  7. package/dist/clients/clients.parser.d.ts +144 -0
  8. package/dist/clients/clients.parser.d.ts.map +1 -0
  9. package/dist/clients/clients.parser.js +473 -0
  10. package/dist/clients/clients.parser.js.map +1 -0
  11. package/dist/clients/clients.service.d.ts +90 -0
  12. package/dist/clients/clients.service.d.ts.map +1 -0
  13. package/dist/clients/clients.service.js +277 -0
  14. package/dist/clients/clients.service.js.map +1 -0
  15. package/dist/clients/clients.types.d.ts +127 -0
  16. package/dist/clients/clients.types.d.ts.map +1 -0
  17. package/dist/clients/clients.types.js +6 -0
  18. package/dist/clients/clients.types.js.map +1 -0
  19. package/dist/clients/index.d.ts +5 -0
  20. package/dist/clients/index.d.ts.map +1 -0
  21. package/dist/clients/index.js +25 -0
  22. package/dist/clients/index.js.map +1 -0
  23. package/dist/core/auth/iiko-auth.service.d.ts +52 -0
  24. package/dist/core/auth/iiko-auth.service.d.ts.map +1 -0
  25. package/dist/core/auth/iiko-auth.service.js +302 -0
  26. package/dist/core/auth/iiko-auth.service.js.map +1 -0
  27. package/dist/core/http/iiko-http.client.d.ts +13 -0
  28. package/dist/core/http/iiko-http.client.d.ts.map +1 -0
  29. package/dist/core/http/iiko-http.client.js +55 -0
  30. package/dist/core/http/iiko-http.client.js.map +1 -0
  31. package/dist/core/iiko-parser.config.d.ts +28 -0
  32. package/dist/core/iiko-parser.config.d.ts.map +1 -0
  33. package/dist/core/iiko-parser.config.js +76 -0
  34. package/dist/core/iiko-parser.config.js.map +1 -0
  35. package/dist/core/parser/iiko-parser.service.d.ts +15 -0
  36. package/dist/core/parser/iiko-parser.service.d.ts.map +1 -0
  37. package/dist/core/parser/iiko-parser.service.js +156 -0
  38. package/dist/core/parser/iiko-parser.service.js.map +1 -0
  39. package/dist/core/session/iiko-session.service.d.ts +68 -0
  40. package/dist/core/session/iiko-session.service.d.ts.map +1 -0
  41. package/dist/core/session/iiko-session.service.js +209 -0
  42. package/dist/core/session/iiko-session.service.js.map +1 -0
  43. package/dist/iiko-parser.d.ts +149 -0
  44. package/dist/iiko-parser.d.ts.map +1 -0
  45. package/dist/iiko-parser.js +209 -0
  46. package/dist/iiko-parser.js.map +1 -0
  47. package/dist/index.d.ts +4 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +7 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/interfaces/company-profile.interface.d.ts +12 -0
  52. package/dist/interfaces/company-profile.interface.d.ts.map +1 -0
  53. package/dist/interfaces/company-profile.interface.js +3 -0
  54. package/dist/interfaces/company-profile.interface.js.map +1 -0
  55. package/dist/invoices/index.d.ts +6 -0
  56. package/dist/invoices/index.d.ts.map +1 -0
  57. package/dist/invoices/index.js +22 -0
  58. package/dist/invoices/index.js.map +1 -0
  59. package/dist/invoices/invoices.fetcher.d.ts +49 -0
  60. package/dist/invoices/invoices.fetcher.d.ts.map +1 -0
  61. package/dist/invoices/invoices.fetcher.js +141 -0
  62. package/dist/invoices/invoices.fetcher.js.map +1 -0
  63. package/dist/invoices/invoices.filters.d.ts +40 -0
  64. package/dist/invoices/invoices.filters.d.ts.map +1 -0
  65. package/dist/invoices/invoices.filters.js +81 -0
  66. package/dist/invoices/invoices.filters.js.map +1 -0
  67. package/dist/invoices/invoices.parser.d.ts +101 -0
  68. package/dist/invoices/invoices.parser.d.ts.map +1 -0
  69. package/dist/invoices/invoices.parser.js +540 -0
  70. package/dist/invoices/invoices.parser.js.map +1 -0
  71. package/dist/invoices/invoices.service.d.ts +82 -0
  72. package/dist/invoices/invoices.service.d.ts.map +1 -0
  73. package/dist/invoices/invoices.service.js +361 -0
  74. package/dist/invoices/invoices.service.js.map +1 -0
  75. package/dist/invoices/invoices.storage.service.d.ts +30 -0
  76. package/dist/invoices/invoices.storage.service.d.ts.map +1 -0
  77. package/dist/invoices/invoices.storage.service.js +135 -0
  78. package/dist/invoices/invoices.storage.service.js.map +1 -0
  79. package/dist/invoices/invoices.types.d.ts +94 -0
  80. package/dist/invoices/invoices.types.d.ts.map +1 -0
  81. package/dist/invoices/invoices.types.js +3 -0
  82. package/dist/invoices/invoices.types.js.map +1 -0
  83. package/dist/types.d.ts +138 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +4 -0
  86. package/dist/types.js.map +1 -0
  87. package/package.json +52 -0
@@ -0,0 +1,473 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ClientsParser = void 0;
37
+ const cheerio = __importStar(require("cheerio"));
38
+ class ClientsParser {
39
+ /**
40
+ * Парсит HTML таблицу со списком клиентов.
41
+ *
42
+ * Поддерживает две структуры HTML:
43
+ * 1. Полный HTML с контейнером #clientsTable_ajax (используется на странице /en/cabinet/clients.html)
44
+ * 2. AJAX фрагмент только с <tbody class="ajax"> (используется в AJAX endpoint /en/cabinet/ajax/clients-list.html)
45
+ *
46
+ * Из каждой строки таблицы извлекает:
47
+ * - name: название клиента (текст из ссылки <a>)
48
+ * - clientId: идентификатор клиента (из href ?clientId=XXX)
49
+ * - shortName: краткое название (опционально, из <div class="small mt-2">)
50
+ *
51
+ * @param html HTML контент от /en/cabinet/ajax/clients-list.html или полная страница
52
+ * @returns Массив объектов с базовой информацией о клиентах
53
+ */
54
+ parseClientsTable(html) {
55
+ const $ = cheerio.load(html);
56
+ const clients = [];
57
+ // Пытаемся найти таблицу в контейнере #clientsTable_ajax (полный HTML)
58
+ let $rows = $('#clientsTable_ajax tbody.ajax tr');
59
+ // Если не найдено, ищем напрямую tbody.ajax (AJAX фрагмент)
60
+ if ($rows.length === 0) {
61
+ $rows = $('tbody.ajax tr');
62
+ }
63
+ // Обрабатываем каждую строку таблицы
64
+ $rows.each((_, row) => {
65
+ const $row = $(row);
66
+ // Ищем второй столбец (td) с информацией о клиенте (первый столбец - тип)
67
+ const $nameTd = $row.find('td').eq(1);
68
+ // Извлекаем ссылку на клиента
69
+ const $link = $nameTd.find('a').first();
70
+ const href = $link.attr('href');
71
+ const name = $link.text().trim();
72
+ // Извлекаем clientId из URL
73
+ const clientIdMatch = href?.match(/clientId=(\d+)/);
74
+ const clientId = clientIdMatch ? clientIdMatch[1] : null;
75
+ if (name && clientId) {
76
+ clients.push({ name, clientId });
77
+ }
78
+ });
79
+ return clients;
80
+ }
81
+ /**
82
+ * Извлекает общее количество страниц из HTML пагинации.
83
+ *
84
+ * Основной способ:
85
+ * - Ищет все элементы пагинации: '.pagination a.page-link[data-page]'
86
+ * - Находит максимальное значение атрибута data-page
87
+ * - Возвращает его как totalPages
88
+ *
89
+ * Резервный способ (fallback):
90
+ * - Если пагинация отсутствует, ищет '.pagination-total'
91
+ * - Извлекает общее количество записей из текста
92
+ * - Вычисляет totalPages = Math.ceil(totalEntries / perPage)
93
+ *
94
+ * @param html HTML контент страницы со списком клиентов
95
+ * @param perPage Количество элементов на странице (для расчета fallback)
96
+ * @returns Общее количество страниц или 1, если определить не удалось
97
+ */
98
+ parseTotalPages(html, perPage) {
99
+ const $ = cheerio.load(html);
100
+ // Основной способ: извлекаем максимальный data-page из пагинации
101
+ let maxPage = 0;
102
+ $('.pagination a.page-link[data-page]').each((_, element) => {
103
+ const pageAttr = $(element).attr('data-page');
104
+ if (pageAttr) {
105
+ const pageNum = parseInt(pageAttr, 10);
106
+ if (!isNaN(pageNum) && pageNum > maxPage) {
107
+ maxPage = pageNum;
108
+ }
109
+ }
110
+ });
111
+ if (maxPage > 0) {
112
+ return maxPage;
113
+ }
114
+ // Резервный способ: расчет через общее количество записей
115
+ const paginationTotalText = $('.pagination-total').text().trim();
116
+ const totalEntriesMatch = paginationTotalText.match(/(\d+)/);
117
+ if (totalEntriesMatch) {
118
+ const totalEntries = parseInt(totalEntriesMatch[1], 10);
119
+ if (!isNaN(totalEntries) && totalEntries > 0) {
120
+ return Math.ceil(totalEntries / perPage);
121
+ }
122
+ }
123
+ // Если ничего не найдено, возвращаем 1 (минимум одна страница)
124
+ return 1;
125
+ }
126
+ /**
127
+ * Парсит HTML страницу профиля клиента.
128
+ *
129
+ * Извлекает детальную информацию о клиенте со страницы /en/cabinet/client-area/index.html?clientId=XXX:
130
+ *
131
+ * - uuid: Уникальный идентификатор (UID) из кнопки "UID: XXX-XXX-XXX"
132
+ * - iikoVersion: Версия iiko из кнопки "Version iiko: X.X.XXXX"
133
+ * - email: Email из таблицы (строка "E-mail")
134
+ * - phone: Телефон из таблицы (строка "Phone")
135
+ * - address: Адрес из таблицы (строка "Address")
136
+ * - legalEntity: Название юридического лица (из строки "Legal entity", убираются кавычки «»)
137
+ * - tin: ИНН (Company tax id, только цифры)
138
+ *
139
+ * Нормализация данных:
140
+ * - UUID: возвращается как есть (формат: XXX-XXX-XXX)
141
+ * - TIN: удаляются все нечисловые символы (пробелы, дефисы и т.д.)
142
+ * - Legal Entity: удаляются внешние кавычки «», экранированные кавычки \" заменяются на "
143
+ *
144
+ * @param html HTML контент страницы профиля клиента
145
+ * @param clientId ID клиента для логирования ошибок
146
+ * @param name Имя клиента для включения в результат
147
+ * @returns Объект ClientData со всей информацией о клиенте или null при ошибке парсинга
148
+ */
149
+ parseClientProfile(html, clientId, name) {
150
+ const $ = cheerio.load(html);
151
+ try {
152
+ // Извлечение UUID из кнопки "UID: XXX-XXX-XXX"
153
+ // Ищем кнопку с текстом "UID:" и внутри span.copy-to-clipboard-text
154
+ let uuid = '';
155
+ $('button').each((_, button) => {
156
+ const $button = $(button);
157
+ const buttonText = $button.text();
158
+ if (buttonText.includes('UID:')) {
159
+ uuid = $button.find('.copy-to-clipboard-text').text().trim();
160
+ return false; // break
161
+ }
162
+ });
163
+ // Извлечение версии iiko из кнопки "Version iiko: X.X.XXXX"
164
+ let iikoVersion;
165
+ $('button').each((_, button) => {
166
+ const $button = $(button);
167
+ const buttonText = $button.text();
168
+ if (buttonText.includes('Version iiko:')) {
169
+ iikoVersion = $button.find('.copy-to-clipboard-text').text().trim();
170
+ return false; // break
171
+ }
172
+ });
173
+ // Извлечение контактной информации и юридических данных из таблицы
174
+ let email;
175
+ let phone;
176
+ let address;
177
+ let legalEntity;
178
+ let tin;
179
+ // Ищем все строки таблицы
180
+ $('table.table tr').each((_, row) => {
181
+ const $row = $(row);
182
+ const header = $row.find('th').text().trim();
183
+ const $td = $row.find('td');
184
+ const value = $td.text().trim();
185
+ if (header === 'E-mail') {
186
+ // Email может быть в виде ссылки <a href="mailto:...">
187
+ const emailLink = $td.find('a').first().text().trim();
188
+ email = emailLink || value || undefined;
189
+ }
190
+ else if (header === 'Phone') {
191
+ phone = value || undefined;
192
+ }
193
+ else if (header === 'Address') {
194
+ // Адрес может быть многострочным с <br>
195
+ // Заменяем <br> на пробелы и нормализуем
196
+ const addressHtml = $td.html() || '';
197
+ if (addressHtml) {
198
+ address = addressHtml
199
+ .replace(/<br\s*\/?>/gi, ' ') // Заменяем <br> на пробел
200
+ .replace(/<[^>]+>/g, '') // Удаляем HTML теги
201
+ .replace(/\s+/g, ' ') // Множественные пробелы -> один пробел
202
+ .trim() || undefined; // Убираем пробелы по краям
203
+ }
204
+ }
205
+ else if (header === 'Legal entity') {
206
+ // Legal entity содержит юр.лицо и ИНН в одной ячейке
207
+ // Формат: - «ООО "Название"»<br>Company tax id: XXX XXX XXX
208
+ const fullText = $td.html() || '';
209
+ // Извлекаем юр.лицо (строка до <br> или "Company tax id:")
210
+ const legalEntityMatch = fullText.match(/- (.+?)(?:<br>|Company tax id:)/i);
211
+ if (legalEntityMatch) {
212
+ legalEntity = this.normalizeLegalEntity(legalEntityMatch[1]);
213
+ }
214
+ // Извлекаем ИНН (после "Company tax id:")
215
+ const tinMatch = fullText.match(/Company tax id:\s*(.+)/i);
216
+ if (tinMatch) {
217
+ tin = this.extractTin(tinMatch[1]);
218
+ }
219
+ }
220
+ });
221
+ // Возвращаем полную информацию о клиенте
222
+ return {
223
+ uuid,
224
+ name,
225
+ clientId,
226
+ iikoVersion,
227
+ email,
228
+ phone,
229
+ address,
230
+ legalEntity,
231
+ tin,
232
+ isChain: false, // Определяется позже в service
233
+ members: [], // Заполняется позже в service если isChain=true
234
+ };
235
+ }
236
+ catch (error) {
237
+ console.error(`Failed to parse client profile for clientId=${clientId}:`, error);
238
+ return null;
239
+ }
240
+ }
241
+ /**
242
+ * Нормализует строку с названием юридического лица.
243
+ *
244
+ * Выполняет следующие преобразования:
245
+ * 1. Удаляет внешние кавычки-ёлочки («»)
246
+ * 2. Заменяет экранированные кавычки \" на обычные "
247
+ * 3. Удаляет лишние пробелы в начале и конце
248
+ *
249
+ * Примеры:
250
+ * - «ООО \"AEF GROUP\"» → ООО "AEF GROUP"
251
+ * - «ИП Иванов» → ИП Иванов
252
+ *
253
+ * @param text Исходная строка с названием юридического лица
254
+ * @returns Нормализованная строка или undefined, если входные данные пусты
255
+ */
256
+ normalizeLegalEntity(text) {
257
+ if (!text)
258
+ return undefined;
259
+ // Удаляем внешние кавычки-ёлочки «»
260
+ let normalized = text.replace(/^«|»$/g, '');
261
+ // Заменяем экранированные кавычки \" на обычные "
262
+ normalized = normalized.replace(/\\"/g, '"');
263
+ return normalized.trim() || undefined;
264
+ }
265
+ /**
266
+ * Извлекает ИНН (Tax Identification Number) из текста.
267
+ *
268
+ * Ищет последовательность цифр в тексте и удаляет все нечисловые символы
269
+ * (пробелы, дефисы, точки и т.д.), оставляя только цифры.
270
+ *
271
+ * Примеры:
272
+ * - "304 467 088" → "304467088"
273
+ * - "12-34-567890" → "1234567890"
274
+ * - "123.456.789" → "123456789"
275
+ *
276
+ * @param text Исходная строка с ИНН
277
+ * @returns Строка, содержащая только цифры, или undefined, если ИНН не найден
278
+ */
279
+ extractTin(text) {
280
+ if (!text)
281
+ return undefined;
282
+ // Ищем последовательность цифр (возможно с пробелами/разделителями)
283
+ const tinMatch = text.match(/\d[\d\s\-\.]+\d/);
284
+ if (!tinMatch)
285
+ return undefined;
286
+ // Удаляем ВСЕ нечисловые символы
287
+ const tin = tinMatch[0].replace(/\D/g, '');
288
+ return tin || undefined;
289
+ }
290
+ /**
291
+ * Определяет, является ли клиент Chain (группой компаний).
292
+ *
293
+ * Chain определяется наличием хотя бы одной из кнопок на странице client-area:
294
+ * - "Cloud license allocation"
295
+ * - "SaaS license allocation"
296
+ *
297
+ * Эти кнопки ведут на:
298
+ * - /client-area/licenses/cloud-mapping.html
299
+ * - /client-area/licenses/saas-mapping.html
300
+ *
301
+ * Метод ищет ссылки (<a>) содержащие эти пути в атрибуте href.
302
+ *
303
+ * @param html HTML контент страницы client-area
304
+ * @returns true если клиент является Chain, иначе false
305
+ */
306
+ detectIsChain(html) {
307
+ const $ = cheerio.load(html);
308
+ // Ищем ссылки на allocation страницы
309
+ let hasCloudAllocation = false;
310
+ let hasSaasAllocation = false;
311
+ $('a').each((_, element) => {
312
+ const href = $(element).attr('href');
313
+ if (href) {
314
+ if (href.includes('cloud-mapping.html')) {
315
+ hasCloudAllocation = true;
316
+ }
317
+ if (href.includes('saas-mapping.html')) {
318
+ hasSaasAllocation = true;
319
+ }
320
+ }
321
+ });
322
+ return hasCloudAllocation || hasSaasAllocation;
323
+ }
324
+ /**
325
+ * Парсит HTML страницу allocation (cloud или saas).
326
+ *
327
+ * Извлекает членов chain из JSON данных в атрибуте data-template-params.
328
+ *
329
+ * Структура JSON:
330
+ * - tps: массив торговых точек (members chain)
331
+ * - mapping: распределение лицензий по продуктам
332
+ *
333
+ * Каждый элемент tps содержит:
334
+ * - id: внутренний ID
335
+ * - obfuscated_id: ID для URL (используется как clientId)
336
+ * - name: название торговой точки
337
+ * - link: ссылка на профиль (/client-area/index.html?clientId=XXX)
338
+ *
339
+ * Mapping содержит количество лицензий по формуле:
340
+ * mapping[productId][date][firmId][tpId] = количество
341
+ *
342
+ * Для подсчёта allocation суммируются все значения для каждого tp.
343
+ *
344
+ * @param html HTML контент страницы cloud-mapping или saas-mapping
345
+ * @returns Массив AllocationMember с информацией о членах и их allocation
346
+ */
347
+ parseAllocationPage(html) {
348
+ const $ = cheerio.load(html);
349
+ const members = [];
350
+ try {
351
+ // Ищем form с data-template-params
352
+ const $form = $('form[data-template-params]');
353
+ if ($form.length === 0) {
354
+ console.warn('⚠️ No form with data-template-params found');
355
+ return members;
356
+ }
357
+ // Извлекаем JSON из атрибута
358
+ const dataAttr = $form.attr('data-template-params');
359
+ if (!dataAttr) {
360
+ console.warn('⚠️ data-template-params attribute is empty');
361
+ return members;
362
+ }
363
+ // Декодируем HTML entities (&quot; → ")
364
+ const jsonStr = dataAttr
365
+ .replace(/&quot;/g, '"')
366
+ .replace(/&amp;/g, '&')
367
+ .replace(/&lt;/g, '<')
368
+ .replace(/&gt;/g, '>');
369
+ // Парсим JSON
370
+ const data = JSON.parse(jsonStr);
371
+ if (!data.tps || !Array.isArray(data.tps)) {
372
+ console.warn('⚠️ No tps array in data-template-params');
373
+ return members;
374
+ }
375
+ // Создаём Map для подсчёта allocation каждого member
376
+ const allocationMap = new Map();
377
+ // Если есть mapping, подсчитываем allocation
378
+ if (data.mapping && typeof data.mapping === 'object') {
379
+ // mapping[productId][date][firmId][tpId] = qty
380
+ for (const productId in data.mapping) {
381
+ const productData = data.mapping[productId];
382
+ for (const date in productData) {
383
+ const dateData = productData[date];
384
+ for (const firmId in dateData) {
385
+ const firmData = dateData[firmId];
386
+ for (const tpId in firmData) {
387
+ const qty = parseInt(firmData[tpId], 10);
388
+ if (!isNaN(qty) && qty > 0) {
389
+ const current = allocationMap.get(tpId) || 0;
390
+ allocationMap.set(tpId, current + qty);
391
+ }
392
+ }
393
+ }
394
+ }
395
+ }
396
+ }
397
+ // Обрабатываем каждую торговую точку
398
+ for (const tp of data.tps) {
399
+ // obfuscated_id используется в URL как clientId
400
+ const clientId = tp.obfuscated_id?.toString() || tp.id?.toString();
401
+ const name = tp.name || '';
402
+ if (!clientId || !name) {
403
+ continue;
404
+ }
405
+ // Получаем allocation для этого tp
406
+ const allocation = allocationMap.get(tp.id?.toString() || '') || 0;
407
+ members.push({
408
+ name,
409
+ clientId,
410
+ allocation,
411
+ });
412
+ }
413
+ console.log(`📊 Parsed ${members.length} members from data-template-params`);
414
+ }
415
+ catch (error) {
416
+ console.error('❌ Error parsing data-template-params:', error);
417
+ // Fallback: пытаемся парсить старым способом через HTML таблицу
418
+ return this.parseAllocationPageLegacy(html);
419
+ }
420
+ return members;
421
+ }
422
+ /**
423
+ * Legacy метод парсинга allocation через HTML таблицу.
424
+ *
425
+ * Используется как fallback если JSON парсинг не сработал.
426
+ * Ищет таблицу с членами chain и input полями с allocation.
427
+ *
428
+ * @param html HTML контент страницы allocation
429
+ * @returns Массив AllocationMember
430
+ */
431
+ parseAllocationPageLegacy(html) {
432
+ const $ = cheerio.load(html);
433
+ const members = [];
434
+ // Ищем таблицу в блоке "Store of the chain"
435
+ $('table tbody tr').each((_, row) => {
436
+ const $row = $(row);
437
+ // Первый столбец содержит ссылку на клиента
438
+ const $firstTd = $row.find('td').first();
439
+ const $link = $firstTd.find('a');
440
+ if ($link.length === 0) {
441
+ return; // skip rows without links
442
+ }
443
+ const name = $link.text().trim();
444
+ const href = $link.attr('href');
445
+ // Извлекаем clientId из URL
446
+ const clientIdMatch = href?.match(/clientId=(\d+)/);
447
+ const clientId = clientIdMatch ? clientIdMatch[1] : null;
448
+ if (!clientId || !name) {
449
+ return; // skip invalid rows
450
+ }
451
+ // Ищем input поле с allocation
452
+ let allocation = 0;
453
+ $row.find('input[type="number"]').each((_, input) => {
454
+ const value = $(input).attr('value') || $(input).val();
455
+ if (value) {
456
+ const parsed = parseInt(value.toString(), 10);
457
+ if (!isNaN(parsed)) {
458
+ allocation = parsed;
459
+ return false; // break
460
+ }
461
+ }
462
+ });
463
+ members.push({
464
+ name,
465
+ clientId,
466
+ allocation,
467
+ });
468
+ });
469
+ return members;
470
+ }
471
+ }
472
+ exports.ClientsParser = ClientsParser;
473
+ //# sourceMappingURL=clients.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.parser.js","sourceRoot":"","sources":["../../src/clients/clients.parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { IikoSessionService } from '../core/session/iiko-session.service';
2
+ import { ParserProgressCallback } from '../types';
3
+ import { ClientsFilter, ClientData } from './clients.types';
4
+ export declare class ClientsService {
5
+ private sessionService;
6
+ private progressCallback?;
7
+ private fetcher;
8
+ private parser;
9
+ constructor(sessionService: IikoSessionService, progressCallback?: ParserProgressCallback | undefined);
10
+ /**
11
+ * Загружает и парсит список клиентов с пагинацией.
12
+ *
13
+ * Алгоритм работы:
14
+ * 1. Инициализирует сессию (должна быть выполнена до вызова через ensureSession())
15
+ * 2. Загружает страницы клиентов через /en/cabinet/ajax/clients-list.html
16
+ * 3. Парсит каждую страницу, извлекая name и clientId из HTML таблицы
17
+ * 4. Останавливается когда:
18
+ * - Получена пустая страница (нет больше клиентов)
19
+ * - Достигнут лимит maxPages
20
+ * - Получено меньше элементов чем perPage (последняя страница)
21
+ * 5. Для каждого клиента загружает детальную информацию с /en/cabinet/client-area/index.html
22
+ * 6. Парсит профиль клиента (UUID, iiko версия, email, phone, юр.лицо, ИНН)
23
+ *
24
+ * Параметры пагинации:
25
+ * - query: поисковый запрос (фильтрация по имени или UID на стороне сервера)
26
+ * - perPage: количество клиентов на странице (по умолчанию: 20)
27
+ * - maxPages: максимальное количество страниц для загрузки (по умолчанию: все)
28
+ *
29
+ * Progress события:
30
+ * - fetch_clients: при загрузке каждой страницы списка
31
+ * - parse_clients: после завершения парсинга всех страниц
32
+ * - fetch_client_details: при загрузке деталей каждого клиента
33
+ *
34
+ * @param filter Опциональные параметры фильтрации и пагинации
35
+ * @returns Массив клиентов с полной информацией (UUID, версия, контакты, юр.данные)
36
+ */
37
+ fetchAndParseClients(filter?: ClientsFilter): Promise<ClientData[]>;
38
+ /**
39
+ * Обогащает список клиентов детальной информацией с поддержкой Chain логики.
40
+ *
41
+ * Алгоритм:
42
+ * 1. Создаёт Map для дедупликации (clientId → ClientData)
43
+ * 2. Создаёт Set для отслеживания членов chain (чтобы исключить их из root списка)
44
+ * 3. Для каждого клиента:
45
+ * - Загружает профиль
46
+ * - Проверяет uuid/clientId (пропускает если нет)
47
+ * - Определяет isChain
48
+ * - Если chain: загружает allocation и собирает members
49
+ * 4. Финальный результат: только клиенты, которые НЕ являются members других chain
50
+ *
51
+ * @param clients Список клиентов с базовой информацией (name, clientId)
52
+ * @returns Массив клиентов с полной информацией, chain содержат members[], дедуплицированные
53
+ */
54
+ private enrichWithDetails;
55
+ /**
56
+ * Загружает членов chain из allocation страниц.
57
+ *
58
+ * Алгоритм:
59
+ * 1. Загружает cloud-mapping.html и saas-mapping.html
60
+ * 2. Парсит списки members из обеих страниц
61
+ * 3. Объединяет данные (по clientId):
62
+ * - Если member есть только в cloud → cloudAllocation > 0, saasAllocation = 0
63
+ * - Если member есть только в saas → cloudAllocation = 0, saasAllocation > 0
64
+ * - Если member есть в обоих → оба allocation > 0
65
+ * 4. Для каждого member загружает полный профиль (UUID, email, phone, etc.)
66
+ * 5. Возвращает массив ClientMember
67
+ *
68
+ * @param chainClientId ID chain для загрузки allocation
69
+ * @param chainName Имя chain для логирования
70
+ * @returns Массив ClientMember с полной информацией и allocation
71
+ */
72
+ private loadChainMembers;
73
+ /**
74
+ * Отправляет событие прогресса в callback, если он был передан.
75
+ *
76
+ * Используется для информирования внешнего кода о текущем состоянии выполнения:
77
+ * - fetch_clients: загрузка страниц списка клиентов
78
+ * - parse_clients: завершение парсинга списка
79
+ * - fetch_client_details: загрузка деталей каждого клиента
80
+ * - detect_chain: определение chain
81
+ * - load_chain_members: загрузка членов chain
82
+ *
83
+ * Безопасно проверяет наличие callback перед вызовом.
84
+ *
85
+ * @param stage Стадия выполнения операции
86
+ * @param data Данные о прогрессе (текущее значение, общее количество, сообщение)
87
+ */
88
+ private report;
89
+ }
90
+ //# sourceMappingURL=clients.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.service.d.ts","sourceRoot":"","sources":["../../src/clients/clients.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAGlD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAkD,MAAM,iBAAiB,CAAC;AAE5G,qBAAa,cAAc;IAKvB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,gBAAgB,CAAC;IAL3B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,MAAM,CAAgB;gBAGpB,cAAc,EAAE,kBAAkB,EAClC,gBAAgB,CAAC,EAAE,sBAAsB,YAAA;IAMnD;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACU,oBAAoB,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAyDhF;;;;;;;;;;;;;;;OAeG;YACW,iBAAiB;IAyE/B;;;;;;;;;;;;;;;;OAgBG;YACW,gBAAgB;IA8E9B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,MAAM;CAaf"}