Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Leaderboard

Popular Content

Showing content with the highest reputation on 09/28/2023 in all areas

  1. Я тоже выбрал Кеу из-за дизайна, в Салес мне тоже показался дизайн из 90, что в эксели каком-то. Но работая з кеу уже подумываю переходить на салес. Так как в кеу з тем же чек боксам интеграция просто тупо на сделанный заказ и распечатать чек, то есть не учитывается предоплата и.т.д, так же нельзя отправить чек когда забрали посылку ( а салес- это работает если не ошибаюсь), по сути все нужно перебивать ручную в чекбокс. Интеграции товаров с опенкарт нет, или через эксель, или по их апи нужно создавать модуль (это в копейку). Передаются только заказы. Если работаешь с маркетплейсами + доплата вроде 25 баксов. Сама по себе црм удобная и красивая, но много нюансов, и нет всего в одной црм, в чекбокс нужно переносить данные, товари с опенкарта переносить через эксель, такая себе автоматика. А еще контры с liqpay, тоже не под тягиваєт, но делают и решают єтот вопрос уже 2-3 месяца и все не как, то есть тоже нужно переходить в ликюпей и смотреть транзакции, короче как то так (( Так же насчет оплаты пакета, когда переходил на црм, менеджер сказал что считается только выполненные заказы, как я перешёл на црм и мне потом выставили на +9$ больше счет, они мне сказали что у них не считается только отменённые заказы ( в статусе доставка и.т.д считается), и наверное менеджер вас неправильно информировал, и они мне сделали типа скидку 9$ на первый месяц. Если больше 200 заказов (считаются все заказы кроме отменённых) доплачивай +9 баксов. Так что если продаете не дорогой товар или много заказов то может быть невыгодно. В обще смотрю с црм у нас беда цены не дешёвые, но работает как то все через раз, вроде все в одном месте должно быть, но как начинаешь работать так преходится несколько вкладок открывать, но я тестиль всего 2 црм . Вот думаю тестить начинать сале
    2 points
  2. Видимо из-за того, что в теге прайс прописаны еще и ид. Вы проверяли через нумерацию колонок, как эти столбцы называются?
    1 point
  3. Совет для большинства. Ну или поделюсь опытом. Я как автор хотел бы что бы мой модуль делал все что вы захотите и любые ограничения в нем в первую очередь бьют по мне. Так как это снижает привлекательность моего продукта, так вот именно я тот кто меньше всего хочет их внедрять. И если они есть они обусловлены какими то вескими причинами, не просто так что бы нагадить. Если откатится во времени к моменту внедрения много поточности, то там была большая дискуссия, я проводил много тестов на десятках клинских сайтов, и ограничение в 5 потоков это баланс. До 5 потоков скорость парсинга растет кратно, а от 5 уже не значительно, но при этом нагрузка растет значительно, как и риски блокировок. В общих чертах, в частных случаях и парсинг в 5 потоков может показать худший результат чем в один поток если сильно убогий хостинг у вас или у донора. Лично я парсю, или парсил в такой конфигурации. Если донор знакомый и я с ним работаю постоянно. И я знаю его поведение. Если донор новый, или к примеру какой то из крупных сайтов, где я могу предположить что есть хороший отдел it который не захочет со мной делится информацией. Я парсю в таком конфиге. Эти два конфига я бы назвал базовыми при здоровом парсинге. Но я понимаю что, там где я могу себе позволить делать что то медленно, с минимальными рисками, вы может не захотите или у вас другие требования. Я просто пишу как я поступаю лично. Из прокси у меня есть только один, на тот случай что бы убедится что проблема не в моем ip, как правило в баны не попадаю. Так поступал я когда парсил активно на заказ. Ну и помните, пока вы не создаете проблемы донору, а именно нагрузку, вы никому не интересны. Когда начинаете парсить 50 000 ссылок в 5 потоков, у донора растет нагрузка на веб сервер, и к нему приходит хостер с просьбой перейти на больший тариф или угомонить трафик. И вот тогда донор начнет задумываться что происходить и искать причину и бороться с ней. То есть с вами. Уважайте своего донора и будете жить дружно и долго.
    1 point
    Уникальный случай - разработчик сделал модуль для пользователей. Просто, быстро, гибко, человекопонятно. Этот модуль заменил мне такого мамонта как АОП. Лучше чем этот модуль - вы не найдете.
    1 point
  4. Колись, ще до початку війни вивчав це питання і навіть розробив таке рішення є звісно недоліки, по перше немає від банку зворотнього зв'язку і перевіряти оплату потрібно вручну, можливо ще щось є, але почалася війна і тема заглохла. Ідея модуля в тому, що Ви отримуєте кошти прямо на iban через подібне посилання , і в такому разі видача чека не потрібна взагалі.
    1 point
  5. Ну наприклад такий костиль: $from = $this->request->server['HTTP_REFERER']; $parts = explode('/', $from); $parts = array_reverse($parts, true); foreach ($parts as $part) { $_query = $this->db->query("SELECT query FROM " . DB_PREFIX . "seo_url WHERE keyword = '" . $this->db->escape(trim($part)) . "' LIMIT 1"); if ($_query->row['query']) { $query = explode('=', $_query->row['query']); $controller = $query[0]; break; } } if ($controller == 'category_id') { // товар додано із сторінки категорії } if ($controller == 'product_id') { // товар додано із сторінки продукта }
    1 point
  6. 1 point
  7. Цей огляд заснований на diff найпростіших вбудованих модулів. Але все перевірено на простому власному модулі, в якому немає ані подій, ані vQmod. Основні зміни у коді стандартного модуля * Примітка Слово Opencart, виділене жовтим кольором — це код модуля (!). Але, мабуть, ви й самі здогадалися У контролері OpenCart 3 OpenCart 4 class ControllerExtensionModuleAccount extends Controller { namespace Opencart\Admin\Controller\Extension\Opencart\Module; class Account extends \Opencart\System\Engine\Controller { protected function validate() { public function save(): void { // ... $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($json)); } private $error = array(); Більше не потрібно. Всі помилки обробляються відразу в методі save() if (isset($this->error['warning'])) { $data['error_warning'] = $this->error['warning']; } else { $data['error_warning'] = ''; } Не потрібно. Обробка помилок відбувається у методі save(). також Обробка помилок if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { Більше не використовується. Збереження форми відбувається шляхом надсилання AJAX-запиту до методу save() $data['action'] = $this->url->link('extension/module/account', 'user_token=' . $this->session->data['user_token'], true); // 4.0.0.0 $data['save'] = $this->url->link('extension/opencart/module/account|save', 'user_token=' . $this->session->data['user_token']); // 4.0.2.0 $data['save'] = $this->url->link('extension/opencart/module/account.save', 'user_token=' . $this->session->data['user_token']); *Зміни у побудові шляхів впливають на будь-які посилання всередині модуля. Ну, це і так зрозуміло. $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true); $data['back'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module'); $this->load->model('extension/dashboard/map'); $this->load->model('extension/opencart/dashboard/map'); $results = $this->model_extension_dashboard_map->getTotalOrdersByCountry(); $results = $this->model_extension_opencart_dashboard_map->getTotalOrdersByCountry(); if (isset($this->request->post['module_account_status'])) { $data['module_account_status'] = $this->request->post['module_account_status']; } else { $data['module_account_status'] = $this->config->get('module_account_status'); } $data['module_account_status'] = $this->config->get('module_account_status'); У моделі OpenCart 3 OpenCart 4 class ModelExtensionDashboardMap extends Model { namespace Opencart\Admin\Model\Extension\Opencart\Dashboard; class Map extends \Opencart\System\Engine\Model { У в'юшці В OpenCart 4.0.0.0 був FontAwesome 5.15.4, а в OpenCart 4.0.2.0 FontAwesome 6.1.1. Це впливає на класи іконок. OpenCart 3 OpenCart 4 pull-right float-end data-toggle="tooltip" data-bs-toggle="tooltip" <i class="fa fa-save"></i> <!-- 4.0.0.0 --> <i class="fas fa-save"></i> <!-- 4.0.2.0 --> <i class="fa-solid fa-save"></i> {{ cancel }} {{ button_cancel }} {{ back }} {{ button_back }} <ul class="breadcrumb"> <ol class="breadcrumb"> <li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li> <li class="breadcrumb-item"><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li> {% if error_warning %} <div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> {{ error_warning }} <button type="button" class="close" data-dismiss="alert">&times;</button> </div> {% endif %}{% if error_warning %} -- (AJAX) <div class="panel panel-default"> <div class="card"> <div class="panel-heading"> <h3 class="panel-title"><i class="fa fa-pencil"></i> {{ text_edit }}</h3> </div> <!-- 4.0.0.0 --> <div class="card-header"><i class="fas fa-pencil-alt"></i> {{ text_edit }}</div> <!-- 4.0.2.0 --> <div class="card-header"><i class="fa-solid fa-pencil"></i> {{ text_edit }}</div> <div class="panel-body"> <div class="card-body"> <form action="{{ action }}" method="post" enctype="multipart/form-data" id="form-module" class="form-horizontal"> <form id="form-module" action="{{ save }}" method="post" data-oc-toggle="ajax"> * Якщо пропустити data-oc-toggle="ajax", то форма обробиться по-старому з повним завантаженням сторінки (принаймні у версії 4.0.0.0). Хоча сам .alert у bootstrap 5 трохи змінився. <div class="form-group"> <div class="row mb-3"> control-label col-form-label <select name="module_account_status" ... <!-- 4.0.2.0 --> <input type="checkbox" name="module_account_status" ... Шляхи в AJAX-запитах url: 'index.php?route=extension/module/imagescanner/getNotUsedImagesList <!-- 4.0.0.0 --> url: 'index.php?route=extension/imagescanner/module/imagescanner|getNotUsedImagesList <!-- 4.0.2.0 --> url: 'index.php?route=extension/imagescanner/module/imagescanner.getNotUsedImagesList Шляхи до зображень var img_loader = new Image().src='view/image/imagescanner-loader.gif'; var img_loader = new Image().src='extension/imagescanner/admin/view/image/imagescanner-loader.gif'; А воно запитує: http://opencart-4000.loc/admin/extension/imagescanner/admin/view/image/imagescanner-loader.gif Значить треба вказати повний шлях до файлу var img_loader = new Image().src='{{ constant('HTTP_CATALOG') }}extension/imagescanner/admin/view/image/imagescanner-loader.gif'; Обробка помилок Щоб поля з помилками підсвічувалися і до них були пояснювальні підписи, першою дією у в'юшці необхідно вписати порожні контейнери для текстів помилок. <div id="error-field" class="invalid-feedback"></div> Далі, при обробці форми по AJAX можна отримати наступний формат відповіді: { "error": { "name_1": "Product Name must be greater than 1 and less than 255 characters!", "keyword_0_1": "SEO URL keyword required!", "warning": "Warning: Please check the form carefully for errors!" } } Потім воно буде універсально оброблено в admin/view/javascript/common.js з урахуванням того, чи це рядок, чи це об'єкт, та чи є там редірект. Також воно автоматично переведе under_score індекси массиву з помилками в kebab-case html-ідентифікаторів, в яких потрібно показати відповідні тексти червоним кольором. TypeError: Cannot access offset of type string on string in при обробці помилок У js при обробці відповіді AJAX-запиту робиться розмежування між отриманим рядком та об'єктом. Все тому, що в найпростішому "модулі" (наприклад, account) в помилки потрапляє лише рядок з текстом без зайвих проблем. І ось я скопіпастив звідти, а потім побачив, що в товарах йде інакше, і скопіпастив шматок коду ще й звідти. У результаті напоровся на помилку: TypeError: Cannot access offset of type string on string in ... $json['error'] = $this->language->get('error_text'); // В найпростішому модулі присвоюється рядок ... if (isset($json['error']) && !isset($json['error']['warning'])) { $json['error']['warning'] = $this->language->get('error_warning'); // Намагається рядку присвоїти індекс масиву, але це ж PHP 8... } Власні бібліотеки у складі модуля Якщо ваш модуль використовує бібліотеку, яка зазвичай завантажувалася в system/library, то зараз при розпакуванні архіву вона потрапить до extnension/modulecode/system/library/ . OpenCart автоматично створює простори імен, як для контролерів з моделями, так і для бібілотек: // 4.0.0.0 [Opencart\Admin\Controller\Extension\Imagescanner] => Array ( [directory] => .../opencart-4000.loc/extension/imagescanner/admin/controller/ [psr4] => ) [Opencart\Admin\Model\Extension\Imagescanner] => Array ( [directory] => .../opencart-4000.loc/extension/imagescanner/admin/model/ [psr4] => ) [Opencart\System\Extension\Imagescanner] => Array ( [directory] => .../opencart-4000.loc/extension/imagescanner/system/ [psr4] => ) // 4.0.2.0 [Opencart\System\Library\Extension\Imagescanner] => Array ( [directory] => .../opencart-4021.loc/extension/imagescanner/system/library/ [psr4] => ) Зверніть увагу, що варіант іменування класу бібліотеки ImageScanner при підключенні перетвориться на image_scanner.php (system/engine/autoloader.php). Тоді як Imagescanner відповідатиме imagescanner.php. Це при тому, що в контролері назва класу в стилі CamelCase працює ок. А чому так — це вже окрема історія. У файлі бібліотеки Задамо простір імен: // 4.0.0.0 namespace Opencart\System\Extension\Modulecode\Library; // 4.0.2.0 namespace Opencart\System\Library\Extension\Imagescanner; Називаємо клас: class Yourclassname { У файлі контролера Створюємо екземпляр класу бібліотеки у нашому контролері: // 4.0.0.0 $this->instance = new \Opencart\System\Extension\Modulecode\Library\Yourclassname(); // 4.0.2.0 $this->stdelog = new \Opencart\System\Library\Extension\Imagescanner\Stdelog('imagescanner'); З іншого боку чудово відпрацює і по-старому, і ще й ніяких приколів зі змінами в системі: require_once DIR_EXTENSION . 'modulecode/system/library/modulecode.php'; $this->instance = new Yourclassname(); // и не паритися Папка модуля На прикладі присутньої в системі папки extension/opencart (де складені всі дефолтні модулі) здавалося, що OpenCart 4 з'явилося поняття "папка постачальника". Але потім з'ясувалося, що при спробі встановити в ту ж папку інший свій модуль, воно не працює До речі, якщо в інсталяційному архіві будуть нестандартні шляхи до файлів (я, наприклад, пробував modulecode/library/file.php на 4.0.0.0), то при видаленні модуля з адмінки папка модуля не видаляється, хоча всі стандартні файли та папки звідти видалені. Тобто це може створити проблеми при оновленні модуля, адже в існуючу папку модуля установник не хоче записувати. І ще з цією папкою є один приємний момент: щоб упакувати модуль, досить просто скопіювати папку та заархівувати. Більше не потрібно ритися в папках і копіювати кожен файл окремо. P.S. На преший погляд, адаптація модуль під OpenCart 4 має бути досить простою. Я цю статтю довше писав, ніж адаптував модуль. Але огляд поки що не повний. Дописуватиму згодом. Також буду додавати в текст статті зауваження з коментарів. --
    1 point
  8. Наприклад додати jquery код внизу product.tpl [twig] let options = $('[id^="input-option"]'); options.each(function(){ $(this).find('input:first').attr('checked', true); });
    1 point
  9. підредагувати метод add (створити модифікатор дуже просто), в catalog/controller/checkout/cart.php , вказавши якщо опції не вибрані але обов’язкові, додай ці опції (наприклад - першу з них). Зверніть тут увагу.
    1 point
  10. кстати, если кому нужно, то вот здесь есть модуль для опенкарт от 2.1 до 3.0.3.8 https://www.opencart.com/index.php?route=marketplace/extension/info&extension_id=34383
    1 point
×
×
  • Create New...

Important Information

On our site, cookies are used and personal data is processed to improve the user interface. To find out what and what personal data we are processing, please go to the link. If you click "I agree," it means that you understand and accept all the conditions specified in this Privacy Notice.