Всего 104 495 комментариев

Артем
13 сентября 2020, 15:17
+1
Если твой сторонний сервис не предоставляет никаких TTL (время жизни цены) или любой другой информации, по которой можно отследить ее актуальность, то у тебя есть 2 пути:
— либо ты делаешь запрос каждый раз, когда нужно узнать цену
— либо ты кэшируешь ее на любое время, которое считаешь нужным.
В первом случае клиенты твоего сайта получат всегда актуальные цены перед глазами, а во втором — нет, поэтому тебе нужно будет принудительно запрашивать цену перед, например, оформлением заказа, ну и уведомлять клиента о том, если она изменилась за это время.

Вопрос нагрузки на их сервис — не твоя забота. Если они хотят меньшую нагрузку, то пусть добавляют к ценам TTL, либо предоставляют тебе возможность общаться с их сервисом в рилтайме посредством сокетов.

Лично мне вариант с сокетами кажется наиболее разумным решением — клиенты всегда видят актуальные цены, не нужно слать по 150 запросов в секунду, все довольны.
Александр Мельник
13 сентября 2020, 13:17
0
Спасибо что ответили.
Нет, честно говоря не совсем понял вашу идею.
Попробую более подробно описать как будет строиться проект.
ИМ будет представлять из себя соединитель сторонних сервисов, поскольку у заказчика на данный момент уже по всем миру обычные магазины офлайновые и у них уже заключены договора на обслуживание с множеством различных компаний. Так например данные о товарах в электронном виде хранятся в одной компании, отдельно заключены договора с компанией которая предоставляет услуги «программы лояльности» которая уже ведет учет покупателей, выдачу им бонусных карт, построение сложных акций и так далее. Сейчас это все работает в их офлайн магазинах — данные передаются на кассовые аппараты и когда человек покупает товар, кассовый аппарат получает от сервиса по хранению товаров базовую стоимость товара, потом клиент дает карточку лояльности и по ней идет запрос от кассового аппарата на сервис по работе с лояльностью. Тот сервис проверят что за клиент, сколько у него бонусов, проверяет нет ли для него индивидуальных скидок и возвращает в кассовый аппарат данные — для него товар стоит столько то, если купит получит на бонусный счет столько-то и прочую инфу. Тоесть Цена товара для клиента оказалась индивидуальной и купи этот же товар другой — для него цена была бы другой.
Эту логику нужно соблюсти и в интернет магазине.
У нас у товара будет базовая цена, полученная от сервиса по хранению товаров. Она более менее стабильна (обновляется раз в полчаса). А есть цена которую нужно показать конкретному покупателю. Авторизовался человек на сайте, перешел в какой-то раздел с товарами, видит например 50 товаров в списке и у каждого товара уже стоимость конкретно для этого покупателя. И особо проблем тут нет — для начала представим самый простой путь — в момент открытия страницы сайт будет отсылать запросы на сервер который занимается программой лояльности и получать в ответ цену каждого товара — да это трудозатратно но пока представим такой вариант. И на фронтенде ему отрисуется страница с товарами и с его индивидуальными ценами. Но с ценами нужно же работать и на бекенде. Товар он может добавить в корзину, увеличить его количество и прочее и это все должно работать с его индивидуальной ценой. И так у каждого пользователя — к примеру на сайте одновременно 1000 покупателей и каждый должен работать со своей стоимостью товара.
Ну вот отсюда и мои вопросы и сомнения.
— если каждый пользователь при каждом открытии страницы будет отсылать по каждому товару запросы на сервер хранящий данные о покупателях, их скидках, то это будет очень высокая нагрузка на их сервер. Возможно это делать заранее, для каждого покупателя пару раз в день получая все цены, но дело в том, что информация меняется очень динамично — к примеру акция может закончиться в 23 часа ночи, а обновление цен запланировано на 3 часа ночи, значит покупатель сделавший заказ в час ночи вызовет сбой в ценах — купит не по той цене.
— ну и плюс не совсем пока представляю где правильнее хранить такие объемы данных, чтобы они были индивидуальны у каждого пользователя и доступны как для фронтенда так и для бекенда.
Я конечно придумаю решение, но в мире много умных и опытных людей и их помощь важна.
Дмитрий
13 сентября 2020, 13:07
0
О, не знал, спасибо!
Надо будет обновить функционал.
Юрий
13 сентября 2020, 12:06
0
Добрый день!
Представьте себе цену как некую виртуальную динамическую страницу. Она вроде как есть (при условии совпадения неких входящих данных), на её можно посмотреть и даже она имеет свой адрес, а в реальности её не существует. Здесь в базе хранятся условия, которые её формируют, а не сама цена + некий индификатор совокупности этих условий в виде хеша, например.
В общем, я думаю, идея понятна.
Александр Мельник
13 сентября 2020, 10:31
+2
Тоже использовал этот официальный SDK от яндекс кассы на одном проекте. Удобно с ним работать.
Жаль только что ссылка на оплату живет только один час и если покупатель засомневался, не оплатил сразу, а через 2 часа все же решился — то переходя по ссылке на страницу оплаты он уже увидит ошибку.
Мой заказчик почти сразу же попросил дописать функционал с возможностью через админку генерировать новые ссылки для оплаты и отсылать их покупателю.
Дмитрий
12 сентября 2020, 19:33
+5
Ни в коем случае не против того, чтобы Володя обновил компонент.
Просто новое API существует с 2017-ого года, а обновления на Modstore до сих пор нет.
Ждать, когда это случится и по этой причине не подключать заказчика к кассе — мягко говоря, странно.
Поэтому и был разработан этот компонент. Не идеальный, с ограниченным функционалом, но тем не менее, оплату принять и чек клиенту отослать он может. А большинству и этого с головой достаточно.
Иван Бочкарев
12 сентября 2020, 19:00
-1
@Володя я думаю обновит в таком случае. У меня пока все работает с этим допом.
Дмитрий
12 сентября 2020, 18:45
+3
Тем, что mspYaCassa работает по старому протоколу, к которому Яндекс больше не подключает.
Ivanov Alexandr
12 сентября 2020, 09:16
0
Код плагина подправил
<?php
switch ($modx->event->name) {
        case "OnMODXInit":
            $map = array(
                'modUserProfile' => array(
                    'fields' => array(
                        'opisanie' => '',
                        'sotrudnik' => '',
                        'sertifikat' => '',
                        'lico' => '',
                        'oborot' => '',
                    ),
                    'fieldMeta' => array(
                        'opisanie' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),
                        'sotrudnik' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),
                        'sertifikat' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),
                        'lico' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),
                        'oborot' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),                        
                    ),
                ),
            );
            foreach ($map as $class => $data) {
                $modx->loadClass($class);
                foreach ($data as $tmp => $fields) {
                    if ($tmp == 'fields') {
                        foreach ($fields as $field => $value) {
                            foreach (array('fields', 'fieldMeta', 'indexes') as $key) {
                                if (isset($data[$key][$field])) {
                                    $modx->map[$class][$key][$field] = $data[$key][$field];
                                }
                            }
                        }
                    } elseif ($tmp == 'composites' || $tmp == 'aggregates') {
                        foreach ($fields as $alias => $relation) {
                            if (!isset($modx->map[$class][$tmp][$alias])) {
                                $modx->map[$class][$tmp][$alias] = $relation;
                            }
                        }
                    }
                }
            }
            break;
        case "OnUserFormPrerender":
            if (!isset($user) || $user->get('id') < 1) {
                return;
            }
            if ($user->get('id') > 0) {
                $data['opisanie'] = htmlspecialchars($user->Profile->opisanie);
                $data['sotrudnik'] = htmlspecialchars($user->Profile->sotrudnik);
                $data['sertifikat'] = htmlspecialchars($user->Profile->sertifikat);
                $data['lico'] = htmlspecialchars($user->Profile->lico);
                $data['oborot'] = htmlspecialchars($user->Profile->oborot);
                $modx->controller->addHtml("
                    <script type='text/javascript'>
                        Ext.ComponentMgr.onAvailable('modx-user-tabs', function() {
                            this.on('beforerender', function() {
                                // Получаем колонки первой вкладки
                                var leftCol = this.items.items[0].items.items[0].items.items[0];
                                // Добавляем новое поле в левую колонку 4ым по счёту полем (перед полем 'Email')
                                leftCol.items.insert(15, 'modx-user-opisanie', new Ext.form.TextArea({
                                    id: 'modx-user-opisanie',
                                    name: 'opisanie',
                                    fieldLabel: 'Описание компании',
                                    xtype: 'textarea',
                                    anchor: '100%',
                                    value: '{$data['opisanie']}',
                                }));
                                leftCol.items.insert(16, 'modx-user-sotrudnik', new Ext.form.TextField({
                                    id: 'modx-user-sotrudnik',
                                    name: 'sotrudnik',
                                    fieldLabel: 'Количество соттрудников',
                                    xtype: 'varchar',
                                    anchor: '100%',
                                    maxLength: 255,
                                    value: '{$data['sotrudnik']}',
                                }));
                                leftCol.items.insert(17, 'modx-user-sertifikat', new Ext.form.TextField({
                                    id: 'modx-user-sertifikat',
                                    name: 'sertifikat',
                                    fieldLabel: 'Наличие сертификата',
                                    xtype: 'varchar',
                                    anchor: '100%',
                                    maxLength: 255,
                                    value: '{$data['sertifikat']}',
                                }));
                                leftCol.items.insert(18, 'modx-user-lico', new Ext.form.TextField({
                                    id: 'modx-user-lico',
                                    name: 'lico',
                                    fieldLabel: 'Ответственное лицо',
                                    xtype: 'varchar',
                                    anchor: '100%',
                                    maxLength: 255,
                                    value: '{$data['lico']}',
                                }));
                                 leftCol.items.insert(19, 'modx-user-oborot', new Ext.form.TextField({
                                    id: 'modx-user-oborot',
                                    name: 'oborot',
                                    fieldLabel: 'Годовой оборот компании',
                                    xtype: 'varchar',
                                    anchor: '100%',
                                    maxLength: 255,
                                    value: '{$data['oborot']}',
                                }));                               
                            });
                        });
                    </script>
                ");
            }
            break;
    }
