Check the complete article in Linkedin
Challenge
In PrestaShop, we do not have a function or module for checking a product available only for a certain period of time or within a certain range of date. It is because Prestashop is CMS which sells only products.
However we needed to customised PrestaShop to sell activities and events which are available for Only a certain range of dates.
Solution
To solve this issue we created a new module “availabilitymodule” to implement different date availability options in the back-end.
Check how we extended the existing to code to achieve the intended result:
Front end


Code of the Default module:
<?php if (!defined('_PS_VERSION_')) { exit; } require_once(dirname(__FILE__) . '/classes/Availability.php'); require_once(dirname(__FILE__) . '/classes/AvailabilitySchedule.php'); class AvailabilityModule extends Module { public function __construct() { $this->name = 'availabilitymodule'; $this->tab = 'front_office_features'; $this->version = '1.0.0'; $this->need_instance = 0; $this->module_key = ""; $this->author = "SS4U"; parent::__construct(); $this->displayName = $this->l('Availability date Module'); $this->description = $this->l('Works with displayAdminProductsExtra and actionProductUpdate'); } public function install() { $sql = array(); $sql[] = 'CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'availability` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id_product` int(11) unsigned NOT NULL, `free_date` tinyint(1) NOT NULL, `last_minute` tinyint(1) NOT NULL, `date_from` date NOT NULL, `date_to` date NOT NULL, `periodic_event` text NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `AVAILABILITY_DATE_UNIQ` (`id_product`) ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8'; $sql[] = 'CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'availability_schedule` ( `id` int(11) NOT NULL AUTO_INCREMENT, `id_availability` int(11) NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8'; if (!parent::install() OR !$this->registerHook('displayAdminProductsExtra') || !$this->registerHook('displayFrontendProductsExtra') || !$this->registerHook('actionKbSellerProductAdd') || !$this->registerHook('actionProductUpdate') || !$this->registerHook('actionProductDelete') || !$this->runSql($sql) ) { return false; } return true; } public function uninstall() { $sql = array(); $sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'availability`'; $sql[] = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'availability_schedule`'; if (!parent::uninstall() || !$this->runSql($sql) ) { return false; } return true; } public function runSql($sql) { foreach ($sql as $s) { if (!Db::getInstance()->Execute($s)) { return false; } } return true; } public function hookDisplayAdminProductsExtra($params) { $id_product = $params['id_product']; $availabilityObj = Availability::loadByIdProduct($id_product); if (!empty($availabilityObj) && isset($availabilityObj->id)) { $this->context->smarty->assign(array( 'availabilityObj' => $availabilityObj, 'schedules' => AvailabilitySchedule::loadByIdAvailability($availabilityObj->id), 'periodicEvent' => !empty($availabilityObj->periodic_event) ? unserialize($availabilityObj->periodic_event) : array(), )); } return $this->display(__FILE__, 'views/admin/availability.tpl'); } public function hookDisplayFrontendProductsExtra($params) { $id_product = $params['id_product']; $availabilityObj = Availability::loadByIdProduct($id_product); $this->context->smarty->assign(array( 'availabilityObj' => $availabilityObj, 'schedules' => AvailabilitySchedule::loadByIdAvailability($availabilityObj->id), 'periodicEvent' => !empty($availabilityObj->periodic_event) ? unserialize($availabilityObj->periodic_event) : array(), 'language' => $this->context->language->id, )); return $this->display(__FILE__, 'views/frontend/availability.tpl'); } public function hookActionKbSellerProductAdd($params) { $productObj = $params['product']; $_POST['id_product'] = $productObj->id; $this->hookActionProductUpdate($params); } public function hookActionProductUpdate($params) { if (!empty(Tools::getValue('duplicateProduct')) && !$this->actionDuplicate()) { return fasle; } $id_product = Tools::getValue('id_product'); $availabilityObj = Availability::loadByIdProduct($id_product); $freeDate = Tools::getValue('free_date'); $lastMinute = Tools::getValue('last_minute'); if ($freeDate) { $availabilityObj->free_date = 1; $availabilityObj->date_from = ''; $availabilityObj->date_to = ''; $availabilityObj->periodic_event = ''; $scheduleDate = array(); } else { $availabilityObj->free_date = 0; $availabilityObj->date_from = Tools::getValue('date_from'); $availabilityObj->date_to = Tools::getValue('date_to'); if ( ($availabilityObj->date_from && empty($availabilityObj->date_to)) || (empty($availabilityObj->date_from) && $availabilityObj->date_to) || ( $availabilityObj->date_from && $availabilityObj->date_to && $availabilityObj->date_from > $availabilityObj->date_to ) ) { throw new Exception('Please check the available date range.'); } $availabilityObj->periodic_event = is_array(Tools::getValue('periodic_event')) ? serialize(Tools::getValue('periodic_event')) : Tools::getValue('periodic_event'); $scheduleDate = array_filter(Tools::getValue('schedule')); } $availabilityObj->last_minute = $lastMinute; $availabilityObj->id_product = $id_product; if (!empty($availabilityObj) && isset($availabilityObj->id)) { $availabilityObj->update(); } else { $availabilityObj->add(); } $schedule = new AvailabilitySchedule(); $schedule->addSchedules($availabilityObj->id, $scheduleDate); return true; } public function hookActionProductDelete($params) { $availabilityObj = Availability::loadByIdProduct($params['id_product']); if ($availabilityObj->id) { AvailabilitySchedule::deleteAllSchedules($availabilityObj->id); $availabilityObj->delete(); } return true; } public function actionDuplicate() { $availabilityObj = Availability::loadByIdProduct(Tools::getValue('id_duplicate_product', $_GET['id_product'])); if (!$availabilityObj->id) { return false; } $properties = array('free_date', 'last_minute', 'date_from', 'date_to', 'periodic_event'); foreach ($properties as $prop) { $_POST[$prop] = $this->getFieldValue($availabilityObj, $prop); } $_POST['schedule'] = AvailabilitySchedule::getAvailabilityScheduleDate($availabilityObj->id); return true; } protected function getFieldValue($obj, $key, $id_lang = null, $default_value = false) { $default_value = false; if ($id_lang) { if (isset($obj->id) && $obj->id) { if (is_array($obj->{$key}) && isset($obj->{$key}[$id_lang])) { $default_value = $obj->{$key}[$id_lang]; } elseif (isset($obj->{$key})) { $default_value = $obj->{$key}; } } } else { if (isset($obj->id) && $obj->id) { if (isset($obj->{$key})) { $default_value = $obj->{$key}; } } } return Tools::getValue($key . ($id_lang ? '_' . $id_lang : ''), $default_value); } }
Admin Back end

