Олег Щавелев

Олег Щавелев

Был в сети 24 июня 2024, 15:51
Заказы принимаю
DocentBF
DocentBF
2
+1
На примере CSV.
1. Создаем кнопку, например, в верхнем баре:
getTopBar: function() { return [{
            text: '<i class="icon icon-chevron-up"></i> ' + _('modExtra_items_export'),
            handler: this.exportCSV, // функция-обработчик кнопки
            scope: this
}]

2. Добавляем виджет-окно импорта с выбором файла:
modExtra.window.ImportCSV = function(config) {
    config = config || {};
    this.ident = config.ident || 'modextra'+Ext.id();
    Ext.applyIf(config,{
        title: _('modextra_items_import')
        ,id: this.ident
        ,fileUpload: true
        ,autoHeight: true
        ,width: 650
        ,url: modExtra.config.connector_url
        ,action: 'mgr/item/import' // процессор загрузки и обработки файла, находится по пути modExtra/processors/mgr/item/import.class.php
        ,fields: [
            {
                xtype: 'fileuploadfield',
                fieldLabel: _('modextra_window_import_file'),
                allowBlank: false
            }
        ]
        ,keys: [
            {
                key: Ext.EventObject.ENTER
                ,shift: true
                ,fn: function() {this.submit() }
                ,scope: this
            }
        ]
    });
    modExtra.window.ImportCSV.superclass.constructor.call(this,config);
};
Ext.extend(modExtra.window.ImportCSV,MODx.Window);
Ext.reg('modextra-window-import-csv',modExtra.window.ImportCSV);
3. Создаете handler кнопки, расширяя grid:
Ext.extend(modExtra.grid.Items, MODx.grid.Grid, {
    windows: {},
    importCSV: function (btn, e) {
        if (!this.windows.ImportCSV) {
            this.windows.ImportCSV = MODx.load({
                xtype: 'modextra-window-import-csv'
                ,listeners: {
                    'success': {fn:function(){this.refresh();},scope:this}
                    ,'failure': {fn:function(){console.log("error")}}
                }
            });
        }
        this.windows.ImportCSV.fp.getForm().reset();
        this.windows.ImportCSV.show(e.target);
    },
    ...
4. Создаем процессор импорта (/core/components/modextra/processors/mgr/item/import.class.php):
<?php
/**
 *  Import
 */
include_once MODX_CORE_PATH . 'model/modx/processors/browser/file/upload.class.php';
class modExtraImportProcessor extends modBrowserFileUploadProcessor {
    public $objectType = 'modExtraItem';
    public $classKey = 'modExtraItem';
    public $languageTopics = array('modExtra');

    public function initialize() {
        $this->setDefaultProperties(array(
            'source' => 0,
            'path' => 'assets/components/modExtra/files/',
        ));
        if (!$this->getProperty('path')) return $this->modx->lexicon('file_folder_err_ns');
        return true;
    }

    /** {inheritDoc} */
    public function process(){
        if (!$this->getSource()) {
            return $this->failure($this->modx->lexicon('permission_denied'));
        }
        $this->source->setRequestProperties($this->getProperties());
        $this->source->initialize();
        $this->source->setProperties(array('basePath'=>''));
        if (!$this->source->checkPolicy('create')) {
            return $this->failure($this->modx->lexicon('permission_denied'));
        }
        $success = $this->source->uploadObjectsToContainer($this->getProperty('path'),$_FILES);
        $file_n = current($_FILES);
        $file = is_array($_FILES) ? $file_n['name'] : false;

        if (empty($success) || !$file) {
            $msg = '';
            $errors = $this->source->getErrors();
            foreach ($errors as $k => $msg) {
                $this->modx->error->addField($k,$msg);
            }
            return $this->failure($msg);
        } else {
            $file = $_SERVER['DOCUMENT_ROOT'].'/'.$this->getProperty('path').$file;
            if(($handle = fopen($file,"r"))) {
                while(($data = fgetcsv($handle,null,';'))) {
                    /*
                        Далее код разборки CSV и сохранение нового объекта
                        $rec = $modx->newObject();
                        $rec->set('field', $data[$n])
                        $rec->save();
                    */                    
                }
                @unlink($file);
            }
        }
        return $this->success();
    }


}

return 'modExtraImportProcessor';
Код написан на скорую руку, может быть кто-то поправит?)
stas
stas
3
0
Хотя я придумал, я просто засовываю принудительно сколько мне нужно товаров и если клиент ввел больше вывожу ваше сообщение

$cartArray = $cart->get(); // Массив корзины
$cartStatus = $cart->status(); // Состояние корзины
$totalCount = $cartStatus['total_count']; // Общее количество товаров в корзине
foreach ($cartArray as &$cartProduct) { // Обрабатываем все товары корзины
  if ($product = $modx->getObject('msProduct', $cartProduct['id'])) { // Получаем объект товара по его ID в корзине
    $quanity = $product->getTVValue('quantity');
    $quanity1 = $cartProduct["count"];
    if($quanity1 > $quanity){
      $cartProduct['count'] = $quanity;
      $modx->event->output('Вы пытаетесь положитель больше товаров чем есть в наличии');
    }
  }
}
$cart->set($cartArray); // Запись нового состояния корзины
Спасибо вам огромное!!!
Максим Кузнецов
Максим Кузнецов
3
+3
Задача решается путем реализации 2х составляющих:

1. Js (идентификатор и алерт заменить на подходящие себе):
$( ".ms2_form input[name='count']" ).change(function() {
	$.jGrowl("Минимальное количество товаров для заказа - 5 шт", {theme: 'error', position: 'center'});
	$(this).val("5");
});

2. Плагин на события msOnBeforeAddToCart и msOnBeforeChangeInCart
<?php
if ($modx->event->name = 'msOnBeforeAddToCart' || $modx->event->name = 'msOnBeforeChangeInCart') {
	$values = & $modx->event->returnedValues;
	if ($values['count'] < 5) {
		$values['count'] = 5;
	}
}
— как-то так.
Антон Фомичёв
Антон Фомичёв
1
0
Вижу два варианта.

Первый:
1. У каждой из форм есть атрибут id, а так же тэг
<input type="hidden" name="formid" value="[[+значение атрибута id]]">
2. Сниппет должен вместе с основным ответом возвращать значение $_POST['formid'] виде {«formid»:«значение»}.
3. Тогда обработчик события выглядит следующим образом:
$(document).on('af_complete', function(event,res) {
	var form = $("#"+res.formid);
	if(!res.success){
		form.find('[name="' + res.key + '"]').addClass('error');
	}
});
Второй:
1. Через гитхаб или как-то по-другому предложить Василию изменить часть кода default.js таким образом:
$(document).trigger("af_complete", response, form);
2. Если коммит будет принят, то тогда твой скрипт будет выглядеть так:
$(document).on('af_complete', function(event,res,form) {
	var $form = $(form);
	if(!res.success){
		$form.find('[name="' + res.key + '"]').addClass('error');
	}
});
Антон Фомичёв
Антон Фомичёв
1
0
Я бы предложил что-то такое:

$(document).on('af_complete', function(event,res) {
	if(!res.success){
		form.find('[name="' + res.key + '"]').addClass('error');
	}
});
При этом, не забудь определить переменную form (она должна содержать объект jQuery).
Ну и твой сниппет должен отдавать json с полями success и key по меньшей мере.
grasp graspoff
grasp graspoff
3
+1
class myDelivery extends msDeliveryHandler {
    public function getCost(msOrderInterface $order, msDelivery $delivery, $cost=0) {
    $totalCostDL=0;
    $products=$this->ms2->cart->get();
    foreach($products as $product){
        $costDL=$this->getPrDlCost($product);
        $totalCostDL += $costDL;
    }
    $cost += $totalCostDL;
    return $cost;
	}
Ну и функция с логикой
private function getPrDlCost($product) {
        $PrDlCost=1000000;
        $pids = $this->modx->getParentIds($product['id'],1);
        $PrCategory = $pids[0];
        $PrCount = $product[count];
        switch ($PrCategory) {
	case '67': 
				if ($PrCount <= 6) $PrDlCost = 1200;
				if ($PrCount > 6 && $PrCount <= 15) $PrDlCost = 1700;
				if ($PrCount > 15 && $PrCount < 25) $PrDlCost = 3900;
				if ($PrCount >= 25) $PrDlCost = 0;
                break;
		....
	}

Peter Zenin
Peter Zenin
1
0
Извиняюсь, я туплю, нашел где их добавлять, производителей.

Просто я пытаюсь дополнительное поле сделать с выпадающим списком как vendor
Мне надо чтоб искал из поля в таблице msProducts и подставлял, а если поля нет, то текущий оставлял, чтоб можно было сохранить и добавить.

Оказывается vendor нее очень удачный пример для копирования, т.к. там автоматом выставляется ноль, если ничего не выбрано…

Даже не представляю по какому примеру сделать автозаполняемое поле из уже существующих значений (чтоб подбирал только разные), а если ничего не выбрано то оставлял текущее.

Подскажите с чего можно подсмотреть подобный функционал?

Заранее благодарю!