Выгрузка заказов

05 мая 2019, 07:00

Выгрузка старых заказов из интернет-магазина в RetailCRM

Описание

Для чего нужно. Если вы подключаете RetailCRM к уже действующему магазину - наверняка там уже есть созданные ранее заказы. Выгружая эти данные мы позволяем RetailCRM просчитывать более точную аналитику, и как минимум, показывать сколько учтенных покупок у того или иного пользователя.

Пошаговая инструкция.

  1. К этому моменту у Вас уже должен быть куплен, подключен к магазину и настроен компонент modRetailCRM. Под настройкой я подразумеваю заполнение ключа АПИ, символьльного кода сайта и адреса вашей CRM, так как здесь мы уже используем компонент. Если это не сделано - вернитесь к предварительной настройке компонента.

  2. Если заказов у вас в базе немного (понятие относительное, скажем меньше сотни) - мы можем запустить в админке MODX компонент console и выполнить в нем следующий код
<?php
//Запуск и первоначальная настройка компонента
if (!$modx->getService('modretailcrm','modRetailCrm', MODX_CORE_PATH.'components/modretailcrm/model/modretailcrm/')) {
    $modx->log(1, '[ModRetailCrm] - Not found class RetailCrm');
    return;
}

$pdo = $modx->getService('pdoFetch');

$site = $modx->getOption('modretailcrm_siteCode');
$apiKey = $modx->getOption('modretailcrm_apiKey');
$crmUrl = $modx->getOption('modretailcrm_url');

if(!empty($site)  && !empty($apiKey) && !empty($crmUrl)){
    $modRetailCrm = new modRetailCrm($modx, $apiKey, $crmUrl, $site);
}else{
    return;
}

$packages = $modx->getOption('extension_packages');
$packages = json_decode($packages, true);
$is_msoptionsprice = false;
foreach($packages as $package){
    if(isset($package['msoptionsprice'])){
        $is_msoptionsprice = true;
    }
}

$is_mspromocode = false;
foreach($packages as $package){
    if(isset($package['mspromocode'])){
        $is_mspromocode = true;
    }
}

//Получаем все заказы из базы
$orders = $modx->getIterator('msOrder');

