Актуальный код

Последняя версия кода

Code.js
/**
 * @OnlyCurrentDoc
 * @author Mikhail Nosaev <m.nosaev@gmail.com>
 * @see {@link https://t.me/nosaev_m Telegram} разработка Google таблиц и GAS скриптов
 * @see {@link https://docs.ozon.ru/api/seller/ Ozon API}
 * Ozon Актуально для версии 318
 */

const contextOzon = {
    service: PropertiesService,
    // requestLog: true,
    // debug: true,
};

Ozon.context = Object.assign(Ozon.context, {
    ...contextOzon,
    storage: Ozon.setStorage({ service: contextOzon.service }),
    ...JSON.parse(contextOzon.service[Ozon.context.serviceType]().getProperty(Ozon.context.serviceName) || "{}")
});

const Support = Ozon.setSheet("⚙️ Поддержка");
const scriptRows = Ozon.CONFIG.settings.scriptRows;

function onOpen() {
    Ozon.menu();
}

const Seller =
    Ozon.context?.clientId && Ozon.context?.apiKey
        ? Ozon.sellerApi(Ozon.context) : null;

function ozonSetSellerAccess() {
    Ozon.ozonSetSellerAccess();
}

// ####################################################################################################################################
// ЗАКАЗЫ
// ####################################################################################################################################

// начальная дата для выгрузки
const tzoffset = new Date().getTimezoneOffset() * 60000; // смещение в миллисекундах

function fboPostingList() {
    // Список отправлений FBO (заказы)
    // https://docs.ozon.ru/api/seller/#operation/PostingAPI_GetFboPostingList

    const row = scriptRows.fboPostingList;
    const [[dateFrom, dateTo, accumulate, msk, offsetDays]] =
        Support.getRange(`E${row}:I${row}`).getValues();

    Ozon.fboPostingList(Seller, {
        since: dateFrom ? dateFrom.toISOString() : null,
        to: dateTo ? dateTo.toISOString() : null,
        indexesToDelete: [3, 9, 11, 14, 15, 18, 19, 20, 26, 27, 29, 30],
        datesRange: ["C:C"],
        generalRange: ["H:S"],
        numberShortRange: ["L:L"],
        msk,
        offsetDays,
        accumulate, // on ChekBox для накопления
        removeDuplicates: true,
        formulas: formulas.fboPostingList(msk),
    });
}

function fbsPostingList() {
    // Список отправлений FBS (заказы)
    // https://docs.ozon.ru/api/seller/#operation/PostingAPI_GetFbsPostingListV3

    const row = scriptRows.fbsPostingList;
    const [[dateFrom, dateTo, accumulate, msk, offsetDays]] =
        Support.getRange(`E${row}:I${row}`).getValues();

    Ozon.fbsPostingList(Seller, {
        since: dateFrom ? dateFrom.toISOString() : null,
        to: dateTo ? dateTo.toISOString() : null,
        indexesToDelete: [
            4, 6, 7, 8, 13, 15, 20, 21, 22, 23, 24, 27, 28, 29, 35, 36, 38, 39, 40
        ],
        datesRange: ["C:D"],
        generalRange: ["I:U"],
        numberShortRange: ["O:O"],
        msk,
        offsetDays,
        accumulate, // on ChekBox для накопления
        removeDuplicates: true,
        formulas: formulas.fbsPostingList(msk),
    });
}

// ####################################################################################################################################
// ВОЗВРАТЫ
// ####################################################################################################################################

function fboFbsReturnsList() {
    // Информация о возвратах FBO и FBS
    // https://docs.ozon.ru/api/seller/#operation/returnsList

    const row = scriptRows.fboFbsReturnsList;
    const [[dateFrom, dateTo, return_schema]] =
        Support.getRange(`E${row}:G${row}`).getValues();

    Ozon.fboFbsReturnsList(Seller, {
        logistic_return_date_time_from: dateFrom ? dateFrom.toISOString() : null,
        logistic_return_date_time_to: dateTo ? dateTo.toISOString() : null,
        return_schema,
        formulas: formulas.fboFbsReturnsList,
    });
}

function rfbsReturns() {
    // Список заявок на возврат rFBS
    // https://docs.ozon.ru/api/seller/#operation/RFBSReturnsAPI_ReturnsRfbsListV2
    Ozon.rfbsReturns(Seller, {});
}

