Warehouse Operations API
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 ΠΈ ΡΡΠΎΠΈΠΌΠΎΡΡΠΈ