Files
drmaterac.pl/modules/x13gpsr/controllers/admin/AdminX13GPSRResponsiblePersonController.php
2025-03-21 20:24:43 +01:00

383 lines
15 KiB
PHP

<?php
/**
* @author x13.pl <x13@x13.pl>
* @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 = '<div class="x13gpsr-tooltip-brand-list">';
if (!empty($brandNames)) {
foreach ($brandNames as $name) {
$tooltipContent .= '<div class="x13gpsr-tooltip-brand-item">' . htmlspecialchars($name) . '</div>';
}
} else {
$tooltipContent .= '<div class="x13gpsr-tooltip-brand-item">0</div>';
}
$tooltipContent .= '</div>';
$additionalClass = "";
if ((int) $value > 0) {
$additionalClass = " x13gpsr-circle-container-green";
}
// Create the styled circle with tooltip
$output = '<div class="x13gpsr-circle-container'. $additionalClass .'">';
$output .= '<span>' . (int) $value . '</span>';
$output .= '<div class="x13gpsr-custom-tooltip">' . $tooltipContent . '</div>';
$output .= '</div>';
return $output;
}
public function getAssignedProductsCount($value, $row)
{
$additionalClass = "";
if ((int) $value > 0) {
$additionalClass = " x13gpsr-circle-container-green";
}
$output = '<div class="x13gpsr-circle-container'. $additionalClass .'">';
$output .= '<div class="x13gpsr-custom-tooltip">'. $this->l('Number of products assigned directly on the product page.') . '</div>';
$output .= '<span>' . (int) $value . '</span>';
$output .= '</div>';
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 = '<div class="alert alert-warning">' . $this->l('There are no available brands available to assign. It means that all brands are already assigned to a responsible person.') . '</div>';
}
$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' => '<div class="alert alert-warning"> ' . $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.') . '</div>',
],
[
'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' => '<h4 style="font-size:17px">'.$this->l('Address').'</h4>',
],
[
'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' => '<h4 style="font-size:17px">'.$this->l('Contact').'</h4>',
],
[
'name' => 'html_content',
'type' => 'html',
'html_content' => '<div class="alert alert-info"> ' . $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.') . '</div>',
],
[
'type' => 'text',
'label' => $this->l('Email'),
'name' => 'email',
],
[
'type' => 'text',
'label' => $this->l('Phone'),
'name' => 'phone',
],
[
'type' => 'html',
'name' => 'html_content',
'html_content' => '<h4 style="font-size:17px">'.$this->l('Other').'</h4>',
],
[
'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' => '<h4 style="font-size:17px">'.$this->l('Brands').'</h4>',
],
$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);
}
}