function reportReturns() {
    // Отчёт о возвратах (версия 2)
    // https://docs.ozon.ru/api/seller/#operation/ReportAPI_ReportReturnsCreate
    const row = scriptRows.reportReturns;
    const status = Support.getRange(`G${row}`).getValue();
    Ozon.reportReturns(Seller, { status });
}

// ####################################################################################################################################
// ОСТАТКИ
// ####################################################################################################################################

function stocksAll() {
    // Информация о количестве товаров (все)
    // https://docs.ozon.ru/api/seller/#operation/ProductAPI_GetProductInfoStocksV3

    const row = scriptRows.stocksAll;
    const [[exists, accumulate, stockType]] = Support.getRange(`F${row}:H${row}`).getValues();

    Ozon.stocks(Seller, {
        stockType, // склад fbo или fbs, если пусто то все
        accumulate, // on ChekBox для накопления
        aboveZero: true, // остаток > 0
        exists,
        formulas: formulas.stocksAll,
    });
}

function analyticsStockOnWarehousesReport() {
    // Отчёт по остаткам и товарам (fbo) (версия 2)
    // https://docs.ozon.ru/api/seller/?utm_source=tg_seller_bot#operation/AnalyticsAPI_AnalyticsGetStockOnWarehousesV2

    const row = scriptRows.analyticsStockOnWarehousesReport;
    const accumulate = Support.getRange(`G${row}`).getValue();

    Ozon.analyticsStockOnWarehousesReport(Seller, {
        accumulate, // on ChekBox для накопления
        cluster: true, // добавить столбец кластер
        // formatUpdatedDate: "dd.MM.yyyy", // формат даты обновления
        aboveZero: true, // остатки > 0
    });
}

function analyticsStocks() {
    // Получить аналитику по остаткам
    // https://docs.ozon.ru/api/seller/#operation/AnalyticsAPI_AnalyticsStocks
    Ozon.analyticsStocks(Seller, {});
}

function analyticsTurnoverStocksReport() {
    // Оборачиваемость товара FBO
    // https://docs.ozon.ru/api/seller/#operation/AnalyticsAPI_StocksTurnover
    Ozon.analyticsTurnoverStocksReport(Seller, {});
}

function fboClusterList() {
    // Информация о кластерах и их складах FBO
    // https://docs.ozon.ru/api/seller/#operation/SupplyDraftAPI_DraftClusterList
    Ozon.fboClusterList(Seller);
}

function stocksByWarehouseFbs() {
    // Информация об остатках на складах продавца (FBS и rFBS)
    Ozon.stocksByWarehouseFbs(Seller);
}

function reportWarehouseStock() {
    // Отчёт об остатках на FBS-складе
    // https://docs.ozon.ru/api/seller/#operation/ReportAPI_CreateStockByWarehouseReport
    Ozon.reportWarehouseStock(Seller);
}

function wherehouses() {
    // Список складов FBS
    Ozon.wherehouses(Seller);
}

function warehousesAvailable() {
    // Загруженность складов Ozon
    // https://docs.ozon.ru/api/seller/#operation/SupplierAPI_SupplierAvailableWarehouses
    Ozon.warehousesAvailable(Seller);
}

// ####################################################################################################################################
// ЦЕНЫ
// ####################################################################################################################################

function prices() {
    // Получить информацию о цене товара
    // https://docs.ozon.ru/api/seller/#operation/ProductAPI_GetProductInfoPricesV4

    const row = scriptRows.prices;
    const accumulate = Support.getRange(`G${row}`).getValue();

    Ozon.prices(Seller, {
        // raw: false, // если используем formulas
        accumulate, // on ChekBox для накопления
        formulas: formulas.prices,
    });
}

function pricesFull() {
    // Получить информацию о цене товара (все)
    // https://docs.ozon.ru/api/seller/#operation/ProductAPI_GetProductInfoPricesV4
    Ozon.pricesFull(Seller, {});
}

// ####################################################################################################################################
// ТОВАРЫ
// ####################################################################################################################################

function reportProducts() {
    // Отчёт по товарам
    // https://docs.ozon.ru/api/seller/#operation/ReportAPI_CreateCompanyProductsReport
    Ozon.reportProducts(Seller, {});
    productsPhoto();
}

function productsPhoto() {
    // Фото товаров
    // https://docs.ozon.ru/api/seller/#operation/ProductAPI_GetProductInfoV2
    Ozon.productsPhoto(Seller, {});
}

