diff --git a/resources/views/livewire/customer/press-releases/show.blade.php b/resources/views/livewire/customer/press-releases/show.blade.php index 1611efbd..824eab9b 100644 --- a/resources/views/livewire/customer/press-releases/show.blade.php +++ b/resources/views/livewire/customer/press-releases/show.blade.php @@ -574,61 +574,6 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends @endif - {{-- ============== DEPUBLIKATION (T12, Meldeverfahren Weg 3) ============== --}} - @if ($pr->status === PressReleaseStatus::Published && $depublicationPriceCents > 0) - @php - $depubNet = number_format($depublicationPriceCents / 100, 2, ',', '.'); - $depubGross = number_format($depublicationPriceCents * (1 + (float) config('billing.vat_rate')) / 100, 2, ',', '.'); - @endphp -
-
- {{ __('Depublikation (Service)') }} -
-
-
-
- -
-
-

{{ __('Aus der öffentlichen Ansicht entfernen') }}

-

- {{ __('Freiwillige Entfernung dieser veröffentlichten Mitteilung — die öffentliche URL zeigt danach dauerhaft einen Entfernt-Hinweis. Kopien in Suchmaschinen oder Drittarchiven können zeitweise weiter verfügbar sein. Preis: :net € zzgl. USt. (:gross € inkl. 19 % USt.)', ['net' => $depubNet, 'gross' => $depubGross]) }} -

-
-
- - @if ($depublicationRequested) -
- {{ __('Für diese Pressemitteilung liegt bereits ein Depublikations-Vorgang vor.') }} -
- @else -
- -

- - {{ __('AGB (Version :version)', ['version' => \App\Models\LegalDocument::currentAgbVersion()]) }} - - · {{ __('Gesetzliche Ansprüche (z. B. DSGVO) bleiben davon unberührt und sind immer kostenlos.') }} -

-
- @if ($depublicationConfirmed) - - {{ __('Kostenpflichtig depublizieren') }} - - @else - - {{ __('Kostenpflichtig depublizieren') }} - - @endif - @endif -
-
- @endif - @if ($pr->status === PressReleaseStatus::Review)
@@ -944,6 +889,63 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends
@endif + {{-- ============== DEPUBLIKATION (T12, Meldeverfahren Weg 3) ============== + Bewusst ganz unten (QA-Befund 07.07.): seltener Ausnahme-Service, + soll nicht zwischen Add-ons und Inhalt um Aufmerksamkeit konkurrieren. --}} + @if ($pr->status === PressReleaseStatus::Published && $depublicationPriceCents > 0) + @php + $depubNet = number_format($depublicationPriceCents / 100, 2, ',', '.'); + $depubGross = number_format($depublicationPriceCents * (1 + (float) config('billing.vat_rate')) / 100, 2, ',', '.'); + @endphp +
+
+ {{ __('Depublikation (Service)') }} +
+
+
+
+ +
+
+

{{ __('Aus der öffentlichen Ansicht entfernen') }}

+

+ {{ __('Freiwillige Entfernung dieser veröffentlichten Mitteilung — die öffentliche URL zeigt danach dauerhaft einen Entfernt-Hinweis. Kopien in Suchmaschinen oder Drittarchiven können zeitweise weiter verfügbar sein. Preis: :net € zzgl. USt. (:gross € inkl. 19 % USt.)', ['net' => $depubNet, 'gross' => $depubGross]) }} +

+
+
+ + @if ($depublicationRequested) +
+ {{ __('Für diese Pressemitteilung liegt bereits ein Depublikations-Vorgang vor.') }} +
+ @else +
+ +

+ + {{ __('AGB (Version :version)', ['version' => \App\Models\LegalDocument::currentAgbVersion()]) }} + + · {{ __('Gesetzliche Ansprüche (z. B. DSGVO) bleiben davon unberührt und sind immer kostenlos.') }} +

+
+ @if ($depublicationConfirmed) + + {{ __('Kostenpflichtig depublizieren') }} + + @else + + {{ __('Kostenpflichtig depublizieren') }} + + @endif + @endif +
+
+ @endif + {{-- ============== MODAL: NICHT GENÜGEND CREDITS ============== Öffnet sich serverseitig, wenn ein Add-on-Kauf (Boost/Nachweis) am Wallet-Guthaben scheitert — mit Direktlink zum Aufladen. --}} diff --git a/tests/Feature/Billing/DepublicationTest.php b/tests/Feature/Billing/DepublicationTest.php index 75ad8b1a..b1d2d9c4 100644 --- a/tests/Feature/Billing/DepublicationTest.php +++ b/tests/Feature/Billing/DepublicationTest.php @@ -15,6 +15,7 @@ use Database\Seeders\RolesAndPermissionsSeeder; use Illuminate\Http\RedirectResponse; use Laravel\Cashier\Checkout; use Laravel\Cashier\Events\WebhookReceived; +use Livewire\Volt\Volt as LivewireVolt; use Tests\TestCase; beforeEach(function (): void { @@ -114,6 +115,51 @@ test('the depublication checkout creates a pending purchase and hands it to stri expect(SinglePurchase::count())->toBe(1); }); +test('the detail page offers depublication and logs the entrepreneur confirmation', function () { + /** @var TestCase $this */ + $user = depublicationCustomer(); + $release = publishedReleaseFor($user); + BookingConfirmation::query()->delete(); // nur die Bestätigung aus dem Test-Setup entfernen + + $this->actingAs($user); + + LivewireVolt::test('customer.press-releases.show', ['id' => $release->id]) + ->assertSee('Depublikation (Service)') + ->assertSee('Kostenpflichtig depublizieren') + ->set('depublicationConfirmed', true); + + $confirmation = BookingConfirmation::sole(); + expect($confirmation->booking_type)->toBe('depublication'); + expect($confirmation->booking_ref)->toBe((string) $release->id); + expect($confirmation->user_id)->toBe($user->id); +}); + +test('the detail page hides the depublication offer without a price and after a purchase', function () { + /** @var TestCase $this */ + $user = depublicationCustomer(); + $release = publishedReleaseFor($user); + $this->actingAs($user); + + // Ohne konfigurierten Preis erscheint die Sektion gar nicht (T12). + config()->set('billing.depublication_price_cents', null); + LivewireVolt::test('customer.press-releases.show', ['id' => $release->id]) + ->assertDontSee('Depublikation (Service)'); + + // Mit laufendem Vorgang: Hinweis statt erneutem Kauf-Button. + config()->set('billing.depublication_price_cents', 19900); + SinglePurchase::query()->create([ + 'user_id' => $user->id, + 'type' => SinglePurchaseType::Depublication->value, + 'status' => SinglePurchaseStatus::Pending->value, + 'price_cents' => 19900, + 'currency' => 'EUR', + 'press_release_id' => $release->id, + ]); + LivewireVolt::test('customer.press-releases.show', ['id' => $release->id]) + ->assertSee('Für diese Pressemitteilung liegt bereits ein Depublikations-Vorgang vor.') + ->assertDontSee('Kostenpflichtig depublizieren'); +}); + test('the paid webhook depublishes the release and the public page shows a tombstone', function () { /** @var TestCase $this */ $user = depublicationCustomer();