Commit graph

46 commits

Author SHA1 Message Date
60f9985313 Kunden loeschen: Modal mit Komplett- oder DSGVO-Loeschung ueber alle Dubletten
Ticket dev/_tickets/2026-09-08.md #2:
- "Kunde loeschen" oeffnet ein Modal statt direkt per GET zu loeschen. Es
  zeigt alle Eintraege desselben Kunden (Kundennummer oder E-Mail, ohne
  Platzhalter-Adressen) mit Anzahl Bestellungen.
- Ohne Bestellungen: Komplett-Loeschung (anonymisiert und soft-geloescht,
  Portal-Logins und Stripe-Kunden entfernt, Zahlungs-Tokens inaktiver Abos
  geleert). Mit Bestellungen nur DSGVO-Loeschung (Superadmin); die arbeitet
  jetzt ebenfalls auf der E-Mail-Gruppe und entfernt Portal-Logins.
- Bei aktivem Abo oder Berater-Datensatz wird abgelehnt.
- Die alte "Loeschung" (CustomerRepository::deleteCustomer) entfaellt.
- Fehlermeldungen nutzen alert-error; alert-danger zeigte kein Layout an.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 15:43:35 +00:00
316a9b76d6 Pint: Formatierung des bisherigen Stands, ohne inhaltliche Aenderung
Die Dateien lagen im Arbeitsbaum formatiert und inhaltlich geaendert
zusammen. Dieser Commit enthaelt nur die Pint-Formatierung des alten
Stands, damit die folgenden Commits nur noch Inhalt zeigen.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 15:39:17 +00:00
03416b0afe Audit 18.09.: Zahlungsdatum nur bei Zahlung, Neupartner-IDs im Snapshot, Pausenende folgt dem Termin
F1: partner_paid_at wird beim Rechnungskauf (paymentStatusPaidAction mit
paid=false) nicht mehr gesetzt, sondern erst bei der Rechnungszahlung; der
Backfill nimmt das Aktivierungsdatum nur noch ohne jede
Registrierungsbestellung (offene Rechnung bleibt leer).
F2: Snapshots speichern je Linie new_partner_ids, die Neupartner-Liste zeigt
genau diese; aeltere Snapshots ohne IDs rechnen mit der damaligen Regel
(Registrierungsmonat, scopeNewPartnerInByActiveDate), damit Kachel und Liste
uebereinstimmen. Keine Payload-Versionsaenderung, kein Neuaufbau noetig.
F3: Liefertag-/Termin-Aenderung waehrend einer Pause zieht paused_until mit;
eine Ausfuehrung loescht auch den paused_by_*-Grund.
F4: expiredCount der Firstlines-Seite (Controller, View, Sprachen) zum bereits
committeten Test nachgezogen.
F5: Backfills schreiben ohne updated_at (toBase()->update, timestamps=false).
Kuendigungsbestaetigung abo_cancel_confirm wird im Selfservice serverseitig
verlangt. AboStatusExplainer laedt die Historie je Abo und Aktion nur einmal.

Stellungnahme und Deploy-Folgen im Audit-Dokument, Regressionstests je Befund.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 08:59:45 +00:00
cf0311afc1 Abo (A1+A2): Liefertag frei waehlbar 1-31, Aenderung nur nach vorn, Sperre erst am Ausfuehrungstag
A1: Jeder Monatstag ist als Liefertag erlaubt (UserAbo::allowedDeliveryDays),
Tage 29-31 liefern in kuerzeren Monaten am letzten Tag. Eine Stelle
AboHelper::dateForDayInMonth klammert; setNextDate, Erstausfuehrung,
Admin-Termin und Pause rechnen darueber, der Folgemonat immer aus dem
Liefertag (31.01 -> 28.02 -> 31.03). Liefertag-Aenderung gilt fuer den
laufenden Zyklus und nur nach vorn: ist der Tag im Referenzmonat vorbei,
wird abgelehnt, der Monat verschiebt sich nie (Rueckfrage R1).
Admin-Filter "naechste Ausfuehrung" als Datumsbereich. Prognose-Kacheln
bekommen die Kachel Monatsende, Team-Abos rechnen bis Monatsende.

