Артур Шевченко

Артур Шевченко

С нами с 24 мая 2019; Место в рейтинге пользователей: #7
Отправить деньги
Артур Шевченко
31 января 2021, 08:37
0
Это вы типа модификации хотите сделать? Или что за другое изображение? А вообще самом простое это сделать TV типа migx с двумя колонками название цвета и путь к картинке, на фронте с помощью js менять картинку в зависимости от выбранного цвета.
Артур Шевченко
31 января 2021, 00:45
0
первое, попробуйте удалить папку с кешем. второе, скажите что делали перед тем как это случилось?
Артур Шевченко
30 января 2021, 12:28
0
А вы можете пошаговое решение написать или дать ссылку? Я бы почитал для саморазвития.
Артур Шевченко
30 января 2021, 00:53
0
То есть если товар есть в корзине, нужно это показать и дать возможность изменить его количество, верно понимаю?
Артур Шевченко
29 января 2021, 23:34
0
Ох, тяжело… Вы хотите чтобы на странице каталога, там где выводятся все товары из всех категорий и, возможно, есть фильтры, после нажатия на кнопку добавления в корзину, происходила проверка на наличие этого товара в корзине и если он там есть, то кнопка добавления должна скрываться и показываться поле для указания количества?
Артур Шевченко
29 января 2021, 18:39
0
Спасибо всем участвующим. Будем считать вопрос решённым.
Артур Шевченко
29 января 2021, 16:01
0
Ну суть та же, только я хотел обойтись без промежуточного массива. По факту
$resources = $modx->getIterator('msProduct', array('parent' => $resource->get('parent')));
Массив для пункта 1 можно вытащить только перебрав $resources. И да, с массивом работать удобнее, но п.3 это проблема. Давайте псевдокод напишу
$oldValue // старое значение позиции текущего ресурса
$newValue // новое значение
$resources // массив со всеми значениями [id => menuindex]
//По идее надо перебрать $resources предварительно сравнив $oldValue и $newValue
if($newValue < $oldValue){
foreach($resources as $r){
//надо прибавить  1 ко всем menuindex которые соответствуют  $newValue <= menuindex < $oldValue
}
else{
//надо отнять  1 ото всех menuindex которые соответствуют  $newValue > menuindex >= $oldValue
}
}
Но получается что если $newValue < $oldValue, то последнее значение не меняется.
Артур Шевченко
29 января 2021, 11:00
0
И вообще TV на самая большая проблема в этой задаче, самая большая проблема это я, потому что я не понимаю что не так, в голове и на бумаге логика безупречна, а код работает не правильно.
Артур Шевченко
29 января 2021, 10:58
0
Сорри, слово before не заметил)))
Артур Шевченко
29 января 2021, 10:50
0
Сразу скажу, с PayAndSee не работал, но он тут и не причём, вам нужно к информации о пользователе добавлять id оплаченной конфигурации, после чего уже при выводе проверять какая конфигурация(и) оплачена(ы), те и показывать. Логика простая, вот реализация у неподготовленного человека может вызвать проблемы. В самом простом варианте для записи данных о купленных модификациях я бы повесил плагин на создание заказа или на смену статуса, саму запись делал бы в поле extended объекта modUser, ну и для вывоза написал бы сниппет, который бы проверял что куплено и в соответствии с этим показывал только доступные файлы. Я бы действовал так. Думаю это не лучшее из возможных решений, но точно одно из простых.
Артур Шевченко
29 января 2021, 10:39
0
Почему вы считаете, что TV не сохраняется из плагина? У меня не далее как вчера сохранялась. И второй момент, почему вы считаете, что TV не нужно, ведь значение menuidex сохраняемого ресурса меняет не плагин, а пользователь, т.е. в плагин приходит уже новое значение.
Артур Шевченко
28 января 2021, 17:36
0
Я переписал код, но он всё равно как-то не так работает
<?php
switch ($modx->event->name) {
    case 'OnDocFormSave':
        $oldValue = $resource->getTVValue('old_value');
        $newValue = $resource->get('menuindex');
        $resource->setTVValue('old_value', $newValue);
        $resource->save();
        $resources = $modx->getIterator('msProduct', array('parent' => $resource->get('parent')));
        
        if($newValue < $oldValue){
            foreach($resources as $res){
                $menuindex = $res->get('menuindex');
               
                if($menuindex >= $newValue && $menuindex < $oldValue && $res->get('id') != $id){
                    $res->set('menuindex', $menuindex + 1);
                    $res->set('old_value', $menuindex + 1);
                }
                
                $res->save();                
            }
        }
        else{
            foreach($resources as $res){
                $menuindex = $res->get('menuindex');
               
                if($menuindex > $newValue && $menuindex <= $oldValue && $res->get('id') != $id){
                    $res->set('menuindex', $menuindex - 1);
                    $res->set('old_value', $menuindex - 1);
                }
                
                $res->save();                
            }    
        }
    break;
}
Артур Шевченко
28 января 2021, 16:11
1
0
Думаю стоить дополнить этот пост раз он есть в поиске. Во-первых на мой взгляд решение не самое лучшее, но достаточно простое, поэтому я его немного переделал для компактности
ПЛАГИН
<?php
switch ($modx->event->name) {
    case 'OnDocFormSave':
        $sql = 'SELECT article FROM modx_msop_modifications WHERE rid= ?';
        $statement = $modx->prepare($sql);
        if ( $statement->execute(array($id)) ) {
            $result = $statement->fetchAll(PDO::FETCH_COLUMN);
        }
        $resource->set('introtext', implode(',',$result));
        $resource->save();
    break;
}
КОД ДЛЯ КОСОЛИ, чтобы обновить товары
<?php
$resources = $modx->getIterator('msProduct');

