[Решено] Как добавить новое поле в таблицу заказов?

Возникла необходимость добавления нового поля в таблицу заказов.
В документации не нашёл ничего по этому вопросу. Также как и в поиске ничего дельного.
В документации сказано, что есть 4 вида служб — cart, order, delivery, payment
А order как я понял отвечает за процесс оформления заказа, а не за таблицу.
Если создать новый столбец в таблице modx_ms2_orders, а потом произвести изменения в файлах:

/assets/components/minishop2/js/mgr/orders/orders.grid.js
/core/components/minishop2/model/minishop2/mysql/msorder.map.inc.php
/core/components/minishop2/model/schema/minishop2.mysql.schema.xml
То всё ок, поле появится. Но ведь при обновлении минишопа изменения потрутся…

А как можно кастомизировать таблицу, чтобы не трогать родные файлы?

РЕШЕНИЕ (25.03.2019)

Создаём плагин по принципу, описанному в статье Плагины товаров. Сначала вручную добавляем новое поле в БД (таблица modx_ms2_orders). Затем в произвольном месте каталога core/components создаём папку, где будет лежать плагин.

В ней будет 2 файла: index.php и msorder.inc.php, например:

index.php
<?php

return array(
    'map' => array(
        'msOrder' => require_once 'msorder.inc.php',
    )
);

msorder.inc.php
<?php

return array(
    'fields' => array(
        'products_custom' => 0.0,
    ),
    'fieldMeta' => array(
        'products_custom' => array(
            'dbtype' => 'decimal',
            'precision' => '12,2',
            'phptype' => 'float',
            'null' => true,
            'default' => 0.0,
        ),
    ),
);

Название поля, тип, и т.д., по вашему усмотрению.

Далее как описано в статье подключаем плагин:
if ($miniShop2 = $modx->getService('miniShop2')) {
    $miniShop2->addPlugin('order_table', '{core_path}components/minishop2/custom/order_table/index.php');
}

Название плагина произвольное, в пути нужно указать путь к файлу index.php. Просмотреть список подключённых плагинов можно в консоли (возможно, потребуется очистить кеш):
echo print_r(json_decode($modx->getOption('ms2_plugins')), 1);

После этого minishop2 видит это поле, к нему можно обращаться по API.

Далее нужно вывести поле в таблице заказов.
Создаём плагин на событие msOnManagerCustomCssJs:
<?php
switch ($modx->event->name) {
    case 'msOnManagerCustomCssJs':
        if ($page != 'orders') return;
        	$modx->controller->addLastJavascript(MODX_ASSETS_URL . 'components/minishop2/custom/default.js');
    break;
}

В скрипте default.js мы переопределяем метод getColumns и добавляем в него поле products_custom:
Ext.override(miniShop2.grid.Orders, {
    getColumns: function() {
        var all = {
            id: {width: 35},
            customer: {width: 100, renderer: function(val, cell, row) {
                return miniShop2.utils.userLink(val, row.data['user_id'], true);
            }},
            num: {width: 50},
            receiver: {width: 100},
            createdon: {width: 75, renderer: miniShop2.utils.formatDate},
            updatedon: {width: 75, renderer: miniShop2.utils.formatDate},
            cost: {width: 50, renderer: this._renderCost},
            cart_cost: {width: 50},
            delivery_cost: {width: 75},
            products_custom: {width: 75},
            weight: {width: 50},
            status: {width: 75},
            delivery: {width: 75},
            payment: {width: 75},
            //address: {width: 50},
            context: {width: 50},
            actions: {width: 75, id: 'actions', renderer: miniShop2.utils.renderActions, sortable: false},
        };

        var fields = this.getFields();
        var columns = [];
        for (var i = 0; i < fields.length; i++) {
            var field = fields[i];
            if (all[field]) {
                Ext.applyIf(all[field], {
                    header: _('ms2_' + field),
                    dataIndex: field,
                    sortable: true,
                });
                columns.push(all[field]);
            }
        }

        return columns;
    }
})

