Skip to content

Develop#565

Merged
dspangenberg merged 3 commits into
mainfrom
develop
Jul 3, 2026
Merged

Develop#565
dspangenberg merged 3 commits into
mainfrom
develop

Conversation

@dspangenberg

@dspangenberg dspangenberg commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Neue ZUGFeRD-Einstellungen für Rechnungen mit eigener Bearbeitungsseite hinzugefügt.
    • Die Einstellungen sind nun direkt über die Seiten-Navigation unter „Rechnungen“ erreichbar.
    • Verkäuferdaten, Kennungen und eine Dokumentnotiz können jetzt gepflegt werden.
  • Bug Fixes

    • Die Prüfung von Leistungszeiträumen bei Rechnungen wurde korrigiert.
    • Zahlungsinformationen können nun mit einem Zahlungsziel ergänzt werden.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@dspangenberg, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 13 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7318501d-9986-4e5a-b7ee-8617e327a33f

📥 Commits

Reviewing files that changed from the base of the PR and between 4137480 and de20023.

📒 Files selected for processing (5)
  • app/Http/Requests/ZugferdSettingUpdateRequest.php
  • app/Services/ZugferdService.php
  • database/migrations/tenant/2026_07_02_183342_zugferd_settings_update.php
  • resources/js/Components/NavUser.tsx
  • resources/js/Pages/App/Setting/BankAccount/BankAccountIndexColumns.tsx

Walkthrough

Führt eine eigenständige ZUGFeRD-Einstellungsseite ein (Controller, Request, Data-Klasse, Frontend-Formular, Routen, Sidebar-Eintrag) und entfernt die zugferd-Gruppe aus den generischen Admin-Settings. Passt ZugferdSettings-Typen/Casts, Migrationen sowie ZugferdService-Logik für Seller-Daten und Zahlungsziel an. Enthält zudem eine unabhängige Invoice-Korrektur und kleinere Styling-Anpassungen.

Changes

ZUGFeRD-Einstellungen

Layer / File(s) Summary
Entfernen aus Admin-Settings
app/Http/Controllers/Admin/SettingController.php, app/Http/Requests/SettingUpdateRequest.php
Die Gruppe zugferd wird aus settingsCollection, update()-Mapping und der group-Validierung entfernt.
Datenmodell, Casts und Migrationen
app/Data/ZugferdSettingData.php, app/Settings/Casts/IntCast.php, app/Settings/ZugferdSettings.php, database/migrations/tenant/2026_07_02_183342_...php, database/migrations/tenant/2026_07_02_183343_...php
Neue ZugferdSettingData-Klasse, IntCast-Casting für Kontakt-IDs, nullable ?int-Properties, neue is_enabled-Property sowie Migrationen zum Umbenennen/Ergänzen der zugferd.*-Keys.
Controller, Request und Routen
app/Http/Controllers/App/Setting/ZugferdSettingController.php, app/Http/Requests/ZugferdSettingUpdateRequest.php, routes/tenant/settings.php
Neuer Controller mit edit()/update(), dedizierte Validierung inkl. exists-Checks und deutschsprachigen Fehlermeldungen, neue GET/PUT-Routen mit Precognitive-Middleware.
Frontend-Seite und Navigation
resources/js/Pages/App/Setting/ZugferdSetting/ZugferdSettingEdit.tsx, resources/js/Components/AppSidebar.tsx, resources/js/Types/generated.d.ts, resources/typescript-transformer-manifest.json
Neue Seite mit Formular für Verkäuferdaten und ICD-Felder, neuer Sidebar-Eintrag „Rechnungen → ZUGFeRD“, generierter ZugferdSettingData-Typ und nullable BankAccountData-Felder.
ZugferdService: Seller-Daten und Zahlungsziel
app/Services/ZugferdService.php
setSellerData() lädt jetzt Contact/ContactAddress statt statischer Settings-Werte; getPaymentInformation() berechnet ein Zahlungszieltextes über payment_deadline und Str::replace.

Sonstige unabhängige Anpassungen

Layer / File(s) Summary
Leistungsdatum-Prüfung korrigiert
app/Models/Invoice.php
checkForRelease() prüft nun service_period_begin und service_period_end statt service_period_end doppelt.
Textgröße xs angepasst
resources/css/app.css, resources/js/Components/twc-ui/field.tsx
--text-xs wird von 0.8rem auf 0.86rem erhöht, FieldDescription nutzt text-xs statt text-sm.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ZugferdSettingEdit
  participant ZugferdSettingController
  participant ZugferdSettingUpdateRequest
  participant ZugferdSettings

  User->>ZugferdSettingEdit: Formular ausfüllen und speichern
  ZugferdSettingEdit->>ZugferdSettingController: PUT app.setting.invoice.zugferd.update
  ZugferdSettingController->>ZugferdSettingUpdateRequest: Werte validieren
  ZugferdSettingUpdateRequest-->>ZugferdSettingController: validierte Daten
  ZugferdSettingController->>ZugferdSettings: Felder setzen und save()
  ZugferdSettingController-->>ZugferdSettingEdit: Redirect mit Erfolgsmeldung
