Применение промокода к заказу в админке

Внимание! Это готовое решение. Для переноса не хватает рейтинга.
Всем привет. Была задача сделать применение промокода к заказу из админки, собственно, чего я и сделал и готов поделиться с сообществом готовым решением.

Версии компонентов, на которых тестировалось решение:
На более ранних версиях не тестировал. Если пробуете, то делайте на свой страх и риск.
miniShop2 2.4.15-pl
msPromocode 1.3.11-beta

Создаём js файл, путь которого assets/components/minishop2/js/mgr/orders/orders.window.extends.js

Напоминаю, список заказов придётся обновлять вручную, чтобы обновить в списке цену. Так же с продуктами в окне и плашкой сверху, которая отображает номер промокода и сумму. Либо менеджер вручную обновляет, либо дописываем сами, обращаясь к процессору по ajax запросу. В окне заказа после применения или отмены промокода цены обновятся.

Собственно, сам код:
Ext.ComponentMgr.onAvailable('minishop2-window-order-update', function() {
    var self = this;

    var fields = this.fields.items[0].items;

    fields.push({
        layout: "column",
        defaults: {
            msgTarget: "under",
            border: false
        },
        style: "",
        items: [{
                columnWidth: .48,
                layout: "form",
                items: [{
                    xtype: "textfield",
                    name: "order_promo_code",
                    fieldLabel: "Промокод",
                    anchor: "100%",
                    id: "mspc_field",
                    listeners: {
                        render: function(field) {
                            MODx.Ajax.request({
                                url: msPromoCode.config.connector_url,
                                params: {
                                    action: "mgr/order/get",
                                    order_id: self.record.id,
                                },
                                listeners: {
                                    'success': {
                                        fn: function® {
                                            field.setValue(r.object.code);

                                            mspcToggle(true, {
                                                cancel: false
                                            });
                                        },
                                        scope: this
                                    },
                                    'failure': {
                                        fn: function() {
                                            mspcToggle(true, {
                                                field: false,
                                                apply: false
                                            });
                                        }
                                    }
                                }
                            });
                        }
                    }
                }]
            },
            {
                columnWidth: .52,
                layout: "column",
                defaults: {
                    msgTarget: "under",
                    border: false
                },
                style: "",
                items: [{
                        columnWidth: .48,
                        xtype: "button",
                        hideLabel: true,
                        text: "Применить",
                        cls: "mspc-btn-primary3",
                        id: "apply_mspc",
                        anchor: "100%",
                        style: "padding:5px 5px 7px; margin-top: 37px;",
                        listeners: {
                            click: {
                                fn: function() {
                                    var mask_body = new Ext.LoadMask(Ext.getBody(), {
                                        msg: "Please wait..."
                                    });
                                    var mask_win = new Ext.LoadMask(Ext.getCmp("minishop2-window-order-update").getEl(), {
                                        msg: "Идет применение..."
                                    });

                                    mask_body.show();
                                    mask_win.show();

                                    var discount_field = Ext.getCmp("mspc_field");
                                    var discount_code = discount_field.getValue();

                                    MODx.Ajax.request({
                                        url: document.location.href,
                                        params: {
                                            action: "apply_mspc",
                                            order_id: self.record.id,
                                            discount_code: discount_code,
                                        },
                                        listeners: {
                                            'success': {
                                                fn: function(response) {
                                                    MODx.Ajax.request({
                                                        url: miniShop2.config.connector_url,
                                                        params: {
                                                            action: "mgr/orders/get",
                                                            id: self.record.id
                                                        },
                                                        listeners: {
                                                            'success': {
                                                                fn: function® {
                                                                    mask_body.hide();
                                                                    mask_win.hide();

                                                                    var w = Ext.getCmp("minishop2-window-order-update");
                                                                    w.setValues(r.object);

                                                                    mspcToggle(true, {
                                                                        cancel: false
                                                                    });

                                                                    MODx.msg.alert(
                                                                        _("success"),
                                                                        response.msg
                                                                    );
                                                                },
                                                                scope: this
                                                            }
                                                        }
                                                    });
                                                },
                                                scope: this
                                            },
                                            'failure': {
                                                fn: function(response) {
                                                    mask_body.hide();
                                                    mask_win.hide();
                                                },
                                                scope: this
                                            },
                                        }
                                    });
                                },
                                scope: this
                            }
                        }
                    },
                    {
                        columnWidth: .48,
                        xtype: "button",
                        hideLabel: true,
                        text: "Отменить",
                        cls: "mspc-btn-primary3",
                        id: "cancel_mspc",
                        anchor: "100%",
                        style: "padding:5px 5px 7px; margin-top: 37px;",
                        listeners: {
                            click: {
                                fn: function() {
                                    MODx.Ajax.request({
                                        url: document.location.href,
                                        params: {
                                            action: "cancel_mspc",
                                            order_id: self.record.id,
                                        },
                                        listeners: {
                                            'success': {
                                                fn: function(response) {
                                                    MODx.Ajax.request({
                                                        url: miniShop2.config.connector_url,
                                                        params: {
                                                            action: "mgr/orders/get",
                                                            id: self.record.id
                                                        },
                                                        listeners: {
                                                            'success': {
                                                                fn: function® {
                                                                    var w = Ext.getCmp("minishop2-window-order-update");
                                                                    w.setValues(r.object);

                                                                    mspcToggle(true, {
                                                                        field: false,
                                                                        apply: false
                                                                    });

                                                                    MODx.msg.alert(
                                                                        _("success"),
                                                                        response.msg
                                                                    )
                                                                },
                                                                scope: this
                                                            }
                                                        }
                                                    });
                                                }
                                            },
                                            scope: this
                                        }
                                    });
                                },
                                scope: this
                            }
                        }
                    }
                ]
            }
        ]
    });

    var mspcToggle = function(state, button) {
        var field = Ext.getCmp("mspc_field");
        var apply = Ext.getCmp("apply_mspc");
        var cancel = Ext.getCmp("cancel_mspc");

        if (typeof button !== 'undefined') {
            if (typeof button.apply === 'undefined') {
                button.apply = true;
            }

            if (typeof button.cancel === 'undefined') {
                button.cancel = true;
            }

            if (typeof button.field === 'undefined') {
                button.field = true;
            }
        } else {
            button = {
                apply: true,
                cancel: true,
                field: true
            };
        }

        if (button.apply) {
            apply.setDisabled(true);
        } else {
            apply.setDisabled(false);
        }

        if (button.cancel) {
            cancel.setDisabled(true);
        } else {
            cancel.setDisabled(false);
        }

        if (button.field) {
            field.setDisabled(true);
        } else {
            field.setDisabled(false);
        }
    };
});

