Warehouse Operations API

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π°Ρ докумСнтация ΠΏΠΎ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΡŽ складскими опСрациями OZON с ΠΏΠΎΠ»Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ TypeScript.

πŸͺ Π‘ΠšΠ›ΠΠ”Π‘ΠšΠžΠ• Π£ΠŸΠ ΠΠ’Π›Π•ΠΠ˜Π• β€” Π”Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎΠ΅ описаниС всСх ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Ρ€Π°Π±ΠΎΡ‚Ρ‹ со складами FBS ΠΈ rFBS.

πŸ“‹ ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ складских ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ

1. getWarehousesList() β€” ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ списка складов

Основной ΠΌΠ΅Ρ‚ΠΎΠ΄ для получСния ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ±ΠΎ всСх складах ΠΏΡ€ΠΎΠ΄Π°Π²Ρ†Π°.

Π—Π°Ρ‡Π΅ΠΌ Π½ΡƒΠΆΠ΅Π½:

  • Π˜Π½Π²Π΅Π½Ρ‚Π°Ρ€ΠΈΠ·Π°Ρ†ΠΈΡ складских рСсурсов: ΠŸΠΎΠ»Π½Ρ‹ΠΉ Π°ΡƒΠ΄ΠΈΡ‚ доступных складских мощностСй
  • ΠŸΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ логистики: Π’Ρ‹Π±ΠΎΡ€ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… складов для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ€Π΅Π³ΠΈΠΎΠ½ΠΎΠ²
  • ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ статусов: ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ работоспособности складских комплСксов
  • Настройка Ρ€Π°Π±ΠΎΡ‚Ρ‹: Анализ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ ΠΈ возмоТностСй ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ склада

TypeScript Interface:

interface WarehouseListRequest {
  readonly [key: string]: unknown;
}

interface WarehouseListResponse {
  /** Бписок складов */
  result?: Warehouse[];
  readonly [key: string]: unknown;
}

interface Warehouse {
  /** Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ‡Π°Ρ‚ΠΈ Π°ΠΊΡ‚Π° ΠΏΡ€ΠΈΡ‘ΠΌΠ°-ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π·Π°Ρ€Π°Π½Π΅Π΅ */
  can_print_act_in_advance?: boolean;
  
  /** ΠŸΠ΅Ρ€Π²Π°Ρ миля FBS */
  first_mile_type?: WarehouseFirstMileType;
  
  /** ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Π΄ΠΎΠ²Π΅Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€ΠΈΡ‘ΠΌΠΊΠΈ */
  has_entrusted_acceptance?: boolean;
  
  /** ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ наличия Π»ΠΈΠΌΠΈΡ‚Π° минимального количСства Π·Π°ΠΊΠ°Π·ΠΎΠ² */
  has_postings_limit?: boolean;
  
  /** `true`, Ссли склад Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с эконом-Ρ‚ΠΎΠ²Π°Ρ€Π°ΠΌΠΈ */
  is_economy?: boolean;
  
  /** ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ, Ρ‡Ρ‚ΠΎ склад Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΈΠ·-Π·Π° ΠΊΠ°Ρ€Π°Π½Ρ‚ΠΈΠ½Π° */
  is_karantin?: boolean;
  
  /** ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ, Ρ‡Ρ‚ΠΎ склад ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΡ€ΡƒΠΏΠ½ΠΎΠ³Π°Π±Π°Ρ€ΠΈΡ‚Π½Ρ‹Π΅ Ρ‚ΠΎΠ²Π°Ρ€Ρ‹ */
  is_kgt?: boolean;
  
  /** ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Ρ€Π°Π±ΠΎΡ‚Ρ‹ склада ΠΏΠΎ схСмС rFBS */
  is_rfbs?: boolean;
  
  /** ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΌΠ΅Π½ΡΡ‚ΡŒ расписаниС Ρ€Π°Π±ΠΎΡ‚Ρ‹ складов */
  is_timetable_editable?: boolean;
  
  /** МинимальноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π»ΠΈΠΌΠΈΡ‚Π° */
  min_postings_limit?: number;
  
  /** ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ Ρ€Π°Π±ΠΎΡ‡ΠΈΡ… Π΄Π½Π΅ΠΉ склада */
  min_working_days?: number;
  
  /** НазваниС склада */
  name?: string;
  
