Дробные числа в заказах (решение?)

Пишу для будущего себя и для таких же как я чайников. Версия minishop2-2.5.0-pl
Долго мучался над вопросом, как сделать не целые числа в minishop2 и нашел таки мануал и немного его переделал, как мне кажется в более правильную сторону. В мануале предлагается изменять файл ядра, вместо того чтобы расширить класс, что не есть хорошо, потому как этот файл затрется при обновлении. Поэтому, я взял кусок класса отсюда и переделал его под себя по совету отсюда

И так:

1) Чтобы расширить класс корзины, создал файл:
/core/components/minishop2/custom/cart/CartHandlerCustom.class.php

Со следующим содержимым:

<?php
class CartHandlerCustom extends msCartHandler {
    public function add($id, $count = 1, $options = array())
    {
        if (empty($id) || !is_numeric($id)) {
            return $this->error('ms2_cart_add_err_id');
        }
        $count = floatval($count); // Вот эту строку только исправил с intval на floatval
        if (is_string($options)) {
            $options = json_decode($options, true);
        }
        if (!is_array($options)) {
            $options = array();
        }

        $filter = array('id' => $id);
        if (!$this->config['allow_deleted']) {
            $filter['deleted'] = 0;
        }
        if (!$this->config['allow_unpublished']) {
            $filter['published'] = 1;
        }
        /** @var msProduct $product */
        if ($product = $this->modx->getObject('modResource', $filter)) {
            if (!($product instanceof msProduct)) {
                return $this->error('ms2_cart_add_err_product', $this->status());
            }
            if ($count > $this->config['max_count'] || $count <= 0) {
                return $this->error('ms2_cart_add_err_count', $this->status(), array('count' => $count));
            }

            /* You can prevent add of product to cart by adding some text to $modx->event->_output
              <?php
                    if ($modx->event->name = 'msOnBeforeAddToCart') {
                        $modx->event->output('Error');
                    }

            // Also you can modify $count and $options variables by add values to $this->modx->event->returnedValues
                <?php
                      if ($modx->event->name = 'msOnBeforeAddToCart') {
                        $values = & $modx->event->returnedValues;
                        $values['count'] = $count + 10;
                        $values['options'] = array('size' => '99');
                    }
            */

            $response = $this->ms2->invokeEvent('msOnBeforeAddToCart', array(
                'product' => $product,
                'count' => $count,
                'options' => $options,
                'cart' => $this,
            ));
            if (!($response['success'])) {
                return $this->error($response['message']);
            }
            $price = $product->getPrice();
            $weight = $product->getWeight();
            $count = $response['data']['count'];
            $options = $response['data']['options'];

            $key = md5($id . $price . $weight . (json_encode($options)));
            if (array_key_exists($key, $this->cart)) {
                return $this->change($key, $this->cart[$key]['count'] + $count);
            } else {
                $this->cart[$key] = array(
                    'id' => $id,
                    'price' => $price,
                    'weight' => $weight,
                    'count' => $count,
                    'options' => $options,
                    'ctx' => $this->modx->context->get('key'),
                );
                $response = $this->ms2->invokeEvent('msOnAddToCart', array('key' => $key, 'cart' => $this));
                if (!$response['success']) {
                    return $this->error($response['message']);
                }

                return $this->success('ms2_cart_add_success', $this->status(array('key' => $key)),
                    array('count' => $count));
            }
        }

        return $this->error('ms2_cart_add_err_nf', $this->status());
    }
}
Это для того, чтобы не затерлось при обновлении. Из всего этого кода разница от оригинального msCartHandler.class.php только в одной строке:
$count = intval($count);
я заменил на:
$count = floatval($count);
Не знаю, нужно ли для этого тащить сюда полностью всю функцию или можно ограничиться каким-то маленьким кусочком?

2) В файле:
core/components/minishop2/model/minishop2/mysql/msorderproduct.map.inc.php

Блок:
'count' => 
    array (
      'dbtype' => 'int',
      'precision' => '10',
      'phptype' => 'integer',
      'attributes' => 'unsigned',
      'null' => true,
      'default' => 1,
    ),
Исправил на:
'count' => 
    array (
      'dbtype' => 'decimal',
      'precision' => '10,2',
      'phptype' => 'float',
      'null' => true,
      'default' => 1,
    ),
'precision' => '10,2' — двойка после 10 — это сколько знаков после запятой может хранить база. Надо не забыть исправить

3) В файле:
core/components/minishop2/model/schema/minishop2.mysql.schema.xml
Заменил строку:
<field key="count" dbtype="int" precision="10" phptype="integer" attributes="unsigned" null="true" default="1"/>
на:
<field key="count" dbtype="decimal" precision="10,2" phptype="float"  null="true" default="1"/>
4) В базе через phpMyAdmin находим таблицу modx_ms2_order_products, если не меняли префикс. В ней полю count меняем тип на float(10,2) и сохраняем.

5) ВСЁ. Вроде все работает, заказы уходят с дробными цифрами, в админке их так же видно и можно менять так же на дробные.

ВОПРОС
Теперь, знатоки, пожалуйста, поправьте меня если что-то не так или где-то есть косяки которые могут вылезти позже.

1) Смущает то, что пришлось редактировать файлы core/components/minishop2/model/minishop2/mysql/msorderproduct.map.inc.php
и
core/components/minishop2/model/schema/minishop2.mysql.schema.xml

Можно их как-то так же «расширить»? :))

2) Вот тут в той же статье Руслан Сафин рекомендует еще одно изменение:
необходимо так же в default.js поправить строку
if (status['total_count'] < 1) {
    location.reload();
}
на строку
if (status['total_count'] < 0.1) {
    location.reload();
}
у меня это 283 — 285 строка

Без этой правки при добавлении в корзину страница будет перезагружаться, пока количество товара в корзине не достигнет единицы
У меня вроде ничего не перезагружается, либо я не понял что он имеет ввиду под этим словом. Может и перезагружается а я этого не вижу? Нужно ли реально это делать? И если нужно, то так же редактируем сам файл default.js или можно подключить к нему так же что-то свое кастомное не изменяя оригинальный файл?
Algirdas
04 июня 2020, 16:43
modx.pro
1
732
0

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

Algirdas
12 июня 2020, 10:07
0
Лес рук )))

Обнаружилась проблема, при попытке добавить количество меньше 1, то есть 0.3 например, minishop2 ругается что количество не может быть 0. Подскажите пожалуйста, где это исправить?
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    1