projects/org/pirotehnika/app/pim/1C_PIM_MASTER_MAPPING.md

МАСТЕР-ТАБЛИЦА: Маппинг полей 1С ↔ PIM для категории ФЕЙЕРВЕРКИ

Дата: 2025-12-25
Версия: 3.0.0 (+ правила фильтрации)
Источники: 1C_PIM_FIELDS_FULL.md, 1C_FIELD_STRUCTURE.md, реальные данные из БД


⚠️ КРИТИЧЕСКОЕ: ПРАВИЛА ФИЛЬТРАЦИИ 1С

В 1С три типа номенклатуры:

  1. ТОВАРЫ (ТипНоменклатуры = "Запас")
    - Обычные товары (ЭтоНабор = false) → ✅ ГРУЗИМ
    - Наборы (ЭтоНабор = true) → ❌ ИГНОРИРУЕМ

  2. УСЛУГИ (ТипНоменклатуры = "Услуга") → ❌ ИГНОРИРУЕМ

  3. Прочее (ТипНоменклатуры = None/null) → ❌ ИГНОРИРУЕМ

Статистика (из 500 товаров 1С):

Тип Количество Наборов Грузим
Запас 469 (93%) 103 (22%) 366 (73%)
Услуга 10 (2%) 0 0 ❌
None 21 (4%) 0 0 ❌

OData фильтр:

$filter=ТипНоменклатуры eq 'Запас' and ЭтоНабор eq false

Python фильтр:

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)

❌ ИГНОРИРУЕМ (Услуги):
- Доставка заказа (Услуга)
- Контекстная реклама в системе Яндекс.Директ (Услуга)


ОСНОВНЫЕ ПОЛЯ (14 полей)

Поле 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 Прямое

ДОПОЛНИТЕЛЬНЫЕ РЕКВИЗИТЫ ПИРОТЕХНИКИ (28 полей)

Только для товаров где КатегорияНоменклатуры_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

СПРАВОЧНИК: Parent_Key (Группы товаров)

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 Цветной дым

СПРАВОЧНИК: КатегорияНоменклатуры_Key

GUID Название Описание
9c4aafaa-e5ae-11ed-919d-3cecefa69fd9 Фейерверки Все пиротехнические изделия
(другие категории) Прочие товары Не пиротехника

ФОРМУЛЫ И ПРАВИЛА ОБРАБОТКИ

1. Калибр (дюймы → мм)

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 мм |

2. Калибры (текст → JSON массив)

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]

3. Высота (метры → мм)

height_m = 25  # из 1С
height_mm = height_m * 1000  # 25000

4. Определение salute_type из Parent_Key

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, 'Неизвестно')

ШАБЛОНЫ НАИМЕНОВАНИЙ

Формула: Description (краткое название)

{ВидТовара} {Имя}

Примеры:
- Батарея салютов Звездопад
- Фонтан Вулкан
- Римская свеча Комета
- Петарда Корсар-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: Батарея салютов

Данные из 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": "Батарея салютов"
  }
}

Пример 2: Дымовое изделие (Maxsem)

Данные из 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
  }
}

АЛГОРИТМ ИМПОРТА

Шаг 1: Получение данных из 1С OData API

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']

Шаг 2: Импорт в pim_products

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()

Шаг 3: Импорт в pim_feierverki

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()

РЕЗЮМЕ

Импортируются в pim_products (14 полей):

✅ article, ref_key_1c, code_1c, name, name_short, brand, category, product_type, weight_kg, height_mm, width_mm, length_mm, is_bundle, barcode

Импортируются в pim_feierverki (16 полей):

✅ 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
Статус: ФИНАЛЬНАЯ ВЕРСИЯ