  /** Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π»ΠΈΠΌΠΈΡ‚Π° (-1, Ссли Π»ΠΈΠΌΠΈΡ‚Π° Π½Π΅Ρ‚) */
  postings_limit?: number;
  
  /** 
   * Бтатус склада:
   * - `new` β€” АктивируСтся
   * - `created` β€” Активный
   * - `disabled` β€” Π’ Π°Ρ€Ρ…ΠΈΠ²Π΅
   * - `blocked` β€” Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½
   * - `disabled_due_to_limit` β€” На ΠΏΠ°ΡƒΠ·Π΅
   * - `error` β€” Ошибка
   */
  status?: 'new' | 'created' | 'disabled' | 'blocked' | 'disabled_due_to_limit' | 'error';
  
  /** Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ склада */
  warehouse_id?: number;
  
  /** 
   * Π Π°Π±ΠΎΡ‡ΠΈΠ΅ Π΄Π½ΠΈ склада
   * Π”Π½ΠΈ Π½Π΅Π΄Π΅Π»ΠΈ ΠΎΡ‚ 1 (понСдСльник) Π΄ΠΎ 7 (Π²ΠΎΡΠΊΡ€Π΅ΡΠ΅Π½ΡŒΠ΅)
   */
  working_days?: ('1' | '2' | '3' | '4' | '5' | '6' | '7')[];
  
  readonly [key: string]: unknown;
}

interface WarehouseFirstMileType {
  /** Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ DropOff-Ρ‚ΠΎΡ‡ΠΊΠΈ */
  dropoff_point_id?: string;
  
  /** Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ слота для DropOff */
  dropoff_timeslot_id?: number;
  
  /** ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ, Ρ‡Ρ‚ΠΎ настройки склада ΠΎΠ±Π½ΠΎΠ²Π»ΡΡŽΡ‚ΡΡ */
  first_mile_is_changing?: boolean;
  
  /** 
   * Π’ΠΈΠΏ ΠΏΠ΅Ρ€Π²ΠΎΠΉ ΠΌΠΈΠ»ΠΈ:
   * - `DropOff` β€” доставка Π² Ρ‚ΠΎΡ‡ΠΊΡƒ
   * - `Pickup` β€” самовывоз
   */
  first_mile_type?: 'DropOff' | 'Pickup';
  
  readonly [key: string]: unknown;
}

ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

import { WarehouseApi } from 'daytona-ozon-seller-api';

const warehouseApi = new WarehouseApi(httpClient);

// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ списка складов
const warehouses = await warehouseApi.getWarehousesList();

console.log(`πŸ“¦ НайдСно складов: ${warehouses.result?.length}`);

