diff --git a/install.sql b/install.sql index 91446f5..cb0995a 100644 --- a/install.sql +++ b/install.sql @@ -6,6 +6,9 @@ CREATE TABLE IF NOT EXISTS `#__virtuemart_shipment_plg_zasilkovna` ( `zasilkovna_packet_id` decimal(10,0), `zasilkovna_packet_price` decimal(15,2), `weight` decimal(10,4), + `length` smallint unsigned, + `width` smallint unsigned, + `height` smallint unsigned, `branch_id` decimal(10,0), `branch_currency` char(5), `branch_name_street` varchar(500), diff --git a/install.zasilkovna.php b/install.zasilkovna.php index 1b88a0e..a78b45e 100644 --- a/install.zasilkovna.php +++ b/install.zasilkovna.php @@ -1,6 +1,7 @@ createCronToken(); + $this->createConfigurationDefaults(); if ($route === 'update' && $this->fromVersion && version_compare($this->fromVersion, '1.2.0', '<')) { $this->migratePricingRules(); } @@ -592,11 +593,11 @@ private function removeAdministratorFiles() { } /** - * Creates update carriers token. + * Creates update carriers token and other plugin configuration defaults. * * @return void */ - private function createCronToken() { + private function createConfigurationDefaults(): void { /** @var \VirtueMartModelZasilkovna $model */ $model = VmModel::getModel('zasilkovna'); $config = $model->loadConfig(); @@ -605,6 +606,12 @@ private function createCronToken() { $config['cron_token'] = substr(sha1(rand()), 0, 16); } + foreach (ConfigConstants::CONFIG_DEFAULTS as $key => $value) { + if (!array_key_exists($key, $config)) { + $config[$key] = $value; + } + } + $model->updateConfig($config); } diff --git a/media/admin/com_virtuemart/controllers/zasilkovna.php b/media/admin/com_virtuemart/controllers/zasilkovna.php index 062745a..7fa90c9 100644 --- a/media/admin/com_virtuemart/controllers/zasilkovna.php +++ b/media/admin/com_virtuemart/controllers/zasilkovna.php @@ -70,25 +70,18 @@ public function updateCarriers() /** * Handle the save task. - * @param int $data + * @param mixed $data * @throws Exception */ - public function save($data = 0) + public function save($data = 0): void { vRequest::vmCheckToken(); - $data = vRequest::getPost(); - $message = null; - - /** @var VirtueMartModelZasilkovna $model */ - $model = VmModel::getModel('zasilkovna'); - $currentData = $model->loadConfig(); - - if (strlen($data['zasilkovna_api_pass']) !== 32) { - $message = new FlashMessage(JText::_('PLG_VMSHIPMENT_PACKETERY_API_PASS_INVALID'), FlashMessage::TYPE_ERROR); - } else { - $model->updateConfig(array_replace_recursive($currentData, $data)); + if ($data === 0) { + $data = vRequest::getPost(); } + $message = $this->updateZasilkovnaConfig($data); + $redir = 'index.php?option=com_virtuemart'; $app = JFactory::getApplication(); if ($app->input->getString('task') === 'apply') { @@ -295,4 +288,49 @@ private function getExportOrders() { return isset($_POST['exportOrders']) && is_array($_POST['exportOrders']) ? $_POST['exportOrders'] : []; } + + /** + * @param array $data + * @return FlashMessage + */ + private function updateZasilkovnaConfig(array $data): FlashMessage + { + $configStorage = new VirtueMartModelZasilkovna\ConfigSessionStorage(JFactory::getSession(), 'packeteryConfig'); + + /** @var VirtueMartModelZasilkovna $model */ + $model = VmModel::getModel('zasilkovna'); + $currentData = $model->loadConfig(); + + $formValidator = new VirtueMartModelZasilkovna\ConfigurationValidator($data); + $formValidator->validate(); + + if (!$formValidator->isValid()) { + $configStorage->write($data); + $errors = $formValidator->getErrors(); + $messages = []; + + //$error is either error string translation key, or array where 1st element is sprintf template and others are sprintf arguments (all untranslated) + foreach ($errors as $formField => $error) { + if (!is_array($error)) { + $messages[] = JText::_($error); + } else { + $messages[] = sprintf( + JText::_($error[0]), + ...array_map( + static function ($item) { + return JText::_($item); + }, + array_slice($error, 1)) + ); + } + } + + return new FlashMessage(implode("
", $messages), FlashMessage::TYPE_ERROR); + } + + $model->updateConfig(array_replace_recursive($currentData, $formValidator->normalize())); + $configStorage->flush(); + + return new FlashMessage(JText::_('PLG_VMSHIPMENT_PACKETERY_CONFIG_SAVED'), FlashMessage::TYPE_MESSAGE); + } } diff --git a/media/admin/com_virtuemart/models/zasilkovna.php b/media/admin/com_virtuemart/models/zasilkovna.php index d4d2095..23360fc 100644 --- a/media/admin/com_virtuemart/models/zasilkovna.php +++ b/media/admin/com_virtuemart/models/zasilkovna.php @@ -5,6 +5,8 @@ * @link http://www.zasilkovna.cz */ +use VirtueMartModelZasilkovna\ConfigConstants; + defined('_JEXEC') or die('Restricted access'); if(!class_exists('VmModel')) require(VMPATH_ADMIN . DS . 'helpers' . DS . 'vmmodel.php'); @@ -16,7 +18,7 @@ */ class VirtueMartModelZasilkovna extends VmModel { - const VERSION = '1.4.0'; + const VERSION = '2.0.0'; const PLG_NAME = 'zasilkovna'; const MAX_WEIGHT_DEFAULT = 5; @@ -58,8 +60,8 @@ public function __construct() $this->config = $this->loadConfig(); - $this->api_pass = isset($this->config['zasilkovna_api_pass']) ? $this->config['zasilkovna_api_pass'] : ''; - $this->api_key = isset($this->config['zasilkovna_api_pass']) ? substr($this->config['zasilkovna_api_pass'], 0, 16) : ''; + $this->api_pass = $this->config[ConfigConstants::KEY_API_PASS] ?? ''; + $this->api_key = isset($this->config[ConfigConstants::KEY_API_PASS]) ? substr($this->config[ConfigConstants::KEY_API_PASS], 0, 16) : ''; $this->_media_url = JURI::root(true) . "/media/com_zasilkovna/media/"; $this->_media_path = JPATH_SITE . DS . "media" . DS . "com_zasilkovna" . DS . "media" . DS; diff --git a/media/admin/com_virtuemart/models/zasilkovna_orders.php b/media/admin/com_virtuemart/models/zasilkovna_orders.php index 24c369d..929a340 100644 --- a/media/admin/com_virtuemart/models/zasilkovna_orders.php +++ b/media/admin/com_virtuemart/models/zasilkovna_orders.php @@ -14,6 +14,7 @@ if(!class_exists('VmModel')) require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'vmmodel.php'); +use VirtueMartModelZasilkovna\ConfigConstants; use VirtueMartModelZasilkovna\Label; /** @@ -158,7 +159,13 @@ public function printCarrierLabels(array $packetIds, Label\Format $format, $offs exit; } - public function submitToZasilkovna($orders_id_arr) { + /** + * @param string[] $orders_id_arr + * @return array> + * @throws Exception + */ + public function submitToZasilkovna(array $orders_id_arr): array + { $db = JFactory::getDBO(); $gw = new SoapClient(VirtueMartModelZasilkovna::PACKETA_WSDL); @@ -185,10 +192,20 @@ public function submitToZasilkovna($orders_id_arr) { 'value' => $order['value'], 'weight' => $order['weight'], 'currency' => $order['currency'], - 'eshop' => $sender_label = $this->zas_model->getConfig('zasilkovna_eshop_label'), + 'eshop' => $sender_label = $this->zas_model->getConfig(ConfigConstants::KEY_ESHOP_LABEL), 'adultContent' => (int)$order['adult_content'] === 1, ); + $dimensions = ['length', 'width', 'height']; + $size = []; + foreach ($dimensions as $dimension) { + $size[$dimension] = $order[$dimension]; + } + + if ($order['length']) { + $attributes['size'] = $size; + } + if (!empty($order['carrier_point'])) { $attributes['carrierPickupPoint'] = $order['carrier_point']; } @@ -307,7 +324,7 @@ public function exportToCSV($orders_id_arr) { } $exportedOrders = array(); - $sender_label = $this->zas_model->getConfig('zasilkovna_eshop_label'); + $sender_label = $this->zas_model->getConfig(ConfigConstants::KEY_ESHOP_LABEL); echo '"verze 5"'.PHP_EOL.PHP_EOL; @@ -334,9 +351,9 @@ public function exportToCSV($orders_id_arr) { $row['recipient_city'], $row['recipient_zip'], $row['carrier_point'], - $row['width'], - $row['height'], - $row['depth'], + $row['width'] ?? '', + $row['height'] ?? '', + $row['length'] ?? '', ); echo "," . implode(',', $order) . PHP_EOL; @@ -430,11 +447,16 @@ private function createConvertInstance() { } } - protected function prepareForExport($orders_arr) + /** + * @param string[] $orders_arr + * @return array> + * @throws Exception + */ + protected function prepareForExport(array $orders_arr): array { if (!$orders_arr) { - return; + return []; } $db = JFactory::getDBO(); @@ -444,16 +466,28 @@ protected function prepareForExport($orders_arr) } $ordersForINStatement = implode("','", $orderNumbers); - $q = "SELECT o.order_number,curr.currency_code_3 order_currency_name, - plg.zasilkovna_packet_price order_total,oi.first_name,oi.last_name, - oi_bt.email,IFNULL(oi.phone_1, oi_bt.phone_1) as phone_1,IFNULL(oi.phone_2, oi_bt.phone_2) as phone_2,plg.packet_cod, - plg.branch_id,plg.zasilkovna_packet_id, plg.carrier_pickup_point, plg.is_carrier, - plg.address as address, plg.adult_content AS adult_content, plg.city, plg.zip_code, plg.branch_currency, plg.weight FROM #__virtuemart_orders o "; - $q .= "INNER JOIN #__virtuemart_order_userinfos oi ON o.virtuemart_order_id=oi.virtuemart_order_id AND oi.address_type = IF(o.STsameAsBT = 1, 'BT', 'ST') "; - $q .= "INNER JOIN #__virtuemart_order_userinfos oi_bt ON o.virtuemart_order_id=oi_bt.virtuemart_order_id AND oi_bt.address_type = 'BT' "; - $q .= "INNER JOIN " . $this->zas_model->getDbTableName() . " plg ON plg.order_number=o.order_number "; - $q .= "LEFT JOIN #__virtuemart_currencies curr ON curr.virtuemart_currency_id=o.order_currency "; - $q .= " WHERE o.order_number IN ('" . $ordersForINStatement . "') GROUP BY o.order_number"; + + $q = sprintf( + "SELECT o.order_number, curr.currency_code_3 order_currency_name, + plg.zasilkovna_packet_price order_total, oi.first_name, oi.last_name, + oi_bt.email, IFNULL(oi.phone_1, oi_bt.phone_1) AS phone_1, IFNULL(oi.phone_2, oi_bt.phone_2) AS phone_2, + plg.packet_cod, plg.branch_id, plg.zasilkovna_packet_id, plg.carrier_pickup_point, plg.is_carrier, + plg.address AS address, plg.adult_content AS adult_content, plg.city, plg.zip_code, plg.branch_currency, + plg.weight, plg.width, plg.length, plg.height + FROM #__virtuemart_orders o + INNER JOIN #__virtuemart_order_userinfos oi + ON o.virtuemart_order_id = oi.virtuemart_order_id AND oi.address_type = IF(o.STsameAsBT = 1, 'BT', 'ST') + INNER JOIN #__virtuemart_order_userinfos oi_bt + ON o.virtuemart_order_id = oi_bt.virtuemart_order_id AND oi_bt.address_type = 'BT' + INNER JOIN %s plg ON plg.order_number = o.order_number + LEFT JOIN #__virtuemart_currencies curr ON curr.virtuemart_currency_id = o.order_currency + WHERE o.order_number IN ('%s') + GROUP BY o.order_number + ", + $this->zas_model->getDbTableName(), + $ordersForINStatement + ); + $db->setQuery($q); $rows = $db->loadAssocList(); @@ -477,7 +511,6 @@ protected function prepareForExport($orders_arr) $street = $streetMatches[1]; } - $phone = ""; foreach (array('phone_2', 'phone_1') as $field) { @@ -488,8 +521,8 @@ protected function prepareForExport($orders_arr) } } - $orderForExport['order_number'] = $row['order_number']; - $orderForExport['recipient_firstname'] = $row['first_name']; + $orderForExport['order_number'] = $row['order_number']; + $orderForExport['recipient_firstname'] = $row['first_name']; $orderForExport['recipient_lastname'] = $row['last_name']; $orderForExport['recipient_company'] = ""; $orderForExport['recipient_email'] = $row['email']; @@ -506,9 +539,9 @@ protected function prepareForExport($orders_arr) $orderForExport['recipient_zip'] = $row['zip_code']; $orderForExport['carrier_point'] = $row['carrier_pickup_point']; $orderForExport['is_carrier'] = $row['is_carrier']; - $orderForExport['width'] = ""; - $orderForExport['height'] = ""; - $orderForExport['depth'] = ""; + $orderForExport['width'] = $row['width']; + $orderForExport['height'] = $row['height']; + $orderForExport['length'] = $row['length']; $orderForExport['zasilkovna_packet_id'] = $row['zasilkovna_packet_id']; $ordersForExport[] = $orderForExport; diff --git a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/Carrier/Repository.php b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/Carrier/Repository.php index 0296125..288f58f 100644 --- a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/Carrier/Repository.php +++ b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/Carrier/Repository.php @@ -101,11 +101,7 @@ public function getActiveHdCarriersForPublishedCountries() return $db->loadAssocList(); } - /** - * @param int $carrierId - * @return null|\stdClass - */ - public function getCarrierById($carrierId) + public function getCarrierById(int $carrierId): ?\stdClass { $db = \JFactory::getDBO(); $db->setQuery( @@ -114,6 +110,7 @@ public function getCarrierById($carrierId) vzc.name, vzc.country, vzc.deleted, + vzc.requires_size, vc.virtuemart_country_id AS vm_country FROM #__virtuemart_zasilkovna_carriers vzc LEFT JOIN #__virtuemart_countries vc diff --git a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ConfigConstants.php b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ConfigConstants.php new file mode 100644 index 0000000..4dc8dd1 --- /dev/null +++ b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ConfigConstants.php @@ -0,0 +1,27 @@ + false, + self::KEY_DEFAULT_WEIGHT => '', + self::KEY_USE_DEFAULT_DIMENSIONS => false, + self::KEY_DEFAULT_LENGTH => '', + self::KEY_DEFAULT_WIDTH => '', + self::KEY_DEFAULT_HEIGHT => '', + self::KEY_API_PASS => '', + self::KEY_ESHOP_LABEL => '', + ]; +} diff --git a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ConfigSessionStorage.php b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ConfigSessionStorage.php new file mode 100644 index 0000000..46ad199 --- /dev/null +++ b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ConfigSessionStorage.php @@ -0,0 +1,31 @@ + + */ + public function read(): array + { + return $this->get(self::ID, self::KEY) ?? []; + } + + /** + * @param array $data + * @return void + */ + public function write(mixed $data): void + { + $this->set(self::ID, self::KEY, $data); + } + + public function flush(): void + { + $this->remove(self::ID, self::KEY); + } +} diff --git a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ConfigurationValidator.php b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ConfigurationValidator.php new file mode 100644 index 0000000..c848d05 --- /dev/null +++ b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ConfigurationValidator.php @@ -0,0 +1,122 @@ + 'PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_LENGTH', + ConfigConstants::KEY_DEFAULT_WIDTH => 'PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_WIDTH', + ConfigConstants::KEY_DEFAULT_HEIGHT => 'PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_HEIGHT', + ]; + + /** + * @var array + */ + private array $formData; + + /** + * @var array |array> + */ + private array $errors = []; + + /** + * @param array $formData + */ + public function __construct(array $formData) + { + $this->formData = $formData; + } + + public function validate(): void { + $this->validateApiPassword(); + $this->validateWeight(); + $this->validateDimensions(); + } + +private function validateWeight(): void { + if ( + $this->formData[ConfigConstants::KEY_DEFAULT_WEIGHT] !== '' + && ( + !is_numeric($this->formData[ConfigConstants::KEY_DEFAULT_WEIGHT]) + || (float)$this->formData[ConfigConstants::KEY_DEFAULT_WEIGHT] < 0.001 + ) + ) { + $this->errors[ConfigConstants::KEY_DEFAULT_WEIGHT] = [ + 'PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_MUST_BE_POSITIVE', + 'PLG_VMSHIPMENT_PACKETERY_DEFAULT_WEIGHT', + ]; + + return; + } + + if ($this->formData[ConfigConstants::KEY_USE_DEFAULT_WEIGHT] === '1' && empty($this->formData[ConfigConstants::KEY_DEFAULT_WEIGHT])) { + $this->errors[ConfigConstants::KEY_DEFAULT_WEIGHT] = [ + 'PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_IS_REQUIRED', + 'PLG_VMSHIPMENT_PACKETERY_DEFAULT_WEIGHT', + ]; + } + } + + private function validateDimensions(): void { + foreach (self::DIMENSIONS as $field => $label) { + if ((!empty($this->formData[$field]) || $this->formData[$field] === '0') + && (!is_numeric($this->formData[$field]) || (int)$this->formData[$field] < 1) + ) { + $this->errors[$field] = ['PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_MUST_BE_POSITIVE_INTEGER', $label]; + continue; + } + if ($this->formData[ConfigConstants::KEY_USE_DEFAULT_DIMENSIONS] === '1' && empty($this->formData[$field])) { + $this->errors[$field] = ['PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_IS_REQUIRED', $label]; + } + } + } + + private function validateApiPassword(): void { + if ($this->formData[ConfigConstants::KEY_API_PASS] === '') { + $this->errors[ConfigConstants::KEY_API_PASS] = 'PLG_VMSHIPMENT_PACKETERY_API_PASS_NOT_SET'; + return; + } + if (strlen($this->formData[ConfigConstants::KEY_API_PASS]) !== 32) { + $this->errors[ConfigConstants::KEY_API_PASS] = 'PLG_VMSHIPMENT_PACKETERY_API_PASS_INVALID'; + } + } + + public function isValid(): bool { + return empty($this->errors); + } + + /** + * @return array|array> + */ + public function getErrors(): array { + return $this->errors; + } + + /** + * @return array + */ + public function normalize(): array { + + $normalizedData = []; + $normalizedData[ConfigConstants::KEY_API_PASS] = $this->formData[ConfigConstants::KEY_API_PASS]; + $normalizedData[ConfigConstants::KEY_ESHOP_LABEL] = $this->formData[ConfigConstants::KEY_ESHOP_LABEL] ?? ConfigConstants::CONFIG_DEFAULTS[ConfigConstants::KEY_ESHOP_LABEL]; + + $normalizedData[ConfigConstants::KEY_USE_DEFAULT_WEIGHT] = $this->formData[ConfigConstants::KEY_USE_DEFAULT_WEIGHT] === '1'; + $normalizedData[ConfigConstants::KEY_DEFAULT_WEIGHT] = is_numeric($this->formData[ConfigConstants::KEY_DEFAULT_WEIGHT]) ? round((float)$this->formData[ConfigConstants::KEY_DEFAULT_WEIGHT], 3) : ''; + + $normalizedData[ConfigConstants::KEY_USE_DEFAULT_DIMENSIONS] = $this->formData[ConfigConstants::KEY_USE_DEFAULT_DIMENSIONS] === '1'; + foreach (self::DIMENSIONS as $field => $label) { + $normalizedData[$field] = is_numeric($this->formData[$field]) ? (int)$this->formData[$field] : ''; + } + + $paymentMethods = array_filter( + $this->formData, + static function ($key) { + return str_starts_with($key, ConfigConstants::KEY_PAYMENT_METHOD_PREFIX); + }, + ARRAY_FILTER_USE_KEY + ); + + return array_merge($normalizedData, $paymentMethods); + } +} diff --git a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/Order/Order.php b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/Order/Order.php index f6192b9..a7c95bf 100644 --- a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/Order/Order.php +++ b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/Order/Order.php @@ -25,6 +25,12 @@ class Order /* @var float $weight */ private $weight; + private ?int $length; + + private ?int $width; + + private ?int $height; + /* @var float $branch_id */ private $branch_id; diff --git a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/SessionStorage.php b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/SessionStorage.php new file mode 100644 index 0000000..5a2c09f --- /dev/null +++ b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/SessionStorage.php @@ -0,0 +1,67 @@ +session = $session; + if ($namespace) { + $this->namespace = $namespace; + } + } + + /** + * @param int|string $id + * @param string $key + * @param mixed|null $default + * @return mixed + */ + public function get(int|string $id, string $key, mixed $default = null): mixed + { + return $this->session->get($this->composeKey($id, $key), $default); + } + + /** + * @param int|string $id + * @param string $key + * @param mixed $value + */ + public function set(int|string $id, string $key, mixed $value): void + { + $this->session->set($this->composeKey($id, $key), $value); + } + + /** + * @param int|string $id + * @param string $key + */ + public function remove(int|string $id, string $key): void + { + $this->session->remove($this->composeKey($id, $key)); + } + + /** + * @param int|string $id + * @param string $key + * @return string + */ + private function composeKey(int|string $id, string $key): string + { + if ($id === '' || $key === '') { + throw new \InvalidArgumentException('Id or key cannot be empty'); + } + + return $this->namespace . '.' . $id . '.' . $key; + } +} diff --git a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ShipmentMethodStorage.php b/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ShipmentMethodStorage.php deleted file mode 100644 index a649a74..0000000 --- a/media/admin/com_virtuemart/models/zasilkovna_src/VirtueMartModelZasilkovna/ShipmentMethodStorage.php +++ /dev/null @@ -1,50 +0,0 @@ -session = $session; - } - - /** - * @param string|int $methodId - * @param string $key - * @param mixed $default - * @return mixed - */ - public function get($methodId, $key, $default = null) - { - return $this->session->get($methodId . '.' . $key, $default, $this->namespace); - } - - /** - * @param string|int $methodId - * @param string $key - * @param mixed $value - */ - public function set($methodId, $key, $value) - { - $this->session->set($methodId . '.' . $key, $value, $this->namespace); - } - - /** - * @param string|int $methodId - * @param string $key - */ - public function clear($methodId, $key) - { - $this->session->clear($methodId . '.' . $key, $this->namespace); - } -} diff --git a/media/admin/com_virtuemart/views/zasilkovna/tmpl/default_config.php b/media/admin/com_virtuemart/views/zasilkovna/tmpl/default_config.php index c5116f9..2cbd6a1 100644 --- a/media/admin/com_virtuemart/views/zasilkovna/tmpl/default_config.php +++ b/media/admin/com_virtuemart/views/zasilkovna/tmpl/default_config.php @@ -1,6 +1,7 @@ setTemplate(Detail::TEMPLATES_DIR . DS . 'card.php'); @@ -30,7 +32,7 @@ - getConfig('zasilkovna_api_pass')); ?>
+ getFormValue(ConfigConstants::KEY_API_PASS)); ?>
',''); ?>
', ''); ?> @@ -40,7 +42,7 @@ - getConfig('zasilkovna_eshop_label')); ?>
+ getFormValue(ConfigConstants::KEY_ESHOP_LABEL)); ?>
', @@ -64,13 +66,15 @@ ob_start(); ?> - paymentMethods as $paymentMethod) { ?> + paymentMethods as $paymentMethod) { + $field = ConfigConstants::KEY_PAYMENT_METHOD_PREFIX . $paymentMethod->virtuemart_paymentmethod_id; + ?> @@ -79,9 +83,87 @@ $codContent = ob_get_clean(); ob_start(); +// Default weight and dimensions start ?> +
payment_name; ?> - virtuemart_paymentmethod_id, $model->getConfig('zasilkovna_payment_method_' . $paymentMethod->virtuemart_paymentmethod_id, '0') ); ?> + getFormValue($field, '0') ); ?>
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + getFormValue(ConfigConstants::KEY_USE_DEFAULT_WEIGHT)); ?> +
+ + + +
+ + + getFormValue(ConfigConstants::KEY_USE_DEFAULT_DIMENSIONS)); ?> +
+ + + +
+ + + +
+ + + +
setVariables([ 'title' => JText::_('PLG_VMSHIPMENT_PACKETERY_SETTINGS'), 'icon' => 'cog', @@ -95,3 +177,10 @@ 'content' => $codContent, ]); echo $renderer->renderToString(); + +$renderer->setVariables([ + 'title' => JText::_('PLG_VMSHIPMENT_PACKETERY_DEFAULT_WEIGHT_DIMENSIONS_TITLE'), + 'icon' => 'cog', + 'content' => $weightDimensionsContent, +]); +echo $renderer->renderToString(); diff --git a/media/admin/com_virtuemart/views/zasilkovna/view.html.php b/media/admin/com_virtuemart/views/zasilkovna/view.html.php index 4de3ab6..12847c5 100644 --- a/media/admin/com_virtuemart/views/zasilkovna/view.html.php +++ b/media/admin/com_virtuemart/views/zasilkovna/view.html.php @@ -37,6 +37,14 @@ */ class VirtuemartViewZasilkovna extends VmViewAdmin { + public VirtueMartModelZasilkovna $model; + public \VirtueMartModelZasilkovna\ConfigSessionStorage $configStorage; + public function __construct($config = array()) { + parent::__construct($config); + $this->model = VmModel::getModel(); + $this->configStorage = new \VirtueMartModelZasilkovna\ConfigSessionStorage(JFactory::getSession(),'packeteryConfig'); + } + function display($tpl = NULL) { @@ -47,10 +55,7 @@ function display($tpl = NULL) { $configModel = VmModel::getModel('config'); - /** @var VirtueMartModelZasilkovna $model */ - $model = VmModel::getModel(); - - if(!$model->getConfig(VirtuemartControllerZasilkovna::ZASILKOVNA_LIMITATIONS_REMOVED_NOTICE_DISMISSED, false)) { + if(!$this->model->getConfig(VirtuemartControllerZasilkovna::ZASILKOVNA_LIMITATIONS_REMOVED_NOTICE_DISMISSED, false)) { $this->showLimitationsRemovedNotice(); } @@ -64,8 +69,8 @@ function cmpShipments($a, $b) { $this->shipmentMethods = $shipments; $this->moduleVersion = VirtueMartModelZasilkovna::VERSION; - $this->errors = $model->errors; - $this->warnings = $model->warnings; + $this->errors = $this->model->errors; + $this->warnings = $this->model->warnings; $paymentModel = VmModel::getModel('paymentmethod'); $payments = $paymentModel->getPayments(); @@ -153,8 +158,9 @@ function cmpPayments($a, $b) { $this->pagination = $ordersModel->getPagination(); $this->shipmentSelect = $this->renderShipmentsList(); - $model->raiseErrors($mainframe); + $this->model->raiseErrors($mainframe); parent::display($tpl); + $this->configStorage->flush(); } public function renderOrderstatesList() { @@ -218,4 +224,22 @@ private function showLimitationsRemovedNotice() $app = JFactory::getApplication(); $app->enqueueMessage($fullFlashMessage, \VirtueMartModelZasilkovna\FlashMessage::TYPE_NOTICE); } + + /** + * @param string $name + * @param mixed $default + * @return array|mixed|string + */ + public function getFormValue(string $name, mixed $default = ''): mixed + { + static $sessionData = null; + + if ($sessionData === null) { + $sessionData = $this->configStorage->read(); + } + + $fromSession = $sessionData[$name] ?? null; + + return $fromSession ?? $this->model->getConfig($name, $default); + } } diff --git a/media/admin/cs-CZ.plg_vmshipment_zasilkovna.ini b/media/admin/cs-CZ.plg_vmshipment_zasilkovna.ini index 94b3a05..e5fa6f0 100644 --- a/media/admin/cs-CZ.plg_vmshipment_zasilkovna.ini +++ b/media/admin/cs-CZ.plg_vmshipment_zasilkovna.ini @@ -129,3 +129,15 @@ PLG_VMSHIPMENT_PACKETERY_ORDER_DETAILS_UPDATED="Detaily objednávky byly aktuali PLG_VMSHIPMENT_PACKETERY_CONFIG_PICKUP_POINTS_GROUPS="Typy výdejních míst" PLG_VMSHIPMENT_PACKETERY_CONFIG_PICKUP_POINTS_GROUP_ZPOINT="Výdejní místa" PLG_VMSHIPMENT_PACKETERY_CONFIG_PICKUP_POINTS_GROUP_ZBOX="Z-Box" + +PLG_VMSHIPMENT_PACKETERY_DEFAULT_WEIGHT_DIMENSIONS_TITLE="Výchozí hmotnost a rozměry zásilky" +PLG_VMSHIPMENT_PACKETERY_USE_DEFAULT_WEIGHT="Použít výchozí hmotnost" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_WEIGHT="Výchozí hmotnost (kg)" +PLG_VMSHIPMENT_PACKETERY_USE_DEFAULT_DIMENSIONS="Použít výchozí rozměry" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_WIDTH="Výchozí šířka (mm)" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_HEIGHT="Výchozí výška (mm)" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_LENGTH="Výchozí délka (mm)" +PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_MUST_BE_POSITIVE="Pole %s musí být kladné číslo." +PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_MUST_BE_POSITIVE_INTEGER="Pole %s musí být kladné celé číslo." +PLG_VMSHIPMENT_PACKETERY_CONFIG_SAVED="Nastavení bylo uloženo." +PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_IS_REQUIRED="Field %s is required." diff --git a/media/admin/en-GB.plg_vmshipment_zasilkovna.ini b/media/admin/en-GB.plg_vmshipment_zasilkovna.ini index 0dd6ff6..cddf8f8 100644 --- a/media/admin/en-GB.plg_vmshipment_zasilkovna.ini +++ b/media/admin/en-GB.plg_vmshipment_zasilkovna.ini @@ -129,3 +129,15 @@ PLG_VMSHIPMENT_PACKETERY_ORDER_DETAILS_UPDATED="Order details were updated." PLG_VMSHIPMENT_PACKETERY_CONFIG_PICKUP_POINTS_GROUPS="Groups" PLG_VMSHIPMENT_PACKETERY_CONFIG_PICKUP_POINTS_GROUP_ZPOINT="Pickup points" PLG_VMSHIPMENT_PACKETERY_CONFIG_PICKUP_POINTS_GROUP_ZBOX="Z-Box" + +PLG_VMSHIPMENT_PACKETERY_DEFAULT_WEIGHT_DIMENSIONS_TITLE="Default packet weight and dimensions" +PLG_VMSHIPMENT_PACKETERY_USE_DEFAULT_WEIGHT="Use default weight" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_WEIGHT="Default weight (kg)" +PLG_VMSHIPMENT_PACKETERY_USE_DEFAULT_DIMENSIONS="Use default dimensions" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_WIDTH="Default width (mm)" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_HEIGHT="Default height (mm)" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_LENGTH="Default length (mm)" +PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_MUST_BE_POSITIVE="Field %s must be a positive number." +PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_MUST_BE_POSITIVE_INTEGER="Field %s must be a positive integer number." +PLG_VMSHIPMENT_PACKETERY_CONFIG_SAVED="Configuration was saved." +PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_IS_REQUIRED="Field %s is required." diff --git a/media/admin/sk-SK.plg_vmshipment_zasilkovna.ini b/media/admin/sk-SK.plg_vmshipment_zasilkovna.ini index 0b6bbde..3877eb0 100644 --- a/media/admin/sk-SK.plg_vmshipment_zasilkovna.ini +++ b/media/admin/sk-SK.plg_vmshipment_zasilkovna.ini @@ -130,3 +130,15 @@ PLG_VMSHIPMENT_PACKETERY_ORDER_DETAILS_UPDATED="Detaily objednávky byly aktuali PLG_VMSHIPMENT_PACKETERY_CONFIG_PICKUP_POINTS_GROUPS="Typy výdajných miest" PLG_VMSHIPMENT_PACKETERY_CONFIG_PICKUP_POINTS_GROUP_ZPOINT="Výdajné miesta" PLG_VMSHIPMENT_PACKETERY_CONFIG_PICKUP_POINTS_GROUP_ZBOX="Z-Box" + +PLG_VMSHIPMENT_PACKETERY_DEFAULT_WEIGHT_DIMENSIONS_TITLE="Výchozí hmotnost a rozměry zásilky" +PLG_VMSHIPMENT_PACKETERY_USE_DEFAULT_WEIGHT="Použít výchozí hmotnost" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_WEIGHT="Výchozí hmotnost (kg)" +PLG_VMSHIPMENT_PACKETERY_USE_DEFAULT_DIMENSIONS="Použít výchozí rozměry" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_WIDTH="Výchozí šířka (mm)" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_HEIGHT="Výchozí výška (mm)" +PLG_VMSHIPMENT_PACKETERY_DEFAULT_DIMENSIONS_LENGTH="Výchozí délka (mm)" +PLG_VMSHIPMENT_PACKETERY_ENTER_POSITIVE_VALUE_IN_MM="zadejte kladnou hodnotu v mm" +PLG_VMSHIPMENT_PACKETERY_ENTER_POSITIVE_VALUE_IN_KG="zadejte kladnou hodnotu v kg" +PLG_VMPSHIPMENT_PACKETERY_DEFAULT_FIELD_MUST_BE_POSITIVE="Pole %s je povinné a musí být kladné číslo." +PLG_VMSHIPMENT_PACKETERY_CONFIG_SAVED="Nastavení bylo uloženo." diff --git a/media/media/css/admin.css b/media/media/css/admin.css index 0e8f222..8398d49 100644 --- a/media/media/css/admin.css +++ b/media/media/css/admin.css @@ -45,6 +45,10 @@ fieldset { padding-bottom: 10px; } +.pb-28 { + padding-bottom: 28px; +} + .va-middle { vertical-align: middle !important; } diff --git a/zasilkovna.php b/zasilkovna.php index 7b68e4d..d86eaa1 100644 --- a/zasilkovna.php +++ b/zasilkovna.php @@ -1,5 +1,6 @@ model = VmModel::getModel('zasilkovna'); $this->session = JFactory::getSession(); $this->checkoutModuleDetector = new \VirtueMartModelZasilkovna\CheckoutModuleDetector(); - $this->shipmentMethodStorage = new \VirtueMartModelZasilkovna\ShipmentMethodStorage($this->session); + $this->shipmentMethodStorage = new \VirtueMartModelZasilkovna\SessionStorage($this->session, 'packeteryShipmentMethods'); $this->shipmentMethodValidator = new \VirtueMartModelZasilkovna\ShipmentMethodValidator(); $this->orderDetail = new \VirtueMartModelZasilkovna\Order\Detail(); $this->orderRepository = new \VirtueMartModelZasilkovna\Order\Repository(); @@ -235,22 +235,22 @@ public function plgVmOnShowOrderFEShipment($virtuemart_order_id, $virtuemart_shi * @param string|int $methodId */ public function clearPickedDeliveryPoint($methodId) { - $this->shipmentMethodStorage->clear($methodId, 'branch_id'); - $this->shipmentMethodStorage->clear($methodId, 'branch_currency'); - $this->shipmentMethodStorage->clear($methodId, 'branch_name_street'); - $this->shipmentMethodStorage->clear($methodId, 'branch_country'); - $this->shipmentMethodStorage->clear($methodId, 'branch_carrier_id'); - $this->shipmentMethodStorage->clear($methodId, 'branch_carrier_pickup_point'); + $this->shipmentMethodStorage->remove($methodId, 'branch_id'); + $this->shipmentMethodStorage->remove($methodId, 'branch_currency'); + $this->shipmentMethodStorage->remove($methodId, 'branch_name_street'); + $this->shipmentMethodStorage->remove($methodId, 'branch_country'); + $this->shipmentMethodStorage->remove($methodId, 'branch_carrier_id'); + $this->shipmentMethodStorage->remove($methodId, 'branch_carrier_pickup_point'); } /** * This event is fired after the order has been stored; it gets the shipment method- * specific data. * - * @return mixed Null when this method was not selected, otherwise true + * @return null|bool Null when this method was not selected, otherwise true * @author Valerie Isaksen */ - function plgVmConfirmedOrder(VirtueMartCart $cart, $order) { + function plgVmConfirmedOrder(VirtueMartCart $cart, array $order): ?bool { if (!($method = $this->getVmPluginMethod($order['details']['BT']->virtuemart_shipmentmethod_id))) { return null; // Another method was selected, do nothing } @@ -268,13 +268,18 @@ function plgVmConfirmedOrder(VirtueMartCart $cart, $order) { // GET PARAMETERS FROM SESSION AND CLEAR $branch_id = $this->shipmentMethodStorage->get($cart->virtuemart_shipmentmethod_id, 'branch_id', 0); - $branch_name_street = $this->shipmentMethodStorage->get($cart->virtuemart_shipmentmethod_id, 'branch_name_street', ''); - $branch_carrier_id = $this->shipmentMethodStorage->get($cart->virtuemart_shipmentmethod_id, 'branch_carrier_id'); - $branch_carrier_pickup_point = $this->shipmentMethodStorage->get($cart->virtuemart_shipmentmethod_id, 'branch_carrier_pickup_point'); + $branch_name_street = $this->shipmentMethodStorage->get($cart->virtuemart_shipmentmethod_id, + 'branch_name_street', + ''); + $branch_carrier_id = $this->shipmentMethodStorage->get($cart->virtuemart_shipmentmethod_id, 'branch_carrier_id', + null); + $branch_carrier_pickup_point = $this->shipmentMethodStorage->get($cart->virtuemart_shipmentmethod_id, + 'branch_carrier_pickup_point', + null); $this->clearPickedDeliveryPoint($cart->virtuemart_shipmentmethod_id); - $codSettings = $this->model->getConfig('zasilkovna_payment_method_'.$cart->virtuemart_paymentmethod_id, 0); + $codSettings = $this->model->getConfig(ConfigConstants::KEY_PAYMENT_METHOD_PREFIX . $cart->virtuemart_paymentmethod_id, 0); $billing=$order['details']['BT']; $shipping=$order['details']['ST']; @@ -315,6 +320,7 @@ function plgVmConfirmedOrder(VirtueMartCart $cart, $order) { } else { $branch_id = $branch_carrier_id; $is_carrier = 1; + $carrier = $this->carrierRepository->getCarrierById($branch_id); } if ($zasMethod->isHdCarrier()) { @@ -351,8 +357,29 @@ function plgVmConfirmedOrder(VirtueMartCart $cart, $order) { $values['exported'] = 0; $values['shipment_name'] = $method->shipment_name; $values['shipment_cost'] = $this->getCosts($cart, ShipmentMethod::fromRandom($method), ""); - $values['weight'] = $this->getOrderWeight($cart, self::DEFAULT_WEIGHT_UNIT); + $weight = $this->getOrderWeight($cart, self::DEFAULT_WEIGHT_UNIT); + + if (!$weight && $this->model->getConfig(ConfigConstants::KEY_USE_DEFAULT_WEIGHT) === true) { + $weight = (float)$this->model->getConfig(ConfigConstants::KEY_DEFAULT_WEIGHT); + } + $values['weight'] = $weight; $values['tax_id'] = $method->tax_id; + + if ($is_carrier === 1 + && $carrier + && $carrier->requires_size === 1 + && $this->model->getConfig(ConfigConstants::KEY_USE_DEFAULT_DIMENSIONS) === true + ) { + $values['length'] = (int)$this->model->getConfig(ConfigConstants::KEY_DEFAULT_LENGTH); + $values['width'] = (int)$this->model->getConfig(ConfigConstants::KEY_DEFAULT_WIDTH); + $values['height'] = (int)$this->model->getConfig(ConfigConstants::KEY_DEFAULT_HEIGHT); + } else { + //empty string to force null in database + $values['length'] = ''; + $values['width'] = ''; + $values['height'] = ''; + } + $this->storePSPluginInternalData($values); return true; @@ -697,7 +724,7 @@ public function plgVmOnCheckoutCheckDataShipment(VirtueMartCart $cart) { */ public function hasPointSelected($methodId) { - $branchId = $this->shipmentMethodStorage->get($methodId, 'branch_id'); + $branchId = $this->shipmentMethodStorage->get($methodId, 'branch_id', null); return !empty($branchId); } @@ -824,7 +851,9 @@ public function plgVmDisplayListFEShipment(VirtueMartCart $cart, $selected = 0, 'baseHtml' => $baseHtml, 'isCountrySelected' => !empty($address['virtuemart_country_id']), 'savedBranchNameStreet' => - (string)$this->shipmentMethodStorage->get($method->virtuemart_shipmentmethod_id, 'branch_name_street', ''), + (string)$this->shipmentMethodStorage->get($method->virtuemart_shipmentmethod_id, + 'branch_name_street', + ''), ] ); @@ -943,7 +972,7 @@ public function plgVmOnUpdateCart(VirtueMartCart $cart) { } $countryCode = strtolower(ShopFunctions::getCountryByID($address['virtuemart_country_id'], 'country_2_code')); - $sessionCountry = $this->shipmentMethodStorage->get($virtuemartShipmentMethodId, 'branch_country'); + $sessionCountry = $this->shipmentMethodStorage->get($virtuemartShipmentMethodId, 'branch_country', null); if ($sessionCountry && $countryCode !== $sessionCountry) { $this->clearPickedDeliveryPoint($virtuemartShipmentMethodId); $cart->virtuemart_shipmentmethod_id = null; // makes selected shipping method disappear diff --git a/zasilkovna.xml b/zasilkovna.xml index 1a13235..7eb7001 100644 --- a/zasilkovna.xml +++ b/zasilkovna.xml @@ -11,7 +11,7 @@ (c) 2021 Zásilkovna s.r.o. License Info with link - 1.4.0 + 2.0.0 2021-06-29