mivita/resources/views/admin/abo/_detail.blade.php
Kevin ec3ecadc5d 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

128 lines
5.7 KiB
PHP

<!-- Info -->
<div class="card-body pb-1">
<div class="row">
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('tables.start_date') }}</div>
{{ $user_abo->start_date }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('tables.next_date') }}</div>
<strong>{{ $user_abo->next_date }}</strong>
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('tables.abo_delivery_day') }}</div>
<strong>{{ \App\Services\HTMLHelper::getAboStrLang($user_abo->abo_interval) }}</strong>
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('tables.last_date') }}</div>
{{ $user_abo->last_date }}
</div>
</div>
</div>
<hr class="m-0">
<div class="card-body pb-1">
<div class="row">
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('tables.status') }} / {{ __('tables.active') }}</div>
{!! get_active_badge($user_abo->active) !!}
@include('admin.abo._status_explain', ['abo' => $user_abo])
@if ($isAdmin && $user_abo->status === 3 && $user_abo->active)
<button type="button" class="btn btn-sm btn-danger mt-3" data-toggle="modal"
data-target="#modal-retry-abo-payment">
<span class="fa fa-redo"></span> {{ __('abo.retry_payment') }}
</button>
<button type="button" class="btn btn-sm btn-success mt-3" data-toggle="modal"
data-target="#modal-abo-extern-done">
<span class="fa fa-check"></span> {{ __('abo.extern_done') }}
</button>
@endif
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('tables.abo_delivery') }}</div>
{{ $user_abo->getCountPaidOrders() }} / {{ \App\Models\Setting::getContentBySlug('abo-min-duration') }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('tables.payment') }}</div>
{{ $user_abo->getPaymentType() }}
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('tables.amount') }}</div>
<span class="text-nowrap" id="value-amount">{{ $user_abo->getFormattedAmount() }}</span> €
</div>
</div>
</div>
<hr class="m-0">
@if ($isAdmin)
<div class="card-body pb-1">
<div class="row">
<div class="col-md-3 mb-3">
<button type="button" class="btn btn-sm btn-secondary" data-toggle="modal"
data-target="#modals-load-content" data-id="{{ $user_abo->id }}" data-action="abo_update_settings"
data-view="admin" data-route="{{ route('modal_load') }}"><span
class="fa fa-edit"></span>{{ __('abo.abo_settings') }}</button>
<button type="button" class="btn btn-sm btn-danger" data-toggle="modal"
data-target="#modal-abo-delete"><span class="fa fa-trash"></span> {{ __('abo.admin_delete') }}</button>
</div>
<div class="col-md-6 mb-3">
@if (isset($user_abo->shopping_user) && $user_abo->shopping_user->member_id > 0)
<div class="text-muted small">{{ __('tables.adviser') }}</div>
{!! '<a href="' .
route('admin_lead_edit', [$user_abo->shopping_user->member_id]) .
'">' .
$user_abo->shopping_user->member->getFullName() .
'</a>' !!}
@endif
</div>
<div class="col-md-3 mb-3">
<div class="text-muted small">{{ __('tables.is_for') }}</div>
{!! $user_abo->getIsForFormated() !!}
@if ($user_abo->is_for === 'me')
<a class="btn btn-xs btn-secondary" href="{{ route('admin_lead_edit', $user_abo->user_id) }}"><i
class="fa fa-edit"></i></a>
@endif
@if ($user_abo->is_for === 'ot')
<a class="btn btn-xs btn-secondary"
href="{{ route('admin_customer_edit', $user_abo->shopping_user->id) }}"><i
class="fa fa-edit"></i></a>
@endif
</div>
</div>
</div>
@else
<div class="card-body pb-1">
<div class="row">
<div class="col-md-6 mb-3">
@if (App\Services\AboHelper::canEditAbo($user_abo, $view))
<button type="button" class="btn btn-sm btn-secondary" data-toggle="modal"
data-target="#modals-load-content" data-id="{{ $user_abo->id }}"
data-action="abo_update_settings" data-view="{{ $view }}"
data-route="{{ route('modal_load') }}"><span
class="fa fa-edit"></span>{{ __('abo.abo_settings') }}</button>
@endif
</div>
<div class="col-md-3 mb-3">
{!! $user_abo->getIsForFormated() !!}
@if ($user_abo->is_for === 'me' && Route::has('user_edit'))
<a class="btn btn-xs btn-secondary" href="{{ route('user_edit') }}"><i class="fa fa-edit"></i></a>
@endif
@if ($user_abo->is_for === 'ot' && $user_abo->shopping_user && Route::has('user_customer_edit'))
<a class="btn btn-xs btn-secondary"
href="{{ route('user_customer_edit', $user_abo->shopping_user->id) }}"><i
class="fa fa-edit"></i></a>
@endif
</div>
</div>
</div>
@endif