foreach ($resources as $resource) {
    $id = $resource->get('id');
    $sql = 'SELECT article FROM modx_msop_modifications WHERE rid= ?';
    $statement = $modx->prepare($sql);
    if ( $statement->execute(array($id)) ) {
        $result = $statement->fetchAll(PDO::FETCH_COLUMN);
    }
    $resource->set('introtext', implode(',',$result));
    $resource->save();
}
Артур Шевченко
28 января 2021, 13:58
0
Сразу оговорюсь это говнокод, а то придут старшие товарищи и начнут тапками меня закидывать. Использовать на свой страх и риск, но у меня работает.
Ссылка имеет вид domain.ru/smeta?order_id=183
На этой странице вызывается сниппет getOrder
{set $order = '!getOrder' | snippet:[
    'order_id' => $.get.order_id
]}
Сниппет возвращает массив, посмотреть что внутри можно так
{$order | print_r}
Сам сниппет выглядит так
<?php
if(!$order_id){return false;}
$pdoTools = $modx->getService('pdoTools');
$orderFields = array('id','num', 'createdon', 
                    'updatedon', 'cart_cost', 
                    'delivery_cost', 'comment', 
                    'status', 'cost');
$orderProductFields = array('id','product_id', 
                            'name', 'count', 
                            'price', 'cost', 'options');
                        
$addressFields = array('city', 'street',
                        'receiver', 'phone',
                        'comment');
$output = array(
    'meta' => [],
    'address' => [],
    'products' => []
    );

