Compare commits
No commits in common. '17803c1acb38e9fd8d87e1aa840f3a2a5158b227' and '0ce9cb608d1a236dc7238b2e096547fc7c624372' have entirely different histories.
17803c1acb
...
0ce9cb608d
@ -1,121 +1,53 @@ |
|||||
<?php |
<?php |
||||
|
|
||||
namespace Config; |
namespace Config; |
||||
|
|
||||
use CodeIgniter\Config\BaseConfig; |
use CodeIgniter\Config\BaseConfig; |
||||
|
|
||||
class Email extends BaseConfig |
class Email extends BaseConfig |
||||
{ |
{ |
||||
public string $fromEmail = ''; |
public string $fromEmail = 'rey342505@gmail.com'; |
||||
public string $fromName = ''; |
public string $fromName = 'motorbike'; |
||||
public string $recipients = ''; |
public string $recipients = ''; |
||||
|
|
||||
/** |
|
||||
* The "user agent" |
|
||||
*/ |
|
||||
public string $userAgent = 'CodeIgniter'; |
public string $userAgent = 'CodeIgniter'; |
||||
|
|
||||
/** |
public string $protocol = 'smtp'; |
||||
* The mail sending protocol: mail, sendmail, smtp |
|
||||
*/ |
|
||||
public string $protocol = 'mail'; |
|
||||
|
|
||||
/** |
|
||||
* The server path to Sendmail. |
|
||||
*/ |
|
||||
public string $mailPath = '/usr/sbin/sendmail'; |
public string $mailPath = '/usr/sbin/sendmail'; |
||||
|
|
||||
/** |
public string $SMTPHost = 'smtp.gmail.com'; |
||||
* SMTP Server Hostname |
|
||||
*/ |
public string $SMTPUser = 'rey342505@gmail.com'; |
||||
public string $SMTPHost = ''; |
|
||||
|
public string $SMTPPass = 'loirqovmfuxnasrm'; // Mot de passe d’application (App Password) Gmail |
||||
/** |
|
||||
* SMTP Username |
public int $SMTPPort = 587; |
||||
*/ |
|
||||
public string $SMTPUser = ''; |
public int $SMTPTimeout = 30; |
||||
|
|
||||
/** |
|
||||
* SMTP Password |
|
||||
*/ |
|
||||
public string $SMTPPass = ''; |
|
||||
|
|
||||
/** |
|
||||
* SMTP Port |
|
||||
*/ |
|
||||
public int $SMTPPort = 25; |
|
||||
|
|
||||
/** |
|
||||
* SMTP Timeout (in seconds) |
|
||||
*/ |
|
||||
public int $SMTPTimeout = 5; |
|
||||
|
|
||||
/** |
|
||||
* Enable persistent SMTP connections |
|
||||
*/ |
|
||||
public bool $SMTPKeepAlive = false; |
public bool $SMTPKeepAlive = false; |
||||
|
|
||||
/** |
|
||||
* SMTP Encryption. |
|
||||
* |
|
||||
* @var string '', 'tls' or 'ssl'. 'tls' will issue a STARTTLS command |
|
||||
* to the server. 'ssl' means implicit SSL. Connection on port |
|
||||
* 465 should set this to ''. |
|
||||
*/ |
|
||||
public string $SMTPCrypto = 'tls'; |
public string $SMTPCrypto = 'tls'; |
||||
|
|
||||
/** |
|
||||
* Enable word-wrap |
|
||||
*/ |
|
||||
public bool $wordWrap = true; |
public bool $wordWrap = true; |
||||
|
|
||||
/** |
|
||||
* Character count to wrap at |
|
||||
*/ |
|
||||
public int $wrapChars = 76; |
public int $wrapChars = 76; |
||||
|
|
||||
/** |
public string $mailType = 'html'; |
||||
* Type of mail, either 'text' or 'html' |
|
||||
*/ |
|
||||
public string $mailType = 'text'; |
|
||||
|
|
||||
/** |
|
||||
* Character set (utf-8, iso-8859-1, etc.) |
|
||||
*/ |
|
||||
public string $charset = 'UTF-8'; |
public string $charset = 'UTF-8'; |
||||
|
|
||||
/** |
public bool $validate = true; |
||||
* Whether to validate the email address |
|
||||
*/ |
|
||||
public bool $validate = false; |
|
||||
|
|
||||
/** |
|
||||
* Email Priority. 1 = highest. 5 = lowest. 3 = normal |
|
||||
*/ |
|
||||
public int $priority = 3; |
public int $priority = 3; |
||||
|
|
||||
/** |
|
||||
* Newline character. (Use “\r\n” to comply with RFC 822) |
|
||||
*/ |
|
||||
public string $CRLF = "\r\n"; |
public string $CRLF = "\r\n"; |
||||
|
|
||||
/** |
|
||||
* Newline character. (Use “\r\n” to comply with RFC 822) |
|
||||
*/ |
|
||||
public string $newline = "\r\n"; |
public string $newline = "\r\n"; |
||||
|
|
||||
/** |
|
||||
* Enable BCC Batch Mode. |
|
||||
*/ |
|
||||
public bool $BCCBatchMode = false; |
public bool $BCCBatchMode = false; |
||||
|
|
||||
/** |
|
||||
* Number of emails in each BCC batch |
|
||||
*/ |
|
||||
public int $BCCBatchSize = 200; |
public int $BCCBatchSize = 200; |
||||
|
|
||||
/** |
|
||||
* Enable notify message from server |
|
||||
*/ |
|
||||
public bool $DSN = false; |
public bool $DSN = false; |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,14 @@ |
|||||
|
<?php |
||||
|
namespace App\Controllers; |
||||
|
|
||||
|
use App\Controllers\BaseController; |
||||
|
|
||||
|
class AlertsController extends BaseController |
||||
|
{ |
||||
|
public function check() |
||||
|
{ |
||||
|
helper('alerts'); |
||||
|
checkDeadlineAlerts(); |
||||
|
return "Vérification des alertes effectuée."; |
||||
|
} |
||||
|
} |
||||
@ -1,58 +1,22 @@ |
|||||
<?php |
<?php |
||||
|
|
||||
namespace App\Controllers; |
namespace App\Controllers; |
||||
|
|
||||
use CodeIgniter\Controller; |
use CodeIgniter\Controller; |
||||
use CodeIgniter\HTTP\CLIRequest; |
|
||||
use CodeIgniter\HTTP\IncomingRequest; |
|
||||
use CodeIgniter\HTTP\RequestInterface; |
|
||||
use CodeIgniter\HTTP\ResponseInterface; |
|
||||
use Psr\Log\LoggerInterface; |
|
||||
|
|
||||
/** |
class BaseController extends Controller |
||||
* Class BaseController |
|
||||
* |
|
||||
* BaseController provides a convenient place for loading components |
|
||||
* and performing functions that are needed by all your controllers. |
|
||||
* Extend this class in any new controllers: |
|
||||
* class Home extends BaseController |
|
||||
* |
|
||||
* For security be sure to declare any new methods as protected or private. |
|
||||
*/ |
|
||||
abstract class BaseController extends Controller |
|
||||
{ |
{ |
||||
/** |
|
||||
* Instance of the main Request object. |
|
||||
* |
|
||||
* @var CLIRequest|IncomingRequest |
|
||||
*/ |
|
||||
protected $request; |
|
||||
|
|
||||
/** |
|
||||
* An array of helpers to be loaded automatically upon |
|
||||
* class instantiation. These helpers will be available |
|
||||
* to all other controllers that extend BaseController. |
|
||||
* |
|
||||
* @var list<string> |
|
||||
*/ |
|
||||
protected $helpers = []; |
protected $helpers = []; |
||||
|
|
||||
/** |
public function initController(\CodeIgniter\HTTP\RequestInterface $request, |
||||
* Be sure to declare properties for any property fetch you initialized. |
\CodeIgniter\HTTP\ResponseInterface $response, |
||||
* The creation of dynamic property is deprecated in PHP 8.2. |
\Psr\Log\LoggerInterface $logger) |
||||
*/ |
|
||||
// protected $session; |
|
||||
|
|
||||
/** |
|
||||
* @return void |
|
||||
*/ |
|
||||
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) |
|
||||
{ |
{ |
||||
// Do Not Edit This Line |
|
||||
parent::initController($request, $response, $logger); |
parent::initController($request, $response, $logger); |
||||
|
|
||||
// Preload any models, libraries, etc, here. |
helper('alerts'); |
||||
|
|
||||
// E.g.: $this->session = \Config\Services::session(); |
if (function_exists('checkDeadlineAlerts')) { |
||||
|
checkDeadlineAlerts(); |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,25 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Controllers; |
||||
|
|
||||
|
use CodeIgniter\Controller; |
||||
|
|
||||
|
class TestDeadline extends Controller |
||||
|
{ |
||||
|
public function index() |
||||
|
{ |
||||
|
// Charger le helper qui contient ta fonction |
||||
|
helper('alerts'); // si ton fichier s'appelle alerts_helper.php |
||||
|
|
||||
|
// 🔹 Supprimer le cache 24h pour forcer l'exécution |
||||
|
$cacheFile = WRITEPATH . 'cache/check_deadline_last_run.txt'; |
||||
|
if (file_exists($cacheFile)) { |
||||
|
unlink($cacheFile); |
||||
|
} |
||||
|
|
||||
|
// Lancer la vérification |
||||
|
checkDeadlineAlerts(); |
||||
|
|
||||
|
echo "✅ Test de l'envoi d'alertes terminé."; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,145 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="fr"> |
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
|
<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '"> |
||||
|
<style> |
||||
|
body { font-size: 14px; font-family: Arial, sans-serif; } |
||||
|
.invoice-container { |
||||
|
max-width: 350px; /* Réduire la largeur du cadre */ |
||||
|
margin: 20px auto; |
||||
|
padding: 20px; |
||||
|
border: 2px solid #007bff; /* Bordure plus visible */ |
||||
|
border-radius: 10px; |
||||
|
background: #f0f8ff; /* Couleur de fond plus douce */ |
||||
|
} |
||||
|
.invoice-header { |
||||
|
background: #007bff; |
||||
|
color: white; |
||||
|
text-align: center; |
||||
|
font-size: 18px; |
||||
|
font-weight: bold; |
||||
|
padding: 10px; |
||||
|
border-radius: 10px 10px 0 0; |
||||
|
} |
||||
|
.invoice-footer { |
||||
|
background: #343a40; |
||||
|
color: white; |
||||
|
text-align: center; |
||||
|
font-size: 14px; |
||||
|
padding: 10px; |
||||
|
border-radius: 0 0 10px 10px; |
||||
|
margin-top: 12px; |
||||
|
} |
||||
|
table { width: 100%; border-collapse: collapse; } |
||||
|
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; } |
||||
|
th { background: #e9ecef; } |
||||
|
p, strong { color: #333; } |
||||
|
</style> |
||||
|
</head> |
||||
|
<body onload="window.print();"> |
||||
|
<div class="invoice-container"> |
||||
|
<div class="invoice-header"> |
||||
|
' . esc($company_info['company_name']) . ' |
||||
|
</div> |
||||
|
<p><strong>Facture ID:</strong> ' . esc($order_data['bill_no']) . '</p> |
||||
|
<p><strong>Nom:</strong> ' . esc($order_data['customer_name']) . '</p> |
||||
|
<p><strong>Adresse:</strong> ' . esc($order_data['customer_address']) . '</p> |
||||
|
<p><strong>Téléphone:</strong> ' . esc($order_data['customer_phone']) . '</p> |
||||
|
|
||||
|
<div style="display: flex;align-items: center;justify-content: space-around;margin-bottom: 3%;"> |
||||
|
<div> |
||||
|
<p>Signature du client</p> |
||||
|
</div> |
||||
|
<div> |
||||
|
<p>Signature du commercial</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<table class="table table-bordered"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th>Produit</th> |
||||
|
<th>Qté</th> |
||||
|
<th>Prix</th> |
||||
|
<th>Total</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody>'; |
||||
|
|
||||
|
foreach ($orders_items as $item) { |
||||
|
$product_data = $Products->getProductData($item['product_id']); |
||||
|
$html .= '<tr> |
||||
|
<td>' . esc($product_data['name']) . '</td> |
||||
|
<td>' . esc($item['qty']) . '</td> |
||||
|
<td>' . number_format((float)$item['rate'], 2, '.', ' ') . '</td> |
||||
|
<td>' . number_format((float)$item['amount'], 2, '.', ' ') . '</td> |
||||
|
</tr>'; |
||||
|
} |
||||
|
|
||||
|
$html .= ' </tbody> |
||||
|
</table> |
||||
|
<table class="table"> |
||||
|
<tr> |
||||
|
<th>Total:</th> |
||||
|
<td>' . number_format((float)$order_data['gross_amount'], 2, '.', ' ') . '</td> |
||||
|
</tr>'; |
||||
|
|
||||
|
if (!empty($order_data['service_charge']) && (float)$order_data['service_charge'] > 0) { |
||||
|
$html .= '<tr> |
||||
|
<th>Frais de service:</th> |
||||
|
<td>' . number_format((float)$order_data['service_charge'], 2, '.', ' ') . '</td> |
||||
|
</tr>'; |
||||
|
} |
||||
|
|
||||
|
if (!empty($order_data['vat_charge']) && (float)$order_data['vat_charge'] > 0) { |
||||
|
$html .= '<tr> |
||||
|
<th>TVA:</th> |
||||
|
<td>' . number_format((float)$order_data['vat_charge'], 2, '.', ' ') . '</td> |
||||
|
</tr>'; |
||||
|
} |
||||
|
|
||||
|
$html .= '<tr> |
||||
|
<th>Réduction:</th> |
||||
|
<td>' . number_format((float)$order_data['discount'], 2, '.', ' ') . '</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<th>Total à payer:</th> |
||||
|
<td><strong>' . number_format((float)$order_data['net_amount'], 2, '.', ' ') . '</strong></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<th>Statut:</th> |
||||
|
<td>' . $paid_status . '</td> |
||||
|
</tr>'; |
||||
|
|
||||
|
// Vérification et ajout des informations de paiement |
||||
|
if (!empty($order_data['order_payment_mode'])) { |
||||
|
$html .= '<tr> |
||||
|
<th>Mode de paiement:</th> |
||||
|
<td><strong>' . esc($order_data['order_payment_mode']) . '</strong></td> |
||||
|
</tr>'; |
||||
|
} |
||||
|
|
||||
|
if (!empty($order_data['tranche_1'])) { |
||||
|
$html .= '<tr> |
||||
|
<th>Tranche 1:</th> |
||||
|
<td><strong>' . number_format((float)$order_data['tranche_1'], 2, '.', ' ') . '</strong></td> |
||||
|
</tr>'; |
||||
|
} |
||||
|
|
||||
|
if (!empty($order_data['tranche_2'])) { |
||||
|
$html .= '<tr> |
||||
|
<th>Tranche 2:</th> |
||||
|
<td><strong>' . number_format((float)$order_data['tranche_2'], 2, '.', ' ') . '</strong></td> |
||||
|
</tr>'; |
||||
|
} |
||||
|
|
||||
|
$html .= '</table> |
||||
|
|
||||
|
<div class="invoice-footer"> |
||||
|
Merci pour votre achat !<br> |
||||
|
<strong>' . esc($company_info['company_name']) . '</strong> |
||||
|
</div> |
||||
|
</div> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,176 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use App\Models\Users; |
||||
|
use App\Models\Avance; |
||||
|
use App\Models\AlertMail; |
||||
|
|
||||
|
function checkDeadlineAlerts() |
||||
|
{ |
||||
|
log_message('info', "=== DÉBUT checkDeadlineAlerts ==="); |
||||
|
|
||||
|
$cacheFile = WRITEPATH . 'cache/check_deadline_last_run.txt'; |
||||
|
|
||||
|
// On enlève la vérification de 24h pour s'assurer que le script tourne quotidiennement |
||||
|
file_put_contents($cacheFile, time()); |
||||
|
|
||||
|
$avanceModel = new Avance(); |
||||
|
$alertMailModel = new AlertMail(); |
||||
|
$usersModel = new Users(); |
||||
|
|
||||
|
$today = date('Y-m-d'); |
||||
|
log_message('info', "Date du jour: {$today}"); |
||||
|
|
||||
|
// Modification pour vérifier les avances dans 0-3 jours |
||||
|
$avances = $avanceModel |
||||
|
->where('DATE(deadline) >=', $today) // Inclut le jour même |
||||
|
->where('DATE(deadline) <=', date('Y-m-d', strtotime('+3 days'))) |
||||
|
->where('active', 1) |
||||
|
->findAll(); |
||||
|
|
||||
|
log_message('info', "Nombre d'avances trouvées (0-3 jours): " . count($avances)); |
||||
|
|
||||
|
$users = $usersModel->select('users.email, users.firstname, users.lastname') |
||||
|
->join('user_group', 'user_group.user_id = users.id') |
||||
|
->join('groups', 'groups.id = user_group.group_id') |
||||
|
->where('groups.group_name', 'DAF') |
||||
|
->findAll(); |
||||
|
|
||||
|
log_message('info', "Utilisateurs DAF trouvés: " . json_encode($users)); |
||||
|
|
||||
|
$emails = array_column($users, 'email'); |
||||
|
log_message('info', "Emails extraits: " . json_encode($emails)); |
||||
|
|
||||
|
if (empty($emails)) { |
||||
|
log_message('error', "Aucun email DAF trouvé"); |
||||
|
|
||||
|
$db = \Config\Database::connect(); |
||||
|
$allGroups = $db->query("SELECT DISTINCT group_name FROM groups")->getResult(); |
||||
|
log_message('info', "Groupes disponibles: " . json_encode($allGroups)); |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
foreach ($avances as $avance) { |
||||
|
$deadline = date('Y-m-d', strtotime($avance['deadline'])); |
||||
|
$daysLeft = (int) ceil((strtotime($deadline) - strtotime($today)) / 86400); |
||||
|
|
||||
|
log_message('info', "Avance ID: {$avance['avance_id']}, Deadline: {$deadline}, Jours restants: {$daysLeft}"); |
||||
|
|
||||
|
// Modification des types d'alerte pour 0, 1, 2, 3 jours |
||||
|
$alertType = match($daysLeft) { |
||||
|
3 => 'deadline_3_days', |
||||
|
2 => 'deadline_2_days', |
||||
|
1 => 'deadline_1_day', |
||||
|
0 => 'deadline_today', |
||||
|
default => null, |
||||
|
}; |
||||
|
|
||||
|
if ($alertType === null) { |
||||
|
log_message('info', "Pas d'alerte nécessaire pour {$daysLeft} jours restants"); |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
log_message('info', "Type d'alerte: {$alertType}"); |
||||
|
|
||||
|
// Vérification si l'alerte a déjà été envoyée |
||||
|
$alreadySent = $alertMailModel |
||||
|
->where('avance_id', $avance['avance_id']) |
||||
|
->where('alert_type', $alertType) |
||||
|
->first(); |
||||
|
|
||||
|
if ($alreadySent) { |
||||
|
log_message('info', "Alerte déjà envoyée pour avance_id={$avance['avance_id']} type={$alertType}"); |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
// Message modifié pour inclure le cas du jour même |
||||
|
$urgencyText = $daysLeft === 0 ? "ÉCHÉANCE AUJOURD'HUI" : "{$daysLeft} jour(s) restant(s)"; |
||||
|
$message = " |
||||
|
<h3>⚠️ URGENT : Avance approchant de la deadline</h3> |
||||
|
<p><strong>ID Avance :</strong> {$avance['avance_id']}</p> |
||||
|
<p><strong>Client :</strong> {$avance['customer_name']}</p> |
||||
|
<p><strong>Montant avance :</strong> " . number_format($avance['avance_amount'], 0, ',', ' ') . " Ar</p> |
||||
|
<p><strong>Montant dû :</strong> " . number_format($avance['amount_due'], 0, ',', ' ') . " Ar</p> |
||||
|
<p><strong>Deadline :</strong> {$deadline}</p> |
||||
|
<p><strong>Statut :</strong> <span style='color: red; font-weight: bold;'>{$urgencyText}</span></p> |
||||
|
<p><strong>Téléphone client :</strong> {$avance['customer_phone']}</p> |
||||
|
<p><strong>Adresse client :</strong> {$avance['customer_address']}</p> |
||||
|
<hr> |
||||
|
<p><em>Cette avance " . ($daysLeft === 0 ? "arrive à échéance aujourd'hui" : "arrivera à échéance dans {$daysLeft} jour(s)") . ". Action requise immédiatement.</em></p> |
||||
|
"; |
||||
|
|
||||
|
$emailsSent = 0; |
||||
|
foreach ($emails as $to) { |
||||
|
log_message('info', "Tentative d'envoi email à: {$to}"); |
||||
|
|
||||
|
$subject = $daysLeft === 0 |
||||
|
? "⚠️ AVANCE URGENTE - ÉCHÉANCE AUJOURD'HUI" |
||||
|
: "⚠️ AVANCE URGENTE - {$daysLeft} jour(s) restant(s)"; |
||||
|
|
||||
|
if (sendEmailInBackground($to, $subject, $message)) { |
||||
|
$emailsSent++; |
||||
|
log_message('info', "Email envoyé avec succès à: {$to}"); |
||||
|
} else { |
||||
|
log_message('error', "Échec envoi email à: {$to}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($emailsSent > 0) { |
||||
|
log_message('info', "Insertion alerte pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
||||
|
$alertMailModel->insert([ |
||||
|
'avance_id' => $avance['avance_id'], |
||||
|
'alert_type' => $alertType, |
||||
|
'sent_date' => date('Y-m-d H:i:s'), |
||||
|
'status' => 'sent', |
||||
|
'created_at' => date('Y-m-d H:i:s'), |
||||
|
]); |
||||
|
} else { |
||||
|
log_message('error', "Aucun email envoyé pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
log_message('info', "=== FIN checkDeadlineAlerts ==="); |
||||
|
} |
||||
|
|
||||
|
function sendEmailInBackground($to, $subject, $message) |
||||
|
{ |
||||
|
try { |
||||
|
log_message('info', "Préparation envoi email à: {$to}"); |
||||
|
|
||||
|
$email = \Config\Services::email(); |
||||
|
|
||||
|
$config = [ |
||||
|
'protocol' => 'smtp', |
||||
|
'SMTPHost' => 'smtp.gmail.com', |
||||
|
'SMTPUser' => 'rey342505@gmail.com', |
||||
|
'SMTPPass' => 'loirqovmfuxnasrm', |
||||
|
'SMTPPort' => 587, |
||||
|
'SMTPCrypto' => 'tls', |
||||
|
'mailType' => 'html', |
||||
|
'charset' => 'utf-8', |
||||
|
'newline' => "\r\n" |
||||
|
]; |
||||
|
|
||||
|
$email->initialize($config); |
||||
|
|
||||
|
$email->setFrom('rey342505@gmail.com', 'Système Motorbike - Alertes Avances'); |
||||
|
$email->setTo($to); |
||||
|
$email->setSubject($subject); |
||||
|
$email->setMessage($message); |
||||
|
|
||||
|
log_message('info', "Configuration email terminée, tentative d'envoi..."); |
||||
|
|
||||
|
if (!$email->send()) { |
||||
|
$debugInfo = $email->printDebugger(['headers']); |
||||
|
log_message('error', "Erreur email à {$to}: " . print_r($debugInfo, true)); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
log_message('info', "Email envoyé avec succès à: {$to}"); |
||||
|
return true; |
||||
|
|
||||
|
} catch (\Exception $e) { |
||||
|
log_message('error', "Exception email à {$to}: " . $e->getMessage()); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Models; |
||||
|
|
||||
|
use CodeIgniter\Model; |
||||
|
|
||||
|
class AlertMail extends Model |
||||
|
{ |
||||
|
protected $table = 'email_alerts'; |
||||
|
protected $primaryKey = 'id'; |
||||
|
|
||||
|
protected $allowedFields = [ |
||||
|
'avance_id', |
||||
|
'alert_type', |
||||
|
'sent_date', |
||||
|
'status', |
||||
|
'created_at', |
||||
|
]; |
||||
|
|
||||
|
// Pas de fonction checkDeadlineAlerts ici ! |
||||
|
} |
||||
@ -1 +0,0 @@ |
|||||
icon |
|
||||
@ -0,0 +1 @@ |
|||||
|
icon |
||||
@ -1 +0,0 @@ |
|||||
icon |
|
||||
@ -0,0 +1 @@ |
|||||
|
icon |
||||
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 0 B |
|
Before Width: | Height: | Size: 354 B After Width: | Height: | Size: 0 B |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 848 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 657 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
@ -0,0 +1 @@ |
|||||
|
1755601005 |
||||