Все равно ничего не сохраняет на сайте.
Ivanov Alexandr
12 сентября 2020, 08:50
0
Все сделал по инструкции.
Плагин повесил на указанные события
<?php
switch ($modx->event->name) {
        case "OnMODXInit":
            $map = array(
                'modUserProfile' => array(
                    'fields' => array(
                        'opisanie' => '',
                        'sotrudnik' => '',
                        'sertifikat' => '',
                        'lico' => '',
                    ),
                    'fieldMeta' => array(
                        'opisanie' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),
                        'sotrudnik' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),
                        'sertifikat' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),
                        'lico' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),
                        'oborot' => array(
                            'dbtype' => 'varchar',
                            'precision' => '100',
                            'phptype' => 'string',
                            'null' => true,
                        ),                        
                    ),
                ),
            );
            foreach ($map as $class => $data) {
                $modx->loadClass($class);
                foreach ($data as $tmp => $fields) {
                    if ($tmp == 'fields') {
                        foreach ($fields as $field => $value) {
                            foreach (array('fields', 'fieldMeta', 'indexes') as $key) {
                                if (isset($data[$key][$field])) {
                                    $modx->map[$class][$key][$field] = $data[$key][$field];
                                }
                            }
                        }
                    } elseif ($tmp == 'composites' || $tmp == 'aggregates') {
                        foreach ($fields as $alias => $relation) {
                            if (!isset($modx->map[$class][$tmp][$alias])) {
                                $modx->map[$class][$tmp][$alias] = $relation;
                            }
                        }
                    }
                }
            }
            break;
        case "OnUserFormPrerender":
            if (!isset($user) || $user->get('id') < 1) {
                return;
            }
            if ($user->get('id') > 0) {
                $data['opisanie'] = htmlspecialchars($user->Profile->opisanie);
                $data['sotrudnik'] = htmlspecialchars($user->Profile->sotrudnik);
                $data['sertifikat'] = htmlspecialchars($user->Profile->sertifikat);
                $data['lico'] = htmlspecialchars($user->Profile->lico);
                $data['oborot'] = htmlspecialchars($user->Profile->oborot);
                $modx->controller->addHtml("
                    <script type='text/javascript'>
                        Ext.ComponentMgr.onAvailable('modx-user-tabs', function() {
                            this.on('beforerender', function() {
                                // Получаем колонки первой вкладки
                                var leftCol = this.items.items[0].items.items[0].items.items[0];
                                // Добавляем новое поле в левую колонку 4ым по счёту полем (перед полем 'Email')
                                leftCol.items.insert(15, 'modx-user-opisanie', new Ext.form.TextArea({
                                    id: 'modx-user-opisanie',
                                    name: 'opisanie',
                                    fieldLabel: 'Описание компании',
                                    xtype: 'textarea',
                                    anchor: '100%',
                                    value: '{$data['opisanie']}',
                                }));
                                leftCol.items.insert(16, 'modx-user-sotrudnik', new Ext.form.TextField({
                                    id: 'modx-user-sotrudnik',
                                    name: 'sotrudnik',
                                    fieldLabel: 'Количество соттрудников',
                                    xtype: 'textfield',
                                    anchor: '100%',
                                    maxLength: 255,
                                    value: '{$data['sotrudnik']}',
                                }));
                                leftCol.items.insert(17, 'modx-user-sertifikat', new Ext.form.TextField({
                                    id: 'modx-user-sertifikat',
                                    name: 'sertifikat',
                                    fieldLabel: 'Наличие сертификата',
                                    xtype: 'varchar',
                                    anchor: '100%',
                                    maxLength: 255,
                                    value: '{$data['sertifikat']}',
                                }));
                                leftCol.items.insert(18, 'modx-user-lico', new Ext.form.TextField({
                                    id: 'modx-user-lico',
                                    name: 'lico',
                                    fieldLabel: 'Ответственное лицо',
                                    xtype: 'varchar',
                                    anchor: '100%',
                                    maxLength: 255,
                                    value: '{$data['lico']}',
                                }));
                                 leftCol.items.insert(19, 'modx-user-oborot', new Ext.form.TextField({
                                    id: 'modx-user-oborot',
                                    name: 'oborot',
                                    fieldLabel: 'Годовой оборот компании',
                                    xtype: 'varchar',
                                    anchor: '100%',
                                    maxLength: 255,
                                    value: '{$data['oborot']}',
                                }));                               
                            });
                        });
                    </script>
                ");
            }
            break;
    }
