[РЕШЕНО]Как кастомизировать историю заказов в Office?

Вообще данный вопрос может быть актуален не только для Office, но и вообще для любого сайта использующего MiniShop2. Я решил проблему так. Написал сниппет, который делает запрос в БД и выводит результат
if(!$user){
    $user = $modx->user->id;
}
$output;
$outputProds;

$sqlOrder = 
"SELECT modx_ms2_orders.id, modx_ms2_orders.createdon, modx_ms2_orders.num, modx_ms2_orders.cost, modx_ms2_orders.cart_cost, modx_ms2_orders.delivery_cost, modx_ms2_orders.status, modx_ms2_orders.delivery, modx_ms2_orders.payment, modx_ms2_orders.address, modx_ms2_payments.name,  modx_ms2_deliveries.name, modx_ms2_order_statuses.name, modx_ms2_order_addresses.phone, modx_ms2_order_addresses.region, modx_ms2_order_addresses.city, modx_ms2_order_addresses.receiver, modx_ms2_order_addresses.country, modx_ms2_order_addresses.index, modx_ms2_order_addresses.metro, modx_ms2_order_addresses.street, modx_ms2_order_addresses.building, modx_ms2_order_addresses.room, modx_ms2_order_addresses.comment
FROM `modx_ms2_orders` 
LEFT JOIN `modx_ms2_payments` 
ON modx_ms2_payments.id = modx_ms2_orders.payment
LEFT JOIN `modx_ms2_deliveries` 
ON modx_ms2_deliveries.id = modx_ms2_orders.delivery
LEFT JOIN `modx_ms2_order_statuses` 
ON modx_ms2_order_statuses.id = modx_ms2_orders.status
LEFT JOIN `modx_ms2_order_addresses` 
ON modx_ms2_order_addresses.id = modx_ms2_orders.address
WHERE modx_ms2_orders.user_id = $user
ORDER BY modx_ms2_orders.createdon DESC";
$orders = $modx->query($sqlOrder); //получаем информацию о заказах пользователя 
$orders = $orders->fetchAll(PDO::FETCH_NAMED); //преобразуем результат в массив

for($i = 0; $i < count($orders); $i++){
    
$order_id = $orders[$i]['id'];

$sqlProducts = "SELECT `product_id`, `name`, `count`, `cost`, `price` FROM `modx_ms2_order_products` WHERE order_id = $order_id";
$products = $modx->query($sqlProducts); //получаем все товары в заказе 
$products = $products->fetchAll(PDO::FETCH_ASSOC); //преобразуем результат в массив

    if($tplProducts){
        
        for ($j = 0; $j < count($products); $j++){
            $prodChunk = $modx->getChunk($tplProducts ,array(
                'prod_id' => $products[$j]['product_id'],
                'prod_name' => $products[$j]['name'],
                'prod_price' => $products[$j]['price'],
                'prod_count' => $products[$j]['count'],
                'prod_cost' => $products[$j]['cost']
                ));
                
            $outputProds .= $prodChunk;
        }
    }else{
            $outputProds = '<pre>' . print_r($products, 1) . '</pre>';  
    }

    if($tpl){
        $date = strtotime($orders[$i]['createdon']);
        $date = date("d.m.Y H:i", $date); 
        $chunk = $modx->getChunk($tpl ,array(
                        'order_id' => $orders[$i]['id'],
                        'date' => $date,
                        'num' => $orders[$i]['num'],
                        'products_cost' => $orders[$i]['cost'],
                        'delivery_cost' => $orders[$i]['delivery_cost'],
                        'order_cost' => $orders[$i]['cart_cost'],
                        'status' => $orders[$i]['name'][2],
                        'delivery_name' => $orders[$i]['name'][1],
                        'payment_name' => $orders[$i]['name'][0],
                        'delivery_id' => $orders[$i]['delivery'],
                        'payment_id' => $orders[$i]['payment'],
                        'phone' =>$orders[$i]['phone'],
                        'receiver' => $orders[$i]['receiver'],
                        'country' => $orders[$i]['country'],
                        'index' => $orders[$i]['index'],
                        'region' => $orders[$i]['region'],
                        'city' => $orders[$i]['city'],
                        'metro' => $orders[$i]['metro'],
                        'street' => $orders[$i]['street'],
                        'building' => $orders[$i]['building'],
                        'room' => $orders[$i]['room'],
                        'comment' => $orders[$i]['comment'],
                        'products' => $outputProds
                    ));
                    
                    $output .= $chunk;
                    $outputProds = '';
    }else{
       $output = '<pre>' .  print_r($orders, 1) . '</pre>';
    }
}
return $output;
На вход сниппет принимает id пользователя в параметре &user и два шаблона &tpl — для вывода информации о заказе и &tplProducts — для вывода списка товаров в этом заказе. Все плейсхолдеры можно посмотреть просто вызвав сниппет с пустыми параметрами шаблонов. Плюс в чанке &tpl доступен плейсхолдер [[+products]] который и содержит список товаров в заказе. Если более опытные товарищи дадут советы по улучшению кода, буду признателен.
Артур
20 декабря 2019, 18:16
modx.pro
1
737
0
Поблагодарить автора Отправить деньги