//Перебираем заказы по одному
foreach($orders as $msOrder){
    $order = $msOrder->toArray();
    $order['address'] = $pdo->getArray('msOrderAddress', array('id' => $order['address']), array('sortby' => 'id'));
    $order['delivery'] = $pdo->getArray('msDelivery', array('id' => $order['delivery']), array('sortby' => 'id'));
    $order['payment'] = $pdo->getArray('msPayment', array('id' => $order['payment']), array('sortby' => 'id'));
    $order['profile'] = $pdo->getArray('modUserProfile', array('internalKey' => $order['user_id']), array('sortby' => 'id'));
    $order['products'] = $pdo->getCollection('msOrderProduct', array('order_id' => $order['id']), array('sortby' => 'id'));
    //Учет промокода, если есть
    if($is_mspromocode){
        $order['sale'] = $pdo->getArray('mspcOrder', array('order_id' => $order['id']));
    }

    $orderData = array();

    //Проверяю наличие пользователя в базе CRM
    $user_response = $modRetailCrm->request->customersGet($order['user_id'], 'externalId', $site);
    if($modx->getOption('modretailcrm_log')){
        $modx->log(MODX_LOG_LEVEL_ERROR, '[ModRetailCrm] - Ищем клиента в базе RetailCRM '.print_r($user_response, 1));
    }
    if($user_response->getStatusCode() == 404){
        $customer_profile = $pdo->getArray('modUserProfile', array('internalKey' => $order['user_id']));
        $customer = array();
        $customer['externalId'] =  $order['user_id'];
        $customer['firstName'] = $customer_profile['fullname'];
        $customer['email'] = $customer_profile['email'];
        if(!empty($customer_profile['phone'])){
            $customer['phones'][]['number'] = $customer_profile['phone'];
        }
        $response = $modRetailCrm->request->customersCreate($customer, $site);
        if($modx->getOption('modretailcrm_log')){
            $modx->log(MODX_LOG_LEVEL_ERROR, '[ModRetailCrm] - Создаем клиента в базе RetailCRM '.print_r($response, 1));
        }
    }

    $orderData['customer']['externalId'] = $order['user_id'];
    $orderData['externalId'] = str_replace('/', '-', $order['num']);
    //$orderData['externalId'] = $order['id']; Желающим идентифицировать заказ по id
    $orderData['firstName'] = !empty($order['address']['receiver']) ? $order['address']['receiver'] : $order['profile']['fullname'];
    $orderData['phone'] = !empty($order['address']['phone']) ? $order['address']['phone'] : $order['profile']['phone'];
    $orderData['email'] = $order['profile']['email'];

    $tmpName = explode(' ', $orderData['firstName']);
    if(count($tmpName) == 3){
        $orderData['lastName'] = $tmpName[0];
        $orderData['firstName'] = $tmpName[1];
        $orderData['patronymic'] = $tmpName[2];
    }

    foreach ($order['products'] as $key=>$product) {
        // Возможность  получить  модификацию msOptionsPrice
        //$modification = $modx->getObject('msopModification', $product['options']['modification']);

        $orderData['items'][$key]['initialPrice'] = $product['price'];
        $orderData['items'][$key]['purchasePrice'] = $product['price'];
        $orderData['items'][$key]['productName'] = $product['name'];
        $orderData['items'][$key]['quantity'] = $product['count'];
        $orderData['items'][$key]['offer']['externalId'] = $product['product_id'];
        foreach($product['options'] as $k=>$v){
            if(!empty($v)){
                switch($k){
                    case 'modifications':
                        // Возможность  получить  модификацию msOptionsPrice
                        if($is_msoptionsprice){
                            foreach($v as $mod){
                                //$modification = $modx->getObject('msopModification', $mod);
                                //$orderData['items'][$key]['properties'][] = array('name' => $k, 'value' => $modification->name);
                            }

                        }
                        break;
                    case 'size':
                        $orderData['items'][$key]['properties'][] = array('name' => 'Размер', 'value' => $v);
                        break;
                    case 'color':
                        $orderData['items'][$key]['properties'][] = array('name' => 'Цвет', 'value' => $v);
                        break;
                    default:
                        $orderData['items'][$key]['properties'][] = array('name' => $k, 'value' => $v);
                }

            }
        }

        if($order['weight']> 0){
            $orderData['weight'] = $order['weight'];
        }
    }

    $fields = array(
        'index' => 'Индекс',
        'country' => 'Страна',
        'region' => 'Регион',
        'city' => 'Город',
        'metro' => 'Метро',
        'street' => 'Улица',
        'building' => 'Дом',
        'room' => 'Квартира\офис'
    );
    $address = '';
    foreach($fields as $field=>$comment){
        if(!empty($order['address'][$field])){
            $address .= $comment.':'.$order['address'][$field].'
            ';
            if($field == 'room'){
                $orderData['delivery']['address']['flat'] = $order['address'][$field];
            }else{
                $orderData['delivery']['address'][$field] = $order['address'][$field];
            }

        }
    }

    $orderData['delivery']['address']['text'] = $address;
    $orderData['customerComment'] = $order['address']['comment'];
    $orderData['delivery']['cost'] = $order['delivery_cost'];
    if(!empty($order['delivery']['retailcrm_delivery_code'])){
        $orderData['delivery']['code'] = $order['delivery']['retailcrm_delivery_code'];
    }

    if(!empty($order['payment']['retailcrm_payment_code'])){
        $orderData['payments'][0]['type'] = $order['payment']['retailcrm_payment_code'];
    }

    if(!empty($order['sale']['discount_amount'])){
        $orderData['discountManualAmount'] = $order['sale']['discount_amount'];
    }

    $response = $modRetailCrm->request->ordersCreate($orderData, $site);

    if($modx->getOption('modretailcrm_log')){
        $modx->log(MODX_LOG_LEVEL_ERROR, '[ModRetailCrm] - Результат отправки заказа '.print_r($response, 1));
    }
}

По сути на этом все. Могу только добавить, что при большой базе эффективнее будет вынести код в отдельный php файл и запустить его через консоль сервера. Только не забудьте в этом случае в начале файла подключить MODX. Если не знаете как это сделать - читаем это

Возможные ошибки

Если что то пошло не так, и выгрузка заказов не удалась, в первую очередь проверяем что вы заполнили системные настройки modRetailCRM.

Затем пробуем сначала передать из базы в RetailCRM один заказ, а не все. Чуть чуть меняем код

<?php
//Запуск и первоначальная настройка компонента
if (!$modx->getService('modretailcrm','modRetailCrm', MODX_CORE_PATH.'components/modretailcrm/model/modretailcrm/')) {
    $modx->log(1, '[ModRetailCrm] - Not found class RetailCrm');
    return;
}

