Skip to content

Refactoring Offer-Status#573

Merged
dspangenberg merged 1 commit into
mainfrom
develop
Jul 5, 2026
Merged

Refactoring Offer-Status#573
dspangenberg merged 1 commit into
mainfrom
develop

Conversation

@dspangenberg

@dspangenberg dspangenberg commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Neue Funktionen

    • Angebotsdetails, Vertragsbedingungen und Historie zeigen und nutzen jetzt eine einheitliche Statusauswahl.
    • Beim Duplizieren und Freigeben von Angeboten wird der Status automatisch auf „Ausstehend“ gesetzt.
  • Bug Fixes

    • Statusbezeichnungen werden nun konsistent angezeigt und lassen sich zuverlässiger ändern.
    • Entwurfsangebote bleiben weiterhin als „Entwurf“ gekennzeichnet.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Der Backend-Controller und das Offer-Modell liefern jetzt Angebotsstatus-Listen über OfferStatusEnum an Inertia-Views und setzen den Status beim Duplizieren/Release explizit auf PENDING. Die zugehörigen React-Komponenten (OfferDetails, OfferDetailsLayout, OfferDetailsSide, OfferTerms, OfferHistory) empfangen eine neue statuses-Prop und lösen Statuslabels dynamisch daraus auf statt über eine statische Directory-Konstante.

Changes

Statuslisten-Integration Backend und Frontend

Layer / File(s) Summary
Backend: Statuses-Prop und Status-Handling
app/Http/Controllers/App/OfferController.php, app/Models/Offer.php
show, terms, history liefern zusätzlich statuses; duplicate setzt den Status des Duplikats auf PENDING; setStatus nutzt OfferStatusEnum::labels() statt fester match-Zuordnung; Offer::release() setzt Status auf PENDING; PHPDoc mit @throws Exception ergänzt.
Frontend: statuses-Prop weiterreichen und Statuslabel dynamisch auflösen
resources/js/Pages/App/Offer/OfferDetails.tsx, OfferDetailsLayout.tsx, OfferDetailsSide.tsx, OfferTerms.tsx, OfferHistory.tsx
Alle genannten Komponenten erweitern ihre Props um statuses: LaravelOptions[], reichen die Prop weiter an Layout/Side-Komponenten und ersetzen die statische offerStatusDirectory-Lookup durch statuses.find(...); Statusdropdown-UI und useMemo-Dependencies in OfferDetailsLayout wurden entsprechend angepasst.

Estimated code review effort: 2 (Simple) | ~12 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant OfferController
  participant Offer
  participant OfferDetailsFrontend

  Client->>OfferController: show/terms/history Request
  OfferController->>Offer: Angebotsdaten laden
  OfferController-->>Client: Inertia Response inkl. statuses
  Client->>OfferDetailsFrontend: statuses als Prop empfangen
  OfferDetailsFrontend->>OfferDetailsFrontend: statuses.find() zur Statuslabel-Auflösung

  Client->>OfferController: duplicate(offer)
  OfferController->>Offer: neues Offer erstellen
  OfferController->>Offer: status = PENDING
  OfferController-->>Client: Redirect/Response
Loading

Possibly related PRs

  • dspangenberg/opsc#14: Führt das Offer-Model mit release() ein, das im Hauptteil um das Setzen von status auf PENDING erweitert wird.
  • dspangenberg/opsc#67: Verändert ebenfalls den Release-Flow von Offer::release(), was mit der Statusänderung im Hauptteil überschneidet.
  • dspangenberg/opsc#332: Führt OfferStatusEnum und OfferController@setStatus ein, worauf die Statuslisten-/Label-Anpassungen im Hauptteil direkt aufbauen.

Poem

Ein Hase hoppelt durch den Code,
bringt Status-Listen an jeden Ort,
kein match mehr starr und alt,
statuses fließt nun vielgestalt.
PENDING blinkt beim Duplizieren froh —
🐇 hopp, hopp, das Enum macht's so!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Der Titel beschreibt passend die Refaktorisierung der Angebots-Statuslogik im PR.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PHPStan (2.2.2)

PHPStan was skipped because the config uses disallowed bootstrapFiles, bootstrapFile, or includes directives.


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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/Http/Controllers/App/OfferController.php (1)

270-279: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Falsches Objekt erhält den neuen Status – Duplikat bleibt beim alten Status.

$offer->status = OfferStatusEnum::PENDING->value; ändert den Status des Original-Angebots, nicht des Duplikats, und es fehlt ein save(). Laut Änderungsbeschreibung soll aber der Status des Duplikats auf PENDING gesetzt werden. Offer::duplicate() (siehe app/Models/Offer.php) übernimmt den Status per replicate() unverändert vom Original, sodass das neue Angebot ohne diese Korrektur weiterhin z. B. ACCEPTED oder REJECTED bleibt. Zusätzlich verpufft die aktuelle Zeile komplett wirkungslos, da $offer nie gespeichert wird.

