Применение промокода к заказу в админке
Внимание! Это готовое решение. Для переноса не хватает рейтинга.Всем привет. Была задача сделать применение промокода к заказу из админки, собственно, чего я и сделал и готов поделиться с сообществом готовым решением.
Версии компонентов, на которых тестировалось решение:
На более ранних версиях не тестировал. Если пробуете, то делайте на свой страх и риск.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, открываем, радуемся.
Если есть вопросы, задавайте.