// Анализ каТдого склада
warehouses.result?.forEach(warehouse => {
  console.log(`\nπŸͺ ${warehouse.name} (ID: ${warehouse.warehouse_id})`);
  
  // Бтатус ΠΈ Ρ‚ΠΈΠΏ склада
  console.log(`   πŸ“Š Бтатус: ${getStatusName(warehouse.status)}`);
  console.log(`   πŸš€ Π’ΠΈΠΏ: ${warehouse.is_rfbs ? 'rFBS (Ρ€Π΅Π³ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ)' : 'FBS (ΠΏΡ€ΠΎΠ΄Π°Π²Ρ†Π°)'}`);
  
  // ВозмоТности склада
  const capabilities = [];
  if (warehouse.is_economy) capabilities.push('Π­ΠΊΠΎΠ½ΠΎΠΌ Ρ‚ΠΎΠ²Π°Ρ€Ρ‹');
  if (warehouse.is_kgt) capabilities.push('ΠšΠ“Π’ Ρ‚ΠΎΠ²Π°Ρ€Ρ‹');
  if (warehouse.is_karantin) capabilities.push('ΠšΠ°Ρ€Π°Π½Ρ‚ΠΈΠ½Π½Ρ‹Π΅ Ρ‚ΠΎΠ²Π°Ρ€Ρ‹');
  if (warehouse.has_entrusted_acceptance) capabilities.push('Π”ΠΎΠ²Π΅Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ ΠΏΡ€ΠΈΠ΅ΠΌΠΊΠ°');
  
  console.log(`   πŸ’Ό ВозмоТности: ${capabilities.join(', ') || 'Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½Ρ‹Π΅'}`);
  
  // Π›ΠΈΠΌΠΈΡ‚Ρ‹ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΉ
  if (warehouse.has_postings_limit) {
    console.log(`   πŸ“¦ Π›ΠΈΠΌΠΈΡ‚ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΉ: ${warehouse.postings_limit} (ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ: ${warehouse.min_postings_limit})`);
  } else {
    console.log(`   πŸ“¦ Π›ΠΈΠΌΠΈΡ‚ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΉ: Π½Π΅ установлСн`);
  }
  
  // Π Π°Π±ΠΎΡ‡Π΅Π΅ расписаниС
  if (warehouse.working_days?.length) {
    const dayNames = ['Пн', 'Π’Ρ‚', 'Π‘Ρ€', 'Π§Ρ‚', 'ΠŸΡ‚', 'Π‘Π±', 'Вс'];
    const workingDayNames = warehouse.working_days.map(day => dayNames[parseInt(day) - 1]);
    console.log(`   πŸ“… Π Π°Π±ΠΎΡ‡ΠΈΠ΅ Π΄Π½ΠΈ: ${workingDayNames.join(', ')}`);
    console.log(`   πŸ“… ΠœΠΈΠ½ΠΈΠΌΡƒΠΌ Π΄Π½Π΅ΠΉ: ${warehouse.min_working_days}`);
  }
  
  // Настройки ΠΏΠ΅Ρ€Π²ΠΎΠΉ ΠΌΠΈΠ»ΠΈ
  if (warehouse.first_mile_type) {
    console.log(`   🚚 ΠŸΠ΅Ρ€Π²Π°Ρ миля: ${warehouse.first_mile_type.first_mile_type}`);
    if (warehouse.first_mile_type.first_mile_is_changing) {
      console.log(`   ⚠️ Настройки ΠΎΠ±Π½ΠΎΠ²Π»ΡΡŽΡ‚ΡΡ`);
    }
    if (warehouse.first_mile_type.dropoff_point_id) {
      console.log(`   πŸ“ DropOff Ρ‚ΠΎΡ‡ΠΊΠ°: ${warehouse.first_mile_type.dropoff_point_id}`);
    }
  }
  
  // Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ возмоТности
  console.log(`   πŸ“‹ ΠŸΠ΅Ρ‡Π°Ρ‚ΡŒ Π°ΠΊΡ‚ΠΎΠ² Π·Π°Ρ€Π°Π½Π΅Π΅: ${warehouse.can_print_act_in_advance ? 'Π”Π°' : 'НСт'}`);
  console.log(`   ⏰ ИзмСнСниС расписания: ${warehouse.is_timetable_editable ? 'Π Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΎ' : 'Π—Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΎ'}`);
});

// Π£Ρ‚ΠΈΠ»ΠΈΡ‚Π° для Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹Ρ… статусов
function getStatusName(status?: string): string {
  const statusMap = {
    'new': 'АктивируСтся ⏳',
    'created': 'Активный βœ…',
    'disabled': 'Π’ Π°Ρ€Ρ…ΠΈΠ²Π΅ πŸ“',
    'blocked': 'Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ 🚫',
    'disabled_due_to_limit': 'На ΠΏΠ°ΡƒΠ·Π΅ ⏸️',
    'error': 'Ошибка ❌'
  };
  return statusMap[status as keyof typeof statusMap] || status || 'НСизвСстно';
}

2. getDeliveryMethods() β€” ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки

ΠœΠ΅Ρ‚ΠΎΠ΄ для получСния всСх доступных ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки для ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ склада с Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ.

Π—Π°Ρ‡Π΅ΠΌ Π½ΡƒΠΆΠ΅Π½:

  • Настройка логистики: Π’Ρ‹Π±ΠΎΡ€ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ склада
  • ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ доступности: ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ активности слуТб доставки
  • Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ SLA: ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ сборки ΠΈ cutoff Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ
  • ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ Π·Π°Ρ‚Ρ€Π°Ρ‚: Анализ доступных поставщиков логистичСских услуг

TypeScript Interface:

interface WarehouseDeliveryMethodListRequest {
  /** 
   * ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ элСмСнтов Π² ΠΎΡ‚Π²Π΅Ρ‚Π΅
   * ΠœΠ°ΠΊΡΠΈΠΌΡƒΠΌ β€” 50, ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ β€” 1
   */
  limit: number;
  
  /** 
   * ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ элСмСнтов, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ Π² ΠΎΡ‚Π²Π΅Ρ‚Π΅
   * Для ΠΏΠ°Π³ΠΈΠ½Π°Ρ†ΠΈΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ²
   */
  offset?: number;
  