function reportDiscounted() {
    // Отчёт об уценённых товарах
    // https://docs.ozon.ru/api/seller/#operation/ReportAPI_CreateDiscountedReport
    Ozon.reportDiscounted(Seller);
}

// ####################################################################################################################################
// ОТЧЁТЫ
// ####################################################################################################################################

function reportPostingsFbo() {
    // Отчёт об отправлениях
    // https://docs.ozon.ru/api/seller/#operation/ReportAPI_CreateCompanyPostingsReport

    const row = scriptRows.reportPostingsFbo;
    const accumulate = Support.getRange(`G${row}`).getValue();

    Ozon.reportPostings(Seller, {
        accumulate, // on ChekBox для накопления
        delivery_schema: "fbo",
        // minusDays: 90,
        // status_alias: ["delivered"],
    });
}

function reportPostingsFbs() {
    // Отчёт об отправлениях
    // https://docs.ozon.ru/api/seller/#operation/ReportAPI_CreateCompanyPostingsReport

    const row = scriptRows.reportPostingsFbs;
    const accumulate = Support.getRange(`G${row}`).getValue();

    Ozon.reportPostings(Seller, {
        accumulate, // on ChekBox для накопления
        delivery_schema: "fbs",
        // minusDays: 90,
        // status_alias: ["delivered"],
    });
}

function reportCashFlowStatement() {
    // Финансовый отчёт
    // https://docs.ozon.ru/api/seller/#operation/FinanceAPI_FinanceCashFlowStatementList

    const row = scriptRows.reportCashFlowStatement;
    const dateFrom = Support.getRange(`E${row}`).getValue();
    const from = dateFrom
        ? new Date(dateFrom - tzoffset).toISOString()
        : new Date(new Date(2023, 0, 1, 0, 0, 0) - tzoffset).toISOString();

    Ozon.reportCashFlowStatement(Seller, { from });
}

function reportCashFlowStatementWithDetails() {
    // Финансовый отчёт (расшифровка)
    // https://docs.ozon.ru/api/seller/#operation/FinanceAPI_FinanceCashFlowStatementList

    const row = scriptRows.reportCashFlowStatementWithDetails;
    const dateFrom = Support.getRange(`E${row}`).getValue();
    const from = dateFrom
        ? new Date(dateFrom - tzoffset).toISOString()
        : new Date(new Date(2023, 0, 1, 0, 0, 0) - tzoffset).toISOString();

    Ozon.reportCashFlowStatement(Seller, { from, with_details: true });
}

function financeTransactionListLoadGrupped() {
    // Список транзакций
    // https://docs.ozon.ru/api/seller/#operation/FinanceAPI_FinanceTransactionListV3

    const row = scriptRows.financeTransactionListLoadGrupped;
    const [[dateOffsetFrom, dateOffsetTo, accumulate, full, operations]] = Support.getRange(`E${row}:I${row}`).getValues();

    Ozon.financeTransactionListLoadGrupped(Seller, {
        dateOffsetFrom,
        dateOffsetTo,
        accumulate, // on ChekBox для накопления
        full,
        operations,
    });
}

function financeRealizations() {
    // Отчёт о реализации товаров
    // https://docs.ozon.ru/api/seller/#operation/FinanceAPI_GetRealizationReport

    const row = scriptRows.financeRealizations;
    const [[dateFrom, _, accumulate]] = Support.getRange(`E${row}:G${row}`).getValues();

    Ozon.financeRealizations(Seller, {
        dateFrom,
        accumulate, // on ChekBox для накопления
    });
}

function financeRealizationsPostings() {
    // Позаказный отчёт о реализации товаров
    // https://docs.ozon.ru/api/seller/#operation/FinanceAPI_GetRealizationReportV1

    const row = scriptRows.financeRealizations;
    const [[dateFrom, _, accumulate]] = Support.getRange(`E${row}:G${row}`).getValues();

    Ozon.financeRealizationsPostings(Seller, {
        dateFrom,
        accumulate, // on ChekBox для накопления
    });
}

