Widget-Prognose: intuitive "Ø X T nach Rechnung" + rotes Datum statt Text [deploy]
All checks were successful
Deploy mahnung / deploy (push) Successful in 13s
All checks were successful
Deploy mahnung / deploy (push) Successful in 13s
Eddy-Feedback: Die Differenz-zur-Faelligkeit (z.B. -13.5 T) war unintuitiv (Kopfrechnen noetig) und "(spaeter als ueblich)" hat die Widget-Spalte gesprengt. - Prognosedatum jetzt am RECHNUNGSDATUM verankert: datef + Oe Tage nach Rechnungseingang (avg_pay). Das ist die klassische Days-to-Pay-Kennzahl, vermeidet Prognosen vor dem Rechnungsdatum und ist direkt lesbar. - Sichtbare Zahl = "Oe X T nach Rechnung" (positiv) statt Differenz zur Faelligkeit. Ampel-Icon bleibt auf der Faelligkeits-Skala (diff) -> weiter Paritaet zur Zahlungsverhalten-Box der Kundenkarte. - "(spaeter als ueblich)" als Text entfernt: bei verstrichener Prognose wird stattdessen nur das DATUM rot gefaerbt (Zeile bleibt schmal), Erklaerung steckt im Tooltip. - getZahlprognose liefert zusaetzlich avg_pay; buildPrognoseCell bekommt das Rechnungsdatum durchgereicht. Neuer Lang-Key MahnungProgNachRechnung, Tooltip umformuliert. Lokal gegen die Test-DB verifiziert (Datum aus datef+avg_pay, Rot nur bei verstrichener Prognose, Zukunfts-Rechnung ohne Rot, php -l sauber). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4997a78599
commit
fdd2b17ab4
5 changed files with 49 additions and 30 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -3,12 +3,12 @@
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Widget (box_mahnung_offen)
|
### Widget (box_mahnung_offen)
|
||||||
- **Neue Spalte „Vsl. Zahlung" (Zahlungsprognose)**: Je offener Rechnung wird aus dem bisherigen Zahlungsverhalten des Kunden prognostiziert, wann er die Rechnung voraussichtlich zahlt (`Fälligkeit + round(Ø-Verzug)`), inkl. Ampel-Icon + Bewertungsstufe + Ø-Verzug + Stichprobengröße `n`.
|
- **Neue Spalte „Vsl. Zahlung" (Zahlungsprognose)**: Je offener Rechnung wird prognostiziert, wann der Kunde sie voraussichtlich zahlt — als **konkretes Datum** plus der direkt lesbaren Kennzahl **„Ø X T nach Rechnung"** (Days-to-Pay). Zweizeilige Zelle: Ampel-Icon + Prognosedatum / darunter `Ø <Tage> nach Rechnung · n=<Stichprobe>`.
|
||||||
- **Skala 1:1 aus dem BuchhaltungsWidget** übernommen (KB #886), damit die Ampel zur „Zahlungsverhalten"-Box auf der Kundenkarte passt: `diff = Ø(Zahlung−Rechnungsdatum) − Ø(Fälligkeit−Rechnungsdatum)` = Ø Tage nach Fälligkeit; Stufen ≤−5 Vorbildlich ★ / ≤0 Pünktlich ✓ / ≤7 Spätzahler ⚠ / ≤14 Verspätet ⏱ / >14 Problematisch ✗ (gleiche Farben `#28a745/#ffc107/#fd7e14/#dc3545`).
|
- **Prognose am Rechnungsdatum verankert**: `Prognosedatum = datef + Ø(Zahlung − Rechnungsdatum)`. Das ist die intuitive „zahlt X Tage nach Rechnungseingang"-Zahl (positiv, kein Kopfrechnen wie bei einer Differenz zur Fälligkeit) und verhindert Prognosen **vor** dem Rechnungsdatum. Fallback auf `Fälligkeit + diff`, falls `datef` fehlt.
|
||||||
|
- **Ampel-Skala 1:1 aus dem BuchhaltungsWidget** übernommen (KB #886), damit das Icon zur „Zahlungsverhalten"-Box auf der Kundenkarte passt: Bewertung über `diff = Ø Tage nach Fälligkeit`; Stufen ≤−5 Vorbildlich ★ / ≤0 Pünktlich ✓ / ≤7 Spätzahler ⚠ / ≤14 Verspätet ⏱ / >14 Problematisch ✗ (Farben `#28a745/#ffc107/#fd7e14/#dc3545`). Icon = Pünktlichkeit (relativ zur Fälligkeit), sichtbare Zahl = Tage nach Rechnung — beides wie auf der Kundenkarte.
|
||||||
- **Berechnung als self-contained Kopie** (`getZahlprognose()`, 1 Query je Kunde/Request gecacht) — **keine** Laufzeit-Abhängigkeit auf das BuchhaltungsWidget. Filter identisch KB #886: `type IN (0,1,5)`, `fk_statut=2 + paye=1`, `date_lim_reglement IS NOT NULL`, `DATEDIFF`, `entity`.
|
- **Berechnung als self-contained Kopie** (`getZahlprognose()`, 1 Query je Kunde/Request gecacht) — **keine** Laufzeit-Abhängigkeit auf das BuchhaltungsWidget. Filter identisch KB #886: `type IN (0,1,5)`, `fk_statut=2 + paye=1`, `date_lim_reglement IS NOT NULL`, `DATEDIFF`, `entity`.
|
||||||
- Prognosedatum bereits verstrichen, Rechnung aber noch offen → Zusatz „(später als üblich)" — der Kunde zahlt langsamer als sein eigenes Muster (Frühwarnung; greift ggf. schon **vor** der formellen Fälligkeit, ist also bewusst nicht mit „überfällig" beschriftet).
|
- **Verstrichene Prognose** (Rechnung noch offen, zahlt langsamer als sein Muster) → das **Prognosedatum wird rot** eingefärbt statt mit Zusatztext beschriftet (hält die Widget-Spalte schmal); die Erläuterung („später als üblich") steht im Tooltip.
|
||||||
- Prognosedatum + Ø-Verzug aus dem **exakten** Mittelwert (eine Nachkommastelle), damit die Zahl 1:1 zur „Differenz" auf der Kundenkarte passt (z.B. −3.1 T).
|
- Mindest-Stichprobe via Konstante `MAHNUNG_PROGNOSE_MIN_N` (**Default 1** = Parität zur Kundenkarten-Box, die ebenfalls ab der 1. bezahlten Rechnung bewertet), darunter „keine Historie". Neue Lang-Keys `MahnungProg*` (de_DE + en_US).
|
||||||
- Mindest-Stichprobe fürs Datum via Konstante `MAHNUNG_PROGNOSE_MIN_N` (**Default 1** = Parität zur Kundenkarten-Box, die ebenfalls ab der 1. bezahlten Rechnung bewertet), darunter „keine Historie". Neue Lang-Keys `MahnungProg*` (de_DE + en_US).
|
|
||||||
- **Summenzeile Netto + Brutto**: Die `liste_total`-Zeile zeigt jetzt zweizeilig **Netto** (`SUM(f.total_ht)`) und **Brutto** (`SUM(f.total_ttc)`). Der Bruttobetrag kommt direkt aus `f.total_ttc` der Rechnung und wird **nicht** aus dem Netto hochgerechnet — so bleiben Steuer-Sonderregelungen (Reverse-Charge §13b, Steuerbefreiung, Kleinunternehmer §19 UStG) korrekt. Einzelzeilen zeigen weiterhin nur Netto. Neue Lang-Keys `MahnungBoxNetto`/`MahnungBoxBrutto` (de_DE + en_US).
|
- **Summenzeile Netto + Brutto**: Die `liste_total`-Zeile zeigt jetzt zweizeilig **Netto** (`SUM(f.total_ht)`) und **Brutto** (`SUM(f.total_ttc)`). Der Bruttobetrag kommt direkt aus `f.total_ttc` der Rechnung und wird **nicht** aus dem Netto hochgerechnet — so bleiben Steuer-Sonderregelungen (Reverse-Charge §13b, Steuerbefreiung, Kleinunternehmer §19 UStG) korrekt. Einzelzeilen zeigen weiterhin nur Netto. Neue Lang-Keys `MahnungBoxNetto`/`MahnungBoxBrutto` (de_DE + en_US).
|
||||||
- **Zähler im Kopf**: Der Badge im Widget-Kopf zeigt die tatsächliche Gesamtzahl offener Rechnungen (verlinkt auf die gefilterte Rechnungsliste). Titel-Lang-Key ohne `(%s)`.
|
- **Zähler im Kopf**: Der Badge im Widget-Kopf zeigt die tatsächliche Gesamtzahl offener Rechnungen (verlinkt auf die gefilterte Rechnungsliste). Titel-Lang-Key ohne `(%s)`.
|
||||||
- **Zeilenanzahl konfigurierbar** via Konstante `MAHNUNG_BOX_MAXLINES` (Admin-Select in `setup.php`: Alle/5/10/20/30/50, Default `0` = alle). Widget lädt immer alle offenen Rechnungen (korrekter Zähler), rendert aber nur `MAHNUNG_BOX_MAXLINES` Zeilen + eine `...`-Überlaufzeile.
|
- **Zeilenanzahl konfigurierbar** via Konstante `MAHNUNG_BOX_MAXLINES` (Admin-Select in `setup.php`: Alle/5/10/20/30/50, Default `0` = alle). Widget lädt immer alle offenen Rechnungen (korrekter Zähler), rendert aber nur `MAHNUNG_BOX_MAXLINES` Zeilen + eine `...`-Überlaufzeile.
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ Dolibarr Custom-Modul: 3-stufiges Mahnwesen nach BGB §288 + Versand-Tracking +
|
||||||
- **Zeilenanzahl konfigurierbar** via Konstante `MAHNUNG_BOX_MAXLINES` (Admin-Select in `setup.php`: Alle/5/10/20/30/50, Default `0` = alle). Widget lädt IMMER alle offenen Rechnungen (für den korrekten Zähler), rendert aber nur `MAHNUNG_BOX_MAXLINES` Zeilen + eine `...`-Überlaufzeile. **Nicht** auf das von Dolibarr übergebene `$max` verlassen — das kommt aus `MAIN_SIZE_SHORTLIST_LIMIT` (Default 5) und gilt global für ALLE Home-Boxen. (KB #598)
|
- **Zeilenanzahl konfigurierbar** via Konstante `MAHNUNG_BOX_MAXLINES` (Admin-Select in `setup.php`: Alle/5/10/20/30/50, Default `0` = alle). Widget lädt IMMER alle offenen Rechnungen (für den korrekten Zähler), rendert aber nur `MAHNUNG_BOX_MAXLINES` Zeilen + eine `...`-Überlaufzeile. **Nicht** auf das von Dolibarr übergebene `$max` verlassen — das kommt aus `MAIN_SIZE_SHORTLIST_LIMIT` (Default 5) und gilt global für ALLE Home-Boxen. (KB #598)
|
||||||
- **Empty-State Pflicht**: bei `$num == 0` Platzhalter-Zeile in `info_box_contents` einfügen — sonst rendert `ModeleBoxes::showBox()` gar nichts und das Widget verschwindet komplett (auch nach neuen Rechnungen sieht der User es nicht zurückkommen). Siehe KB #682.
|
- **Empty-State Pflicht**: bei `$num == 0` Platzhalter-Zeile in `info_box_contents` einfügen — sonst rendert `ModeleBoxes::showBox()` gar nichts und das Widget verschwindet komplett (auch nach neuen Rechnungen sieht der User es nicht zurückkommen). Siehe KB #682.
|
||||||
- **Summenzeile Netto+Brutto**: Betragszelle der `liste_total`-Zeile zeigt zweizeilig Netto (`SUM(f.total_ht)`) und Brutto (`SUM(f.total_ttc)`). Brutto kommt direkt aus `f.total_ttc` der Rechnung, NICHT aus Netto × Steuersatz hochgerechnet — sonst wären Reverse-Charge §13b, Steuerbefreiung und Kleinunternehmer §19 UStG falsch. Lang-Keys `MahnungBoxNetto`/`MahnungBoxBrutto`.
|
- **Summenzeile Netto+Brutto**: Betragszelle der `liste_total`-Zeile zeigt zweizeilig Netto (`SUM(f.total_ht)`) und Brutto (`SUM(f.total_ttc)`). Brutto kommt direkt aus `f.total_ttc` der Rechnung, NICHT aus Netto × Steuersatz hochgerechnet — sonst wären Reverse-Charge §13b, Steuerbefreiung und Kleinunternehmer §19 UStG falsch. Lang-Keys `MahnungBoxNetto`/`MahnungBoxBrutto`.
|
||||||
- **Spalte „Vsl. Zahlung" (Zahlungsprognose)**: `getZahlprognose()`/`buildPrognoseCell()`/`prognoseRating()`. Skala + Berechnung sind eine **self-contained Kopie aus BuchhaltungsWidget** (`getPaymentStatistics()`), Referenz **KB #886** — bei Skala-Änderungen BEIDE Module synchron halten (Schwellen ≤−5/≤0/≤7/≤14, Farben `#28a745/#ffc107/#fd7e14/#dc3545`, Filter `type IN (0,1,5)` + `fk_statut=2`+`paye=1`+`date_lim_reglement IS NOT NULL`). `diff = Ø(Zahlung−Rechnungsdatum) − Ø(Fälligkeit−Rechnungsdatum)`; Prognosedatum = `Fälligkeit + diff` (exakt, aus dem Timestamp); Mindest-`n` via `MAHNUNG_PROGNOSE_MIN_N` (**Default 1** = Parität zur Kundenkarten-Box). Prognose verstrichen + Rechnung offen → „(später als üblich)" (NICHT „überfällig" — greift ggf. schon vor formeller Fälligkeit). Die **Kundenkarten-Statistik selbst liefert BuchhaltungsWidget** (Hook `tabContentViewThirdparty`) — Mahnung baut dort KEINEN zweiten Block. **`$langs->transnoentities(...)` verwenden** (nicht `trans()`+`sprintf` → leere `%s`; nicht `trans()`+`dol_escape_htmltag` → doppeltes `&`-Encoding).
|
- **Spalte „Vsl. Zahlung" (Zahlungsprognose)**: `getZahlprognose()`/`buildPrognoseCell()`/`prognoseRating()`. Skala + Berechnung sind eine **self-contained Kopie aus BuchhaltungsWidget** (`getPaymentStatistics()`), Referenz **KB #886** — bei Skala-Änderungen BEIDE Module synchron halten (Schwellen ≤−5/≤0/≤7/≤14, Farben `#28a745/#ffc107/#fd7e14/#dc3545`, Filter `type IN (0,1,5)` + `fk_statut=2`+`paye=1`+`date_lim_reglement IS NOT NULL`). Prognosedatum = `datef + avg_pay` (am **Rechnungsdatum** verankert, avg_pay = Ø Tage nach Rechnungseingang), Fallback `Fälligkeit + diff`. Sichtbare Zahl = „Ø X T nach Rechnung" (intuitive Days-to-Pay, NICHT die Differenz zur Fälligkeit — die war zu unintuitiv, Eddy-Feedback). Ampel-Icon aber weiter über `diff = Ø Tage nach Fälligkeit` (Parität zur Kundenkarte). Mindest-`n` via `MAHNUNG_PROGNOSE_MIN_N` (**Default 1**). Prognose verstrichen + Rechnung offen → **Datum wird rot** (kein Zusatztext — sprengt sonst die Spalte; „später als üblich" nur im Tooltip). Die **Kundenkarten-Statistik selbst liefert BuchhaltungsWidget** (Hook `tabContentViewThirdparty`) — Mahnung baut dort KEINEN zweiten Block. **`$langs->transnoentities(...)` verwenden** (nicht `trans()`+`sprintf` → leere `%s`; nicht `trans()`+`dol_escape_htmltag` → doppeltes `&`-Encoding).
|
||||||
|
|
||||||
## Hooks-Stolperfallen
|
## Hooks-Stolperfallen
|
||||||
- **`completeTabsHead`** wird bei jedem Aufruf von `complete_head_from_modules()` getriggert — pro Karte mehrfach (core + external + remove). Filter auf `mode=add` + `filterorigmodule=external`, sonst doppelter Tab. (KB #601)
|
- **`completeTabsHead`** wird bei jedem Aufruf von `complete_head_from_modules()` getriggert — pro Karte mehrfach (core + external + remove). Filter auf `mode=add` + `filterorigmodule=external`, sonst doppelter Tab. (KB #601)
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,7 @@ class box_mahnung_offen extends ModeleBoxes
|
||||||
$objp = $this->db->fetch_object($result);
|
$objp = $this->db->fetch_object($result);
|
||||||
|
|
||||||
$datelimit = $this->db->jdate($objp->datelimit);
|
$datelimit = $this->db->jdate($objp->datelimit);
|
||||||
|
$dateinvoice = $this->db->jdate($objp->date);
|
||||||
|
|
||||||
$facturestatic->id = $objp->facid;
|
$facturestatic->id = $objp->facid;
|
||||||
$facturestatic->ref = $objp->ref;
|
$facturestatic->ref = $objp->ref;
|
||||||
|
|
@ -223,7 +224,7 @@ class box_mahnung_offen extends ModeleBoxes
|
||||||
// Spalte 5: Voraussichtliche Zahlung (Prognose aus dem Zahlungsverhalten)
|
// Spalte 5: Voraussichtliche Zahlung (Prognose aus dem Zahlungsverhalten)
|
||||||
$this->info_box_contents[$line][] = array(
|
$this->info_box_contents[$line][] = array(
|
||||||
'td' => 'class="center nowraponall"',
|
'td' => 'class="center nowraponall"',
|
||||||
'text' => $this->buildPrognoseCell((int) $objp->socid, $datelimit),
|
'text' => $this->buildPrognoseCell((int) $objp->socid, $datelimit, $dateinvoice),
|
||||||
'asis' => 1,
|
'asis' => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -359,6 +360,9 @@ class box_mahnung_offen extends ModeleBoxes
|
||||||
if ($o && (int) $o->invoice_count > 0) {
|
if ($o && (int) $o->invoice_count > 0) {
|
||||||
$out = array(
|
$out = array(
|
||||||
'count' => (int) $o->invoice_count,
|
'count' => (int) $o->invoice_count,
|
||||||
|
// avg_pay = Ø Tage nach Rechnungseingang (intuitive "Days to Pay"-Zahl).
|
||||||
|
'avg_pay' => (float) $o->avg_payment_days,
|
||||||
|
// diff = Ø Tage nach Fälligkeit (nur für die Ampel-Bewertung, KB #886).
|
||||||
'diff' => (float) $o->avg_payment_days - (float) $o->avg_due_days,
|
'diff' => (float) $o->avg_payment_days - (float) $o->avg_due_days,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -394,14 +398,20 @@ class box_mahnung_offen extends ModeleBoxes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Baut die HTML-Zelle "Vsl. Zahlung": Ampel-Icon + Prognosedatum + Kurzstatistik.
|
* Baut die HTML-Zelle "Vsl. Zahlung": Ampel-Icon + Prognosedatum + Kurzstatistik.
|
||||||
* Prognosedatum = Fälligkeit + round(diff). Prognose bereits vorbei, Rechnung aber
|
*
|
||||||
* noch offen → Zusatz "(überfällig)" (Kunde zahlt schlechter als sonst).
|
* Prognose = Rechnungsdatum (datef) + Ø Tage nach Rechnungseingang (avg_pay) —
|
||||||
|
* die intuitive "Days to Pay"-Kennzahl. Verstrichenes Prognosedatum bei noch
|
||||||
|
* offener Rechnung → Datum wird rot eingefärbt (kompakt, Erklärung im Tooltip),
|
||||||
|
* KEIN zusätzlicher Text (würde die Widget-Spalte zu breit machen).
|
||||||
|
* Ampel-Icon bleibt auf der Fälligkeits-Skala (diff), damit es zur
|
||||||
|
* "Zahlungsverhalten"-Box der Kundenkarte passt.
|
||||||
*
|
*
|
||||||
* @param int $socid
|
* @param int $socid
|
||||||
* @param int $datelimit Fälligkeit als Unix-Timestamp (jdate)
|
* @param int $datelimit Fälligkeit als Unix-Timestamp (jdate) — Fallback-Anker
|
||||||
|
* @param int $dateinvoice Rechnungsdatum (datef) als Unix-Timestamp (jdate)
|
||||||
* @return string HTML (wird 'asis' gerendert)
|
* @return string HTML (wird 'asis' gerendert)
|
||||||
*/
|
*/
|
||||||
private function buildPrognoseCell($socid, $datelimit)
|
private function buildPrognoseCell($socid, $datelimit, $dateinvoice)
|
||||||
{
|
{
|
||||||
global $langs;
|
global $langs;
|
||||||
|
|
||||||
|
|
@ -422,27 +432,34 @@ class box_mahnung_offen extends ModeleBoxes
|
||||||
$rating = $this->prognoseRating($prog['diff']);
|
$rating = $this->prognoseRating($prog['diff']);
|
||||||
$label = $langs->transnoentities($rating['labelkey']);
|
$label = $langs->transnoentities($rating['labelkey']);
|
||||||
|
|
||||||
// Prognosedatum aus dem EXAKTEN Ø-Verzug (gleiche Zahl wie "Differenz" auf der
|
// Prognosedatum = Rechnungsdatum + Ø Tage nach Rechnungseingang. Verankerung am
|
||||||
// Kundenkarte); Anzeige mit einer Nachkommastelle, damit z.B. −3.1 exakt passt.
|
// Rechnungsdatum (statt Fälligkeit) ist intuitiv und vermeidet Prognosen VOR dem
|
||||||
|
// Rechnungsdatum. Fallback auf Fälligkeit + diff, falls datef fehlt.
|
||||||
|
if ((int) $dateinvoice > 0) {
|
||||||
|
$progTs = (int) round((int) $dateinvoice + $prog['avg_pay'] * 86400);
|
||||||
|
} else {
|
||||||
$progTs = (int) round((int) $datelimit + $prog['diff'] * 86400);
|
$progTs = (int) round((int) $datelimit + $prog['diff'] * 86400);
|
||||||
|
}
|
||||||
$progDate = dol_print_date($progTs, 'day', 'tzuserrel');
|
$progDate = dol_print_date($progTs, 'day', 'tzuserrel');
|
||||||
$avg = sprintf('%+.1f', $prog['diff']); // Vorzeichen: + nach Fälligkeit, − davor
|
$nachRe = sprintf('%.1f', $prog['avg_pay']); // Ø Tage nach Rechnungseingang (i.d.R. positiv)
|
||||||
|
|
||||||
// Prognosedatum bereits verstrichen, Rechnung aber noch offen → der Kunde zahlt
|
// Prognosedatum verstrichen, Rechnung noch offen → zahlt langsamer als sein Muster.
|
||||||
// langsamer als sein eigenes Muster. NICHT dasselbe wie "überfällig" (kann schon
|
// Kompakt: nur das Datum rot färben + Tooltip-Zusatz (kein Extra-Text in der Zelle).
|
||||||
// vor der formellen Fälligkeit greifen) — daher eigene Formulierung.
|
$dateStyle = '';
|
||||||
$hint = '';
|
$tipExtra = '';
|
||||||
if ($progTs < dol_now()) {
|
if ($progTs < dol_now()) {
|
||||||
$hint = ' <span style="color:#dc3545;">('.dol_escape_htmltag($langs->transnoentities('MahnungProgSpaeterAlsUeblich')).')</span>';
|
$dateStyle = ' style="color:#dc3545;"';
|
||||||
|
$tipExtra = ' — '.$langs->transnoentities('MahnungProgSpaeterAlsUeblich');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parameter direkt an trans übergeben (macht das %s-sprintf selbst).
|
// Voller Kontext im Tooltip (Parameter direkt an trans → macht das %s-sprintf selbst).
|
||||||
$tooltip = $langs->transnoentities('MahnungProgTooltip', $progDate, $avg, (string) $prog['count']);
|
$tooltip = $label.': '.$langs->transnoentities('MahnungProgTooltip', $progDate, $nachRe, (string) $prog['count']).$tipExtra;
|
||||||
|
|
||||||
$html = '<span title="'.dol_escape_htmltag($tooltip).'">';
|
$html = '<span title="'.dol_escape_htmltag($tooltip).'">';
|
||||||
$html .= '<span style="color:'.$rating['color'].';">'.$rating['icon'].'</span> ~'.$progDate.$hint;
|
$html .= '<span style="color:'.$rating['color'].';">'.$rating['icon'].'</span> ';
|
||||||
$html .= '<br><span class="opacitymedium small">'.dol_escape_htmltag($label)
|
$html .= '<span'.$dateStyle.'>~'.$progDate.'</span>';
|
||||||
.' · Ø '.$avg.' T · n='.((int) $prog['count']).'</span>';
|
$html .= '<br><span class="opacitymedium small">Ø '.$nachRe.' '
|
||||||
|
.dol_escape_htmltag($langs->transnoentities('MahnungProgNachRechnung')).' · n='.((int) $prog['count']).'</span>';
|
||||||
$html .= '</span>';
|
$html .= '</span>';
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,8 @@ MahnungProgProblematisch = Problematisch
|
||||||
MahnungProgKeineHistorie = keine Historie
|
MahnungProgKeineHistorie = keine Historie
|
||||||
MahnungProgKeineHistorieTip = Zu wenig bezahlte Rechnungen für eine belastbare Zahlungsprognose
|
MahnungProgKeineHistorieTip = Zu wenig bezahlte Rechnungen für eine belastbare Zahlungsprognose
|
||||||
MahnungProgSpaeterAlsUeblich = später als üblich
|
MahnungProgSpaeterAlsUeblich = später als üblich
|
||||||
MahnungProgTooltip = Voraussichtlich am %s (im Schnitt %s Tage zur Fälligkeit, %s bezahlte Rechnungen)
|
MahnungProgNachRechnung = T nach Rechnung
|
||||||
|
MahnungProgTooltip = voraussichtlich am %s — zahlt Ø %s Tage nach Rechnungseingang (%s bezahlte Rechnungen)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Dokumentenmodelle
|
# Dokumentenmodelle
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,8 @@ MahnungProgProblematisch = Problematic
|
||||||
MahnungProgKeineHistorie = no history
|
MahnungProgKeineHistorie = no history
|
||||||
MahnungProgKeineHistorieTip = Too few paid invoices for a reliable payment forecast
|
MahnungProgKeineHistorieTip = Too few paid invoices for a reliable payment forecast
|
||||||
MahnungProgSpaeterAlsUeblich = later than usual
|
MahnungProgSpaeterAlsUeblich = later than usual
|
||||||
MahnungProgTooltip = Expected on %s (on average %s days relative to due date, %s paid invoices)
|
MahnungProgNachRechnung = d after invoice
|
||||||
|
MahnungProgTooltip = expected on %s — pays on average %s days after invoice date (%s paid invoices)
|
||||||
MahnungVorschlagStufeNichtKonfiguriert = Stage 1 not configured
|
MahnungVorschlagStufeNichtKonfiguriert = Stage 1 not configured
|
||||||
MahnungVorschlagFristNichtErreicht = Stage 1 deadline (%s days) not yet reached (overdue %s days)
|
MahnungVorschlagFristNichtErreicht = Stage 1 deadline (%s days) not yet reached (overdue %s days)
|
||||||
MahnungVorschlagAlleStufenAusgeschoepft = All dunning stages exhausted (last stage %s)
|
MahnungVorschlagAlleStufenAusgeschoepft = All dunning stages exhausted (last stage %s)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue