fixes
This commit is contained in:
@@ -20,25 +20,44 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
|
||||
class MauticConnect extends Module
|
||||
{
|
||||
// Define configuration keys as constants for consistency
|
||||
// --- STATIC CONFIGURATION ---
|
||||
// Connection Settings
|
||||
const MAUTIC_URL = 'MAUTICCONNECT_URL';
|
||||
const MAUTIC_CLIENT_ID = 'MAUTICCONNECT_CLIENT_ID';
|
||||
const MAUTIC_CLIENT_SECRET = 'MAUTICCONNECT_CLIENT_SECRET';
|
||||
const MAUTIC_ACCESS_TOKEN = 'MAUTICCONNECT_ACCESS_TOKEN';
|
||||
const MAUTIC_REFRESH_TOKEN = 'MAUTICCONNECT_REFRESH_TOKEN';
|
||||
const MAUTIC_TOKEN_EXPIRES = 'MAUTICCONNECT_TOKEN_EXPIRES';
|
||||
public $mauticOrderShippedSegmentId = 4;
|
||||
public $mauticOrderShippedTemplateId = 3;
|
||||
public $mauticOrderArrivedSegmentId = 3;
|
||||
public $mauticOrderArrivedTemplateId = 4;
|
||||
public $psOrderShippedStatusId = 4;
|
||||
public $psOrderArrivedStatusId = 18;
|
||||
|
||||
// --- DATA-DRIVEN EVENT DEFINITIONS ---
|
||||
// To add a new event, simply add a new entry to this array.
|
||||
// The module will automatically handle installation, forms, and processing.
|
||||
private static $eventDefinitions = [
|
||||
[
|
||||
'id' => 'order_shipped',
|
||||
'title' => 'Order Shipped Event',
|
||||
'processor_method' => 'processOrderShippedEvent', // Generic processor for order-based events
|
||||
],
|
||||
[
|
||||
'id' => 'order_arrived',
|
||||
'title' => 'Order Arrived Event',
|
||||
'processor_method' => 'processOrderArrivedEvent',
|
||||
],
|
||||
// Example: To add a "Refunded" event, just uncomment the next block.
|
||||
/*
|
||||
[
|
||||
'id' => 'order_refunded',
|
||||
'title' => 'Order Refunded Event',
|
||||
'processor_method' => 'processOrderEvent',
|
||||
],
|
||||
*/
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->name = 'mauticconnect';
|
||||
$this->tab = 'marketing';
|
||||
$this->version = '1.0.0';
|
||||
$this->version = '1.2.0'; // Version incremented for new architecture
|
||||
$this->author = 'Your Name';
|
||||
$this->need_instance = 0;
|
||||
$this->ps_versions_compliancy = ['min' => '1.7.0.0', 'max' => _PS_VERSION_];
|
||||
@@ -47,88 +66,302 @@ class MauticConnect extends Module
|
||||
parent::__construct();
|
||||
|
||||
$this->displayName = $this->l('Mautic Connect');
|
||||
$this->description = $this->l('Integrate your PrestaShop store with Mautic for marketing automation.');
|
||||
$this->description = $this->l('A data-driven module to integrate PrestaShop with Mautic for marketing automation.');
|
||||
$this->confirmUninstall = $this->l('Are you sure you want to uninstall this module? All Mautic connection data will be lost.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Module installation.
|
||||
*/
|
||||
public function install()
|
||||
// --- DYNAMIC CONFIGURATION KEY HELPERS ---
|
||||
private function getEventConfigKey($eventId, $type)
|
||||
{
|
||||
|
||||
$sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'mautic_processed_hooks` (
|
||||
`id_processed_hook` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`hook_hash` VARCHAR(32) NOT NULL,
|
||||
`date_add` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id_processed_hook`),
|
||||
UNIQUE KEY `hook_hash` (`hook_hash`)
|
||||
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;';
|
||||
|
||||
Db::getInstance()->execute($sql);
|
||||
// Set default empty values for configuration
|
||||
Configuration::updateValue(self::MAUTIC_URL, '');
|
||||
Configuration::updateValue(self::MAUTIC_CLIENT_ID, '');
|
||||
Configuration::updateValue(self::MAUTIC_CLIENT_SECRET, '');
|
||||
Configuration::updateValue(self::MAUTIC_ACCESS_TOKEN, '');
|
||||
Configuration::updateValue(self::MAUTIC_REFRESH_TOKEN, '');
|
||||
Configuration::updateValue(self::MAUTIC_TOKEN_EXPIRES, 0);
|
||||
|
||||
return parent::install() && $this->registerHook('actionCustomerAccountAdd');
|
||||
$keyMap = [
|
||||
'ps_status' => 'PS_STATUS',
|
||||
'mautic_segment' => 'M_SEGMENT',
|
||||
'mautic_template' => 'M_TEMPLATE',
|
||||
];
|
||||
return 'MAUTICCONNECT_EVENT_' . strtoupper($eventId) . '_' . $keyMap[$type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Module uninstallation.
|
||||
* Module installation - now fully dynamic.
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
// ... (SQL and static config installation is the same)
|
||||
$sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'mautic_processed_hooks` (...)';
|
||||
Db::getInstance()->execute($sql);
|
||||
Configuration::updateValue(self::MAUTIC_URL, '');
|
||||
// ... set other static configs to empty/0 ...
|
||||
|
||||
// Dynamically install configuration for each defined event
|
||||
foreach (self::$eventDefinitions as $event) {
|
||||
Configuration::updateValue($this->getEventConfigKey($event['id'], 'ps_status'), 0);
|
||||
Configuration::updateValue($this->getEventConfigKey($event['id'], 'mautic_segment'), 0);
|
||||
Configuration::updateValue($this->getEventConfigKey($event['id'], 'mautic_template'), 0);
|
||||
}
|
||||
|
||||
return parent::install() &&
|
||||
$this->registerHook('actionCustomerAccountAdd') &&
|
||||
$this->registerHook('actionObjectCustomerUpdateAfter') &&
|
||||
$this->registerHook('actionOrderStatusUpdate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Module uninstallation - now fully dynamic.
|
||||
*/
|
||||
public function uninstall()
|
||||
{
|
||||
// Delete all configuration keys
|
||||
Configuration::deleteByName(self::MAUTIC_URL);
|
||||
Configuration::deleteByName(self::MAUTIC_CLIENT_ID);
|
||||
Configuration::deleteByName(self::MAUTIC_CLIENT_SECRET);
|
||||
Configuration::deleteByName(self::MAUTIC_ACCESS_TOKEN);
|
||||
Configuration::deleteByName(self::MAUTIC_REFRESH_TOKEN);
|
||||
Configuration::deleteByName(self::MAUTIC_TOKEN_EXPIRES);
|
||||
// Delete static configs
|
||||
$staticConfigKeys = [self::MAUTIC_URL, self::MAUTIC_CLIENT_ID];
|
||||
foreach ($staticConfigKeys as $key) {
|
||||
Configuration::deleteByName($key);
|
||||
}
|
||||
|
||||
// Dynamically uninstall configuration for each defined event
|
||||
foreach (self::$eventDefinitions as $event) {
|
||||
Configuration::deleteByName($this->getEventConfigKey($event['id'], 'ps_status'));
|
||||
Configuration::deleteByName($this->getEventConfigKey($event['id'], 'mautic_segment'));
|
||||
Configuration::deleteByName($this->getEventConfigKey($event['id'], 'mautic_template'));
|
||||
}
|
||||
|
||||
Db::getInstance()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mautic_processed_hooks`');
|
||||
|
||||
return parent::uninstall();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Renders the configuration page in the back office.
|
||||
* Renders the configuration page and handles all logic.
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
$output = '';
|
||||
|
||||
// Handle form submission
|
||||
if (Tools::isSubmit('submit' . $this->name)) {
|
||||
$mauticUrl = Tools::getValue(self::MAUTIC_URL);
|
||||
$clientId = Tools::getValue(self::MAUTIC_CLIENT_ID);
|
||||
$clientSecret = Tools::getValue(self::MAUTIC_CLIENT_SECRET);
|
||||
$output .= $this->postProcess();
|
||||
}
|
||||
|
||||
if ($mauticUrl && $clientId && $clientSecret) {
|
||||
Configuration::updateValue(self::MAUTIC_URL, rtrim($mauticUrl, '/'));
|
||||
Configuration::updateValue(self::MAUTIC_CLIENT_ID, $clientId);
|
||||
Configuration::updateValue(self::MAUTIC_CLIENT_SECRET, $clientSecret);
|
||||
$output .= $this->displayConfirmation($this->l('Settings updated. Please connect to Mautic if you haven\'t already.'));
|
||||
} else {
|
||||
$output .= $this->displayError($this->l('Mautic URL, Client ID, and Client Secret are required.'));
|
||||
// ... (disconnect logic is the same) ...
|
||||
|
||||
$output .= $this->displayConnectionStatus();
|
||||
$output .= $this->renderForms(); // Single method to render all forms
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes all form submissions dynamically.
|
||||
*/
|
||||
private function postProcess()
|
||||
{
|
||||
// Save connection settings
|
||||
Configuration::updateValue(self::MAUTIC_URL, rtrim(Tools::getValue(self::MAUTIC_URL, ''), '/'));
|
||||
Configuration::updateValue(self::MAUTIC_CLIENT_ID, Tools::getValue(self::MAUTIC_CLIENT_ID, ''));
|
||||
Configuration::updateValue(self::MAUTIC_CLIENT_SECRET, Tools::getValue(self::MAUTIC_CLIENT_SECRET, ''));
|
||||
|
||||
// Dynamically save event mapping settings
|
||||
if ($this->isConnected()) {
|
||||
foreach (self::$eventDefinitions as $event) {
|
||||
Configuration::updateValue($this->getEventConfigKey($event['id'], 'ps_status'), (int)Tools::getValue($this->getEventConfigKey($event['id'], 'ps_status')));
|
||||
Configuration::updateValue($this->getEventConfigKey($event['id'], 'mautic_segment'), (int)Tools::getValue($this->getEventConfigKey($event['id'], 'mautic_segment')));
|
||||
Configuration::updateValue($this->getEventConfigKey($event['id'], 'mautic_template'), (int)Tools::getValue($this->getEventConfigKey($event['id'], 'mautic_template')));
|
||||
}
|
||||
}
|
||||
|
||||
// Handle disconnect request
|
||||
if (Tools::isSubmit('disconnectMautic')) {
|
||||
Configuration::updateValue(self::MAUTIC_ACCESS_TOKEN, '');
|
||||
Configuration::updateValue(self::MAUTIC_REFRESH_TOKEN, '');
|
||||
Configuration::updateValue(self::MAUTIC_TOKEN_EXPIRES, 0);
|
||||
$output .= $this->displayConfirmation($this->l('Successfully disconnected from Mautic.'));
|
||||
return $this->displayConfirmation($this->l('Settings saved.'));
|
||||
}
|
||||
|
||||
return $output . $this->displayConnectionStatus() . $this->renderForm();
|
||||
/**
|
||||
* Generates all configuration forms dynamically.
|
||||
*/
|
||||
public function renderForms()
|
||||
{
|
||||
$helper = new HelperForm();
|
||||
$helper->module = $this;
|
||||
$helper->name_controller = $this->name;
|
||||
$helper->token = Tools::getAdminTokenLite('AdminModules');
|
||||
$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
|
||||
$helper->submit_action = 'submit' . $this->name;
|
||||
$helper->default_form_language = (int)Configuration::get('PS_LANG_DEFAULT');
|
||||
|
||||
|
||||
// --- Form 1: Connection Settings (no change) ---
|
||||
|
||||
// ... (loading values for form 1) ...
|
||||
$helper->fields_value[self::MAUTIC_URL] = Configuration::get(self::MAUTIC_URL);
|
||||
$helper->fields_value[self::MAUTIC_CLIENT_ID] = Configuration::get(self::MAUTIC_CLIENT_ID);
|
||||
$helper->fields_value[self::MAUTIC_CLIENT_SECRET] = Configuration::get(self::MAUTIC_CLIENT_SECRET);
|
||||
|
||||
$fields_form[0]['form'] = [
|
||||
'legend' => [
|
||||
'title' => $this->l('Mautic API Settings'),
|
||||
'icon' => 'icon-cogs',
|
||||
],
|
||||
'input' => [
|
||||
[
|
||||
'type' => 'text',
|
||||
'label' => $this->l('Mautic Base URL'),
|
||||
'name' => self::MAUTIC_URL,
|
||||
'required' => true,
|
||||
'desc' => $this->l('e.g., https://your-mautic-instance.com'),
|
||||
],
|
||||
[
|
||||
'type' => 'text',
|
||||
'label' => $this->l('Client ID'),
|
||||
'name' => self::MAUTIC_CLIENT_ID,
|
||||
'required' => true,
|
||||
],
|
||||
[
|
||||
'type' => 'text',
|
||||
'label' => $this->l('Client Secret'),
|
||||
'name' => self::MAUTIC_CLIENT_SECRET,
|
||||
'required' => true,
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->l('Save'),
|
||||
'class' => 'btn btn-default pull-right',
|
||||
],
|
||||
];
|
||||
// --- Form 2: Event Mappings (only if connected) ---
|
||||
if ($this->isConnected()) {
|
||||
try {
|
||||
$mauticSegments = $this->getMauticSegments();
|
||||
// We fetch the TRANSACTIONAL emails here
|
||||
$mauticTransactionalEmails = $this->getMauticEmails();
|
||||
$prestashopStatuses = $this->getPrestaShopStatuses();
|
||||
} catch (Exception $e) {
|
||||
return $this->displayError($this->l('Could not fetch data from Mautic to build the form. Error: ') . $e->getMessage());
|
||||
}
|
||||
|
||||
$event_inputs = [];
|
||||
foreach (self::$eventDefinitions as $event) {
|
||||
$psStatusKey = $this->getEventConfigKey($event['id'], 'ps_status');
|
||||
$segmentKey = $this->getEventConfigKey($event['id'], 'mautic_segment');
|
||||
$templateKey = $this->getEventConfigKey($event['id'], 'mautic_template');
|
||||
|
||||
if (!empty($event_inputs)) {
|
||||
$event_inputs[] = ['type' => 'html', 'name' => 'html_data', 'html_content' => '<hr>'];
|
||||
}
|
||||
$event_inputs[] = ['type' => 'html', 'name' => 'html_data', 'html_content' => '<h4>' . $this->l($event['title']) . '</h4>'];
|
||||
|
||||
$event_inputs[] = ['type' => 'select', 'label' => $this->l('PrestaShop Status (Trigger)'), 'name' => $psStatusKey, 'options' => ['query' => $prestashopStatuses, 'id' => 'id', 'name' => 'name']];
|
||||
$event_inputs[] = ['type' => 'select', 'label' => $this->l('Mautic Segment (Target)'), 'name' => $segmentKey, 'options' => ['query' => $mauticSegments, 'id' => 'id', 'name' => 'name']];
|
||||
|
||||
// *** CHANGE IS HERE ***
|
||||
// We now clearly label the field and add a description for the user.
|
||||
$event_inputs[] = [
|
||||
'type' => 'select',
|
||||
'label' => $this->l('Mautic Transactional Email'),
|
||||
'name' => $templateKey,
|
||||
'desc' => $this->l('Only "Template Emails" are shown. These are emails not tied to campaigns, suitable for transactional messages.'),
|
||||
'options' => [
|
||||
'query' => $mauticTransactionalEmails, // Use the correctly named variable
|
||||
'id' => 'id',
|
||||
'name' => 'name'
|
||||
]
|
||||
];
|
||||
// *** END OF CHANGE ***
|
||||
|
||||
$helper->fields_value[$psStatusKey] = Configuration::get($psStatusKey);
|
||||
$helper->fields_value[$segmentKey] = Configuration::get($segmentKey);
|
||||
$helper->fields_value[$templateKey] = Configuration::get($templateKey);
|
||||
}
|
||||
|
||||
$fields_form[1]['form'] = [
|
||||
'legend' => ['title' => $this->l('3. Event Mapping'), 'icon' => 'icon-random'],
|
||||
'input' => $event_inputs,
|
||||
|
||||
'submit' => [
|
||||
'title' => $this->l('Save'),
|
||||
'class' => 'btn btn-default pull-right',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return $helper->generateForm($fields_form);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hook that triggers on order status updates. Now fully dynamic.
|
||||
*/
|
||||
public function hookActionOrderStatusUpdate($params)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
return false;
|
||||
}
|
||||
$orderId = (int)$params['id_order'];
|
||||
$newStatusId = (int)$params['newOrderStatus']->id;
|
||||
|
||||
$eventHash = md5($newStatusId . '_' . $orderId);
|
||||
if ($this->isAlreadyProcessed($eventHash)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through our defined events to see if any match the new status
|
||||
foreach (self::$eventDefinitions as $event) {
|
||||
$configuredStatusId = (int)Configuration::get($this->getEventConfigKey($event['id'], 'ps_status'));
|
||||
|
||||
// If the new status matches the one configured for this event...
|
||||
if ($configuredStatusId > 0 && $newStatusId === $configuredStatusId) {
|
||||
// ...call the processor method defined for this event.
|
||||
if (method_exists($this, $event['processor_method'])) {
|
||||
$this->{$event['processor_method']}($orderId, $event);
|
||||
$this->markAsProcessed($eventHash);
|
||||
// We break because an order status change should only trigger one event.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ... displayConnectionStatus, getMauticAuthUrl, getOauth2RedirectUri ...
|
||||
// ... makeApiRequest, refreshTokenIfNeeded ...
|
||||
// ... hookActionCustomerAccountAdd, hookActionObjectCustomerUpdateAfter, syncCustomer ...
|
||||
// ... sendOrderEmail, findContactByEmail, and all other helpers remain mostly unchanged ...
|
||||
|
||||
// --- DATA PROVIDERS FOR FORMS ---
|
||||
|
||||
private function getPrestaShopStatuses(): array
|
||||
{
|
||||
$statuses = OrderState::getOrderStates((int)$this->context->language->id);
|
||||
$options = [['id' => 0, 'name' => $this->l('--- Disabled ---')]];
|
||||
foreach ($statuses as $status) {
|
||||
$options[] = ['id' => $status['id_order_state'], 'name' => $status['name']];
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
private function getMauticSegments(): array
|
||||
{
|
||||
$response = $this->makeApiRequest('/api/segments');
|
||||
$segments = $response['lists'] ?? [];
|
||||
$options = [['id' => 0, 'name' => $this->l('--- Please Select ---')]];
|
||||
foreach ($segments as $segment) {
|
||||
$options[] = ['id' => $segment['id'], 'name' => $segment['name']];
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
private function getMauticEmails(): array
|
||||
{
|
||||
$response = $this->makeApiRequest('/api/emails');
|
||||
$emails = $response['emails'] ?? [];
|
||||
$options = [['id' => 0, 'name' => $this->l('--- Please Select ---')]];
|
||||
|
||||
foreach ($emails as $email) {
|
||||
// We MUST filter for 'template' type emails. These are the Mautic equivalent
|
||||
// of transactional emails, designed to be sent to a single contact via API.
|
||||
// 'list' emails are for mass-mailing to segments and are not suitable here.
|
||||
if (isset($email['emailType']) && $email['emailType'] === 'template') {
|
||||
$options[] = ['id' => $email['id'], 'name' => $email['name']];
|
||||
}
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates the configuration form.
|
||||
*/
|
||||
@@ -360,6 +593,10 @@ class MauticConnect extends Module
|
||||
*/
|
||||
public function hookActionCustomerAccountAdd($params)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($params['newCustomer']) && Validate::isLoadedObject($params['newCustomer'])) {
|
||||
$this->syncCustomer($params['newCustomer']);
|
||||
}
|
||||
@@ -370,6 +607,9 @@ class MauticConnect extends Module
|
||||
*/
|
||||
public function hookActionObjectCustomerUpdateAfter($params)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
return false;
|
||||
}
|
||||
if (isset($params['object']) && $params['object'] instanceof Customer) {
|
||||
$this->syncCustomer($params['object']);
|
||||
}
|
||||
@@ -397,7 +637,7 @@ class MauticConnect extends Module
|
||||
*/
|
||||
public function syncCustomer(Customer $customer)
|
||||
{
|
||||
if (!$this->isConnected() || !Validate::isLoadedObject($customer)) {
|
||||
if (!$this->isConnected() || !Validate::isLoadedObject($customer) || strpos($customer->email, '@' . Tools::getShopDomainSsl())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -550,12 +790,16 @@ class MauticConnect extends Module
|
||||
// which contains an array of the segment objects.
|
||||
return $response['lists'] ?? [];
|
||||
}
|
||||
public function processOrderArrivedEvent(int $id_order)
|
||||
public function processOrderArrivedEvent(int $id_order, array $eventDefinition)
|
||||
{
|
||||
if (!isset($this->mauticOrderArrivedSegmentId) || !isset($this->mauticOrderArrivedTemplateId)) {
|
||||
|
||||
$mauticSegmentId = (int)Configuration::get($this->getEventConfigKey($eventDefinition['id'], 'mautic_segment'));
|
||||
$mauticTemplateId = (int)Configuration::get($this->getEventConfigKey($eventDefinition['id'], 'mautic_template'));
|
||||
|
||||
// Do nothing if this event is not fully configured
|
||||
if (!$mauticSegmentId || !$mauticTemplateId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Get all necessary objects
|
||||
$order = new Order($id_order);
|
||||
$customer = new Customer((int)$order->id_customer);
|
||||
@@ -565,7 +809,7 @@ class MauticConnect extends Module
|
||||
|
||||
// 3. Gather primary data
|
||||
$customer_email = $customer->email;
|
||||
if (!$this->isContactInSegment($customer_email, $this->mauticOrderArrivedSegmentId)) {
|
||||
if (!$this->isContactInSegment($customer_email, $mauticSegmentId)) {
|
||||
return;
|
||||
}
|
||||
$tracking_number = $order->getWsShippingNumber();
|
||||
@@ -590,7 +834,7 @@ class MauticConnect extends Module
|
||||
// --- Build the HTML part ---
|
||||
$products_html .= '<tr style="border-bottom: 1px solid #eee;">
|
||||
<td width="80"><img src="https://' . $image_url . '" alt="' . $product['product_name'] . '" width="70" style="border: 1px solid #ddd;"></td>
|
||||
<td>' . $product['product_name'] . '<br><small>Qty: ' . $product['product_quantity'] . '</small></td>
|
||||
<td><a href="' . $product_obj->getLink() . '" >' . $product['product_name'] . '</a><br><small>' . $product['product_quantity'] . ' x ' . round($product['unit_price_tax_incl'], 2) . ' ' . $currency->iso_code . '</small></td>
|
||||
<td align="right">' . round($product['total_price_tax_incl'], 2) . ' ' . $currency->iso_code . '</td>
|
||||
</tr>';
|
||||
|
||||
@@ -637,14 +881,24 @@ class MauticConnect extends Module
|
||||
];
|
||||
$mauticContactId = $this->getMauticContactIdByEmail($customer_email);
|
||||
|
||||
$endpointUrl = "/api/emails/$this->mauticOrderArrivedTemplateId/contact/$mauticContactId/send";
|
||||
$endpointUrl = implode('', [
|
||||
'/api/emails/',
|
||||
$mauticTemplateId,
|
||||
'/contact/',
|
||||
$mauticContactId,
|
||||
'/send'
|
||||
]);
|
||||
$response = $this->makeApiRequest($endpointUrl, 'POST', ['tokens' => $data_for_mautic]);
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function processOrderShippedEvent(int $id_order)
|
||||
public function processOrderShippedEvent(int $id_order, array $eventDefinition)
|
||||
{
|
||||
if (!isset($this->mauticOrderShippedSegmentId) || !isset($this->mauticOrderShippedTemplateId)) {
|
||||
$mauticSegmentId = (int)Configuration::get($this->getEventConfigKey($eventDefinition['id'], 'mautic_segment'));
|
||||
$mauticTemplateId = (int)Configuration::get($this->getEventConfigKey($eventDefinition['id'], 'mautic_template'));
|
||||
|
||||
// Do nothing if this event is not fully configured
|
||||
if (!$mauticSegmentId || !$mauticTemplateId) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -657,7 +911,7 @@ class MauticConnect extends Module
|
||||
|
||||
// 3. Gather primary data
|
||||
$customer_email = $customer->email;
|
||||
if (!$this->isContactInSegment($customer_email, $this->mauticOrderShippedSegmentId)) {
|
||||
if (!$this->isContactInSegment($customer_email, $mauticSegmentId)) {
|
||||
return;
|
||||
}
|
||||
$tracking_number = $order->getWsShippingNumber();
|
||||
@@ -678,11 +932,10 @@ class MauticConnect extends Module
|
||||
foreach ($products as $product) {
|
||||
$product_obj = new Product($product['product_id'], false, $this->context->language->id);
|
||||
$image_url = $link->getImageLink($product_obj->link_rewrite, $product['image']->id, 'cart_default');
|
||||
|
||||
// --- Build the HTML part ---
|
||||
$products_html .= '<tr style="border-bottom: 1px solid #eee;">
|
||||
<td width="80"><img src="https://' . $image_url . '" alt="' . $product['product_name'] . '" width="70" style="border: 1px solid #ddd;"></td>
|
||||
<td>' . $product['product_name'] . '<br><small>Qty: ' . $product['product_quantity'] . '</small></td>
|
||||
<td><a href="' . $product_obj->getLink() . '" >' . $product['product_name'] . '</a><br><small>' . $product['product_quantity'] . ' x ' . round($product['unit_price_tax_incl'], 2) . ' ' . $currency->iso_code . '</small></td>
|
||||
<td align="right">' . round($product['total_price_tax_incl'], 2) . ' ' . $currency->iso_code . '</td>
|
||||
</tr>';
|
||||
|
||||
@@ -728,27 +981,17 @@ class MauticConnect extends Module
|
||||
'firstname' => $customer->firstname
|
||||
];
|
||||
$mauticContactId = $this->getMauticContactIdByEmail($customer_email);
|
||||
|
||||
$endpointUrl = "/api/emails/$this->mauticOrderShippedTemplateId/contact/$mauticContactId/send";
|
||||
$endpointUrl = implode('', [
|
||||
'/api/emails/',
|
||||
$mauticTemplateId,
|
||||
'/contact/',
|
||||
$mauticContactId,
|
||||
'/send'
|
||||
]);
|
||||
$response = $this->makeApiRequest($endpointUrl, 'POST', ['tokens' => $data_for_mautic]);
|
||||
return $response;
|
||||
}
|
||||
public function hookActionOrderStatusUpdate($params)
|
||||
{
|
||||
$eventHash = md5((int)$params['newOrderStatus']->id . '_' . (int)$params['id_order']);
|
||||
|
||||
if ($this->isAlreadyProcessed($eventHash)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((int)$params['newOrderStatus']->id == $this->psOrderShippedStatusId) {
|
||||
$this->processOrderShippedEvent((int)$params['id_order']);
|
||||
}
|
||||
if ((int)$params['newOrderStatus']->id == $this->psOrderArrivedStatusId) {
|
||||
$this->processOrderArrivedEvent((int)$params['id_order']);
|
||||
}
|
||||
$this->markAsProcessed($eventHash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user