function analyticsDataReport() {
    // Данные аналитики
    // https://docs.ozon.ru/api/seller/#operation/AnalyticsAPI_AnalyticsGetData

    const row = scriptRows.analyticsDataReport;
    let [[accumulate, premium, sales, offsetDays]] = Support.getRange(`E${row}:H${row}`).getValues();

    const sheet = Ozon.setSheet("Данные аналитики");

    // ##############################
    const timeZone = "Europe/Moscow";
    const dateFormat = "yyyy-MM-dd";
    let date_from, date_to;

    // первичная выгрузка
    if (!accumulate && offsetDays > 0) {
        date_from = Utilities.formatDate(
            new Date(new Date().setDate(new Date().getDate() - offsetDays)),
            timeZone,
            dateFormat
        );

        sheet.clearContents();
    }

    date_to = Utilities.formatDate(
        new Date(new Date().setDate(new Date().getDate() - 1
            // accumulate ? 1 : 0
        )),
        timeZone,
        dateFormat
    );
    // ##############################

    const options = {
        date_from,
        date_to,
        sales: false, // true, если запрос по продажам
        emptyCols: false, // true, удалить пустые столбцы
        sleep: 25000,
    };

    options.key = "day";

    if (premium) {
        options.premium = true;

        if (sales) {
            options.sales = true;
            options.dimension = ["category1", "sku", "day"];
            options.metrics = [
                "ordered_units",
                "revenue",
                "returns",
                "cancellations",
            ];

            options.header = [
                "Категория",
                "Ozon SKU id",
                "Название",
                "Дата",
                "Заказано товаров",
                "Заказано на сумму",
                "Возвращено товаров",
                "Отменено товаров",
                "",
            ];
            options.filters = [
                { key: "ordered_units", op: "GTE", value: "1" },
                { key: "revenue", op: "GTE", value: "0" },
                { key: "returns", op: "GTE", value: "0" },
                { key: "cancellations", op: "GTE", value: "0" },
            ];
        } else {
            options.filters = [{ key: "hits_view", op: "GT", value: "0" }];
        }
    } else {
        options.filters = [{ key: "ordered_units", op: "GTE", value: "1" }];
        options.dimension = ["sku", "day"];
        options.metrics = ["ordered_units", "revenue"];
        options.header = [
            "Ozon SKU id",
            "Название",
            "Дата",
            "Заказано товаров",
            "Заказано на сумму",
        ];
    }

    Ozon.analyticsDataReport(Seller, options);

    if (premium && !sales) {
        formulas.analyticsDataReport.premiumNosales(sheet);
    } else if (sales) {
        formulas.analyticsDataReport.sales(sheet);
    } else {
        formulas.analyticsDataReport.other(sheet);
    }

    SpreadsheetApp.flush();
}

// ####################################################################################################################################
// АКЦИИ
// ####################################################################################################################################

function actionsList() {
    // Список акций
    // https://docs.ozon.ru/api/seller/#operation/Promos
    Ozon.actionsList(Seller);
}

function actionsCandidates() {
    // Список доступных для акции товаров
    // https://docs.ozon.ru/api/seller/#operation/PromosCandidates
    Ozon.actionsCandidates(Seller);
}

function actionsProducts() {
    // Список товаров в акциях
    // https://docs.ozon.ru/api/seller/#operation/PromosProducts
    Ozon.actionsProducts(Seller);
}

function actionsActivate() {
    // Добавить товары в акцию
    Ozon.actionsActivate(Seller);
}

function actionsDeactivate() {
    // Удалить товары из акции
    Ozon.actionsDeactivate(Seller);
}

// ####################################################################################################################################
// РЕКЛАМА
// ####################################################################################################################################

const utilsPerformance = Ozon.utilsPerformance;

function ozonSetPerformanceAccess() {
    Ozon.ozonSetPerformanceAccess();
}

function pfCampaigns() {
    // Список кампаний
    // https://docs.ozon.ru/api/performance/#operation/ListCampaigns

    const Performance = Ozon.performanceApi(Ozon.context);

    const row = scriptRows.pfCampaigns;
    const type = Support.getRange(`E${row}`).getValue() || null;

    Ozon.pfCampaigns(Performance, {
        advObjectType: utilsPerformance.CampaignObjectTypeReverse[type],
    });
}

function pfLimitsList() {
    // Лимиты ставок для инструментов продвижения
    // https://docs.ozon.ru/api/performance/#operation/GetLimitsList

    const Performance = Ozon.performanceApi(Ozon.context);

    Ozon.pfLimitsList(Performance, {
    });
}