$pdo = $modx->getService('pdoFetch');

$site = $modx->getOption('modretailcrm_siteCode');
$apiKey = $modx->getOption('modretailcrm_apiKey');
$crmUrl = $modx->getOption('modretailcrm_url');

if(!empty($site)  && !empty($apiKey) && !empty($crmUrl)){
    $modRetailCrm = new modRetailCrm($modx, $apiKey, $crmUrl, $site);
}else{
    return;
}

$packages = $modx->getOption('extension_packages');
$packages = json_decode($packages, true);
$is_msoptionsprice = false;
foreach($packages as $package){
    if(isset($package['msoptionsprice'])){
        $is_msoptionsprice = true;
    }
}

$is_mspromocode = false;
foreach($packages as $package){
    if(isset($package['mspromocode'])){
        $is_mspromocode = true;
    }
}

//Получаем один заказ из базы, у которого id = 1
$msOrder = $modx->getObject('msOrder', array('id' => 1));

$order = $msOrder->toArray();
$order['address'] = $pdo->getArray('msOrderAddress', array('id' => $order['address']), array('sortby' => 'id'));
$order['delivery'] = $pdo->getArray('msDelivery', array('id' => $order['delivery']), array('sortby' => 'id'));
$order['payment'] = $pdo->getArray('msPayment', array('id' => $order['payment']), array('sortby' => 'id'));
$order['profile'] = $pdo->getArray('modUserProfile', array('internalKey' => $order['user_id']), array('sortby' => 'id'));
$order['products'] = $pdo->getCollection('msOrderProduct', array('order_id' => $order['id']), array('sortby' => 'id'));
//Учет промокода, если есть
if($is_mspromocode){
    $order['sale'] = $pdo->getArray('mspcOrder', array('order_id' => $order['id']));
}

$orderData = array();

//Проверяю наличие пользователя в базе CRM
$user_response = $modRetailCrm->request->customersGet($order['user_id'], 'externalId', $site);
if($modx->getOption('modretailcrm_log')){
    $modx->log(MODX_LOG_LEVEL_ERROR, '[ModRetailCrm] - Ищем клиента в базе RetailCRM '.print_r($user_response, 1));
}
if($user_response->getStatusCode() == 404){
    $customer_profile = $pdo->getArray('modUserProfile', array('internalKey' => $order['user_id']));
    $customer = array();
    $customer['externalId'] =  $order['user_id'];
    $customer['firstName'] = $customer_profile['fullname'];
    $customer['email'] = $customer_profile['email'];
    if(!empty($customer_profile['phone'])){
        $customer['phones'][]['number'] = $customer_profile['phone'];
    }
    $response = $modRetailCrm->request->customersCreate($customer, $site);
    if($modx->getOption('modretailcrm_log')){
        $modx->log(MODX_LOG_LEVEL_ERROR, '[ModRetailCrm] - Создаем клиента в базе RetailCRM '.print_r($response, 1));
    }
}

$orderData['customer']['externalId'] = $order['user_id'];
$orderData['externalId'] = str_replace('/', '-', $order['num']);
//$orderData['externalId'] = $order['id']; Желающим идентифицировать заказ по id
$orderData['firstName'] = !empty($order['address']['receiver']) ? $order['address']['receiver'] : $order['profile']['fullname'];
$orderData['phone'] = !empty($order['address']['phone']) ? $order['address']['phone'] : $order['profile']['phone'];
$orderData['email'] = $order['profile']['email'];

$tmpName = explode(' ', $orderData['firstName']);
if(count($tmpName) == 3){
    $orderData['lastName'] = $tmpName[0];
    $orderData['firstName'] = $tmpName[1];
    $orderData['patronymic'] = $tmpName[2];
}

foreach ($order['products'] as $key=>$product) {
    // Возможность  получить  модификацию msOptionsPrice
    //$modification = $modx->getObject('msopModification', $product['options']['modification']);

    $orderData['items'][$key]['initialPrice'] = $product['price'];
    $orderData['items'][$key]['purchasePrice'] = $product['price'];
    $orderData['items'][$key]['productName'] = $product['name'];
    $orderData['items'][$key]['quantity'] = $product['count'];
    $orderData['items'][$key]['offer']['externalId'] = $product['product_id'];
    foreach($product['options'] as $k=>$v){
        if(!empty($v)){
            switch($k){
                case 'modifications':
                    // Возможность  получить  модификацию msOptionsPrice
                    if($is_msoptionsprice){
                        foreach($v as $mod){
                            //$modification = $modx->getObject('msopModification', $mod);
                            //$orderData['items'][$key]['properties'][] = array('name' => $k, 'value' => $modification->name);
                        }

                    }
                    break;
                case 'size':
                    $orderData['items'][$key]['properties'][] = array('name' => 'Размер', 'value' => $v);
                    break;
                case 'color':
                    $orderData['items'][$key]['properties'][] = array('name' => 'Цвет', 'value' => $v);
                    break;
                default:
                    $orderData['items'][$key]['properties'][] = array('name' => $k, 'value' => $v);
            }

        }
    }

    if($order['weight']> 0){
        $orderData['weight'] = $order['weight'];
    }
}