Далее, создаём плагин и обзываем как хотим :)
Проставляем в нём галочками такие события, как OnManagerPageBeforeRender и OnHandleRequest
<?php
if (!function_exists(getMspc)) {
    function getMspc()
    {
        global $modx;
        
        $path = MODX_CORE_PATH . 'components/mspromocode/model/mspromocode/';
        $mspc = $modx->getService('mspromocode', 'msPromoCode', $path, array(
            'ctx' => $modx->context->key
        ));
        
        return ($mspc instanceof msPromoCode) ? $mspc : false;
    }
    
}
switch ($modx->event->name) {
    case 'OnManagerPageBeforeRender':
        if ($modx->controller->config['controller'] == 'mgr/orders') {
            if ($miniShop2 = $modx->getService('miniShop2')) {
                $modx->controller->addLastJavascript($miniShop2->config['jsUrl'] . 'mgr/orders/orders.window.extends.js');
            }
        }
        break;
    
    case 'OnHandleRequest':
        if ($modx->context->key != 'mgr') {
            return;
        }
        
        switch ($_REQUEST['action']) {
            case 'apply_mspc':
                $mspc = getMspc();
                
                $msg     = $modx->lexicon('mspromocode_enter_promocode');
                $success = false;
                
                $order_id = $_REQUEST['order_id'];
                
                $discount_code = trim($_REQUEST['discount_code']);
                
                $order = $modx->getObject('msOrder', $order_id);
                
                if (!empty($discount_code)) {
                    if ($mspc) {
                        foreach ($order->getMany('Products') as $key => $product) {
                            $mspc->cart[$key] = $product->toArray();
                        }
                        
                        if ($coupon = $mspc->coupon->setCurrentCoupon($discount_code)) {
                            $success = true;
                            
                            $mspc->discount->setDiscountForCart($coupon['id']);
                            
                            $sp = array(
                                'msOrder' => $order,
                                'order' => $order
                            );
                            
                            $mspc->msOnCreateOrder($sp);
                            
                            foreach ($mspc->cart as $key => $product) {
                                $modx->runProcessor('mgr/orders/product/update', array(
                                    'id' => $product['id'], // тут внимательнее, нужен id товара из таблицы prefix_ms2_order_products,
                                    'count' => $product['count'], // это количество, которое надо установить
                                    'price' => $product['price'] // это цена товара за штуку. сумму процессор посчитает сам
                                ), array(
                                    'processors_path' => MODX_CORE_PATH . 'components/minishop2/processors/'
                                ));
                            }
                            
                            $mspc->discount->removeDiscountFromCart(true);
                            $mspc->ms2->cart->clean();
                            
                            $msg = $modx->lexicon('mspromocode_ok_code_apply');
                        } else {
                            $msg = $mspc->getError();
                        }
                    }
                }
                break;
            
            case 'cancel_mspc':
                $order_id = $_REQUEST['order_id'];
                $order    = $modx->getObject('msOrder', $order_id);
                
                $mspc = getMspc();
                
                if ($mspc) {
                    $success = true;
                    
                    $mspcOrder = $modx->getObject('mspcOrder', array(
                        'order_id' => $order_id
                    ));
                    
                    $mspcOrder->remove();
                    
                    foreach ($order->getMany('Products') as $key => $product) {
                        $data  = $product->toArray();
                        $price = $modx->getObject('msProduct', $data['product_id'])->get('price');
                        
                        $modx->runProcessor('mgr/orders/product/update', array(
                            'id' => $data['id'], // тут внимательнее, нужен id товара из таблицы prefix_ms2_order_products,
                            'count' => $data['count'], // это количество, которое надо установить
                            'price' => $price // это цена товара за штуку. сумму процессор посчитает сам
                        ), array(
                            'processors_path' => MODX_CORE_PATH . 'components/minishop2/processors/'
                        ));
                    }
                    
                    $msg = $modx->lexicon('mspromocode_ok_code_remove');
                }
                break;
        }
        
        if (isset($msg)) {
            $output = $modx->toJSON(array(
                "success" => $success,
                "msg" => $msg,
                'message' => $msg
            ));
            exit($output);
        }
        break;
}

Далее, создаём заказ или смотрим имеющийся, ctrl + F5, открываем, радуемся.
Если есть вопросы, задавайте.
Кирилл Киселев
19 октября 2018, 18:09
modx.pro
1
831
+2

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

Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
0