- Enhanced validator with critical zero-price validation - Fixed currency GUIDs and money formatting in XML generator - Removed incompatible VidED field - Added comprehensive documentation - Updated test files
297 lines
12 KiB
Markdown
297 lines
12 KiB
Markdown
# Исправления XML генератора - 6 ноября 2025
|
||
|
||
## Выполненные критичные исправления
|
||
|
||
### ✅ 1. Исправлена потеря копеек (КРИТИЧНО)
|
||
|
||
**Было:**
|
||
```python
|
||
etree.SubElement(row_elem, "Сумма").text = str(int(total)) # Отбрасывались копейки
|
||
etree.SubElement(row_elem, "Цена").text = str(int(price)) # Отбрасывались копейки
|
||
```
|
||
|
||
**Стало:**
|
||
```python
|
||
etree.SubElement(row_elem, "Сумма").text = f"{total:.2f}" # 2 знака после запятой
|
||
etree.SubElement(row_elem, "Цена").text = f"{price:.2f}" # 2 знака после запятой
|
||
```
|
||
|
||
**Результат тестирования:**
|
||
- Цена: 1234.56 руб ✅ (было бы 1234)
|
||
- Количество: 10 шт
|
||
- Сумма: 12345.60 руб ✅ (было бы 12345)
|
||
- **Разница: 56 коп на строку, 5.60 руб на документ** - это критично для налогового учёта!
|
||
|
||
---
|
||
|
||
### ✅ 2. Удалено поле ВидЭД (КРИТИЧНО)
|
||
|
||
**Было:**
|
||
```python
|
||
etree.SubElement(doc, "ВидЭД").text = "ТОРГ12"
|
||
```
|
||
|
||
**Стало:**
|
||
```python
|
||
# Поле удалено - его нет в схеме EnterpriseData 1.20
|
||
```
|
||
|
||
**Причина:**
|
||
- Поле `ВидЭД` используется в УПД/ФормализованныхДокументах
|
||
- В EnterpriseData 1.20 этого поля нет
|
||
- Приводило к ошибке валидации по XSD
|
||
|
||
---
|
||
|
||
### ✅ 3. Fallback даты заменён на исключение (КРИТИЧНО)
|
||
|
||
**Было:**
|
||
```python
|
||
except Exception as e:
|
||
logger.error(f"Ошибка форматирования даты: {e}")
|
||
return datetime.now().strftime("%Y-%m-%dT%H:%M:%S") # Подставляем текущую дату
|
||
```
|
||
|
||
**Стало:**
|
||
```python
|
||
except Exception as e:
|
||
logger.error(f"Критическая ошибка: некорректная дата '{date_str}': {e}")
|
||
raise ValueError(
|
||
f"Невозможно сформировать документ с некорректной датой: {date_str}. "
|
||
"Проверьте исходные данные."
|
||
)
|
||
```
|
||
|
||
**Причина:**
|
||
- Подстановка текущей даты вместо корректной - искажение первичного документа
|
||
- Риск налоговых проблем (неверный период)
|
||
- Теперь генерация прерывается с понятной ошибкой
|
||
|
||
---
|
||
|
||
### ⚠️ 4. Счета учёта закомментированы (опционально)
|
||
|
||
**Было:**
|
||
```python
|
||
etree.SubElement(row_elem, "СчетУчета").text = "43"
|
||
etree.SubElement(row_elem, "СчетДоходов").text = "90.01.1"
|
||
etree.SubElement(row_elem, "СчетРасходов").text = "90.02.1"
|
||
etree.SubElement(row_elem, "СчетУчетаНДСПоРеализации").text = "90.03"
|
||
```
|
||
|
||
**Стало:**
|
||
```python
|
||
# ВНИМАНИЕ: Следующие поля могут отсутствовать в XSD некоторых версий 1С
|
||
# Если импорт падает - закомментируйте эти строки
|
||
etree.SubElement(row_elem, "ТипЗапасов").text = "СобственныеТовары"
|
||
# TODO: Сделать опциональными через config
|
||
# etree.SubElement(row_elem, "СчетУчета").text = "43"
|
||
# etree.SubElement(row_elem, "СчетДоходов").text = "90.01.1"
|
||
# etree.SubElement(row_elem, "СчетРасходов").text = "90.02.1"
|
||
# etree.SubElement(row_elem, "СчетУчетаНДСПоРеализации").text = "90.03"
|
||
```
|
||
|
||
**Причина:**
|
||
- Эти поля есть не во всех версиях EnterpriseData
|
||
- Зависит от конфигурации 1С клиента
|
||
- Оставлен только `ТипЗапасов` (более универсален)
|
||
|
||
---
|
||
|
||
## Проблемы, требующие проверки с клиентом
|
||
|
||
### ⚠️ 1. Жёстко прошитые GUID справочников
|
||
|
||
**Местоположение:**
|
||
- Валюта: `72357d18-63a8-11e8-80dd-0050569f5448` (RUB)
|
||
- Страна: `67700c1b-63a8-11e8-80dd-0050569f5448` (Россия)
|
||
- ЕдиницаИзмерения: `cdf130e2-63a8-11e8-80dd-0050569f5448` (штука)
|
||
|
||
**Риск:**
|
||
- Эти GUID уникальны для конкретной базы
|
||
- В базе клиента могут быть другие GUID
|
||
- Импорт завершится ошибкой "Объект не найден"
|
||
|
||
**Решения:**
|
||
1. **Получить GUID из базы клиента** (запросом к 1С)
|
||
2. **Убрать `<Ссылка>`**, передавать только коды (643, 796, RUB)
|
||
3. **Включить флаг "создавать отсутствующие объекты"** в настройках обмена
|
||
|
||
**Рекомендация:**
|
||
```xml
|
||
<!-- Вариант А: Без Ссылки (пусть 1С найдёт по коду) -->
|
||
<Валюта>
|
||
<ДанныеКлассификатора>
|
||
<Код>643</Код>
|
||
<НаименованиеПолное>Российский рубль</НаименованиеПолное>
|
||
<КодЦифровой>643</КодЦифровой>
|
||
<КодСимвольный>RUB</КодСимвольный>
|
||
</ДанныеКлассификатора>
|
||
</Валюта>
|
||
|
||
<!-- Вариант Б: Получить GUID из базы клиента через HTTP-сервис -->
|
||
```
|
||
|
||
---
|
||
|
||
### ⚠️ 2. Структура валюты/банков
|
||
|
||
**Текущая структура:**
|
||
```xml
|
||
<Валюта>
|
||
<Ссылка>guid</Ссылка>
|
||
<ДанныеКлассификатора>
|
||
<Код>643</Код>
|
||
<Наименование>руб.</Наименование>
|
||
</ДанныеКлассификатора>
|
||
</Валюта>
|
||
```
|
||
|
||
**Проблема:**
|
||
- Структура может не соответствовать XSD 1.20 клиента
|
||
- В разных версиях ED структура отличается
|
||
|
||
**TODO:**
|
||
- [ ] Получить от клиента актуальный XSD EnterpriseData 1.20
|
||
- [ ] Сверить структуру валюты, банка, страны
|
||
- [ ] При необходимости адаптировать
|
||
|
||
---
|
||
|
||
### ⚠️ 3. Банк/счёт - некорректные ссылки
|
||
|
||
**Текущий код (строка 833):**
|
||
```python
|
||
bank_elem = etree.SubElement(bank_acc_elem, "Банк")
|
||
etree.SubElement(bank_elem, "Ссылка").text = acc_id # ❌ ID счёта вместо ID банка
|
||
```
|
||
|
||
**Проблема:**
|
||
- Для банка должен быть свой GUID (из справочника "Банки")
|
||
- Используется GUID счёта - это неверно
|
||
|
||
**Рекомендация:**
|
||
```python
|
||
# Вариант А: Убрать Ссылку, передавать только БИК
|
||
bank_elem = etree.SubElement(bank_acc_elem, "Банк")
|
||
# НЕ создавать <Ссылка>
|
||
bank_data = etree.SubElement(bank_elem, "ДанныеКлассификатораБанков")
|
||
etree.SubElement(bank_data, "БИК").text = acc.get("bic", "")
|
||
# 1С найдёт банк по БИК
|
||
|
||
# Вариант Б: Получить GUID банка из МойСклад или 1С
|
||
bank_id = get_bank_guid_by_bic(acc.get("bic"))
|
||
etree.SubElement(bank_elem, "Ссылка").text = bank_id
|
||
```
|
||
|
||
---
|
||
|
||
### ⚠️ 4. Договор - сложная структура
|
||
|
||
**Текущая структура:**
|
||
```xml
|
||
<Договор>
|
||
<Ссылка>uuid</Ссылка>
|
||
<ВидДоговора>СПокупателем</ВидДоговора>
|
||
<Организация>...</Организация>
|
||
<Контрагент>...</Контрагент>
|
||
</Договор>
|
||
```
|
||
|
||
**Проблема:**
|
||
- Детальная структура может не соответствовать XSD
|
||
- Обычно договор - это просто ссылка
|
||
|
||
**Варианты:**
|
||
1. Если договор УЖЕ существует в базе - передавать только `<Ссылка>`
|
||
2. Если нужно создать - выносить в отдельный блок Message
|
||
3. Уточнить у клиента бизнес-логику
|
||
|
||
---
|
||
|
||
## Что нужно от клиента
|
||
|
||
### 1. XSD EnterpriseData 1.20
|
||
- Актуальная схема для их версии 1С
|
||
- Версия платформы (8.3.xx.xxxx)
|
||
- Конфигурация (УТ, КА, ERP)
|
||
|
||
### 2. GUID справочников
|
||
**Три варианта:**
|
||
- Получить через HTTP-сервис 1С
|
||
- Экспортировать из базы вручную
|
||
- Использовать коды без GUID (рекомендуется)
|
||
|
||
### 3. Тестовая среда
|
||
- Доступ к тестовой базе для импорта
|
||
- Логи ошибок импорта
|
||
- Возможность итерации
|
||
|
||
### 4. Бизнес-требования
|
||
- Как обрабатывать договоры? (создавать/ссылаться)
|
||
- Как обрабатывать банки? (создавать/ссылаться)
|
||
- Нужны ли счета учёта в строках?
|
||
|
||
---
|
||
|
||
## План тестирования
|
||
|
||
### Этап 1: Локальная проверка ✅
|
||
- [x] Копейки сохраняются
|
||
- [x] ВидЭД убран
|
||
- [x] Дата не подменяется
|
||
- [x] Счета учёта закомментированы
|
||
|
||
### Этап 2: Проверка с XSD
|
||
- [ ] Получить XSD от клиента
|
||
- [ ] Валидация по XSD (xmllint или lxml)
|
||
- [ ] Исправление несоответствий
|
||
|
||
### Этап 3: Импорт в тестовую 1С
|
||
- [ ] Импорт тестового XML
|
||
- [ ] Проверка ошибок
|
||
- [ ] Проверка контрольных сумм
|
||
- [ ] Проверка НДС
|
||
|
||
### Этап 4: Production
|
||
- [ ] Финальные правки
|
||
- [ ] Документация для пользователя
|
||
- [ ] Мониторинг первых импортов
|
||
|
||
---
|
||
|
||
## Риски и митигация
|
||
|
||
| Риск | Вероятность | Влияние | Митигация |
|
||
|------|------------|---------|-----------|
|
||
| GUID не найдены в базе | Высокая | Критично | Убрать GUID, использовать коды |
|
||
| Структура не соответствует XSD | Средняя | Критично | Получить XSD, адаптировать |
|
||
| Банк/счёт не создаётся | Средняя | Высоко | Использовать БИК без GUID |
|
||
| Договор не распознаётся | Низкая | Средне | Упростить до Ссылки |
|
||
| Копейки всё ещё теряются | Низкая | Критично | Уже исправлено ✅ |
|
||
|
||
---
|
||
|
||
## Выводы
|
||
|
||
### ✅ Что сделано:
|
||
1. **Копейки сохраняются** - критично для налогового учёта
|
||
2. **ВидЭД убран** - больше не ломает валидацию
|
||
3. **Даты проверяются** - нет риска искажения
|
||
4. **Счета учёта опциональны** - совместимость с разными версиями
|
||
|
||
### ⚠️ Что требует внимания:
|
||
1. **GUID справочников** - высокий риск, нужен XSD клиента
|
||
2. **Структура объектов** - зависит от версии ED
|
||
3. **Банк/счёт** - нужна корректная логика
|
||
|
||
### 📋 Следующие шаги:
|
||
1. Запросить у клиента XSD EnterpriseData 1.20
|
||
2. Протестировать импорт в их тестовой базе
|
||
3. Получить обратную связь по структуре
|
||
4. Доработать под реальную схему
|
||
|
||
**Готовность к продакшену:** ~70%
|
||
- Критичные баги исправлены ✅
|
||
- Нужна проверка совместимости с клиентской 1С ⚠️
|