  /** Π€ΠΈΠ»ΡŒΡ‚Ρ€ для поиска ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки */
  filter?: DeliveryMethodListRequestFilter;
  
  readonly [key: string]: unknown;
}

interface DeliveryMethodListRequestFilter {
  /** Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ слуТбы доставки */
  provider_id?: number;
  
  /** 
   * Бтатус ΠΌΠ΅Ρ‚ΠΎΠ΄Π° доставки:
   * - `NEW` β€” создан
   * - `EDITED` β€” рСдактируСтся
   * - `ACTIVE` β€” Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ
   * - `DISABLED` β€” Π½Π΅Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ
   */
  status?: 'NEW' | 'EDITED' | 'ACTIVE' | 'DISABLED';
  
  /** 
   * Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ склада
   * МоТно ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ getWarehousesList()
   */
  warehouse_id?: number;
  
  readonly [key: string]: unknown;
}

interface WarehouseDeliveryMethodListResponse {
  /** 
   * ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ, Ρ‡Ρ‚ΠΎ Π² запросС Π²Π΅Ρ€Π½ΡƒΠ»Π°ΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π°ΡΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки
   * - `true` β€” ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ offset для получСния ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²
   * - `false` β€” ΠΎΡ‚Π²Π΅Ρ‚ содСрТит всС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ доставки ΠΏΠΎ запросу
   */
  has_next?: boolean;
  
  /** Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ запроса */
  result?: WarehouseDeliveryMethod[];
  
  readonly [key: string]: unknown;
}

interface WarehouseDeliveryMethod {
  /** Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΡ€ΠΎΠ΄Π°Π²Ρ†Π° */
  company_id?: number;
  
  /** Π”Π°Ρ‚Π° ΠΈ врСмя создания ΠΌΠ΅Ρ‚ΠΎΠ΄Π° доставки */
  created_at?: string;
  
  /** ВрСмя, Π΄ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ΄Π°Π²Ρ†Ρƒ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ Π·Π°ΠΊΠ°Π· */
  cutoff?: string;
  
  /** Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° доставки */
  id?: number;
  
  /** НазваниС ΠΌΠ΅Ρ‚ΠΎΠ΄Π° доставки */
  name?: string;
  
  /** Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ слуТбы доставки */
  provider_id?: number;
  
  /** 
   * МинимальноС врСмя Π½Π° сборку Π·Π°ΠΊΠ°Π·Π° Π² ΠΌΠΈΠ½ΡƒΡ‚Π°Ρ…
   * Π’ соотвСтствии с настройками склада
   */
  sla_cut_in?: number;
  
  /** 
   * Бтатус ΠΌΠ΅Ρ‚ΠΎΠ΄Π° доставки:
   * - `NEW` β€” создан
   * - `EDITED` β€” рСдактируСтся
   * - `ACTIVE` β€” Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ
   * - `DISABLED` β€” Π½Π΅Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ
   */
  status?: 'NEW' | 'EDITED' | 'ACTIVE' | 'DISABLED';
  
  /** Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ услуги ΠΏΠΎ доставкС Π·Π°ΠΊΠ°Π·Π° */
  template_id?: number;
  
  /** Π”Π°Ρ‚Π° ΠΈ врСмя послСднСго обновлСния ΠΌΠ΅Ρ‚ΠΎΠ΄Π° доставки */
  updated_at?: string;
  
  /** Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ склада */
  warehouse_id?: number;
  
  readonly [key: string]: unknown;
}

ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

import { WarehouseApi } from 'daytona-ozon-seller-api';

const warehouseApi = new WarehouseApi(httpClient);

// Π‘Π½Π°Ρ‡Π°Π»Π° ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ список Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… складов
const warehouses = await warehouseApi.getWarehousesList();
const activeWarehouses = warehouses.result?.filter(w => w.status === 'created');