$order = $modx->getObject('msOrder', $order_id);
if($order){        
    //заполняем массив основных данных заказа
    for($i = 0; $i < count($orderFields); $i++){
        $output['meta'][$orderFields[$i]] = $order->get($orderFields[$i]); 
    }
    
    //вычисляем срок выполнения заказа
    $output['meta']['duration'] = ceil($output['meta']['cost'] / $modx->getOption('base_cost'));
            
    //заполняем адрес и дополнительные данные
    $address = $order->getOne('Address');
    $properties = $address->get('properties');
    for($i = 0; $i < count($addressFields); $i++){
        if($addressFields[$i] != 'properties'){
            $output['address'][$addressFields[$i]] = $address->get($addressFields[$i]); 
        }else{
            foreach($properties as $name => $prop){
                $output['address'][$name] = $prop; 
            }
        }
    }
    //заполняем продукты
    $products = $order->getMany('Products');
    if($products){
        foreach($products as $key => $product){
            for($i = 0; $i < count($orderProductFields); $i++){
                $output['products'][$key][$orderProductFields[$i]] = $product->get($orderProductFields[$i]); 
            }
        }  
    }
    
    
    //$modx->log(1, 'OUTPUT getUserOrder ' . print_r($output, 1));
    
    if($tpl){
        return $pdoTools->getChunk($tpl, $output);
    }
    //$modx->log(1, print_r($output,1));
    return $output;
}else{
    return false;
}
После вызова сниппет идёт такой код
{if $order}
<p class="h-6"><span class="text-orange">Номер заказа:</span> {$order['meta']['num']}</p>
<p class="h-6"><span class="text-orange">Дата заказа:</span> {$order['meta']['createdon'] | date: 'd.m.Y H:i:s'}</p>
<p class="h-6"><span class="text-orange">Имя заказчика:</span> {$order['address']['receiver']}</p>
{if $_modx->isAuthenticated('mgr') || $.get.admin}
<p class="h-6"><span class="text-orange">Телефон заказчика:</span> <a class="service-link" href="tel:{$order['address']['phone'] | replace:'-':'' }">{$order['address']['phone'] | replace:'-':'' }</a></p>
{/if}
<p class="h-6"><span class="text-orange">Общая стоимость:</span> <span class="jsTotalOrderCost">{$order['meta']['cost']}</span> руб.</p>
<p class="h-6"><span class="text-orange">Срок выполнения:</span> <span class="jsOrderDuration">{$order['meta']['duration']}</span> дн.</p>
<p class="h-6 mb-0"><span class="text-orange">Перечень включенных в состав услуг 
 <small class="small">(в стоимость услуг входит стоимость платных дополнений)</small></span></p>
    {if $_modx->isAuthenticated('mgr') || $.get.admin}
        <div class="pl-0" id="orderWrap">
        {if $order['products']}    
        {set $i = 1}    
        {foreach $order['products'] as $key => $product}
            {set $description = $product['product_id'] | resource: 'desc'}
            {set $introtext = $product['product_id'] | resource: 'introtext'}
            {set $add_cost = $product['product_id'] | resource: 'add_cost'}
            {set $weight = $product['product_id'] | resource: 'weight'}
            {$_modx->parseChunk('@FILE chunks/shop/editOrderProduct.html', [
                'description' => $product['options']['desc']?:$description,
                'introtexxt' => $introtext,
                'index' => $i,
                'add_cost' => $add_cost,
                'price' => $product['price'],
                'weight' => $weight,
                'count' => $product['count'],
                'name' => $product['options']['name']?:$product['name'],
                'cost' => $product['cost'],
                'id' => $product['id'],
                'options' => $product['options'],
                'order_id' => $.get.order_id,
                'total_cost' => $order['meta']['cost'],
                'product_id' => $product['product_id']
            ])}
            {set $i = $i + 1}
        {/foreach}
        {else}
        <p class="h-6 my-3 text-red">Необходимо добавить услуги!</p>
        {/if}
        </div>
         <p class="h-5 mt-3 mb-3">Найти услугу</p>
        {'!AjaxForm' | snippet: [
            'snippet' => 'searchResources',
            'tpl' => '@FILE chunks/shop/editOrderProductTpl.html',
            'form' => '@FILE chunks/forms/searchForm.html',
            'fieldsForSearch' => 'pagetitle,longtitle,menutitle',
            'validate' => 'query:required:minLength=^3^',
            'placeholderPrefix' =>'find.'
        ]}
        <div id="productList"></div>
        <p class="h-5 mt-3 mb-0">Добавить услугу</p>
        <form class="row py-3 jsProductRow border-gray-bottom jsAddForm">
            <div class="jsCommonFields">
                <input type="hidden" name="weight" value="1">
                <input type="hidden" name="order_id" value="{$.get.order_id}">
                <input type="hidden" name="total_cost" value="{$order['meta']['cost']}">
                <input type="hidden" name="action" value="editOrder">
            </div>
            <input type="hidden" name="product_id" value="130">
            <div class="col-lg-7 col-md-5 col-6 mb-md-0 mb-3 d-flex flex-column justify-content-center align-items-start">
                <label class="label-text par mb-0 w-100">
                    <input type="text" class="input pr-1" name="name" placeholder="{130 | resource: 'pagetitle'}" value="" required>
                </label>
            </div>
            <div class="col-lg-1 col-md-2 col-6 mb-md-0 mb-3 d-flex justify-content-center align-items-center">
                <label class="label-text par mb-0">
                    <input type="number" class="input pr-1" min="1" name="count" value="1">
                </label>
            </div>
            <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
                <label class="label-text par mb-0">
                    <input type="text" class="input pr-1" name="price" placeholder="Цена" value="" required>
                </label>
            </div>
            <div class="col-lg-2 col-md-2 col-6 d-flex justify-content-center align-items-center">
                <button class="btn btn-orange btn-cart" type="submit">
                    <i class="fa fa-cart-plus"></i>
                </button>
            </div>
            <div class="col-12 order-5 mt-3">
                <label class="label-text par mb-0">
                    <textarea name="options[desc]" class="textarea w-100" rows="4" placeholder="Описание"></textarea>
                </label>
            </div>
        </form>
    {else}
     <ul class="pl-0">
    {foreach $order['products'] as $key => $product}
        {set $description = $product['product_id'] | resource: 'description'}
        {set $introtext = $product['product_id'] | resource: 'introtext'}
        {set $add_cost = $product['product_id'] | resource: 'add_cost'}
        <li class="row py-3 jsProductRow border-gray-bottom">
            <input type="hidden" name="id" value="{$id}">
            <div class="col-lg-7 col-md-5 col-6 d-flex flex-column justify-content-center align-items-start">
                <span class="par service-link mb-3">{$product['options']['name']?:$product['name']}</span>
                <small class="small">{$product['options']['desc']?:$description}</small>
                {if $add_cost}
                    {if $id == 45}
                    <small class="small text-red">*стоимость шаблона: {$add_cost} руб.</small>
                    {else}
                    <small class="small text-red">*стоимость дополнения: {$add_cost} руб.</small>
                    {/if}
                {/if}
            </div>
            <div class="col-lg-1 col-md-1 col-6 d-flex justify-content-center align-items-center">
                <span class="price text-orange h-6">{$product['count']} шт.</span>
            </div>
            <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
                    <span class="text-orange h-6">{$product['price']} руб.</span>
            </div>
            <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
                <span class="text-orange h-6">{$product['cost']} руб.</span>
            </div>
        </li>
    {/foreach}
    </ul>
    {/if}
{else}
<p class="h-4 text-center">Заказ с id = {$.get.order_id} не существует в системе</p>
{/if}
<div class="row">
        <div class="col-lg-3 offset-lg-3 col-sm-6 mt-3">
        <div class="btn-wrap">
            <a href="/" class="btn btn-no-bg w-100">На Главную</a>
        </div>
    </div>
    <div class="col-lg-3 col-sm-6 mt-3">
        <div class="btn-wrap">
            <a href="{9 | url}" class="btn btn-no-bg w-100">К Услугам</a>
        </div>
    </div>
