- Enabled SMTP debugging in PHPMailer for better error tracking. - Added a "Test send email" link in the Inventory Detail View for quick email testing. - Implemented automatic PDF generation and email sending upon Sales Order creation. - Created a new action for sending Sales Order emails with attached PDFs. - Added a new AJAX action for testing outgoing email server configurations. - Updated outgoing server settings to use new SMTP credentials. - Improved email templates for better user experience. - Added test scripts for validating PDF generation and email sending.
252 lines
8.5 KiB
PHP
252 lines
8.5 KiB
PHP
<?php
|
|
/*+**********************************************************************************
|
|
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
|
|
* ("License"); You may not use this file except in compliance with the License
|
|
* The Original Code is: vtiger CRM Open Source
|
|
* The Initial Developer of the Original Code is vtiger.
|
|
* Portions created by vtiger are Copyright (C) vtiger.
|
|
* All Rights Reserved.
|
|
************************************************************************************/
|
|
require_once dirname(__FILE__) . '/ModTracker.php';
|
|
require_once 'data/VTEntityDelta.php';
|
|
|
|
class ModTrackerHandler extends VTEventHandler
|
|
{
|
|
|
|
function handleEvent($eventName, $data)
|
|
{
|
|
global $adb, $current_user;
|
|
$moduleName = $data->getModuleName();
|
|
$isTrackingEnabled = ModTracker::isTrackingEnabledForModule($moduleName);
|
|
if (!$isTrackingEnabled) {
|
|
return;
|
|
}
|
|
if ($eventName == 'vtiger.entity.aftersave.final') {
|
|
$recordId = $data->getId();
|
|
$columnFields = $data->getData();
|
|
$vtEntityDelta = new VTEntityDelta();
|
|
$delta = $vtEntityDelta->getEntityDelta($moduleName, $recordId, true);
|
|
|
|
$newerEntity = $vtEntityDelta->getNewEntity($moduleName, $recordId);
|
|
$newerColumnFields = $newerEntity->getData();
|
|
|
|
|
|
if ($moduleName === 'SalesOrder') {
|
|
|
|
$recordId = $data->getId();
|
|
$focus = CRMEntity::getInstance($moduleName);
|
|
$focus->retrieve_entity_info($recordId, $moduleName);
|
|
|
|
$accountId = $focus->column_fields['account_id'];
|
|
if (empty($accountId)) return;
|
|
|
|
$toEmail = "souldibachir3150@gmail.com";
|
|
// $toEmail = getSingleFieldValue('vtiger_account', 'email1', 'accountid', $accountId);
|
|
if (empty($toEmail)) return;
|
|
|
|
|
|
/** -----------------------------------------------------------
|
|
* 🔥 Secure ExportPDF with login cookie (your working version)
|
|
* ----------------------------------------------------------- */
|
|
|
|
ob_clean();
|
|
|
|
$loginUrl = "https://sophal.net/sophalcrm/index.php?module=Users&action=Login";
|
|
$exportUrl = "https://sophal.net/sophalcrm/index.php?module=SalesOrder&action=ExportPDF&record=$recordId";
|
|
|
|
// 1) Login
|
|
$post = http_build_query([
|
|
'username' => 'admin', // ⚠️ Replace later with "pdfbot"
|
|
'password' => 'Sophal@Crm@Sophal', // ⚠️ Replace later with another password
|
|
]);
|
|
|
|
$contextLogin = stream_context_create([
|
|
'http' => [
|
|
'method' => 'POST',
|
|
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
|
|
'content' => $post,
|
|
]
|
|
]);
|
|
|
|
file_get_contents($loginUrl, false, $contextLogin);
|
|
|
|
// Extract session cookie
|
|
$cookies = [];
|
|
foreach ($http_response_header as $hdr) {
|
|
if (stripos($hdr, 'Set-Cookie:') === 0) {
|
|
$cookies[] = trim(substr($hdr, 11), ';');
|
|
}
|
|
}
|
|
$cookieHeader = 'Cookie: ' . implode('; ', $cookies);
|
|
|
|
// 2) Download PDF
|
|
$contextPDF = stream_context_create([
|
|
'http' => [
|
|
'method' => 'GET',
|
|
'header' => $cookieHeader
|
|
]
|
|
]);
|
|
|
|
$pdfContent = file_get_contents($exportUrl, false, $contextPDF);
|
|
|
|
// 3) Validate
|
|
if (strpos($pdfContent, '%PDF') !== 0) {
|
|
error_log("❌ ExportPDF returned invalid PDF for SalesOrder #$recordId");
|
|
return;
|
|
}
|
|
|
|
// 4) Save to storage
|
|
$pdfPath = "storage/SalesOrder_{$recordId}.pdf";
|
|
$filePath = $_SERVER['DOCUMENT_ROOT']."/sophalcrm/storage/SalesOrder_$recordId.pdf";
|
|
file_put_contents($filePath, $pdfContent);
|
|
|
|
ob_end_clean();
|
|
|
|
|
|
/** -----------------------------------------------------------
|
|
* 📧 Email body + send
|
|
* ----------------------------------------------------------- */
|
|
|
|
$subject = "Sales Order #" . $focus->column_fields['salesorder_no'];
|
|
$body = '<html>
|
|
<body style="font-family: Arial, sans-serif; background-color:#f5f5f5; margin:0; padding:0;">
|
|
|
|
<!-- HEADER -->
|
|
<table width="100%" cellpadding="0" cellspacing="0" style="background-color:#0d6efd; padding:20px 0;">
|
|
<tr>
|
|
<td align="center">
|
|
<img src="https://sophal.net/sophalcrm/layouts/v7/skins/images/favicon.ico" alt="SOPHAL SPA" style="max-height:60px;">
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" style="color:#ffffff; font-size:20px; padding-top:10px;">
|
|
<strong>SOPHAL SPA</strong>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<!-- BODY -->
|
|
<table width="100%" cellpadding="0" cellspacing="0" style="padding:30px;">
|
|
<tr>
|
|
<td style="background:#ffffff; padding:25px; border-radius:8px;">
|
|
|
|
<p>Bonjour <strong>'.$accountId.'</strong>,</p>
|
|
|
|
<p>Votre <strong>bon de commande n° '.$focus->column_fields['salesorder_no'].'</strong> est maintenant disponible.</p>
|
|
<p>Vous pouvez le télécharger en cliquant sur le bouton ci-dessous :</p>
|
|
|
|
<!-- DOWNLOAD BUTTON -->
|
|
<p style="text-align:center; margin:30px 0;">
|
|
<a href="https://sophal.net/sophalcrm/'.$pdfPath.'"
|
|
style="
|
|
background-color:#0d6efd;
|
|
color:#ffffff;
|
|
padding:14px 28px;
|
|
text-decoration:none;
|
|
font-size:16px;
|
|
border-radius:6px;
|
|
display:inline-block;
|
|
font-weight:bold;
|
|
">
|
|
📄 Télécharger le Bon de Commande
|
|
</a>
|
|
</p>
|
|
|
|
<p style="color:#b00; font-size:13px; margin-top:20px;">
|
|
⚠️ Ceci est un email automatique. Merci de ne pas répondre à ce message.
|
|
</p>
|
|
|
|
<p>
|
|
Pour toute assistance, veuillez contacter notre service client :<br>
|
|
📞 +213541229487<br>
|
|
✉️ COMMERCIAL@SOPHAL.DZ
|
|
</p>
|
|
|
|
<p>Cordialement,<br>
|
|
<strong>SOPHAL SPA</strong></p>
|
|
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<!-- FOOTER -->
|
|
<table width="100%" cellpadding="0" cellspacing="0" style="background:#f0f0f0; padding:15px 0; border-top:1px solid #ddd;">
|
|
<tr>
|
|
<td align="center" style="font-size:12px; color:#666;">
|
|
© 2025 SOPHAL SPA — Tous droits réservés.<br>
|
|
HASSI BEN OKBA ORAN
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</body>
|
|
</html>';
|
|
|
|
// Send email
|
|
$outgoingModel = Settings_Vtiger_Systems_Model::getInstanceFromServerType('email', 'OutgoingServer');
|
|
$outgoingModel->pdf_path = $pdfPath;
|
|
$outgoingModel->to_email = $toEmail;
|
|
|
|
$ajaxAction = new Settings_Vtiger_OutgoingServerAjax_Action();
|
|
$ajaxAction->sendTestMail($outgoingModel, $subject, $body, $pdfPath);
|
|
}
|
|
|
|
|
|
if (is_array($delta)) {
|
|
$inserted = false;
|
|
foreach ($delta as $fieldName => $values) {
|
|
if ($fieldName != 'modifiedtime') {
|
|
if (!$inserted) {
|
|
$checkRecordPresentResult = $adb->pquery('SELECT * FROM vtiger_modtracker_basic WHERE crmid = ? AND status = ?', array($recordId, ModTracker::$CREATED));
|
|
if (!$adb->num_rows($checkRecordPresentResult) && $data->isNew()) {
|
|
$status = ModTracker::$CREATED;
|
|
} else {
|
|
$status = ModTracker::$UPDATED;
|
|
}
|
|
$this->id = $adb->getUniqueId('vtiger_modtracker_basic');
|
|
$changedOn = $newerColumnFields['modifiedtime'];
|
|
if ($moduleName == 'Users') {
|
|
$date_var = date("Y-m-d H:i:s");
|
|
$changedOn = $adb->formatDate($date_var, true);
|
|
}
|
|
$adb->pquery('INSERT INTO vtiger_modtracker_basic(id, crmid, module, whodid, changedon, status)
|
|
VALUES(?,?,?,?,?,?)', array(
|
|
$this->id,
|
|
$recordId,
|
|
$moduleName,
|
|
$current_user->id,
|
|
$changedOn,
|
|
$status
|
|
));
|
|
$inserted = true;
|
|
}
|
|
$adb->pquery(
|
|
'INSERT INTO vtiger_modtracker_detail(id,fieldname,prevalue,postvalue) VALUES(?,?,?,?)',
|
|
array($this->id, $fieldName, $values['oldValue'], $values['currentValue'])
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
header("Location: index.php");
|
|
exit;
|
|
}
|
|
|
|
if ($eventName == 'vtiger.entity.beforedelete') {
|
|
$recordId = $data->getId();
|
|
$columnFields = $data->getData();
|
|
$id = $adb->getUniqueId('vtiger_modtracker_basic');
|
|
$adb->pquery('INSERT INTO vtiger_modtracker_basic(id, crmid, module, whodid, changedon, status)
|
|
VALUES(?,?,?,?,?,?)', array($id, $recordId, $moduleName, $current_user->id, date('Y-m-d H:i:s', time()), ModTracker::$DELETED));
|
|
}
|
|
|
|
if ($eventName == 'vtiger.entity.afterrestore') {
|
|
$recordId = $data->getId();
|
|
$columnFields = $data->getData();
|
|
$id = $adb->getUniqueId('vtiger_modtracker_basic');
|
|
$adb->pquery('INSERT INTO vtiger_modtracker_basic(id, crmid, module, whodid, changedon, status)
|
|
VALUES(?,?,?,?,?,?)', array($id, $recordId, $moduleName, $current_user->id, date('Y-m-d H:i:s', time()), ModTracker::$RESTORED));
|
|
}
|
|
}
|
|
}
|