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>
179 lines
8.6 KiB
PHP
179 lines
8.6 KiB
PHP
{!! Form::open(['action' => $route, 'class' => 'modal-content', 'enctype' => 'multipart/form-data']) !!}
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">
|
||
{{ __('abo.abo_settings') }} <span class="text-muted">{{ '#'.$user_abo->payone_userid }}</span>
|
||
</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<input type="hidden" name="action" value="{{$data['action']}}">
|
||
<input type="hidden" name="id" value="{{$data['id']}}">
|
||
<input type="hidden" name="view" value="{{$data['view']}}">
|
||
|
||
@php
|
||
$aboChangeLocked = App\Services\AboHelper::isAboChangeLocked($user_abo, $data['view']);
|
||
@endphp
|
||
|
||
@if(!App\Services\AboHelper::canEditAbo($user_abo, $data['view']))
|
||
<div class="alert alert-danger">
|
||
Unauthorized action. Is not my abo
|
||
</div>
|
||
@else
|
||
|
||
@if($aboChangeLocked)
|
||
<div class="alert alert-warning">
|
||
{{ __('abo.error_change_locked', [
|
||
'days' => (int) now()->diffInDays(\Carbon\Carbon::parse($user_abo->next_date), false),
|
||
'lock' => App\Repositories\AboRepository::getLockDaysChange(),
|
||
]) }}
|
||
</div>
|
||
@endif
|
||
|
||
<div class="form-row">
|
||
<div class="col-sm-6">
|
||
<label for="abo_interval" class="form-label">{{ __('tables.abo_delivery_day') }}*</label>
|
||
<select class="custom-select" name="abo_interval" id="abo_interval" required {{ $aboChangeLocked ? 'disabled' : '' }}>
|
||
{!! HTMLHelper::getAboDeliveryOptions($user_abo->abo_interval) !!}
|
||
</select>
|
||
@if($aboChangeLocked)
|
||
{{-- Deaktiviertes Select sendet keinen Wert: aktuellen Liefertag mitsenden,
|
||
damit andere Aktionen (z. B. Kündigen) nicht an der Liefertag-Validierung scheitern. --}}
|
||
<input type="hidden" name="abo_interval" value="{{ $user_abo->abo_interval }}">
|
||
@endif
|
||
</div>
|
||
@if($data['view'] === 'admin')
|
||
@php
|
||
$selectedNextMonth = $user_abo->getRawOriginal('next_date')
|
||
? \Carbon\Carbon::parse($user_abo->getRawOriginal('next_date'))->format('Y-m')
|
||
: now()->format('Y-m');
|
||
@endphp
|
||
<div class="col-sm-6">
|
||
<label for="abo_next_month" class="form-label">{{ __('validation.attributes.month') }}*</label>
|
||
<select class="custom-select" name="abo_next_month" id="abo_next_month" required>
|
||
@foreach(range(0, 3) as $monthOffset)
|
||
@php
|
||
$executionMonth = now()->copy()->startOfMonth()->addMonths($monthOffset);
|
||
@endphp
|
||
<option value="{{ $executionMonth->format('Y-m') }}" @if($executionMonth->format('Y-m') === $selectedNextMonth) selected @endif>
|
||
{{ \App\Services\HTMLHelper::getMonth($executionMonth->month) }} {{ $executionMonth->year }}
|
||
</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
@endif
|
||
<div class="col-sm-12 mt-1">
|
||
<i class="text-muted">
|
||
@if($data['view'] === 'admin')
|
||
{{ __('abo.admin_abo_copy_next_date') }}
|
||
@else
|
||
{{ __('abo.abo_copy_abo_interval') }}
|
||
@endif
|
||
</i>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
{{--
|
||
<div class="form-row">
|
||
<div class="col-sm-6">
|
||
<label for="next_date" class="form-label">{{ __('tables.next_date') }} ({{ $user_abo->next_date }})</label>
|
||
{!! Form::text('next_date', $user_abo->next_date, ['class'=>'form-control datepicker-base']) !!}
|
||
</div>
|
||
<div class="form-group col-sm-12 mt-1">
|
||
<i class="text-muted">{{ __('abo.abo_copy_next_date') }}</i>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
--}}
|
||
|
||
@php
|
||
$canCancel = App\Services\AboHelper::canCancelAbo($user_abo, $data['view']);
|
||
@endphp
|
||
<hr>
|
||
@if($data['view'] === 'admin')
|
||
<div class="form-row">
|
||
<div class="col-sm-12">
|
||
<label class="switcher switcher-primary">
|
||
<input type="checkbox" class="switcher-input" name="abo_is_active" value="true" @if($user_abo->active) checked @endif>
|
||
<span class="switcher-indicator">
|
||
<span class="switcher-yes"></span>
|
||
<span class="switcher-no"></span>
|
||
</span>
|
||
<span class="switcher-label">{{ __('abo.abo_is_active') }}</span>
|
||
</label>
|
||
</div>
|
||
<div class="col-sm-12 mt-1">
|
||
<i class="text-muted">{{ __('abo.abo_copy_active') }}</i>
|
||
</div>
|
||
</div>
|
||
@elseif($canCancel)
|
||
{{-- Selfservice: kein Aktiv-Schalter mehr (die Pause übernimmt diese Rolle),
|
||
aktueller Zustand wird unverändert mitgesendet. --}}
|
||
<input type="hidden" name="abo_is_active" value="{{ $user_abo->active }}">
|
||
|
||
@php
|
||
$canPause = App\Services\AboHelper::canPauseAbo($user_abo, $data['view']);
|
||
$nextPossiblePause = App\Services\AboHelper::nextPossiblePauseDate($user_abo);
|
||
@endphp
|
||
@if($canPause || ($user_abo->active && $nextPossiblePause))
|
||
<div class="form-row">
|
||
<div class="col-sm-12">
|
||
@if($canPause)
|
||
<button type="submit" name="abo_pause" value="true" class="btn btn-outline-primary btn-sm" onclick="return confirm('{{ __('abo.confirm_pause') }}')">
|
||
<i class="ion ion-md-pause"></i> {{ __('abo.pause_abo') }}
|
||
</button>
|
||
<div class="mt-1">
|
||
<i class="text-muted">{{ __('abo.abo_copy_pause', ['months' => App\Services\AboHelper::getPauseIntervalMonths()]) }}</i>
|
||
</div>
|
||
@else
|
||
<i class="text-muted">{{ __('abo.info_pause_available_from', ['date' => $nextPossiblePause->format(Util::formatDateDB()), 'months' => App\Services\AboHelper::getPauseIntervalMonths()]) }}</i>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
@endif
|
||
|
||
<div class="form-row">
|
||
<div class="col-sm-12">
|
||
<button type="submit" name="abo_cancel" value="true" class="btn btn-outline-danger btn-sm" onclick="return confirm('{{ __('abo.confirm_cancel') }}')">
|
||
<i class="ion ion-ios-trash"></i> {{ __('abo.cancel_abo') }}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
@else
|
||
<input type="hidden" name="abo_is_active" value="{{ $user_abo->active }}">
|
||
<div class="mt-1">
|
||
<div class="alert alert-warning">
|
||
{{ __('abo.info_min_duration_orders_left', ['count' => App\Services\AboHelper::getAboMinDuration() - $user_abo->getCountPaidOrders()]) }}
|
||
</div>
|
||
</div>
|
||
@endif
|
||
@endif
|
||
</div>
|
||
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('close') }}</button>
|
||
<button type="submit" class="btn btn-primary">{{__('speichern')}}</button>
|
||
</div>
|
||
{!! Form::close() !!}
|
||
|
||
|
||
<script type="text/javascript">
|
||
$( document ).ready(function() {
|
||
$('.datepicker-base').datepicker({
|
||
orientation: 'auto right',
|
||
calendarWeeks: true,
|
||
todayBtn: 'linked',
|
||
//daysOfWeekDisabled: '1',
|
||
todayHighlight: true,
|
||
multidate: false,
|
||
daysOfWeekHighlighted: '0,6',
|
||
autoclose: true,
|
||
format: 'dd.mm.yyyy',
|
||
language: '{{ \App::getLocale() }}',
|
||
clearBtn: true,
|
||
}).on('clearDate', function(e) {
|
||
$('.datepicker-base').datepicker('update', '{{ $user_abo->next_date }}');
|
||
});
|
||
});
|
||
</script>
|