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

Возникла необходимость добавления нового поля в таблицу заказов.
В документации не нашёл ничего по этому вопросу. Также как и в поиске ничего дельного.
В документации сказано, что есть 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
modx.pro
13
3 832
0
Поблагодарить автора Отправить деньги

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

Николай
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
              Обновил заметку с решением
                Сергей
                26 апреля 2019, 22:55
                0
                Способ рабочий на сегодня? а то вроде все по описанной схеме делал — все никак не появляется новое поле в админке.
                  Николай
                  27 апреля 2019, 13:05
                  0
                  Недавно совсем делал, должно работать. Ошибок в консоли нет? Доступ к полю через API работат? В системных настройках есть новое поле?
                    Сергей
                    28 апреля 2019, 22:20
                    0
                    Не, сейчас заработало, не там искал, спасибо. Теперь загвоздка в том, что оно из формы заказа в hidden input не записывается в БД. Через админку, если пересохранять значение в поле, меняется. А вот через форму заказа, не прокатывает. Нужно плагин дополнительный вешать?
                      Николай
                      28 апреля 2019, 22:40
                      +1
                      Мой вариант работает с таблицей заказов в админке. Т.е., чтобы из этой таблицы значение в БД записывалось. Если речь про всплывающие формы, то там уже надо их тоже кастомизировать. Навскидку не знаю, надо разбираться, сам в этих делах плаваю ещё.
                        Сергей
                        28 апреля 2019, 23:08
                        0
                        Не, кастомизировать как раз всплывающую форму у меня получилось. Вопрос именно во фронте, чтобы обычный пользователь смог записать данные в кастомное поле.
                          Николай
                          28 апреля 2019, 23:23
                          +1
                          Форма с необходимыми инпутами делает запрос на какой-то php-скрипт, который производит всю работу. Могу лишь порекомендовать это видео, как грамотно передать данные из фронта в бэкенд. Там уже в процессоре можно писать что угодно, и как угодно обновлять записи в БД, общаться с фронтом и т.д.
                            Сергей
                            29 апреля 2019, 12:09
                            0
                            Спасибо, поизучаю.
              Николай
              25 марта 2019, 13:45
              0
              Можно не переопределять целиком метод getColumns, а как-то через прототип добавить к существующему массиву новое поле. Но пока не знаю как это сделать.
                Михаил
                29 января 2020, 09:44
                0
                А как подключить плагин? В каком файле он подключается?
                  Михаил
                  29 января 2020, 12:34
                  0
                  Просто тут написано:
                  «Далее как описано в статье подключаем плагин:if ($miniShop2 = $modx->getService('miniShop2')) {
                  $miniShop2->addPlugin('order_table', '{core_path}components/minishop2/custom/order_table/index.php');
                  }», а в статье это не описано. От сюда и всё запара с этим мануалом…
                    Алексей Шумаев
                    29 января 2020, 14:43
                    0
                    Хм. Вам тоже похоже это нужно: https://modx.pro/solutions/10040#comment-117319
                    Точнее это: https://modx.pro/solutions/7037.
                    Берите на вооружение.
                      Николай
                      29 января 2020, 15:44
                      0
                      В разделе Подключение:

                      if ($miniShop2 = $modx->getService('miniShop2')) {
                          $miniShop2->addPlugin('msplColor', '{core_path}components/msplcolor/index.php');
                      }


                      Там прописывается путь к файлу, он может быть произвольным, код этого файла в разделе Принцип работы:

                      <?php
                      
                      return array(
                          'map' => array(
                              'msProductData' => require_once 'msproductdata.inc.php',
                          ),
                          'manager' => array(
                              'msProductData' => MODX_ASSETS_URL . 'components/msplcolor/msproductdata.js',
                          ),
                      );
                      Этот же файл как видно ссылается ещё на 2 других. msproductdata.inc.php лежит рядом с текущим, а js в папке assets.

                      В общем, пути могут быть разные. Можно расширить модель через плагин OnMODXInit, но это чисто для БД сработает. В смысле что в скриптах из БД можно будет вытащить значения, а в админке они нигде фигурировать не будут.
                    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                    25