Оригинал метода, который переопределяем лежит тут: assets/components/minishop2/js/mgr/orders/orders.grid.js

Далее в Системных настройках (minishop2-Заказы) нужно добавить в ms2_order_grid_fields новое поле products_custom, а потом добавить запись в словаре: minishop2-ru-manager. Возможно, потребуется обновить кеш браузера, чтобы его увидеть в таблице заказов.
Николай
29 мая 2017, 11:00
2
1 569
0
Поблагодарить автора Отправить деньги

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

Николай
29 мая 2017, 14:04
0
И ещё один вопрос. В полях таблицы заказов выводятся статические данные из БД. А если нужно вывести динамические. Например, посчитать сколько было сделано заказов данным покупателем, или, сколько времени прошло с момента последнего заказа. Как это можно сделать?
Дмитрий Меркурьев
29 мая 2017, 17:14
0
Посмотрите тут
    Николай
    02 июня 2017, 08:51
    0
    Этот пост видел, но как я понял там нет способа прикручивания нового поля к таблице заказа…
Волков Николай
29 мая 2017, 22:56
0
Врать не буду, но беглый взгляд на способ Дмитрия мне не особо понравился чем-то.

Самый простой способ — прочитать документацию к минишопу. Конкретно вот это:
docs.modx.pro/components/minishop2/development/plug-ins-products

Единственное, нужно передавать в массиве не«msProductData», а «msOrder».

Плюс не уверен, что прокатит как указано в расширении админки, поэтому может потребоваться альтернативный вариант. Если нужно будет, то потом могу подсказать как.
    Николай
    02 июня 2017, 08:57
    0
    Да, знаю про плагины, но думал не работает для таблицы заказов. Оказалось работает, система видит новое поле. Но в таблице оно не появляется, либо я что-то делаю не так… По аналогии со статьёй делаю примерно так:

    miniShop2.plugin.newfield = {
        getFields: function () {
            return {
                newfield: {
                    xtype: 'textfield',
                    /* description: '<b>[[+color]]</b><br />' + _('ms2_product_color_help') */
                }
            }
        },
        getColumns: function () {
            return {
                newfield: {
                    width: 50,
                    sortable: false,
                    editor: {
                        xtype: 'textfield',
                        name: 'newfield'
                    }
                }
            }
        }
    };

    Если нужно будет, то потом могу подсказать как.
    Нужно, до сих пор актуально :)
      Stan Ezersky
      16 октября 2017, 22:30
      0
      Николай, решили вопрос?
      У меня в базу данные заливаются, в админку не могу вывести
        Николай
        16 октября 2017, 22:36
        0
        К сожалению нет. Пришлось всё сделать путём правки исходников минишопа, как я и описал в самом топике. Вопрос для меня до сих пор актуален. В тот раз весь форум перерыл, много чего перепробовал — не получилось…
          Stan Ezersky
          16 октября 2017, 22:41
          0
          Этот топик посмотрите
            Николай
            17 октября 2017, 01:29
            0
            Да, я знаю этот способ, и чуть выше в комментарии тоже работает, но проблема вывести данные в таблицу заказов. Возможно, проблему можно решить таким способом, там где в коде идёт скрипт добавляющий произвольный html-код в форму профиля пользователя. Но мне нужно много времени, чтобы это узнать, extjs не знаю…
Николай
02 июня 2017, 08:59
0
Неужели за столько лет пользования минишопом ни у кого не возникало необходимости в новом поле в таблице?) По крайней мере поиск по сайту ничего толкового не дал…
Станислав
03 октября 2017, 17:00
+1
Давно пора добавить в документацию инструкцию по расширению таблицы заказов. Лично мне потребовалось вывести столбец с emails покупателей.
Илья Александрович
25 марта 2019, 04:14
0
нашли решение не трогая исходников?
    Николай
    25 марта 2019, 13:36
    0
    Обновил заметку с решением
Николай
25 марта 2019, 13:45
0
Можно не переопределять целиком метод getColumns, а как-то через прототип добавить к существующему массиву новое поле. Но пока не знаю как это сделать.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.