if (activeWarehouses && activeWarehouses.length > 0) {
  const warehouseId = activeWarehouses[0].warehouse_id;
  
  console.log(`🚚 Анализ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки для склада ${warehouseId}`);
  
  // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ всСх ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки с ΠΏΠ°Π³ΠΈΠ½Π°Ρ†ΠΈΠ΅ΠΉ
  let offset = 0;
  const limit = 20;
  let allMethods: WarehouseDeliveryMethod[] = [];
  
  do {
    const deliveryMethods = await warehouseApi.getDeliveryMethods({
      limit,
      offset,
      filter: {
        warehouse_id: warehouseId,
        status: 'ACTIVE' // Волько Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹
      }
    });
    
    if (deliveryMethods.result) {
      allMethods.push(...deliveryMethods.result);
    }
    
    console.log(`   πŸ“¦ Π—Π°Π³Ρ€ΡƒΠΆΠ΅Π½ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²: ${deliveryMethods.result?.length}`);
    console.log(`   πŸ”„ Π•ΡΡ‚ΡŒ Π΅Ρ‰Π΅ Π΄Π°Π½Π½Ρ‹Π΅: ${deliveryMethods.has_next ? 'Π”Π°' : 'НСт'}`);
    
    // ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ страницС
    if (deliveryMethods.has_next) {
      offset += limit;
    } else {
      break;
    }
  } while (true);
  
  console.log(`\nπŸ“Š ВсСго Π½Π°ΠΉΠ΄Π΅Π½ΠΎ Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²: ${allMethods.length}`);
  
  // Анализ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки
  const methodsByProvider = new Map<number, WarehouseDeliveryMethod[]>();
  
  allMethods.forEach(method => {
    console.log(`\nπŸ“¦ ${method.name} (ID: ${method.id})`);
    console.log(`   πŸ“Š Бтатус: ${getMethodStatusName(method.status)}`);
    console.log(`   🏒 ΠŸΠΎΡΡ‚Π°Π²Ρ‰ΠΈΠΊ: ${method.provider_id}`);
    console.log(`   ⏰ Cutoff: ${method.cutoff || 'НС установлСн'}`);
    console.log(`   πŸ• SLA сборки: ${method.sla_cut_in} ΠΌΠΈΠ½ΡƒΡ‚`);
    console.log(`   πŸ“… Π‘ΠΎΠ·Π΄Π°Π½: ${formatDate(method.created_at)}`);
    console.log(`   πŸ”„ ОбновлСн: ${formatDate(method.updated_at)}`);
    
    // Π“Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΏΠΎ поставщикам
    if (method.provider_id) {
      if (!methodsByProvider.has(method.provider_id)) {
        methodsByProvider.set(method.provider_id, []);
      }
      methodsByProvider.get(method.provider_id)?.push(method);
    }
  });
  
  // Анализ ΠΏΠΎ поставщикам
  console.log(`\nπŸ“ˆ Анализ ΠΏΠΎ поставщикам доставки:`);
  methodsByProvider.forEach((methods, providerId) => {
    const avgCutoff = methods
      .filter(m => m.sla_cut_in)
      .reduce((sum, m) => sum + (m.sla_cut_in || 0), 0) / methods.length;
    
    console.log(`   🏒 ΠŸΠΎΡΡ‚Π°Π²Ρ‰ΠΈΠΊ ${providerId}: ${methods.length} ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²`);
    console.log(`   ⏱️ Π‘Ρ€Π΅Π΄Π½Π΅Π΅ SLA: ${Math.round(avgCutoff)} ΠΌΠΈΠ½ΡƒΡ‚`);
  });
  
  // Поиск ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² с быстрой сборкой (ΠΌΠ΅Π½Π΅Π΅ 2 часов)
  const fastMethods = allMethods.filter(m => (m.sla_cut_in || 0) < 120);
  console.log(`\n⚑ БыстрыС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ доставки (< 2 часа): ${fastMethods.length}`);
  
  fastMethods.forEach(method => {
    console.log(`   πŸ“¦ ${method.name}: ${method.sla_cut_in} ΠΌΠΈΠ½ (cutoff: ${method.cutoff})`);
  });
}

// Π£Ρ‚ΠΈΠ»ΠΈΡ‚Ρ‹ для форматирования
function getMethodStatusName(status?: string): string {
  const statusMap = {
    'NEW': 'Π‘ΠΎΠ·Π΄Π°Π½ πŸ†•',
    'EDITED': 'РСдактируСтся ✏️',
    'ACTIVE': 'Активный βœ…',
    'DISABLED': 'НСактивный ❌'
  };
  return statusMap[status as keyof typeof statusMap] || status || 'НСизвСстно';
}

function formatDate(dateStr?: string): string {
  if (!dateStr) return 'НС ΡƒΠΊΠ°Π·Π°Π½ΠΎ';
  return new Date(dateStr).toLocaleString('ru-RU');
}