function pfExpense() {
    // Статистика по расходу кампаний
    // https://docs.ozon.ru/api/performance/#operation/GetCampaignExpense

    const Performance = Ozon.performanceApi(Ozon.context);

    const row = scriptRows.pfExpense;
    const [[dateFrom, dateTo]] = Support.getRange(`E${row}:F${row}`).getValues();

    Ozon.pfExpense(Performance, {
        dateFrom,
        dateTo,
    });
}

function pfDaily() {
    // Дневная статистика по кампаниям
    // https://docs.ozon.ru/api/performance/#operation/GetCampaignDailyStats

    const Performance = Ozon.performanceApi(Ozon.context);

    const row = scriptRows.pfDaily;
    const [[dateFrom, dateTo]] = Support.getRange(`E${row}:F${row}`).getValues();

    Ozon.pfDaily(Performance, {
        dateFrom,
        dateTo,
    });
}

function pfSkuProduct() {
    // РК Оплата за клик и Спецразмещение
    // https://docs.ozon.ru/api/performance/#operation/ProductCampaignList

    const Performance = Ozon.performanceApi(Ozon.context);

    const row = scriptRows.pfSkuProduct;
    const [[dateFrom, dateTo]] = Support.getRange(`E${row}:F${row}`).getValues();

    Ozon.pfSkuProduct(Performance, {
        dateFrom,
        dateTo,
    });
}

function pfSearchPromoOrders() {
    // РК По заказам (Оплата за заказ)
    // https://docs.ozon.ru/api/performance/#operation/SearchPromoOrdersReportSubmitRequest

    const Performance = Ozon.performanceApi(Ozon.context);

    Ozon.pfSearchPromoOrders(Performance);
}

function pfSearchPromoProducts() {
    // РК По товарам (Оплата за заказ)
    // https://docs.ozon.ru/api/performance/#operation/SearchPromoProductsReportSubmitRequest

    const Performance = Ozon.performanceApi(Ozon.context);

    Ozon.pfSearchPromoProducts(Performance);
}

function pfSearchPromoProductsDaily() {
    // РК По товарам (Оплата за заказ) по дня
    // https://docs.ozon.ru/api/performance/#operation/SearchPromoProductsReportSubmitRequest

    const Performance = Ozon.performanceApi(Ozon.context);

    const row = scriptRows.pfSearchPromoProductsDaily;
    const [[dateFrom, dateTo]] = Support.getRange(`E${row}:F${row}`).getValues();

    const runInfo = Ozon.pfSearchPromoProductsDaily(Performance, {
        dateFrom,
        dateTo,
        updatedAtRange: `H${row}`,
    });

    if (runInfo)
        Ozon.pfSearchPromoProductsDailyRun(Performance, {
            runInfo,
        });
}

function pfSearchPromoProductsDailyRun() {
    // РК По товарам (Оплата за заказ) по дням долгая загрузка
    // https://docs.ozon.ru/api/performance/#operation/SearchPromoProductsReportSubmitRequest

    const Performance = Ozon.performanceApi(Ozon.context);

    Ozon.pfSearchPromoProductsDailyRun(Performance, {});
}

function pfStatSku() {
    // РК Статистика (Оплата за клик)
    // https://docs.ozon.ru/api/performance/#operation/SubmitRequest

    const Performance = Ozon.performanceApi(Ozon.context);

    const row = scriptRows.pfStatSku;
    const [[dateFrom, dateTo]] = Support.getRange(`E${row}:F${row}`).getValues();

    const runInfo = Ozon.pfStat(Performance, {
        dateFrom,
        dateTo,
        advType: "Оплата за клик",
        updatedAtRange: `H${row}`,
    });

    if (runInfo)
        Ozon.pfStatSkuRun(Performance, {
            runInfo,
        });
}

function pfStatSkuRun() {
    // РК Статистика (Оплата за клик) долгая загрузка
    // https://docs.ozon.ru/api/performance/#operation/SubmitRequest

    const Performance = Ozon.performanceApi(Ozon.context);

    Ozon.pfStatSkuRun(Performance, {});
}

function pfStatBanners() {
    // РК Статистика (Баннерная)
    // https://docs.ozon.ru/api/performance/#operation/SubmitRequest

    const Performance = Ozon.performanceApi(Ozon.context);

    const row = scriptRows.pfStatBanners;
    const [[dateFrom, dateTo]] = Support.getRange(`E${row}:F${row}`).getValues();

    Ozon.pfStat(Performance, {
        dateFrom,
        dateTo,
        advType: "Баннерная",
        updatedAtRange: `H${row}`,
    });
}

Last updated