</div>
Каждый товар выводится в форму редактирования, а под всеми товарами есть форма добавления нового и форма поиска
editOrderProduct.htm выглядит так
<form class="row py-3 jsProductRow border-gray-bottom jsEditForm" name="product-{$id}" id="product-{$id}">
    <input type="hidden" name="id" value="{$id}">
    <input type="hidden" name="weight" value="{$weight}">
    <input type="hidden" name="order_id" value="{$order_id}">
    <input type="hidden" name="total_cost" value="{$total_cost}">
    <input type="hidden" name="action" value="editOrder">
    <input type="hidden" name="price" value="{$price}">
    <input type="hidden" name="options[addcost]" value="{$add_cost | number: '0': '.': ''}">
    <input type="hidden" name="product_id" value="{$product_id}">
    <div class="col-lg-7 col-md-5 col-6 d-flex flex-column justify-content-center align-items-start">
        <span class="par service-link">{$index}. {$name}</span>
        {if $introtext}
        <small class="small">{$introtext}</small>
        {/if}
        {if $add_cost}
        {if $id == 45}
        <small class="small text-red">*стоимость шаблона: {$add_cost} руб.</small>
        {else}
        <small class="small text-red">*стоимость дополнения: {$add_cost} руб.</small>
        {/if}
        {/if}
    </div>
    <div class="col-lg-1 col-md-1 col-6 d-flex justify-content-center align-items-center">
        <label class="label-text par mb-0">
            <input type="number" class="input pr-1" min="0" name="count" value="{$count}">
        </label>
    </div>
    <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
        <span class="text-orange h-6">{$price} руб.</span>
    </div>
    <div class="col-lg-2 col-md-3 col-6 d-flex justify-content-center align-items-center">
        <span class="text-orange h-6">{$cost} руб.</span>
    </div>
    <div class="col-12 order-5 mt-3">
        <label class="label-text par mb-0">
            <textarea name="options[desc]" class="textarea w-100" rows="4" placeholder="Описание">{$description}</textarea>
        </label>
    </div>
</form>
Как отправить запрос на сервер думаю разберётесь, в заметке про поиск это есть. Ну и собственно сам сниппет editOrder
<?php
if(!isset($_POST['order_id'])){
    $modx->log(1,'EditOrder: Не передан идентификатор заказа');
    return false;
}
//$modx->log(1, print_r($_POST,1));
$res = [];
$tpl = '@FILE chunks/shop/editOrderProduct.html';
$order = $modx->getObject('msOrder', $_POST['order_id']);
if(isset($_POST['id'])){
    $product = $modx->getObject('msOrderProduct', $_POST['id']);
    $productCost = $_POST['price'] * $_POST['count'] + $_POST['options']['addcost'];
    $totalWeight = $_POST['weight'] + $order->get('weight') - $product->get('weight');
    $totalCost = $order->get('cost') + $productCost - $product->get('cost')  - $_POST['options']['addcost'];
    if($_POST['count'] > 0){
        $product->set('count', $_POST['count']);
	    $product->set('cost', $_POST['price'] * $_POST['count']);
	    if($_POST['options']['desc']){
	        $options = $product->get('options');
	        $options['desc'] = $_POST['options']['desc'];
	        $product->set('options', $options);
	    }
	    $product->save();
    }else{
        $totalWeight = $_POST['weight'] - $product->get('weight');
        $totalCost = $order->get('cost') - $product->get('cost');
        $product->remove();
        
    }
}else{
    $product = $modx->newObject('msOrderProduct');
    $data = $_POST;
    $data['cost'] = $_POST['price'] * $_POST['count'] + $_POST['options']['addcost'];
    $totalWeight = $_POST['weight'] * $_POST['count'] + $order->get('weight');
    $totalCost = $order->get('cost') + $data['cost'];
    $product->fromArray($data);
    $product->save();
}
	    
$order->set('cost', $totalCost);
$order->set('cart_cost', $totalCost);
$order->set('weight', $totalWeight);
$order->set('updatedon', date('Y-m-d H:i:s'));
$order->save();

if($totalCost){
    $pdoTools = $modx->getService('pdoTools');
    $products = $order->getMany('Products');
    $i = 1;
    foreach($products as $product){
        $options = $product->get('options');
        $resource = $modx->getObject('modResource', $product->get('product_id'));
        $desc = $options['desc']?:$resource->get('description');
        $name = $options['name']?:$product->get('name');
          
        $productData = array(
                'description' => $desc,
                'introtexxt' => $resource->get('introtext'),
                'index' => $i,
                'add_cost' => $resource->get('add_cost'),
                'price' => $product->get('price'),
                'weight' => $product->get('weight'),
                'count' => $product->get('count'),
                'name' => $name,
                'cost' => $product->get('cost') + $resource->get('add_cost'),
                'id' => $product->get('id'),
                'options' => $options,
                'order_id' => $_POST['order_id'],
                'product_id' => $resource->get('id')
            );
        
        if(isset($tpl)){
            $res['orderProducts'] .= $pdoTools->getChunk($tpl, $productData);
        }else{
            $res['orderProducts'][] = $productData;
        }
        $i++;
    }
}
else{
    $res['orderProducts'] = '<p class="h-6 my-3 text-red">Необходимо добавить услуги!</p>';
}       
$res['total_cost'] = $totalCost;
$res['duration'] = ceil($totalCost / $modx->getOption('base_cost'));

