* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. */ /** * \file core/triggers/interface_99_modMahnung_MahnungTriggers.class.php * \ingroup mahnung * \brief Trigger: setzt offene Mahnvorgänge nach Zahlungseingang auf "erledigt". * * Klassenname: InterfaceTriggers — Suffix muss zu Dateinamen passen. * Datei muss in core/triggers/ liegen, wird durch DolibarrModules->loadtriggers * (module_parts['triggers']=1) beim Modul-Aktivieren registriert. */ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; class InterfaceMahnungTriggers extends DolibarrTriggers { /** * @param DoliDB $db Datenbank-Handler */ public function __construct($db) { parent::__construct($db); $this->family = 'financial'; $this->description = 'MahnungTriggerBeschreibung'; $this->version = self::VERSIONS['dev']; $this->picto = 'fa-envelope-open-text'; } /** * Wird bei jedem Dolibarr-Event aufgerufen. * * @param string $action z.B. PAYMENT_CUSTOMER_CREATE, BILL_PAYED * @param CommonObject $object Event-Subjekt * @param User $user aktueller User * @param Translate $langs Sprache * @param Conf $conf Konfig * @return int <0 Fehler, 0 nichts getan, >0 OK */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) { if (!isModEnabled('mahnung')) { return 0; } switch ($action) { case 'BILL_PAYED': case 'BILL_VALIDATE': // $object ist Facture if (!empty($object) && !empty($object->id) && !empty($object->paye)) { return $this->onRechnungBezahlt((int) $object->id, $user); } return 0; case 'PAYMENT_CUSTOMER_CREATE': // $object ist Paiement; eventuell auch ohne paye=1 Status — pro betroffener Rechnung prüfen return $this->onPaiementErzeugt($object, $user); default: return 0; } } /** * Setzt alle offenen Mahnvorgänge zur Rechnung auf STATUS_ERLEDIGT. * * @param int $factureId * @param User $user * @return int >=0 Anzahl aktualisierter Mahnungen, <0 Fehler */ private function onRechnungBezahlt($factureId, User $user) { require_once DOL_DOCUMENT_ROOT.'/custom/mahnung/class/mahnung.class.php'; $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."mahnung_mahnung"; $sql .= " WHERE fk_facture = ".((int) $factureId); $sql .= " AND status NOT IN (".Mahnung::STATUS_ERLEDIGT.", ".Mahnung::STATUS_STORNIERT.")"; $resql = $this->db->query($sql); if (!$resql) { return -1; } $count = 0; while ($obj = $this->db->fetch_object($resql)) { $m = new Mahnung($this->db); if ($m->fetch((int) $obj->rowid) > 0 && $m->setErledigt($user) > 0) { $count++; } } $this->db->free($resql); // Wenn Mahnungen erledigt wurden: prüfen ob noch offene übrig sind. // Falls nicht, GlobalNotify-Badge räumen. if ($count > 0 && !$this->hatOffeneMahnungen()) { require_once DOL_DOCUMENT_ROOT.'/custom/mahnung/class/mahnungcron.class.php'; MahnungCron::clearGlobalNotify(); } return $count; } /** * Bei Zahlungs-Erzeugung: alle betroffenen Rechnungen prüfen, ob sie nun * vollständig bezahlt sind. paye-Flag wird in Dolibarr typischerweise erst * gesetzt, wenn Summe der Zahlungen >= total_ttc — wir prüfen pessimistisch: * sobald überhaupt eine Zahlung kommt + offene Mahnung existiert -> erledigen, * wenn die Zahlung den offenen Betrag deckt. * * @param CommonObject $payment * @param User $user * @return int */ private function onPaiementErzeugt($payment, User $user) { if (empty($payment) || empty($payment->amounts) || !is_array($payment->amounts)) { return 0; } $total = 0; foreach ($payment->amounts as $factureId => $amount) { $factureId = (int) $factureId; if ($factureId <= 0) { continue; } // Prüfen, ob die Rechnung jetzt voll bezahlt ist if ($this->istRechnungVollBezahlt($factureId)) { $total += $this->onRechnungBezahlt($factureId, $user); } } return $total; } /** * Prüft ob noch offene Mahnvorgänge existieren (Status weder erledigt noch storniert). * * @return bool true wenn mindestens eine offene Mahnung existiert */ private function hatOffeneMahnungen() { $sql = "SELECT COUNT(*) AS nb FROM ".MAIN_DB_PREFIX."mahnung_mahnung"; $sql .= " WHERE status NOT IN (".Mahnung::STATUS_ERLEDIGT.", ".Mahnung::STATUS_STORNIERT.")"; $resql = $this->db->query($sql); if (!$resql) { return true; // Im Zweifel Badge stehen lassen } $obj = $this->db->fetch_object($resql); $this->db->free($resql); return (int) $obj->nb > 0; } /** * @param int $factureId * @return bool */ private function istRechnungVollBezahlt($factureId) { $sql = "SELECT f.total_ttc, COALESCE(SUM(pf.amount), 0) AS gezahlt"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_facture = f.rowid"; $sql .= " WHERE f.rowid = ".((int) $factureId); $sql .= " GROUP BY f.rowid, f.total_ttc"; $resql = $this->db->query($sql); if (!$resql || !$this->db->num_rows($resql)) { return false; } $obj = $this->db->fetch_object($resql); $this->db->free($resql); return (float) $obj->gezahlt + 0.005 >= (float) $obj->total_ttc; } }