All checks were successful
Deploy mahnung / deploy (push) Successful in 14s
Vollstaendiges 3-stufiges Mahnwesen nach BGB §288: - SQL-Schema (llx_mahnung_mahnung, llx_mahnung_stufe) - CRUD-Klassen (Mahnung, MahnungStufe, MahnungVorschlag) - TCPDF DIN-5008 PDF-Generierung - Verzugszinsberechnung B2C/B2B + §288 Abs.5 Pauschale - Trigger: offene Mahnungen bei Zahlungseingang schliessen - Hook: Tab + Button auf Rechnungs-/Kundenkarte - Cron: taegl. Vorschlagsliste + Ntfy-Push - Deploy-Pipeline (.forgejo/workflows/deploy.yml) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
145 lines
4.1 KiB
PHP
145 lines
4.1 KiB
PHP
<?php
|
|
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
|
|
*
|
|
* GPL v3 (siehe COPYING).
|
|
*/
|
|
|
|
/**
|
|
* \file htdocs/custom/mahnung/class/actions_mahnung.class.php
|
|
* \ingroup mahnung
|
|
* \brief Hook-Klasse: Tab "Mahnungen" + Button "Mahnung erstellen" auf Rechnungs-Karte.
|
|
*
|
|
* Wird in modMahnung registriert via module_parts['hooks'] = ['data' => ['invoicecard']].
|
|
*/
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/custom/mahnung/class/mahnung.class.php';
|
|
|
|
class ActionsMahnung
|
|
{
|
|
/** @var array */
|
|
public $errors = array();
|
|
|
|
/** @var string */
|
|
public $resprints = '';
|
|
|
|
/**
|
|
* Hook addMoreActionsButtons: Button "Mahnung erstellen" im Header der Rechnungs-Karte.
|
|
*
|
|
* @param array $parameters
|
|
* @param CommonObject $object Facture
|
|
* @param string $action
|
|
* @param HookManager $hookmanager
|
|
* @return int 0 = weiter, 1 = ueberschreiben
|
|
*/
|
|
public function addMoreActionsButtons($parameters, &$object, &$action, $hookmanager)
|
|
{
|
|
global $user, $langs;
|
|
|
|
$contexts = explode(':', $parameters['context'] ?? '');
|
|
if (!in_array('invoicecard', $contexts, true)) {
|
|
return 0;
|
|
}
|
|
|
|
if (empty($object->id) || empty($object->socid)) {
|
|
return 0;
|
|
}
|
|
|
|
// Nur fuer normale Kundenrechnungen
|
|
if (!isset($object->type) || (int) $object->type !== 0) {
|
|
return 0;
|
|
}
|
|
|
|
$paye = (int) ($object->paye ?? 0);
|
|
$statut = (int) ($object->statut ?? ($object->status ?? 0));
|
|
$dateLim = !empty($object->date_lim_reglement) ? (int) $object->date_lim_reglement : 0;
|
|
$ueberfaellig = ($statut === 1 && $paye === 0 && $dateLim > 0 && $dateLim < dol_now());
|
|
|
|
$langs->load('mahnung@mahnung');
|
|
|
|
if (!$user->hasRight('mahnung', 'write')) {
|
|
return 0;
|
|
}
|
|
|
|
$label = $langs->trans('MahnungErstellen');
|
|
|
|
if ($ueberfaellig) {
|
|
$url = DOL_URL_ROOT.'/custom/mahnung/list.php?mode=vorschlag&search_socid='.((int) $object->socid);
|
|
print dolGetButtonAction($label, '', 'default', $url, 'btn-mahnung-create', 1);
|
|
} else {
|
|
$attr = array('title' => $langs->trans('MahnungKeineUeberfaelligen'));
|
|
print dolGetButtonAction($label, '', 'default', '#', 'btn-mahnung-create', 0, array('attr' => $attr));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Hook completeTabsHead: Tab "Mahnungen (n)" sowohl auf Rechnungs- als
|
|
* auch auf Kundenkarte einblenden.
|
|
*
|
|
* @param array $parameters
|
|
* @param CommonObject $object Facture oder Societe
|
|
* @param string $action
|
|
* @param HookManager $hookmanager
|
|
* @return int 0 = weiter
|
|
*/
|
|
public function completeTabsHead($parameters, &$object, &$action, $hookmanager)
|
|
{
|
|
global $langs, $db;
|
|
|
|
$contexts = explode(':', $parameters['context'] ?? '');
|
|
$onInvoice = in_array('invoicecard', $contexts, true);
|
|
$onThirdparty = in_array('thirdpartycard', $contexts, true);
|
|
if (!$onInvoice && !$onThirdparty) {
|
|
return 0;
|
|
}
|
|
if (empty($object->id)) {
|
|
return 0;
|
|
}
|
|
if (!isset($parameters['head']) || !is_array($parameters['head'])) {
|
|
return 0;
|
|
}
|
|
|
|
$langs->load('mahnung@mahnung');
|
|
|
|
if ($onInvoice) {
|
|
$count = $this->countMahnungen($db, 'fk_facture', (int) $object->id);
|
|
$tabUrl = DOL_URL_ROOT.'/custom/mahnung/list.php?mode=archiv&fk_facture='.((int) $object->id);
|
|
} else {
|
|
$count = $this->countMahnungen($db, 'fk_soc', (int) $object->id);
|
|
$tabUrl = DOL_URL_ROOT.'/custom/mahnung/list.php?mode=archiv&search_socid='.((int) $object->id);
|
|
}
|
|
|
|
$head = &$parameters['head'];
|
|
$pos = count($head);
|
|
$head[$pos][0] = $tabUrl;
|
|
$head[$pos][1] = $langs->trans('MahnungMenu').($count > 0 ? ' <span class="badge">'.$count.'</span>' : '');
|
|
$head[$pos][2] = 'mahnung';
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @param DoliDB $db
|
|
* @param string $col 'fk_facture' | 'fk_soc'
|
|
* @param int $id
|
|
* @return int
|
|
*/
|
|
private function countMahnungen($db, $col, $id)
|
|
{
|
|
if (!in_array($col, array('fk_facture', 'fk_soc'), true)) {
|
|
return 0;
|
|
}
|
|
$sql = "SELECT COUNT(*) AS n FROM ".MAIN_DB_PREFIX."mahnung_mahnung";
|
|
$sql .= " WHERE ".$col." = ".((int) $id);
|
|
$sql .= " AND status NOT IN (".Mahnung::STATUS_STORNIERT.")";
|
|
$resql = $db->query($sql);
|
|
if (!$resql) {
|
|
return 0;
|
|
}
|
|
$obj = $db->fetch_object($resql);
|
|
$count = (int) $obj->n;
|
|
$db->free($resql);
|
|
return $count;
|
|
}
|
|
}
|