* @copyright Copyright (c) 2018-2024 - www.x13.pl * @license Commercial license, only to use on restricted domains */ if (!defined('_PS_VERSION_')) { exit; } require_once _PS_MODULE_DIR_ . '/x13gpsr/x13gpsr.ion.php'; class AdminX13GPSRResponsiblePersonController extends x13gpsr\GPSRModuleAdminController { public function __construct() { $this->table = 'x13gpsr_responsible_person'; $this->identifier = 'id_x13gpsr_responsible_person'; $this->className = 'XGpsrResponsiblePerson'; $this->lang = true; $this->bootstrap = true; $this->addRowAction('edit'); $this->addRowAction('delete'); parent::__construct(); // Join query to include the count of assigned brands $this->_select = '( SELECT COUNT(rb.id_brand) FROM `' . _DB_PREFIX_ . 'x13gpsr_responsible_person_brand` rb WHERE rb.id_x13gpsr_responsible_person = a.id_x13gpsr_responsible_person ) AS brands_count'; // Join query to include the cound of assigned products $this->_select .= ', ( SELECT COUNT(rp.id_product) FROM `' . _DB_PREFIX_ . 'x13gpsr_responsible_person_product` rp WHERE rp.id_x13gpsr_responsible_person = a.id_x13gpsr_responsible_person ) AS products_count'; $this->bulk_actions = [ 'delete' => [ 'text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?') ] ]; $this->fields_list = [ 'id_x13gpsr_responsible_person' => [ 'title' => $this->l('ID'), 'align' => 'center', 'class' => 'fixed-width-xs' ], 'name' => [ 'title' => $this->l('Name and Surname / Company') ], 'private_name' => [ 'title' => $this->l('Private Name') ], 'email' => [ 'title' => $this->l('Email') ], 'brands_count' => [ 'title' => $this->l('Assigned Brands'), 'align' => 'center', 'class' => 'fixed-width-xs', 'search' => false, 'callback' => 'getAssignedBrandsCount', ], 'products_count' => [ 'title' => $this->l('Assigned Individual Products'), 'align' => 'center', 'class' => 'fixed-width-xs', 'search' => false, 'callback' => 'getAssignedProductsCount', ], // 'active' => [ // 'title' => $this->l('Active'), // 'class' => 'fixed-width-xs', // 'active' => 'status', // 'align' => 'center', // 'type' => 'bool', // 'orderby' => false, // ], ]; $this->addJS($this->module->getLocalPath() . 'views/js/back.js'); $this->addCSS($this->module->getLocalPath() . 'views/css/back.css'); Media::addJsDefL('x13gpsr_select_brands_txt', $this->l('Select brands')); } public function getAssignedBrandsCount($value, $row) { $idResponsible = $row['id_x13gpsr_responsible_person']; // Fetch assigned brands $query = new DbQuery(); $query->select('m.name') ->from('manufacturer', 'm') ->innerJoin('x13gpsr_responsible_person_brand', 'rb', 'rb.id_brand = m.id_manufacturer') ->where('rb.id_x13gpsr_responsible_person = ' . (int) $idResponsible); $assignedBrands = Db::getInstance()->executeS($query); // Format the list of brands $brandNames = array_column($assignedBrands, 'name'); $tooltipContent = '
'; if (!empty($brandNames)) { foreach ($brandNames as $name) { $tooltipContent .= '
' . htmlspecialchars($name) . '
'; } } else { $tooltipContent .= '
0
'; } $tooltipContent .= '
'; $additionalClass = ""; if ((int) $value > 0) { $additionalClass = " x13gpsr-circle-container-green"; } // Create the styled circle with tooltip $output = '
'; $output .= '' . (int) $value . ''; $output .= '
' . $tooltipContent . '
'; $output .= '
'; return $output; } public function getAssignedProductsCount($value, $row) { $additionalClass = ""; if ((int) $value > 0) { $additionalClass = " x13gpsr-circle-container-green"; } $output = '
'; $output .= '
'. $this->l('Number of products assigned directly on the product page.') . '
'; $output .= '' . (int) $value . ''; $output .= '
'; return $output; } public function renderList() { $this->initToolbar(); $this->context->smarty->assign( [ 'isX13AllegroInstalled' => Module::isInstalled('x13allegro'), ] ); $this->content .= $this->context->smarty->fetch($this->module->getLocalPath() . 'views/templates/admin/responsible-person.tpl'); return parent::renderList(); } public function renderForm() { $obj = $this->loadObject(true); $availableBrands = $this->getAvailableBrands(); $assignedBrands = $obj->id ? $this->getAssignedBrands($obj->id) : []; $htmlContentForEmptyAvailableBrands = ''; if (empty($availableBrands)) { $htmlContentForEmptyAvailableBrands = '
' . $this->l('There are no available brands available to assign. It means that all brands are already assigned to a responsible person.') . '
'; } $emptyAvailableBrandsInformation = [ 'name' => 'empty_available_brands_information', 'type' => 'html', 'html_content' => $htmlContentForEmptyAvailableBrands, ]; $countries = Country::getCountries($this->context->language->id); array_unshift($countries, ['id_country' => '', 'name' => $this->l('--- Choose ---')]); $this->fields_form = [ 'legend' => [ 'title' => $this->l('Responsible person'), 'icon' => 'icon-user', ], 'input' => [ [ 'name' => 'html_content', 'type' => 'html', 'html_content' => '
' . $this->l('You are obligated to provide all the contact details. If, for some reason, responsible person does not provide you some, you can type: "Not provided". Remember that address details may be required by external marketplaces, like Allegro.') . '
', ], [ 'type' => 'text', 'label' => $this->l('Name and Surname / Company'), 'desc' => $this->l('The responsible person may be identified as a natural person (indicated by name) or as an entity/company (indicated by name).'), 'name' => 'name', 'required' => true, ], [ 'type' => 'text', 'label' => $this->l('Private Name'), 'desc' => $this->l('The custom name will allow you to conveniently assign the correct responsible person to a specific item. The name is not visible to buyers.'), 'name' => 'private_name', 'required' => true, ], [ 'name' => 'html_content', 'type' => 'html', 'html_content' => '

'.$this->l('Address').'

', ], [ 'class' => 'chosen', 'type' => 'select', 'label' => $this->l('Country'), 'name' => 'id_country', 'options' => [ 'query' => $countries, 'id' => 'id_country', 'name' => 'name', ], 'required' => true, ], [ 'type' => 'text', 'label' => $this->l('Address'), 'name' => 'address', 'required' => true, ], [ 'type' => 'text', 'label' => $this->l('Postcode'), 'name' => 'postcode', 'required' => true, ], [ 'type' => 'text', 'label' => $this->l('City'), 'name' => 'city', 'required' => true, ], [ 'name' => 'html_content', 'type' => 'html', 'html_content' => '

'.$this->l('Contact').'

', ], [ 'name' => 'html_content', 'type' => 'html', 'html_content' => '
' . $this->l('You have to provide contact information to responsible person. If you do not have an email address, you can - for your responsibility - type three asterisks *** to hide this information from the front office and add more details or a different contact method (e.g., contact form on the website) in the textarea for the "extra information" below.') . '
', ], [ 'type' => 'text', 'label' => $this->l('Email'), 'name' => 'email', ], [ 'type' => 'text', 'label' => $this->l('Phone'), 'name' => 'phone', ], [ 'type' => 'html', 'name' => 'html_content', 'html_content' => '

'.$this->l('Other').'

', ], [ 'type' => 'textarea', 'autoload_rte' => true, 'label' => $this->l('Extra Note'), 'name' => 'extra_note', 'lang' => true, 'desc' => $this->l('Additional information about the responsible person'), ], [ 'type' => 'html', 'name' => 'html_content', 'html_content' => '

'.$this->l('Brands').'

', ], $emptyAvailableBrandsInformation, [ 'class' => 'chosen', 'type' => 'select', 'multiple' => true, 'label' => $this->l('Assign Brands'), 'name' => 'brands[]', 'required' => false, 'options' => [ 'query' => array_merge($assignedBrands, $availableBrands), 'id' => 'id_brand', 'name' => 'name', ], 'desc' => $this->l('Select brands that are assigned to this responsible person. This person will be responsible for the products of these brands.'), ], // [ // 'type' => 'switch', // 'label' => $this->l('Active'), // 'name' => 'active', // 'required' => false, // 'is_bool' => true, // 'values' => [ // [ // 'id' => 'active_on', // 'value' => 1, // 'label' => $this->l('Yes'), // ], // [ // 'id' => 'active_off', // 'value' => 0, // 'label' => $this->l('No'), // ], // ], // ], ], 'submit' => [ 'title' => $this->l('Save'), ], ]; $this->fields_value = [ 'brands[]' => Tools::getValue('brands', array_column($assignedBrands, 'id_brand')), ]; return parent::renderForm(); } public function processSave() { $privateName = Tools::getValue('private_name'); $existingRecord = XGpsrResponsiblePerson::checkIfPrivateNameExistsForId((int) Tools::getValue($this->identifier), $privateName); if ($existingRecord) { $this->errors[] = $this->l('The "Private Name" must be unique. Another record already uses this name.'); } $result = parent::processSave(); if ($result) { $idResponsible = (int) Tools::getValue($this->identifier); $brands = Tools::getValue('brands', []); Db::getInstance()->delete('x13gpsr_responsible_person_brand', 'id_x13gpsr_responsible_person = ' . $idResponsible); foreach ($brands as $idBrand) { Db::getInstance()->insert('x13gpsr_responsible_person_brand', [ 'id_x13gpsr_responsible_person' => $idResponsible, 'id_brand' => (int) $idBrand, ]); } } return $result; } /** * Retrieves the list of brands assigned to the current responsible person. * * @param int $idResponsible * * @return array */ protected function getAssignedBrands($idResponsible) { return XGpsrResponsiblePerson::getAssignedBrands($idResponsible); } /** * Retrieves the list of available brands that are not already assigned to a responsible person. * * @return array */ protected function getAvailableBrands() { $brandsQuery = new DbQuery(); $brandsQuery->select('m.id_manufacturer AS id_brand, m.name') ->from('manufacturer', 'm') ->leftJoin('x13gpsr_responsible_person_brand', 'rb', 'rb.id_brand = m.id_manufacturer') ->where('rb.id_x13gpsr_responsible_person IS NULL'); return Db::getInstance()->executeS($brandsQuery); } }