🐛 Vorgeschlagener Fix
     public function duplicate(Offer $offer)
     {
         $duplicatedOffer = Offer::duplicate($offer);

-        $offer->status = OfferStatusEnum::PENDING->value;
+        $duplicatedOffer->status = OfferStatusEnum::PENDING->value;
+        $duplicatedOffer->save();

         $duplicatedOffer->addHistory('hat das Angebot erstellt.', 'created', auth()->user());
🤖 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/OfferController.php` around lines 270 - 279, The
duplicate action in OfferController currently updates the original Offer instead
of the cloned one, so the duplicated record keeps the old status. Change
duplicate(Offer $offer) to set OfferStatusEnum::PENDING on the object returned
by Offer::duplicate($offer), then persist that duplicated offer before returning
the redirect; keep the history call on the duplicated record as it already is.
Use the existing duplicate() workflow and Offer::duplicate() behavior in
Offer.php to ensure the new Offer is the one saved with the pending status.
app/Models/Offer.php (1)

252-286: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Status beim Duplizieren direkt auf PENDING setzen

Offer::duplicate() übernimmt den Originalstatus per replicate(), und der Reset im Controller trifft nur das ursprüngliche $offer-Objekt ohne save(). Dadurch bleibt das duplizierte Angebot auf dem alten Status.

Den Reset direkt in app/Models/Offer.php vor dem save() setzen und die fehlerhafte Controller-Zeile entfernen.

🤖 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/Models/Offer.php` around lines 252 - 286, In Offer::duplicate(), the
duplicated offer is currently keeping the original status because replicate()
copies it and the controller reset only affects the source Offer instance. Set
the duplicated model’s status to PENDING inside Offer::duplicate() before
save(), alongside the other field resets on $duplicatedOffer, and remove the
now-redundant controller-side status reset. Use the duplicate() method and
$duplicatedOffer assignment block as the fix location.
🧹 Nitpick comments (1)
resources/js/Pages/App/Offer/OfferDetailsLayout.tsx (1)

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

Debug-console.log entfernen.

console.log(status) sieht nach einem vergessenen Debug-Artefakt aus und sollte vor dem Merge entfernt werden.

🧹 Vorgeschlagener Fix
   const handleStatusChange = async (status: string) => {
-    console.log(status)
     const statusName = statuses?.find(item => item.id === status)?.name
🤖 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 `@resources/js/Pages/App/Offer/OfferDetailsLayout.tsx` at line 150, Remove the
մն leftover debug logging from OfferDetailsLayout by deleting the
console.log(status) statement in the component logic; locate it via the
OfferDetailsLayout function/component and ensure no console output remains in
the merged code.
🤖 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.

Outside diff comments:
In `@app/Http/Controllers/App/OfferController.php`:
- Around line 270-279: The duplicate action in OfferController currently updates
the original Offer instead of the cloned one, so the duplicated record keeps the
old status. Change duplicate(Offer $offer) to set OfferStatusEnum::PENDING on
the object returned by Offer::duplicate($offer), then persist that duplicated
offer before returning the redirect; keep the history call on the duplicated
record as it already is. Use the existing duplicate() workflow and
Offer::duplicate() behavior in Offer.php to ensure the new Offer is the one
saved with the pending status.

In `@app/Models/Offer.php`:
- Around line 252-286: In Offer::duplicate(), the duplicated offer is currently
keeping the original status because replicate() copies it and the controller
reset only affects the source Offer instance. Set the duplicated model’s status
to PENDING inside Offer::duplicate() before save(), alongside the other field
resets on $duplicatedOffer, and remove the now-redundant controller-side status
reset. Use the duplicate() method and $duplicatedOffer assignment block as the
fix location.

---

Nitpick comments:
In `@resources/js/Pages/App/Offer/OfferDetailsLayout.tsx`:
- Line 150: Remove the մն leftover debug logging from OfferDetailsLayout by
deleting the console.log(status) statement in the component logic; locate it via
the OfferDetailsLayout function/component and ensure no console output remains
in the merged code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 37218543-3be3-4eee-96b1-53330b651fbd

📥 Commits

Reviewing files that changed from the base of the PR and between 4de59a4 and 1b808f9.

📒 Files selected for processing (7)
  • app/Http/Controllers/App/OfferController.php
  • app/Models/Offer.php
  • resources/js/Pages/App/Offer/OfferDetails.tsx
  • resources/js/Pages/App/Offer/OfferDetailsLayout.tsx
  • resources/js/Pages/App/Offer/OfferDetailsSide.tsx
  • resources/js/Pages/App/Offer/OfferHistory.tsx
  • resources/js/Pages/App/Offer/OfferTerms.tsx

@dspangenberg dspangenberg merged commit 9d4c46d into main Jul 5, 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