return json_encode($res);
Если интересует добавление товаров, то вот сниппет addToOrder
<?php
	    $res = [];
	    $order = $modx->getObject('msOrder', $_POST['order_id']);
	    
	    $product = $modx->newObject('msOrderProduct');
	    $data = $_POST;
	    //$modx->log(1, print_r($_POST,1));
	    $data['cost'] = $_POST['price'] * $_POST['count'];
	    $totalWeight = $_POST['weight'] * $_POST['count'] + $order->get('weight');
	    $totalCost = $order->get('cost') + $data['cost'] + $data['options']['addcost'];
	    $product->fromArray($data);
	    $product->save();
	    
	    $order->set('cost', $totalCost);
	    $order->set('cart_cost', $totalCost);
	    $order->set('weight', $totalWeight);
	    $order->set('updatedon', date('Y-m-d H:i:s'));
	    $order->save();
	    
	    $pdoTools = $modx->getService('pdoTools');
	    $products = $order->getMany('Products');
	    $i = 1;
        foreach($products as $product){
            $options = $product->get('options');
            $resource = $modx->getObject('modResource', $_POST['product_id']);
            $res['orderProducts'] .= $pdoTools->getChunk('@FILE chunks/shop/editOrderProduct.html', array(
                    'description' => $options['desc']?:$resource->get('description'),
                    'introtexxt' => $resource->get('introtext'),
                    'index' => $i,
                    'add_cost' => $resource->get('add_cost'),
                    'price' => $product->get('price'),
                    'weight' => $product->get('weight'),
                    'count' => $product->get('count'),
                    'name' => $options['name']?:$product->get('name'),
                    'cost' => $product->get('cost'),
                    'id' => $product->get('id'),
                    'options' => $options,
                    'order_id' => $_POST['order_id'],
                    'total_cost' => $totalCost,
                    'product_id' => $resource->get('id')
                ));
                $i++;
        }
        $res['total_cost'] = $totalCost;
        $res['duration'] = ceil($totalCost / $modx->getOption('base_cost'));
        $res = json_encode($res);
        return $res;
Артур Шевченко
28 января 2021, 11:31
0
А вы проверяли переменные перед запуском runSnippet, в $image точно корректная строка?
Артур Шевченко
28 января 2021, 10:51
0
А где взять старое значение? Изменение делает пользователь, сохраняет и только потом срабатывает плагин.
Артур Шевченко
28 января 2021, 00:27
0
Я проверил это код в консоли, всё сработало, может ошибка не в нём?
Артур Шевченко
26 января 2021, 22:15
0
1.не могут оплатить, т.к. под рукой нет карты, Сбербанка онлайн и так далее
2.не могут оплатить, т.к. что-то пошло не так (номер не тот ввел, денег нет на карте, еще что-то)
3.передумывают платить онлайн, решают, что выберут другой вариант оплаты
Для первых двух кейсов в письме клиенту есть ссылка на оплату. А третий на мой взгляд достаточно редкий. Собственно по этой причине готовых решений и нет, если вам ссылки на оплату недостаточно и вы непременно хотите как-то иначе обрабатывать ошибку оплаты или отказ от неё, придётся заморочиться.
Артур Шевченко
26 января 2021, 20:51
0
Я думаю надо переопределить метод submit вот в этом файле core/components/minishop2/model/minishop2/msorderhandler.class.php Как это сделать написано тут

Возможно так же стоит изучить эту страницу