РАЗРАБОТКА НА БИТРИКС

Ежедневное формирование отчета по заказам в виде .xls-файла

Подписывайтесь на канал для bitrix-разработчиков в Telegram!
В кейсе приведен пример формирования отчета по заказам за предыдущие сутки в виде .xls-файла и отправки данного отчета на email.

Описание задачи

Отчет должен включать следующие колонки:
  • дата заказа,
  • номер заказа,
  • стоимость доставки,
  • полная стоимость заказа,
  • все позиции (товары) в заказе и их количество.

Решение

Добавляем скрипт /local/cron/orders_export.php со следующим кодом:
<?
define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
define('NO_AGENT_STATISTIC', true);
define('STOP_STATISTICS', true);
define('BX_CRONTAB_SUPPORT', true);
define('LANGUAGE_ID', 'ru');

ini_set('memory_limit', '512M');

@set_time_limit(0);
@ignore_user_abort(true);

// для запуска на cron необходимо указать корректный путь к корневой папке сайта
$_SERVER["DOCUMENT_ROOT"] = "/home/bitrix/www";

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

$file = $_SERVER["DOCUMENT_ROOT"] . '/export/orders.xls';

CModule::IncludeModule("sale");
use Bitrix\\Sale;


$arFilter = Array(
    ">=DATE_INSERT" => date($DB->DateFormatToPHP(CSite::GetDateFormat("SHORT")),  strtotime('yesterday')),
    "<DATE_INSERT" => date($DB->DateFormatToPHP(CSite::GetDateFormat("SHORT")),  strtotime('today'))
);

$arOrders = array();
$db_sales = CSaleOrder::GetList(array("DATE_INSERT" => "ASC"), $arFilter);
$i = 0;
while ($ar_sales = $db_sales->Fetch())
{

    $basket = Sale\\Order::load($ar_sales['ID'])->getBasket();
    $basketItems = $basket->getBasketItems();
    $counter = 0;
    foreach ($basket as $basketItem) {
        $productId = $basketItem->getProductId();
        $measure = \\Bitrix\\Catalog\\ProductTable::getCurrentRatioWithMeasure($productId);
        $arOrders[$i]['ITEMS'][$counter] = $basketItem->getField('NAME') . ' - ' . $basketItem->getQuantity() . ' ' . $measure[$productId]['MEASURE']['SYMBOL_RUS'];
        $counter++;
    }
    $arOrders[$i]['DATE_INSERT_FORMAT'] = $ar_sales['DATE_INSERT_FORMAT'];
    $arOrders[$i]['ID'] = $ar_sales['ID'];
    $arOrders[$i]['PRICE_DELIVERY'] = $ar_sales['PRICE_DELIVERY'];
    $arOrders[$i]['PRICE'] = $ar_sales['PRICE'];
    $i++;
}

//echo "<pre>";
//print_r($arOrders);
//echo "</pre>";
$str = "";
$str .= "<html>
<head>
    <title></title>
    <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
    <style>
        td {mso-number-format:\\@;}
        .number0 {mso-number-format:0;}
        .number2 {mso-number-format:Fixed;}
    </style>
</head>
<body><table border='1'>

    <tr>
        <td>Дата заказа</td>
        <td>Номер заказа</td>
        <td>Стоимость доставки</td>
        <td>Полная стоимость заказа</td>
        <td>Позиции</td>        
    </tr>";

foreach ($arOrders as $order)
{
    $rowspan = count($order['ITEMS']) > 1 ? 'rowspan="' . count($order['ITEMS']) . '"' : '';
    $str .= "
        <tr>
            <td {$rowspan}>{$order['DATE_INSERT_FORMAT']}</td>
            <td {$rowspan}>{$order['ID']}</td>
            <td {$rowspan}>{$order['PRICE_DELIVERY']}</td>
            <td {$rowspan}>{$order['PRICE']}</td>
            <td>{$order['ITEMS'][0]}</td>        
        </tr>
    ";

    if(count($order['ITEMS']) > 1) {
        foreach ($order['ITEMS'] as $key => $value) {
            if($key == 0) continue;
            $str .= "
                <tr>
                    <td>{$value}</td>
                </tr>
            ";
        }
    }

}

$str .= "</table></body></html>";

//echo $str;


$fp = fopen($file, 'w');
fwrite($fp, $str);
fclose($fp);

$arFiles = array($file);
CEvent::Send("ORDERS_EXPORT", 's2', array(), "N", "", $arFiles);
Данный скрипт получает данные по заказам за предыдущие сутки, формирует из них табличную html-разметку, записывает в файл и отправляет по почтовому событию ORDERS_EXPORT.
При формировании табличной разметки есть нюанс — необходимо объединять все строки в ячейках, кроме позиций. Для это используется rowspan со значением, равным количеству позиций в заказе.
Создание почтового события и шаблона
Необходимо создать почтовое событие ORDERS_EXPORT и шаблон для него. Шаблон минимален — указываем отправителя (например, #DEFAULT_EMAIL_FROM#), адресата, тему письма "Экспорт заказов с сайта #SITE_NAME#" и тело письма (я ограничился простым текстом "Список заказов за предыдущий день в приложенном файле").
Добавление скрипта на cron ежедневно на 9 утра
0 9 * * * /usr/bin/php -f /home/bitrix/www/local/cron/orders_export.php
Ограничение публичного доступа к папке Сайт/export/
Чтобы данные по заказам не были в публичном доступе, можно ограничить доступ (либо удалять файл в скрипте /local/cron/orders_export.php после отправки). Я решил ограничить доступ, поэтому добавил в папку /export/ файл .htaccess, где прописал 1 строку
Deny from all
Добавление исключения в .gitignore (в случае, если сформированный файл не удаляем)
/export/*.xls

Результат

  1. Написали скрипт, формирующий отчет по заказам за предыдущие сутки в формате .xls и отправляющий его на email.
  2. Создали почтовое событие и почтовый шаблон.
  3. Добавили скрипт на cron.
  4. Ограничили публичный доступ к папке, где лежит файл с заказами.
  5. Добавили необходимые исключения в .gitignore.

Выводы

В результате выполнения задачи мы получили ежедневное автоматическое формирование отчета по заказам за предыдущие сутки в формате .xls с требуемыми данными и отправку данного файла клиенту на почту.
Подписывайтесь на канал для bitrix-разработчиков в Telegram!

Рекомендованные статьи