$fields = array(
    'index' => 'Индекс',
    'country' => 'Страна',
    'region' => 'Регион',
    'city' => 'Город',
    'metro' => 'Метро',
    'street' => 'Улица',
    'building' => 'Дом',
    'room' => 'Квартира\офис'
);
$address = '';
foreach($fields as $field=>$comment){
    if(!empty($order['address'][$field])){
        $address .= $comment.':'.$order['address'][$field].'
        ';
        if($field == 'room'){
            $orderData['delivery']['address']['flat'] = $order['address'][$field];
        }else{
            $orderData['delivery']['address'][$field] = $order['address'][$field];
        }

    }
}

$orderData['delivery']['address']['text'] = $address;
$orderData['customerComment'] = $order['address']['comment'];
$orderData['delivery']['cost'] = $order['delivery_cost'];
if(!empty($order['delivery']['retailcrm_delivery_code'])){
    $orderData['delivery']['code'] = $order['delivery']['retailcrm_delivery_code'];
}

if(!empty($order['payment']['retailcrm_payment_code'])){
    $orderData['payments'][0]['type'] = $order['payment']['retailcrm_payment_code'];
}

if(!empty($order['sale']['discount_amount'])){
    $orderData['discountManualAmount'] = $order['sale']['discount_amount'];
}

$response = $modRetailCrm->request->ordersCreate($orderData, $site);

if($modx->getOption('modretailcrm_log')){
    $modx->log(MODX_LOG_LEVEL_ERROR, '[ModRetailCrm] - Результат отправки заказа '.print_r($response, 1));
}

Закомментируем строку отправки заказа и посмотрим сначала, что мы получаем из базы данных

///$response = $modRetailCrm->request->ordersCreate($orderData, $site);

Для начала распечатаем на экран выборку информации из базы данных

//Получаем один заказ из базы, у которого id = 1
$msOrder = $modx->getObject('msOrder', array('id' => 1));

$order = $msOrder->toArray();
$order['address'] = $pdo->getArray('msOrderAddress', array('id' => $order['address']), array('sortby' => 'id'));
$order['delivery'] = $pdo->getArray('msDelivery', array('id' => $order['delivery']), array('sortby' => 'id'));
$order['payment'] = $pdo->getArray('msPayment', array('id' => $order['payment']), array('sortby' => 'id'));
$order['profile'] = $pdo->getArray('modUserProfile', array('internalKey' => $order['user_id']), array('sortby' => 'id'));
$order['products'] = $pdo->getCollection('msOrderProduct', array('order_id' => $order['id']), array('sortby' => 'id'));
//Учет промокода, если есть
if($is_mspromocode){
    $order['sale'] = $pdo->getArray('mspcOrder', array('order_id' => $order['id']));
}
echo '<pre>';
print_r($order);

Если массив не пустой и информация в принципе есть, двигаемся дальше и распечатываем на экран данные подготовленные к отправке в RetailCRM

if(!empty($order['sale']['discount_amount'])){
    $orderData['discountManualAmount'] = $order['sale']['discount_amount'];
}

echo '<pre>';
print_r($orderData);

///$response = $modRetailCrm->request->ordersCreate($orderData, $site);

Здесь также смотрим, не пустой ли в принципе массив, все ли ячейки массива заполнены, нет ли пустоты. Если и здесь все с виду хорошо отправляем заказ в RetailCRM и распечатаем вернувшийся ответ

$response = $modRetailCrm->request->ordersCreate($orderData, $site);
echo '<pre>';
print_r($response);

Как правило RetailCRM хорошо описывает все ошибки - и этого шага будет достаточно, чтобы понять чего не хватает для выгрузки.



Предыдущий документ
Выгрузка пользователей
Следующий документ
Выгрузка товаров