Init project
Future fixes: -Remove logic for showing current order reference in ajax.js. Instead grab from database using cart ID
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
vendor/
|
||||
29
composer.json
Normal file
29
composer.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "dewebsmid/ws_orderreference",
|
||||
"description": "Adds an optional order reference field to the shopping cart summary.",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Isabelle Oving-Anno",
|
||||
"email": "isabelle@dewebsmid.nl"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.2.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Module\\WsOrderreference\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"ws_orderreference.php"
|
||||
],
|
||||
"exclude-from-classmap": []
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist",
|
||||
"prepend-autoloader": false
|
||||
},
|
||||
"type": "prestashop-module",
|
||||
"author": "Isabelle Oving-Anno",
|
||||
"license": "AFL-3.0"
|
||||
}
|
||||
20
composer.lock
generated
Normal file
20
composer.lock
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "14a8801fe935c090041cfc25afe6829f",
|
||||
"packages": [],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=8.2.0"
|
||||
},
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
18
config/services.yml
Normal file
18
config/services.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
# Repository - this makes it available via dependency injection
|
||||
Module\WsOrderreference\Repository\OrderReferenceRepository:
|
||||
public: true
|
||||
factory: ["@doctrine.orm.default_entity_manager", getRepository]
|
||||
arguments:
|
||||
- Module\WsOrderreference\Entity\OrderReference
|
||||
|
||||
# Database installer
|
||||
Module\WsOrderreference\Database\ReferenceInstaller:
|
||||
public: true
|
||||
arguments:
|
||||
- "@doctrine.dbal.default_connection"
|
||||
- "%database_prefix%"
|
||||
11
config_nl.xml
Normal file
11
config_nl.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<module>
|
||||
<name>ws_orderreference</name>
|
||||
<displayName><![CDATA[Orderreferentie]]></displayName>
|
||||
<version><![CDATA[1.0.0]]></version>
|
||||
<description><![CDATA[Voegt een optioneel orderreferentieveld toe aan het winkelwagenoverzicht.]]></description>
|
||||
<author><![CDATA[Isabelle Oving-Anno | De Websmid b.v.]]></author>
|
||||
<tab><![CDATA[other]]></tab>
|
||||
<is_configurable>0</is_configurable>
|
||||
<need_instance>0</need_instance>
|
||||
</module>
|
||||
63
controllers/front/ajax.php
Normal file
63
controllers/front/ajax.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
use Module\WsOrderreference\Entity\OrderReference;
|
||||
use Module\WsOrderreference\Repository\OrderReferenceRepository;
|
||||
|
||||
if (file_exists(__DIR__ . '../../vendor/autoload.php')) {
|
||||
require_once __DIR__ . '../../vendor/autoload.php';
|
||||
}
|
||||
|
||||
class ws_orderreferenceAjaxModuleFrontController extends ModuleFrontController
|
||||
{
|
||||
public function initContent()
|
||||
{
|
||||
$orderReference = Tools::getValue('order_reference_input');
|
||||
$idCart = $this->context->cart->id;
|
||||
|
||||
if (!$idCart) {
|
||||
$this->ajaxRender(json_encode([
|
||||
'success' => false,
|
||||
'message' => $this->module->l('No cart found.', 'ajax')
|
||||
]));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9_\- ]+$/', $orderReference)) {
|
||||
$this->ajaxRender(json_encode([
|
||||
'success' => false,
|
||||
'message' => $this->module->l('Please enter a valid order reference. Characters allowed: a-z, 0-9, -, _ and space', 'ajax')
|
||||
]));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
/** @var \Doctrine\ORM\EntityManagerInterface $entityManager */
|
||||
$entityManager = $this->get('doctrine.orm.default_entity_manager');
|
||||
|
||||
/** @var OrderReferenceRepository $repository */
|
||||
$repository = $entityManager->getRepository(OrderReference::class);
|
||||
|
||||
$orderRef = $repository->findByCartId($idCart);
|
||||
|
||||
if (!$orderRef) {
|
||||
$orderRef = new OrderReference();
|
||||
$orderRef->setIdCart($idCart);
|
||||
}
|
||||
|
||||
$orderRef->setOrderReference($orderReference);
|
||||
|
||||
$entityManager->persist($orderRef);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->ajaxRender(json_encode([
|
||||
'success' => true,
|
||||
'message' => $this->module->l('Order reference received!', 'ajax')
|
||||
]));
|
||||
} catch (Exception $e) {
|
||||
$this->ajaxRender(json_encode([
|
||||
'success' => false,
|
||||
'message' => $this->module->l('Could not save order reference.', 'ajax')
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
||||
35
index.php
Normal file
35
index.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/AFL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
|
||||
*/
|
||||
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
|
||||
header("Location: ../");
|
||||
exit;
|
||||
82
src/Database/ReferenceInstaller.php
Normal file
82
src/Database/ReferenceInstaller.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* 2026 De Websmid
|
||||
*
|
||||
* @author De Websmid <contact@De Websmid.com>
|
||||
* @copyright 2026 De Websmid
|
||||
* @license De Websmid
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Academic Free License 3.0 (AFL-3.0).
|
||||
* It is also available through the world-wide-web at this URL: https://opensource.org/licenses/AFL-3.0
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Module\WsOrderreference\Database;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Exception as DBALException;
|
||||
|
||||
class ReferenceInstaller
|
||||
{
|
||||
private Connection $connection;
|
||||
private string $dbPrefix;
|
||||
|
||||
public function __construct(Connection $connection, string $dbPrefix)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->dbPrefix = $dbPrefix;
|
||||
}
|
||||
|
||||
public function createTables(): array
|
||||
{
|
||||
$errors = [];
|
||||
$this->dropTables();
|
||||
$sqlInstallFile = dirname(__DIR__) . '/Resources/data/install.sql';
|
||||
|
||||
$sqlContent = file_get_contents($sqlInstallFile);
|
||||
$sqlContent = str_replace('PREFIX_', $this->dbPrefix, $sqlContent);
|
||||
|
||||
$sqlQueries = array_filter(array_map('trim', explode(';', $sqlContent)));
|
||||
|
||||
foreach ($sqlQueries as $query) {
|
||||
if (empty($query)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->connection->executeQuery($query);
|
||||
} catch (DBALException $e) {
|
||||
$errors[] = [
|
||||
'key' => $e->getMessage(),
|
||||
'parameters' => [],
|
||||
'domain' => 'Admin.Modules.Notification',
|
||||
];
|
||||
}
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public function dropTables(): array
|
||||
{
|
||||
$errors = [];
|
||||
$tableNames = [
|
||||
'ws_orderreference',
|
||||
];
|
||||
foreach ($tableNames as $tableName) {
|
||||
$sql = 'DROP TABLE IF EXISTS ' . $this->dbPrefix . $tableName;
|
||||
try {
|
||||
$this->connection->executeQuery($sql);
|
||||
} catch (DBALException $e) {
|
||||
$errors[] = [
|
||||
'key' => $e->getMessage(),
|
||||
'parameters' => [],
|
||||
'domain' => 'Admin.Modules.Notification',
|
||||
];
|
||||
}
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
91
src/Entity/OrderReference.php
Normal file
91
src/Entity/OrderReference.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 2026 De Websmid
|
||||
*
|
||||
* @author De Websmid <contact@De Websmid.com>
|
||||
* @copyright 2026 De Websmid
|
||||
* @license Academic Free License 3.0 (AFL-3.0)
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Module\WsOrderreference\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Table()
|
||||
* @ORM\Entity(repositoryClass="Module\WsOrderreference\Repository\OrderReferenceRepository")
|
||||
*/
|
||||
class OrderReference
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Id
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="id_cart", type="integer", unique=true)
|
||||
*/
|
||||
private $idCart;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="order_reference", type="string", length=255)
|
||||
*/
|
||||
private $orderReference;
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function getIdCart(): ?int
|
||||
{
|
||||
return $this->idCart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $idCart
|
||||
* @return $this
|
||||
*/
|
||||
public function setIdCart(int $idCart): self
|
||||
{
|
||||
$this->idCart = $idCart;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOrderReference(): string
|
||||
{
|
||||
return $this->orderReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $orderReference
|
||||
* @return $this
|
||||
*/
|
||||
public function setOrderReference(string $orderReference): self
|
||||
{
|
||||
$this->orderReference = $orderReference;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
45
src/Module/Install.php
Normal file
45
src/Module/Install.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Module\WsOrderreference\Module;
|
||||
|
||||
use Module\WsOrderreference\Database\ReferenceInstaller;
|
||||
|
||||
trait Install
|
||||
{
|
||||
public function install()
|
||||
{
|
||||
return $this->installTables()
|
||||
&& parent::install()
|
||||
&& $this->registerHook('displayShoppingCart')
|
||||
&& $this->registerHook('displayPDFDeliverySlip')
|
||||
&& $this->registerHook('actionFrontControllerSetMedia');
|
||||
}
|
||||
|
||||
private function getInstaller(): ReferenceInstaller
|
||||
{
|
||||
try {
|
||||
$installer = $this->get(ReferenceInstaller::class);
|
||||
} catch (\Throwable $e) {
|
||||
$installer = null;
|
||||
}
|
||||
|
||||
if (!$installer) {
|
||||
$installer = new ReferenceInstaller(
|
||||
$this->get('doctrine.dbal.default_connection'),
|
||||
$this->getContainer()->getParameter('database_prefix')
|
||||
);
|
||||
}
|
||||
|
||||
return $installer;
|
||||
}
|
||||
|
||||
private function installTables(): bool
|
||||
{
|
||||
/** @var ReferenceInstaller $installer */
|
||||
$installer = $this->getInstaller();
|
||||
$errors = $installer->createTables();
|
||||
|
||||
return empty($errors);
|
||||
}
|
||||
|
||||
}
|
||||
25
src/Module/actionHooks.php
Normal file
25
src/Module/actionHooks.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Module\WsOrderreference\Module;
|
||||
|
||||
trait actionHooks
|
||||
{
|
||||
public function hookActionFrontControllerSetMedia($params)
|
||||
{
|
||||
\Media::addJsDef([
|
||||
'ajax_url' => $this->context->link->getModuleLink($this->name, 'ajax'),
|
||||
]);
|
||||
|
||||
$this->context->controller->registerJavascript(
|
||||
'index.js',
|
||||
'modules/'.$this->name.'/views/js/index.js',
|
||||
['position' => 'bottom', 'priority' => 150]
|
||||
);
|
||||
|
||||
$this->context->controller->registerStylesheet(
|
||||
'styles.css',
|
||||
'modules/'.$this->name.'/views/css/styles.css',
|
||||
['media' => 'all', 'priority' => 150]
|
||||
);
|
||||
}
|
||||
}
|
||||
23
src/Module/displayHooks.php
Normal file
23
src/Module/displayHooks.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Module\WsOrderreference\Module;
|
||||
|
||||
trait displayHooks
|
||||
{
|
||||
public function hookDisplayShoppingCart($params)
|
||||
{
|
||||
return $this->fetch('module:ws_orderreference/views/templates/front/orderreference.tpl');
|
||||
}
|
||||
|
||||
public function hookDisplayPDFDeliverySlip($params)
|
||||
{
|
||||
$orderId = $params['object']->id_order;
|
||||
|
||||
$orderReferenceRepo = \PrestaShop\PrestaShop\Adapter\SymfonyContainer::getInstance()->get('Module\WsOrderreference\Repository\OrderReferenceRepository');
|
||||
$orderReference = $orderReferenceRepo->customRefByOrderId($orderId);
|
||||
|
||||
$this->context->smarty->assign('orderReference', $orderReference);
|
||||
|
||||
return $this->fetch('module:ws_orderreference/views/templates/pdf/delivery-slip.tpl');
|
||||
}
|
||||
}
|
||||
53
src/Repository/OrderReferenceRepository.php
Normal file
53
src/Repository/OrderReferenceRepository.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* 2026 De Websmid
|
||||
*
|
||||
* @author De Websmid <contact@De Websmid.com>
|
||||
* @copyright 2026 De Websmid
|
||||
* @license Academic Free License 3.0 (AFL-3.0)
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Module\WsOrderreference\Repository;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Module\WsOrderreference\Entity\OrderReference;
|
||||
|
||||
class OrderReferenceRepository extends EntityRepository
|
||||
{
|
||||
/**
|
||||
* Find order reference by cart ID
|
||||
*
|
||||
* @param int $cartId
|
||||
* @return OrderReference|null
|
||||
*/
|
||||
public function findByCartId(int $cartId): ?OrderReference
|
||||
{
|
||||
return $this->findOneBy(['idCart' => $cartId]);
|
||||
}
|
||||
|
||||
// Create a function that accepts an order Id and uses the cart ID to check if there is a custom order reference.
|
||||
// Requires an order ID as a parameter.
|
||||
// Returns the order reference if found, otherwise returns null.
|
||||
// Used in the display hook to show the order reference on the pdf.
|
||||
|
||||
// Steps to build and break the problem down:
|
||||
// 1.) Just return the cart ID from the order ID to see if that works.
|
||||
// 2.) Use the cart ID to find the order reference.
|
||||
|
||||
public function customRefByOrderId(int $orderId): ?string
|
||||
{
|
||||
$conn = $this->getEntityManager()->getConnection();
|
||||
$sql = 'SELECT id_cart FROM ps_orders WHERE id_order = :orderId';
|
||||
$stmt = $conn->prepare($sql);
|
||||
$resultSet = $stmt->executeQuery(['orderId' => $orderId]);
|
||||
$idCart = $resultSet->fetchOne();
|
||||
if ($idCart) {
|
||||
$orderReference = $this->findByCartId((int)$idCart);
|
||||
return $orderReference ? $orderReference->getOrderReference() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
7
src/Resources/data/install.sql
Normal file
7
src/Resources/data/install.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS `PREFIX_order_reference` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`id_cart` int(11) NOT NULL,
|
||||
`order_reference` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `id_cart` (`id_cart`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
14
translations/nl.php
Normal file
14
translations/nl.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
global $_MODULE;
|
||||
$_MODULE = array();
|
||||
$_MODULE['<{ws_orderreference}prestashop>ws_orderreference_1e860e56970a81a1ba3e1fcb7fccc846'] = 'Orderreferentie';
|
||||
$_MODULE['<{ws_orderreference}prestashop>ws_orderreference_9f0d684399938af879ce3fb38710642c'] = 'Voegt een optioneel orderreferentieveld toe aan het winkelwagenoverzicht.';
|
||||
$_MODULE['<{ws_orderreference}prestashop>ajax_ec19148e5460115c7abda82799f02269'] = 'Geen winkelwagen gevonden.';
|
||||
$_MODULE['<{ws_orderreference}prestashop>ajax_ffc8410c88b32eb4547230088b9df62a'] = 'Voer een geldige orderreferentie in. Toegestane tekens: a-z, 0-9, -, _ en spatie';
|
||||
$_MODULE['<{ws_orderreference}prestashop>ajax_588d7a076adcf5a584c049d954496ae6'] = 'Orderreferentie ontvangen!';
|
||||
$_MODULE['<{ws_orderreference}prestashop>ajax_4602466a12672337138c0925bd5f737f'] = 'Kon orderreferentie niet opslaan.';
|
||||
$_MODULE['<{ws_orderreference}prestashop>orderreference_9f5ba9ae96aa82530d03f434f4da0670'] = 'Orderreferentie (optioneel)';
|
||||
$_MODULE['<{ws_orderreference}prestashop>orderreference_a4d3b161ce1309df1c4e25df28694b7b'] = 'Opslaan';
|
||||
$_MODULE['<{ws_orderreference}prestashop>orderreference_fe8cc190e37aa5083375088bd5873c29'] = 'Uw bestelreferentie:';
|
||||
$_MODULE['<{ws_orderreference}prestashop>delivery-slip_f8c9e6a6b5ac4fd353d569c78cbabd90'] = 'Uw aangepaste bestelreferentie:';
|
||||
13
views/css/styles.css
Normal file
13
views/css/styles.css
Normal file
@@ -0,0 +1,13 @@
|
||||
/* Fade out for alert */
|
||||
.fade-out {
|
||||
animation: fadeOut 0.75s forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeOut {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
105
views/js/index.js
Normal file
105
views/js/index.js
Normal file
@@ -0,0 +1,105 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// Load saved reference on page load (with retry for dynamic content)
|
||||
loadSavedReferenceWithRetry();
|
||||
|
||||
// Ajax submission
|
||||
document.addEventListener("submit", function (e) {
|
||||
if (e.target && e.target.id === "order_reference_form") {
|
||||
e.preventDefault();
|
||||
const form = e.target;
|
||||
const url = typeof ajax_url !== "undefined" ? ajax_url : null;
|
||||
const input = document.querySelector("#order_reference_input");
|
||||
const inputValue = input.value.trim();
|
||||
|
||||
fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body:
|
||||
"ajax=1&order_reference_input=" +
|
||||
encodeURIComponent(inputValue),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
// Save to localStorage
|
||||
localStorage.setItem("order_reference", inputValue);
|
||||
displaySavedReference(inputValue);
|
||||
input.value = "";
|
||||
}
|
||||
alertFadeOut(form, data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
alertFadeOut(form, {
|
||||
success: false,
|
||||
message: "An error occurred",
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Load saved reference with retry mechanism for dynamic content
|
||||
function loadSavedReferenceWithRetry(attempts = 0, maxAttempts = 10) {
|
||||
const savedReference = localStorage.getItem("order_reference");
|
||||
if (savedReference) {
|
||||
const success = displaySavedReference(savedReference);
|
||||
|
||||
if (!success && attempts < maxAttempts) {
|
||||
setTimeout(() => {
|
||||
loadSavedReferenceWithRetry(attempts + 1, maxAttempts);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function displaySavedReference(value) {
|
||||
const form = document.querySelector("#order_reference_form");
|
||||
if (!form) return false;
|
||||
|
||||
const lastSubmittedContainer = form.querySelector(
|
||||
".last-submitted-container",
|
||||
);
|
||||
if (lastSubmittedContainer) {
|
||||
const lastSubmittedSpan =
|
||||
lastSubmittedContainer.querySelector(".last-submitted");
|
||||
if (lastSubmittedSpan) {
|
||||
lastSubmittedSpan.textContent = value;
|
||||
lastSubmittedContainer.classList.remove("d-none");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset alert to initial state
|
||||
function resetAlert(alert, messageEl) {
|
||||
alert.classList.add("d-none");
|
||||
alert.classList.remove("alert-success", "alert-danger", "fade-out");
|
||||
messageEl.textContent = "";
|
||||
}
|
||||
|
||||
// Fade out alert and reset
|
||||
function alertFadeOut(form, data) {
|
||||
const alert = form.querySelector(".alert");
|
||||
if (!alert) return;
|
||||
|
||||
const messageEl = alert.querySelector(".alert-message");
|
||||
if (!messageEl) return;
|
||||
|
||||
// Show alert with appropriate class and message
|
||||
alert.classList.remove("d-none");
|
||||
alert.classList.add(data.success ? "alert-success" : "alert-danger");
|
||||
messageEl.textContent = data.message;
|
||||
|
||||
// Fade out after delay
|
||||
setTimeout(() => {
|
||||
alert.classList.add("fade-out");
|
||||
setTimeout(() => {
|
||||
resetAlert(alert, messageEl);
|
||||
}, 750); // 750ms for fade-out animation - make sure it matches in styles.css
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
21
views/templates/front/orderreference.tpl
Normal file
21
views/templates/front/orderreference.tpl
Normal file
@@ -0,0 +1,21 @@
|
||||
<div class="col-lg-12 col-md-12 box card p-0" id="ref_order" style="border: 0px;">
|
||||
<form action="#" class="p-0" method="post" id="order_reference_form">
|
||||
<fieldset>
|
||||
<p class="h4">{l s='Order reference (optional)' mod='ws_orderreference'}</p>
|
||||
<div class="d-flex flex-nowrap mb-2" style="gap: 10px;">
|
||||
<div class="form-group w-100 mb-0">
|
||||
<label for="order_reference_input" class="sr-only">{l s='Order reference (optional)' mod='ws_orderreference'}</label>
|
||||
<input type="text" class="form-control w-100 mb-0" id="order_reference_input" name="order_reference_input" value="{$order_reference_value|escape:'html':'UTF-8'}" required="required">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" id="order_reference_submit">{l s='Submit' mod='ws_orderreference'}</button>
|
||||
</div>
|
||||
<div class="d-none last-submitted-container mb-2">
|
||||
<span class="text-danger">{l s='Your order reference:' mod='ws_orderreference'}</span>
|
||||
<span class="last-submitted text-danger"></span>
|
||||
</div>
|
||||
<div id="order_ref_message" class="alert d-none">
|
||||
<p class="alert-message mb-0"></p>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
1
views/templates/pdf/delivery-slip.tpl
Normal file
1
views/templates/pdf/delivery-slip.tpl
Normal file
@@ -0,0 +1 @@
|
||||
<h3>{l s='Your custom order reference:' mod='ws_orderreference'} {$orderReference}</h3>
|
||||
44
ws_orderreference.php
Normal file
44
ws_orderreference.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use Module\WsOrderreference\Module\Install;
|
||||
use Module\WsOrderreference\Module\displayHooks;
|
||||
use Module\WsOrderreference\Module\actionHooks;
|
||||
|
||||
|
||||
if (file_exists(__DIR__ . '/vendor/autoload.php')) {
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
}
|
||||
|
||||
class Ws_OrderReference extends Module
|
||||
{
|
||||
/** @var OrderReferenceRepository */
|
||||
protected $orderReferenceRepository;
|
||||
|
||||
use Install;
|
||||
use displayHooks;
|
||||
use actionHooks;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->name = 'ws_orderreference';
|
||||
$this->tab = 'other';
|
||||
$this->version = '1.0.0';
|
||||
$this->author = 'Isabelle Oving-Anno | De Websmid b.v.';
|
||||
$this->need_instance = 0;
|
||||
$this->ps_versions_compliancy = [
|
||||
'min' => '9.0.0',
|
||||
'max' => '9.99.99',
|
||||
];
|
||||
$this -> bootstrap = true;
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->displayName = $this->l('Order Reference');
|
||||
$this->description = $this->l('Adds an optional order reference field to the shopping cart summary.');
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user