{
 "$schema": "https://json-schema.org/draft/2020-12/schema",
 "$id": "https://geooptimization.ru/mashinochitaemoe-kp/kp-1.0.schema.json",
 "title": "Машиночитаемое коммерческое предложение (КП), версия 1.0",
 "description": "Ответ поставщика на запрос цены в структурированном виде, который ИИ-агент покупателя может без ручного переноса положить в таблицу сравнения. Отправляется вместе с обычным письмом и PDF, а не вместо них. Открытая схема, CC BY 4.0, https://geooptimization.ru/mashinochitaemoe-kp/. Поля сверх схемы допускаются.",
 "type": "object",
 "required": ["schema_version", "quote_id", "issued", "valid_until", "supplier", "currency", "vat", "items", "total", "payment_terms", "delivery_terms"],
 "properties": {
  "schema": {"type": "string", "format": "uri", "description": "Адрес этой схемы"},
  "schema_version": {"type": "string", "const": "1.0"},
  "quote_id": {"type": "string", "description": "Номер КП у поставщика"},
  "rfq_id": {"type": "string", "description": "Номер запроса, на который дан ответ"},
  "issued": {"type": "string", "format": "date-time", "description": "Когда выдано, ISO 8601 с часовым поясом"},
  "valid_until": {"type": "string", "format": "date", "description": "Последний день действия цен"},
  "supplier": {
   "type": "object",
   "required": ["name", "inn"],
   "properties": {
    "name": {"type": "string"},
    "legal_name": {"type": "string"},
    "inn": {"type": "string", "pattern": "^(\\d{10}|\\d{12})$"},
    "kpp": {"type": "string", "pattern": "^\\d{9}$"},
    "ogrn": {"type": "string", "pattern": "^(\\d{13}|\\d{15})$"},
    "email": {"type": "string", "format": "email"},
    "phone": {"type": "string"},
    "site": {"type": "string", "format": "uri"},
    "contact": {"type": "string"}
   }
  },
  "buyer": {
   "type": "object",
   "properties": {
    "name": {"type": "string"},
    "inn": {"type": "string"},
    "contact": {"type": "string"},
    "email": {"type": "string"},
    "phone": {"type": "string"}
   }
  },
  "currency": {"type": "string", "pattern": "^[A-Z]{3}$", "description": "ISO 4217, например RUB"},
  "vat": {
   "type": "object",
   "required": ["included", "rate"],
   "properties": {
    "included": {"type": "boolean", "description": "Цены и суммы указаны с НДС"},
    "rate": {"type": "number", "minimum": 0, "maximum": 100, "description": "Ставка НДС, %; 0 — без НДС"}
   }
  },
  "items": {
   "type": "array",
   "minItems": 1,
   "items": {
    "type": "object",
    "required": ["sku", "name", "qty", "unit", "price", "amount"],
    "properties": {
     "line": {"type": "integer", "minimum": 1},
     "sku": {"type": "string", "description": "Артикул поставщика"},
     "gtin": {"type": "string"},
     "name": {"type": "string"},
     "qty": {"type": "number", "exclusiveMinimum": 0},
     "unit": {"type": "string", "description": "Единица по-русски: шт, м², кг, лист"},
     "unit_code": {"type": "string", "description": "Код единицы UN/CEFACT: H87 — штука, MTK — м², KGM — кг"},
     "price": {"type": "number", "minimum": 0, "description": "Цена за единицу в валюте currency, с НДС, если vat.included"},
     "price_tier": {"type": "string", "description": "Ступень цены, по которой посчитано"},
     "price_tiers": {
      "type": "array",
      "description": "Вся шкала цен по количеству — агент видит, сколько стоит взять больше",
      "items": {
       "type": "object",
       "required": ["min_qty", "price"],
       "properties": {
        "min_qty": {"type": "number"},
        "max_qty": {"type": ["number", "null"]},
        "price": {"type": "number"}
       }
      }
     },
     "amount": {"type": "number", "minimum": 0},
     "vat_amount": {"type": "number", "minimum": 0},
     "availability": {"type": "string", "enum": ["in_stock", "to_order", "out_of_stock"]},
     "lead_time_days": {"type": "integer", "minimum": 0, "description": "Срок изготовления или отгрузки, рабочих дней"},
     "shelf_life_months": {"type": "integer", "minimum": 0},
     "storage": {"type": "string"},
     "included": {"type": "string", "description": "Комплектность"},
     "color": {"type": "string"},
     "documents": {"$ref": "#/$defs/documents"}
    }
   }
  },
  "total": {
   "type": "object",
   "required": ["amount"],
   "properties": {
    "amount": {"type": "number", "minimum": 0},
    "vat_amount": {"type": "number", "minimum": 0},
    "vat_included": {"type": "boolean"}
   }
  },
  "minimum_order": {
   "type": "object",
   "properties": {
    "qty": {"type": "number"},
    "unit": {"type": "string"}
   }
  },
  "availability": {"type": "string", "enum": ["in_stock", "to_order", "out_of_stock"]},
  "lead_time": {
   "type": "object",
   "properties": {
    "days": {"type": "integer", "minimum": 0},
    "text": {"type": "string"}
   }
  },
  "payment_terms": {
   "type": "object",
   "required": ["type"],
   "properties": {
    "type": {"type": "string", "enum": ["prepayment", "deferred", "partial_prepayment", "on_delivery"]},
    "percent": {"type": "number", "minimum": 0, "maximum": 100, "description": "Доля предоплаты, %"},
    "deferral_days": {"type": "integer", "minimum": 0},
    "text": {"type": "string"}
   }
  },
  "delivery_terms": {
   "type": "object",
   "properties": {
    "requested": {"type": "object", "description": "Что выбрал покупатель в запросе"},
    "options": {
     "type": "array",
     "items": {
      "type": "object",
      "required": ["method"],
      "properties": {
       "method": {"type": "string", "enum": ["pickup", "carrier", "supplier_delivery"]},
       "place": {"type": "string"},
       "price": {"type": ["number", "null"], "description": "Стоимость доставки; null — по тарифу перевозчика"},
       "text": {"type": "string"}
      }
     }
    }
   }
  },
  "samples": {"type": "string"},
  "how_to_order": {"type": "string", "description": "Что сделать покупателю, чтобы получить счёт"}
 },
 "$defs": {
  "documents": {
   "type": "array",
   "items": {
    "type": "object",
    "required": ["type", "url"],
    "properties": {
     "type": {"type": "string", "description": "technical_data, certificates, product_data, safety_data_sheet и т. п."},
     "url": {"type": "string", "format": "uri"},
     "number": {"type": "string"},
     "valid_until": {"type": "string", "format": "date"}
    }
   }
  }
 },
 "additionalProperties": true
}