A2: Sperrfristen Default 0, Setting 0 ist ausdruecklich 0 (fiel bisher auf
den Default zurueck). Bedingung Kalendertage <= Sperre, zentral in
AboHelper::isWithinLock: am Ausfuehrungstag ab 0:00 Uhr fixiert, Vortag bis
23:59 Uhr frei, fuer Liefertag, Produkte, Pause und Kuendigung (R2). Texte
mit _zero-Varianten ueber AboHelper::lockMessage.

Sprachdateien de/en/es/fr, neuer AboDeliveryDayTest, bestehende Tests
angepasst, Plan-Status mit Deploy-Schritt (Settings auf 0).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 11:28:55 +00:00
d6efe56cd4 Abo (A3): Status und Grund eines Abos sichtbar machen
Neue Spalten user_abos.status_reason / paused_until und
user_abo_orders.error_message. Der Grund wird zentral am Model gepflegt
(saving-Event): Zahlungsfehler, Kuendigung/Deaktivierung mit Akteur aus dem
Formular-Kanal, Loeschen beim Zurueckkehren in den Lauf; die Pause setzt
paused_until und paused_by_*. Cron- und Retry-Zahlung schreiben den Fehlertext
des Anbieters an die Abo-Bestellung.

AboStatusExplainer uebersetzt das in einen Satz ("Pausiert bis ... vom Kunden
am ...", "Zahlung am ... fehlgeschlagen - Grund: ...", "Gekuendigt am ... vom
Berater"), Partial _status_explain in Abo-Detail (CRM, Portal, Admin),
Abo-Uebersicht, Kundenabo-Liste, Team-Kundenabos und Admin-Datatable; dort
neuer Filter "Zustand" (pausiert / Zahlung fehlgeschlagen). Backfill-Kommando
abo:backfill-status-reasons fuer Bestandsdaten, Fallback ueber das
Statusprotokoll und die Pausenfelder.

Sprachdateien de/en/es/fr, Tests in AboStatusExplainTest, Plan-Status.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 10:24:18 +00:00
e8057f9f7b Abo (A4): Abschnitt "Abo pausieren oder kuendigen" mit Kuendigungs-Hinweis
Eigener Abschnitt auf der Abo-Seite (CRM me/ot und Kundenportal) mit
Fortschritt zur Mindestlaufzeit, Pause und Kuendigung. Die Kuendigung laeuft
ueber ein Modal, das die Folgen nennt (Abo endet, Konditionen entfallen, ein
neues Abo hat wieder 6 Pflichtlieferungen), die Pause als Alternative anbietet
und erst nach Bestaetigungs-Checkbox freigibt. Innerhalb der Sperrfrist vor
der Ausfuehrung erscheint statt der Buttons ein Hinweis
(AboHelper::isPauseCancelLocked). Das Einstellungs-Modal verweist nur noch
auf den Abschnitt. Die Kuendigung im Repository ist jetzt wie die Pause eine
eigenstaendige Aktion: Erfolgsmeldung statt Liefertermin-Hinweis, next_date
bleibt unangetastet.

Sprachdateien de/en/es/fr, Tests in AboPauseCancelSectionTest, Plan-Status.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 10:14:51 +00:00
5a38f4ac3e Statistik: uebrige Audit-Korrekturen (Abo-Regeln, Prognose, Sortierung)
A01 — Abo-Regeln waren ueber das Aktiv-Feld umgehbar. Das
Selbstbedienungsformular hat gar keinen Aktiv-Schalter, es spiegelt den Zustand
nur in einem versteckten Feld zurueck; `updateStatus()` hat den Wert trotzdem
uebernommen. Wer den Request manipulierte, konnte sein eigenes Abo dauerhaft
deaktivieren und so die Mindestlaufzeit umgehen, am Pausenpfad mit seinen
Sperren vorbei. Das Feld wirkt jetzt nur noch im Admin-Pfad.

A16 — Statuswechsel wurden nur aus dem Formular protokolliert. Recovery-Zahlung,
Retry, externe Erledigung und die DSGVO-Anonymisierung schreiben `active` direkt
auf das Modell. Das ist heikel, weil die historische Bestandsrueckrechnung ein
Abo verwirft, solange eine protokollierte Deaktivierung nicht durch eine
spaetere protokollierte Reaktivierung aufgehoben ist — ein stiller
`active = true` nimmt es dauerhaft aus allen Folgemonaten.

Der Eintrag liegt deshalb jetzt am Model (`UserAbo::logStatusTransition()`) und
nicht in den einzelnen Diensten: so kann ihn ein kuenftiger Schreibpfad nicht
vergessen, und er entsteht in derselben Transaktion wie die Statusaenderung.
Nebeneffekt: Die DSGVO-Anonymisierung setzt `active = false` ohne `cancel_date`
— bisher fiel ein so abgeschaltetes Abo rueckwirkend aus allen vergangenen
Monaten, jetzt bleibt die Historie korrekt.

A13 — Ein heute faelliges Abo galt ab Mitternacht als erledigt, der
Ausfuehrungsjob laeuft aber erst um 04:00. In diesem Fenster fehlten die Punkte
in der Prognose UND im Ist. Der neue Scope `UserAbo::scopeOpenExecutionUntil()`
zaehlt den heutigen Liefertag mit, solange keine Ausfuehrung angelegt ist —
genau diese Bedingung verhindert die Doppelzaehlung. Alle drei Prognosen nutzen
jetzt denselben Scope statt je einer eigenen Kopie der Datumsregel.

A11 — Der Namens-Tiebreak der Top 3 lief nach dem Abschneiden auf 25
Kandidaten, bei Gleichstand entschied also die Reihenfolge der Abfrage. Die
Auswahlgrenze wird jetzt um alle Gleichstaende an dieser Grenze erweitert, und
Kandidaten ohne Account fallen vorher weg statt die Plaetze zu blockieren. Als
letzte Regel entscheidet die user_id, damit eine gecachte Rangliste
reproduzierbar bleibt.

A14 — Sortiert wurde ueber den angezeigten Zellentext. Unter `en` liefert die
Anwendung `Y-m-d` und `1,000.00`, damit ergab jedes Datum 0 und `1,000.00` wurde
zur 1. Die Zellen tragen jetzt `data-sort-value` mit dem unformatierten Wert;
ohne Attribut gilt weiter der Textweg. Dabei mitgenommen: Umlaute landeten hinter
dem Z (jetzt localeCompare), leere Werte lagen als 0 zwischen den negativen
Stornowerten, und `next_date` wurde doppelt formatiert.

Ausserdem A08 (Prognose auch ohne erreichte Qualifikationsstufe), A09
(Summenzeile im Neupartner-CSV), A10 (Lieferungszahl vorgeladen), A17
(Faelligkeitsgruppen ohne Monatsueberlauf), A18 (Formelinhalte im CSV als Text)
und A19 (fehlgeschlagene Provisionsberechnung ist als solche erkennbar statt
0,00 EUR).

Audit-Befunde A01, A08, A09, A10, A11, A13, A14, A16, A17, A18, A19.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 11:19:38 +00:00
867dc21b57 Statistiken: Kundenfeedback 2026-08-19 komplett (N1-N8) + Review-Fixes + VP-/Incentive-Repair gehärtet
Statistik-Änderungen 2026-08-19 (dev/2026-07-22/entwicklungsplan-2026-08-19.md, alle 8 Pakete gemäß beantworteten F-Fragen):
- N1 Monatsstatistik: Team-Cluster (Firstlines klickbar -> neue Seite user_team_firstlines, Teampartner gesamt/Payline [nur aktive], Abos Payline mit +N) + Level-Kachel (Quali-Stufe, fehlende Payline-/persönliche Punkte, Karriere-Level); LiveCommissionService-Snapshot v3 reicht Level-/Quali-Daten durch
- N2 Abo-Kacheln auf Home monatsbezogen (aboStockCount-Rückrechnung über cancel/deleted/Status-Historie; VIP-Statistik bleibt tagesaktuell)
- N3 VIP-Statistik 'Recruiter des Monats' (Neupartner-Definition wie KPI, rekursives Ketten-Volumen als Gesamtpunkte inkl. Starterpaket) + Drilldown/CSV-Spalte 'Punkte gesamt'
- N4 Prognose-Block 'Level & Provision laut Prognose (Stand 25.)' mit unverbindlich-Kennzeichnung (ebenengenaue offene Abo-Punkte + TP-Laufstände)
- N5 Checkout-Herkunft: Dropdown raus, Pflicht-Freitext (lokalisierte Fehlermeldung)
- N6 Berater-Profilfoto (user_accounts.profile_image, Einwilligung als Sprachkey-Platzhalter, DSGVO-Löschung) + teaminterne Top-3-Karte (TopResultsService, Scope-Schalter)
- N7 USt-Optionen: 'nicht umsatzsteuerpflichtig' zuerst + '§ 19 UStG'-Textfix
- N8 Jahresgebühr-Nachfassliste je Berater (AnnualFeeDueService, überfällig/1-3 Monate, Sidenav)

Kontroll-Review (8 Perspektiven) angewendet: next-Level-Fallback im Steady-State (resolveNextLevel — sonst 'Höchstes Level erreicht' für Normalfälle), _calculated-Punktebasis bei mehr Paylines, keine Wiederbelebung deaktivierter Abos in der Monatsrückrechnung, Payline-Abo-Kachel monatskonsistent, Top-3-Nachrücker; Performance: BackofficeDashboardService als Singleton mit lineBuckets-Memo (+flushLineBucketsMemo), level_forecast 6h-Cache; Reuse: User-Scopes firstlinesOf/newPartnerIn, SalesVolumePoints::totalPointsByUser, Slim::storeCroppedImage (3 Upload-Kopien vereinigt), activeAbo-Scope statt Inline-Prädikate, Form::open-Konvention, Return-Types

Repair-Härtung (Kundenentscheide): VP-Nachtrepair dedupliziert über shopping_order_id (Live-Pfad schreibt sie jetzt mit), zählende Alt-Zeilen-Erkennung, Vormonats-Scan für Monatswechsel, Firmenaccount-Buchungen (config mivita.company_user_id) werden automatisch auf den Berater umgebucht (in place bzw. per Gegenbuchung bei geschlossenem Monat; Echtfall Anna Schall Order 58797 -> Christina Schuder), Berater-zu-Berater nur Warnung; Incentive-Repair: m_sponsor=NULL löscht nicht mehr, FK-Repair vor Stale-Bereinigung, gebatchte Lookups, zentrales Incentive::qualificationWindow(); .env aus dem Git-Tracking entfernt (Pflege per SFTP)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 10:44:44 +00:00
ac3bd6e8ea Statistiken/Abo: Kundenfeedback 2026-07-24 komplett umgesetzt + Steuern: DATEV-Fixes 08+09/2025 (Sammel-Commit Branch-WIP)
Feedback-Umsetzung (dev/2026-07-22/feedback-analyse-2026-07-24.md, alle 10 Punkte):
- VIP-Statistik: eigener Berater ('ich', Linie 0) in Neue-Kundenabos- und beiden Top-10-Listen; Top-10-Umsatz sortiert nach abgerechneten Ist-Punkten + Abo-Anzahl-Spalte; Fußnote nicht-payline-wirksame Punkte (SalesVolumePoints::nonPaylinePoints)
- Führungskräfte-Liste: beide Sichten 'direkt' (an nächster FK abgeschnitten, additiv) und 'gesamt' (komplette Downline), Gesamt-Spalte nach Kundenzählweise
- Team-Abos: je Ebene 'abgerechnet (Monat)' und 'bis zum 25. erwartet'; Payline-Karte mit Teamabo-/Kundenabo-Zählern
- Incentive-Live-Ranking: Qualifizierte zuerst nummeriert (fixt auch isWinner rank<=max_winners)
- Porto: Netto-/Brutto-Kennzeichnung (Berater netto, Endkunden inkl. MwSt., portal_view-Flag; auch CRM-/Shop-Warenkorb + Checkout), Yard::shipping_tax-Fix
- Struktur-Ansicht: Abo-Badges 'A' (eigenes Abo) und '(n)' (Kundenabos) je Teampartner, gebatcht
- Abo-Löschung: Softdelete setzt active=0 (UserAbo deleting-Hook) + Bereinigungs-Migration für gelöschte-aber-aktive Abos
- Doku: technische Analyse + Kundinnen-Feedback-Dokument unter dev/2026-07-22/
- Tests: IncentiveRankingTest, TeamStructureAboBadgesTest, YardShippingTaxTest (neu); BackofficeStatisticsListsTest, TeamAboOverviewTest, PaylineForecastServiceTest, AboAdminDeleteTest, AboOneTimeViewTest erweitert

Außerdem enthalten (Branch-WIP vor dem Feedback): DATEV-Abgleich-Fixes 08+09/2025, USt-ID-Live-Validierung sowie restliche unkommittete Stände (u. a. Abo-Pause-Sprachkeys).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 13:56:02 +00:00
cdb121fde0 Abo: Einmalprodukte bereits bei der Abo-Anlage + es/fr-Sprachsync
Einmalprodukte (Normalsortiment, show_on 3) können jetzt schon beim
Abo-Abschluss hinzugefügt werden – im Portal-Wizard (Abschnitt im
Upgrade-Schritt) und in allen drei Sales-Center-Abo-Strecken (eigene
Produktliste). Variante A: Zeilen laufen als Cart-Option abo_addon mit
durch den Checkout, werden sofort bezahlt und mit der Erstlieferung
verschickt (Rechnung/Lieferschein gruppieren automatisch).

- Checkout persistiert is_abo_addon (CheckoutRepository, PaymentHelper)
- createAboItems/ensureUserAboItemsFromLatestOrder überspringen Addons
  (sonst würden Einmalprodukte dauerhaft wiederkehren); amount ohne
  Addon-Anteil; aboHasBaseProduct ignoriert Addon-Zeilen
- CreateAboReplacementOrder propagiert is_abo_addon in Ersatzbestellungen
- iq-shopping-cart.js: zweite Datatable + abo_addon-Flag-Weitergabe
- i18n: neue abo.onetime_create_*-Keys (de/en/es/fr); zusätzlich es/fr
  komplett synchronisiert (abo-Kartenblock, navigation, payment,
  weborder inkl. Entfernung PAYONE-Altlasten, withdrawal.php neu)
- Tests: AboCreateOneTimeItemsTest, AboCreateOneTimeCartTest,
  AboPortalCreateOneTimeTest (17 neue, 122 Tests gesamt grün)

Plan: dev/2026-07-21-abo-einmalprodukte-anlage/

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 14:36:40 +00:00
1e7ae92d0c Stornorechnung: Fix überdeckte Artikelzeile + Regenerate-Command
Der ACHTUNG-Hinweiskasten hat wegen fixer 15mm-Höhe des Titel-Blocks
den Tabellenkopf und die erste Artikelzeile überdeckt (z.B. Artikel
5010400 auf den Stornos zu Bestellung 56965/56966). Titel-Block wächst
jetzt mit dem Inhalt.

Neuer Command sales:regenerate-cancellation-pdf erzeugt die PDFs
bestehender Stornorechnungen neu (gleiche Nummer/Pfade, keine
Punktebuchung, keine Mails) – per Rechnungs-ID oder mit --order per
Bestell-ID.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:19:28 +00:00
6f21845607 Stripe-Integration (S0–S3): Einmalzahlungen über Stripe Checkout + Notfall-Go-Live
Wegen PAYONE-Ausfall vorgezogen live geschaltet: alle Einmalzahlungen
(Shop + Salescenter) laufen über Stripe Hosted Checkout, Abos sind bis
Phase S4 eingefroren.

- Provider-Abstraktion: PaymentProvider-Enum, PaymentGatewayInterface,
  PaymentProviderManager (Settings-Schalter, provider-treu je Bestand),
  PayoneGateway als unveränderter Adapter
- StripePaymentService: Checkout Session (eine Gesamtposition, Metadata,
  success/cancel-Redirects), StripeClientWrapper (lazy, Dark Launch),
  StripeCustomerService, StripeTransactionRecorder (client_secret-Redaction)
- Webhook /stripe/webhook: Signaturprüfung, Idempotenz über
  stripe_webhook_events (Crash-Retry-Reprocessing), txaction-Prioritäten,
  Betrags-Guard, lockForUpdate-Paid-Pfad, genau eine Bestätigungsmail
- Zahlungsmethoden-Anzeige aus charge.succeeded (carddata inkl. Wallet,
  auftragsunabhängiges Backfill aus dem Event-Store)
- Checkout: Wartungsmodus mit Admin-Bypass, Abo-Freeze-Hinweis,
  Stripe-Option (Online-Zahlung) statt Zahlartenwahl, Vorkasse ausblendbar
- Abo-Freeze-Guards: Cron user:make_abo_order, Retry, Kartenupdate
- Admin-Settings-Karte Zahlungen (Provider, Wartung, Freeze, Vorkasse)
- Hotfix: 500 bei Vorkasse ohne Clearing-Daten in admin/sales/_detail
  und checkout-final (PAYONE-Ausfall)
- Doku dev/2026-07-08-stripe/ (Plan S0–S8, Konzept, IST-Analyse)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 15:56:41 +00:00
0660f4e0a0 Abo-Recovery: fehlgeschlagene Folgezahlung im Checkout nachholen
- Pay-now-Flow: bei fehlgeschlagenem Abo (Status 3) begleicht der Inhaber die
  offene Rechnung im Standard-Checkout mit frei waehlbarer, abo-faehiger Zahlart
  (nur eigenes Abo: Berater me-View + Kundenportal), payNow-Controller + Routen
- AboRecoveryCheckoutService baut die ShoppingInstance aus den Abo-Artikeln;
  neue Spalte shopping_orders.recovery_user_abo_id verknuepft Bestellung<->Abo
- Bei Erfolg: AboHelper::advanceAboAfterRecoveryPayment schreibt das Abo fort
  (Status->2, next_date) und uebernimmt die gewaehlte Zahlart als neues Token
  fuer kuenftige Abbuchungen
- Neue Pay-now-Fehlermail (AboPaymentFailedMail) ersetzt die generische
  Fehlermail im Abo-Cron; Link fuehrt auf die Abo-Detailseite (CRM bzw. Portal)
- Retry-/"extern erledigt"-Buttons nur noch fuer Admins; tote user/portal-
  Retry-Routen entfernt
- Checkout: Recovery-Hinweis statt "Abschluss des Abonnements", Lieferadresse
  vorbelegt, korrekter Zurueck-Link (Abo statt Shop)
- UserAbo::selfServiceDetailUrl zentralisiert die Abo-URL (Mail, Back-Links)
- Test-Command abo:test-recovery; Tests fuer payNow, Advance-Logik, Fehlermail

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 10:38:05 +00:00
65b867f8ee Abo Einmalprodukte: Phasen 5-7, konfigurierbare Sperrfristen, Lokalisierung & Dashboard
Rechnung/Lieferschein:
- PDF-Gruppierung Abo- vs. Einmal-Artikel (is_abo_addon), rueckwaertskompatibel
- Vorschau-Command sales:preview-invoice (umgeht Test-System-Gate, ohne Rechnungsnummer)

Reminder-Mail (vorbereitet, Cron inaktiv):
- MailAboExecutionReminder + Template, abo:send-execution-reminder, Spalte onetime_reminder_sent_for
- Berater -> Sales Center, Kunde -> Portal; Vorschau abo:preview-reminder
- Datum-Fix: formatDateDB() statt formatDate() (ICU-Format)

Sperrfristen konfigurierbar (Admin-Settings):
- abo-lock-days-change (Liefertag + Abo-Produkte), abo-lock-days-pause-cancel
- Meldungen mit :lock-Platzhalter; Pausieren/Kuendigen vom Change-Lock entkoppelt
- Abo-Produkt-Aenderungen im Lock-Fenster server- + clientseitig eingefroren
- Selbstbedienung: Add-only/Lock nach $view (kein Admin-Bypass), Stale-Cache-Fix beim Mengen-Update

Dashboard:
- Einmalprodukte-Card + Team-Abo-KPI-Card, News-Card responsiv (col-xl-6)

Lokalisierung:
- Sprachdateien en/es/fr vollstaendig mit de synchronisiert (inkl. marketingplan/portal)
- LocalizationSyncTest sichert Key-Gleichheit ab

Tests: AboOneTimeInvoiceGrouping, AboExecutionReminder, AboLockDaysSetting,
AboOnetimeDashboardAndMail, PreviewInvoiceCommand, TeamAboOverview + erweiterte View-Tests

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 13:38:11 +00:00
34d8f60bbd User Statistik 2026-05-18 17:23:28 +02:00
a639c4f63c Steuerberater Modul tax 2026-05-08 15:34:57 +02:00
396d049439 10.April 2026 2026-04-10 17:15:27 +02:00
4a8f4b4abc 20-02-2026 2026-02-20 17:55:06 +01:00
7325edebbd 23-01-2026 2026-01-23 17:35:23 +01:00
a67740d6ef update 20.10.2025 2025-10-20 17:42:08 +02:00
Kevin Adametz
3b2253147b commit 08-2025 2025-08-12 18:01:59 +02:00
Kevin Adametz
824fa43e96 Updates to 03-2025 2025-04-01 10:36:47 +02:00
Kevin Adametz
7ec90d7e18 08 2024 2024-08-05 12:05:24 +02:00
Kevin Adametz
3a81b8a0f5 last changes since 6-2023 2023-07-03 10:07:08 +02:00
Kevin Adametz
da10f19fcb Free Shipping, Business Levels correction, Products Buying, Fonts 2023-01-25 12:37:29 +01:00
Kevin Adametz
7f6052acf5 #51 Festschreiben der Points, Gutschriftenmodul 2022-07-29 18:18:05 +02:00
Kevin Adametz
813b30e616 #53, #52, #51 change Points 2022-07-21 10:37:34 +02:00
Kevin Adametz
37371ab31c Sammelbestellung von Extern 2022-07-18 18:07:31 +02:00
Kevin Adametz
77b0bc7c7c API Shopping Order backend 2022-07-15 21:21:56 +02:00
Kevin Adametz
6e5b002ec9 06 2022 2022-06-15 18:08:45 +02:00
Kevin Adametz
c56adb2c40 Update Framework, Invoices 2022-04-14 13:14:36 +02:00
Kevin Adametz
2ffc33dcd6 Custom Price / Land / User Order Homeparty 2021-08-20 18:22:21 +02:00
Kevin Adametz
33dae5adf3 Lieferland UST CH, Reverse Charge 2021-08-03 16:00:01 +02:00
Kevin Adametz
4979c12d9a API work 2021-02-10 10:56:40 +01:00
Kevin Adametz
43c2d121d4 Homparty dev 2020-12-16 20:03:51 +01:00
Kevin Adametz
01242b4690 User Order step1 2020-08-07 16:02:03 +02:00
Kevin Adametz
4bd888e6d6 Customers Add+Edit, API WP 2020-06-12 14:46:51 +02:00
Kevin Adametz
37e00c0eb7 Kundenhoheit 2020-05-06 15:43:53 +02:00
Kevin Adametz
9f7b6561ba Registierung Korrekturen 2020-04-29 20:06:51 +02:00
Kevin Adametz
1e8d5a31cf 01 2020 2020-02-14 10:18:44 +01:00
Kevin Adametz
0142e59c81 leads, sales lists, m_data, orders 2020-01-03 17:44:26 +01:00
Kevin Adametz
80dc93b6b8 Tickets #4, #5, #6 2020-01-02 19:22:30 +01:00
Kevin Adametz
c85ab3cb23 checkout, register, payment,
checkout correction,
register wizard,
payment packege,
2019-03-02 00:08:11 +01:00
Kevin Adametz
7f6f07a778 Your Shop creates, verify user 2019-01-04 18:46:48 +01:00
Kevin Adametz
ed06b7cef7 17 Nov - Static Sites to laravel 2018-11-17 02:01:22 +01:00
Kevin Adametz
a82d449c0a First Commit 2018-10-29 09:39:31 +01:00