πŸ”§ Π Π°ΡΡˆΠΈΡ€Π΅Π½Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования

Π‘Ρ†Π΅Π½Π°Ρ€ΠΈΠΉ 1: ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ складской сСти

// ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡΠ½Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ всСх складов ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки
class WarehouseMonitor {
  private warehouseApi: WarehouseApi;
  
  constructor(httpClient: HttpClient) {
    this.warehouseApi = new WarehouseApi(httpClient);
  }
  
  async generateFullReport(): Promise<WarehouseReport> {
    // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ всСх складов
    const warehouses = await this.warehouseApi.getWarehousesList();
    
    if (!warehouses.result) {
      throw new Error('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ список складов');
    }
    
    const report: WarehouseReport = {
      totalWarehouses: warehouses.result.length,
      warehousesByStatus: {},
      warehousesByType: { fbs: 0, rfbs: 0 },
      capabilities: {
        economy: 0,
        kgt: 0,
        karantin: 0,
        entrustedAcceptance: 0
      },
      deliveryMethods: [],
      recommendations: []
    };
    
    // Анализ складов ΠΏΠΎ статусам
    for (const warehouse of warehouses.result) {
      const status = warehouse.status || 'unknown';
      report.warehousesByStatus[status] = (report.warehousesByStatus[status] || 0) + 1;
      
      // Анализ Ρ‚ΠΈΠΏΠΎΠ² складов
      if (warehouse.is_rfbs) {
        report.warehousesByType.rfbs++;
      } else {
        report.warehousesByType.fbs++;
      }
      
      // Анализ возмоТностСй
      if (warehouse.is_economy) report.capabilities.economy++;
      if (warehouse.is_kgt) report.capabilities.kgt++;
      if (warehouse.is_karantin) report.capabilities.karantin++;
      if (warehouse.has_entrusted_acceptance) report.capabilities.entrustedAcceptance++;
      
      // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки для Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… складов
      if (warehouse.status === 'created' && warehouse.warehouse_id) {
        const deliveryMethods = await this.getWarehouseDeliveryMethods(warehouse.warehouse_id);
        report.deliveryMethods.push({
          warehouseId: warehouse.warehouse_id,
          warehouseName: warehouse.name || `Π‘ΠΊΠ»Π°Π΄ ${warehouse.warehouse_id}`,
          methods: deliveryMethods
        });
      }
    }
    
    // ГСнСрация Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΉ
    report.recommendations = this.generateRecommendations(warehouses.result, report);
    
    return report;
  }
  
  private async getWarehouseDeliveryMethods(warehouseId: number): Promise<WarehouseDeliveryMethod[]> {
    const allMethods: WarehouseDeliveryMethod[] = [];
    let offset = 0;
    const limit = 50;
    
    do {
      const response = await this.warehouseApi.getDeliveryMethods({
        limit,
        offset,
        filter: {
          warehouse_id: warehouseId,
          status: 'ACTIVE'
        }
      });
      
      if (response.result) {
        allMethods.push(...response.result);
      }
      
      if (!response.has_next) break;
      offset += limit;
    } while (true);
    
    return allMethods;
  }
  
  private generateRecommendations(warehouses: Warehouse[], report: WarehouseReport): string[] {
    const recommendations: string[] = [];
    
    // Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ статусам складов
    if (report.warehousesByStatus['error'] > 0) {
      recommendations.push(`⚠️ Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ внимания: ${report.warehousesByStatus['error']} склад(ΠΎΠ²) Π² статусС "Ошибка"`);
    }
    
    if (report.warehousesByStatus['blocked'] > 0) {
      recommendations.push(`🚫 Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΎ: ${report.warehousesByStatus['blocked']} склад(ΠΎΠ²) Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ`);
    }
    
    // Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ Ρ‚ΠΈΠΏΠ°ΠΌ складов
    if (report.warehousesByType.rfbs === 0 && report.totalWarehouses > 2) {
      recommendations.push(`πŸš€ РСкомСндуСтся Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ rFBS склады для ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ Ρ€Π΅Π³ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΉ логистики`);
    }
    
    // Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ возмоТностям
    const activeWarehouses = warehouses.filter(w => w.status === 'created').length;
    if (report.capabilities.economy < activeWarehouses / 2) {
      recommendations.push(`πŸ’° РассмотритС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ эконом-Ρ‚ΠΎΠ²Π°Ρ€ΠΎΠ² Π½Π° большСм количСствС складов`);
    }
    
    return recommendations;
  }
}

interface WarehouseReport {
  totalWarehouses: number;
  warehousesByStatus: Record<string, number>;
  warehousesByType: { fbs: number; rfbs: number };
  capabilities: {
    economy: number;
    kgt: number;
    karantin: number;
    entrustedAcceptance: number;
  };
  deliveryMethods: Array<{
    warehouseId: number;
    warehouseName: string;
    methods: WarehouseDeliveryMethod[];
  }>;
  recommendations: string[];
}

Π‘Ρ†Π΅Π½Π°Ρ€ΠΈΠΉ 2: ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки

// Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚ для Π°Π½Π°Π»ΠΈΠ·Π° ΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки
class DeliveryOptimizer {
  private warehouseApi: WarehouseApi;
  
  constructor(httpClient: HttpClient) {
    this.warehouseApi = new WarehouseApi(httpClient);
  }
  
  async optimizeDeliveryMethods(): Promise<DeliveryOptimizationReport> {
    const warehouses = await this.warehouseApi.getWarehousesList();
    const activeWarehouses = warehouses.result?.filter(w => w.status === 'created') || [];
    
    const report: DeliveryOptimizationReport = {
      warehouseAnalysis: [],
      globalInsights: {
        averageSLA: 0,
        providerDistribution: new Map(),
        cutoffAnalysis: new Map()
      },
      optimizationSuggestions: []
    };
    
    let totalSLA = 0;
    let totalMethods = 0;
    
    for (const warehouse of activeWarehouses) {
      if (!warehouse.warehouse_id) continue;
      
      const methods = await this.getAllDeliveryMethods(warehouse.warehouse_id);
      const analysis = this.analyzeWarehouseMethods(warehouse, methods);
      
      report.warehouseAnalysis.push(analysis);
      
      // Π‘Π±ΠΎΡ€ глобальной статистики
      methods.forEach(method => {
        if (method.sla_cut_in) {
          totalSLA += method.sla_cut_in;
          totalMethods++;
        }
        
        if (method.provider_id) {
          const count = report.globalInsights.providerDistribution.get(method.provider_id) || 0;
          report.globalInsights.providerDistribution.set(method.provider_id, count + 1);
        }
        
        if (method.cutoff) {
          const count = report.globalInsights.cutoffAnalysis.get(method.cutoff) || 0;
          report.globalInsights.cutoffAnalysis.set(method.cutoff, count + 1);
        }
      });
    }
    
    report.globalInsights.averageSLA = totalMethods > 0 ? totalSLA / totalMethods : 0;
    report.optimizationSuggestions = this.generateOptimizationSuggestions(report);
    
    return report;
  }
  
  private async getAllDeliveryMethods(warehouseId: number): Promise<WarehouseDeliveryMethod[]> {
    const allMethods: WarehouseDeliveryMethod[] = [];
    let offset = 0;
    const limit = 50;
    
    do {
      const response = await this.warehouseApi.getDeliveryMethods({
        limit,
        offset,
        filter: { warehouse_id: warehouseId }
      });
      
      if (response.result) {
        allMethods.push(...response.result);
      }
      
      if (!response.has_next) break;
      offset += limit;
    } while (true);
    
    return allMethods;
  }
  
  private analyzeWarehouseMethods(warehouse: Warehouse, methods: WarehouseDeliveryMethod[]): WarehouseMethodAnalysis {
    const activeMethods = methods.filter(m => m.status === 'ACTIVE');
    const avgSLA = activeMethods
      .filter(m => m.sla_cut_in)
      .reduce((sum, m) => sum + (m.sla_cut_in || 0), 0) / activeMethods.length;
    
    const providerCount = new Set(activeMethods.map(m => m.provider_id)).size;
    
    return {
      warehouseId: warehouse.warehouse_id!,
      warehouseName: warehouse.name || `Π‘ΠΊΠ»Π°Π΄ ${warehouse.warehouse_id}`,
      totalMethods: methods.length,
      activeMethods: activeMethods.length,
      averageSLA: Math.round(avgSLA),
      providerCount,
      fastMethodsCount: activeMethods.filter(m => (m.sla_cut_in || 0) < 120).length,
      issues: this.identifyWarehouseIssues(warehouse, methods)
    };
  }
  
  private identifyWarehouseIssues(warehouse: Warehouse, methods: WarehouseDeliveryMethod[]): string[] {
    const issues: string[] = [];
    
    const activeMethods = methods.filter(m => m.status === 'ACTIVE');
    
    if (activeMethods.length === 0) {
      issues.push('НСт Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки');
    } else if (activeMethods.length < 3) {
      issues.push('Мало Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки - рСкомСндуСтся Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ большС Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ²');
    }
    
    const avgSLA = activeMethods
      .filter(m => m.sla_cut_in)
      .reduce((sum, m) => sum + (m.sla_cut_in || 0), 0) / activeMethods.length;
    
    if (avgSLA > 240) { // 4 часа
      issues.push('ВысокоС срСднСС врСмя сборки - ΠΌΠΎΠΆΠ΅Ρ‚ Π²Π»ΠΈΡΡ‚ΡŒ Π½Π° ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ доставки');
    }
    
    const providerCount = new Set(activeMethods.map(m => m.provider_id)).size;
    if (providerCount < 2) {
      issues.push('Π—Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ поставщика доставки - риск для бизнСса');
    }
    
    return issues;
  }
  
  private generateOptimizationSuggestions(report: DeliveryOptimizationReport): string[] {
    const suggestions: string[] = [];
    
    // Анализ ΠΎΠ±Ρ‰ΠΈΡ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ
    const warehousesWithIssues = report.warehouseAnalysis.filter(w => w.issues.length > 0);
    if (warehousesWithIssues.length > 0) {
      suggestions.push(`πŸ”§ ${warehousesWithIssues.length} складов Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ внимания ΠΊ настройкС ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки`);
    }
    
    // Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ SLA
    if (report.globalInsights.averageSLA > 180) { // 3 часа
      suggestions.push(`⚑ Π‘Ρ€Π΅Π΄Π½Π΅Π΅ врСмя сборки ${Math.round(report.globalInsights.averageSLA)} ΠΌΠΈΠ½ - рСкомСндуСтся оптимизация процСссов`);
    }
    
    // Анализ распрСдСлСния поставщиков
    const dominantProvider = Array.from(report.globalInsights.providerDistribution.entries())
      .sort(([,a], [,b]) => b - a)[0];
    
    if (dominantProvider && dominantProvider[1] > report.warehouseAnalysis.length * 0.7) {
      suggestions.push(`⚠️ Высокая Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΡ‚ поставщика ${dominantProvider[0]} - рСкомСндуСтся дивСрсификация`);
    }
    
    return suggestions;
  }
}

interface DeliveryOptimizationReport {
  warehouseAnalysis: WarehouseMethodAnalysis[];
  globalInsights: {
    averageSLA: number;
    providerDistribution: Map<number, number>;
    cutoffAnalysis: Map<string, number>;
  };
  optimizationSuggestions: string[];
}

interface WarehouseMethodAnalysis {
  warehouseId: number;
  warehouseName: string;
  totalMethods: number;
  activeMethods: number;
  averageSLA: number;
  providerCount: number;
  fastMethodsCount: number;
  issues: string[];
}

⚠️ Π’Π°ΠΆΠ½Ρ‹Π΅ особСнности ΠΈ ограничСния

API ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΡ

  • ΠŸΠ°Π³ΠΈΠ½Π°Ρ†ΠΈΡ: ΠœΠ°ΠΊΡΠΈΠΌΡƒΠΌ 50 ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки Π·Π° запрос
  • Π€ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡ: ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΏΠΎ складу, статусу, поставщику
  • Волько FBS/rFBS: API Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ со складами FBO

БизнСс-Π»ΠΎΠ³ΠΈΠΊΠ°

  • Бтатусы складов: Π Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ стадии ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π° склада
  • Π›ΠΈΠΌΠΈΡ‚Ρ‹ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΉ: ΠœΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Π΅ трСбования ΠΊ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ поставки
  • ΠŸΠ΅Ρ€Π²Π°Ρ миля: Π’Ρ‹Π±ΠΎΡ€ ΠΌΠ΅ΠΆΠ΄Ρƒ самовывозом ΠΈ доставкой Π² Ρ‚ΠΎΡ‡ΠΊΡƒ

Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ использованию

  • ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅: Бкладская информация обновляСтся Π½Π΅ часто
  • ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³: РСгулярная ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° статусов складов
  • ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ: Π’Ρ‹Π±ΠΎΡ€ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² доставки ΠΏΠΎ SLA ΠΈ стоимости