Loading

Possibly related PRs

  • dspangenberg/opsc#487: Betrifft dieselbe ZUGFeRD-Settings-Verdrahtung in SettingController.php/SettingUpdateRequest.php, jedoch mit gegenteiliger Richtung (Hinzufügen statt Entfernen).
  • dspangenberg/opsc#559: Ergänzt invoice_text in PaymentDeadlineData, das hier direkt in der Zahlungsziel-Erzeugung des ZugferdService verwendet wird.
  • dspangenberg/opsc#562: Ändert dieselbe getPaymentInformation()-Logik in app/Services/ZugferdService.php für Zahlungsterm-Erzeugung.

Poem

Ein Kaninchen hoppelt durchs ZUGFeRD-Feld,
tippt Kontaktdaten sorgsam in die Welt.
Settings umbenannt, Migrationen sind klar,
die alte Route entfernt, das Formular ward wahr.
🐇✨ Mit *text-xs* und neuem Pfad —
so wächst die App, Schritt für Schritt, ganz brav.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive Der Titel ist nur ein Branch-/Arbeitsname und beschreibt die Änderungen nicht ausreichend. Benennen Sie den PR nach der Hauptänderung, z. B. „ZUGFeRD-Einstellungen hinzufügen“.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (2)
database/migrations/tenant/2026_07_02_183342_zugferd_settings_update.php (1)

18-27: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Auskommentierten Code entfernen.

Der auskommentierte delete-Block sollte nicht im Code verbleiben; ungenutzten/toten Code entfernen statt auskommentieren.

As per coding guidelines: "Prefer PHPDoc blocks over inline comments, and avoid comments in code unless the logic is exceptionally complex."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@database/migrations/tenant/2026_07_02_183342_zugferd_settings_update.php`
around lines 18 - 27, Remove the commented-out delete block from the migration
and keep the class clean of dead code. In the Zugferd settings migration, delete
the unused $this->migrator->delete(...) statements instead of leaving them
commented, and rely on code history if needed; do not replace them with another
inline comment.

Source: Coding guidelines

app/Http/Controllers/App/Setting/ZugferdSettingController.php (1)

17-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

edit() bitte mit explizitem Rückgabetyp deklarieren.

Die Methode verletzt hier die PHP-Richtlinie zu Return Types; den ungenutzten $request kannst du in dem Zug ebenfalls entfernen.

Möglicher Fix
 use Illuminate\Http\RedirectResponse;
-use Illuminate\Http\Request;
 use Inertia\Inertia;
+use Inertia\Response as InertiaResponse;
 
 class ZugferdSettingController extends Controller
 {
-    public function edit(Request $request)
+    public function edit(): InertiaResponse
     {
         $zugferdSettings = app(ZugferdSettings::class);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/Http/Controllers/App/Setting/ZugferdSettingController.php` at line 17, In
ZugferdSettingController::edit, add an explicit return type to the method
signature and remove the unused Request $request parameter. Update the method
declaration and any related imports/usages so the controller action matches the
project’s PHP return type policy.

Sources: Coding guidelines, Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/Data/ZugferdSettingData.php`:
- Around line 16-24: In ZugferdSettingData, the edit form fields global_id_type
and global_id are present but not covered by validation, so their updates get
dropped when the controller saves only validated() data. Update
ZugferdSettingUpdateRequest to include validation rules for global_id_type and
global_id, matching the existing ZugferdSettingData properties and the rest of
the request’s field constraints so these values are persisted on update.

In `@app/Http/Requests/ZugferdSettingUpdateRequest.php`:
- Around line 17-19: The validation in ZugferdSettingUpdateRequest only checks
free exists rules for seller_contact_person_id and seller_contact_address_id, so
they are not guaranteed to belong to seller_contact_id. Update the request rules
to enforce that both selected IDs are scoped to the chosen seller contact, using
the existing request validation logic in ZugferdSettingUpdateRequest so only
related contact person and address records can be saved together.
- Around line 24-30: The custom validation messages in
ZugferdSettingUpdateRequest still target the old generic settings fields, so
they no longer match the request’s actual inputs. Update the messages() keys to
the new field names used by the request’s rules and validation logic, and keep
the German text aligned with those fields so the correct errors are shown for
the current payload.
- Around line 14-21: The ZugferdSettingUpdateRequest validation currently omits
global_id_type and global_id, so update() only persists a subset of the form
data and silently drops those fields. Add both fields to the rules() method in
ZugferdSettingUpdateRequest with the appropriate validation constraints so they
are included in validated() and saved by the update flow, and verify the related
update action continues to use $request->validated() with the new keys
available.

In `@app/Services/ZugferdService.php`:
- Around line 39-68: The seller lookup in ZugferdService::setSellerData
dereferences the results of Contact::find and ContactAddress::find directly,
even though the seller IDs can be null or point to missing records. Add null
checks or guard clauses for $contact, $contactPerson, and $contactAddress before
using their properties, and decide on a safe fallback or early exit when any of
them is missing so the XML builder calls never run on null values.
- Line 19: The Str import in the ZugferdService class is incorrect and currently
points to a global class instead of Laravel’s helper class. Update the import
used by ZugferdService so that Str resolves to Illuminate\Support\Str, then
verify the Str::replace() call in this service still references that imported
symbol correctly.
- Around line 198-205: The payment term generation in ZugferdService::create*
currently passes payment_deadline->invoice_text directly into Str::replace(),
but that field can be null and break ZUGFeRD generation. Guard the invoice_text
access before calling Str::replace() by either falling back to an empty string
or skipping the replacement when invoice_text is missing, using the existing
$this->invoice->payment_deadline and $paypentTerm logic.

In `@database/migrations/tenant/2026_07_02_183342_zugferd_settings_update.php`:
- Around line 13-16: The migration in zugferd settings has a misspelled key and
an incorrect default flow: update the add call in the zugferd settings migration
to use seller_contact_address_id consistently with the rest of the code, set its
default to null, and remove the need for any follow-up migration that only fixes
this typo.

---

Nitpick comments:
In `@app/Http/Controllers/App/Setting/ZugferdSettingController.php`:
- Line 17: In ZugferdSettingController::edit, add an explicit return type to the
method signature and remove the unused Request $request parameter. Update the
method declaration and any related imports/usages so the controller action
matches the project’s PHP return type policy.

In `@database/migrations/tenant/2026_07_02_183342_zugferd_settings_update.php`:
- Around line 18-27: Remove the commented-out delete block from the migration
and keep the class clean of dead code. In the Zugferd settings migration, delete
the unused $this->migrator->delete(...) statements instead of leaving them
commented, and rely on code history if needed; do not replace them with another
inline comment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a9f35c7d-07f1-49ab-9ea5-e9d04a9887f8

📥 Commits

Reviewing files that changed from the base of the PR and between 3d90022 and 4137480.

📒 Files selected for processing (18)
  • app/Data/ZugferdSettingData.php
  • app/Http/Controllers/Admin/SettingController.php
  • app/Http/Controllers/App/Setting/ZugferdSettingController.php
  • app/Http/Requests/SettingUpdateRequest.php
  • app/Http/Requests/ZugferdSettingUpdateRequest.php
  • app/Models/Invoice.php
  • app/Services/ZugferdService.php
  • app/Settings/Casts/IntCast.php
  • app/Settings/ZugferdSettings.php
  • database/migrations/tenant/2026_07_02_183342_zugferd_settings_update.php
  • database/migrations/tenant/2026_07_02_183343_zugferd_settings_update.php
  • resources/css/app.css
  • resources/js/Components/AppSidebar.tsx
  • resources/js/Components/twc-ui/field.tsx
  • resources/js/Pages/App/Setting/ZugferdSetting/ZugferdSettingEdit.tsx
  • resources/js/Types/generated.d.ts
  • resources/typescript-transformer-manifest.json
  • routes/tenant/settings.php
💤 Files with no reviewable changes (1)
  • app/Http/Controllers/Admin/SettingController.php

Comment thread app/Data/ZugferdSettingData.php
Comment thread app/Http/Requests/ZugferdSettingUpdateRequest.php Outdated
Comment on lines +17 to +19
'seller_contact_id' => ['required', 'numeric', 'exists:contacts,id'],
'seller_contact_person_id' => ['required', 'numeric', 'exists:contacts,id'],
'seller_contact_address_id' => ['required', 'numeric', 'exists:contact_addresses,id'],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Kontaktperson und Anschrift sind serverseitig nicht an seller_contact_id gebunden.

Das UI filtert beide Auswahllisten zwar nach der gewählten Organisation, hier wird aber nur ein freies exists geprüft. Dadurch können fachlich unpassende IDs gespeichert werden, was später falsche Verkäuferdaten in den ZUGFeRD-Einstellungen hinterlässt.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/Http/Requests/ZugferdSettingUpdateRequest.php` around lines 17 - 19, The
validation in ZugferdSettingUpdateRequest only checks free exists rules for
seller_contact_person_id and seller_contact_address_id, so they are not
guaranteed to belong to seller_contact_id. Update the request rules to enforce
that both selected IDs are scoped to the chosen seller contact, using the
existing request validation logic in ZugferdSettingUpdateRequest so only related
contact person and address records can be saved together.

Comment thread app/Http/Requests/ZugferdSettingUpdateRequest.php Outdated
Comment thread app/Services/ZugferdService.php Outdated
Comment thread app/Services/ZugferdService.php Outdated
Comment thread app/Services/ZugferdService.php
@dspangenberg dspangenberg merged commit a2522c9 into main Jul 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant