Дата: 2025-12-25
Версия: 3.0.0 (+ правила фильтрации)
Источники: 1C_PIM_FIELDS_FULL.md, 1C_FIELD_STRUCTURE.md, реальные данные из БД
В 1С три типа номенклатуры:
ТОВАРЫ (ТипНоменклатуры = "Запас")
- Обычные товары (ЭтоНабор = false) → ✅ ГРУЗИМ
- Наборы (ЭтоНабор = true) → ❌ ИГНОРИРУЕМ
УСЛУГИ (ТипНоменклатуры = "Услуга") → ❌ ИГНОРИРУЕМ
Прочее (ТипНоменклатуры = None/null) → ❌ ИГНОРИРУЕМ
| Тип | Количество | Наборов | Грузим |
|---|---|---|---|
| Запас | 469 (93%) | 103 (22%) | 366 (73%) ✅ |
| Услуга | 10 (2%) | 0 | 0 ❌ |
| None | 21 (4%) | 0 | 0 ❌ |
$filter=ТипНоменклатуры eq 'Запас' and ЭтоНабор eq false
def is_valid_product(item: dict) -> bool:
"""Проверка: товар подходит для импорта в PIM"""
typ = item.get('ТипНоменклатуры')
is_bundle = item.get('ЭтоНабор', False)
# Только обычные товары (не услуги, не наборы)
return typ == 'Запас' and not is_bundle
✅ ГРУЗИМ:
- Петарды "Корсар-1" упаковка 20 шт (Запас, ЭтоНабор=false)
- Батарея салютов "Праздничный" 30мм 49 залпов (Запас, ЭтоНабор=false)
❌ ИГНОРИРУЕМ (Наборы):
- Дым 30 сек 115 мм MA0509 Smoking fountain Red - Красный 1,75" НАБОР 3 шт (ЭтоНабор=true)
❌ ИГНОРИРУЕМ (Услуги):
- Доставка заказа (Услуга)
- Контекстная реклама в системе Яндекс.Директ (Услуга)
| № | Поле 1С OData | Тип 1С | Пример значения 1С | → | Поле PIM | Тип PIM | Пример PIM | Обработка | Обязательное |
|---|---|---|---|---|---|---|---|---|---|
| ИДЕНТИФИКАТОРЫ | |||||||||
| 1 | Ref_Key |
UUID | b12e7ca3-29cb-11ef-8279-00155d029d48 |
→ | ref_key_1c |
varchar(36) | b12e7ca3-29cb-11ef-8279-00155d029d48 |
Прямое | ✅ |
| 2 | Code |
String(11) | НФ-00000556 |
→ | code_1c |
varchar(11) | НФ-00000556 |
Прямое | ✅ |
| 3 | Артикул |
String(50) | MA0509_Red_x03 |
→ | article |
varchar(50) PK | MA0509_Red_x03 |
Прямое | ✅ |
| НАИМЕНОВАНИЯ | |||||||||
| 4 | Description |
String(100) | Дым 30 сек 115 мм MA0509 Smoking fountain Red |
→ | name_short |
varchar(150) | Дым 30 сек 115 мм MA0509 |
Прямое | ✅ |
| 5 | НаименованиеПолное |
String(1000) | Дым 30 сек 115 мм MA0509 Smoking fountain Red - Красный 1,75" НАБОР 3 шт |
→ | name |
varchar(1000) | Дым 30 сек 115 мм MA0509 Smoking fountain Red - Красный 1,75" НАБОР 3 шт |
Прямое | ✅ |
| ПРОЧИЕ | |||||||||
| 6 | Штрихкод |
String(13) | 4607101130001 |
→ | barcode |
varchar(13) | 4607101130001 |
Прямое | ❌ |
| 7 | Вес |
Number(10,3) кг | 0.16 |
→ | weight_kg |
numeric(10,3) | 0.160 |
Прямое (в кг) | ❌ |
| 8 | Высота |
Number(10,2) мм | 115 |
→ | height_mm |
integer | 115 |
Прямое | ❌ |
| 9 | Ширина |
Number(10,2) мм | 50 |
→ | width_mm |
integer | 50 |
Прямое | ❌ |
| 10 | Длина |
Number(10,2) мм | 50 |
→ | length_mm |
integer | 50 |
Прямое | ❌ |
| КАТЕГОРИЗАЦИЯ | |||||||||
| 11 | Parent_Key |
UUID | 0699197f-e960-11ed-919d-3cecefa69fd9 |
→ | category |
varchar(100) | Батареи салютов |
Из справочника | ✅ |
| 12 | КатегорияНоменклатуры_Key |
UUID | 9c4aafaa-e5ae-11ed-919d-3cecefa69fd9 |
→ | product_type |
varchar(50) | Фейерверки |
Из справочника | ✅ |
| 13 | ЕдиницаИзмерения_Key |
UUID | a43c9f4d-e951-11ed-919d-3cecefa69fd9 |
→ | (не сохраняем) | - | - | Всегда "шт" | - |
| 14 | ЭтоНабор |
Boolean | true / false |
→ | is_bundle |
boolean | true |
Прямое | ❌ |
Только для товаров где КатегорияНоменклатуры_Key = 9c4aafaa-e5ae-11ed-919d-3cecefa69fd9 ("Фейерверки")
| № | Реквизит 1С | GUID 1С | Тип 1С | Пример 1С | → | Поле PIM | Тип PIM | Пример PIM | Обработка | Обязательное |
|---|---|---|---|---|---|---|---|---|---|---|
| БРЕНД | ||||||||||
| 15 | Бренд |
b86639de-7d0c-11ee-919d-3cecefa69fd9 |
String(100) | Maxsem |
→ | brand |
varchar(100) | Maxsem |
Прямое | ✅ |
| КАЛИБР | ||||||||||
| 16 | Калибры |
9c4aafaf-e5ae-11ed-919d-3cecefa69fd9 |
String(50) | 1,75" или 20-30 мм |
→ | calibers_text |
varchar(50) | 1,75" |
Прямое (как в прайсе) | ⚠️ |
| 17 | Калибр макс цифра |
7c85ff2d-6890-11ee-919d-3cecefa69fd9 |
Number(5,2) | 1.75 |
→ | caliber_inch |
numeric(5,2) | 1.75 |
Прямое (дюймы) | ⚠️ |
| 17a | (вычисляемое) | - | - | - | → | caliber_mm |
numeric(6,2) | 44.45 |
caliber_inch × 25.4 |
❌ |
| 18 | (извлекаем) | - | - | 20/25/30 |
→ | calibers |
jsonb | ["20","25","30"] |
Парсинг из calibers_text | ❌ |
| ЗАЛПЫ И ЭФФЕКТЫ | ||||||||||
| 19 | Кол-во выстрелов |
9c4aafd8-e5ae-11ed-919d-3cecefa69fd9 |
Integer | 25 |
→ | shots_count |
integer | 25 |
Прямое | ⚠️ |
| 20 | Количество эффектов |
a7b59bb8-6890-11ee-919d-3cecefa69fd9 |
Integer | 5 |
→ | effects_count |
integer | 5 |
Прямое | ❌ |
| 21 | Спецэффекты |
19b43d79-7d77-11ee-919d-3cecefa69fd9 |
Text | Пион, хризантема, кометы |
→ | effects |
text | Пион, хризантема, кометы |
Прямое | ❌ |
| ВРЕМЯ И ВЫСОТА | ||||||||||
| 22 | Время работы |
9c4aafe2-e5ae-11ed-919d-3cecefa69fd9 |
Integer сек | 30 |
→ | duration_sec |
integer | 30 |
Прямое (секунды) | ❌ |
| 23 | Высота разрыва |
9c4aafe3-e5ae-11ed-919d-3cecefa69fd9 |
Integer м | 25 |
→ | height_mm |
integer | 25000 |
значение × 1000 |
❌ |
| ТИП | ||||||||||
| 24 | Вид фейерверка |
9c4aafe4-e5ae-11ed-919d-3cecefa69fd9 |
String(50) | Батарея салютов |
→ | salute_type |
varchar(50) | Батарея салютов |
Прямое | ✅ |
| МЕДИА | ||||||||||
| 25 | Файл изображения |
1a8a2229-8fe3-11ee-919d-3cecefa69fd9 |
String(500) | https://disk.yandex.ru/i/xxx |
→ | photo_url |
text | https://disk.yandex.ru/i/xxx |
Прямое | ❌ |
| 26 | Видео Rutube |
df5d5f35-acf5-11f0-ba8b-1c98ec2a5329 |
String(200) | https://rutube.ru/video/xxx |
→ | video_rutube |
varchar(200) | https://rutube.ru/video/xxx |
Прямое | ❌ |
| 27 | Видео Youtube |
4ff1d78c-6eef-11ee-919d-3cecefa69fd9 |
String(200) | https://youtube.com/watch?v=xxx |
→ | video_youtube |
varchar(200) | https://youtube.com/watch?v=xxx |
Прямое | ❌ |
| УПАКОВКА | ||||||||||
| 28 | штук в упаковке |
be4a9332-6895-11ee-919d-3cecefa69fd9 |
Integer | 6 |
→ | pack_qty |
integer | 6 |
Прямое | ❌ |
| 29 | Фасовка текст |
4e8da965-836a-11ee-919d-3cecefa69fd9 |
String(100) | 6 шт/уп, 12 уп/кор |
→ | packing |
varchar(100) | 6 шт/уп, 12 уп/кор |
Прямое | ❌ |
| ДОСТУПНОСТЬ | ||||||||||
| 30 | наличие |
12e08fe1-9013-11ee-919d-3cecefa69fd9 |
Boolean | true / false |
→ | is_available |
boolean | true |
Прямое | ❌ |
| ОПИСАНИЕ (извлекается из названия или добавляется вручную) | ||||||||||
| 31 | (генерируется) | - | - | - | → | description |
text | Дымовое изделие красного цвета... |
Из name или AI | ❌ |
| GUID | Название группы |
|---|---|
0699197f-e960-11ed-919d-3cecefa69fd9 |
Батареи салютов |
e5d73639-68a0-11ee-919d-3cecefa69fd9 |
Дневные фейерверки |
12e3c580-e960-11ed-919d-3cecefa69fd9 |
Катюши |
5cb9ea4d-68a0-11ee-919d-3cecefa69fd9 |
Летающие фейерверки |
414d84c0-e957-11ed-919d-3cecefa69fd9 |
Наземные фейерверки |
414d8518-e957-11ed-919d-3cecefa69fd9 |
Петарды |
414d8cba-e957-11ed-919d-3cecefa69fd9 |
Ракеты |
414d8f60-e957-11ed-919d-3cecefa69fd9 |
Римские свечи |
185b58c6-e960-11ed-919d-3cecefa69fd9 |
Свечи бенгальские огни |
62b726dc-68a0-11ee-919d-3cecefa69fd9 |
Стробоскопы |
23780078-6efc-11ee-919d-3cecefa69fd9 |
Товары для карнавала |
2dc1f600-6efc-11ee-919d-3cecefa69fd9 |
Тортовые свечи праздничные |
1916d79e-e960-11ed-919d-3cecefa69fd9 |
Тортовые свечи фейерверки |
e40da3a0-78c6-11ee-919d-3cecefa69fd9 |
Файеры, фальшфееры |
02c571af-811d-11ee-919d-3cecefa69fd9 |
Фейерверк + фонтан |
414d85a3-e957-11ed-919d-3cecefa69fd9 |
Фестивальные шары |
62b720db-68a0-11ee-919d-3cecefa69fd9 |
Фонтаны пиротехнические |
04fd1a14-68a1-11ee-919d-3cecefa69fd9 |
Хлопушки пиротехнические |
1a524796-e960-11ed-919d-3cecefa69fd9 |
Хлопушки пневматические |
1aee671d-e960-11ed-919d-3cecefa69fd9 |
Цветной дым |
| GUID | Название | Описание |
|---|---|---|
9c4aafaa-e5ae-11ed-919d-3cecefa69fd9 |
Фейерверки | Все пиротехнические изделия |
| (другие категории) | Прочие товары | Не пиротехника |
caliber_inch = Decimal(str(record['Калибр макс цифра'])) # 1.75
caliber_mm = caliber_inch * Decimal('25.4') # 44.45
Стандартные значения:
| Дюймы | Миллиметры |
|-------|------------|
| 0.8" | 20.32 мм |
| 1.0" | 25.4 мм |
| 1.2" | 30.48 мм |
| 1.75" | 44.45 мм |
| 2.0" | 50.8 мм |
calibers_text = "20-30 мм" # или "0.8\"-1.2\""
# Парсинг диапазона в мм
if '-' in calibers_text and 'мм' in calibers_text:
parts = calibers_text.replace('мм', '').split('-')
calibers = [p.strip() for p in parts] # ["20", "30"]
# Парсинг диапазона в дюймах
elif '-' in calibers_text and '"' in calibers_text:
parts = calibers_text.replace('"', '').split('-')
# Конвертируем в мм
calibers = [str(round(float(p) * 25.4)) for p in parts]
height_m = 25 # из 1С
height_mm = height_m * 1000 # 25000
PARENT_TO_TYPE = {
'0699197f-e960-11ed-919d-3cecefa69fd9': 'Батарея салютов',
'62b720db-68a0-11ee-919d-3cecefa69fd9': 'Фонтан',
'414d8f60-e957-11ed-919d-3cecefa69fd9': 'Римская свеча',
'414d8518-e957-11ed-919d-3cecefa69fd9': 'Петарда',
'414d8cba-e957-11ed-919d-3cecefa69fd9': 'Ракета',
'185b58c6-e960-11ed-919d-3cecefa69fd9': 'Бенгальские огни',
'1aee671d-e960-11ed-919d-3cecefa69fd9': 'Дым',
}
salute_type = PARENT_TO_TYPE.get(parent_key, 'Неизвестно')
{ВидТовара} {Имя}
Примеры:
- Батарея салютов Звездопад
- Фонтан Вулкан
- Римская свеча Комета
- Петарда Корсар-1
{ВидТовара} {Характеристики} {Имя} {Бренд}
Примеры:
- Батарея салютов 25 залпов 0.8" Звездопад Народный Фейерверк
- Дневной салют 49 залпов 1.0" Бабочка Адмирал JF-Pyro
- Фонтан высота 3м время 40сек Вулкан Салют России
- Бенгальские огни 300мм цветные Искры радости Maxsem
import re
def extract_commercial_name(full_name: str) -> str:
"""
Извлекает коммерческое название из полного наименования
Примеры:
"Батарея салютов 25 залпов 0.8" Звездопад Народный Фейерверк" → "Звездопад"
"Дым 30 сек 115 мм MA0509 Smoking fountain Red - Красный" → "Smoking fountain Red"
"""
# Паттерн для батарей
match = re.search(r'(?:Батарея салютов|Салют)\s+\d+\s+залпов?\s+[\d\.]+"\s+([А-Яа-яA-Za-z0-9 ]+)', full_name)
if match:
return match.group(1).split()[0] # Первое слово после характеристик
# Паттерн для фонтанов
match = re.search(r'Фонтан\s+(?:высота\s+\d+м\s+)?(?:время\s+\d+сек\s+)?([А-Яа-яA-Za-z0-9 ]+)', full_name)
if match:
return match.group(1).split()[0]
# Для товаров без паттерна - возвращаем как есть
return full_name
Данные из 1С:
{
"Ref_Key": "b12e7ca3-29cb-11ef-8279-00155d029d48",
"Code": "НФ-00000556",
"Артикул": "HF7302",
"Description": "Батарея салютов Новогодняя забава",
"НаименованиеПолное": "Батарея салютов 25 залпов 0.8\" Новогодняя забава Народный Фейерверк",
"Вес": 1.25,
"Высота": 200,
"Ширина": 150,
"Длина": 250,
"Parent_Key": "0699197f-e960-11ed-919d-3cecefa69fd9",
"КатегорияНоменклатуры_Key": "9c4aafaa-e5ae-11ed-919d-3cecefa69fd9",
"ЭтоНабор": false,
"ДополнительныеРеквизиты": [
{"Свойство": "b86639de-7d0c-11ee-919d-3cecefa69fd9", "Значение": "Народный Фейерверк"},
{"Свойство": "7c85ff2d-6890-11ee-919d-3cecefa69fd9", "Значение": 0.8},
{"Свойство": "9c4aafaf-e5ae-11ed-919d-3cecefa69fd9", "Значение": "0.8\""},
{"Свойство": "9c4aafd8-e5ae-11ed-919d-3cecefa69fd9", "Значение": 25},
{"Свойство": "9c4aafe3-e5ae-11ed-919d-3cecefa69fd9", "Значение": 30},
{"Свойство": "9c4aafe4-e5ae-11ed-919d-3cecefa69fd9", "Значение": "Батарея салютов"}
]
}
Результат в PIM:
{
"pim_products": {
"article": "HF7302",
"ref_key_1c": "b12e7ca3-29cb-11ef-8279-00155d029d48",
"code_1c": "НФ-00000556",
"name": "Батарея салютов 25 залпов 0.8\" Новогодняя забава Народный Фейерверк",
"name_short": "Батарея салютов Новогодняя забава",
"brand": "Народный Фейерверк",
"category": "Батареи салютов",
"product_type": "Фейерверки",
"weight_kg": 1.25,
"height_mm": 200,
"width_mm": 150,
"length_mm": 250,
"is_bundle": false
},
"pim_feierverki": {
"article": "HF7302",
"caliber_inch": 0.8,
"caliber_mm": 20.32,
"calibers_text": "0.8\"",
"calibers": null,
"shots_count": 25,
"height_mm": 30000,
"salute_type": "Батарея салютов"
}
}
Данные из 1С:
{
"Ref_Key": "a12e7ca3-29cb-11ef-8279-00155d029d48",
"Code": "НФ-00000557",
"Артикул": "MA0509_Red_x03",
"Description": "Дым 30 сек 115 мм MA0509",
"НаименованиеПолное": "Дым 30 сек 115 мм MA0509 Smoking fountain Red - Красный 1,75\" НАБОР 3 шт",
"Вес": 0.16,
"Высота": 115,
"Parent_Key": "1aee671d-e960-11ed-919d-3cecefa69fd9",
"КатегорияНоменклатуры_Key": "9c4aafaa-e5ae-11ed-919d-3cecefa69fd9",
"ЭтоНабор": true,
"ДополнительныеРеквизиты": [
{"Свойство": "b86639de-7d0c-11ee-919d-3cecefa69fd9", "Значение": "Maxsem"},
{"Свойство": "7c85ff2d-6890-11ee-919d-3cecefa69fd9", "Значение": 1.75},
{"Свойство": "9c4aafe2-e5ae-11ed-919d-3cecefa69fd9", "Значение": 30},
{"Свойство": "be4a9332-6895-11ee-919d-3cecefa69fd9", "Значение": 3}
]
}
Результат в PIM:
{
"pim_products": {
"article": "MA0509_Red_x03",
"ref_key_1c": "a12e7ca3-29cb-11ef-8279-00155d029d48",
"code_1c": "НФ-00000557",
"name": "Дым 30 сек 115 мм MA0509 Smoking fountain Red - Красный 1,75\" НАБОР 3 шт",
"name_short": "Дым 30 сек 115 мм MA0509",
"brand": "Maxsem",
"category": "Цветной дым",
"product_type": "Фейерверки",
"weight_kg": 0.16,
"height_mm": 115,
"is_bundle": true
},
"pim_feierverki": {
"article": "MA0509_Red_x03",
"caliber_inch": 1.75,
"caliber_mm": 44.45,
"duration_sec": 30,
"salute_type": "Дым",
"pack_qty": 3
}
}
async def fetch_from_1c_odata(
base_url: str = "http://1c-server/odata/standard.odata",
filter: str = None
):
"""
Получает номенклатуру из 1С через OData
URL: /Catalog_Номенклатура
Filter: КатегорияНоменклатуры_Key eq guid'9c4aafaa-e5ae-11ed-919d-3cecefa69fd9'
"""
url = f"{base_url}/Catalog_Номенклатуры"
params = {
"$format": "json",
"$filter": "КатегорияНоменклатуры_Key eq guid'9c4aafaa-e5ae-11ed-919d-3cecefa69fd9'"
}
response = await client.get(url, params=params)
return response.json()['value']
async def import_to_pim_products(record: dict):
"""Импорт базовых данных"""
# Получаем имя категории из справочника
category_name = get_category_name(record['Parent_Key'])
product = PimProduct(
article=record['Артикул'],
ref_key_1c=record['Ref_Key'],
code_1c=record['Code'],
name=record['НаименованиеПолное'],
name_short=record['Description'],
brand=get_dop_rekvizit(record, 'b86639de-7d0c-11ee-919d-3cecefa69fd9'),
category=category_name,
product_type='Фейерверки',
weight_kg=record.get('Вес'),
height_mm=record.get('Высота'),
width_mm=record.get('Ширина'),
length_mm=record.get('Длина'),
is_bundle=record.get('ЭтоНабор', False)
)
db.add(product)
await db.commit()
async def import_to_pim_feierverki(record: dict):
"""Импорт характеристик пиротехники"""
caliber_inch = get_dop_rekvizit_decimal(record, '7c85ff2d-6890-11ee-919d-3cecefa69fd9')
caliber_mm = caliber_inch * Decimal('25.4') if caliber_inch else None
feierverki = PimFeierverki(
article=record['Артикул'],
caliber_inch=caliber_inch,
caliber_mm=caliber_mm,
calibers_text=get_dop_rekvizit(record, '9c4aafaf-e5ae-11ed-919d-3cecefa69fd9'),
shots_count=get_dop_rekvizit_int(record, '9c4aafd8-e5ae-11ed-919d-3cecefa69fd9'),
effects_count=get_dop_rekvizit_int(record, 'a7b59bb8-6890-11ee-919d-3cecefa69fd9'),
effects=get_dop_rekvizit(record, '19b43d79-7d77-11ee-919d-3cecefa69fd9'),
duration_sec=get_dop_rekvizit_int(record, '9c4aafe2-e5ae-11ed-919d-3cecefa69fd9'),
height_mm=get_dop_rekvizit_int(record, '9c4aafe3-e5ae-11ed-919d-3cecefa69fd9') * 1000,
salute_type=get_dop_rekvizit(record, '9c4aafe4-e5ae-11ed-919d-3cecefa69fd9'),
photo_url=get_dop_rekvizit(record, '1a8a2229-8fe3-11ee-919d-3cecefa69fd9'),
video_rutube=get_dop_rekvizit(record, 'df5d5f35-acf5-11f0-ba8b-1c98ec2a5329'),
video_youtube=get_dop_rekvizit(record, '4ff1d78c-6eef-11ee-919d-3cecefa69fd9'),
pack_qty=get_dop_rekvizit_int(record, 'be4a9332-6895-11ee-919d-3cecefa69fd9'),
packing=get_dop_rekvizit(record, '4e8da965-836a-11ee-919d-3cecefa69fd9'),
is_available=get_dop_rekvizit_bool(record, '12e08fe1-9013-11ee-919d-3cecefa69fd9')
)
db.add(feierverki)
await db.commit()
✅ article, ref_key_1c, code_1c, name, name_short, brand, category, product_type, weight_kg, height_mm, width_mm, length_mm, is_bundle, barcode
✅ caliber_inch, caliber_mm, calibers_text, shots_count, effects_count, effects, duration_sec, height_mm, salute_type, photo_url, video_rutube, video_youtube, pack_qty, packing, is_available, calibers (JSON)
Версия: 2.0.0
Дата: 2025-12-23
Статус: ФИНАЛЬНАЯ ВЕРСИЯ