// Функция генерации HTML формы подтверждения заявления // Основана на структуре из n8n Code node "Mini-app Подтверждение данных" export function generateConfirmationFormHTML(data: any): string { // Нормализуем данные const raw = { propertyName: data.case || {}, session_token: data.session_token || '', prefix: data.sms_meta?.prefix || '', telegram_id: data.telegram_id || '', claim_id: data.case?.meta?.claim_id || '', unified_id: data.case?.meta?.unified_id || '', user_id: data.case?.meta?.user_id || '', token: data.token || '', }; // Извлекаем SMS данные const smsInputData = { prefix: raw.prefix || '', session_token: raw.session_token || '', telegram_id: raw.telegram_id || '', claim_id: raw.claim_id || '', unified_id: (raw.propertyName && raw.propertyName.meta && raw.propertyName.meta.unified_id) || '', user_id: (raw.propertyName && raw.propertyName.meta && raw.propertyName.meta.user_id) || '', status: (raw.propertyName && raw.propertyName.meta && raw.propertyName.meta.status) || '', }; // Утилиты function safeGet(...keys: any[]): any { for (const k of keys) { if (k === undefined || k === null) continue; if (typeof k === 'object') { if (Object.keys(k).length) return k; continue; } const s = String(k).trim(); if (s !== '') return k; } return ''; } function tryParseJSON(x: any): any { try { return typeof x === 'string' ? JSON.parse(x) : x; } catch { return null; } } function escapeHtml(str: any): string { if (str === undefined || str === null) return ''; return String(str) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } // Нормализация денежной суммы function normalizeMoney(rawValue: any): number | null { if (!rawValue) return null; let s = String(rawValue); s = s.replace(/\s+/g, ''); s = s.replace(/руб(лей|ль|\.)?/gi, ''); s = s.replace(/₽|р\.|р$/gi, ''); s = s.replace(/[^0-9,.-]/g, ''); s = s.replace(',', '.'); if (!/^-?[0-9]+(\.[0-9]{1,2})?$/.test(s)) return null; const result = parseFloat(s); return result > 0 ? result : null; } // Базовые схемы const baseUser = { firstname: null, secondname: null, lastname: null, mobile: null, email: null, tgid: null, birthday: null, birthplace: null, mailingstreet: null, inn: null, }; const baseProject = { category: null, direction: null, agrprice: null, subject: null, agrdate: null, startdate: null, finishdate: null, period_text: null, description: null, reason: null, }; const baseOffender = { accountname: null, address: null, email: null, website: null, phone: null, inn: null, ogrn: null, }; // Нормализация данных function normalizeData(data: any): any { // Если данные приходят в новом формате (с propertyName) if (data.propertyName && data.propertyName.applicant) { const props = data.propertyName; const applicant = props.applicant || {}; const caseData = props.case || {}; const contract = props.contract_or_service || {}; const offenders = props.offenders || []; const claim = props.claim || {}; const meta = props.meta || {}; const attachments = props.attachments_names || []; return { user: { firstname: applicant.first_name || null, secondname: applicant.middle_name || null, lastname: applicant.last_name || null, mobile: applicant.phone || null, email: applicant.email || null, birthday: applicant.birth_date_fmt || applicant.birth_date || null, birthplace: applicant.birth_place || null, mailingstreet: applicant.address || null, inn: applicant.inn || null, tgid: null, }, project: { category: caseData.category || null, direction: caseData.direction || null, agrprice: normalizeMoney(contract.amount_paid_fmt || contract.amount_paid) || null, subject: contract.subject || null, agrdate: contract.agreement_date_fmt || contract.agreement_date || null, startdate: contract.period_start_fmt || contract.period_start || null, finishdate: contract.period_end_fmt || contract.period_end || null, period_text: contract.period_text || null, description: claim.description || null, reason: claim.reason || caseData.category || null, }, attachments: attachments, offenders: offenders.map((o: any) => ({ accountname: o.name || null, address: o.address || null, email: o.email || null, website: o.website || null, phone: o.phone || null, inn: o.inn || null, ogrn: o.ogrn || null, })), meta: { ...meta, session_token: data.session_token || meta.claim_id || null, prefix: data.prefix || null, telegram_id: data.telegram_id || null, claim_id: data.claim_id || meta.claim_id || null, unified_id: meta.unified_id || null, user_id: meta.user_id || null, }, }; } // Старый формат (обратная совместимость) return { user: Object.assign({}, baseUser, tryParseJSON(data.user) || data.user || {}), project: Object.assign({}, baseProject, tryParseJSON(data.project) || data.project || {}), offenders: Array.isArray(data.offenders) ? data.offenders.map((o: any) => Object.assign({}, baseOffender, o || {})) : [], meta: Object.assign({}, data.meta || {}), }; } // Нормализуем данные let dataCandidate = null; if (raw.propertyName !== undefined) { if (typeof raw.propertyName === 'object' && raw.propertyName !== null) { dataCandidate = raw.propertyName; } else if (typeof raw.propertyName === 'string') { dataCandidate = tryParseJSON(raw.propertyName); } } if (!dataCandidate && raw.value !== undefined) dataCandidate = tryParseJSON(raw.value); if (!dataCandidate && (raw.user || raw.project || raw.offenders || raw.meta)) dataCandidate = raw; if (!dataCandidate && raw.data) dataCandidate = raw.data; if (!dataCandidate && raw.output) dataCandidate = tryParseJSON(raw.output) || raw.output; dataCandidate = dataCandidate || {}; const dataToNormalize = Array.isArray(dataCandidate) ? dataCandidate[0] : dataCandidate; const caseObj = normalizeData({ propertyName: dataToNormalize, ...raw }); if (!caseObj.offenders.length) { caseObj.offenders = [Object.assign({}, baseOffender)]; } // Сервисные поля const sessionToken = String(safeGet(caseObj.meta?.session_token, raw.session_token, '')); const telegramId = String(safeGet(caseObj.user?.tgid, raw.telegram_id, '')); const smsMetaData = { session_token: String(safeGet(smsInputData.session_token, sessionToken, '')), prefix: String(safeGet(smsInputData.prefix, '')), telegram_id: String(safeGet(smsInputData.telegram_id, telegramId, '')), claim_id: String(safeGet(smsInputData.claim_id, '')), unified_id: String(safeGet(smsInputData.unified_id, '')), user_id: String(safeGet(smsInputData.user_id, '')), }; // Безопасно встраиваем данные в HTML let caseJson = JSON.stringify({ case: caseObj, session_token: sessionToken, telegram_id: telegramId, token: raw.token || '', sms_meta: smsMetaData, }); caseJson = caseJson.replace(/
Проверьте и при необходимости отредактируйте все поля