На странице редактирования профиля вывожу
[[!officeProfile?
	&HybridAuth=`0`
	&tplProfile=`PrifileEdit`
	&profileFields=`username:50,email:50,fullname:50,name:50,sotrudnik:50,lastname:50,phone:12,mobilephone:12,dob:10,
	address,state,zip,fax,photo,website,opisanie,lico,sertifikat,oborot`
]]
Пытаюсь отредактировать профиль а поля которые были созданы не сохраняются. При этом если в админке редактировать то поля сохраняются. А на сайте не хотят сохраняться. В чем может быть причина может что то не так сделал?

Стандартные поля при этом изменить можно на сайте. Не получается только добавленные.
Евгений
11 сентября 2020, 01:06
0
Проблема была в правах доступа на файл
П.С. логи сервера тоже ничего не дали, проверял методом тыка. Хостинг ukraine
Евгений
11 сентября 2020, 00:44
+1
письма приходят, проблема была в не закритом хтмл, а сейчас проблема что файл по пути ajaxform/action.php недоступен
Руслан Алеев
11 сентября 2020, 00:37
0
Еще поменьше используйте test в названии ящиков, тексте и т.п. Особо умные хосты или хуки форм могут тупо блочить отправку, причем не сообщая визуально никак об этом :)
Павел Бигель
11 сентября 2020, 00:33
+5
Не хочу никого обижать, но минифицировать страницу с предварительным запросом в тивиху, звучит как начало анекдота
Рушан
10 сентября 2020, 23:35
0
А куда идёт этот путь просто главной странице?
require 'то что увидели/index.php';
Рушан
10 сентября 2020, 23:18
0
У вас есть скайп?
Я всё прописал всё сделал
при нажатии на кнопку пишет страница не найдена(
Александр Мельник
10 сентября 2020, 22:57
0
Вы правы, но я добавляю сам руками. Мне так спокойнее что ли.