Загрузка данных
Нужно доработать **SQL-процедуру `dbo.WR_mtsCertificate_v12`**: после сохранения сертификата заполнять пустое `sb_reports.manFIO` из `dat_mts_certificates.manFIO`.
Python уже передаёт `issuerName`, и у всех 136 проблемных записей ФИО сохранено в таблице сертификатов. Поэтому дополнительный запрос к API не нужен.
Вставьте этот блок **внутри существующей транзакции, непосредственно перед `COMMIT;`**:
```sql
-- Заполняем только пустое ФИО отчёта.
-- Непустые значения и применённые исправления сохраняем.
UPDATE r
SET r.manFIO = c.manFIO
FROM dbo.sb_reports AS r
JOIN dbo.dat_members AS m
ON m.kod = r.kodMember
JOIN dbo.dat_activity AS a
ON a.kod = m.kodMerop
JOIN dbo.dat_mts_certificates AS c
ON c.kodReport = r.kod
AND c.kodMember = m.kod
AND c.kodMerop = a.kod
WHERE r.kod = @kodReport
AND m.kod = @kodMember
AND a.kod = @kodMerop
AND c.sessionId = @sessionId
AND c.participantId = @participantId
AND r.a1 LIKE N'otzyvMTS[_]%'
AND ISNULL(r.correctionApplied, 0) = 0
AND ISNULL(r.processingStatus, N'') = N''
AND c.fallbackAt IS NULL
AND c.internalSentAt IS NULL
AND NULLIF(LTRIM(RTRIM(r.manFIO)), N'') IS NULL
AND NULLIF(LTRIM(RTRIM(c.manFIO)), N'') IS NOT NULL
AND NULLIF(LTRIM(RTRIM(c.mtsCertNumber)), N'') IS NOT NULL
-- Не выбираем произвольный источник при дублировании.
AND NOT EXISTS (
SELECT 1
FROM dbo.dat_mts_certificates AS other
WHERE other.kodReport = r.kod
AND other.kod <> c.kod
)
-- Дополнительная защита от перезаписи исправленной версии.
AND NOT EXISTS (
SELECT 1
FROM dbo.mts_daemon_mail_v12 AS j
WHERE j.kodReport = r.kod
AND j.kind IN ('correction', 'fallback_certificate')
AND (
j.appliedAt IS NOT NULL
OR j.state IN ('QUEUED', 'SENT')
)
);
```
Здесь **`LTRIM/RTRIM` используются только для проверки пустоты**. В отчёт записывается полное исходное `c.manFIO`, без обрезки и изменения текста. Проверка допуска со строгим `>` остаётся в существующей части процедуры.
Также в этой же процедуре замените текущую строку:
```sql
SET manFIO = COALESCE(
manFIO,
NULLIF(JSON_VALUE(@formData, '$.issuerName'), N'')
),
```
на:
```sql
SET manFIO = CASE
WHEN NULLIF(LTRIM(RTRIM(manFIO)), N'') IS NULL
AND NULLIF(
LTRIM(RTRIM(JSON_VALUE(@formData, '$.issuerName'))),
N''
) IS NOT NULL
THEN JSON_VALUE(@formData, '$.issuerName')
ELSE manFIO
END,
```
Это исправит ещё один случай: прежний `COALESCE` сохраняет пустую строку или пробелы, поскольку они не являются `NULL`.
**Что произойдёт с существующими 136 записями**
После изменения процедуры следующий цикл, повторно обрабатывающий эти сертификаты, заполнит подходящие отчёты. По последней выгрузке сертификаты повторно проверяются, поэтому отдельный массовый UPDATE сначала не нужен. Исключённые защитными условиями записи останутся для ручного разбора.
После полного цикла проверьте остаток:
```sql
SELECT
c.kodMerop,
COUNT_BIG(*) AS missingReportFIO
FROM dbo.dat_mts_certificates AS c
JOIN dbo.sb_reports AS r
ON r.kod = c.kodReport
AND r.kodMember = c.kodMember
WHERE NULLIF(LTRIM(RTRIM(c.mtsCertNumber)), N'') IS NOT NULL
AND NULLIF(LTRIM(RTRIM(c.manFIO)), N'') IS NOT NULL
AND NULLIF(LTRIM(RTRIM(r.manFIO)), N'') IS NULL
GROUP BY c.kodMerop
ORDER BY missingReportFIO DESC;
```
**Не заменяйте процедуру целиком старой версией из выгрузки:** добавьте изменения в её текущую серверную версию, сохранив уже расширенные строковые параметры. Этот патч устраняет отсутствие переноса ФИО; правильность самого имени, введённого участником, он не меняет.