feat: GlobalNotify Integration für Import-Benachrichtigungen
- Helper-Funktion notify() für sichere GlobalNotify-Nutzung - Benachrichtigung bei importierten Rechnungen (zur Prüfung) - Warnung bei Import-Fehlern - Fehler-Benachrichtigung bei IMAP-Verbindungsproblemen - Sofortige Benachrichtigung bei Exception/Fatal - countPendingInvoices() für Draft-Rechnungen-Zählung - Fallback auf dol_syslog wenn GlobalNotify nicht verfügbar - Version 3.7 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
59ce17b7b5
commit
8b0d1830a3
3 changed files with 157 additions and 1 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -2,6 +2,19 @@
|
|||
|
||||
Alle wesentlichen Änderungen an diesem Projekt werden in dieser Datei dokumentiert.
|
||||
|
||||
## [3.7] - 2026-02-23
|
||||
|
||||
### Hinzugefügt
|
||||
- **GlobalNotify Integration**: Benachrichtigungen über das zentrale GlobalNotify-Modul
|
||||
- Import-Fehler: Warnung bei fehlgeschlagenen Importen
|
||||
- Rechnungen zur Prüfung: Aktion wenn neue Rechnungen warten
|
||||
- IMAP-Fehler: Warnung wenn E-Mail Postfach nicht erreichbar
|
||||
- Exception/Fatal: Sofortige Benachrichtigung bei Abstürzen
|
||||
- **Helper-Funktion**: `notify()` für sichere GlobalNotify-Nutzung mit Fallback
|
||||
|
||||
### Hinweis
|
||||
GlobalNotify ist optional. Ohne das Modul werden Benachrichtigungen ins Dolibarr-Log geschrieben.
|
||||
|
||||
## [3.6] - 2026-02-23
|
||||
|
||||
### Behoben
|
||||
|
|
|
|||
|
|
@ -71,6 +71,57 @@ class CronImportZugferd
|
|||
*/
|
||||
private $startTime = 0;
|
||||
|
||||
/**
|
||||
* Send notification via GlobalNotify (if available)
|
||||
*
|
||||
* @param string $type 'error', 'warning', 'info', 'action'
|
||||
* @param string $title Title
|
||||
* @param string $message Message
|
||||
* @param string $actionUrl URL for action button
|
||||
* @param string $actionLabel Label for action button
|
||||
* @return bool True if sent via GlobalNotify
|
||||
*/
|
||||
protected function notify($type, $title, $message, $actionUrl = '', $actionLabel = '')
|
||||
{
|
||||
if (!isModEnabled('globalnotify')) {
|
||||
dol_syslog("ImportZugferd [{$type}]: {$title} - {$message}", LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
$classFile = dol_buildpath('/globalnotify/class/globalnotify.class.php', 0);
|
||||
if (!file_exists($classFile)) {
|
||||
dol_syslog("ImportZugferd [{$type}]: {$title} - {$message}", LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
require_once $classFile;
|
||||
|
||||
if (!class_exists('GlobalNotify')) {
|
||||
dol_syslog("ImportZugferd [{$type}]: {$title} - {$message}", LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
switch ($type) {
|
||||
case 'error':
|
||||
GlobalNotify::error('importzugferd', $title, $message, $actionUrl, $actionLabel);
|
||||
break;
|
||||
case 'warning':
|
||||
GlobalNotify::warning('importzugferd', $title, $message, $actionUrl, $actionLabel);
|
||||
break;
|
||||
case 'action':
|
||||
GlobalNotify::actionRequired('importzugferd', $title, $message, $actionUrl, $actionLabel ?: 'Aktion erforderlich');
|
||||
break;
|
||||
default:
|
||||
GlobalNotify::info('importzugferd', $title, $message, $actionUrl, $actionLabel);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
dol_syslog("GlobalNotify error: ".$e->getMessage(), LOG_ERR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
|
@ -226,17 +277,34 @@ class CronImportZugferd
|
|||
$this->cronLog("Completed: imported={$this->imported_count}, skipped={$this->skipped_count}, errors={$this->error_count}, duration={$duration}s");
|
||||
$this->cronLog("========== CRON END (success) ==========");
|
||||
|
||||
// Send GlobalNotify notifications
|
||||
$this->sendImportNotifications();
|
||||
|
||||
return ($this->error_count > 0) ? -1 : 0;
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->error = 'Exception: '.$e->getMessage();
|
||||
$this->cronLog("EXCEPTION: ".$e->getMessage()."\n".$e->getTraceAsString(), 'ERROR');
|
||||
$this->cronLog("========== CRON END (exception) ==========");
|
||||
$this->notify(
|
||||
'error',
|
||||
'ZUGFeRD Import fehlgeschlagen',
|
||||
'Exception: '.$e->getMessage(),
|
||||
dol_buildpath('/importzugferd/admin/setup.php', 1),
|
||||
'Einstellungen prüfen'
|
||||
);
|
||||
return -1;
|
||||
} catch (Throwable $t) {
|
||||
$this->error = 'Fatal: '.$t->getMessage();
|
||||
$this->cronLog("FATAL: ".$t->getMessage()."\n".$t->getTraceAsString(), 'ERROR');
|
||||
$this->cronLog("========== CRON END (fatal) ==========");
|
||||
$this->notify(
|
||||
'error',
|
||||
'ZUGFeRD Import Absturz',
|
||||
'Fatal: '.$t->getMessage(),
|
||||
dol_buildpath('/importzugferd/admin/setup.php', 1),
|
||||
'Einstellungen prüfen'
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -645,4 +713,79 @@ class CronImportZugferd
|
|||
dol_syslog("CronImportZugferd: Keeping error file in watch folder: " . $file, LOG_INFO);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send notifications based on import results
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function sendImportNotifications()
|
||||
{
|
||||
// Check for errors
|
||||
if ($this->error_count > 0) {
|
||||
$errorSummary = count($this->errors) > 0 ? implode(', ', array_slice($this->errors, 0, 3)) : 'Siehe Log';
|
||||
$this->notify(
|
||||
'warning',
|
||||
$this->error_count.' ZUGFeRD Import-Fehler',
|
||||
$errorSummary,
|
||||
dol_buildpath('/importzugferd/list.php?status=error', 1),
|
||||
'Fehler anzeigen'
|
||||
);
|
||||
}
|
||||
|
||||
// Check for imported invoices that need review
|
||||
if ($this->imported_count > 0) {
|
||||
// Count pending invoices (drafts needing approval)
|
||||
$pendingCount = $this->countPendingInvoices();
|
||||
|
||||
if ($pendingCount > 0) {
|
||||
$this->notify(
|
||||
'action',
|
||||
$this->imported_count.' ZUGFeRD Rechnungen importiert',
|
||||
"{$pendingCount} Lieferantenrechnungen warten auf Prüfung und Freigabe",
|
||||
dol_buildpath('/fourn/facture/list.php?search_status=0', 1),
|
||||
'Rechnungen prüfen'
|
||||
);
|
||||
} else {
|
||||
// All auto-created and validated
|
||||
$this->notify(
|
||||
'info',
|
||||
$this->imported_count.' ZUGFeRD Rechnungen importiert',
|
||||
'Alle Rechnungen wurden erfolgreich verarbeitet',
|
||||
dol_buildpath('/fourn/facture/list.php', 1),
|
||||
'Anzeigen'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// IMAP connection issues
|
||||
if (strpos($this->error, 'IMAP connection failed') !== false) {
|
||||
$this->notify(
|
||||
'error',
|
||||
'IMAP Verbindung fehlgeschlagen',
|
||||
'E-Mail Postfach für ZUGFeRD-Import nicht erreichbar',
|
||||
dol_buildpath('/importzugferd/admin/setup.php', 1),
|
||||
'IMAP prüfen'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count pending (draft) supplier invoices
|
||||
*
|
||||
* @return int Number of draft supplier invoices
|
||||
*/
|
||||
protected function countPendingInvoices()
|
||||
{
|
||||
$sql = "SELECT COUNT(*) as cnt FROM ".MAIN_DB_PREFIX."facture_fourn";
|
||||
$sql .= " WHERE fk_statut = 0"; // Draft status
|
||||
$sql .= " AND entity IN (".getEntity('facture_fourn').")";
|
||||
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$obj = $this->db->fetch_object($resql);
|
||||
return (int) $obj->cnt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class modImportZugferd extends DolibarrModules
|
|||
$this->editor_squarred_logo = ''; // Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@importzugferd'
|
||||
|
||||
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z'
|
||||
$this->version = '3.6';
|
||||
$this->version = '3.7';
|
||||
// Url to the file with your last numberversion of this module
|
||||
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue