# CARGO.RUN Логистика > Полная машиночитаемая версия. Источник: https://cargorun-ru.github.io/cargo.run-api-docs/products/cargorun-logistics/ --- Source: products/cargorun-logistics/index.md

CARGO.RUN Logo

# CARGO.RUN Logistics — Документация по API Добро пожаловать в документацию по интеграции с **CARGO.RUN Логистика**. Здесь собраны: - правила работы с API (форматы данных, статусы, обязательные поля), - сценарии интеграции с учетными системами (1С и др.), - справочник методов API (по доменам: заявки, заказы, справочники, ЭТРН и пр.). --- ## 1. С чего начать 1. Прочитать общие принципы и архитектуру интеграции: [Введение](./introduction.md) 2. Ознакомиться с базовыми понятиями и терминами: [Глоссарий](./glossary.md) 3. Посмотреть, какие форматы данных используются во всех методах: [Форматы данных](./formats.md) 4. Понять, какие статусы бывают у заявок, контрагентов, ЭТРН и т.д.: [Статусные модели](./statuses.md) 5. Уточнить минимальные требования к полям при создании сущностей: [Минимальные требования к запросам](./minimal-requirements.md) --- ## 2. Сценарии интеграции Раздел для аналитиков и интеграторов, отвечающих за поток данных между CARGO.RUN и учетной системой (1С, ERP и др.): - Общий обзор интеграции [Общий обзор](./integration/overview.md) - Сценарий: заявка создается в CARGO.RUN [CARGO.RUN → учетная система](./integration/scenario-cr-to-external.md) - Сценарий: заявка создается во внешней системе [Учетная система → CARGO.RUN](./integration/scenario-external-to-cr.md) - Синхронизация справочников и статусов [Синхронизация данных](./integration/sync.md) - Асинхронная синхронизация заявок [Синхронизация заявок API 2.0](./integration/async-sync-v2.md) - Примеры интеграции с 1С [Примеры для 1С](./integration/examples-1c.md) --- ## 3. API Reference Технический справочник методов API, сгруппированных по доменам. Раздел для разработчиков, которые пишут интеграцию. - Общие принципы работы API, заголовки, ошибки [Обзор API](./api/overview.md) - Авторизация и работа с токенами [Auth API](./api/auth.md) - Справочники [API справочников](./api/directories.md) - Контрагенты, договоры и адреса [Контрагенты API](./api/counterparties.md) - Пользовательские справочники [Пользовательские справочники API](./api/custom-catalogs.md) - Заявки и рейсы [Bids API](./api/bids.md) - Асинхронные задания API 2.0 [Очередь API 2.0](./api/async-tasks.md) - Заказы / распределительные заявки [Distribution bids API](./api/distribution-bids.md) - Транзакции заправок [Refueling Transactions API](./api/refueling-transactions.md) - Трекеры и привязка к ТС [Trackers API](./api/trackers.md) - Электронные транспортные накладные (ЭТРН) [ЭТРН API](./api/etrn.md) --- ## 4. Для LLM и ИИ-агентов Для подключения документации к ИИ-ассистенту, базе знаний или агенту используйте [машиночитаемые материалы и правила безопасной работы](./for-ai.md). --- Source: products/cargorun-logistics/introduction.md # Введение Этот документ описывает правила интеграции с системой **CARGO.RUN Логистика** через REST API. API предназначен для обмена данными между CARGO.RUN и внешними учётными системами (1С, ERP, WMS, мобильными приложениями, внешними сервисами и т.д.). Документация разделена на три большие части: 1. общие правила и форматы данных; 2. сценарии интеграции; 3. API Reference (справочник методов). --- ## 1. Назначение API CARGO.RUN API предоставляет доступ к данным и функциям системы: - создание и редактирование заявок и заказов, - работа с маршрутами, - синхронизация справочников (контрагенты, водители, техника, организации), - управление статусами заявок, титулов и ЭТРН, - получение событий и информации о ходе перевозок, - работа с данными сотрудников, трекеров и мобильных клиентов. API предназначено для систем: - 1С и её конфигураций, - собственных ERP клиентов, - CRM, - внешних логистических платформ, - сервисов телематики, - приложений мобильных водителей, - корпоративных интеграционных решений. --- ## 2. Архитектура интеграции Архитектурно API CARGO.RUN устроено как REST API: - обмен данными осуществляется по HTTPS; - запросы и ответы передаются в формате JSON UTF-8; - каждый метод соответствует ресурсу или действию; - авторизация выполняется через токен. REST-подход обеспечивает простоту интеграции, предсказуемость и совместимость с клиентскими библиотеками. --- ## 3. Версионирование API стремится сохранять обратную совместимость. Обновления вносятся в соответствии с принципами: - новые поля добавляются без нарушения обратной совместимости; - изменение обязательности полей всегда оговаривается заранее; - разрушительные изменения должны сопровождаться новой версией API и планом миграции. Текущие методы используют пути без номера версии (`/api/...`). Поэтому перед обновлением интеграции проверяйте журнал изменений и согласовывайте разрушительные изменения с владельцем API. --- ## 4. Базовый URL API Фактический адрес среды предоставляется при подключении интеграции. В документации он обозначается как `` и **не включает** суффикс `/api`. Примеры формирования URL: - `GET /api/bids/GetListForExternal` - `POST /api/TruckingBids/Apply` - `POST /api/tasks/queue` --- ## 5. Формат запросов и ответов - Все запросы — JSON. - Успешные ответы обычно передаются в JSON. Ошибки отдельных методов могут быть JSON-объектом или обычным текстом; это указано в описании форматов. - Кодировка — UTF-8. - При необходимости передавать вложенные структуры используются стандартные JSON-объекты и массивы. Во всех примерах документации используется форматирование, совместимое с JSONLint. --- ## 6. Авторизация Доступ к API выполняется через выдачу токена. В интеграции используется схема: Authorization: Bearer Токен выдаётся методом авторизации и имеет срок действия. Обновление токена (refresh) выполняется через соответствующий метод API. Все методы, взаимодействующие с данными клиента, требуют авторизации. --- ## 7. Ограничения и квоты API может вводить ограничения: - лимиты на количество запросов в единицу времени (rate limit), - ограничения на размер запросов, - требования к обязательным полям, - набор допустимых статусов и переходов для сущностей. Эти ограничения фиксируются по мере необходимости в описаниях методов. --- ## 8. Следующие шаги Для дальнейшей работы рекомендуется: 1. Ознакомиться с форматами данных: [Форматы данных](./formats.md) 2. Изучить статусные модели: [Статусы сущностей](./statuses.md) 3. Посмотреть минимальные требования к обязательным полям: [Минимальные требования](./minimal-requirements.md) 4. Перейти к обзору сценариев интеграции: [Сценарии интеграции](./integration/overview.md) 5. Для оперативного обмена изменениями заявок изучить: [Синхронизация заявок API 2.0](./integration/async-sync-v2.md) --- Source: products/cargorun-logistics/minimal-requirements.md # Минимальные требования к данным Этот раздел содержит минимальные обязательные поля, которые необходимы при создании сущностей через API **CARGO.RUN Логистика**. Значения обязательных полей должны присутствовать в запросах, иначе метод вернёт ошибку валидации. Если метод требует дополнительные поля, они указаны в описании соответствующего метода в API Reference. --- # 1. Создание заявки (Bid) Минимальный набор полей зависит от того, создаётся ли заявка полностью в CARGO.RUN или поступает из внешней системы (1С, ERP). | Поле | Тип | Описание | |------|------|----------| | `cargoOwnerDictionaryItemId` | number | Идентификатор заказчика (контрагента). | | `paymentTypeId` | number | Тип оплаты. | | `ndsTypeId` | number | Тип НДС. | | `price` | number | стоимость в рублях (с НДС). | | `driver` | object | Идентификатор водителя. | | `carOption` | object | Идентификатор автомобиля (тягача). | | `trailerOption` | object | Идентификатор полуприцепа. | | `bidPoints` | array | Маршрутные точки (минимум две: погрузка и выгрузка). | Для порожней заявки передайте `isEmptyMileageBid = true`. Текущая валидация также требует технические заполнители, хотя при обработке порожней заявки их значения игнорируются: - `price`: например, `1`; - `cargos`: непустой массив, например `[ { "id": 0, "name": null } ]`; - `paymentTypeId` и `ndsTypeId`: существующие ID из справочников целевой организации. Не придумывайте ID типов оплаты и НДС: получите допустимые значения до запуска интеграции. `cargoOwnerDictionaryItemId` для порожней заявки можно не передавать. Если в организации включён учёт причин порожнего пробега, объект `emptyMileageBid` обязателен. --- # 2. Создание заказа (DistributionBid) | Поле | Тип | Описание | |------|------|----------| | `bidPoints` | array | Маршрутные точки (минимум две: погрузка и выгрузка). | --- # 3. Создание контрагента (Counterparty) | Поле | Тип | Описание | |------|------|----------| | `name` | string | Наименование организации. | | `inn` | string | ИНН. | | `kpp` | string (nullable) | КПП (опционально)| --- # 4. Создание водителя (Driver) | Поле | Тип | Описание | |------|------|----------| | `firstName` | string | Имя водителя. | | `lastName` | string | Фамилия водителя. | | `phoneNumber` | string | Телефон в формате +7XXXXXXXXXX. | --- # 5. Создание автомобиля (Car) | Поле | Тип | Описание | |------|------|----------| | `number` | string | Госномер. | --- # 6. Создание прицепа (Trailer) | Поле | Тип | Описание | |------|------|----------| | `number` | string | Госномер. | --- # 7. Общие правила 1. Все числовые идентификаторы (`xxxId`) должны существовать в справочниках. 2. Поля, указанные как обязательные, не могут быть `null`. 3. Любые дополнительные поля передавайте только если они описаны в соответствующем разделе API Reference. 4. Если описание конкретного метода требует больший набор полей, используйте требования этого метода. --- # 8. Что делать при ошибке валидации Если обязательное поле опущено или не соответствует типу: - сервер возвращает ошибку `400 Bad Request`, - тело ответа может быть обычным текстом или объектом `ValidationApiResult` с полем `errorMessage`; клиент должен уметь сохранить оба варианта. Рекомендуется логировать ошибки на стороне внешней системы. --- Source: products/cargorun-logistics/formats.md # Форматы данных В этом разделе приведены единые форматы данных, используемые во всех методах API **CARGO.RUN Логистика**. --- ## 1. Формат даты и времени ### Основной формат API использует ISO 8601, но трактовка часового пояса зависит от поля. | Категория | Формат | Трактовка | |---|---|---| | Технические метки (`createdAt`, `updatedAt`) и границы OData-фильтров | `YYYY-MM-DDTHH:mm:ssZ` | UTC | | Поля с суффиксом `Offset` | `YYYY-MM-DDTHH:mm:ss±HH:mm` | Момент времени с явным смещением | | `bidPoints[].planEnterDate` и другие явно локальные плановые даты | `YYYY-MM-DDTHH:mm:ss` | Локальное время адреса точки; зона определяется по геоданным точки | Примеры: - `2025-03-12T15:20:00Z` - `2025-03-12T18:20:00+03:00` - `2025-03-12T18:20:00` Исключение: метод получения пробегов `/api/car/getcarmileageforperiod` В нем используется формат без часового пояса: `YYYY-MM-DDTHH:mm:ss` Пример: `/api/car/getcarmileageforperiod?carid=694385&start=2025-10-31T21:00:00&end=2025-11-17T20:59:59` ### Особенности - Для `updatedAt` и других технических меток используйте UTC с `Z`. - Для `planEnterDate` передавайте локальное время точки без `Z`; геозона должна позволять системе определить часовой пояс. - Не добавляйте `Z` к локальной дате: это изменит смысл времени. - Если конкретный метод задаёт другой формат, его описание имеет приоритет. - Доли секунды не используйте, если они не показаны в описании метода. --- ## 2. Числовые идентификаторы (ID) Идентификаторы сущностей передаются **только как целые числа**. Правильно: `12345` Неправильно: `"12345"` Это требование распространяется на: - заявки (`bidId`) - заказы (`orderId`) - контрагентов (`counterpartyId`) - водителей (`driverId`) - автомобили (`carId`) - прицепы (`trailerId`) - организации (`organizationId`) - сотрудников (`employeeId`) - трекеры (`trackerId`) --- ## 3. Телефонные номера Телефон передаётся в международном формате: `+7XXXXXXXXXX` Где: - нет пробелов, - нет дефисов, - код страны обязательно `+7`. Пример: `+79991234567` --- ## 4. Координаты Координаты передаются в виде двух числовых значений: - **latitude** — широта - **longitude** — долгота Формат: ```json { "latitude": 55.7558, "longitude": 37.6176 } ``` Допускается использование вложенных структур (например, GeoJSON), если это описано в конкретном методе API. --- ## 5. Адреса Адрес всегда содержит следующие элементы (если применимо): - строка адреса, - город, - регион, - страна, - геокоординаты, - дополнительные комментарии. Используемые поля зависят от конкретного эндпоинта. --- ## 6. Денежные значения и ставки Стоимость, суммы, ставки и другие денежные поля передаются как числа с фиксированной точностью: - только число, без строк; - без символа валюты; - разделитель — точка. Примеры: - `1000` - `12000.5` - `0.0` --- ## 7. Boolean (логические значения) Используются стандартные JSON-значения: - `true` - `false` Недопустимо: - `"true"` - `"yes"` - `"0"` - `"1"` --- ## 8. Строки Строки передаются в кодировке UTF-8. Допускается использование: - точек, - запятых, - спецсимволов JSON, - Unicode. --- ## 9. Enum-значения Если поле принимает фиксированный набор значений (например, статус заявки или тип прицепа), то: - значение должно быть строго равно одному из элементов перечисления; - формат перечислений приведён в разделе "Статусы". --- ## 10. Списки и массивы Если поле является массивом: ```json [ { ... }, { ... } ] ``` Особенности: - массив должен содержать однородные элементы; - порядок элементов — значимый, если указано в описании метода. --- ## 11. Пагинация Некоторые методы API поддерживают постраничную выборку. Используются два механизма: 1. Классическая пагинация: - `page` — номер страницы (начиная с 1); - `pageSize` — количество элементов на странице. 2. OData-пагинация: - `$top` — максимальное количество записей; - `$skip` — количество записей, которые нужно пропустить. Конкретный механизм для метода указан в описании эндпоинта (API Reference). Если метод принимает `page`/`pageSize`, их значения должны быть целыми числами ≥ 1. Если метод принимает `$top`/`$skip`, рекомендуется использовать их в духе OData: - `$top` — ограничение выборки (например, 100); - `$skip` — смещение (например, 0, 100, 200...). --- ## 12. Параметры OData Ряд методов поддерживает фильтрацию и выборку данных в стиле OData. В описаниях методов могут использоваться следующие параметры: - `$filter` — фильтрация по условиям; - `$select` — выбор отдельных полей; - `$expand` — раскрытие связанных сущностей; - `$orderBy` — сортировка; - `$top` — ограничение числа записей; - `$skip` — пропуск указанного числа записей; - `$count` — запрос количества записей. Конкретный синтаксис выражений в `$filter`, `$orderBy` и правила комбинации параметров следует смотреть в описании соответствующих методов API. --- ## 13. Ошибки API { #api-errors } При ошибках бизнес-валидации API CARGO.RUN возвращает: - HTTP-код 400 (`Bad Request`) - тело ответа в виде обычного текста либо объекта `ValidationApiResult` с полем `errorMessage` — в зависимости от метода Формат ответа: ``` 400 Bad Request <текст ошибки> ``` Пример: ``` 400 Bad Request Driver cannot be deleted because he has active bids ``` Клиенту не следует предполагать единственный `Content-Type` ошибки. Сначала проверьте тип содержимого ответа; если получен JSON, прочитайте `errorMessage`, иначе сохраните текст ответа целиком. --- Source: products/cargorun-logistics/statuses.md # Статусы сущностей В этом разделе собраны статусные модели ключевых сущностей **CARGO.RUN Логистика**. --- # 1. Статусы заявок (BidStatus) Статус отражает текущее состояние заявки. Заявка проходит несколько этапов — от создания до завершения или отмены. | Статус | Код | Описание | |---|---:|---| | `New` | `0` | Заявка создана, находится в статусе черновика. | | `Planned` | `5` | Запланирована к выполнению. | | `Started` | `10` | Начата, запущена в работу. | | `Canceled` | `20` | Заявка отменена. | | `Done` | `30` | Заявка выполнена. | ### Примечания - Статус `New` означает, что заявка еще не запущена логистом. - Статус `Planned` означает, что заявку попытались запустить, но транспортное средство занято другой заявкой и у организации включено планирование. Этот статус назначает система; передавать `Planned` в `SetStatus` вручную нельзя. - При запросе `Started` итоговый статус может оказаться `Planned`. Проверяйте ответ команды и повторно читайте заявку. - Переходы между статусами контролируются бизнес-логикой системы. --- # 2. Статусы оплаты заявки Статусы отражают состояние расчётов по заявке со стороны заказчика. | Статус | Описание | |--------|----------| | `NotPaid` | Оплата по заявке не поступила. | | `PartiallyPaid` | Оплачена частично. | | `Paid` | Полностью оплачена. | | `Expired` | Истёк срок оплаты. | --- # 3. Статусы контрагентов Контрагенты могут иметь различный статус, определяющий возможность работы с ними в системе. | Статус | Описание | |--------|----------| | `None` | Ограничения отсутствуют. | | `Priority` | Приоритетный контрагент. | | `Suspended` | Работа временно приостановлена. | --- # 4. Статусы титулов (ЭТРН) Электронная транспортная накладная (ЭТРН) включает несколько титулов и уровней подписания. Фактические статусы могут отличаться в зависимости от провайдера ЭТРН, поэтому здесь указаны статусы `WaybillTitleStatus`, используемые в API. | Статус | Описание | |--------|----------| | `ReceivedOrCreated` | Титул получен или создан системой. | | `Accepted` | Титул принят водителем или внешней системой. | | `Signed` | Титул подписан. | | `Sent` | Титул передан на отправку в ЭДО. | | `Processed` | Титул обработан провайдером ЭТРН. | | `Declined` | Титул отклонён. | | `Failed` | При обработке титула возникла ошибка. | --- Source: products/cargorun-logistics/glossary.md # Глоссарий Этот раздел содержит основные термины, используемые в документации и API **CARGO.RUN Логистика**. Определения даны в техническом и интеграционном контексте. --- ## Заявка (Bid) Основная сущность планирования перевозки. Содержит: - информацию о контрагенте (заказчике), - параметры груза, - маршрутные точки, - сроки посещения точек, - стоимость и условия оплаты, - транспортное средство, - водитель, - полуприцеп. Заявка является основой для формирования рейса. --- ## Заказ (DistributionBid) Сущность планирования перевозки, аналогичная Заявке, но без указанных транспортного средства, водителя, полуприцепа. Используется для управления нераспределёнными рейсами. --- ## Маршрутная точка (BidPoints) Элемент маршрута, включающий: - адрес, - геокоординаты, - даты, - вид операции (погрузка, выгрузка, пересортировка). Передаются массивом в сущности Заявка (Bid). --- ## Контрагент (Counterparty) Юридическое лицо заказчика перевозки: В API используются поля `counterpartyId` и связанные справочники. --- ## Организация (Organization) Юридическое лицо перевозчика (транспортной компании). --- ## Водитель (Driver) Сотрудник транспортной компании, закреплённый за рейсом. Связан с мобильным приложением CARGO.RUN Driver. --- ## Машина (Car) Транспортное средство — тягач или грузовик. В API содержит: - государственный номер, - модель и марка, - привязанный трекер. --- ## Прицеп / Полуприцеп (Trailer) Дополнительное транспортное средство, используемое с тягачом. В API содержит: - государственный номер, - модель и марка, - тип полуприцепа (тент, изотерм, рефрижератор). Может иметь привязанный трекер. --- ## Трекер (Tracker) Устройство телематики, передающее координаты и технические данные. В API используются методы привязки/отвязки трекеров. --- ## ЭТРН / Электронная транспортная накладная (Waybill) Электронный аналог транспортной накладной, содержащий: - сведения о грузе, - отправителе, - перевозчике, - водителе, - маршруте, - титулы подписей. API позволяет получать статусы ЭТРН, передавать титулы, QR-коды, электронные подписи и изменять статусы титулов. --- ## Сотрудник (Employee) Человек, имеющий доступ в систему или связанный с операционными процессами: - логист, - водитель, - администратор, - бухгалтер. --- ## Статус (Status) Текущее состояние сущности: - заявки, - оплаты, - контрагента, - ЭТРН. Перечни статусов находятся в разделе "[Статусы](./statuses.md)". --- ## Идентификатор (ID) Числовое значение, определяющее сущность в системе. Все идентификаторы передаются как числа (не строки). --- ## Токен (Token) Ключ авторизации в API, выдаётся методом авторизации. Передаётся в заголовке: Authorization: Bearer --- ## Обновление данных (Sync / Synchronization) Регулярное сравнение данных между внешней системой (1С, ERP) и CARGO.RUN: - синхронизация справочников, - обновление заявок, - передача статусов. Описано в разделе "[Синхронизация данных](./integration/sync.md)". --- Source: products/cargorun-logistics/integration/overview.md # Обзор интеграции Этот документ описывает архитектуру и общие принципы интеграции между CARGO.RUN Logistics 2.0 и внешними системами (1С, ERP, WMS, CRM, внешние логистические платформы). Он служит отправной точкой перед изучением сценариев и конкретных методов API. --- # 1. Общая архитектура интеграции Интеграция выполняется через REST API: - обмен осуществляется по HTTPS; - данные передаются в формате JSON; - доступ — по токену авторизации; - для выборок и фильтрации используется система query-параметров (включая OData-стиль). Архитектура интеграции предполагает два возможных источника данных: 1. **CARGO.RUN → внешняя система** данные создаются в CARGO.RUN, внешняя система их получает; 2. **Внешняя система → CARGO.RUN** данные создаются во внешней системе и передаются в CARGO.RUN для планирования и исполнения. Обе модели полностью поддерживаются. --- # 2. Роль CARGO.RUN в потоке данных CARGO.RUN выступает как: - система планирования маршрутов и рейсов, - система контроля исполнения перевозок, - система мониторинга транспорта, - хранилище заявок и статусов, - точка сборки всех событий по перевозке. Внешние системы (ERP, 1С, WMS) обычно отвечают за: - учёт грузов, - расчёты и финансы, - ведение справочников, - учёт заказчиков и заказов. --- # 3. Базовые интеграционные возможности API CARGO.RUN предоставляет возможности: - создавать заявки (Bid) и заказы (DistributionBids); - обновлять статусы заявок и ЭТРН; - передавать маршрутные точки и параметры груза; - синхронизировать справочники: - контрагенты, - водители, - автомобили, - прицепы, - организации; - управлять трекерами (привязка/отвязка); - получать данные о рейсах и событиях выполнения; - получать статусы титулов ЭТРН. Для заявок используются два канала синхронизации: асинхронная очередь API 2.0 для оперативных изменений и `GetListForExternal` для первичной загрузки, статусов, удалений и контрольной сверки. См. [Синхронизация заявок API 2.0](./async-sync-v2.md). --- # 4. Двусторонняя интеграция Интеграция может быть: ## 4.1. Односторонняя Только внешняя система отправляет данные в CARGO.RUN Или наоборот, CARGO.RUN передаёт события во внешнюю систему. ## 4.2. Двусторонняя Обе системы создают данные, обновляют статусы и синхронизируют справочники. Типовой пример двусторонней интеграции: - 1С создаёт заявку; - заявка передаётся в CARGO.RUN; - CARGO.RUN планирует и исполняет рейс; - статусы и результаты выполнения возвращаются в 1С. --- # 5. Основные потоки данных Интеграция покрывает три больших направления: ## 5.1. Справочники Передаются регулярно или по событию: - контрагенты, - водители, - автомобили, - прицепы, - организации. Справочники должны быть синхронизированы до создания заявок. --- ## 5.2. Документы (заявки и заказы) Потоки данных: 1. Внешняя система создаёт заявку/заказ → отправка в CARGO.RUN. 2. CARGO.RUN создаёт заявку → внешняя система получает её через API. 3. Обновление заявок обеими сторонами. 4. Отслеживание статусов заявок. --- ## 5.3. События перевозки CARGO.RUN может передавать или предоставлять: - время прибытия/отъезда, - времена начала/завершения погрузки/выгрузки, - пробег, - задержки, - отклонения от маршрута. Эти данные используются внешними системами для: - аналитики, - расчётов, - контроля SLA, - контроля выполнения перевозок. --- # 6. Потоки статусов Статусы меняются: - со стороны логиста, - со стороны ЭТРН-провайдера, - со стороны исполнителя (водитель), - автоматически (например, при успешном закрытии рейса). Внешние системы могут: - получать статусы через API, - сверять статусы заявок, - сохранять историю изменений у себя. --- # 7. Требования к идентификаторам Для корректной интеграции обязательны: - единые ID справочников; - фиксированные значения статусных моделей; - строгое соответствие названий полей, указанным в API Reference. Дубликаты или ошибки в идентификаторах приводят к конфликтам в данных. --- # 8. Принципы синхронизации данных - Данные синхронизируются по методу «запрос → ответ». - Для выборок поддерживаются фильтры и пагинация. - Для оптимизации могут использоваться: - `updatedAt`, - `$filter` c условиями, - `$top` / `$skip`, - `$orderby`. Синхронизация справочников и заявок описана в посвящённом разделе. --- # 9. Что изучать дальше Для продолжения работы: 1. Сценарий: заявка создаётся в CARGO.RUN → [CARGO.RUN → внешняя система](./scenario-cr-to-external.md) 2. Сценарий: заявка создаётся во внешней системе → [Внешняя система → CARGO.RUN](./scenario-external-to-cr.md) 3. Синхронизация справочников → [Синхронизация данных](./sync.md) --- Source: products/cargorun-logistics/integration/scenario-cr-to-external.md # Сценарий: заявка создаётся в CARGO.RUN Этот сценарий описывает ситуацию, когда заявка (Bid) создаётся и редактируется в системе CARGO.RUN, а внешняя система (1С, ERP или другое приложение) должна получать эти данные, реагировать на изменения и использовать их в собственных процессах. --- # 1. Структура процесса Процесс синхронизации в этом сценарии включает три части: 1. **CARGO.RUN создаёт и изменяет заявки.** 2. **Внешняя система получает новые или обновлённые заявки через API 2.0 и выполняет контрольную сверку.** 3. **Внешняя система сохраняет данные и обновляет статусы у себя.** Внешняя система не должна создавать заявку в CARGO.RUN — только принимать и обрабатывать. --- # 2. Создание заявки в CARGO.RUN Заявки формируются логистами CARGO.RUN: - выбор контрагента, - указание маршрута и точек, - выбор водителя и автомобиля, - назначение стоимости и НДС, - уточнение условий перевозки. После сохранения заявка получает статус `New` или `Planned`, в зависимости от процесса клиента. --- # 3. Получение заявок внешней системой Внешняя система должна периодически выполнять запрос на получение заявок, созданных или обновлённых после определенного момента времени. Типовой алгоритм: 1. Хранить границу последнего полностью обработанного окна синхронизации. 2. Для оперативных изменений использовать `POST/GET /api/tasks/queue` и `ReadConfirmation`; вызывать чтение чаще одного раза в час. 3. Зафиксировать новую верхнюю границу и выполнить первичную или контрольную выборку методом `GET /api/bids/GetListForExternal`. 4. Получать фиксированное окно порциями по 50 записей через `$top=50` и `$skip`. 5. Сортировать результат по `updatedAt,id` и идемпотентно сохранять по `id` и `updatedAt`. 6. Учитывать `isDeleted = true`, а не отбрасывать удалённые заявки. 7. Продвигать границу только после успешной обработки всех страниц; следующее окно начинать с перекрытием для защиты от совпадающих меток времени. Пример запроса: ```http GET /api/bids/GetListForExternal ?$filter=updatedAt ge 2024-01-23T21:00:00Z and updatedAt le 2024-01-25T20:59:59Z and createdAt ge 2022-09-30T21:00:00Z &$top=50 &$orderby=updatedAt,id &$skip=0 ``` Подробный алгоритм приведён в разделах [Синхронизация данных](./sync.md) и [Синхронизация заявок API 2.0](./async-sync-v2.md). --- # 4. Синхронизация справочников перед обработкой заявок Перед обработкой новых заявок внешняя система должна обеспечить актуальность справочников: - контрагенты, - водители, - автомобили, - прицепы, - организации. Если у заявки указан водитель с `driverId`, который отсутствует в внешней базе, система должна либо: - предварительно загрузить справочник водителей, - либо запросить данные этого водителя. --- # 5. Обработка статусов заявок CARGO.RUN управляет статусами заявки (этапы выполнения рейса). Внешняя система должна регулярно получать актуальные статусы через `GET /api/bids/GetListForExternal`. API 2.0 пока не гарантирует доставку каждой смены статуса и удаления, поэтому очередь не заменяет контрольную выборку. Статусы, которые важно отслеживать: - `Planned` - `New` - `Done` - `Canceled` Внешняя система должна обновлять свои записи в соответствии с полученными статусами. --- # 6. Обработка событий перевозки Дополнительно могут передаваться: - фактические времена прибытия, - времена начала/завершения погрузки/выгрузки, - пробег, - задержки, - отклонения от маршрута. Эти данные используются во внешних системах для: - расчёта KPI, - учёта времени, - проверки SLA, - расчётов с перевозчиком. --- # 7. Частота синхронизации Подходы: - **периодически** — каждые 1–5 минут (рекомендуемый вариант), - **по расписанию** — например, каждые 15 минут, - **только вручную** — если система не требует оперативного обновления (не рекомендуется). При высокой нагрузке возможно использовать: - `$top=50` - `$skip` для перехода к следующей странице - `$orderby=updatedAt` - инкрементальные загрузки. Не запрашивайте полный список без ограничения количества записей. Для минимизации нагрузки на сервер списки нужно получать порциями по 50 записей; при тяжелых запросах пользователь может быть временно заблокирован системой. --- # 8. Обработка ошибок и конфликтов Внешняя система должна корректно обрабатывать: - отсутствие данных, - некорректные значения справочников, - недоступность API, - устаревшие timestamp (если синхронизация задержалась). При ошибке желательно: - повторить запрос, - логировать ситуацию, - не терять timestamp последней успешной синхронизации. --- # 9. Что изучать дальше - Сценарий обратного направления: [Внешняя система → CARGO.RUN](./scenario-external-to-cr.md) - Механизмы синхронизации: [Синхронизация данных](./sync.md) - Минимальные требования к данным: [Минимальные требования](../minimal-requirements.md) --- Source: products/cargorun-logistics/integration/scenario-external-to-cr.md # Сценарий: заявка создаётся во внешней системе Этот сценарий описывает процесс, в котором внешняя система (1С, ERP, WMS или другая учетная система) является источником создания заявок. CARGO.RUN принимает данные, формирует рейсы, управляет маршрутом, контролирует исполнение и возвращает статусы во внешнюю систему. --- ## 1. Общая последовательность процесса Процесс включает следующие этапы: 1. Внешняя система формирует заявку или заказ. 2. Перед отправкой заявка проходит проверку данных. 3. Внешняя система отправляет заявку в CARGO.RUN. 4. CARGO.RUN создаёт заявку **в статусе `New` (Черновик)**. 5. Внешняя система **запускает заявку в работу**. 6. CARGO.RUN планирует и исполняет рейс. 7. Внешняя система регулярно получает обновления статусов заявки. --- ## 2. Требования к данным перед отправкой Перед тем как создать заявку в CARGO.RUN, внешняя система должна убедиться: - все необходимые справочники синхронизированы: - контрагенты, - водители, - автомобили, - прицепы, - организации; - обязательные поля заполнены (см. раздел "Минимальные требования"): - `cargoOwnerDictionaryItemId`, - `paymentTypeId`, - `ndsTypeId`, - `carId`, - `driverId`, - `bidPoints`. - значения идентификаторов (`xxxId`) существуют в системе. Если справочники не синхронизированы, система вернет ошибку валидации. --- ## 3. Создание заявки во внешней системе Обычно внешняя система формирует заявку на основе внутренних процессов: - формирование груза, - данные клиента, - информация по отправителю/получателю, - планируемая дата доставки, - параметры перевозки. После формирования заявки данные приводятся к структуре JSON, соответствующей требованиям API CARGO.RUN. --- ## 4. Создание черновика заявки в CARGO.RUN Отправка выполняется запросом: ``` POST /api/TruckingBids/Apply Content-Type: application/json Authorization: Bearer ``` ### Требование к адресу (геокодирование) Для корректности адресов рекомендуется использовать геокодер CARGO.RUN: ``` POST /api/Map/GetAddresses ``` Тело запроса: ```json { "address": "" } ``` Метод возвращает структурированные данные: - координаты, - регион, - город, - район, - улицу и номер дома, - федеральный округ. Рекомендуется всегда использовать результаты геокодера для `bidPoints.geozone`. --- ### Пример создания черновика заявки ```json { "id": 0, "cargoOwnerDictionaryItemId": 10638021, "paymentTypeId": 41, "ndsTypeId": 40, "price": 234000, "cargos": [ { "name": "ТНП", "typeId": 707, "extendedProperties": [] } ], "typeOptions": [ { "entityOptionId": 14655740, "id": 14655282 } ], "bidPoints": [ { "order": 0, "type": "LoadPoint", "planEnterDate": "2021-01-07T04:33:00", "geozone": { "location": { "type": "Point", "coordinates": [ 52.41153359413148, 55.71049164294613 ] }, "address": "Россия, Республика Татарстан, Набережные Челны, Транспортный проезд, 15", "city": "Набережные Челны", "state": "Республика Татарстан", "county": "городской округ Набережные Челны", "street": "Транспортный проезд", "houseNumber": "15", "federalDistrict": "Приволжский федеральный округ", "radius": 0 } }, { "order": 1, "type": "UnloadPoint", "planEnterDate": "2021-01-07T13:33:00", "geozone": { "location": { "type": "Point", "coordinates": [ 48.39303731918335, 54.30654645200388 ] }, "address": "Россия, Ульяновск, улица Минаева, 48Б", "city": "Ульяновск", "state": "Ульяновская область", "county": "городской округ Ульяновск", "street": "улица Минаева", "houseNumber": "48Б", "federalDistrict": "Приволжский федеральный округ", "radius": 0 }, "cargoOwnerDictionaryItemId": null } ], "driver": { "id": 16309296 }, "carOption": { "carId": 10483431 }, "trailerOption": { "trailerId": 17758587 } } ``` ### Важные детали - Поле `id` должно быть равно **0**. - `externalId` можно использовать как атрибут для сопоставления, но он не уникален: ```json "externalId": "string" ``` После создания сохраните возвращённый `id` CARGO.RUN. Все обновления, смены статуса и удаления выполняйте по нему, а не по `externalId`. ### Порожняя заявка ```json { "isEmptyMileageBid": true, "price": 1, "paymentTypeId": 41, "ndsTypeId": 40, "cargos": [ { "id": 0, "name": null } ], "emptyMileageBid": { "logisticReasonTypeId": 12345, "technicalReason": null } } ``` При порожней заявке: - `price`, `paymentTypeId`, `ndsTypeId` и непустой `cargos` передаются как технические заполнители для валидации; их значения при обработке порожней заявки игнорируются; - `paymentTypeId` и `ndsTypeId` должны ссылаться на существующие значения справочников; - контрагент `cargoOwnerDictionaryItemId` можно не указывать. `logisticReasonTypeId` берётся из справочника причин порожнего пробега. Для технической порожней заявки вместо него передайте `technicalReason` (не более 256 символов). Эти два поля взаимоисключающие. Обязательность объекта `emptyMileageBid` зависит от настройки учёта причин в организации. --- ## 5. Запуск заявки в работу После создания черновика необходимо запустить заявку: ``` POST /api/TruckingBids/SetStatus ``` Тело запроса: ```json { "bidId": 123456, "status": "Started" } ``` Здесь `123456` — `id`, возвращённый при создании заявки. Значение `0` используется только при создании и не подходит для последующего изменения статуса. --- ## 6. Получение статусов и списка заявок во внешней системе Для инкрементальной синхронизации с внешней системой используется метод: ``` GET /api/bids/GetListForExternal ``` Метод возвращает HTTP-статус `200` и массив заявок. ### Принцип работы синхронизации У каждой заявки в CARGO.RUN есть поле: ```text updatedAt ``` Это дата последнего обновления заявки. В процессе синхронизации используется следующий алгоритм: 1. Внешняя система фиксирует верхнюю границу окна и запрашивает заявки, у которых `updatedAt` попадает в это окно. 2. Все страницы окна обрабатываются идемпотентно по `id` и `updatedAt`. 3. Верхняя граница сохраняется как новый рубеж только после успешной обработки всех страниц. 4. Следующее окно начинается с небольшим перекрытием; дубликаты допустимы и отбрасываются. Полный алгоритм и его ограничения описаны в разделе [Синхронизация данных](./sync.md#sync-updated-at). ### Пример запроса ```text /api/bids/GetListForExternal ?$filter=updatedAt ge 2024-01-23T21:00:00Z and updatedAt le 2024-01-25T20:59:59Z and createdAt ge 2022-09-30T21:00:00Z &$top=50 &$orderby=updatedAt,id &$skip=0 ``` Запрос вернёт список заявок: - с датой обновления больше `24.01.2024 00:00` (МСК) (`23.01.2024 21:00:00` UTC); - с датой обновления меньше `25.01.2024 23:59` (МСК) (`25.01.2024 20:59:59` UTC); - с датой создания больше `30.09.2022` (если необходимо ограничение по дате создания); - первые `50` заявок (параметр `$top`), начиная с `0` (`$skip=0`); - отсортированные по полю `updatedAt`. --- ## 7. Обработка ошибок и корректировка данных Типовые причины ошибок при создании и обновлении заявок: - несоответствие идентификаторов справочников (водители, автомобили, прицепы, контрагенты); - некорректные адреса и геозоны; - некорректная структура массива `bidPoints`; - отсутствие обязательных полей. Рекомендуется: - логировать все ошибки на стороне внешней системы; - отображать текст ошибки операторам; - повторять запрос после исправления данных. --- ## 8. Обновление заявки Для обновления заявки поддерживаются два подхода. ### 8.1. Полное обновление заявки Вызовите `POST /api/TruckingBids/Apply` и передайте полную актуальную модель заявки с её `id > 0`. Каждый вызов полностью перезаписывает заявку: отсутствующие значения могут быть потеряны или сброшены. Перед обновлением получите актуальную карточку и объедините изменения. ### 8.2. Частичное обновление заявки Вызовите `POST /api/TruckingBids/Patch`. Для вложенных коллекций действуют особые правила: массив `bidPoints` передаётся целиком, даже при изменении одной точки. Подробности и ограничения приведены в [справочнике методов заявок](../api/bids.md#bid-patch). --- Source: products/cargorun-logistics/integration/sync.md # Синхронизация справочников и заявок Этот документ описывает порядок синхронизации данных между внешней системой (1С/ERP/WMS) и CARGO.RUN. Синхронизация одинакова для обоих сценариев интеграции: когда заявка создаётся в CARGO.RUN и когда она создаётся во внешней системе. --- ## 1. Общие принципы синхронизации Синхронизация выполняется через REST API CARGO.RUN по протоколу HTTPS с использованием токена авторизации. Каждый объект (водитель, машина, прицеп, контрагент, организация, заявка): - имеет уникальный идентификатор `id` в CARGO.RUN; - при создании в CARGO.RUN возвращает этот `id`, который должен быть сохранён во внешней системе; - содержит поле `updatedAt`, отражающее дату и время последнего изменения. Поле `updatedAt` используется как основа для инкрементальной синхронизации. Для заявок применяйте два взаимодополняющих канала: - [асинхронную очередь API 2.0](./async-sync-v2.md) — для оперативного обмена; - `GET /api/bids/GetListForExternal` — для первичной загрузки, статусов, удалений и контрольной сверки. --- ## 2. Справочники, подлежащие синхронизации ### 2.1. Справочники, данные которых поступают из внешней системы Эти справочники всегда считаются первичными во внешней системе: - Водители - Машины - Прицепы - Контрагенты - Организации Для них внешний идентификатор является источником истины, а CARGO.RUN — получателем. Синхронизация выполняется через методы: - `/api/Driver/Apply`, `/api/Driver/Delete`, `/api/Driver/Restore`, `/api/Driver/GetList` - `/api/Car/Apply`, `/api/Car/Delete`, `/api/Car/GetList`, `/api/Car/GetForEdit` - `/api/Trailer/Apply`, `/api/Trailer/Delete`, `/api/Trailer/GetList` - `/api/CargoOwnerDictionary/Apply`, `/api/CargoOwnerDictionary/Delete`, `/api/CargoOwnerDictionary/Get` - `/api/LegalPersons/Apply`, `/api/LegalPersons/Delete`, `/api/LegalPersons/GetList` **Рекомендуемая частота синхронизации: не больше чем раз в 1 минуту.** --- ### 2.2. Ограничения на удаление водителей, машин и прицепов При удалении объектов-справочников (водителей, машин, прицепов) действуют бизнес-ограничения. Система не позволяет удалить объект, если он используется в актуальных данных, например: - водитель назначен на активную или запланированную заявку; - машина участвует в активной заявке; - прицеп привязан к активной заявке или рейсу. В этих случаях: - операция удаления завершается ошибкой (HTTP-статус 4xx); - в ответе возвращается текстовое пояснение причины, например что объект используется в заявке и не может быть удалён. Рекомендуется при интеграции: - логировать текст ошибки; - отображать комментарий пользователю внешней системы; - при необходимости реализовать бизнес-процесс «вывода из эксплуатации» (деактивацию) вместо физического удаления. --- ### 2.3. Справочники, данные которых поступают из CARGO.RUN - Тип оплаты (`PaymentType`) - Тип НДС (`NDSType`) - Тип груза (`CargoType`) - Типы машин (`CarType`) - Типы прицепов (`TrailerType`) - Бренды машин (`CarBrandType`) - Бренды прицепов (`TrailerBrandType`) Получение выполняется методом: ``` GET /api/catalogs/getSimple?$filter=externalId eq null&$orderby=id desc ``` Метод поддерживает OData-фильтры. --- ## 3. Использование справочников при создании заявок Поля, заканчивающиеся на `TypeId` (например, `paymentTypeId`, `ndsTypeId`, `typeId`, `brandTypeId`) должны заполняться значениями из общих справочников. Некорректные идентификаторы приведут к ошибке валидации. --- ## 4. Синхронизация заявок (Bid) Заявка — основной объект интеграции. Синхронизация выполняется по полю: ``` updatedAt ``` Существует два направления синхронизации: 1. **Внешняя система → CARGO.RUN** (создание/обновление через `/api/TruckingBids/Apply` или `/api/TruckingBids/Patch`) 2. **CARGO.RUN → внешняя система** (оперативные изменения через `/api/tasks/queue`, первичная загрузка и сверка через `/api/bids/GetListForExternal`) --- ## 5. Обработка `updatedAt` { #sync-updated-at } Не используйте максимальный `updatedAt` последней страницы как единственный курсор: несколько заявок могут иметь одинаковую метку времени, а состав выборки меняется во время постраничного чтения. Рекомендуемый алгоритм: 1. До начала цикла зафиксировать верхнюю границу `windowEnd` в UTC. 2. Взять нижнюю границу `windowStart` из состояния последней **полностью успешной** синхронизации и отступить назад на небольшой интервал перекрытия. 3. Запросить фиксированное окно `updatedAt ge windowStart and updatedAt le windowEnd` с `$orderby=updatedAt,id`, `$top=50` и последовательным `$skip`. 4. Обработать все страницы; повторные записи безопасно обновлять по паре `id` и `updatedAt`. Учитывать записи с `isDeleted = true`. 5. Только после успешной обработки всего окна атомарно сохранить `windowEnd` как новый завершённый рубеж. 6. При ошибке не продвигать рубеж и повторить окно. Периодически выполнять контрольную сверку за более длинный период. Перекрытие и дедупликация дают семантику «как минимум один раз», а не «ровно один раз». Документация API пока не определяет составной серверный курсор для записей с одинаковым `updatedAt`, поэтому обработчик должен быть идемпотентным. --- ## 6. Получение списка заявок из CARGO.RUN Основной метод для инкрементальной синхронизации: ``` GET /api/bids/GetListForExternal ``` ### Пример запроса ``` /api/bids/GetListForExternal ?$filter=updatedAt ge 2024-01-23T21:00:00Z and updatedAt le 2024-01-25T20:59:59Z and createdAt ge 2022-09-30T21:00:00Z &$top=50 &$orderby=updatedAt,id &$skip=0 ``` Запрос возвращает заявки: - обновлённые не раньше `24.01.2024 00:00 МСК` (`2024-01-23T21:00:00Z`); - обновлённые не позже `25.01.2024 23:59:59 МСК` (`2024-01-25T20:59:59Z`); - созданные после `01.10.2022 00:00 МСК` (`2022-09-30T21:00:00Z`), если нужно ограничить выборку по дате создания; - первые 50 записей, начиная с позиции 0; - отсортированные по дате обновления и ID: `updatedAt,id`. Все списки рекомендуется получать порциями по 50 записей. Не запрашивайте полный список без ограничения количества: тяжелые запросы увеличивают нагрузку на сервер и могут привести к временной блокировке пользователя системой. --- Source: products/cargorun-logistics/integration/async-sync-v2.md # Синхронизация заявок API 2.0 Этот сценарий предназначен для 1С/ERP, которая должна получать изменения заявок из CARGO.RUN и надёжно подтверждать их обработку. ## 1. Какие каналы нужны | Канал | Назначение | |---|---| | `GET /api/bids/GetListForExternal` | Первичная загрузка, статусы, удаления, периодическая сверка | | `POST/GET /api/tasks/queue` | Оперативное асинхронное получение накопленных изменений | API 2.0 не заменяет `GetListForExternal`: он не гарантирует все смены статуса и удаления. ## 2. Первичная загрузка 1. Зафиксируйте `windowEnd` перед началом выборки. 2. Прочитайте все страницы `GetListForExternal` до `windowEnd`. 3. Используйте `$orderby=updatedAt,id`, фиксированный `$top` и последовательный `$skip`. 4. Сохраняйте заявки по `id` CARGO.RUN. `externalId` не уникален. 5. Обрабатывайте `isDeleted = true` как изменение. 6. Продвигайте курсор только после успешной обработки всех страниц. ## 3. Оперативный цикл 1. Отдельный пользователь интеграции вызывает `POST /api/tasks/queue` с `Read` для `Bid`. 2. Вызов выполняется чаще одного раза в час. Окно изменений в текущей реализации равно одному часу. 3. Клиент сохраняет ID задания и ожидает `Completed` или `Error`. 4. Клиент проверяет `objects[].status` и сохраняет каждый `Success` вместе с `id` и `version`. 5. После фиксации в локальной транзакции клиент отправляет `ReadConfirmation`. 6. При `VersionMismatch` клиент повторно читает объект и подтверждает уже новую версию. Несколько быстрых изменений одной заявки могут объединиться. API 2.0 передаёт последнюю версию объекта, а не журнал всех промежуточных событий. ## 4. Защита от эха Изменения, записанные тем же пользователем синхронизации, не ставятся ему в очередь входящих изменений. Поэтому: - используйте для интеграции отдельного пользователя; - не ожидайте, что собственная запись вернётся через `Read`; - после изменяющего запроса проверяйте ответ или повторно читайте объект по `id`. ## 5. Контрольная сверка Выполняйте её: - по расписанию; - после перерыва в работе длиннее часа; - после ошибки `Read`, `ReadConfirmation` или локальной транзакции; - для получения гарантированных смен статуса и удалений. Выборка должна иметь фиксированные границы по `updatedAt`, небольшое перекрытие и дедупликацию по `id + updatedAt`. Подробности: [Синхронизация справочников и заявок](./sync.md). ## 6. Восстановление Если курсор API 2.0 потерян, не пытайтесь восстановить его из ID последнего задания. Запустите контрольную выборку `GetListForExternal` от последней надёжно сохранённой границы. Технический контракт очереди: [Асинхронная очередь API 2.0](../api/async-tasks.md). --- Source: products/cargorun-logistics/integration/examples-1c.md # Пример интеграции CARGO.RUN и 1С Этот пример описывает типовую схему интеграции между: - **CARGO.RUN** — система управления перевозками; - **1С** — учётная система Клиента. Пример показывает, как: - настроить обмен справочниками и заявками; - организовать инкрементальную синхронизацию; - обрабатывать обновления заявок из CARGO.RUN в 1С; - решать конфликты изменений. --- ## 1. Общая архитектура интеграции В 1С рекомендуется реализовать отдельный слой для интеграции со следующей логикой: 1. **Создать дополнительную таблицу для интеграции**, в которой хранить: - ссылки на элементы справочников (водитель, машина, прицеп, контрагент, организация); - ссылки на заявки; - идентификатор объекта в CARGO.RUN (`id`); - внешний атрибут `externalId`, если он нужен проекту, но не как уникальный ключ; - дату обновления объекта в CARGO.RUN (`updatedAt`); - дату обновления объекта в 1С. 2. При создании или обновлении: - элемента справочника, - заявки, необходимо: - записывать запись в интеграционную таблицу; - при первом создании объекта в CARGO.RUN сохранять его `id` в 1С; - при последующих обновлениях — всегда передавать этот `id` в запросах к API CARGO.RUN. `externalId` заявки не уникален. Первичный ключ интеграционной таблицы должен однозначно связывать локальный объект с `id` CARGO.RUN. 3. **Периодически (например, раз в 15 минут)**: - выбирать из интеграционной таблицы все элементы справочников и заявки, созданные или изменённые за этот период; - отправлять их в CARGO.RUN через соответствующие методы (`/api/driver/apply`, `/api/car/apply`, `/api/trailer/apply`, `/api/truckingbids/apply` и т.д.). 4. В 1С у каждого элемента справочника и заявки рекомендуется хранить две даты: - «Дата обновления в CARGO.RUN»; - «Дата обновления в 1С». Эти даты используются для анализа изменений и разрешения конфликтов. --- ## 2. Обновление данных заявок из CARGO.RUN в 1С Если данные заявки могут изменяться в CARGO.RUN (например, фактические времена въезда/выезда, пробег, факт выполнения), 1С должна получать оперативные изменения через API 2.0 и периодически выполнять контрольную выборку `GetListForExternal`. Очередь API 2.0 не гарантирует каждую смену статуса и удаление. См. [Синхронизация заявок API 2.0](./async-sync-v2.md). ### 2.1. Основные шаги 1. При создании или обновлении заявки в 1С сохранять: - дату обновления заявки в 1С; - последнюю известную дату обновления заявки в CARGO.RUN (`updatedAt`). 2. В CARGO.RUN получать список заявок и их дату обновления `updatedAt`. 3. Для выполненных заявок особый интерес представляют: - статус заявки: `status = "Done"`; - фактический километраж: `factMileage`; - по точкам загрузки/выгрузки: - дата въезда в геозону: `bidPoints -> autoEnteredAt`; - дата выезда из геозоны: `bidPoints -> autoLeavedAt`. ### 2.2. Пример запроса по выполненным заявкам Пример OData-запроса (с фильтрацией по статусу и дате обновления): ```text GET /api/bids/GetListForExternal ?$filter=Status eq 'Done' and updatedAt gt 2019-11-20T06:00:00Z &$orderby=updatedAt,id &$top=50 &$skip=0 ``` После получения данных: - если дата обновления заявки в CARGO.RUN (`updatedAt`) более поздняя, чем дата обновления заявки в 1С — необходимо обновить данные заявки в 1С. ### 2.3. Пользовательские поля (extendedProperties) При получении данных по заявке пользовательские поля передаются в массиве `extendedProperties`: ```json "extendedProperties": [ { "propertyName": "Due_date", "value": "12" } ] ``` - `propertyName` — имя пользовательского поля; - `value` — значение, заданное пользователем. ### 2.4. Пользовательские справочники (typeOptions) Пользовательские справочники заявки описываются в массиве `typeOptions`: ```json "typeOptions": [ { "id": 3795270, "entityOptionId": 3794317 } ] ``` - `id` — идентификатор справочника в организации клиента; - `entityOptionId` — идентификатор справочника в CARGO.RUN. --- ## 3. Варианты обновления данных заявки При обновлении данных по заявке из CARGO.RUN в 1С возможны четыре базовые ситуации: 1. Заявка не изменилась в CARGO.RUN, не изменилась в 1С. 2. Заявка не изменилась в CARGO.RUN, изменилась в 1С. 3. Заявка изменилась в CARGO.RUN, не изменилась в 1С. 4. Заявка изменилась и в CARGO.RUN, и в 1С. Для анализа используются три даты: - дата обновления заявки в CARGO.RUN; - дата обновления заявки в 1С; - дата последней синхронизации. Ниже рассмотрены все варианты. ### 3.1. Заявка не изменилась в CARGO.RUN, не изменилась в 1С Условия: - Дата последней синхронизации > Дата обновления заявки в CARGO.RUN. - Дата последней синхронизации > Дата обновления заявки в 1С. Итог: - Обновление данных не требуется. --- ### 3.2. Заявка не изменилась в CARGO.RUN, изменилась в 1С Условия: - дата последней синхронизации не меньше `updatedAt` заявки CARGO.RUN; - дата изменения заявки в 1С больше даты последней синхронизации. Итог: - если 1С является владельцем изменённых полей, отправить изменения в CARGO.RUN; - перечитать заявку и сохранить новое `updatedAt`; - помнить, что `Apply` полностью перезаписывает заявку: перечитать объект, объединить изменения и не отправлять устаревшие значения полей, владельцем которых является CARGO.RUN. --- ### 3.3. Заявка изменилась в CARGO.RUN, не изменилась в 1С Условия: - `updatedAt` заявки CARGO.RUN больше даты последней синхронизации; - дата изменения заявки в 1С не больше даты последней синхронизации. Итог: - обновить запись 1С данными CARGO.RUN; - сохранить полученное `updatedAt` и время успешной синхронизации. --- ### 3.4. Заявка изменилась и в CARGO.RUN, и в 1С Условия: - `updatedAt` заявки CARGO.RUN больше даты последней синхронизации; - дата изменения заявки в 1С больше даты последней синхронизации. Это конфликт. Не выбирайте победителя только по более позднему времени: часы систем могут различаться, а системы могут владеть разными полями. Рекомендуемый порядок: 1. Разделить поля по владельцу. Например, 1С может владеть номером первичного документа и данными оплаты, а CARGO.RUN — оперативным статусом, фактическими событиями и назначенной техникой. Конкретную матрицу утверждают до запуска. 2. Автоматически объединять только изменения в непересекающихся группах полей. 3. Если одно поле изменено с обеих сторон, создать запись конфликта и передать её ответственному сотруднику; не выполнять `Apply` автоматически. 4. После разрешения перечитать заявку, сохранить итоговое `updatedAt` и зафиксировать время успешной синхронизации. ### 3.5. Обязательная матрица владельцев данных До внедрения двусторонней синхронизации зафиксируйте для каждой группы полей: | Группа | Владелец | Допустимое направление | Правило конфликта | |---|---|---|---| | Статус исполнения | CARGO.RUN | CARGO.RUN → 1С | Не перезаписывать из 1С | | Фактические события точек | CARGO.RUN | CARGO.RUN → 1С | Не перезаписывать из 1С | | Данные оплаты | Утверждается проектом | Одно направление | Ручное разрешение при расхождении | | Пользовательские поля | Для каждого поля отдельно | По утверждённой схеме | По владельцу поля | Таблица выше — безопасный шаблон, а не универсальное распределение ответственности. Добавьте в неё все поля, которые интеграция разрешает изменять. --- Source: products/cargorun-logistics/api/overview.md # Обзор API CARGO.RUN Этот документ содержит общие принципы работы API и служит вводной точкой перед изучением детальных сценариев. --- ## 1. Стиль и структура API API CARGO.RUN построен на REST и использует: - протокол HTTPS, - методы HTTP (`GET`, `POST`), - формат JSON, - авторизацию через токен. Все структуры данных, обязательные поля и параметры приведены в соответствующих разделах API Reference. Если для метода нужна модель запроса или ответа, она описывается рядом с методом. --- ## 2. Авторизация Большинство методов требует токен: ``` Authorization: Bearer ``` Полное описание авторизации приведено в разделе: [Auth API](./auth.md) --- ## 3. Модели и данные Структуры объектов описаны в разделах конкретных методов: таблицах полей, примерах JSON и перечнях допустимых значений. Для оперативной инкрементальной синхронизации заявок используйте асинхронную очередь API 2.0: ``` POST /api/tasks/queue GET /api/tasks/queue?id={taskId} ``` Для первичной загрузки, получения статусов и удалений, а также контрольной сверки используйте: ``` GET /api/bids/GetListForExternal ``` API-методы по справочникам не поддерживают фильтрацию по `updatedAt`. API 2.0 пока не гарантирует доставку каждой смены статуса и удаления. Подробности: [Синхронизация заявок API 2.0](../integration/async-sync-v2.md). --- ## 4. Правила работы с API ### 4.1. Формат данных API принимает и возвращает JSON. Подробные правила работы с форматами описаны в: [Форматы данных](../formats.md) --- ### 4.2. Даты и время В документации даты обозначаются типом: ``` string (date-time) ``` Это формат ISO 8601. Используйте формат ISO 8601 со смещением часового пояса. В интеграционных примерах обычно используется UTC (`Z` или `+00:00`). --- ### 4.3. Пагинация и фильтрация Поддерживаются параметры OData: - `$filter` - `$orderby` - `$top` - `$skip` Они применимы только к методам, в описании которых явно указаны соответствующие query-параметры. --- ### 4.4. Регистрозависимость URL API CARGO.RUN регистронезависим. Однако для единообразия во всей документации используется **нижний регистр URL**. --- ### 4.5. Ошибки Универсальная JSON-структура ошибок не используется для всех методов. API возвращает: - HTTP 4xx при бизнес‑ограничениях, - текстовое пояснение причины ошибки. --- ### 4.6. Используемые HTTP‑методы API CARGO.RUN использует **только два HTTP‑метода**: - **GET** — получение данных - **POST** — создание, обновление, удаление, отмена, восстановление, смена статусов Методы `DELETE`, `PUT`, `PATCH` **не используются**. Примеры POST-команд: ``` POST /api/bids/delete POST /api/bids/restore POST /api/truckingbids/revert POST /api/truckingbids/setstatus POST /api/truckingbids/forcecomplete ``` --- ### 4.7. Общий паттерн создания и обновления объектов Для большинства сущностей используется единый подход: #### Создание объекта ``` POST /api/.../apply { "id": 0, ... } ``` #### Обновление объекта ``` POST /api/.../apply { "id": <фактический идентификатор объекта>, ... } ``` --- ## 5. Сценарии интеграции ### Заявка создаётся в CARGO.RUN [CARGO.RUN → учетная система](../integration/scenario-cr-to-external.md) ### Заявка создаётся во внешней системе [Учетная система → CARGO.RUN](../integration/scenario-external-to-cr.md) Общая синхронизация справочников и заявок: [Синхронизация данных](../integration/sync.md) --- ## 6. Дополнительные материалы - Пример интеграции с 1С: [Примеры для 1С](../integration/examples-1c.md) - Минимальные требования к данным: [Минимальные требования к запросам](../minimal-requirements.md) - Глоссарий терминов: [Глоссарий](../glossary.md) --- Source: products/cargorun-logistics/api/auth.md # Авторизация и доступ к API Этот раздел описывает, как получить доступ к API CARGO.RUN и как передавать токен авторизации в запросах. --- ## 1. Общие принципы Доступ к API CARGO.RUN защищён с помощью **JWT-токена**, который передаётся в HTTP-заголовке: ```http Authorization: Bearer ``` Заголовок передается во все методы, которым требуется авторизация. Формат значения: слово `Bearer`, пробел и токен доступа. --- ## 2. Базовый URL Базовый URL API определяется для конкретного клиента при подключении: ```text https://api.app.cargorun.ru/ https://api.test.cargorun.ru/ https://api..cargorun.ru/ ``` Во всех примерах далее используется абстрактный ``. --- ## 3. Получение токена доступа Для получения токена используется метод: ``` POST /api/Account/GenerateToken ``` ### 3.1. Модель запроса ```json { "userName": "string", "password": "string", "code": "string" } ``` Для интеграции поле `code` может быть проигнорировано. Используется для авторизации водителей. Полученный токен имеет ограниченный срок действия и не требует повторного запроса при каждой операции. До его истечения или после ответа `401` обновите пару токенов. Не вычисляйте срок действия самостоятельно: используйте `accessToken.expiresIn` из ответа. Значение задаётся сервером и может отличаться между средами. ### 3.2. Пример запроса ```http POST /api/Account/GenerateToken Content-Type: application/json { "userName": "user@example.com", "password": "P@ssw0rd", "code": "999999" } ``` ### 3.3. Успешный ответ Основные поля ответа: | Поле | Тип | Описание | |---|---|---| | `accessToken.token` | `string` | JWT для заголовка `Authorization` | | `accessToken.expiresIn` | `integer` | Срок действия access token в секундах | | `refreshToken` | `string` | Токен для обновления пары токенов | | `requiresTwoFactor` | `boolean` | Требуется ли второй фактор | | `twoFactorToken` | `object?` | Временный токен второго фактора, если он требуется | | `currentUser` | `object?` | Данные текущего пользователя | Сокращённый пример без пользовательских данных: ```json { "accessToken": { "token": "", "expiresIn": 1800 }, "refreshToken": "", "requiresTwoFactor": false, "twoFactorToken": null } ``` ### 3.4. Ограничения метода Метод `/api/Account/GenerateToken` не предназначен для регулярного или частого вызова. На стороне сервера действуют ограничения (cooldown), и при слишком частом запросе токена сервер может вернуть ошибку `429`. Причина введения ограничения: - метод должен использоваться только для начальной авторизации пользователя; - дальнейшая работа с API должна выполняться через механизм обновления токена (`RefreshToken`). --- ## 4. Обновление токена Для обновления токена необходимо использовать метод: ``` POST /api/Account/RefreshToken ``` ### 4.1. Модель запроса ```json { "accessToken": "string", "refreshToken": "string" } ``` ### 4.2. Пример запроса ```http POST /api/Account/RefreshToken Content-Type: application/json { "accessToken": "<старый_access_token>", "refreshToken": "" } ``` При успехе метод возвращает новую пару в том же формате. Сохраните оба новых значения атомарно; не продолжайте использовать прежний refresh token, если сервер вернул новый. --- ## 5. Передача токена в запросах ```http Authorization: Bearer ``` Пример: ```http GET /api/bids/GetListForExternal Authorization: Bearer eyJhbGciOiJIUzI1... ``` --- ## 6. Ошибки авторизации ### 401 Unauthorized - отсутствует заголовок - токен просрочен или недействителен ### 403 Forbidden - недостаточно прав --- ## 7. Рекомендации по безопасности - не хранить токены в логах; - ограничить доступ к файлам конфигурации; - использовать только HTTPS; - при утечке токена немедленно перевыпустить. --- ## 8. Связанные разделы - [Общий обзор](../integration/overview.md) - [Синхронизация справочников](../integration/sync.md) - [Примеры для 1С](../integration/examples-1c.md) --- Source: products/cargorun-logistics/api/bids.md # Работа с заявками (Bids) Этот раздел описывает методы API CARGO.RUN, использующиеся для создания, обновления, получения, удаления и управления статусами заявок. Общие правила работы API, в том числе паттерн `Apply`, приведены в файле: - [Обзор API](./overview.md) Минимальные обязательные поля заявки — в: - [Минимальные требования к запросам](../minimal-requirements.md) Сценарии интеграции описаны в: - [CARGO.RUN → учетная система](../integration/scenario-cr-to-external.md) - [Учетная система → CARGO.RUN](../integration/scenario-external-to-cr.md) - [Синхронизация данных](../integration/sync.md) - [Синхронизация заявок API 2.0](../integration/async-sync-v2.md) --- # 1. Создание и обновление заявки ## 1.1. Полное создание или обновление заявки {#truckingbids-apply} ```http POST /api/truckingbids/apply ``` ### Назначение - Создание новой заявки (`id = 0`) - Полное обновление существующей заявки (`id > 0`) В теле запроса передается полная модель заявки. При каждом вызове `Apply` модель перезаписывает сохранённое состояние заявки. Для обновления (`id > 0`) сначала получите актуальную карточку, объедините изменения и передайте все значения, которые должны сохраниться. Для изменения отдельных полей используйте `Patch`. `externalId` не уникален и не обеспечивает идемпотентность. После создания сохраните возвращённый `id` CARGO.RUN и используйте именно его для всех последующих операций. ### Основные поля тела запроса | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | `0` для создания новой заявки, ID существующей заявки для обновления | | `cargoOwnerDictionaryItemId` | `long?` | Да, кроме порожней заявки | ID заказчика/контрагента | | `paymentTypeId` | `long?` | Да | Тип оплаты; для порожней заявки требуется валидный технический ID, значение игнорируется | | `ndsTypeId` | `long?` | Да | Тип НДС; для порожней заявки требуется валидный технический ID, значение игнорируется | | `price` | `double?` | Да | Стоимость заявки; для порожней заявки передайте техническое значение, например `1`, оно игнорируется | | `driver` | `object?` | Да | Водитель | | `carOption` | `object?` | Да | Автомобиль/тягач | | `trailerOption` | `object?` | Да | Прицеп | | `bidPoints` | `BidPointEditModel[]` | Да | Маршрутные точки, минимум две: погрузка и выгрузка | | `cargos` | `CargoModel[]?` | Да | Грузы; для порожней заявки нужен непустой технический массив, значения игнорируются | | `typeOptions` | `TypeOptionModel[]?` | Нет | Пользовательские справочники и дополнительные опции | | `externalId` | `string?` | Нет | Внешний ID заявки; не уникален и не заменяет `id` CARGO.RUN | | `comment` | `string?` | Нет | Комментарий | | `clientBidNumber` | `string?` | Нет | Номер заявки клиента | | `clientBidDate` | `date-time?` | Нет | Дата заявки клиента | | `isEmptyMileageBid` | `boolean?` | Нет | Признак порожней заявки | | `emptyMileageBid` | `EmptyMileageBidModel?` | Условно | Причина порожнего пробега; обязательна, если в организации включён учёт причин | ### Поля `bidPoints[]` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | `0` для новой точки, ID существующей точки для обновления | | `order` | `int` | Да | Порядковый номер точки в маршруте | | `type` | `BidPointType` | Да | Тип точки, например погрузка или выгрузка | | `customPointTypeId` | `long?` | Нет | Тип пользовательской точки, если `type = CustomPoint` | | `planEnterDate` | `date-time?` | Нет | Плановое время прибытия | | `secondaryPlanEnterDate` | `date-time?` | Нет | Дополнительное плановое время | | `geozone` | `MapObjectEditModel?` | Да | Геозона/адрес точки | | `counterpartyId` | `long?` | Нет | Контрагент точки | | `contactPerson` | `object?` | Нет | Контактное лицо точки | | `comment` | `string?` | Нет | Комментарий к точке | | `loadOptions` | `object[]?` | Нет | Опции погрузки/выгрузки | ### Значения `BidPointType` | Значение | Код | Описание | |---|---:|---| | `StartPoint` | `0` | Стартовая точка маршрута | | `LoadPoint` | `1` | Точка погрузки | | `UnloadPoint` | `2` | Точка выгрузки | | `CustomPoint` | `3` | Пользовательская точка маршрута. Для нее можно передать `customPointTypeId` | ### Поля `bidPoints[].geozone` `geozone` описывает адрес и географию точки маршрута. | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | ID геообъекта. Для новой точки обычно передается `0` | | `location` | `PointEditModel` | Да | Координаты точки | | `city` | `string?` | Нет | Город | | `address` | `string?` | Нет | Полный адрес | | `village` | `string?` | Нет | Населенный пункт | | `state` | `string?` | Нет | Регион | | `county` | `string?` | Нет | Район | | `street` | `string?` | Нет | Улица | | `houseNumber` | `string?` | Нет | Номер дома | | `federalDistrict` | `string?` | Нет | Федеральный округ | | `radius` | `double?` | Нет | Радиус геозоны | | `type` | `MapObjectType` | Да | Тип геообъекта | ### Поля `bidPoints[].geozone.location` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `coordinates` | `double[]?` | Нет | Координаты точки. Обычно передаются в формате `[долгота, широта]` | ### Значения `MapObjectType` | Значение | Код | Описание | |---|---:|---| | `None` | `0` | Тип не задан | | `BidPoint` | `1` | Точка заявки | | `RouteSupportPoint` | `2` | Опорная точка маршрута | | `GasStation` | `3` | АЗС | | `StartBidPoint` | `4` | Стартовая точка заявки | | `PostamatPoint` | `5` | Постамат | | `ItemChangePoint` | `6` | Точка перецепки или пересменки | | `ServicePoint` | `7` | Сервисная точка | | `CounterpartyPoint` | `8` | Точка контрагента | | `TripCouplingPoint` | `9` | Точка сцепки рейса | ### Поля `bidPoints[].contactPerson` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | ID контактного лица | | `name` | `string?` | Нет | Имя контактного лица | | `phoneNumber` | `string?` | Нет | Телефон контактного лица | ### Поля `bidPoints[].loadOptions[]` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | ID опции погрузки или выгрузки | ### Как читать массивы, справочники и перечисления | Признак в поле | Что означает | Примеры | |---|---|---| | Тип заканчивается на `[]` | Поле содержит массив объектов или значений | `bidPoints`, `cargos`, `typeOptions`, `loadOptions`, `accessPermitIds` | | Название заканчивается на `Id` или `Ids` | Поле ссылается на существующий объект или элемент справочника | `counterpartyId`, `paymentTypeId`, `ndsTypeId`, `driverId`, `accessPermitIds` | | Тип указан как отдельная модель с обязательным `id` | Нужно передать ссылку на существующий объект и, если требуется, дополнительные поля модели | `contactPerson`, `loadOptions` | | Тип имеет фиксированный список значений | Это перечисление, а не справочник | `BidPointType`, `MapObjectType` | ### Поля `cargos[]` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | `0` для нового груза, ID существующего груза для обновления | | `typeId` | `long?` | Нет | Тип груза | | `name` | `string?` | Нет | Наименование груза | | `weight` | `double?` | Нет | Вес | | `volume` | `double?` | Нет | Объем | | `length` | `double?` | Нет | Длина | | `width` | `double?` | Нет | Ширина | | `height` | `double?` | Нет | Высота | | `loadingTypeId` | `long?` | Нет | Тип погрузки | | `unloadingTypeId` | `long?` | Нет | Тип выгрузки | | `comment` | `string?` | Нет | Комментарий к грузу | ### Поля `typeOptions[]` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | ID элемента пользовательского справочника | | `entityOptionId` | `long` | Да | ID настройки/свойства справочника | ### Поля `emptyMileageBid` Используются только при `isEmptyMileageBid = true`. | Поле | Тип | Описание | |---|---|---| | `logisticReasonTypeId` | `long?` | Причина из справочника `EmptyMileageBidReasonType` для обычной порожней заявки | | `technicalReason` | `string?` | Текст технической причины, не более 256 символов, для технической порожней заявки | Передавайте **одно** из этих полей в соответствии с типом заявки. Для обычной порожней заявки `technicalReason` должен быть `null`; для технической заявки `logisticReasonTypeId` должен быть `null`. Если у организации отключён учёт причин, объект может быть опущен. ### Особенности - поддерживает как создание, так и полное обновление; - при создании статус заявки — `New` (черновик); - при ошибках валидации API возвращает HTTP 4xx с текстом ошибки. ### Пример создания заявки В примере показан запрос на создание черновика заявки. Он адаптирован из payload фронта: служебные поля интерфейса и поля состояния не передаются, а `id` новых объектов указаны как `0`. ```json { "id": 0, "cargoOwnerDictionaryItemId": 129647034, "legalPersonId": 127039077, "paymentTypeId": 41, "ndsTypeId": 129493473, "price": 45000, "isVatTop": false, "contractNumber": "324352352352", "paymentPeriodType": "InCalendarDays", "responsibleId": 1466813, "isDriverForwarder": false, "isEmptyMileageBid": false, "createDocumentAssignment": false, "driver": { "id": 1478168 }, "carOption": { "carId": 1465629 }, "trailerOption": { "trailerId": 128820197 }, "bidPoints": [ { "id": 0, "order": 0, "type": "LoadPoint", "comment": "Комментарий к первой точке", "planEnterDate": "2026-07-15T10:58:00", "cargoOwnerDictionaryItemId": 129647035, "geozone": { "id": 0, "location": { "type": "Point", "coordinates": [ 47.4720139, 55.86623 ] }, "city": "Цивильск", "address": "Россия, Чувашская Республика — Чувашия, Цивильск, улица Гагарина", "state": "Чувашская Республика — Чувашия", "county": "Цивильский муниципальный округ", "street": "улица Гагарина", "houseNumber": null, "federalDistrict": "Приволжский федеральный округ", "radius": 2000, "type": "BidPoint" }, "contactPerson": { "id": 129417981, "phoneNumber": "+7 964 781-40-98", "name": "Александр Пушкин" }, "loadOptions": [ { "id": 4612889 } ], "typeOptions": [], "extendedProperties": [] }, { "id": 0, "order": 1, "type": "UnloadPoint", "comment": "Комментарий к выгрузке", "planEnterDate": "2026-07-16T11:10:00", "cargoOwnerDictionaryItemId": 129647014, "geozone": { "id": 0, "location": { "type": "Point", "coordinates": [ 55.9507846, 54.7017154 ] }, "city": "Уфа", "address": "Россия, Республика Башкортостан, Уфа, Сарапульская улица, 35", "state": "Республика Башкортостан", "county": "городской округ Уфа", "street": "Сарапульская улица", "houseNumber": "35", "federalDistrict": "Приволжский федеральный округ", "radius": 1999, "type": "BidPoint" }, "contactPerson": { "id": 129417982, "phoneNumber": "8 914 781 07 01", "name": "Михаил Лермонтов" }, "loadOptions": [ { "id": 4612889 } ], "typeOptions": [], "extendedProperties": [] } ], "cargos": [ { "id": 0, "name": "Крышки", "weight": 20, "volume": 5, "length": 6, "height": 8, "width": 7, "typeId": 712, "packType": "Паллеты", "comment": "Комментарий к грузу", "extendedProperties": [], "typeOptions": [] } ], "extendedProperties": [ { "propertyName": "CustomeFieldForDemo", "value": "Пример заполнения кастомного поля" } ], "typeOptions": [], "documents": [], "accessPermitIds": [] } ``` ### Успешный ответ При успехе метод возвращает служебный результат сохранения, включая идентификатор заявки и ее статус. Набор полей может быть шире примера, поэтому интеграция должна читать нужные поля и допускать появление дополнительных. ```http HTTP/1.1 200 OK Content-Type: application/json ``` ```json { "entityId": 123456, "status": "New" } ``` Сохраните `entityId` как ID заявки CARGO.RUN. Перед запуском при необходимости перечитайте заявку, затем измените статус отдельным методом. --- ## 1.2. Частичное обновление заявки (Patch) { #bid-patch } ```http POST /api/truckingbids/patch ``` ### Назначение - обновление только изменённых полей заявки. ### Ограничения - нельзя частично изменить вложенные структуры (`bidPoints`, `cargos`, `typeOptions` и др.); - если нужно изменить маршрутные точки — необходимо передать **весь массив** `bidPoints`, включая неизменённые точки. --- # 2. Управление статусами и жизненным циклом ## 2.1. Запуск заявки в работу ```http POST /api/truckingbids/setstatus ``` ### Тело запроса ```json { "bidId": 123456, "status": "Started" } ``` `bidId` — фактический идентификатор существующей заявки. Вручную поддерживается запуск со значением `Started`. Если машина занята и для организации включено планирование, система может сохранить заявку как `Planned`. Значение `Planned` нельзя устанавливать этим методом напрямую. При успехе метод возвращает: ```json { "id": 123456 } ``` --- ## 2.2. Отмена заявки ```http POST /api/bids/cancel ``` ### Тело запроса ```json { "bidId": 123456 } ``` --- ## 2.3. Закрытие заявки вручную ```http POST /api/truckingbids/forcecomplete ``` ### Тело запроса ```json { "bidId": 123456, "reason": "string", "mileage": 0, "useOdometerMileage": true, "bidPoints": [ { "id": 654321, "enteredAtByLogist": "2025-05-07T07:15:04Z", "loadUnloadedAtByLogist": "2025-05-07T07:15:04Z", "loadUnloadStatus": "AtLoading" } ] } ``` --- ## 2.4. Возврат заявки в черновик ```http POST /api/truckingbids/revert ``` ### Тело запроса ```json { "bidId": 123456 } ``` --- # 3. Удаление и восстановление ## 3.1. Удаление заявки ```http POST /api/bids/delete ``` ### Тело запроса ```json { "bidId": 123456 } ``` Заявка должна быть предварительно переведена в статус `New` (через `/api/truckingbids/revert`). --- ## 3.2. Восстановление удалённой заявки ```http POST /api/bids/restore ``` ### Тело запроса ```json { "bidId": 123456 } ``` --- # 4. Получение заявок ## 4.1. Получение заявки для редактирования ```http GET /api/bids/get ``` Параметры: - `id` — идентификатор заявки. --- ## 4.2. Получение списка заявок (инкрементальная синхронизация) ```http GET /api/bids/getlistforexternal ``` Метод возвращает список заявок по фильтру для внешних сервисов с более подробной информацией. Используется OData-формат параметров. У каждой заявки есть поле `updatedAt` — дата последнего изменения заявки в CARGO.RUN. Для инкрементальной синхронизации обрабатывайте фиксированные окна времени с перекрытием и дедупликацией по `id` и `updatedAt`. Не продвигайте границу окна до успешной обработки всех страниц. Подробный алгоритм приведён в разделе [Синхронизация данных](../integration/sync.md#sync-updated-at). Поддерживает: - `$filter` - `$orderby` - `$top` - `$skip` Пример запроса: ```http GET /api/bids/GetListForExternal ?$filter=updatedAt ge 2024-01-23T21:00:00Z and updatedAt le 2024-01-25T20:59:59Z and createdAt ge 2022-09-30T21:00:00Z &$top=50 &$orderby=updatedAt &$skip=0 ``` Запрос возвращает заявки: - дата обновления которых больше или равна `24.01.2024 00:00 МСК` (`2024-01-23T21:00:00Z`); - дата обновления которых меньше или равна `25.01.2024 23:59:59 МСК` (`2024-01-25T20:59:59Z`); - дата создания которых больше или равна `01.10.2022 00:00 МСК` (`2022-09-30T21:00:00Z`), если нужно ограничить выборку по дате создания; - первые 50 записей, начиная с позиции 0; - отсортированные по дате обновления `updatedAt`. Все списки необходимо получать порциями по 50 записей для минимизации нагрузки на сервер. Если получать полные списки без ограничения количества, пользователь может быть временно заблокирован системой. Подробное описание в: - [Синхронизация данных](../integration/sync.md) ### Основные поля ответа `BidForExternalSyncModel` Метод возвращает массив заявок. Общее количество записей передается в заголовке `X-MetaCount`. | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID заявки | | `status` | `BidStatus` | Статус заявки | | `price` | `double?` | Цена | | `priceWithoutVatOnTop` | `double?` | Цена без НДС, если НДС сверху | | `createdAt` | `date-time` | Дата создания заявки | | `updatedAt` | `date-time` | Дата последнего изменения | | `externalUpdatedAt` | `date-time?` | Дата обновления из внешней системы | | `createdById` | `long` | ID пользователя, создавшего заявку | | `approvedById` | `long?` | ID пользователя, согласовавшего заявку | | `approvedAt` | `date-time?` | Дата согласования | | `responsibleId` | `long?` | ID ответственного | | `salesManagerId` | `long?` | ID менеджера по продажам | | `carLogistId` | `long?` | ID логиста автомобиля на момент создания заявки | | `paymentTypeId` | `long` | Тип оплаты | | `ndsTypeId` | `long` | Тип НДС | | `isVatTop` | `boolean` | НДС начисляется сверху | | `counterpartyId` | `long?` | ID контрагента | | `contractId` | `long?` | ID договора контрагента | | `distributionBidId` | `long?` | ID заказа, из которого создана заявка | | `routeId` | `long?` | ID маршрута | | `driverId` | `long?` | ID текущего водителя | | `secondaryDriverId` | `long?` | ID второго водителя | | `isDriverForwarder` | `boolean` | Водитель является экспедитором | | `acceptedByDriverAt` | `date-time?` | Дата принятия заявки водителем | | `acceptedByDriverForwarderAt` | `date-time?` | Дата принятия водителем-экспедитором | | `car` | `CarSimpleModel?` | Автомобиль | | `trailer` | `TrailerListViewModel?` | Прицеп | | `legalPerson` | `IdModel?` | Юридическое лицо | | `bidPoints` | `BidPointViewModel[]?` | Точки маршрута | | `cargos` | `CargoModel[]?` | Грузы | | `typeOptions` | `TypeOptionModel[]?` | Пользовательские справочники и дополнительные опции | | `temperatureRegime` | `BidTemperatureRegimeModel?` | Температурный режим | | `temperature` | `TemperatureValueModel?` | Текущая температура | | `documents` | `RelatedDocumentModel[]?` | Документы | | `extendedProperties` | `ExtendedPropertyJsonObject[]?` | Дополнительные поля заявки | | `externalId` | `string?` | Внешний ID | | `contractNumber` | `string?` | Номер договора | | `comment` | `string?` | Комментарий | | `clientBidNumber` | `string?` | Номер заявки клиента | | `clientBidDate` | `date-time?` | Дата заявки клиента | | `paymentPeriodInDays` | `int?` | Срок оплаты в днях | | `paymentPeriodType` | `PaymentPeriodType?` | Вариант срока оплаты | | `sourceType` | `SourceType` | Источник заявки | | `hasFactoring` | `boolean` | Заявка отправлена на факторинг | | `isEmptyMileageBid` | `boolean` | Порожняя заявка | | `isInternational` | `boolean` | Международная заявка | | `hasItemsChange` | `boolean` | Есть перецепка/пересменка | | `isDeleted` | `boolean` | Заявка удалена | | `createDocumentAssignment` | `boolean` | Создавать задание сдачи документов после завершения | | `hasServicePoints` | `boolean` | Есть точки сервисных работ | | `isPreBid` | `boolean` | Предзаявка | | `payment` | `BidPaymentGetModel?` | Информация об оплате | | `accessPermitIds` | `long[]?` | Допуски и разрешения | ### Поля `extendedProperties[]` `extendedProperties` содержит пользовательские дополнительные поля заявки. | Поле | Тип | Описание | |---|---|---| | `propertyName` | `string` | Имя пользовательского поля | | `value` | `string?` | Значение, заданное пользователем | ### Поля `typeOptions[]` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID элемента пользовательского справочника | | `entityOptionId` | `long` | ID настройки/свойства справочника | Чтобы получить человекочитаемое значение элемента, запросите `GET /api/Catalogs/GetItems?$filter=id eq {typeOptions[].id}`. Подробнее: [Пользовательские справочники](./custom-catalogs.md). --- # 5. Получение связанных данных ## 5.1. Связанные документы ```http GET /api/bids/getbiddocumentassignmentsforbid ``` Возвращает связанные документы (внешние файлы) по заявке. --- ## 5.2. Данные по точкам заявки Изменение точек выполняется: - через `/apply` — полная передача модели, - через `/patch` — но с передачей **всего массива `bidPoints`**. ## 5.3. Получение данных по перецепкам в заявке ```http GET /api/truckingbids/gettrailerreplacements ``` ### Назначение Получение данных о перецепках (замене прицепа) в рамках конкретной заявки. ### Параметры - `bidId` — идентификатор заявки (query-параметр). ### Комментарии Метод возвращает список всех событий замены прицепа, зафиксированных по заявке: старый и новый прицеп, время замены, источник данных и комментарий (если задан). ### Основные поля ответа | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID события замены | | `bidId` | `long` | ID заявки | | `oldTrailerId` | `long?` | ID старого прицепа | | `oldTrailerNumber` | `string?` | Номер старого прицепа | | `newTrailerId` | `long?` | ID нового прицепа | | `newTrailerNumber` | `string?` | Номер нового прицепа | | `replacedAt` | `date-time?` | Дата и время замены | | `sourceType` | `SourceType?` | Источник данных | | `comment` | `string?` | Комментарий | --- ## 5.4. Обновление данных по оплате заявки ```http POST /api/TruckingBids/ApplyBidPayment ``` ### Назначение Установка или изменение данных по оплате заявки. Используйте `ApplyBidPayment`, если внешняя система (например, 1С) фиксирует оплату по заявке и должна передать в CARGO.RUN статус оплаты, дату оплаты, плановую дату оплаты, сумму остатка или комментарий. ### Тело запроса Тело описано моделью `BidPaymentWrapperModel`: ```json { "bidId": 123456, "payment": { "paymentStatus": "Paid", "factPaymentDate": "2026-06-30", "planPaymentDate": "2026-07-05", "invoiceDate": "2026-06-29", "remainingPayment": 0, "comment": "Оплата получена" } } ``` Поля: - `bidId` — идентификатор заявки; - `payment` — данные оплаты (`BidPaymentModel`); - `payment.paymentStatus` — статус оплаты, обязательное поле; - `payment.factPaymentDate` — фактическая дата оплаты; - `payment.planPaymentDate` — плановая дата оплаты; - `payment.invoiceDate` — дата счёта; - `payment.remainingPayment` — остаток к оплате; - `payment.comment` — комментарий по оплате. ### Поддерживаемые значения Поддерживаемые значения `payment.paymentStatus`: - `NotPaid` - `PartiallyPaid` - `Paid` - `Expired` --- # 6. Ошибки Возможные ошибки: - невалидные данные (`paymentTypeId`, `ndsTypeId`, элементы геозон и т.д.); - попытка удалить заявку без предварительного `revert`; - частичное обновление вложенных структур через `/patch`. Поведение API: - ошибки бизнес-валидации возвращаются с HTTP-статусом `400`; - тело ошибки может быть обычным текстом или JSON-объектом `ValidationApiResult`; - не повторяйте запрос с теми же данными после `400`: сначала исправьте payload; - при `401` обновите токен и повторите запрос один раз; - при `429` или временной ошибке `5xx` используйте ограниченные повторы с увеличивающейся задержкой. Общий формат обработки ошибок описан в разделе [Форматы данных](../formats.md#api-errors). --- Source: products/cargorun-logistics/api/async-tasks.md # Асинхронная очередь API 2.0 API 2.0 выполняет чтение и запись объектов в фоновой очереди. Обычный клиент 1С/ERP работает с методами: ```http POST /api/tasks/queue GET /api/tasks/queue?id={taskId} ``` `/api/iris/queue` — алиас тех же методов. В новых интеграциях используйте `/api/tasks/queue`. !!! warning `/api/integrations/Tasks/Queue` относится к отдельному партнёрскому API с другой авторизацией. Не используйте его вместо `/api/tasks/queue`. ## 1. Подготовка Администратор организации должен создать настройку внешней системы и привязать к ней отдельного пользователя: ```http GET /api/SyncSystems/Get POST /api/SyncSystems/Apply POST /api/SyncSystems/Delete ``` Основные поля `SyncSystemModel`: | Поле | Значение | |---|---| | `id` | `0` для новой настройки, ID для изменения | | `userId` | Пользователь, от имени которого работает интеграция | | `behavior` | `0` — очистка при чтении; `1` — очистка только после `ReadConfirmation` | | `trackingType` | `0` — не отслеживать; `1` — все изменения; `2` — изменения экспедиции | | `callback.target` | HTTPS URL для уведомления о завершении задания | | `callback.secret` | Секрет HMAC-SHA256; не передавайте его в журналах | Для надёжной синхронизации используйте `behavior = 1` и `trackingType = 1`. ## 2. Постановка задания ```http POST /api/tasks/queue Authorization: Bearer Idempotency-Key: sync-bids-20261012-1200 Content-Type: application/json ``` ```json { "commands": [ { "action": 1, "objects": [ { "type": 1, "modelType": 0 } ] } ] } ``` Пример ставит в очередь чтение накопленных изменений заявок. `Idempotency-Key` необязателен, имеет длину не более 100 символов и в течение 24 часов возвращает те же задания для повторного запроса. Сервер возвращает HTTP `202 Accepted`: ```json { "latencyMsec": 25, "enqueuedInMsec": 3, "commands": [ { "id": 731245, "action": 1, "status": 0, "readyInMsec": 25, "message": null } ] } ``` Каждая команда ставится в очередь независимо. Проверяйте `commands[].status`: `0` — успех, `1` — команда не попала в очередь. `commands[].id` — ID задания, а не ID заявки. ## 3. Действия | Код | Имя | Назначение | |---:|---|---| | `0` | `Write` | Создание или полное обновление | | `1` | `Read` | Чтение объектов или накопленных изменений | | `2` | `ReadConfirmation` | Подтверждение обработанной версии | | `3` | `ReadQuery` | Чтение по OData-запросу | | `4` | `Delete` | Удаление по ID CARGO.RUN | Типы объектов: `1` — `Bid`, `2` — `DistributionBid`, `3` — `Car`, `4` — `Trailer`, `5` — `Driver`, `6` — `Counterparty`. Основные поля `objects[]`: | Поле | Правило | |---|---| | `id` | Внутренний ID CARGO.RUN; `null`/`0` при `Write` создаёт объект | | `key` | Внешний корреляционный ключ до 64 символов; не уникален и не заменяет `id` | | `version` | UUID версии; передача при `Write` включает проверку конкурентного изменения | | `modelType` | `0` — основная модель; другие значения используйте только в описанном сценарии | | `body` | Полная модель для `Write` | | `query` | OData-запрос для `ReadQuery`; в этом объекте `id`, `version` и `key` должны быть пустыми | `externalId` заявки и `objects[].key` не уникальны. Обновление, чтение, подтверждение и удаление выполняйте по `objects[].id` CARGO.RUN. ## 4. Получение результата ```http GET /api/tasks/queue?id=731245 Authorization: Bearer ``` Статусы задания: `0` — `Awaiting`, `1` — `InProgress`, `2` — `Completed`, `3` — `Error`. - При `InProgress` сервер передаёт `Retry-After` в секундах. - При `Awaiting` ориентируйтесь на `nextRetryAt`. - `Completed` не означает успех всех объектов. Проверьте каждый `objects[].status`. - Неизвестное или недоступное задание может вернуть HTTP `200` с `null`. Статусы объекта: `0` — `Created`, `1` — `Success`, `2` — `Error`, `3` — `VersionMismatch`. При `VersionMismatch` в ответе передаётся текущая версия: перечитайте объект и не подтверждайте устаревшую версию. Обработка задания выполняется до трёх раз. После ошибок используются задержки 5 и 10 секунд. Завершённые задания хранятся примерно три дня; забирайте результат без отлагательств. ## 5. Надёжное чтение с подтверждением Для `behavior = 1`: 1. поставьте `Read` для типа `Bid`; 2. дождитесь `Completed`; 3. надёжно сохраните каждый успешный объект вместе с `id` и `version`; 4. только после успешной локальной транзакции отправьте `ReadConfirmation`: ```json { "commands": [ { "action": 2, "objects": [ { "type": 1, "modelType": 0, "id": 123456, "version": "2f1ac0f8-1da7-4e74-b69d-1a94de150803" } ] } ] } ``` Изменения, сделанные тем же пользователем синхронизации, не возвращаются ему как входящие изменения. Это предотвращает эхо синхронизации. ## 6. Callback Если в `SyncSystemModel` задан `callback.target`, CARGO.RUN отправляет `POST` после завершения задания. Проверяйте: ```text HMAC_SHA256(callback.secret, ".") ``` Заголовки: `X-Cargorun-Task-Id`, `X-Cargorun-Webhook-Event`, `X-Cargorun-Webhook-Timestamp`, `X-Cargorun-Webhook-Signature: sha256=`. Callback выполняется до пяти раз с задержками 10, 20, 40 и 80 секунд. Повтор выполняется при сетевой ошибке, HTTP `408`, `429` или `5xx`. `callbackStatus` и счётчики callback возвращаются в `GET /api/tasks/queue`. ## 7. Границы гарантий - В выборку `Read` попадают накопленные изменения не старше одного часа. Это намеренное ограничение. Вызывайте синхронизацию чаще одного раза в час. - Несколько изменений одного объекта могут объединяться: клиент получит последнюю версию, а не журнал каждого промежуточного события. - API 2.0 пока не гарантирует доставку всех смен статуса и удалений. Для них используйте контрольную синхронизацию через `GET /api/bids/GetListForExternal`. Полный алгоритм: [Синхронизация заявок API 2.0](../integration/async-sync-v2.md). --- Source: products/cargorun-logistics/api/distribution-bids.md # Заказы на распределение (DistributionBids) Этот раздел описывает методы API CARGO.RUN для работы с заказами на распределение (DistributionBids). Общие принципы работы API см. в: - [Обзор API](../api/overview.md) - [Auth API](../api/auth.md) Минимальные требования к данным заказа на распределение приведены в: - [Минимальные требования к запросам](../minimal-requirements.md) --- ## 1. Создание и обновление заказов ### 1.1. Пакетное создание/обновление заказов ```http POST /api/distributionbids/apply ``` ### Назначение Создание и изменение заказов на распределение. - При `id = 0` в элементах массива — создаётся новый заказ. - При `id > 0` — обновляется существующий заказ. ### Тело запроса Тело запроса описано моделью `DistributionBidBatchEditModel`: ```json { "items": [ { // DistributionBidEditModel } ] } ``` Модель `DistributionBidEditModel` содержит поля заказа. Обязательные поля указаны в разделе: - [Минимальные требования к запросам](../minimal-requirements.md) ### Основные поля `DistributionBidEditModel` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | `0` для создания нового заказа, ID существующего заказа для обновления | | `counterpartyId` | `long?` | Нет | ID контрагента | | `legalPersonId` | `long?` | Нет | ID юридического лица | | `sourceId` | `long?` | Нет | ID источника заказа | | `trailerTypeId` | `long?` | Нет | ID типа прицепа | | `contactPerson` | `object?` | Нет | Контактное лицо | | `temperatureRegime` | `object?` | Нет | Температурный режим | | `carId` | `long?` | Нет | ID автомобиля | | `driverId` | `long?` | Нет | ID водителя | | `trailerId` | `long?` | Нет | ID прицепа | | `externalStatus` | `ExternalDistributionBidStatus` | Да | Внешний статус заказа | | `cargos` | `DistributionBidCargoModel[]?` | Нет | Грузы | | `bidPoints` | `DistributionBidPointEditModel[]?` | Нет | Точки заказа | | `key` | `string?` | Нет | Ключ или внешний код заказа | | `comment` | `string?` | Нет | Комментарий | | `paymentTypeId` | `long?` | Нет | Тип оплаты | | `ndsTypeId` | `long?` | Нет | Тип НДС | | `price` | `double?` | Нет | Стоимость | | `isVatTop` | `boolean?` | Нет | НДС начисляется сверху | | `externalId` | `string?` | Нет | Внешний ID | ### Поля `bidPoints[]` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | `0` для новой точки, ID существующей точки для обновления | | `order` | `int` | Да | Порядковый номер точки в маршруте | | `type` | `BidPointType` | Да | Тип точки заказа | | `customPointTypeId` | `long?` | Нет | Тип пользовательской точки, если `type = CustomPoint` | | `planEnterDate` | `date-time?` | Нет | Плановое время прибытия | | `secondaryPlanEnterDate` | `date-time?` | Нет | Дополнительное плановое время | | `geozone` | `MapObjectEditModel?` | Нет | Геозона/адрес точки | | `counterpartyId` | `long?` | Нет | Контрагент точки | | `contactPerson` | `ContactPersonModel?` | Нет | Контактное лицо точки | | `comment` | `string?` | Нет | Комментарий к точке | | `loadOptions` | `LoadOptionModel[]?` | Нет | Опции погрузки/выгрузки | ### Значения `BidPointType` | Значение | Код | Описание | |---|---:|---| | `StartPoint` | `0` | Стартовая точка маршрута | | `LoadPoint` | `1` | Точка погрузки | | `UnloadPoint` | `2` | Точка выгрузки | | `CustomPoint` | `3` | Пользовательская точка маршрута. Для нее можно передать `customPointTypeId` | ### Поля `bidPoints[].geozone` `geozone` описывает адрес и географию точки заказа. | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | ID геообъекта. Для новой точки обычно передается `0` | | `location` | `PointEditModel` | Да | Координаты точки | | `city` | `string?` | Нет | Город | | `address` | `string?` | Нет | Полный адрес | | `village` | `string?` | Нет | Населенный пункт | | `state` | `string?` | Нет | Регион | | `county` | `string?` | Нет | Район | | `street` | `string?` | Нет | Улица | | `houseNumber` | `string?` | Нет | Номер дома | | `federalDistrict` | `string?` | Нет | Федеральный округ | | `radius` | `double?` | Нет | Радиус геозоны | | `type` | `MapObjectType` | Да | Тип геообъекта | ### Поля `bidPoints[].geozone.location` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `coordinates` | `double[]?` | Нет | Координаты точки. Обычно передаются в формате `[долгота, широта]` | ### Значения `MapObjectType` | Значение | Код | Описание | |---|---:|---| | `None` | `0` | Тип не задан | | `BidPoint` | `1` | Точка заявки или заказа | | `RouteSupportPoint` | `2` | Опорная точка маршрута | | `GasStation` | `3` | АЗС | | `StartBidPoint` | `4` | Стартовая точка заявки или заказа | | `PostamatPoint` | `5` | Постамат | | `ItemChangePoint` | `6` | Точка перецепки или пересменки | | `ServicePoint` | `7` | Сервисная точка | | `CounterpartyPoint` | `8` | Точка контрагента | | `TripCouplingPoint` | `9` | Точка сцепки рейса | ### Поля `bidPoints[].contactPerson` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | ID контактного лица | | `name` | `string?` | Нет | Имя контактного лица | | `phoneNumber` | `string?` | Нет | Телефон контактного лица | ### Поля `bidPoints[].loadOptions[]` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | ID опции погрузки или выгрузки | ### Пример создания заказа В примере показано создание заказа на распределение с двумя точками маршрута, грузом, наемным транспортом и пользовательским дополнительным полем. ```json { "items": [ { "id": 0, "externalStatus": "None", "counterpartyId": 129647035, "legalPersonId": 127039078, "responsibleId": 1466813, "price": 120000, "paymentTypeId": 41, "ndsTypeId": 129493473, "paymentPeriodType": "InCalendarDays", "paymentPeriodInDays": 30, "invoiceTriggerType": "ByOriginal", "trailerTypeId": 94325, "hasHiredCar": true, "isMandatory": true, "hiredCarCounterpartyId": 129647034, "hiredCarPrice": 115000, "hiredCarCompletedAt": "2026-07-15T00:00:00", "hiredCarNdsTypeId": 129493473, "hiredCarPaymentTypeId": 41, "hiredCarInvoiceTriggerType": "AtUnloading", "hiredCarPaymentPeriodType": "InCalendarDays", "hiredCarPaymentPeriodInDays": 30, "hiredCarId": 301, "hiredTrailerId": 182, "hiredDriverId": 242, "contractNumber": "324352352352", "comment": "Произвольный комментарий к заказу", "contactPerson": { "name": "Владимир Высоцкий", "phoneNumber": "+7 (962) 568-85-39" }, "bidPoints": [ { "id": 0, "order": 0, "type": "LoadPoint", "planEnterDate": "2026-07-13T13:55", "counterpartyId": 129647035, "comment": "Произвольный комментарий к точке загрузки", "geozone": { "id": 0, "location": { "type": "Point", "coordinates": [ 44.697292211870554, 43.03449472631854 ] }, "address": "Россия, Республика Северная Осетия — Алания, Владикавказ, Пушкинская улица, 58А", "geocoderSourceType": "Yandex", "city": "Владикавказ", "state": "Республика Северная Осетия — Алания", "county": "городской округ Владикавказ", "street": "Пушкинская улица", "houseNumber": "58А", "federalDistrict": "Северо-Кавказский федеральный округ", "radius": null, "coordinates": null, "type": "BidPoint" }, "contactPerson": { "phoneNumber": "+7 964 781-40-98", "name": "Александр Пушкин" }, "loadOptions": [ { "id": 4612889 }, { "id": 4612891 }, { "id": 4675966 } ], "extendedProperties": [] }, { "id": 0, "order": 1, "type": "UnloadPoint", "planEnterDate": "2026-07-15T00:00", "counterpartyId": 5225295, "comment": "Произвольный комментарий к точке выгрузки", "geozone": { "id": 0, "location": { "type": "Point", "coordinates": [ 52.224350311291346, 52.80040289067903 ] }, "address": "Россия, Оренбургская область, Бузулук, улица Гая, 69", "geocoderSourceType": "Yandex", "city": "Бузулук", "state": "Оренбургская область", "county": "городской округ Бузулук", "street": "улица Гая", "houseNumber": "69", "federalDistrict": "Приволжский федеральный округ", "radius": null, "coordinates": null, "type": "BidPoint" }, "contactPerson": { "phoneNumber": "8 914 781 07 01", "name": "Михаил Лермонтов" }, "loadOptions": [ { "id": 4612890 } ], "extendedProperties": [] } ], "cargos": [ { "id": 0, "name": "Кирпичи", "typeId": 713, "comment": "Произвольный комментарий к грузу", "packType": "паллеты", "volume": 18, "length": 82, "width": 13, "height": 8, "extendedProperties": [] } ], "extendedProperties": [ { "propertyName": "CustomeFieldForDemo", "value": "Пример заполнения кастомного поля" } ], "typeOptions": [], "documents": [] } ] } ``` При ошибках валидации возвращается HTTP 4xx и текстовое описание ошибки. --- ## 2. Получение списков заказов ### 2.1. Список заказов для внешних сервисов ```http GET /api/distributionbids/getlistforexternal ``` ### Назначение Получение списка заказов по фильтру для внешних сервисов с более подробной информацией. Поддерживается формат OData. ### Параметры - `$filter` — фильтр по полям `DistributionBidForExternalSyncModel`; - `$orderBy` — сортировка; - `$top` — ограничение количества; - `$skip` — смещение; - `$count` — запрос количества записей; - `$select` — выбор отдельных полей, если поддерживается в подключении; - `$expand` — раскрытие связанных сущностей, если поддерживается в подключении. Ответ — массив `DistributionBidForExternalSyncModel`. ### Основные поля ответа `DistributionBidForExternalSyncModel` Метод возвращает массив заказов на распределение. Общее количество записей передается в заголовке `X-MetaCount`. | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID заказа | | `bidId` | `long?` | ID заявки, созданной на основании заказа; `null`, если заказ не распределен | | `status` | `DistributionBidStatus` | Внутренний статус заказа | | `counterpartyId` | `long?` | ID контрагента | | `counterparty` | `CounterpartyViewModel?` | Контрагент | | `contractId` | `long?` | ID договора контрагента | | `contactPersonId` | `long?` | ID контактного лица | | `contactPerson` | `ContactPersonViewModel?` | Контактное лицо | | `createdAt` | `date-time` | Дата создания | | `updatedAt` | `date-time` | Дата последнего изменения | | `createdById` | `long` | ID создателя | | `createdBy` | `ShortNameModel?` | Пользователь, создавший заказ | | `paymentTypeId` | `long?` | Тип оплаты | | `ndsTypeId` | `long?` | Тип НДС | | `hourlyPrice` | `double?` | Почасовая ставка | | `price` | `double?` | Стоимость | | `priceWithoutVatOnTop` | `double?` | Стоимость без НДС, если НДС сверху | | `isVatTop` | `boolean?` | НДС начисляется сверху | | `externalId` | `string?` | Внешний ID | | `contractNumber` | `string?` | Номер договора | | `comment` | `string?` | Комментарий | | `clientBidNumber` | `string?` | Номер заявки клиента | | `clientBidDate` | `date-time?` | Дата заявки клиента | | `sourceType` | `SourceType` | Источник заказа | | `paymentPeriodInDays` | `int?` | Срок оплаты в днях | | `paymentPeriodType` | `PaymentPeriodType?` | Вариант срока оплаты | | `invoiceTriggerType` | `InvoiceTriggerType?` | Основание для выставления счета | | `documents` | `RelatedDocumentModel[]?` | Документы | | `hasHiredCar` | `boolean` | Используется наемный транспорт | | `hiredCarCounterpartyId` | `long?` | ID перевозчика наемного транспорта | | `hiredCarId` | `long?` | ID наемного транспорта | | `hiredTrailerId` | `long?` | ID прицепа наемного транспорта | | `hiredDriverId` | `long?` | ID водителя наемного транспорта | | `hiredCarPrice` | `double?` | Стоимость наемного транспорта | | `isHiredCarVatTop` | `boolean` | НДС сверху по наемному транспорту | | `hiredCarNdsTypeId` | `long?` | Тип НДС наемного транспорта | | `hiredCarPaymentTypeId` | `long?` | Тип оплаты перевозчику | | `hiredCarPaymentPeriodInDays` | `int?` | Срок оплаты перевозчику | | `hiredCarCompletedAtOffset` | `date-time?` | Ручная дата выполнения со смещением часового пояса | | `hiredCarCompletedAt` | `date-time?` | Ручная дата выполнения | | `lastSyncStatus` | `SyncEntityStatus` | Последний статус синхронизации | | `legalPersonId` | `long?` | ID юридического лица | | `isMandatory` | `boolean` | Обязательный заказ | | `isDeleted` | `boolean` | Заказ удален | | `createDocumentAssignment` | `boolean` | Создавать задание сдачи документов после завершения | | `extendedProperties` | `ExtendedPropertyJsonObject[]?` | Дополнительные поля | | `hiredCarCounterparty` | `CounterpartyViewModel?` | Перевозчик наемного транспорта | | `hiredCar` | `HiredVehicleViewModel?` | Наемный транспорт | | `hiredTrailer` | `HiredVehicleViewModel?` | Прицеп наемного транспорта | | `hiredDriver` | `HiredDriverViewModel?` | Водитель наемного транспорта | | `cargos` | `CargoModel[]?` | Грузы | | `bidPoints` | `DistributionBidPointViewModel[]?` | Точки заказа | | `typeOptions` | `TypeOptionModel[]?` | Пользовательские справочники и настраиваемые опции | | `hasUploadedFile` | `boolean` | Загружен файл заказа | | `isPreBid` | `boolean` | Предзаявка | | `accessPermitIds` | `long[]?` | Допуски и разрешения | ### Поля `extendedProperties[]` `extendedProperties` содержит пользовательские дополнительные поля заказа. | Поле | Тип | Описание | |---|---|---| | `propertyName` | `string` | Имя пользовательского поля | | `value` | `string?` | Значение, заданное пользователем | ### Поля `typeOptions[]` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID элемента пользовательского справочника | | `entityOptionId` | `long` | ID настройки/свойства справочника | Чтобы получить значение элемента, запросите `GET /api/Catalogs/GetItems?$filter=id eq {typeOptions[].id}`. Подробнее: [Пользовательские справочники](./custom-catalogs.md). --- ### 2.2. Получение статусов внешних заказов ```http GET /api/distributionbids/getlistforexternalstatuses ``` ### Назначение Получение заказов по идентификаторам с информацией о статусах (для сценариев экспедиции). ### Параметры - `Ids` — массив идентификаторов заказов; - `$filter`, `$orderBy`, `$top`, `$skip`, `$count`, `$select`, `$expand` — как в методе `getlist`. Ответ — массив `ExternalDistributionBidStatusModel`. --- ## 3. Получение одного заказа ### 3.1. Получение заказа по идентификатору ```http GET /api/distributionbids/get/{id} ``` ### Параметры - `id` — идентификатор заказа (path-параметр). Ответ — `DistributionBidViewModel`. --- ### 3.2. Получение заказа по заявке ```http GET /api/distributionbids/getforbid/{id} ``` ### Параметры - `id` — идентификатор заявки. Ответ — модель заказа, связанного с указанной заявкой. --- ## 4. Управление жизненным циклом заказа ### 4.1. Отмена заказа ```http POST /api/distributionbids/cancel ``` ### Тело запроса ```json { "id": 0, "comment": "Причина отмены" } ``` | Поле | Тип | Обязательность | Описание | |---|---|---|---| | `id` | `long` | Да | ID заказа на распределение | | `comment` | `string?` | Нет | Комментарий или причина отмены, если используется в подключении | --- ### 4.2. Удаление заказа ```http POST /api/distributionbids/delete ``` ### Назначение Удаление заказа, если по нему не создана заявка. ### Тело запроса ```json { // DistributionBidDeleteModel } ``` --- ### 4.3. Восстановление удалённого заказа ```http POST /api/distributionbids/restore ``` ### Тело запроса ```json { // DistributionBidRestoreModel } ``` --- ### 4.4. Возврат отменённого заказа ```http POST /api/distributionbids/revert ``` ### Назначение Возвращает отменённый заказ в исходный статус («Без заявки»). ### Тело запроса ```json { // DistributionBidRevertModel } ``` --- ## 5. Сводная таблица методов | Метод | Описание | |-------|----------| | `POST /api/DistributionBids/Apply` | Создание и обновление заказов на распределение | | `GET /api/DistributionBids/GetListForExternal` | Список заказов для внешней синхронизации | | `GET /api/DistributionBids/GetListForExternalStatuses` | Получение статусов внешних заказов | | `GET /api/DistributionBids/Get/{id}` | Получение одного заказа по ID | | `GET /api/DistributionBids/GetForBid/{id}` | Получение заказа по ID заявки | | `POST /api/DistributionBids/Cancel` | Отмена заказа | | `POST /api/DistributionBids/Delete` | Удаление заказа | | `POST /api/DistributionBids/Restore` | Восстановление удаленного заказа | | `POST /api/DistributionBids/Revert` | Возврат отмененного заказа | --- Source: products/cargorun-logistics/api/counterparties.md # Контрагенты API Раздел описывает работу с контрагентами CARGO.RUN Логистика: создание, удаление, получение списка и одного элемента, а также работу с договорами и адресами/точками контрагента. Контрагенты используются в заявках и заказах через поля `counterpartyId`, `cargoOwnerDictionaryItemId`, `contractId` и связанные адресные точки. --- ## 1. Контрагенты ### 1.1. Создание или обновление контрагента ```http POST /api/CargoOwnerDictionary/Apply ``` Метод создает нового контрагента или обновляет существующего. Если `id = 0`, создается новый контрагент. Если `id` содержит ID существующего контрагента, метод обновляет его данные. #### Основные поля запроса `CounterpartyEditModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | `0` для создания, ID контрагента для обновления | | `name` | `string?` | Наименование | | `inn` | `string?` | ИНН | | `kpp` | `string?` | КПП | | `ogrn` | `string?` | ОГРН | | `address` | `string?` | Юридический адрес полностью | | `city`, `street`, `houseNumber` | `string?` | Части юридического адреса | | `mailingAddress` | `string?` | Почтовый адрес | | `settlementAccount` | `string?` | Расчетный счет | | `correspondentAccount` | `string?` | Корреспондентский счет | | `bankName` | `string?` | Название банка | | `bankId` | `string?` | БИК | | `counterpartyGroupId` | `long?` | ID группы контрагентов | | `comment` | `string?` | Комментарий | | `management` | `Management?` | Руководитель | | `contactPerson` | `CounterpartyContactPersonModel?` | Контактное лицо | | `documents` | `CounterpartyDocumentModel[]?` | Документы | | `platforms` | `CounterpartyPlatformModel[]?` | Площадки/платформы | | `noteForDrivers` | `string?` | Примечание для водителей | | `analyzeStrictOffsetHours` | `int?` | Смещение для учета посещений точки | | `status` | `CounterpartyStatus?` | Статус контрагента | | `isInsolvent` | `boolean` | Контрагент неплатежеспособен | | `insolvencyComment` | `string?` | Комментарий о неплатежеспособности | #### Пример ```json { "id": 0, "name": "ООО \"ЦИФРОВИЗАЦИЯ ТРАНСПОРТА\"", "inn": "1650379003", "kpp": "165001001", "status": "Priority", "analyzeStrictOffsetHours": 48, "comment": "Произвольный комментарий по контрагенту", "noteForDrivers": "Произвольное примечание по контрагенту, которое отображается водителям", "management": {}, "platforms": [ { "name": "Атракс", "url": "https://www.atrucks.su/", "representativeFullName": "Иван Цыплаков", "representativeEmail": "example@example.com", "representativePhoneNumber": "+74343434344", "paymentTypeId": 41, "paymentPeriodType": "InCalendarDays", "paymentMethodType": "ByUnloading" } ], "manual": true } ``` ### 1.2. Получение списка контрагентов ```http GET /api/CargoOwnerDictionary/Get ``` Метод возвращает список контрагентов в OData-формате. Общее количество записей приходит в заголовке `X-MetaCount`. #### Query-параметры | Параметр | Описание | |---|---| | `withDeleted` | Включить удаленных контрагентов | | `onlyInsolvent` | Вернуть только неплатежеспособных контрагентов | | `$filter` | Фильтр по полям модели, например `Id eq 1` | | `$orderby` | Сортировка, например `CreatedAt desc` | | `$top` | Количество записей | | `$skip` | Смещение | | `$count` | Запросить количество записей | #### Основные поля ответа `CounterpartyListModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID контрагента | | `name` | `string?` | Наименование | | `inn` | `string?` | ИНН | | `kpp` | `string?` | КПП | | `email` | `string?` | Email организации | | `hasAccess` | `boolean` | Есть доступ к просмотру заявок | | `linkedOrganizationId` | `long?` | ID прикрепленной организации | | `comment` | `string?` | Комментарий | | `status` | `CounterpartyStatus` | Статус контрагента | | `insolvencyRegistryEntry` | `InsolvencyRegistryEntryGetModel?` | Данные из реестра неплатежеспособности | | `counterpartyGroupId` | `long?` | ID группы контрагента | | `counterpartyGroupName` | `string?` | Название группы контрагента | | `documents` | `CounterpartyDocumentModel[]?` | Документы | | `points` | `CounterpartyPointModel[]?` | Точки/адреса контрагента | | `isDeleted` | `boolean` | Контрагент удален | ### 1.3. Получение одного контрагента ```http GET /api/CargoOwnerDictionary/Get({id}) ``` Метод возвращает карточку контрагента по ID. #### Параметры | Параметр | Тип | Описание | |---|---|---| | `id` | `long` | ID контрагента в path | #### Основные поля ответа `CounterpartyModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID контрагента | | `isDeleted` | `boolean` | Контрагент удален | | `name`, `inn`, `kpp`, `ogrn` | `string?` | Реквизиты контрагента | | `address`, `mailingAddress` | `string?` | Юридический и почтовый адрес | | `city`, `street`, `houseNumber` | `string?` | Части адреса | | `email` | `string?` | Email организации | | `management` | `Management?` | Руководитель | | `bankName`, `bankId` | `string?` | Банк и БИК | | `settlementAccount`, `correspondentAccount` | `string?` | Расчетный и корреспондентский счет | | `regionId` | `long?` | ID региона | | `flags` | `CounterpartyFlag` | Флаги контрагента | | `type` | `CounterpartyType` | Тип контрагента | | `contactPerson` | `CounterpartyContactPersonModel?` | Контактное лицо | | `hasAccess` | `boolean` | Есть доступ к просмотру заявок | | `linkedOrganizationId` | `long?` | ID прикрепленной организации | | `comment` | `string?` | Комментарий | | `noteForDrivers` | `string?` | Примечание для водителей | | `status` | `CounterpartyStatus` | Статус | | `isInsolvent` | `boolean` | Контрагент неплатежеспособен | | `insolvencyComment` | `string?` | Комментарий о неплатежеспособности | | `counterpartyGroupId`, `counterpartyGroupName` | `long?`, `string?` | Группа контрагента | | `documents` | `CounterpartyDocumentModel[]?` | Документы | | `points` | `CounterpartyPointModel[]?` | Точки/адреса | | `platforms` | `CounterpartyPlatformModel[]?` | Площадки | | `documentTemplates` | `CounterpartyDocumentTemplateModel[]?` | Шаблоны документов | ### 1.4. Удаление контрагента ```http POST /api/CargoOwnerDictionary/Delete ``` Метод удаляет контрагента, если это не запрещено бизнес-правилами. #### Тело запроса `CounterpartyDeleteModel` ```json { "id": 57398 } ``` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID контрагента | --- ## 2. Договоры контрагентов Договоры привязаны к контрагенту и используются в заявках/заказах через `contractId`. ### 2.1. Создание или обновление договора ```http POST /api/CargoOwnerDictionary/ApplyContract ``` Если `id = 0`, создается новый договор. Если `id` содержит ID договора, метод обновляет существующий договор. #### Поля запроса `CounterpartyContractEditModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | `0` для создания, ID договора для обновления | | `counterpartyId` | `long` | ID контрагента | | `legalPersonId` | `long` | ID организации/юридического лица | | `name` | `string?` | Название договора | | `number` | `string?` | Номер договора | | `date` | `date` | Дата договора | | `settlementCurrency` | `string?` | Валюта взаиморасчетов | | `billingOptionId` | `long?` | Вариант выставления счета | | `invoiceTriggerType` | `InvoiceTriggerType?` | Основание для выставления счета | | `paymentPeriod` | `int?` | Срок оплаты | | `paymentTypeId` | `long?` | Тип оплаты | | `paymentPeriodType` | `PaymentPeriodType?` | Вариант срока оплаты | | `debtCeiling` | `double?` | Лимит задолженности | | `currentDebt` | `double?` | Текущая задолженность | | `isMain` | `boolean?` | Основной договор | #### Пример ```json { "id": 0, "counterpartyId": 129762942, "name": "999999 от 08.07.2026", "isMain": true, "legalPersonId": 127039078, "number": "999999", "date": "2026-07-08", "invoiceTriggerType": "ByOriginal", "settlementCurrency": "Руб", "paymentPeriod": 30, "paymentPeriodType": "InCalendarDays", "paymentTypeId": 41, "debtCeiling": 123000, "currentDebt": 5000 } ``` ### 2.2. Получение списка договоров ```http GET /api/CargoOwnerDictionary/GetContracts?counterpartyId={counterparty_id} ``` Метод возвращает список договоров контрагента в OData-формате. #### Query-параметры | Параметр | Описание | |---|---| | `counterpartyId` | ID контрагента | | `$filter` | Фильтр по полям модели | | `$orderby` | Сортировка | | `$top` | Количество записей | | `$skip` | Смещение | | `$count` | Запросить количество записей | ### 2.3. Получение одного договора ```http GET /api/CargoOwnerDictionary/GetContract?counterpartyId={counterparty_id}&contractId={contract_id} ``` #### Параметры | Параметр | Тип | Описание | |---|---|---| | `counterpartyId` | `long` | ID контрагента | | `contractId` | `long` | ID договора | #### Поля ответа `CounterpartyContractModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID договора | | `name` | `string?` | Название договора | | `number` | `string?` | Номер договора | | `date` | `date` | Дата договора | | `settlementCurrency` | `string?` | Валюта взаиморасчетов | | `billingOptionId` | `long?` | Вариант выставления счета | | `invoiceTriggerType` | `InvoiceTriggerType?` | Основание для выставления счета | | `legalPersonId` | `long?` | ID организации/юридического лица | | `legalPersonName` | `string?` | Название организации/юридического лица | | `paymentPeriod` | `int?` | Срок оплаты | | `paymentPeriodType` | `PaymentPeriodType?` | Вариант срока оплаты | | `paymentTypeId` | `long?` | Тип оплаты | | `debtCeiling` | `double?` | Лимит задолженности | | `currentDebt` | `double?` | Текущая задолженность | | `isMain` | `boolean` | Основной договор | ### 2.4. Удаление договора ```http POST /api/CargoOwnerDictionary/DeleteContract ``` #### Тело запроса `CounterpartyContractDeleteModel` ```json { "id": 100500, "counterpartyId": 57398 } ``` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID договора | | `counterpartyId` | `long` | ID контрагента | --- ## 3. Адреса и точки контрагентов Точки контрагента используются для сохранения часто используемых адресов погрузки, выгрузки или складов. ### 3.1. Создание или обновление точки ```http POST /api/CargoOwnerDictionary/ApplyCounterpartyPoint ``` #### Поля запроса `CounterpartyPointEditModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | `0` для создания, ID точки для обновления | | `counterpartyId` | `long` | ID контрагента | | `organizationId` | `long` | ID организации | | `name` | `string?` | Наименование точки | | `client` | `string?` | Клиент | | `geozone` | `MapObjectEditModel` | Геоданные точки | | `lastUsedAt` | `date-time` | Дата последнего использования | #### Основные поля `geozone` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID геообъекта | | `location` | `PointEditModel` | Координаты | | `address` | `string?` | Полный адрес | | `city`, `village`, `state`, `county`, `street`, `houseNumber` | `string?` | Компоненты адреса | | `federalDistrict` | `string?` | Федеральный округ | | `coordinates` | `array?` | Координаты полигона | | `radius` | `double?` | Радиус | | `type` | `MapObjectType` | Тип точки | #### Пример ```json { "id": 0, "counterpartyId": 129647035, "name": "Филиал IV", "geozone": { "location": { "type": "Point", "coordinates": [ 47.28185386175986, 56.06857967426879 ] }, "address": "Россия, Чувашская Республика — Чувашия, Чебоксары, микрорайон Альгешево, улица Розы Люксембург, 2", "geocoderSourceType": "Yandex", "city": "Чебоксары", "state": "Чувашская Республика — Чувашия", "county": "городской округ Чебоксары", "street": "улица Розы Люксембург", "houseNumber": "2", "federalDistrict": "Приволжский федеральный округ", "radius": 500, "coordinates": null, "type": "CounterpartyPoint" } } ``` ### 3.2. Получение списка точек ```http GET /api/CargoOwnerDictionary/GetCounterpartyPoints?counterpartyId={counterparty_id} ``` Метод возвращает список точек контрагента в OData-формате. ### 3.3. Получение одной точки ```http GET /api/CargoOwnerDictionary/GetCounterpartyPoint/{id} ``` #### Поля ответа `CounterpartyPointModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID точки | | `counterpartyId` | `long` | ID контрагента | | `name` | `string?` | Наименование | | `client` | `string?` | Клиент | | `geozone` | `MapObjectModel` | Геоданные точки | | `lastUsedAt` | `date-time` | Дата последнего использования | ### 3.4. Удаление точки ```http POST /api/CargoOwnerDictionary/DeleteCounterpartyPoint ``` #### Тело запроса `CounterpartyPointDeleteModel` ```json { "id": 2435200 } ``` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID точки контрагента | ### 3.5. Восстановление точки ```http POST /api/CargoOwnerDictionary/RestoreCounterpartyPoint ``` Метод восстанавливает ранее удаленную точку контрагента. --- Source: products/cargorun-logistics/api/directories.md # Справочники API CARGO.RUN Этот раздел описывает методы работы со справочниками, которые участвуют в интеграции: - водители; - автомобили; - прицепы; - организации; - общие каталоги (типы, бренды и др.). Подробные правила синхронизации справочников приведены в документе: - [Синхронизация данных](../integration/sync.md) Здесь описаны именно **методы API** для работы со справочниками. --- ## 1. Общие принципы Для всех справочников используются общие правила: - формат данных — JSON; - авторизация — по токену (см. [Auth API](../api/auth.md)); - операции создания и обновления выполняются по паттерну `Apply`: - `id = 0` — создание; - `id > 0` — обновление; - операции удаления и восстановления выполняются через `POST`-методы (`.../delete`, `.../restore`); - при ошибках валидации возвращается HTTP 4xx и текстовое описание ошибки. Минимальные требования к полям см. в: - [Минимальные требования к запросам](../minimal-requirements.md) --- ## 2. Водители ### 2.1. Создание и обновление водителя ```http POST /api/driver/apply ``` Назначение: - создание нового водителя (`id = 0`); - обновление существующего водителя (`id > 0`). Минимальные обязательные поля и структура объекта описаны в `minimal-requirements.md`. #### Пример создания водителя ```json { "id": 0, "firstName": "Николай", "lastName": "Миклухо-Маклай", "patronymic": "Николаевич", "phoneNumber": "+73222323233", "comment": "Ссылка на яндекс-диск", "needsShiftChangeComment": "Произвольный текст", "needsUrgentShiftChange": true, "accessPermitIds": [ 5, 16 ] } ``` #### Пример обновления паспортных данных и водительского удостоверения Паспортные данные и данные водительского удостоверения передаются в модели водителя. Для обновления существующего водителя укажите его `id`. ```json { "id": 128943713, "passportSeries": "9292", "passportNumber": "122345", "passportGivenBy": "Электротехническим ОВД г. Кукуево", "passportGivenWhen": "2026-07-09", "departmentCode": "178-787", "driverLicenseSeries": "2323", "driverLicenseNumber": "123213", "driverLicenseGivenWhen": "2026-06-30", "driverLicenseValidUntil": "2026-06-30" } ``` --- ### 2.2. Удаление водителя ```http POST /api/driver/delete ``` Тело запроса содержит идентификатор водителя. Особенности: - водитель не может быть удалён, если участвует в активных или запланированных заявках; - в случае бизнес-ошибки возвращается HTTP 4xx и текстовое пояснение. --- ### 2.3. Восстановление водителя ```http POST /api/driver/restore ``` Используется для восстановления ранее удалённого водителя. --- ### 2.4. Получение списка водителей ```http GET /api/driver/getlist ``` Метод возвращает список водителей с основными атрибутами. Метод поддерживает стандартные параметры списков, если они включены для конкретного подключения: | Параметр | Описание | |---|---| | `$filter` | Фильтр по полям списка водителей | | `$orderby` | Сортировка | | `$top` | Ограничение количества записей | | `$skip` | Смещение | --- ## 3. Автомобили ### 3.1. Создание и обновление автомобиля ```http POST /api/car/apply ``` Назначение: - создание нового автомобиля (`id = 0`); - обновление существующего автомобиля (`id > 0`). Минимальные поля и структура приведены в `minimal-requirements.md`. #### Пример создания автомобиля ```json { "id": 0, "number": "А232ОО/122", "brandTypeId": 2716, "typeId": 164, "logistId": 1466813, "trackerId": 109918, "mechanic": { "name": "Максим Горький", "phoneNumber": "+7 (962) 568-00-89" }, "columnDispatcher": { "name": "Владимир Набоков", "phoneNumber": "+7 (962) 6463232" }, "comment": "Ссылка на яндекс-диск", "needsMaintenanceComment": "Произвольный текст", "needsUrgentMaintenance": true, "isInRefuelingSyncList": true, "accessPermitIds": [ 1, 2 ], "fuelTanks": [ { "minimumVolume": 10, "currentVolume": 0, "totalVolume": 800, "fuelConsumption": 33, "minimumFuelTankVolume": 120, "type": "Diesel" } ] } ``` --- ### 3.2. Удаление автомобиля ```http POST /api/car/delete ``` Особенности: - автомобиль не может быть удалён, если используется в активных заявках; - при попытке удалить такой автомобиль API вернёт ошибку с пояснением. --- ### 3.3. Получение списка автомобилей ```http GET /api/car/getlist ``` Возвращает список автомобилей. --- ### 3.4. Получение автомобиля для редактирования ```http GET /api/car/getforedit ``` Метод возвращает подробные данные по одному автомобилю для редактирования. --- ## 4. Прицепы ### 4.1. Создание и обновление прицепа ```http POST /api/trailer/apply ``` По паттерну `Apply`: - `id = 0` — создание прицепа; - `id > 0` — обновление. #### Пример создания прицепа ```json { "id": 0, "number": "КК2323/232", "brandTypeId": 2720, "typeId": 15470, "loadUnloadOptions": [ { "id": 4612889 }, { "id": 4612891 }, { "id": 4612890 } ], "mechanic": { "name": "Максим Горький", "phoneNumber": "+7 (927) 200-66-00" }, "comment": "Ссылка на яндекс-диск", "trackerId": 4137, "isInRefuelingSyncList": true, "accessPermitIds": [ 4, 7 ], "fuelTanks": [ { "minimumVolume": 0, "currentVolume": 0, "totalVolume": 120, "fuelConsumption": 33, "minimumFuelTankVolume": 120, "type": "Diesel" } ] } ``` --- ### 4.2. Удаление прицепа ```http POST /api/trailer/delete ``` Удаление возможно только при отсутствии использования в активных заявках. При нарушении этого ограничения возвращается бизнес-ошибка. --- ### 4.3. Получение списка прицепов ```http GET /api/trailer/getlist ``` Возвращает список прицепов. --- ## 5. Контрагенты, договоры и адреса Контрагенты вынесены в отдельный раздел, потому что кроме самой карточки контрагента там описаны договоры и адреса/точки контрагентов. - [Контрагенты API](./counterparties.md) --- ## 6. Организации ### 6.1. Создание и обновление организации ```http POST /api/legalpersons/apply ``` Применяется для создания/обновления юридических лиц, используемых в CARGO.RUN. --- ### 6.2. Удаление организации ```http POST /api/legalpersons/delete ``` Удаление ограничено бизнес-правилами (нельзя удалить организацию, которая используется в действующих данных). --- ### 6.3. Получение списка организаций ```http GET /api/legalpersons/getlist ``` Возвращает список юридических лиц. --- ## 7. Общие каталоги (типы, бренды и др.) Для получения различных типовых справочников (типы машин, типы прицепов, типы груза, бренды и пр.) используется единый метод: ```http GET /api/catalogs/getSimple ``` Список общих справочников со значениями можно получить так: ```http GET /api/catalogs/getSimple?$filter=externalId eq null&$orderby=id desc ``` В URL пробелы кодируются как `%20`: ```http https://app.cargorun.ru/api/catalogs/getSimple?$filter=externalId%20eq%20null&$orderby=id%20desc ``` `externalId eq null` возвращает общие справочники CARGO.RUN, а `$orderby=id desc` сортирует их по ID в обратном порядке. Набор доступных каталогов зависит от подключения клиента. Минимальный набор параметров: | Параметр | Описание | |---|---| | `$filter` | Фильтр по элементам каталога | | `$orderby` | Сортировка | | `$top` | Ограничение количества записей | | `$skip` | Смещение | Примеры каталогов: - типы оплаты; - типы НДС; - типы машин; - типы прицепов; - бренды машин; - бренды прицепов; - типы грузов. ### Пример ответа Ниже показан сокращенный пример ответа: в реальном ответе может быть больше справочников и больше элементов внутри каждого справочника. ```json [ { "id": 30, "displayName": "НДС", "propertyName": "NDSType", "type": "NDSType", "externalId": null, "items": [ { "id": 38, "displayName": "Без НДС", "propertyName": "Without", "isDeleted": false, "isHidden": false }, { "id": 39, "displayName": "10%", "propertyName": "10%", "isDeleted": false, "isHidden": false }, { "id": 40, "displayName": "20%", "propertyName": "20%", "isDeleted": false, "isHidden": false } ] }, { "id": 25, "displayName": "Типы прицепов/полуприцепов", "propertyName": "TrailerType", "type": "TrailerType", "externalId": null, "items": [ { "id": 44, "displayName": "Бензовоз", "propertyName": "Gasoline", "isDeleted": false, "isHidden": false }, { "id": 45, "displayName": "Автоцистерна", "propertyName": "Tank", "isDeleted": false, "isHidden": false }, { "id": 46, "displayName": "Цементовоз", "propertyName": "Cement", "isDeleted": false, "isHidden": false } ] }, { "id": 31, "displayName": "Тип оплаты", "propertyName": "PaymentType", "type": "PaymentType", "externalId": null, "items": [ { "id": 41, "displayName": "Безналичный", "propertyName": "NonCash", "isDeleted": false, "isHidden": false }, { "id": 42, "displayName": "Наличный", "propertyName": "Cash", "isDeleted": false, "isHidden": false }, { "id": 88752941, "displayName": "Платежная карта", "propertyName": "Платежная карта", "isDeleted": false, "isHidden": false } ] } ] ``` Использование этих каталогов описано в: - [Минимальные требования к запросам](../minimal-requirements.md) - [Синхронизация данных](../integration/sync.md) - [Пользовательские справочники](./custom-catalogs.md) --- Source: products/cargorun-logistics/api/custom-catalogs.md # Пользовательские справочники API Пользовательские, или кастомные, справочники — это несистемные справочники, которые клиент создает в своем аккаунте CARGO.RUN. Они используются только внутри организации клиента и могут быть привязаны к заявкам или заказам. В выгрузке заявок и заказов такие значения приходят в массиве `typeOptions`. --- ## 1. Как связаны `typeOptions` и справочники В методах: ```http GET /api/bids/GetListForExternal GET /api/DistributionBids/GetListForExternal ``` может приходить массив: ```json { "typeOptions": [ { "id": 129619121, "entityOptionId": 126364242 } ] } ``` Поля `TypeOptionModel`: | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID элемента справочника | | `entityOptionId` | `long` | ID настройки/свойства справочника, к которому относится значение | Чтобы получить текстовое значение элемента справочника, используйте `id` из `typeOptions[]` и запросите элемент через `GET /api/Catalogs/GetItems`. ```http GET /api/Catalogs/GetItems?$filter=id eq 129619121 ``` В ответе будет элемент справочника, где значение лежит в `displayName`. --- ## 2. Получение списка справочников ```http GET /api/Catalogs/GetCatalogs ``` Метод возвращает список доступных справочников, включая пользовательские справочники организации. Поддерживает OData-фильтры и пагинацию. ### Query-параметры | Параметр | Описание | |---|---| | `$filter` | Фильтр по полям модели | | `$orderby` | Сортировка | | `$top` | Количество записей | | `$skip` | Смещение | | `$count` | Запросить количество | ### Основные поля `CatalogListModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID справочника | | `displayName` | `string?` | Название справочника | | `propertyName` | `string?` | Системное имя свойства | | `type` | `CatalogType?` | Тип справочника | | `entityType` | `EntityType?` | Тип сущности, к которой относится справочник | | `entityOptions` | `CatalogEntityOptionModel[]?` | Настройки привязки к сущностям | | `flags` | `CatalogFlag` | Флаги справочника | | `intFlags` | `int` | Числовое представление флагов | | `organizationId` | `long?` | ID организации, если справочник пользовательский | | `description` | `string?` | Описание | | `externalId` | `string?` | Внешний ID | | `version` | `uuid?` | Версия справочника | --- ## 3. Получение элементов справочника ```http GET /api/Catalogs/GetItems ``` Метод возвращает элементы справочников. Для получения одного значения из `typeOptions[]` фильтруйте по `id` элемента. ### Пример получения значения по ID элемента ```http GET /api/Catalogs/GetItems?$filter=id eq 129619121 ``` ### Пример получения элементов конкретного справочника Если во внешней системе хранится ID справочника, можно фильтровать элементы по полям, которые включены в настройки конкретного клиента. Для точного значения из `GetListForExternal` достаточно запроса по `id`. ### Основные поля `CatalogListItemSimpleViewModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID элемента справочника | | `displayName` | `string?` | Значение элемента, которое нужно показывать пользователю | | `propertyName` | `string?` | Системное имя | | `isDeleted` | `boolean` | Элемент удален | | `isHidden` | `boolean` | Элемент скрыт | | `externalId` | `string?` | Внешний ID элемента | --- ## 4. Получение справочников вместе с элементами ```http GET /api/Catalogs/Get GET /api/Catalogs/GetSimple ``` Оба метода возвращают справочники с вложенным массивом `items`. `GetSimple` дополнительно поддерживает параметр: | Параметр | Описание | |---|---| | `showObsolete` | Показывать устаревшие значения | ### Основные поля `CatalogListWithItemsModel` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID справочника | | `displayName` | `string?` | Название справочника | | `propertyName` | `string?` | Системное имя свойства | | `organizationId` | `long?` | ID организации для пользовательского справочника | | `description` | `string?` | Описание | | `externalId` | `string?` | Внешний ID справочника | | `items` | `CatalogListItemSimpleModel[]?` | Элементы справочника | ### Основные поля `items[]` | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID элемента | | `displayName` | `string?` | Значение элемента | | `propertyName` | `string?` | Системное имя | | `isDeleted` | `boolean` | Элемент удален | | `isHidden` | `boolean` | Элемент скрыт | | `options` | `object?` | Дополнительные свойства элемента | | `itemEntityOptions` | `CatalogItemEntityOptionSimpleModel[]?` | Привязки элемента к настройкам сущностей | --- ## 5. Рекомендуемый алгоритм для интеграции 1. Получить заявки или заказы через `GET /api/bids/GetListForExternal` или `GET /api/DistributionBids/GetListForExternal`. 2. В каждом объекте проверить массив `typeOptions`. 3. Для каждого элемента взять `typeOptions[].id`. 4. Получить значение справочника: ```http GET /api/Catalogs/GetItems?$filter=id eq {typeOptions[].id} ``` 5. Использовать `displayName` из ответа как человекочитаемое значение. Пример: ```json { "typeOptions": [ { "id": 129619121, "entityOptionId": 126364242 } ] } ``` Запрос: ```http GET /api/Catalogs/GetItems?$filter=id eq 129619121 ``` Ответ: ```json [ { "id": 129619121, "displayName": "Значение справочника", "propertyName": null, "isDeleted": false, "isHidden": false, "externalId": null } ] ``` --- Source: products/cargorun-logistics/api/etrn.md # Электронные транспортные накладные (ЭТРН) Этот раздел описывает методы API CARGO.RUN для работы с электронными транспортными накладными (ЭТРН) со стороны внешних систем, включая 1С и провайдеров ЭТРН. Общие принципы работы API и авторизации см.: - [Обзор API](./overview.md) - [Auth API](../api/auth.md) --- ## 1. Методы для 1С ### 1.1. Получение списка титулов со статусами ```http GET /api/1c/bills/gettitles ``` #### Назначение Получение списка титулов ЭТРН с их текущими статусами в формате OData. Метод возвращает коллекцию `TitleExternalModel`, в которой для каждого титула указаны: - `id` — идентификатор титула; - `type` — тип титула (`TitleType`); - `status` — статус (`WaybillTitleStatus`); - `statusDate` — дата и время изменения статуса; - `bill` — данные по накладной (`WaybillExternalModel`). [Статусы титулов ЭТРН](../statuses.md) #### Параметры запроса Метод поддерживает стандартные OData-параметры: - `$filter` — фильтр по полям модели `TitleExternalModel`; - `$orderBy` — сортировка; - `$top` — ограничение количества; - `$skip` — смещение; - `$count` — возврат количества записей; - `$select` — выбор полей. Примеры: 1. Получить все титулы в статусе `ReceivedOrCreated`: ```text GET /api/1c/bills/gettitles?$filter=status eq 'ReceivedOrCreated' ``` 2. Получить первые 50 титулов, отсортированных по дате статуса: ```text GET /api/1c/bills/gettitles?$orderby=statusDate desc&$top=50 ``` ### 1.2. Получение титула по заявке ```http GET /api/1c/Bills/GetTitle?titleId={titleId}&bidId={bidId}&bidExternalId={bidExternalId} ``` #### Назначение Получение данных одного титула ЭТРН. Метод может искать титул: - по идентификатору заявки и по идентификатору титула; - по внешнему идентификатору заявки и по идентификатору титула. #### Параметры запроса Метод поддерживает следующие query-параметры: - `titleId` — идентификатор титула (int64); - `bidId` — идентификатор заявки (int64); - `bidExternalId` — внешний идентификатор заявки (string). Ответ — модель `TitleWithRemarksExternalModel`, содержащая: - данные титула; - статус и дату статуса; - комментарии и замечания, если есть. ### 1.3. Смена статуса титула ```http POST /api/1c/bills/applystatus ``` #### Назначение Изменение статуса титула ЭТРН со стороны внешней системы. Метод позволяет: - подтвердить титул; - отклонить титул; - передать новый статус обработки титула в CARGO.RUN. #### Тело запроса Тело описано моделью `TitleStatusApplyExternalModel`: ```json { "id": 0, "status": "Accepted", "bidId": 0, "bidExternalId": "string" } ``` Поля: - `id` — идентификатор титула, обязательное поле; - `status` — новый статус титула, обязательное поле; - `bidId` — идентификатор заявки; - `bidExternalId` — внешний идентификатор заявки. #### Поддерживаемые значения статуса Список статусов задаётся enum `WaybillTitleStatus`: | Значение | Описание | |----------|----------| | `ReceivedOrCreated` | Титул получен или создан системой. | | `Accepted` | Титул принят. | | `Signed` | Титул подписан. | | `Sent` | Титул передан на отправку. | | `Processed` | Титул обработан. | | `Declined` | Титул отклонён. | | `Failed` | При обработке титула возникла ошибка. | --- ## 2. Методы внешней Waybill-интеграции Эти методы используются внешним сервисом ЭТРН для обмена данными с CARGO.RUN. | Метод | Описание | |-------|----------| | `GET /api/waybill/Bids/Get/{bidId}` | Получение данных заявки по идентификатору. | | `GET /api/waybill/Bids/GetLoadPoints` | Получение активных точек загрузки для формирования первого титула. | | `POST /api/waybill/Bids/BatchMarkBidPoints` | Отметка точек заявки как переданных в обработку. | | `POST /api/waybill/Bids/ApplyTitle` | Сохранение титула в заявке. | | `GET /api/waybill/Bids/GetAcceptedTitles` | Получение принятых титулов для последующей генерации QR-кодов. | | `POST /api/waybill/Bids/BatchMarkTitles` | Отметка титулов как переданных в обработку. | | `POST /api/waybill/Bids/ApplyQrCodes` | Сохранение QR-кодов в заявке. | | `GET /api/waybill/Bids/GetTitleSignatures` | Получение электронных подписей титулов. | | `POST /api/waybill/Bids/BatchMarkTitleSignatures` | Отметка подписей как переданных в обработку. | | `GET /api/waybill/Bids/GetPaymentDetailsList` | Получение данных для оплаты. | --- ## 3. Enum'ы ### 3.1. WaybillProviderType Флаговый enum провайдера ЭТРН: | Значение | Код | Описание | |----------|-----|----------| | `ProviderEmulator` | `0` | Эмулятор провайдера. | | `Astral` | `1` | Провайдер Астрал. | | `Kontur` | `2` | Провайдер Контур. | ### 3.2. WaybillTitleStatus | Значение | Код | Описание | |----------|-----|----------| | `ReceivedOrCreated` | `0` | Титул получен или создан системой. | | `Accepted` | `1` | Титул принят. | | `Signed` | `2` | Титул подписан. | | `Sent` | `3` | Титул передан на отправку. | | `Processed` | `4` | Титул обработан. | | `Declined` | `5` | Титул отклонён. | | `Failed` | `6` | При обработке титула возникла ошибка. | ### 3.3. Дополнительные значения | Enum | Значение | Код | |------|----------|-----| | `FeatureModuleType` | `Waybills` | `32` | | `Role` | `WaybillIntegrationAccount` | `180` | | `UserMessageType` | `Waybills` | `80` | | `PushType` | `WaybillQrCodes` | `8` | | `PushTemplateType` | `WaybillQrCodes` | `12` | --- Source: products/cargorun-logistics/api/refueling-transactions.md # Транзакции заправок Метод загрузки транзакций с АЗС для формирования отчёта план‑факт по посещению АЗС и сопоставления с маршрутом. - Запрос может выполняться как с `X-Api-Key`, так и с JWT. - При запросе с `X-Api-Key` без JWT — доступ ко всем транзакциям. - При запросе с JWT — доступ ограничен текущей организацией; чужие трекеры отфильтровываются. --- ## 1. Создание транзакций ```http POST /api/refuelingTransactions/create Content-Type: application/json ``` ### Тело запроса ```json { "transactions": [ { "deviceNumber": "string", "cardNumber": "string", "externalId": "string", "createdAt": "2025-12-01T12:42", "volume": 1.0, "cost": 1.0, "description": "string", "address": "string", "x": 55.23123, "y": 69.42 } ] } ``` ### Обязательность и ограничения полей - Идентификатор: обязателен один из `deviceNumber` или `cardNumber` или `externalId`. Если не указан ни один — элемент пропускается и вернётся в `errors`. - Остальные обязательные поля: `createdAt`, `volume`, `cost`, `address`, `x`, `y`. - `deviceNumber`: max 128 символов. - `cardNumber`: max 128 символов. - `externalId`: max 512 символов. - `createdAt`: не ранее 2023 года, не позже текущее время + 6 часов (UTC). - `address`: max 1024 символа. - `description`: необязательное, max 2048 символов. - `x` (долгота): диапазон [-90, 90], точность до 6 знаков после запятой. - `y` (широта): диапазон [-180, 180], точность до 6 знаков после запятой. - `transactions`: максимум 4096 элементов. ### Идемпотентность и ключи Транзакция определяется одним из ключей (приоритет сверху вниз): 1. `deviceNumber` + `createdAt` 2. `cardNumber` + `createdAt` 3. `externalId` + `createdAt` - Если указаны все три — используется `deviceNumber`, остальные игнорируются. - При наличии записи с тем же ключом данные обновляются, а не дублируются. - Если внутри одного запроса есть несколько элементов с одинаковым ключом, применяется последний по порядку. - Обновление существующих транзакций возможно только для дат не старше четырёх месяцев; более поздние транзакции вернутся с ошибкой. - Если `deviceNumber` или `cardNumber` не существуют в системе, такие транзакции просто игнорируются (не попадут в `errors`). --- ## 2. Ответы сервера - `201` — все транзакции сохранены; тело ответа пустое. - `200` — часть транзакций не принята: ```json { "errors": [ { "message": "Причина, почему не создалась транзакция", "transaction": { } } ] } ``` - `400` или `500` — текстовая ошибка; ни одна транзакция не сохранена. - `401` — не указан `X-Api-Key` и отсутствует валидный токен. - `403` (если нет `X-Api-Key`) — недостаточно прав/нет нужной роли у пользователя. --- ## 3. Назначение и сценарии - Загрузка транзакций с АЗС для отчёта план‑факт по маршруту. - Поля `deviceNumber`/`cardNumber` позволяют связать транзакцию с трекером и топливной картой; `externalId` помогает дедуплицировать данные из внешних систем. - Координаты и адрес используются для сопоставления с плановыми точками заправки на маршруте. --- Source: products/cargorun-logistics/api/trackers.md # Трекеры и привязка к транспортным средствам Этот раздел описывает только те методы работы с трекерами, которые используются во внешней интеграции: - привязка трекера к машине или прицепу; - получение списка трекеров; - отвязка трекера от машины или прицепа. Общие принципы работы API описаны в: - [Обзор API](../api/overview.md) - [Auth API](../api/auth.md) --- ## 1. Привязка трекера к машине или прицепу ```http POST /api/trackers/attach ``` ### Назначение Привязать трекер к конкретному транспортному средству: - грузовому автомобилю; - прицепу. ### Тело запроса ```json { "id": 0, "entityId": 0, "type": "Car" } ``` Поля: - `id` — идентификатор трекера в CARGO.RUN; - `entityId` — идентификатор объекта (машина или прицеп); - `type` — тип объекта: - `Car` — грузовой автомобиль; - `Trailer` — прицеп. ### Комментарии - Для привязки необходимо знать **id трекера** и **id машины/прицепа**. - Идентификатор трекера можно получить через метод `GET /api/trackers/get`, отфильтровав по номеру устройства (`deviceNumber`). Пример (поиск трекера по номеру устройства в OData): ```text GET /api/trackers/get?$filter=deviceNumber eq '1234567890' ``` Из полученного списка выбирается нужный трекер, и его `id` используется в теле запроса `POST /api/trackers/attach`. --- ## 2. Получение списка трекеров ```http GET /api/trackers/get ``` ### Назначение Получение списка трекеров, доступных организации. Метод поддерживает OData-фильтрацию. ### Параметры OData Метод поддерживает стандартные параметры: ```text ?$filter= &$orderBy= &$top= &$skip= &$count= &$select= &$expand= ``` Примеры использования: 1. Поиск трекера по номеру устройства: ```text GET /api/trackers/get?$filter=deviceNumber eq '1234567890' ``` 2. Получение первых 50 трекеров: ```text GET /api/trackers/get?$top=50 ``` ### Основные поля ответа | Поле | Тип | Описание | |---|---|---| | `id` | `long` | ID трекера | | `deviceNumber` | `string?` | Номер устройства / идентификатор трекера | | `entityId` | `long?` | ID машины или прицепа, к которому привязан трекер | | `type` | `string?` | Тип привязанного объекта: `Car` или `Trailer` | | `isDeleted` | `boolean?` | Признак удаления, если поле возвращается в подключении | | `updatedAt` | `date-time?` | Дата последнего изменения, если поле возвращается в подключении | --- ## 3. Отвязка трекера от машины или прицепа ```http POST /api/trackers/attach ``` ### Назначение Отвязать трекер от машины или прицепа. ### Тело запроса ```json { "id": 0, "entityId": null, "type": "Car" } ``` Поля: - `id` — идентификатор трекера; - `entityId` — `null` (означает, что объект отвязывается); - `type` — тип объекта: - `Car` — если трекер был привязан к машине; - `Trailer` — если трекер был привязан к прицепу. ### Комментарии Для отвязки трекера необходимо: - указать корректный `id` трекера; - указать `entityId = null`; - задать `type` в соответствии с тем, к какому типу объекта трекер был привязан (`Car` или `Trailer`). --- ## 4. Сводка используемых методов | Метод | Описание | |-------|----------| | `POST /api/trackers/attach` | Привязка трекера к машине или прицепу | | `GET /api/trackers/get` | Получение списка трекеров (с поддержкой OData) | | `POST /api/trackers/attach` + `entityId = null` | Отвязка трекера от машины или прицепа | --- Source: products/cargorun-logistics/for-ai.md # Для LLM и ИИ-агентов Этот раздел предназначен для ИИ-ассистентов и автономных агентов, которые анализируют интеграцию, генерируют код или выполняют операции через API **CARGO.RUN Логистика**. ## Машиночитаемые материалы - [Краткий индекс `cargorun-logistics-llms.txt`](../../cargorun-logistics-llms.txt) — карта разделов и порядок чтения. - [Полная документация `cargorun-logistics-llms-full.txt`](../../cargorun-logistics-llms-full.txt) — весь раздел одним Markdown-документом. - [Skill `cargorun-logistics`](../../skills/cargorun-logistics/SKILL.md) — готовые правила и сценарии для ИИ-агента. Используйте краткий индекс, если агент может открывать ссылки. Полный файл подходит для базы знаний, RAG-системы или среды без доступа к сайту. ## Приоритет источников Если описания расходятся, агент не должен угадывать контракт. Используйте такой порядок: 1. описание конкретного метода в разделе API; 2. общие форматы, статусы и минимальные требования; 3. интеграционный сценарий; 4. пример payload. Пример не отменяет таблицу полей. Если расхождение влияет на запрос, остановите автоматическое выполнение и запросите подтверждение у владельца интеграции. ## Правила выполнения операций 1. Получите `` и учётные данные из защищённой конфигурации. Не помещайте пароль, access token, refresh token и персональные данные в промпт, журнал или отчёт. 2. Получите токен через `GenerateToken`, затем обновляйте его через `RefreshToken`. Не вызывайте `GenerateToken` перед каждым запросом. 3. Перед созданием заявки сопоставьте справочники и проверьте все `...Id`. 4. Для новой заявки передайте `id = 0`; для обновления — фактический `id` CARGO.RUN. 5. Сохраните связь локального первичного ключа с возвращённым `id` CARGO.RUN, а также значение `updatedAt`. `externalId` не уникален и не подходит как ключ обновления. 6. После создания используйте возвращённый `id` для запуска, отмены или изменения заявки. 7. Считайте операции создания, обновления, смены статуса и удаления изменяющими данные. Перед их выполнением агент должен показать целевой объект и получить разрешение, если такое разрешение не было явно дано в исходной задаче. 8. После изменяющего запроса прочитайте объект повторно и проверьте результат. ## Повторы и ошибки | Результат | Действие агента | |---|---| | `2xx` | Проверить тело ответа и сохранить идентификаторы/курсор синхронизации | | `400` | Не повторять без изменений; разобрать текст или `errorMessage`, исправить payload | | `401` | Обновить токен и повторить один раз | | `403` | Остановиться и сообщить о нехватке прав | | `404` | Проверить ``, регистр пути и ID; не создавать замену автоматически | | `409` | Повторно прочитать объект и разрешить конфликт с участием владельца данных | | `429`, `5xx` | Ограниченные повторы с экспоненциальной задержкой и случайным сдвигом | ## Инкрементальная синхронизация - Для оперативного обмена используйте асинхронную очередь API 2.0 и подтверждайте обработанные версии через `ReadConfirmation`. - Вызывайте чтение API 2.0 чаще одного раза в час: текущее окно изменений намеренно ограничено одним часом, а несколько изменений объекта могут объединяться в последнее. - API 2.0 пока не гарантирует каждую смену статуса и удаление. Получайте заявки через `GET /api/bids/GetListForExternal` порциями по 50 записей для начальной загрузки и контрольной сверки. - Используйте фильтр по `updatedAt` и стабильную сортировку, поддерживаемую методом. - Не продвигайте сохранённую верхнюю границу синхронизации, пока не обработаны все страницы. - Делайте небольшое перекрытие временных окон и устраняйте дубликаты по `id` и `updatedAt`. - Обрабатывайте `isDeleted`: удалённая заявка также является изменением. - Периодически выполняйте контрольную сверку, а не полагайтесь только на последний курсор. Подробный алгоритм: [Синхронизация заявок API 2.0](./integration/async-sync-v2.md). ## Минимальный контекст для агента Перед генерацией или выполнением запроса передайте агенту: - целевой сценарий и допустимые изменяющие операции; - базовый URL среды без секретов; - описание конкретного метода; - таблицы полей и enum, используемых в запросе; - правила форматов и ошибок; - локальные соответствия внешних идентификаторов и ID CARGO.RUN. Не передавайте агенту всю документацию, если достаточно одного метода и связанных моделей.