Комментарии: 5

Артур
20 декабря 2019, 18:30
0
Дополнительно, пользуясь вот этой информацией modx.pro/development/3139, сделал кнопку добавляющую все товары заказа в корзину.
Вот код, который отправляет запрос на сервер
//Повторить заказ в истории заказов
$('.jsOrderRepeat').click(function(){
    var orderProds ={}; //создаем пустой объект куда будем записывать id и количество товара
    var prods = $(this).siblings('.jsProdList').children('.jsProdItem'); //получаем список товаров с заказе
    $(prods).each(function(){
        var prodId =  $(this).data('prodId'); //получаем id товара
        var prodCount = $(this).data('prodCount'); //получаем количество товара
       Object.defineProperty(orderProds, prodId,{ //динамически создаем новое свойство у объекта orderProds, с именем = id и значением = количеству
            value : prodCount,
            enumerable: true //это важно иначе json будет пустым
        });
    });
    orderProds = JSON.stringify(orderProds); //преобразуем объект в json строку
    $.post(document.location.href, {action: 'repeatOrder', orderProds: orderProds}, function (response) { //отправляем ajax на сервер
    //сервер возвращает строку из нескольких json объектов
        response = response.split('|'); //преобразуем ответ сервера в массив 
        for(var i = 0; i < response.length; i++){ //перебираем массив
            if(response[i]){
                var res = JSON.parse(response[i]);
                if(res['success']){
                    miniShop2.Message.success(res['message']);
                }else{
                    miniShop2.Message.error(res['message']);
                }
            }
        }
        
        //Получаем состояние корзины после добавления товаров
        var lastRes = JSON.parse(response[response.length-2]);
        lastRes = lastRes['data'];
        
        //Обновляем мини корзину
        $('#msMiniCart .ms2_total_cost').text(lastRes.total_cost);
        $('#msMiniCart .ms2_total_count').text(lastRes.total_count);
        $('#msMiniCart .empty').css('display', 'none');
        $('#msMiniCart .not_empty').css('display', 'block');
    });
});


Вот код в сниппите, который обрабатывает ajax
<?php
//Инициализируем скрипты minishop2
$miniShop2 = $modx->getService('miniShop2');
$scriptProperties = array(
    'json_response' => true, // возвращать ответы в JSON
    'max_count' => 1000, // максимальное число товаров для добавления за один раз
    'allow_deleted' => false, // не добавлять в корзину товары с deleted = 1
    'allow_unpublished' => false, // не добавлять в корзину товары с published = 0
);
$miniShop2->initialize($modx->context->key, $scriptProperties); //инициалтзируем minishop2 для вывода истории заказов в ЛК

// Откликаться будет ТОЛЬКО на ajax запросы
if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {return;}

// Сниппет будет обрабатывать не один вид запросов, поэтому работать будем по запрашиваемому действию
// Если в массиве POST нет действия - выход
if (empty($_POST['action'])) {return;}

// А если есть - работаем
$res = '';
switch ($action) {	
	case 'repeatOrder':
	   $orderProds = $_POST['orderProds'];
	   $orderProds = json_decode($orderProds);
	   foreach($orderProds as $prod_id => $prod_count){
	        $response .= $miniShop2->cart->add($prod_id, $prod_count);
	        $response .= '|';
	  }
	    $res = $response;
	break;	
}

// Если у нас есть, что отдать на запрос - отдаем и прерываем работу парсера MODX
if (!empty($res)) {
	die($res);
}
Думаю тут далеко не всё хорошо, но код работает исправно. И в совокупности делает почти тоже самое что и сниппет OfficeMiniShop2, только внешний вид можно легко настроить под дизайн сайта.
    Андрей Шевяков
    20 декабря 2019, 22:48
    +1
      Артур
      23 декабря 2019, 10:30
      0
      Как вариант, но самому всегда интереснее сделать. Тем более это не так уж и сложно)))
      SEQUEL.ONE
      21 декабря 2019, 04:25
      +1
      Если есть компонент Office, то можно еще так сделать docs.modx.pro/komponentyi/office/kontrolleryi/istoriya-zakazov-ms2 единственный минус это адаптивность. Таблицы сгенеренные через ExtJS сложно кастомизируются.
        Артур
        23 декабря 2019, 10:31
        +1
        Собственно именно поэтому я и заморочился)))
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        5