- Исправлена потеря документов при обновлении черновика (SQL объединяет вместо перезаписи) - Исправлено определение типа документа (приоритет field_label над field_name) - Исправлены дубликаты в documents_meta и documents_uploaded - Добавлена передача group_index с фронтенда для правильного field_name - Исправлены все документы в таблице clpr_claim_documents с правильными field_name - Обновлены SQL запросы: claimsave и claimsave_final для нового флоу - Добавлена поддержка multi-file upload для одного документа - Исправлены дубликаты в списке загруженных документов на фронтенде Файлы: - SQL: SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql, SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql - n8n: N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js (поддержка group_index) - Backend: documents.py (передача group_index в n8n) - Frontend: StepWizardPlan.tsx (передача group_index, исправление дубликатов) - Скрипты: fix_claim_documents_field_names.py, fix_documents_meta_duplicates.py Результат: документы больше не теряются, имеют правильные типы и field_name
131 lines
4.9 KiB
SQL
131 lines
4.9 KiB
SQL
-- ============================================================================
|
||
-- Исправленный SQL для сохранения документов (claimsave_final) - ПОДДЕРЖКА НОВОГО ФЛОУ
|
||
-- ============================================================================
|
||
-- Проблема: SQL не сохранял documents_required и мог перезаписать статус
|
||
-- Решение: Сохраняем documents_required и не перезаписываем новые статусы
|
||
-- ============================================================================
|
||
|
||
WITH partial AS (
|
||
SELECT $1::jsonb AS p, $2::text AS claim_id_str
|
||
),
|
||
|
||
claim_lookup AS (
|
||
SELECT
|
||
c.id,
|
||
c.payload,
|
||
c.status_code
|
||
FROM clpr_claims c, partial
|
||
WHERE c.id::text = partial.claim_id_str
|
||
OR c.payload->>'claim_id' = partial.claim_id_str
|
||
ORDER BY
|
||
CASE WHEN c.id::text = partial.claim_id_str THEN 1 ELSE 2 END,
|
||
c.updated_at DESC
|
||
LIMIT 1
|
||
),
|
||
|
||
docs AS (
|
||
SELECT
|
||
claim_lookup.id::text AS claim_id,
|
||
doc.field_name::text AS field_name,
|
||
doc.file_id::text AS file_id,
|
||
doc.file_name::text AS file_name,
|
||
doc.original_file_name::text AS original_file_name,
|
||
(doc.uploaded_at)::timestamptz AS uploaded_at,
|
||
doc.file_url::text AS file_url
|
||
FROM partial, claim_lookup
|
||
CROSS JOIN LATERAL jsonb_to_recordset(
|
||
COALESCE(partial.p->'documents_meta','[]'::jsonb)
|
||
) AS doc(
|
||
field_name text, file_id text, file_name text,
|
||
original_file_name text, uploaded_at text, file_url text
|
||
)
|
||
),
|
||
|
||
upsert_docs AS (
|
||
INSERT INTO clpr_claim_documents
|
||
(claim_id, field_name, file_id, uploaded_at, file_name, original_file_name)
|
||
SELECT claim_id, field_name, file_id, uploaded_at, file_name, original_file_name
|
||
FROM docs
|
||
ON CONFLICT (claim_id, field_name) DO UPDATE
|
||
SET file_id = EXCLUDED.file_id,
|
||
uploaded_at = EXCLUDED.uploaded_at,
|
||
file_name = EXCLUDED.file_name,
|
||
original_file_name = EXCLUDED.original_file_name
|
||
RETURNING id, claim_id, field_name, file_id
|
||
),
|
||
|
||
-- ✅ ИСПРАВЛЕНО: Сохраняем documents_required и обновляем статус правильно
|
||
upd_claim AS (
|
||
UPDATE clpr_claims c
|
||
SET
|
||
-- ✅ Объединяем payload: сохраняем documents_required и documents_meta
|
||
payload = jsonb_set(
|
||
jsonb_set(
|
||
COALESCE(c.payload, '{}'::jsonb),
|
||
'{documents_meta}',
|
||
COALESCE((SELECT p->'documents_meta' FROM partial), '[]'::jsonb),
|
||
true
|
||
),
|
||
'{documents_required}',
|
||
COALESCE(
|
||
(SELECT p->'documents_required' FROM partial WHERE partial.p->'documents_required' IS NOT NULL),
|
||
c.payload->'documents_required', -- Сохраняем существующий, если новый не пришёл
|
||
'[]'::jsonb
|
||
),
|
||
true
|
||
),
|
||
-- ✅ Обновляем статус только если нужно (не перезаписываем новые статусы)
|
||
status_code = CASE
|
||
-- Если статус уже новый - сохраняем его
|
||
WHEN c.status_code IN ('draft_new', 'draft_docs_progress', 'draft_docs_complete', 'draft_claim_ready')
|
||
THEN c.status_code
|
||
-- Если есть documents_required и документы загружены - обновляем статус
|
||
WHEN c.payload->'documents_required' IS NOT NULL
|
||
AND jsonb_array_length(COALESCE(c.payload->'documents_required', '[]'::jsonb)) > 0
|
||
AND (SELECT COUNT(*) FROM docs) > 0
|
||
THEN CASE
|
||
WHEN (SELECT COUNT(*) FROM docs) >= jsonb_array_length(COALESCE(c.payload->'documents_required', '[]'::jsonb))
|
||
THEN 'draft_docs_complete'
|
||
ELSE 'draft_docs_progress'
|
||
END
|
||
-- Иначе сохраняем существующий
|
||
ELSE c.status_code
|
||
END,
|
||
updated_at = now(),
|
||
expires_at = now() + interval '14 days'
|
||
FROM partial, claim_lookup
|
||
WHERE c.id = claim_lookup.id
|
||
RETURNING c.id, c.payload, c.status_code
|
||
)
|
||
|
||
SELECT
|
||
(SELECT jsonb_build_object(
|
||
'claim_id', u.id::text,
|
||
'status_code', u.status_code,
|
||
'payload', u.payload
|
||
) FROM upd_claim u) AS claim,
|
||
|
||
(
|
||
SELECT jsonb_agg(
|
||
jsonb_build_object(
|
||
'id', u.id,
|
||
'field_name', u.field_name,
|
||
'file_id', u.file_id,
|
||
'file_url', d.file_url,
|
||
'file_name', d.file_name,
|
||
'original_file_name', d.original_file_name,
|
||
'uploaded_at', d.uploaded_at,
|
||
'filename_for_upload',
|
||
COALESCE(
|
||
NULLIF(d.original_file_name, ''),
|
||
NULLIF(d.file_name, ''),
|
||
regexp_replace(d.file_id, '^.*/', '')
|
||
)
|
||
)
|
||
)
|
||
FROM upsert_docs u
|
||
JOIN docs d ON d.claim_id = u.claim_id AND d.field_name = u.field_name
|
||
WHERE d.file_url IS NOT NULL AND d.file_url <> ''
|
||
) AS documents;
|
||
|