FSP 1.0

FSP / Модули / quote

stable версия 1.0

FSP Quote 1.0

Запрос сметы (операции + объём) и ответ: подошедшие операторы, смета, применённые допущения, коды непокрытия.

Зависит от: core, pricing, capacity. Объявить этот модуль в манифесте без них нельзя (PROFILE-002).

Единый контракт: запрос на фулфилмент и ответ со сметой. Язык услуг берётся из core, движок цены из pricing, свободные мощности из capacity.

API: api/quote.openapi.yamlPOST /quote и POST /quote/free-form.

Реестры

Реестр Что внутри
quote_model Сущности quote_request и quote_response
unmet_reasons Закрытый реестр 21 кода непокрытия с влиянием и подсказкой оператору
rules QUOTE-*

Запрос описывается работой, а не площадью

Реальная заявка — это перечень операций и объём, а не «сколько мне нужно квадратных метров». Поэтому требовать storage_need запрещено (QUOTE-001): если он не задан, площадь выводит принимающая сторона из demand — отгрузок в день, дней запаса, объёма единицы товара.

Формулы вывода стандартом не нормируются. Коэффициент «сколько м³ помещается на м²» зависит от высоты стеллажей, а «дни запаса» считают по-разному. Вместо этого действует QUOTE-002: каждая применённая величина обязана быть перечислена в quote_response.assumptions кодом и значением.

"assumptions": [
  { "code": "turnover_basis", "value": "stock_days" },
  { "code": "volume_per_m2", "value": 1.8 },
  { "code": "days_per_month", "value": 30 }
]

Непокрытое возвращается кодами

unmet заполняется только кодами закрытого реестра, свободный текст допускается лишь в detail рядом с кодом (QUOTE-003). У каждого кода есть влияние:

  • exclude — оператор уходит из выдачи (не берёт категорию, нет нужного режима хранения, объём ниже минимального);
  • partial — остаётся с fit: partial (площади в обрез, дата готовности позже, часть услуг без ставки).

Оператор с непустым unmet никогда не имеет fit: full (QUOTE-004).

В реестре у каждого кода есть колонка «Что делать оператору»: insufficient_free_area → обновите свободную площадь, pricing_level_insufficient → опишите условия и поднимитесь до L2.

Пустая смета не равна нулю: если ставки нет или она требует согласования, возвращается service_not_priced или manual_quote_required, а не сумма 0 (QUOTE-005).

Свободная форма

POST /quote/free-form принимает текст («нужно хранить 50 паллет одежды, отгрузки на WB из Москвы, маркировка ЧЗ, старт в августе»), разбирает его в тот же quote_request и выполняет обычный расчёт. Ответ обязан вернуть разобранную структуру и перечень полей, которые не удалось определить однозначно (QUOTE-007) — иначе заявитель не может отличить «так и было в запросе» от «мы додумали».

Разбор текста в код услуги — задача реализации. Стандарт фиксирует только то, что результат обязан быть тем же quote_request, что и у структурированного входа.

Нормативные правила

Обязательны для соответствия модулю. Префиксы объявлены в манифесте: QUOTE-*.

Схема

JSON Schema 2020-12: /1.0/quote/schema.json. Определения: pricing_level, unmet_code, unmet, assumption, operation_request, quote_request, quote_response.

Манифест модуля

{
  "module": "quote",
  "title": "FSP Quote",
  "version": "1.0",
  "status": "stable",
  "summary": "Запрос сметы (операции + объём) и ответ: подошедшие операторы, смета, применённые допущения, коды непокрытия.",
  "depends": [
    "core",
    "pricing",
    "capacity"
  ],
  "registries": [
    "quote_model",
    "unmet_reasons",
    "rules"
  ],
  "rule_prefixes": [
    "QUOTE"
  ],
  "schema": "schema.json",
  "api": "../../api/quote.openapi.yaml"
}