20-02-2026
This commit is contained in:
parent
a8b395e20d
commit
a00c42e770
252 changed files with 28785 additions and 8907 deletions
62
resources/views/admin/abo/_change_history.blade.php
Normal file
62
resources/views/admin/abo/_change_history.blade.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
@php
|
||||
$changeHistory = $user_abo->getChangeHistory();
|
||||
$priceLabel = $user_abo->is_for === 'me' ? __('abo_history.price_net') : __('abo_history.price_gross');
|
||||
@endphp
|
||||
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h5 class="font-weight-semibold mb-0">
|
||||
<i class="fas fa-history"></i> {{ __('abo_history.change_history') }}
|
||||
</h5>
|
||||
@if(isset($isAdmin) && $isAdmin && $user_abo->getInitialItems()->isNotEmpty())
|
||||
{{-- <form action="{{ route('admin_abos_rollback', [$user_abo->id]) }}" method="POST"
|
||||
onsubmit="return confirm('{{ __('abo_history.rollback_confirm') }}')">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">
|
||||
<i class="fas fa-undo"></i> {{ __('abo_history.rollback_btn') }}
|
||||
</button>
|
||||
</form>
|
||||
--}}
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if($changeHistory->isEmpty())
|
||||
<p class="text-muted mb-0">
|
||||
<i class="fas fa-info-circle"></i> {{ __('abo_history.no_changes') }}
|
||||
</p>
|
||||
@else
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-striped mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('abo_history.col_date') }}</th>
|
||||
<th>{{ __('abo_history.col_action') }}</th>
|
||||
<th>{{ __('abo_history.col_product') }}</th>
|
||||
<th>{{ __('abo_history.col_details') }}</th>
|
||||
<th class="text-right">{{ __('tables.price') }} <small class="text-muted">({{ $priceLabel }})</small></th>
|
||||
<th>{{ __('abo_history.col_changed_by') }}</th>
|
||||
<th>{{ __('abo_history.col_channel') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($changeHistory as $entry)
|
||||
<tr>
|
||||
<td class="text-nowrap small">{{ $entry->getFormattedDate() }}</td>
|
||||
<td>{!! $entry->getActionBadge() !!}</td>
|
||||
<td>
|
||||
<strong>{{ $entry->product_name }}</strong>
|
||||
@if($entry->product_number)
|
||||
<br><small class="text-muted">{{ $entry->product_number }}</small>
|
||||
@endif
|
||||
</td>
|
||||
<td class="small">{{ $entry->getChangeDescription() }}</td>
|
||||
<td class="text-right text-nowrap">{{ $entry->getFormattedTotalPrice() }} €</td>
|
||||
<td class="small">{{ $entry->changed_by_name }}</td>
|
||||
<td>{!! $entry->getChannelBadge() !!}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
59
resources/views/admin/abo/_initial_composition.blade.php
Normal file
59
resources/views/admin/abo/_initial_composition.blade.php
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
@php
|
||||
$initialItems = $user_abo->getInitialItems();
|
||||
$initialCompItems = $user_abo->getInitialCompItems();
|
||||
$priceLabel = $user_abo->is_for === 'me' ? __('abo_history.price_net') : __('abo_history.price_gross');
|
||||
@endphp
|
||||
|
||||
<div class="card-body">
|
||||
<h5 class="font-weight-semibold">
|
||||
<i class="fas fa-box-open"></i> {{ __('abo_history.initial_composition') }}
|
||||
</h5>
|
||||
|
||||
@if($initialItems->isEmpty() && $initialCompItems->isEmpty())
|
||||
<p class="text-muted mb-0">
|
||||
<i class="fas fa-info-circle"></i> {{ __('abo_history.no_initial_data') }}
|
||||
</p>
|
||||
@else
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('order.article') }}</th>
|
||||
<th>{{ __('order.art_no') }}</th>
|
||||
<th class="text-center">{{ __('tables.quantity') }}</th>
|
||||
<th class="text-right">{{ __('tables.price') }} <small class="text-muted">({{ $priceLabel }})</small></th>
|
||||
<th class="text-right">{{ __('order.total_sum') }} <small class="text-muted">({{ $priceLabel }})</small></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($initialItems as $item)
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{{ $item->product_name }}</strong>
|
||||
@if($item->product)
|
||||
{!! \App\Services\AboHelper::getAboTypeBadge(\App\Services\AboHelper::getAboShowOn($item->product)) !!}
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-muted">{{ $item->product_number }}</td>
|
||||
<td class="text-center">{{ $item->qty_after }}</td>
|
||||
<td class="text-right text-nowrap">{{ $item->getFormattedUnitPrice() }} €</td>
|
||||
<td class="text-right text-nowrap font-weight-semibold">{{ $item->getFormattedTotalPrice() }} €</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@foreach($initialCompItems as $item)
|
||||
<tr class="bg-light">
|
||||
<td>
|
||||
<span class="badge badge-outline-secondary">Comp</span>
|
||||
{{ $item->product_name }}
|
||||
</td>
|
||||
<td class="text-muted">{{ $item->product_number }}</td>
|
||||
<td class="text-center">{{ $item->qty_after }}</td>
|
||||
<td class="text-right text-nowrap">{{ $item->getFormattedUnitPrice() }} €</td>
|
||||
<td class="text-right text-nowrap font-weight-semibold">{{ $item->getFormattedTotalPrice() }} €</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
|
@ -108,9 +108,19 @@
|
|||
{{ __('abo.abo_order_hl') }}
|
||||
</h5>
|
||||
@if(isset($only_show_products) && $only_show_products === true)
|
||||
<p>{!! __('abo.abo_order_info_block', ['abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration')]) !!}</p>
|
||||
@if($view === 'team')
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_block_team', ['abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration')]) !!}</div>
|
||||
@else
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_block', ['abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration')]) !!}</div>
|
||||
@endif
|
||||
@elseif(isset($add_only_mode) && $add_only_mode)
|
||||
@if($view === 'ot')
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_block_customer', ['abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration')]) !!}</div>
|
||||
@else
|
||||
<div class="alert alert-info">{!! __('abo.abo_order_info_add_only', ['abo-min-duration' => \App\Models\Setting::getContentBySlug('abo-min-duration')]) !!}</div>
|
||||
@endif
|
||||
@else
|
||||
<p>{{ __('abo.abo_order_info_2') }}</p>
|
||||
<div class="alert alert-info">{{ __('abo.abo_order_info_2') }}</div>
|
||||
@endif
|
||||
<hr>
|
||||
@include('user.abo.vat_info')
|
||||
|
|
@ -121,8 +131,11 @@
|
|||
data-route="{{ route('modal_load') }}"><i class="fa fa-plus-circle"></i> {{ __('abo.add_product') }}</button>
|
||||
@endif
|
||||
<div class="" id="insert_show_products_order" data-cart-order-id="{{ $user_abo->id }}">
|
||||
@php $only_show_products = isset($only_show_products) ? $only_show_products : false; @endphp
|
||||
@include('admin.abo._order_abo_show', ['only_show_products' => $only_show_products])
|
||||
@php
|
||||
$only_show_products = isset($only_show_products) ? $only_show_products : false;
|
||||
$add_only_mode = isset($add_only_mode) ? $add_only_mode : false;
|
||||
@endphp
|
||||
@include('admin.abo._order_abo_show', ['only_show_products' => $only_show_products, 'add_only_mode' => $add_only_mode])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
<div>{{ __('order.content') }}: {{ $abo_item->product->contents }}</div>
|
||||
<div>{{ __('order.art_no') }}: {{ $abo_item->product->number }}</div>
|
||||
</div>
|
||||
@if(!isset($only_show_products) || !$only_show_products)
|
||||
@if((!isset($only_show_products) || !$only_show_products) && (!isset($add_only_mode) || !$add_only_mode))
|
||||
<div class="options">
|
||||
<a href="#" class="auto-delete-product remove_item_form_cart product-tooltip" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}"><i class="fa fa-times"></i> {{ __('order.article_remove') }}</a>
|
||||
</div>
|
||||
|
|
@ -38,12 +38,14 @@
|
|||
@if(!isset($only_show_products) || !$only_show_products)
|
||||
<div class="no-line-break input-group-min-w">
|
||||
<div class="input-group d-inline-flex w-auto">
|
||||
@if(!isset($add_only_mode) || !$add_only_mode)
|
||||
<span class="input-group-prepend">
|
||||
<button type="button" class="btn btn-secondary icon-btn md-btn-extra remove-from-basket" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}">-</button>
|
||||
</span>
|
||||
<input type="text" class="form-control text-center input-extra table-input-event-onchange" name="product_qty_{{$abo_item->id}}" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}" value="{{$abo_item->qty}}">
|
||||
@endif
|
||||
<input type="text" class="form-control text-center input-extra table-input-event-onchange" name="product_qty_{{$abo_item->id}}" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}" value="{{$abo_item->qty}}" {{ (isset($add_only_mode) && $add_only_mode) ? 'readonly' : '' }}>
|
||||
<span class="input-group-append">
|
||||
<button type="button" class="btn btn-secondary icon-btn md-btn-extra add-from-basket" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}">+</button>
|
||||
<button type="button" class="btn btn-secondary icon-btn md-btn-extra add-from-basket" data-order-item-id="{{$abo_item->id}}" data-product-id="{{ $abo_item->product->id }}" data-product-name="{{ $abo_item->product->getLang('name') }}" data-product-price="{{ $abo_item->getFormattedPrice() }} €">+</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,14 @@
|
|||
|
||||
{{ Form::close() }}
|
||||
|
||||
<div class="card mt-3">
|
||||
@include('admin.abo._initial_composition')
|
||||
</div>
|
||||
|
||||
<div class="card mt-3">
|
||||
@include('admin.abo._change_history')
|
||||
</div>
|
||||
|
||||
<div class="card mt-3">
|
||||
@include('admin.abo._executions')
|
||||
</div>
|
||||
|
|
@ -48,7 +56,45 @@
|
|||
|
||||
<a href="{{route('admin_abos')}}" class="btn btn-sm btn-default mt-2 float-right">{{ __('back') }}</a>
|
||||
|
||||
|
||||
<div class="modal fade" id="modal-confirm-add" tabindex="-1" role="dialog" aria-labelledby="modal-confirm-add-label" aria-hidden="true"
|
||||
data-title-add-only="{{ __('abo.confirm_add_title') }}"
|
||||
data-title-normal="{{ __('abo.confirm_add_title_normal') }}"
|
||||
data-warning-add-only="{{ __('abo.confirm_add_warning') }}"
|
||||
data-warning-normal="{{ __('abo.confirm_add_warning_normal') }}">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="modal-confirm-add-label"></h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-warning mb-3">
|
||||
<i class="fa fa-exclamation-triangle"></i> <span id="confirm-add-warning-text"></span>
|
||||
</div>
|
||||
<table class="table table-sm mb-0">
|
||||
<tr>
|
||||
<td class="font-weight-bold">{{ __('order.article') }}:</td>
|
||||
<td id="confirm-add-product-name"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-bold">{{ __('tables.price') }}:</td>
|
||||
<td id="confirm-add-product-price"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-bold">{{ __('tables.quantity') }}:</td>
|
||||
<td id="confirm-add-qty-info"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('abo.confirm_add_cancel') }}</button>
|
||||
<button type="button" class="btn btn-primary" id="confirm-add-btn">{{ __('abo.confirm_add_ok') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
placeholder="mivita" required>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Basis-Informationen --}}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
|
|
@ -33,25 +34,183 @@
|
|||
@if($userSalesVolume)
|
||||
<tr>
|
||||
<td>{{ $userSalesVolume->date }}</td>
|
||||
<td>{{ $userSalesVolume->getFormattedPoints() }}</td>
|
||||
<td>{{ formatNumber($userSalesVolume->total_net) }} €</td>
|
||||
<td>{{ $userSalesVolume->getStatusType() }}</td>
|
||||
<td>
|
||||
<strong class="{{ $userSalesVolume->points < 0 ? 'text-danger' : '' }}">
|
||||
{{ $userSalesVolume->getFormattedPoints() }}
|
||||
</strong>
|
||||
</td>
|
||||
<td class="{{ $userSalesVolume->total_net < 0 ? 'text-danger' : '' }}">
|
||||
{{ formatNumber($userSalesVolume->total_net) }} €
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge badge-{{ $userSalesVolume->getStatusColor() }}">
|
||||
{{ $userSalesVolume->getStatusType() }}
|
||||
</span>
|
||||
</td>
|
||||
<td>@if($userSalesVolume->user)
|
||||
{{ $userSalesVolume->user->getFullName() }}
|
||||
@else
|
||||
nicht zugewiesen
|
||||
<span class="text-muted">nicht zugewiesen</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@if($userSalesVolume->message)
|
||||
<tr>
|
||||
<td colspan="5">{{ $userSalesVolume->message }}</td>
|
||||
<td colspan="5"><i class="fa fa-info-circle"></i> {{ $userSalesVolume->message }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- Erweiterte Informationen --}}
|
||||
@if($userSalesVolume)
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6">
|
||||
<h6 class="mb-2"><strong>Verknüpfungen</strong></h6>
|
||||
<div class="list-group list-group-flush">
|
||||
{{-- Bestellung --}}
|
||||
@if($userSalesVolume->shopping_order)
|
||||
<div class="list-group-item px-0 py-2">
|
||||
<strong>Bestellung:</strong>
|
||||
@if($userSalesVolume->status === 1)
|
||||
<a href="{{ route('admin_sales_users_detail', [$userSalesVolume->shopping_order->id]) }}"
|
||||
class="btn btn-xs btn-primary" target="_blank">
|
||||
<i class="fa fa-shopping-cart"></i> #{{ $userSalesVolume->shopping_order->id }}
|
||||
</a>
|
||||
@elseif($userSalesVolume->status === 2 || $userSalesVolume->status === 3)
|
||||
<a href="{{ route('admin_sales_customers_detail', [$userSalesVolume->shopping_order->id]) }}"
|
||||
class="btn btn-xs btn-secondary" target="_blank">
|
||||
<i class="fa fa-shopping-cart"></i> #{{ $userSalesVolume->shopping_order->id }}
|
||||
</a>
|
||||
@elseif($userSalesVolume->status === 6)
|
||||
@php
|
||||
$route = ($userSalesVolume->shopping_order->payment_for === 6 || $userSalesVolume->shopping_order->payment_for === 7)
|
||||
? route('admin_sales_customers_detail', [$userSalesVolume->shopping_order->id])
|
||||
: route('admin_sales_users_detail', [$userSalesVolume->shopping_order->id]);
|
||||
@endphp
|
||||
<a href="{{ $route }}" class="btn btn-xs btn-danger" target="_blank">
|
||||
<i class="fa fa-undo"></i> #{{ $userSalesVolume->shopping_order->id }} (Storno)
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Rechnung --}}
|
||||
@if($userSalesVolume->user_invoice)
|
||||
<div class="list-group-item px-0 py-2">
|
||||
@if($userSalesVolume->user_invoice->cancellation)
|
||||
<strong>Stornorechnung:</strong>
|
||||
<span class="badge badge-danger">Storno</span>
|
||||
<a href="{{ route('storage_file', [$userSalesVolume->user_invoice->shopping_order_id, 'cancellation', 'stream']) }}"
|
||||
class="btn btn-xs btn-danger" target="_blank">
|
||||
<i class="fa fa-file-pdf"></i> {{ $userSalesVolume->user_invoice->full_number }}
|
||||
</a>
|
||||
{{-- Link zur Original-Rechnung --}}
|
||||
@if($userSalesVolume->shopping_order && $userSalesVolume->shopping_order->user_invoice)
|
||||
<br><small class="text-muted">Original:
|
||||
<a href="{{ route('storage_file', [$userSalesVolume->shopping_order->id, 'invoice', 'stream']) }}"
|
||||
class="text-muted" target="_blank">
|
||||
{{ $userSalesVolume->shopping_order->user_invoice->full_number }}
|
||||
</a>
|
||||
</small>
|
||||
@endif
|
||||
@else
|
||||
<strong>Rechnung:</strong>
|
||||
<a href="{{ route('storage_file', [$userSalesVolume->user_invoice->shopping_order_id, 'invoice', 'stream']) }}"
|
||||
class="btn btn-xs btn-info" target="_blank">
|
||||
<i class="fa fa-file-pdf"></i> {{ $userSalesVolume->user_invoice->full_number }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Info/Notiz --}}
|
||||
@if($userSalesVolume->info)
|
||||
<div class="list-group-item px-0 py-2">
|
||||
<strong>Notiz:</strong> {{ $userSalesVolume->info }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<h6 class="mb-2"><strong>Monatssummen (kumuliert)</strong></h6>
|
||||
<div class="list-group list-group-flush">
|
||||
<div class="list-group-item px-0 py-2">
|
||||
<strong>KP-Punkte (Eigene):</strong>
|
||||
<span class="badge badge-primary">{{ formatNumber($userSalesVolume->month_KP_points) }}</span>
|
||||
</div>
|
||||
<div class="list-group-item px-0 py-2">
|
||||
<strong>TP-Punkte (Team):</strong>
|
||||
<span class="badge badge-success">{{ formatNumber($userSalesVolume->month_TP_points) }}</span>
|
||||
</div>
|
||||
<div class="list-group-item px-0 py-2">
|
||||
<strong>Shop-Punkte:</strong>
|
||||
<span class="badge badge-secondary">{{ formatNumber($userSalesVolume->month_shop_points) }}</span>
|
||||
</div>
|
||||
<div class="list-group-item px-0 py-2">
|
||||
<strong>Umsatz (netto):</strong>
|
||||
{{ formatNumber($userSalesVolume->month_total_net) }} €
|
||||
</div>
|
||||
<div class="list-group-item px-0 py-2">
|
||||
<strong>Shop-Umsatz:</strong>
|
||||
{{ formatNumber($userSalesVolume->month_shop_total_net) }} €
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Status-Details --}}
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-12">
|
||||
<h6 class="mb-2"><strong>Status-Details</strong></h6>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<span class="badge badge-{{ $userSalesVolume->getStatusColor() }} mr-2">
|
||||
<i class="fa fa-tag"></i> {{ $userSalesVolume->getStatusType() }}
|
||||
</span>
|
||||
<span class="badge badge-{{ $userSalesVolume->getStatusPointsColor() }} mr-2">
|
||||
<i class="fa fa-calculator"></i> {{ $userSalesVolume->getStatusPointsType() }}
|
||||
</span>
|
||||
@if($userSalesVolume->status_turnover)
|
||||
<span class="badge badge-{{ $userSalesVolume->getStatusTurnoverColor() }} mr-2">
|
||||
<i class="fa fa-chart-line"></i> {{ $userSalesVolume->getStatusTurnoverType() }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Änderungshistorie (Syslog) --}}
|
||||
@if($userSalesVolume->syslog && count($userSalesVolume->syslog) > 0)
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-12">
|
||||
<h6 class="mb-2"><strong>Änderungshistorie</strong></h6>
|
||||
<div class="alert alert-light p-2">
|
||||
<ul class="mb-0 pl-3">
|
||||
@foreach($userSalesVolume->syslog as $timestamp => $log_entry)
|
||||
<li><small><code>{{ $timestamp }}</code>: {{ $log_entry }}</small></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Timestamps --}}
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-12">
|
||||
<small class="text-muted">
|
||||
<i class="fa fa-clock"></i> Erstellt: {{ $userSalesVolume->created_at->format('d.m.Y H:i:s') }}
|
||||
@if($userSalesVolume->updated_at && $userSalesVolume->updated_at != $userSalesVolume->created_at)
|
||||
| Aktualisiert: {{ $userSalesVolume->updated_at->format('d.m.Y H:i:s') }}
|
||||
@endif
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<hr>
|
||||
@if($userSalesVolume->isCurrentMonthYear())
|
||||
<div class="form-row">
|
||||
|
|
|
|||
|
|
@ -51,6 +51,10 @@
|
|||
<div class="text-muted small">{{ __('E-Mail') }}</div>
|
||||
@if($shopping_user->faker_mail) "-" @else {{ $shopping_user->billing_email }} @endif
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="text-muted small">{{ __('account.preferred_language') }}</div>
|
||||
{{ \App\Models\ShoppingUser::getAvailableLanguages()[$shopping_user->language] ?? $shopping_user->language }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="m-0">
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
<a class="btn btn-sm btn-secondary mt-2" href="{{route('user_customer_edit', [$shopping_user->id])}}">{{ __('customer.edit_customer_data') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -283,10 +283,22 @@
|
|||
{{ Form::textarea('remarks', $shopping_user->remarks, array('placeholder'=>__('Comments'), 'class'=>'form-control', 'rows'=>4, 'id'=>'remarks')) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-6">
|
||||
<label class="form-label" for="language">{{ __('account.preferred_language') }}</label>
|
||||
<select class="selectpicker" name="language" id="language" data-style="btn-light">
|
||||
@foreach(\App\Models\ShoppingUser::getAvailableLanguages() as $code => $label)
|
||||
<option value="{{ $code }}" {{ $shopping_user->language === $code ? 'selected' : '' }}>
|
||||
{{ $label }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<p class="badge badge-default mt-2">{{ __('customer.language_hint') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
{{ Form::hidden('faker_mail', $shopping_user->faker_mail) }}
|
||||
{{ Form::hidden('language', $shopping_user->language) }}
|
||||
|
||||
@if($isView === 'customer-add')
|
||||
{{ Form::hidden('billing_email_1', $billing_email) }}
|
||||
|
|
|
|||
|
|
@ -345,11 +345,11 @@
|
|||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if($shipment->recipient && isset($shipment->recipient['street']))
|
||||
@if($shipment->recipient && isset($shipment->recipient['postnumber']))
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Straße:</td>
|
||||
<td class="font-weight-semibold">Postnummer:</td>
|
||||
<td>
|
||||
{{ $shipment->recipient['street'] }}
|
||||
{{ $shipment->recipient['postnumber'] }}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
|
@ -539,16 +539,24 @@
|
|||
<!-- Tracking Information -->
|
||||
@if($shipment->tracking_status || $shipment->dhl_shipment_no)
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-route text-info"></i>
|
||||
Tracking-Informationen
|
||||
</h5>
|
||||
@if($shipment->dhl_shipment_no)
|
||||
<a href="https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?lang=de&idc={{ $shipment->dhl_shipment_no }}"
|
||||
target="_blank"
|
||||
class="btn btn-sm btn-warning">
|
||||
<i class="fas fa-external-link-alt"></i>
|
||||
Bei DHL verfolgen
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if($shipment->tracking_status)
|
||||
<div class="alert alert-info">
|
||||
<h6 class="alert-heading">
|
||||
<div class="alert alert-info mb-4">
|
||||
<h6 class="alert-heading mb-1">
|
||||
<i class="fas fa-map-marker-alt"></i>
|
||||
Aktueller Status: {{ $shipment->tracking_status }}
|
||||
</h6>
|
||||
|
|
@ -559,24 +567,52 @@
|
|||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($shipment->dhl_shipment_no)
|
||||
<div class="text-center">
|
||||
<p>Verfolgen Sie diese Sendung direkt bei DHL:</p>
|
||||
<a href="https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?lang=de&idc={{ $shipment->dhl_shipment_no }}"
|
||||
target="_blank"
|
||||
class="btn btn-warning">
|
||||
<i class="fas fa-external-link-alt"></i>
|
||||
Bei DHL verfolgen
|
||||
</a>
|
||||
{{-- TODO: Tracking-Nummer ist nicht mehr verfügbar
|
||||
<a href="{{ route('public.tracking') }}?tracking_number={{ $shipment->dhl_shipment_no }}"
|
||||
target="_blank"
|
||||
class="btn btn-outline-info ml-2">
|
||||
<i class="fas fa-search"></i>
|
||||
Lokales Tracking
|
||||
</a>
|
||||
--}}
|
||||
|
||||
{{-- Tracking Events Timeline --}}
|
||||
@if($shipment->trackingEvents && $shipment->trackingEvents->count() > 0)
|
||||
<div class="tracking-timeline">
|
||||
@foreach($shipment->trackingEvents as $index => $event)
|
||||
<div class="d-flex mb-3 {{ $index === 0 ? '' : 'text-muted' }}">
|
||||
<div class="mr-3 text-center" style="min-width: 40px;">
|
||||
@if($index === 0)
|
||||
@if($event->status_code === 'delivered')
|
||||
<i class="fas fa-check-circle fa-lg text-success"></i>
|
||||
@elseif($event->status_code === 'transit')
|
||||
<i class="fas fa-truck fa-lg text-primary"></i>
|
||||
@elseif($event->status_code === 'out-for-delivery')
|
||||
<i class="fas fa-shipping-fast fa-lg text-warning"></i>
|
||||
@elseif($event->status_code === 'failure' || $event->status_code === 'exception')
|
||||
<i class="fas fa-exclamation-circle fa-lg text-danger"></i>
|
||||
@elseif($event->status_code === 'returned')
|
||||
<i class="fas fa-undo fa-lg text-secondary"></i>
|
||||
@else
|
||||
<i class="fas fa-circle fa-lg text-info"></i>
|
||||
@endif
|
||||
@else
|
||||
<i class="fas fa-circle text-muted" style="font-size: 0.6rem; margin-top: 6px;"></i>
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="{{ $index === 0 ? 'font-weight-bold' : '' }}">
|
||||
{{ $event->status_text }}
|
||||
</div>
|
||||
<small class="text-muted">
|
||||
{{ $event->event_time->format('d.m.Y H:i') }} Uhr
|
||||
@if($event->location)
|
||||
· {{ $event->location }}
|
||||
@endif
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
@if(!$loop->last)
|
||||
<div class="ml-3 border-left" style="height: 8px; margin-left: 19px;"></div>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
@elseif(!$shipment->tracking_status)
|
||||
<div class="text-center text-muted py-3">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Noch keine Tracking-Daten vorhanden. Klicken Sie auf "Tracking aktualisieren" um die Daten abzurufen.
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
{!! Form::open(['action' => route('admin_lead_store')."?show=".$show, 'class' => 'form-horizontal', 'id'=>'lead-form-validation']) !!}
|
||||
|
||||
<input type="hidden" name="user_id" value="{{ $user->id }}">
|
||||
|
||||
<div class="text-left mt-0 mb-2">
|
||||
<button type="submit" class="btn btn-submit btn-primary">{{ __('save') }}</button>
|
||||
<a href="{{ route('admin_leads') }}" class="btn btn-default">{{ __('back') }}</a>
|
||||
|
|
@ -46,7 +48,55 @@
|
|||
</div>
|
||||
|
||||
{!! Form::close() !!}
|
||||
|
||||
|
||||
<!-- Modal für Vertragsneuerstellung -->
|
||||
<div class="modal fade" id="modal-recreate-contract">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Beratervertrag neu erstellen</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="mb-3">
|
||||
<strong>Der Vertrag wird neu erstellt (DE @if($user->account->language !== 'de') + {{ strtoupper($user->account->language) }}@endif).</strong><br>
|
||||
Dies überschreibt die bestehenden Vertragsdateien.
|
||||
</p>
|
||||
<p class="mb-2">Welches Datum soll im Vertrag verwendet werden?</p>
|
||||
<div class="alert alert-info">
|
||||
@if($user->active_date)
|
||||
<strong>Bestehendes Vertragsdatum:</strong> {{ $user->getActiveDateFormat(false) }}
|
||||
@else
|
||||
<strong>Hinweis:</strong> Kein bestehendes Vertragsdatum gefunden.
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<form action="{{ route('admin_lead_store') }}?show={{$show}}" method="POST" class="d-inline">
|
||||
@csrf
|
||||
<input type="hidden" name="user_id" value="{{ $user->id }}">
|
||||
<input type="hidden" name="action" value="recreate_contract">
|
||||
<input type="hidden" name="use_current_date" value="1">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fa fa-calendar"></i> Mit aktuellem Datum
|
||||
</button>
|
||||
</form>
|
||||
@if($user->active_date)
|
||||
<form action="{{ route('admin_lead_store') }}?show={{$show}}" method="POST" class="d-inline">
|
||||
@csrf
|
||||
<input type="hidden" name="user_id" value="{{ $user->id }}">
|
||||
<input type="hidden" name="action" value="recreate_contract">
|
||||
<input type="hidden" name="use_current_date" value="0">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="fa fa-calendar-check"></i> Mit bestehendem Datum ({{ $user->getActiveDateFormat(false) }})
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modal template -->
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
<div class="card-body p-0">
|
||||
|
||||
{!! Form::open(['action' => route('admin_leads'), 'class' => 'form-horizontal', 'id'=>'form_admin_leads']) !!}
|
||||
|
||||
<div class="form-row align-items-center px-4 pb-2 pt-3">
|
||||
<div class="col-12 col-sm-4 col-md-4 col-lg-4 mb-1">
|
||||
<select class="selectpicker on_change_select" data-style="btn-default" name="leads_filter_sponsor_id" id="leads_filter_sponsor_id" data-live-search="true">
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
<strong>{{__('Daten vollständig, freigeschaltet')}}</strong>: {{ $user->getActiveDateFormat() }}</p>
|
||||
@if($user->files->count())
|
||||
@foreach($user->files()->whereIdentifier('contract')->get() as $file)
|
||||
<a class="btn btn-secondary" href="{{ route('storage_file', [$file->id, 'user']) }}" target="_blank">MIVITA_Beratervertrag.pdf</a>
|
||||
<a class="btn btn-secondary" href="{{ route('storage_file', [$file->id, 'user']) }}" target="_blank">{{ $file->original_name }}</a>
|
||||
@endforeach
|
||||
@endif
|
||||
@else
|
||||
|
|
@ -72,6 +72,7 @@
|
|||
@endif
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
|
||||
@if(!$user->active)
|
||||
<hr>
|
||||
@if($user->release_account)
|
||||
|
|
@ -83,6 +84,11 @@
|
|||
@else
|
||||
<strong><span class="text-danger">Berater muss Registrierung noch abschließen</span></strong>
|
||||
@endif
|
||||
@else
|
||||
<hr>
|
||||
<button type="button" class="btn btn-sm btn-info" data-toggle="modal" data-target="#modal-recreate-contract">
|
||||
<i class="fa fa-file-pdf"></i> Vertrag neu erstellen (DE @if($user->account->language !== 'de') | {{ strtoupper($user->account->language) }}@endif)
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -183,3 +189,4 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,56 @@
|
|||
<div class="modal-body modal-body-overflow">
|
||||
<table class="table user-view-table m-0">
|
||||
<tbody>
|
||||
{{-- Status & Business --}}
|
||||
<tr>
|
||||
<td>{{ __('team.account') }}:</td>
|
||||
<td>
|
||||
@if($user->isActive())
|
||||
<span class="badge badge-outline-success">{{ __('team.active') }}</span>
|
||||
@else
|
||||
<span class="badge badge-outline-danger">{{ __('team.not_active') }}</span>
|
||||
@endif
|
||||
@if($user->payment_account)
|
||||
{{ __('team.until') }}: {{ $user->getPaymentAccountDateFormat(false) }}
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@if($user->payment_shop)
|
||||
<tr>
|
||||
<td>{{ __('team.shop') }}:</td>
|
||||
<td>{{ __('team.until') }}: {{ $user->getPaymentShopDateFormat(false) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if($user->account->m_account)
|
||||
<tr>
|
||||
<td>{{ __('team.ID') }}:</td>
|
||||
<td>{{ $user->account->m_account }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if($user->user_level)
|
||||
<tr>
|
||||
<td>{{ __('team.career_level') }}:</td>
|
||||
<td>{{ \App\Services\TranslationHelper::transUserLevelName($user->user_level->name) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if($user->user_sponsor && $user->user_sponsor->account)
|
||||
<tr>
|
||||
<td>{{ __('team.sponsor') }}:</td>
|
||||
<td>{{ $user->user_sponsor->account->first_name }} {{ $user->user_sponsor->account->last_name }} | {{ $user->user_sponsor->email }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if($user->last_login)
|
||||
<tr>
|
||||
<td>{{ __('team.last_login') }}:</td>
|
||||
<td>{{ \Carbon\Carbon::parse($user->last_login)->format(\Util::formatDateTimeDB()) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
<tr>
|
||||
<td>{{ __('team.registered_at') }}:</td>
|
||||
<td>{{ $user->created_at ? $user->created_at->format(\Util::formatDateDB()) : '-' }}</td>
|
||||
</tr>
|
||||
<tr><td colspan="2"></td></tr>
|
||||
{{-- Stammdaten --}}
|
||||
<tr>
|
||||
<td>{{ __('Company name') }}:</td>
|
||||
<td> {{ $user->account->company }} </td>
|
||||
|
|
@ -47,6 +97,10 @@
|
|||
<td>{{ __('Country') }}:</td>
|
||||
<td>{{ $user->account->country->getLocated() }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ __('account.preferred_language') }}:</td>
|
||||
<td>{{ \App\Models\UserAccount::getAvailableLanguages()[$user->account->getLocale()] ?? $user->account->getLocale() }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ __('Date of birth') }}:</td>
|
||||
<td>{{ $user->account->birthday }}</td>
|
||||
|
|
@ -63,6 +117,18 @@
|
|||
<td>{{ __('E-Mail') }}:</td>
|
||||
<td>{{ $user->email }}</td>
|
||||
</tr>
|
||||
@if($user->account->tax_number)
|
||||
<tr>
|
||||
<td>{{ __('account.tax_number') }}:</td>
|
||||
<td>{{ $user->account->tax_number }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if($user->account->tax_identification_number)
|
||||
<tr>
|
||||
<td>{{ __('account.VAT_ID_number') }}:</td>
|
||||
<td>{{ $user->account->tax_identification_number }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
<tr>
|
||||
</tr>
|
||||
@if($user->account->same_as_billing)
|
||||
|
|
|
|||
|
|
@ -2,128 +2,536 @@
|
|||
|
||||
@section('content')
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@if (session('success'))
|
||||
<div class="alert alert-success alert-dismissible fade show">
|
||||
{{ session('success') }}
|
||||
<button type="button" class="close" data-dismiss="alert"><span>×</span></button>
|
||||
</div>
|
||||
@endif
|
||||
@if (session('error'))
|
||||
<div class="alert alert-danger alert-dismissible fade show">
|
||||
{{ session('error') }}
|
||||
<button type="button" class="close" data-dismiss="alert"><span>×</span></button>
|
||||
</div>
|
||||
@endif
|
||||
@if (session('info'))
|
||||
<div class="alert alert-info alert-dismissible fade show">
|
||||
{{ session('info') }}
|
||||
<button type="button" class="close" data-dismiss="alert"><span>×</span></button>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card">
|
||||
<h5 class="card-header">
|
||||
{{ __('navigation.payments') }} {{ __('navigation.tax_advisor') }}
|
||||
<i class="fas fa-file-invoice"></i> DATEV Export - Steuerberater
|
||||
</h5>
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
Modul ist in Arbeit! Noch nicht verwenden.
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{!! Form::open(['action' => route('admin_payments_taxadvisor_download'), 'class' => '']) !!}
|
||||
{!! Form::hidden('key', 'value') !!}
|
||||
<button type="submit" name="action" value="export" class="btn btn-md btn-primary mb-2"><i class="ion ion-md-download"></i> Export als xls</button>
|
||||
<hr>
|
||||
<div class="form-row align-items-center px-0 pb-2 pt-0">
|
||||
<div class="col-6 col-sm-4 col-md-4 col-lg-4 mb-1">
|
||||
<select class="custom-select on_change_select_filter" name="payment_taxadvisor_filter_month">
|
||||
@foreach($filter_months as $key=>$value)
|
||||
<option value="{{$key}}" @if(session('payment_taxadvisor_filter_month') == $key) selected @endif>{{$value}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6 col-sm-4 col-md-4 col-lg-4 mb-1">
|
||||
<select class="custom-select on_change_select_filter" name="payment_taxadvisor_filter_year">
|
||||
@foreach($filter_years as $key=>$value)
|
||||
<option value="{{$value}}" @if(session('payment_taxadvisor_filter_year') == $value) selected @endif>{{$value}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{!! Form::close() !!}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="table table-striped table-bordered" id="datatable-payment-taxadvisor">
|
||||
|
||||
<thead>
|
||||
<div class="form-row align-items-center px-0 pb-2 pt-0">
|
||||
<div class="col-6 col-sm-3 col-md-3 col-lg-2 mb-1">
|
||||
<label class="small mb-1">Monat</label>
|
||||
<select class="custom-select" name="payment_taxadvisor_filter_month" id="filter_month">
|
||||
@foreach ($filter_months as $key => $value)
|
||||
<option value="{{ $key }}" @if (session('payment_taxadvisor_filter_month') == $key) selected @endif>
|
||||
{{ $value }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6 col-sm-3 col-md-3 col-lg-2 mb-1">
|
||||
<label class="small mb-1">Jahr</label>
|
||||
<select class="custom-select" name="payment_taxadvisor_filter_year" id="filter_year">
|
||||
@foreach ($filter_years as $key => $value)
|
||||
<option value="{{ $value }}" @if (session('payment_taxadvisor_filter_year') == $value) selected @endif>
|
||||
{{ $value }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6 col-lg-4 mb-1 d-flex align-items-end">
|
||||
<button type="button" class="btn btn-info mr-2" id="btn-preview">
|
||||
<i class="fas fa-search"></i> Vorschau laden
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="btn-generate"
|
||||
@if ($current_export && $current_export->isLocked()) disabled @endif>
|
||||
<i class="fas fa-cogs"></i> Export generieren
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($current_export)
|
||||
<div class="alert alert-{{ $current_export->isLocked() ? 'secondary' : 'info' }} mt-3">
|
||||
<div class="d-flex justify-content-between align-items-center flex-wrap">
|
||||
<div class="mb-1">
|
||||
<strong>Aktueller Export:</strong>
|
||||
{!! $current_export->status_badge !!}
|
||||
— {{ $current_export->total_lines }} Zeilen
|
||||
({{ $current_export->invoice_count }} RE,
|
||||
{{ $current_export->credit_count }} GS,
|
||||
{{ $current_export->cancellation_count }} ST)
|
||||
— {{ $current_export->created_at->format('d.m.Y H:i') }}
|
||||
@if ($current_export->warning_count > 0)
|
||||
<span class="badge badge-warning ml-1">{{ $current_export->warning_count }}
|
||||
Warnungen</span>
|
||||
@endif
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<a href="{{ route('admin_payments_taxadvisor_download', $current_export->id) }}"
|
||||
class="btn btn-sm btn-success">
|
||||
<i class="fas fa-download"></i> CSV
|
||||
</a>
|
||||
@if (!$current_export->isLocked())
|
||||
<form action="{{ route('admin_payments_taxadvisor_lock', $current_export->id) }}"
|
||||
method="POST" class="d-inline" onsubmit="return confirm('Export wirklich sperren?')">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-sm btn-dark">
|
||||
<i class="fas fa-lock"></i> Sperren
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="preview-section" style="display:none;">
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="card text-center">
|
||||
<div class="card-body py-3">
|
||||
<div class="text-muted small">Rechnungen</div>
|
||||
<h4 class="mb-0" id="stat-invoices">0</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="card text-center">
|
||||
<div class="card-body py-3">
|
||||
<div class="text-muted small">Gutschriften</div>
|
||||
<h4 class="mb-0" id="stat-credits">0</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="card text-center">
|
||||
<div class="card-body py-3">
|
||||
<div class="text-muted small">Stornos</div>
|
||||
<h4 class="mb-0" id="stat-cancellations">0</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="card text-center">
|
||||
<div class="card-body py-3">
|
||||
<div class="text-muted small">Gesamt Zeilen</div>
|
||||
<h4 class="mb-0" id="stat-total">0</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-6 col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-body py-3">
|
||||
<div class="text-muted small">Umsatz (Haben)</div>
|
||||
<h5 class="mb-0 text-success" id="stat-revenue">0,00 EUR</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-body py-3">
|
||||
<div class="text-muted small">Provisionen (Soll)</div>
|
||||
<h5 class="mb-0 text-warning" id="stat-commissions">0,00 EUR</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-body py-3">
|
||||
<div class="text-muted small">Stornos (Soll)</div>
|
||||
<h5 class="mb-0 text-danger" id="stat-cancellation-amount">0,00 EUR</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="validation-section" style="display:none;">
|
||||
<div id="validation-errors" class="alert alert-danger" style="display:none;">
|
||||
<strong><i class="fas fa-exclamation-triangle"></i> Fehler:</strong>
|
||||
<ul id="validation-errors-list" class="mb-0 mt-1"></ul>
|
||||
</div>
|
||||
<div id="validation-warnings" class="alert alert-warning" style="display:none;">
|
||||
<strong><i class="fas fa-exclamation-circle"></i> Warnungen:</strong>
|
||||
<ul id="validation-warnings-list" class="mb-0 mt-1"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h5 class="card-header">Vorschau: Konten-Zusammenfassung</h5>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-striped table-bordered mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{__('#') }}</th>
|
||||
<th>{{__('Umsatz (ohne Soll/Haben-Kz)')}}</th>
|
||||
<th>{{__('Soll/Haben-Kennzeichen')}}</th>
|
||||
<th>{{__('Konto')}}</th>
|
||||
<th>{{__('Gegenkonto (ohne BU-Schlüssel)')}}</th>
|
||||
<th>{{__('BU-Schlüssel')}}</th>
|
||||
<th>{{__('Belegdatum')}}</th>
|
||||
<th>{{__('Belegfeld 1')}}</th>
|
||||
<th>{{__('Buchungstext')}}</th>
|
||||
<th>{{__('Datum')}}</th>
|
||||
<th>{{__('Rechnung')}}</th>
|
||||
|
||||
<th>Konto</th>
|
||||
<th>BU-Schl.</th>
|
||||
<th>S/H</th>
|
||||
<th>Anzahl</th>
|
||||
<th class="text-right">Summe</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="preview-table-body">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($current_export)
|
||||
<div class="card mt-3">
|
||||
<h5 class="card-header">
|
||||
Buchungszeilen (Export {{ $current_export->period_label }})
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="table table-striped table-bordered" id="datatable-datev-lines">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Typ</th>
|
||||
<th>Umsatz</th>
|
||||
<th>S/H</th>
|
||||
<th>Konto</th>
|
||||
<th>Gegenkonto</th>
|
||||
<th>BU</th>
|
||||
<th>Belegdatum</th>
|
||||
<th>Belegfeld 1</th>
|
||||
<th>Buchungstext</th>
|
||||
<th>USt-ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($recent_exports->count() > 0)
|
||||
<div class="card mt-3">
|
||||
<h5 class="card-header">
|
||||
<i class="fas fa-history"></i> Export-Historie
|
||||
</h5>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-striped table-bordered mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Periode</th>
|
||||
<th>Status</th>
|
||||
<th>Zeilen</th>
|
||||
<th class="text-right">Umsatz</th>
|
||||
<th class="text-right">Provisionen</th>
|
||||
<th>Erstellt</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($recent_exports as $exp)
|
||||
<tr>
|
||||
<td>{{ $exp->period_label }}</td>
|
||||
<td>{!! $exp->status_badge !!}</td>
|
||||
<td>{{ $exp->total_lines }}</td>
|
||||
<td class="text-right">{{ number_format($exp->total_revenue, 2, ',', '.') }} EUR</td>
|
||||
<td class="text-right">{{ number_format($exp->total_commissions, 2, ',', '.') }} EUR</td>
|
||||
<td>{{ $exp->created_at->format('d.m.Y H:i') }}</td>
|
||||
<td>
|
||||
<a href="{{ route('admin_payments_taxadvisor_download', $exp->id) }}"
|
||||
class="btn btn-xs btn-success" title="Download">
|
||||
<i class="fas fa-download"></i>
|
||||
</a>
|
||||
@if (!$exp->isLocked())
|
||||
<form action="{{ route('admin_payments_taxadvisor_lock', $exp->id) }}"
|
||||
method="POST" class="d-inline" onsubmit="return confirm('Export sperren?')">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-xs btn-dark" title="Sperren">
|
||||
<i class="fas fa-lock"></i>
|
||||
</button>
|
||||
</form>
|
||||
<form action="{{ route('admin_payments_taxadvisor_destroy', $exp->id) }}"
|
||||
method="POST" class="d-inline"
|
||||
onsubmit="return confirm('Export wirklich loeschen?')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-xs btn-danger" title="Loeschen">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<span class="badge badge-dark"><i class="fas fa-lock"></i></span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="modal fade" id="generateModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">DATEV Export generieren</h5>
|
||||
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Soll der DATEV-Export fuer <strong id="modal-period"></strong> generiert werden?</p>
|
||||
<p class="text-muted small">Ein vorhandener frueherer Export wird ersetzt.</p>
|
||||
<div id="modal-preview-stats" class="mb-2"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Abbrechen</button>
|
||||
<form id="form-generate" method="POST" action="{{ route('admin_payments_taxadvisor_generate') }}">
|
||||
@csrf
|
||||
<input type="hidden" name="month" id="generate-month">
|
||||
<input type="hidden" name="year" id="generate-year">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-cogs"></i> Jetzt generieren
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
<script>
|
||||
function fmtNum(num) {
|
||||
return new Intl.NumberFormat('de-DE', {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
}).format(num);
|
||||
}
|
||||
|
||||
$( document ).ready(function() {
|
||||
var oTable = $('#datatable-payment-taxadvisor').DataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"stateSave": true,
|
||||
"searching": false,
|
||||
function renderValidationEntry(entry) {
|
||||
if (typeof entry === 'string') {
|
||||
return entry;
|
||||
}
|
||||
var html = '<span>' + entry.message + '</span>';
|
||||
var links = [];
|
||||
if (entry.source_id && entry.belegfeld1) {
|
||||
links.push('<a href="{{ url('/admin/payments/invoice') }}?search=' + entry.belegfeld1 +
|
||||
'" target="_blank" title="Rechnung anzeigen"><i class="fas fa-file-invoice"></i> ' +
|
||||
entry.belegfeld1 + '</a>');
|
||||
}
|
||||
if (entry.user_id) {
|
||||
links.push('<a href="{{ url('/admin/sales/users/detail') }}/' + entry.user_id +
|
||||
'" target="_blank" title="Berater anzeigen"><i class="fas fa-user"></i> User #' + entry
|
||||
.user_id + '</a>');
|
||||
}
|
||||
if (links.length > 0) {
|
||||
html += ' <span class="ml-2">' + links.join(' · ') + '</span>';
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
$('#btn-preview').on('click', function() {
|
||||
var btn = $(this);
|
||||
var month = $('#filter_month').val();
|
||||
var year = $('#filter_year').val();
|
||||
btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Laden...');
|
||||
|
||||
$.ajax({
|
||||
url: '{!! route('admin_payments_taxadvisor_preview') !!}',
|
||||
method: 'POST',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}',
|
||||
month: month,
|
||||
year: year
|
||||
},
|
||||
success: function(res) {
|
||||
if (res.success) {
|
||||
var s = res.data.summary;
|
||||
$('#stat-invoices').text(s.invoice_count);
|
||||
$('#stat-credits').text(s.credit_count);
|
||||
$('#stat-cancellations').text(s.cancellation_count);
|
||||
$('#stat-total').text(s.total_lines);
|
||||
$('#stat-revenue').text(fmtNum(s.total_revenue) + ' EUR');
|
||||
$('#stat-commissions').text(fmtNum(s.total_commissions) + ' EUR');
|
||||
$('#stat-cancellation-amount').text(fmtNum(s.total_cancellations) +
|
||||
' EUR');
|
||||
|
||||
var tbody = $('#preview-table-body');
|
||||
tbody.empty();
|
||||
var grouped = res.data.grouped;
|
||||
if (grouped && grouped.length > 0) {
|
||||
for (var i = 0; i < grouped.length; i++) {
|
||||
var r = grouped[i];
|
||||
var cls = r.soll_haben === 'H' ? 'badge-success' :
|
||||
'badge-warning';
|
||||
tbody.append('<tr><td>' + r.konto + '</td><td>' + r
|
||||
.bu_schluessel + '</td><td><span class="badge ' +
|
||||
cls + '">' + r.soll_haben + '</span></td><td>' + r
|
||||
.count + '</td><td class="text-right">' + fmtNum(r
|
||||
.total) + ' EUR</td></tr>');
|
||||
}
|
||||
} else {
|
||||
tbody.append(
|
||||
'<tr><td colspan="5" class="text-center text-muted">Keine Daten</td></tr>'
|
||||
);
|
||||
}
|
||||
|
||||
var v = res.data.validation;
|
||||
$('#validation-section').show();
|
||||
if (v.errors && v.errors.length > 0) {
|
||||
var el = $('#validation-errors-list');
|
||||
el.empty();
|
||||
for (var e = 0; e < v.errors.length; e++) {
|
||||
el.append('<li>' + renderValidationEntry(v.errors[e]) +
|
||||
'</li>');
|
||||
}
|
||||
$('#validation-errors').show();
|
||||
} else {
|
||||
$('#validation-errors').hide();
|
||||
}
|
||||
|
||||
if (v.warnings && v.warnings.length > 0) {
|
||||
var wl = $('#validation-warnings-list');
|
||||
wl.empty();
|
||||
var max = Math.min(v.warnings.length, 20);
|
||||
for (var w = 0; w < max; w++) {
|
||||
wl.append('<li>' + renderValidationEntry(v.warnings[w]) +
|
||||
'</li>');
|
||||
}
|
||||
if (v.warnings.length > 20) {
|
||||
wl.append('<li><em>... und ' + (v.warnings.length - 20) +
|
||||
' weitere</em></li>');
|
||||
}
|
||||
$('#validation-warnings').show();
|
||||
} else {
|
||||
$('#validation-warnings').hide();
|
||||
}
|
||||
|
||||
$('#preview-section').slideDown();
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert('Fehler: ' + (xhr.responseJSON ? xhr.responseJSON.message :
|
||||
'Unbekannt'));
|
||||
},
|
||||
complete: function() {
|
||||
btn.prop('disabled', false).html(
|
||||
'<i class="fas fa-search"></i> Vorschau laden');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#btn-generate').on('click', function() {
|
||||
var month = $('#filter_month').val();
|
||||
var year = $('#filter_year').val();
|
||||
var monthText = $('#filter_month option:selected').text();
|
||||
$('#modal-period').text(monthText + ' ' + year);
|
||||
$('#generate-month').val(month);
|
||||
$('#generate-year').val(year);
|
||||
var stats = '';
|
||||
var inv = $('#stat-invoices').text();
|
||||
if (inv !== '0') {
|
||||
stats = '<div class="small text-muted">' + inv + ' Rechnungen, ' + $('#stat-credits')
|
||||
.text() + ' Gutschriften, ' + $('#stat-cancellations').text() + ' Stornos</div>';
|
||||
}
|
||||
$('#modal-preview-stats').html(stats);
|
||||
$('#generateModal').modal('show');
|
||||
});
|
||||
|
||||
$('#filter_month, #filter_year').on('change', function() {
|
||||
var month = $('#filter_month').val();
|
||||
var year = $('#filter_year').val();
|
||||
window.location.href = '{!! route('admin_payments_taxadvisor') !!}?payment_taxadvisor_filter_month=' + month +
|
||||
'&payment_taxadvisor_filter_year=' + year;
|
||||
});
|
||||
|
||||
@if ($current_export)
|
||||
$('#datatable-datev-lines').DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
stateSave: true,
|
||||
ajax: {
|
||||
url: '{!! route('admin_payments_taxadvisor_datatable') !!}',
|
||||
data: function(d) {
|
||||
d.payment_taxadvisor_filter_month = $('select[name=payment_taxadvisor_filter_month]').val();
|
||||
d.payment_taxadvisor_filter_year = $('select[name=payment_taxadvisor_filter_year]').val();
|
||||
d.export_id = {{ $current_export->id }};
|
||||
}
|
||||
},
|
||||
"order": [[0, "asc" ]],
|
||||
"columns": [
|
||||
{ data: 'id', orderable: true, searchable: false },
|
||||
{ data: 'turnover', name: 'turnover', orderable: false, searchable: false },
|
||||
{ data: 'debit_credit_indicator', name: 'debit_credit_indicator', orderable: false, searchable: false },
|
||||
{ data: 'account', name: 'account', orderable: false, searchable: false },
|
||||
{ data: 'contra_account', name: 'contra_account', orderable: false, searchable: false },
|
||||
{ data: 'bu_key', name: 'bu_key', orderable: false, searchable: false },
|
||||
{ data: 'voucher_date', name: 'voucher_date', orderable: true, searchable: false },
|
||||
{ data: 'document_field_1', name: 'document_field_1', orderable: false, searchable: false },
|
||||
{ data: 'posting_text', name: 'posting_text', orderable: false, searchable: false },
|
||||
{ data: 'date', name: 'date', orderable: true, searchable: false },
|
||||
|
||||
{ data: 'invoice', name: 'invoice', searchable: false },
|
||||
|
||||
|
||||
order: [
|
||||
[0, 'asc']
|
||||
],
|
||||
"bLengthChange": false,
|
||||
"iDisplayLength": 100,
|
||||
"language": {
|
||||
"url": "/js/datatables-{{ \App::getLocale() }}.json"
|
||||
columns: [{
|
||||
data: 'line_number',
|
||||
orderable: true,
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
data: 'source_type_label',
|
||||
orderable: false,
|
||||
searchable: true
|
||||
},
|
||||
{
|
||||
data: 'amount_display',
|
||||
orderable: false,
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
data: 'soll_haben',
|
||||
orderable: false,
|
||||
searchable: true
|
||||
},
|
||||
{
|
||||
data: 'konto',
|
||||
orderable: false,
|
||||
searchable: true
|
||||
},
|
||||
{
|
||||
data: 'gegenkonto',
|
||||
orderable: false,
|
||||
searchable: true
|
||||
},
|
||||
{
|
||||
data: 'bu_schluessel',
|
||||
orderable: false,
|
||||
searchable: true
|
||||
},
|
||||
{
|
||||
data: 'belegdatum_display',
|
||||
orderable: false,
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
data: 'belegfeld1',
|
||||
orderable: false,
|
||||
searchable: true
|
||||
},
|
||||
{
|
||||
data: 'buchungstext',
|
||||
orderable: false,
|
||||
searchable: true
|
||||
},
|
||||
{
|
||||
data: 'eu_ustid',
|
||||
orderable: false,
|
||||
searchable: true
|
||||
},
|
||||
],
|
||||
bLengthChange: false,
|
||||
iDisplayLength: 50,
|
||||
language: {
|
||||
url: '/js/datatables-{{ \App::getLocale() }}.json'
|
||||
}
|
||||
});
|
||||
@endif
|
||||
});
|
||||
</script>
|
||||
|
||||
$('select.on_change_select_filter').on('change', function(){
|
||||
oTable.draw();
|
||||
});
|
||||
|
||||
$('input.on_keyup_input_filter').on('keyup', function(){
|
||||
oTable.draw();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -121,6 +121,26 @@
|
|||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label class="form-label">Versandkostenfrei für Berater (FcB.)</label>
|
||||
<label class="custom-control custom-checkbox">
|
||||
{!! Form::checkbox('free_shipping_consultant', 1, $product->free_shipping_consultant, ['class'=>'custom-control-input', 'id'=>'free_shipping_consultant']) !!}
|
||||
<span class="custom-control-label">Versandkosten für Berater sind bei diesem Produkt immer 0 (z.B. Starterpakete).</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label class="form-label">Reine Mitgliedschaft (MoP.)</label>
|
||||
<label class="custom-control custom-checkbox">
|
||||
{!! Form::checkbox('is_membership_only', 1, $product->is_membership_only, ['class'=>'custom-control-input', 'id'=>'is_membership_only']) !!}
|
||||
<span class="custom-control-label">Dieses Produkt ist eine reine Mitgliedschaft ohne Starterpaket (Warnung im Wizard).</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-8">
|
||||
<label class="form-label">Kaufeinschränkung Berater</label>
|
||||
|
|
|
|||
|
|
@ -4,14 +4,15 @@
|
|||
<div class="row">
|
||||
<div class="col-md-2 mb-1">
|
||||
<strong class="mr-2">{{ __('Status') }}:</strong>
|
||||
<span class="text-big">
|
||||
{!! \App\Services\Payment::getShoppingOrderBadge($shopping_order) !!}
|
||||
</span>
|
||||
<div class="d-flex flex-wrap align-items-center mt-1" style="gap: 6px;">
|
||||
<span class="text-big">
|
||||
{!! \App\Services\Payment::getShoppingOrderBadge($shopping_order) !!}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-1">
|
||||
<div class="col-md-3 mb-1">
|
||||
<strong class="mr-2">{{ __('order.shipping') }}:</strong>
|
||||
<div style="display: inline-block;">
|
||||
@if($shopping_order->payment_for !== 8)
|
||||
<div class="d-flex flex-wrap align-items-center mt-1" style="gap: 6px;"> @if($shopping_order->payment_for !== 8)
|
||||
@if ($isAdmin)
|
||||
<button type="button" class="btn btn-sm btn-{{ $shopping_order->getShippedColor() }}"
|
||||
data-toggle="modal" data-target="#modals-shipped" data-id="{{ $shopping_order->id }}"
|
||||
|
|
@ -37,15 +38,26 @@
|
|||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-1">
|
||||
<div class="col-md-4 mb-2">
|
||||
<strong class="mr-2">{{ __('order.invoice') }}:</strong>
|
||||
<div style="display: inline-block;">
|
||||
<div class="d-flex flex-wrap align-items-center mt-1" style="gap: 6px;">
|
||||
@if ($isAdmin)
|
||||
@if ($shopping_order->isInvoice())
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'invoice', 'download']) }}"
|
||||
class="btn btn-primary btn-sm"><i class="fa fa-download"></i></a>
|
||||
class="btn btn-primary btn-sm" title="Download DE"><i class="fa fa-download"></i></a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'invoice', 'stream']) }}"
|
||||
target="_blank" class="btn btn-warning btn-sm"><i class="fa fa-eye"></i></a>
|
||||
target="_blank" class="btn btn-warning btn-sm" title="Ansicht DE"><i class="fa fa-eye"></i></a>
|
||||
{{-- Lokalisierte Versionen --}}
|
||||
@foreach($shopping_order->user_invoice->getAvailableLocales() as $locale)
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'invoice', 'download', $locale]) }}"
|
||||
class="btn btn-outline-primary btn-sm" title="Download {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-download"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'invoice', 'stream', $locale]) }}"
|
||||
class="btn btn-outline-warning btn-sm" title="Ansicht {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-eye"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
@endforeach
|
||||
@if (Auth::user()->isSySAdmin())
|
||||
<button type="button" class="btn btn-sm btn-info" data-toggle="modal"
|
||||
data-target="#modals-invoice" data-id="{{ $shopping_order->id }}" //TODO
|
||||
|
|
@ -67,9 +79,20 @@
|
|||
@else
|
||||
@if ($shopping_order->isInvoice())
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'invoice', 'download']) }}"
|
||||
class="btn btn-primary btn-sm"><i class="fa fa-download"></i></a>
|
||||
class="btn btn-primary btn-sm" title="Download DE"><i class="fa fa-download"></i></a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'invoice', 'stream']) }}"
|
||||
target="_blank" class="btn btn-warning btn-sm"><i class="fa fa-eye"></i></a>
|
||||
target="_blank" class="btn btn-warning btn-sm" title="Ansicht DE"><i class="fa fa-eye"></i></a>
|
||||
{{-- Lokalisierte Versionen --}}
|
||||
@foreach($shopping_order->user_invoice->getAvailableLocales() as $locale)
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'invoice', 'download', $locale]) }}"
|
||||
class="btn btn-outline-primary btn-sm" title="Download {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-download"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'invoice', 'stream', $locale]) }}"
|
||||
class="btn btn-outline-warning btn-sm" title="Ansicht {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-eye"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
@endforeach
|
||||
@endif
|
||||
@endif
|
||||
@if (($shopping_order->txaction === 'extern' || $shopping_order->txaction === 'extern_paid') && $shopping_order->wp_invoice_path)
|
||||
|
|
@ -78,19 +101,65 @@
|
|||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-1">
|
||||
@if ($isAdmin && $shopping_order->payment_for != 8)
|
||||
@if ($isAdmin && $shopping_order->payment_for != 8)
|
||||
<div class="col-md-3 mb-2">
|
||||
|
||||
<strong class="mr-2">{{ __('order.delivery_note') }}:</strong>
|
||||
<div style="display: inline-block;">
|
||||
<div class="d-flex flex-wrap align-items-center mt-1" style="gap: 6px;">
|
||||
@if ($shopping_order->isInvoice())
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'delivery', 'download']) }}"
|
||||
class="btn btn-primary btn-sm"><i class="fa fa-download"></i></a>
|
||||
class="btn btn-primary btn-sm" title="Download DE"><i class="fa fa-download"></i></a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'delivery', 'stream']) }}"
|
||||
target="_blank" class="btn btn-warning btn-sm"><i class="fa fa-eye"></i></a>
|
||||
target="_blank" class="btn btn-warning btn-sm" title="Ansicht DE"><i class="fa fa-eye"></i></a>
|
||||
{{-- Lokalisierte Versionen --}}
|
||||
@foreach($shopping_order->user_invoice->getAvailableLocales() as $locale)
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'delivery', 'download', $locale]) }}"
|
||||
class="btn btn-outline-primary btn-sm" title="Download {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-download"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'delivery', 'stream', $locale]) }}"
|
||||
class="btn btn-outline-warning btn-sm" title="Ansicht {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-eye"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
<div class="col-md-3 mb-2">
|
||||
@if (!$isAdmin && $shopping_order->isCancellationInvoice())
|
||||
@php
|
||||
$cancellation_invoice = $shopping_order->getCancellationInvoice();
|
||||
@endphp
|
||||
@if($cancellation_invoice)
|
||||
<strong class="mr-2">Stornorechnung:</strong><span class="badge badge-danger">{{ $cancellation_invoice->full_number }}</span>
|
||||
<br>
|
||||
<div class="d-flex flex-wrap align-items-center mt-1" style="gap: 6px;">
|
||||
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'cancellation', 'download']) }}"
|
||||
class="btn btn-danger btn-sm" title="Stornorechnung herunterladen DE">
|
||||
<i class="fa fa-download"></i>
|
||||
</a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'cancellation', 'stream']) }}"
|
||||
target="_blank" class="btn btn-danger btn-sm" title="Stornorechnung anzeigen DE">
|
||||
<i class="fa fa-eye"></i>
|
||||
</a>
|
||||
{{-- Lokalisierte Versionen der Stornorechnung --}}
|
||||
@foreach($cancellation_invoice->getAvailableLocales() as $locale)
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'cancellation', 'download', $locale]) }}"
|
||||
class="btn btn-outline-danger btn-sm" title="Download {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-download"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'cancellation', 'stream', $locale]) }}"
|
||||
class="btn btn-outline-danger btn-sm" title="Ansicht {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-eye"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -122,7 +191,7 @@
|
|||
|
||||
<div class="card-body pb-1">
|
||||
<div class="row">
|
||||
<div class="col-md-12 mb-3">
|
||||
<div class="col-md-9 mb-3">
|
||||
<div class="text-muted small">{{ __('order.points_turnover_assigned') }}</div>
|
||||
@if($shopping_order->user_sales_volume && $shopping_order->user_sales_volume->user)
|
||||
{{ $shopping_order->user_sales_volume->user->getFullName() }}
|
||||
|
|
@ -133,7 +202,48 @@
|
|||
data-action="shopping-order-change-points" data-view="{{ $isView }}"
|
||||
data-route="{{ route('modal_load') }}"><span class="fa fa-edit"></span></button>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
@if ($isAdmin)
|
||||
@if ($shopping_order->isCancellationInvoice())
|
||||
@php
|
||||
$cancellation_invoice = $shopping_order->getCancellationInvoice();
|
||||
@endphp
|
||||
@if($cancellation_invoice)
|
||||
<strong class="mr-2">Stornorechnung:</strong><br>
|
||||
<span class="badge badge-danger">{{ $cancellation_invoice->full_number }}</span>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'cancellation', 'download']) }}"
|
||||
class="btn btn-danger btn-sm" title="Stornorechnung herunterladen DE">
|
||||
<i class="fa fa-download"></i>
|
||||
</a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'cancellation', 'stream']) }}"
|
||||
target="_blank" class="btn btn-danger btn-sm" title="Stornorechnung anzeigen DE">
|
||||
<i class="fa fa-eye"></i>
|
||||
</a>
|
||||
{{-- Lokalisierte Versionen der Stornorechnung --}}
|
||||
@foreach($cancellation_invoice->getAvailableLocales() as $locale)
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'cancellation', 'download', $locale]) }}"
|
||||
class="btn btn-outline-danger btn-sm" title="Download {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-download"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
<a href="{{ route('storage_file', [$shopping_order->id, 'cancellation', 'stream', $locale]) }}"
|
||||
class="btn btn-outline-danger btn-sm" title="Ansicht {{ strtoupper($locale) }}">
|
||||
<i class="fa fa-eye"></i> {{ strtoupper($locale) }}
|
||||
</a>
|
||||
@endforeach
|
||||
<br><small class="text-muted">Erstellt am: {{ $cancellation_invoice->date }}</small>
|
||||
@endif
|
||||
@else
|
||||
@if ($shopping_order->isInvoice())
|
||||
<button type="button" class="btn btn-sm btn-outline-warning" data-toggle="modal"
|
||||
data-target="#modals-cancellation-invoice" data-id="{{ $shopping_order->id }}"
|
||||
data-back="{{ url()->current() }}" data-action="create_cancellation_invoice">
|
||||
<span class="fa fa-undo"></span> <strong>Stornorechnung erstellen</strong>
|
||||
</button>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -324,6 +434,10 @@
|
|||
<div class="text-muted small">{{ __('Country') }}</div>
|
||||
{{ $shopping_order->shopping_user->billing_country->getLocated() }}
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="text-muted small">{{ __('account.preferred_language') }}</div>
|
||||
{{ \App\Models\ShoppingUser::getAvailableLanguages()[$shopping_order->shopping_user->language] ?? $shopping_order->shopping_user->language }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Billing -->
|
||||
|
|
@ -671,7 +785,7 @@
|
|||
<div class="form-group col-sm-12">
|
||||
<label class="custom-control custom-checkbox">
|
||||
{!! Form::checkbox('invoice_send_mail', 1, false, ['class' => 'custom-control-input']) !!}
|
||||
<span class="custom-control-label">{{ __('order.invoice') }} <strong>nicht</strong> senden an:
|
||||
<span class="custom-control-label">{{ __('order.invoice') }} senden an:
|
||||
{{ $shopping_order->shopping_user->billing_email }}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
|
@ -713,6 +827,63 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="modals-cancellation-invoice">
|
||||
<div class="modal-dialog">
|
||||
<form class="modal-content form-prevent-multiple-submits"
|
||||
action="{{ route('admin_sales_invoice_cancellation') }}" method="post">
|
||||
@csrf
|
||||
<input type="hidden" name="id" value="{{ $shopping_order->id }}">
|
||||
<input type="hidden" name="action" value="create_cancellation_invoice">
|
||||
<input type="hidden" name="back" value="{{ url()->current() }}">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">{{ __('Stornorechnung erstellen') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-warning">
|
||||
<strong>Achtung!</strong> Sie sind dabei, eine Stornorechnung zu erstellen. Diese wird die
|
||||
ursprüngliche Rechnung mit negativen Beträgen stornieren.
|
||||
</div>
|
||||
<div class="form-group col-sm-12">
|
||||
<label class="form-label">{{ __('Ursprüngliche Rechnung') }}</label>
|
||||
<div class="form-control-plaintext">
|
||||
<strong>Rechnungsnummer:</strong>
|
||||
{{ App\Services\Invoice::getNumber($shopping_order) }}<br>
|
||||
<strong>Rechnungsdatum:</strong> {{ App\Services\Invoice::getDate($shopping_order) }}<br>
|
||||
<strong>Betrag:</strong> {{ $shopping_order->getFormattedTotalShipping() }} €
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-12">
|
||||
<label class="form-label" for="cancellation_date">{{ __('Stornodatum') }}</label>
|
||||
{!! Form::text('cancellation_date', now()->format('d.m.Y'), ['class' => 'form-control datepicker-base']) !!}
|
||||
</div>
|
||||
<div class="form-group col-sm-12">
|
||||
<label class="form-label" for="cancellation_number">{{ __('Stornonummer') }}</label>
|
||||
{!! Form::text('cancellation_number', App\Services\Invoice::getInvoiceNumber(), [
|
||||
'class' => 'form-control',
|
||||
'disabled',
|
||||
]) !!}
|
||||
<em> nächste Rechnungsnummer <a href="{{ route('admin_settings') }}"><i
|
||||
class="fa fa-edit"></i></a></em>
|
||||
</div>
|
||||
<div class="form-group col-sm-12">
|
||||
<label class="custom-control custom-checkbox">
|
||||
{!! Form::checkbox('cancellation_send_mail', 1, false, ['class' => 'custom-control-input']) !!}
|
||||
<span class="custom-control-label">Stornorechnung an
|
||||
{{ $shopping_order->shopping_user->billing_email }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default"
|
||||
data-dismiss="modal">{{ __('close') }}</button>
|
||||
<button type="submit" class="btn btn-danger button-prevent-multiple-submits"><i
|
||||
class="spinner fa fa-spinner fa-spin"></i> Stornorechnung erstellen</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
|
|
|||
|
|
@ -136,8 +136,13 @@
|
|||
<!-- DHL Standard-Einstellungen -->
|
||||
<div class="form-row">
|
||||
<div class="col-sm-12">
|
||||
<h5>Standard-Einstellungen</h5>
|
||||
<h5>Standard-Einstellungen @if(config('dhl.config_source') == 'database')
|
||||
<span class="badge badge-success">Database</span>
|
||||
@else
|
||||
<span class="badge badge-primary">Environment</span>
|
||||
@endif</h5>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('API Basis URL') }}*</label>
|
||||
{{ Form::text('settings[dhl_base_url][val]', \App\Models\Setting::getContentBySlug('dhl_base_url') ?: 'https://api-eu.dhl.com', array('class'=>'form-control')) }}
|
||||
|
|
|
|||
692
resources/views/admin/user/cleanup/index.blade.php
Normal file
692
resources/views/admin/user/cleanup/index.blade.php
Normal file
|
|
@ -0,0 +1,692 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@push('head')
|
||||
<style>
|
||||
/* Bootstrap-select Dropdown im Modal */
|
||||
.bootstrap-select .dropdown-menu {
|
||||
z-index: 10060 !important;
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<h4 class="font-weight-bold py-2 mb-2">
|
||||
<i class="ion ion-ios-people"></i> {{ __('navigation.user_cleanup') }}
|
||||
</h4>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<div class="alert alert-info">
|
||||
<strong>Info:</strong> Diese Übersicht zeigt alle deaktivierten und gelöschten User.
|
||||
Deaktivierte User können ihre Downline behalten oder an den Sponsor übertragen haben.
|
||||
Gelöschte User haben alle Daten an den Sponsor übertragen.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nav-tabs-top mb-4">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="{{ route('admin_user_cleanup') }}">
|
||||
<i class="ion ion-ios-people"></i> Deaktivierte/Gelöschte User
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin_user_cleanup_logs') }}">
|
||||
<i class="ion ion-md-git-network"></i> Downline-Übertragungen
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin_user_cleanup_shopping_logs') }}">
|
||||
<i class="ion ion-md-cart"></i> Kunden-Übertragungen
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="datatables-cleanup table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>{{ __('tables.firstname') }}</th>
|
||||
<th>{{ __('tables.lastname') }}</th>
|
||||
<th>{{ __('E-Mail') }}</th>
|
||||
<th>M-Account</th>
|
||||
<th>Status</th>
|
||||
<th>Gelöscht am</th>
|
||||
<th>Account bis</th>
|
||||
<th>Sponsor</th>
|
||||
<th>Pre-Sponsor</th>
|
||||
<th>Downline</th>
|
||||
<th>Kunden</th>
|
||||
<th> #</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal User Historie -->
|
||||
<div class="modal fade" id="modal-user-history" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">
|
||||
<i class="fa fa-history"></i> User Historie & Details
|
||||
</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
|
||||
</div>
|
||||
<div class="modal-body" id="history-content" style="max-height: 75vh; overflow-y: auto;">
|
||||
<div class="text-center py-5">
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
<p class="mt-3">Lade Daten...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('close') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Restore User -->
|
||||
<div class="modal fade" id="modal-restore-user">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">User wiederherstellen</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" id="restore-user-id">
|
||||
<div class="form-group">
|
||||
<label>E-Mail:</label>
|
||||
<input type="text" class="form-control" id="restore-user-email" readonly>
|
||||
</div>
|
||||
<div class="alert alert-warning">
|
||||
<strong>Hinweis:</strong> Dies führt den Artisan-Befehl <code>user:restore</code> aus.
|
||||
Bitte in den Logs überprüfen ob die Wiederherstellung erfolgreich war.
|
||||
</div>
|
||||
<div class="alert alert-info">
|
||||
<strong>Was wird wiederhergestellt:</strong>
|
||||
<ul class="mb-0">
|
||||
<li>User wird reaktiviert (active=true)</li>
|
||||
<li>Sponsor wird aus pre_sponsor wiederhergestellt</li>
|
||||
<li>Downline-Struktur wird wiederhergestellt</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('close') }}</button>
|
||||
<button type="button" class="btn btn-success" id="btn-restore-user">
|
||||
<i class="fa fa-undo"></i> User wiederherstellen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.datatables-cleanup').dataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": '{!! route('admin_user_cleanup_datatable') !!}',
|
||||
"order": [[0, "desc"]],
|
||||
"columns": [
|
||||
{ data: 'user_id', name: 'id' },
|
||||
{ data: 'first_name', name: 'account.first_name' },
|
||||
{ data: 'last_name', name: 'account.last_name' },
|
||||
{ data: 'email', name: 'email' },
|
||||
{ data: 'm_account', name: 'account.m_account' },
|
||||
{ data: 'status', name: 'status' },
|
||||
{ data: 'deleted_at', name: 'pre_deleted_at', orderable: true },
|
||||
{ data: 'payment_account', name: 'payment_account' },
|
||||
{ data: 'm_sponsor', name: 'm_sponsor', orderable: false },
|
||||
{ data: 'pre_sponsor', name: 'pre_sponsor', orderable: false },
|
||||
{ data: 'childs_count', name: 'childs_count', orderable: false, searchable: false },
|
||||
{ data: 'shopping_users_count', name: 'shopping_users_count', orderable: false, searchable: false },
|
||||
{ data: 'action', orderable: false, searchable: false }
|
||||
],
|
||||
"bLengthChange": false,
|
||||
"iDisplayLength": 50,
|
||||
"language": {
|
||||
"url": "/js/datatables-{{ \App::getLocale() }}.json"
|
||||
}
|
||||
});
|
||||
|
||||
// Modal Cleanup beim Schließen
|
||||
$('#modal-user-history').on('hidden.bs.modal', function() {
|
||||
// Zerstöre selectpicker Instanz wenn vorhanden
|
||||
if ($('#select-new-sponsor').length && $('#select-new-sponsor').hasClass('selectpicker')) {
|
||||
$('#select-new-sponsor').selectpicker('destroy');
|
||||
}
|
||||
currentUserId = null;
|
||||
});
|
||||
|
||||
// Modal Historie Handler
|
||||
$(document).on('click', '.btn-user-history', function() {
|
||||
var userId = $(this).data('id');
|
||||
var userEmail = $(this).data('email');
|
||||
|
||||
$('#modal-user-history').modal('show');
|
||||
$('#history-content').html('<div class="text-center py-5"><i class="fa fa-spinner fa-spin fa-3x"></i><p class="mt-3">Lade Daten...</p></div>');
|
||||
|
||||
$.ajax({
|
||||
url: '{{ route('admin_user_cleanup_history', ['userId' => ':userId']) }}'.replace(':userId', userId),
|
||||
type: 'GET',
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
renderHistory(response);
|
||||
} else {
|
||||
$('#history-content').html('<div class="alert alert-danger">Fehler: ' + response.message + '</div>');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
$('#history-content').html('<div class="alert alert-danger">Fehler beim Laden der Daten: ' + xhr.responseText + '</div>');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var currentUserId = null;
|
||||
|
||||
function renderHistory(data) {
|
||||
currentUserId = data.user.id;
|
||||
var html = '';
|
||||
|
||||
// User Info
|
||||
html += '<div class="card mb-3">';
|
||||
html += '<div class="card-header"><h5><i class="fa fa-user"></i> User Informationen</h5></div>';
|
||||
html += '<div class="card-body">';
|
||||
html += '<div class="row">';
|
||||
html += '<div class="col-md-6"><strong>Name:</strong> ' + data.user.name + '</div>';
|
||||
html += '<div class="col-md-6"><strong>E-Mail:</strong> ' + data.user.email + '</div>';
|
||||
html += '<div class="col-md-6"><strong>M-Account:</strong> ' + data.user.m_account + '</div>';
|
||||
html += '<div class="col-md-6"><strong>Status:</strong> ';
|
||||
if (data.user.deleted) {
|
||||
html += '<span class="badge badge-danger">Gelöscht am ' + data.user.deleted_at + '</span>';
|
||||
} else if (data.user.active) {
|
||||
html += '<span class="badge badge-success">Aktiv</span>';
|
||||
} else {
|
||||
html += '<span class="badge badge-warning">Deaktiviert</span>';
|
||||
}
|
||||
html += '</div>';
|
||||
html += '</div></div></div>';
|
||||
|
||||
// Sponsor Neu-Zuweisen
|
||||
// Die zu übertragenden Werte kommen IMMER aus den Logs (bereits übertragene, die neu zugewiesen werden sollen)
|
||||
var childrenCount = data.cleanup_logs ? data.cleanup_logs.length : 0;
|
||||
var customersCount = data.shopping_logs ? data.shopping_logs.length : 0;
|
||||
|
||||
html += '<div class="card mb-3 border-warning">';
|
||||
html += '<div class="card-header bg-warning"><h5><i class="fa fa-exchange-alt"></i> Sponsor manuell neu zuweisen</h5></div>';
|
||||
html += '<div class="card-body">';
|
||||
html += '<div class="alert alert-warning">';
|
||||
html += '<strong>⚠️ Achtung:</strong> Diese Funktion ermöglicht die manuelle Korrektur eines falsch zugewiesenen Sponsors. ';
|
||||
html += 'Alle Änderungen werden vollständig geloggt und können bei Bedarf rückgängig gemacht werden.';
|
||||
html += '</div>';
|
||||
|
||||
// Bereits übertragene Zuordnungen anzeigen (aus Logs)
|
||||
html += '<div class="alert alert-info mb-3">';
|
||||
html += '<strong>📊 Bereits übertragene Zuordnungen (können neu zugewiesen werden):</strong><br>';
|
||||
html += '<div class="row mt-2">';
|
||||
html += '<div class="col-6">';
|
||||
html += '<i class="fa fa-users"></i> <strong>Downline:</strong> ';
|
||||
if (childrenCount > 0) {
|
||||
html += '<span class="badge badge-warning">' + childrenCount + ' bereits übertragen</span>';
|
||||
} else {
|
||||
html += '<span class="text-muted">Keine Übertragungen</span>';
|
||||
}
|
||||
html += '</div>';
|
||||
html += '<div class="col-6">';
|
||||
html += '<i class="fa fa-shopping-cart"></i> <strong>Kunden:</strong> ';
|
||||
if (customersCount > 0) {
|
||||
html += '<span class="badge badge-warning">' + customersCount + ' bereits übertragen</span>';
|
||||
} else {
|
||||
html += '<span class="text-muted">Keine Übertragungen</span>';
|
||||
}
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<div class="form-group">';
|
||||
html += '<label for="select-new-sponsor"><strong>Neuer Sponsor auswählen:</strong></label>';
|
||||
html += '<select id="select-new-sponsor" class="selectpicker" data-style="btn-light" data-live-search="true" data-size="8" style="width: 100%;">';
|
||||
html += '<option value="">Bitte auswählen...</option>';
|
||||
html += '</select>';
|
||||
html += '<small class="form-text text-muted">Suche nach Name, E-Mail oder M-Account</small>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<hr>';
|
||||
html += '<h6 class="mb-3">Was soll mit übertragen werden?</h6>';
|
||||
|
||||
html += '<div class="form-group">';
|
||||
html += '<div class="custom-control custom-checkbox">';
|
||||
html += '<input type="checkbox" class="custom-control-input" id="transfer-downline" ' + (childrenCount > 0 ? 'checked' : 'disabled') + '>';
|
||||
html += '<label class="custom-control-label" for="transfer-downline">';
|
||||
html += '<strong>Downline neu zuweisen</strong> ';
|
||||
if (childrenCount > 0) {
|
||||
html += '<span class="badge badge-primary">' + childrenCount + '</span>';
|
||||
} else {
|
||||
html += '<span class="text-muted">(keine Übertragungen vorhanden)</span>';
|
||||
}
|
||||
html += '</label>';
|
||||
html += '</div>';
|
||||
html += '<small class="form-text text-muted">Die bereits übertragenen Downline-Mitglieder werden dem neuen Sponsor zugewiesen</small>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<div class="form-group">';
|
||||
html += '<div class="custom-control custom-checkbox">';
|
||||
html += '<input type="checkbox" class="custom-control-input" id="transfer-customers" ' + (customersCount > 0 ? 'checked' : 'disabled') + '>';
|
||||
html += '<label class="custom-control-label" for="transfer-customers">';
|
||||
html += '<strong>Shopping-Kunden neu zuweisen</strong> ';
|
||||
if (customersCount > 0) {
|
||||
html += '<span class="badge badge-primary">' + customersCount + '</span>';
|
||||
} else {
|
||||
html += '<span class="text-muted">(keine Übertragungen vorhanden)</span>';
|
||||
}
|
||||
html += '</label>';
|
||||
html += '</div>';
|
||||
html += '<small class="form-text text-muted">Die bereits übertragenen Shopping-Kunden werden dem neuen Berater zugewiesen</small>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<button type="button" class="btn btn-warning btn-block btn-lg" id="btn-reassign-sponsor">';
|
||||
html += '<i class="fa fa-exchange-alt"></i> Sponsor jetzt neu zuweisen';
|
||||
html += '</button>';
|
||||
|
||||
html += '</div></div>';
|
||||
|
||||
// Downline Position
|
||||
html += '<div class="card mb-3">';
|
||||
html += '<div class="card-header">';
|
||||
html += '<h5 class="mb-0"><i class="fa fa-sitemap"></i> Position in der Downline</h5>';
|
||||
html += '</div>';
|
||||
html += '<div class="card-body">';
|
||||
|
||||
// Sponsor-Info
|
||||
html += '<div class="row mb-3">';
|
||||
html += '<div class="col-md-6">';
|
||||
html += '<strong>Aktueller Sponsor:</strong><br>';
|
||||
if (data.sponsor) {
|
||||
html += '<span class="badge badge-' + (data.sponsor.active ? 'success' : 'warning') + '">' + data.sponsor.name + '</span> ';
|
||||
html += '<small class="text-muted">(' + data.sponsor.email + ')</small>';
|
||||
} else {
|
||||
html += '<em class="text-muted">Nicht vorhanden</em>';
|
||||
}
|
||||
html += '</div>';
|
||||
|
||||
if (data.pre_sponsor) {
|
||||
html += '<div class="col-md-6">';
|
||||
html += '<strong>Vorheriger Sponsor (Pre-Sponsor):</strong><br>';
|
||||
html += '<span class="badge badge-info">' + data.pre_sponsor.name + '</span> ';
|
||||
html += '<small class="text-muted">(' + data.pre_sponsor.email + ')</small>';
|
||||
html += '</div>';
|
||||
}
|
||||
html += '</div>';
|
||||
|
||||
html += '<hr>';
|
||||
|
||||
// Downline mit Badge
|
||||
html += '<div class="mb-2">';
|
||||
html += '<strong>Direkte Downline:</strong> ';
|
||||
if (data.children.length > 0) {
|
||||
html += '<span class="badge badge-primary">' + data.children.length + ' Mitglieder</span>';
|
||||
} else {
|
||||
html += '<span class="badge badge-secondary">0 Mitglieder</span>';
|
||||
}
|
||||
html += '</div>';
|
||||
if (data.children.length > 0) {
|
||||
html += '<table class="table table-sm mt-2">';
|
||||
html += '<thead><tr><th>Name</th><th>E-Mail</th><th>Status</th></tr></thead><tbody>';
|
||||
data.children.forEach(function(child) {
|
||||
html += '<tr>';
|
||||
html += '<td>' + child.name + '</td>';
|
||||
html += '<td>' + child.email + '</td>';
|
||||
html += '<td>';
|
||||
if (child.deleted) {
|
||||
html += '<span class="badge badge-danger">Gelöscht</span>';
|
||||
} else if (child.active) {
|
||||
html += '<span class="badge badge-success">Aktiv</span>';
|
||||
} else {
|
||||
html += '<span class="badge badge-warning">Inaktiv</span>';
|
||||
}
|
||||
if (child.is_pre_sponsor) {
|
||||
html += ' <span class="badge badge-info">Pre-Sponsor</span>';
|
||||
}
|
||||
html += '</td></tr>';
|
||||
});
|
||||
html += '</tbody></table>';
|
||||
} else {
|
||||
html += '<p class="mt-2 mb-0"><em>Keine direkten Downline-Mitglieder</em></p>';
|
||||
}
|
||||
html += '</div></div></div>';
|
||||
|
||||
// Shopping Kunden
|
||||
html += '<div class="card mb-3">';
|
||||
html += '<div class="card-header">';
|
||||
html += '<h5 class="mb-0">';
|
||||
html += '<i class="fa fa-shopping-cart"></i> Shopping-Kunden ';
|
||||
if (data.shopping_users.length > 0) {
|
||||
html += '<span class="badge badge-primary">' + data.shopping_users.length + '</span>';
|
||||
} else {
|
||||
html += '<span class="badge badge-secondary">0</span>';
|
||||
}
|
||||
html += '</h5>';
|
||||
html += '</div>';
|
||||
html += '<div class="card-body">';
|
||||
if (data.shopping_users.length > 0) {
|
||||
html += '<table class="table table-sm">';
|
||||
html += '<thead><tr><th>Name</th><th>E-Mail</th><th>Stadt</th><th>Erstellt am</th></tr></thead><tbody>';
|
||||
data.shopping_users.forEach(function(customer) {
|
||||
html += '<tr>';
|
||||
html += '<td>' + customer.name + '</td>';
|
||||
html += '<td>' + customer.email + '</td>';
|
||||
html += '<td>' + customer.city + '</td>';
|
||||
html += '<td>' + customer.created_at + '</td>';
|
||||
html += '</tr>';
|
||||
});
|
||||
html += '</tbody></table>';
|
||||
} else {
|
||||
html += '<p class="mb-0"><em>Keine Shopping-Kunden vorhanden</em></p>';
|
||||
}
|
||||
html += '</div></div>';
|
||||
|
||||
// Cleanup Logs
|
||||
if (data.cleanup_logs.length > 0) {
|
||||
html += '<div class="card mb-3">';
|
||||
html += '<div class="card-header">';
|
||||
html += '<h5 class="mb-0">';
|
||||
html += '<i class="fa fa-exchange-alt"></i> Downline-Übertragungen (Protokoll) ';
|
||||
html += '<span class="badge badge-info">' + data.cleanup_logs.length + '</span>';
|
||||
html += '</h5>';
|
||||
html += '</div>';
|
||||
html += '<div class="card-body">';
|
||||
html += '<table class="table table-sm">';
|
||||
html += '<thead><tr><th>Betroffener User</th><th>Status</th><th>Von Sponsor</th><th>Zu Sponsor</th><th>Datum</th></tr></thead><tbody>';
|
||||
data.cleanup_logs.forEach(function(log) {
|
||||
html += '<tr>';
|
||||
html += '<td>' + (log.child_user ? log.child_user.name + '<br><small>' + log.child_user.email + '</small>' : 'N/A') + '</td>';
|
||||
html += '<td>';
|
||||
if (log.child_user) {
|
||||
if (log.child_user.deleted) {
|
||||
html += '<span class="badge badge-danger">Gelöscht</span>';
|
||||
} else if (log.child_user.active) {
|
||||
html += '<span class="badge badge-success">Aktiv</span>';
|
||||
} else {
|
||||
html += '<span class="badge badge-warning">Inaktiv</span>';
|
||||
}
|
||||
} else {
|
||||
html += 'N/A';
|
||||
}
|
||||
html += '</td>';
|
||||
html += '<td>' + (log.inactive_sponsor ? log.inactive_sponsor.name + '<br><small>' + log.inactive_sponsor.email + '</small>' : 'N/A') + '</td>';
|
||||
html += '<td>';
|
||||
|
||||
// Ursprünglicher Sponsor aus dem Log
|
||||
if (log.new_sponsor) {
|
||||
html += '<small class="text-muted">Damals:</small><br>';
|
||||
html += log.new_sponsor.name + '<br><small>' + log.new_sponsor.email + '</small>';
|
||||
|
||||
// Falls aktueller Sponsor anders ist
|
||||
if (log.current_sponsor) {
|
||||
html += '<hr class="my-1">';
|
||||
html += '<span class="badge badge-warning">Geändert!</span><br>';
|
||||
html += '<small class="text-success">Aktuell:</small><br>';
|
||||
html += '<strong>' + log.current_sponsor.name + '</strong><br>';
|
||||
html += '<small>' + log.current_sponsor.email + '</small>';
|
||||
}
|
||||
} else {
|
||||
html += 'N/A';
|
||||
}
|
||||
|
||||
html += '</td>';
|
||||
html += '<td>' + log.created_at + '</td>';
|
||||
html += '</tr>';
|
||||
});
|
||||
html += '</tbody></table></div></div>';
|
||||
}
|
||||
|
||||
// Shopping Logs
|
||||
if (data.shopping_logs.length > 0) {
|
||||
html += '<div class="card mb-3">';
|
||||
html += '<div class="card-header">';
|
||||
html += '<h5 class="mb-0">';
|
||||
html += '<i class="fa fa-users"></i> Kunden-Übertragungen (Protokoll) ';
|
||||
html += '<span class="badge badge-info">' + data.shopping_logs.length + '</span>';
|
||||
html += '</h5>';
|
||||
html += '</div>';
|
||||
html += '<div class="card-body">';
|
||||
html += '<table class="table table-sm">';
|
||||
html += '<thead><tr><th>Kunde</th><th>Neuer Berater</th><th>Datum</th></tr></thead><tbody>';
|
||||
data.shopping_logs.forEach(function(log) {
|
||||
html += '<tr>';
|
||||
html += '<td>' + log.customer_name + '<br><small>' + log.customer_email + '</small></td>';
|
||||
html += '<td>';
|
||||
|
||||
// Ursprünglicher Berater aus dem Log
|
||||
if (log.new_member) {
|
||||
html += '<small class="text-muted">Damals:</small><br>';
|
||||
html += log.new_member.name + '<br><small>' + log.new_member.email + '</small>';
|
||||
|
||||
// Falls aktueller Berater anders ist
|
||||
if (log.current_member) {
|
||||
html += '<hr class="my-1">';
|
||||
html += '<span class="badge badge-warning">Geändert!</span><br>';
|
||||
html += '<small class="text-success">Aktuell:</small><br>';
|
||||
html += '<strong>' + log.current_member.name + '</strong><br>';
|
||||
html += '<small>' + log.current_member.email + '</small>';
|
||||
}
|
||||
} else {
|
||||
html += 'N/A';
|
||||
}
|
||||
|
||||
html += '</td>';
|
||||
html += '<td>' + log.created_at + '</td>';
|
||||
html += '</tr>';
|
||||
});
|
||||
html += '</tbody></table></div></div>';
|
||||
}
|
||||
|
||||
$('#history-content').html(html);
|
||||
|
||||
// Lade Sponsoren und initialisiere selectpicker
|
||||
setTimeout(function() {
|
||||
var selectElement = $('#select-new-sponsor');
|
||||
|
||||
if (selectElement.length) {
|
||||
console.log('Lade Sponsoren für selectpicker...');
|
||||
|
||||
// Lade alle aktiven Sponsoren
|
||||
$.ajax({
|
||||
url: '{{ route('admin_user_cleanup_search_sponsors') }}',
|
||||
type: 'GET',
|
||||
data: {
|
||||
q: '', // Leere Suche = alle laden
|
||||
exclude_user_id: currentUserId,
|
||||
load_all: true
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.results && response.results.length > 0) {
|
||||
// Füge alle Sponsoren als Options hinzu
|
||||
response.results.forEach(function(sponsor) {
|
||||
selectElement.append(
|
||||
$('<option></option>')
|
||||
.val(sponsor.id)
|
||||
.text(sponsor.text)
|
||||
);
|
||||
});
|
||||
|
||||
// Initialisiere selectpicker
|
||||
selectElement.selectpicker('refresh');
|
||||
console.log('Selectpicker initialisiert mit ' + response.results.length + ' Sponsoren');
|
||||
} else {
|
||||
console.warn('Keine Sponsoren gefunden');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
console.error('Fehler beim Laden der Sponsoren:', xhr);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error('Select Element nicht gefunden');
|
||||
}
|
||||
}, 200);
|
||||
|
||||
// Reassign Sponsor Handler
|
||||
$('#btn-reassign-sponsor').off('click').on('click', function() {
|
||||
var newSponsorId = $('#select-new-sponsor').val();
|
||||
var transferDownline = $('#transfer-downline').is(':checked');
|
||||
var transferCustomers = $('#transfer-customers').is(':checked');
|
||||
|
||||
if (!newSponsorId) {
|
||||
alert('Bitte wählen Sie einen neuen Sponsor aus!');
|
||||
return;
|
||||
}
|
||||
|
||||
var sponsorName = $('#select-new-sponsor option:selected').text() || 'ID: ' + newSponsorId;
|
||||
|
||||
var confirmMsg = '═══════════════════════════════════════\n';
|
||||
confirmMsg += 'SPONSOR NEU ZUWEISEN - BESTÄTIGUNG\n';
|
||||
confirmMsg += '═══════════════════════════════════════\n\n';
|
||||
confirmMsg += '👤 User:\n ' + data.user.name + '\n ' + data.user.email + '\n\n';
|
||||
confirmMsg += '➡️ Neuer Sponsor:\n ' + sponsorName + '\n\n';
|
||||
confirmMsg += '───────────────────────────────────────\n';
|
||||
confirmMsg += 'WAS WIRD NEU ZUGEWIESEN?\n';
|
||||
confirmMsg += '───────────────────────────────────────\n\n';
|
||||
|
||||
if (transferDownline && childrenCount > 0) {
|
||||
confirmMsg += '✅ Downline: ' + childrenCount + ' bereits übertragene Kinder\n';
|
||||
} else if (childrenCount > 0) {
|
||||
confirmMsg += '❌ Downline: ' + childrenCount + ' Kinder (NICHT neu zuweisen)\n';
|
||||
} else {
|
||||
confirmMsg += '⚪ Downline: Keine Übertragungen vorhanden\n';
|
||||
}
|
||||
|
||||
if (transferCustomers && customersCount > 0) {
|
||||
confirmMsg += '✅ Kunden: ' + customersCount + ' bereits übertragene Kunden\n';
|
||||
} else if (customersCount > 0) {
|
||||
confirmMsg += '❌ Kunden: ' + customersCount + ' Kunden (NICHT neu zuweisen)\n';
|
||||
} else {
|
||||
confirmMsg += '⚪ Kunden: Keine Übertragungen vorhanden\n';
|
||||
}
|
||||
|
||||
confirmMsg += '\n───────────────────────────────────────\n';
|
||||
confirmMsg += '📝 WICHTIG:\n';
|
||||
confirmMsg += ' • Alle Änderungen werden geloggt\n';
|
||||
confirmMsg += ' • Kann rückgängig gemacht werden\n';
|
||||
confirmMsg += ' • User wird dem neuen Sponsor zugewiesen\n\n';
|
||||
confirmMsg += '═══════════════════════════════════════\n\n';
|
||||
confirmMsg += 'Fortfahren?';
|
||||
|
||||
if (!confirm(confirmMsg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var btn = $(this);
|
||||
btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Wird neu zugewiesen...');
|
||||
|
||||
$.ajax({
|
||||
url: '{{ route('admin_user_cleanup_reassign_sponsor') }}',
|
||||
type: 'POST',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}',
|
||||
user_id: currentUserId,
|
||||
new_sponsor_id: newSponsorId,
|
||||
transfer_downline: transferDownline,
|
||||
transfer_customers: transferCustomers
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
var msg = '═══════════════════════════════════════\n';
|
||||
msg += '✅ ERFOLGREICH ABGESCHLOSSEN\n';
|
||||
msg += '═══════════════════════════════════════\n\n';
|
||||
msg += 'Der Sponsor wurde erfolgreich neu zugewiesen!\n\n';
|
||||
|
||||
if (response.logs && response.logs.length > 0) {
|
||||
msg += '───────────────────────────────────────\n';
|
||||
msg += '📋 Durchgeführte Änderungen:\n';
|
||||
msg += '───────────────────────────────────────\n\n';
|
||||
response.logs.forEach(function(log) {
|
||||
msg += '• ' + log + '\n';
|
||||
});
|
||||
msg += '\n';
|
||||
}
|
||||
|
||||
if (response.transferred) {
|
||||
msg += '───────────────────────────────────────\n';
|
||||
msg += '📊 Zusammenfassung:\n';
|
||||
msg += '───────────────────────────────────────\n\n';
|
||||
if (response.transferred.downline > 0) {
|
||||
msg += '✓ Downline übertragen\n';
|
||||
}
|
||||
if (response.transferred.customers > 0) {
|
||||
msg += '✓ Kunden übertragen\n';
|
||||
}
|
||||
msg += '✓ User neu zugewiesen\n\n';
|
||||
}
|
||||
|
||||
msg += '═══════════════════════════════════════';
|
||||
alert(msg);
|
||||
$('#modal-user-history').modal('hide');
|
||||
$('.datatables-cleanup').DataTable().ajax.reload();
|
||||
} else {
|
||||
alert('❌ FEHLER\n\n' + response.message);
|
||||
btn.prop('disabled', false).html('<i class="fa fa-exchange-alt"></i> Sponsor jetzt neu zuweisen');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
var errorMsg = 'Fehler beim Neu-Zuweisen';
|
||||
try {
|
||||
var response = JSON.parse(xhr.responseText);
|
||||
errorMsg += ': ' + response.message;
|
||||
} catch(e) {
|
||||
errorMsg += ': ' + xhr.responseText;
|
||||
}
|
||||
alert(errorMsg);
|
||||
btn.prop('disabled', false).html('<i class="fa fa-exchange-alt"></i> Sponsor jetzt neu zuweisen');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Modal Restore Handler
|
||||
$('#modal-restore-user').on('show.bs.modal', function(event) {
|
||||
var button = $(event.relatedTarget);
|
||||
$('#restore-user-id').val(button.data('id'));
|
||||
$('#restore-user-email').val(button.data('email'));
|
||||
});
|
||||
|
||||
$('#btn-restore-user').click(function() {
|
||||
var userId = $('#restore-user-id').val();
|
||||
var btn = $(this);
|
||||
|
||||
btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Wird wiederhergestellt...');
|
||||
|
||||
$.ajax({
|
||||
url: '{{ route('admin_user_cleanup_restore') }}',
|
||||
type: 'POST',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}',
|
||||
user_id: userId
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
alert('User wurde erfolgreich wiederhergestellt!');
|
||||
$('#modal-restore-user').modal('hide');
|
||||
$('.datatables-cleanup').DataTable().ajax.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + response.message);
|
||||
}
|
||||
btn.prop('disabled', false).html('<i class="fa fa-undo"></i> User wiederherstellen');
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert('Fehler beim Wiederherstellen: ' + xhr.responseText);
|
||||
btn.prop('disabled', false).html('<i class="fa fa-undo"></i> User wiederherstellen');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
75
resources/views/admin/user/cleanup/logs.blade.php
Normal file
75
resources/views/admin/user/cleanup/logs.blade.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
<h4 class="font-weight-bold py-2 mb-2">
|
||||
<i class="ion ion-md-git-network"></i> Downline-Übertragungen (User Cleanup Logs)
|
||||
</h4>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<div class="alert alert-info">
|
||||
<strong>Info:</strong> Diese Übersicht zeigt alle Downline-Übertragungen bei User-Deaktivierungen.
|
||||
Wenn ein User deaktiviert wird, werden seine Vertriebspartner-Kinder dem nächsten aktiven Sponsor zugewiesen.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nav-tabs-top mb-4">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin_user_cleanup') }}">
|
||||
<i class="ion ion-ios-people"></i> Deaktivierte/Gelöschte User
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="{{ route('admin_user_cleanup_logs') }}">
|
||||
<i class="ion ion-md-git-network"></i> Downline-Übertragungen
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin_user_cleanup_shopping_logs') }}">
|
||||
<i class="ion ion-md-cart"></i> Kunden-Übertragungen
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="datatables-logs table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Inaktiver Sponsor</th>
|
||||
<th>Betroffenes Kind (Downline)</th>
|
||||
<th>Neuer Sponsor</th>
|
||||
<th>Übertragen am</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.datatables-logs').dataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": '{!! route('admin_user_cleanup_logs_datatable') !!}',
|
||||
"order": [[0, "desc"]],
|
||||
"columns": [
|
||||
{ data: 'id', name: 'id' },
|
||||
{ data: 'inactive_sponsor', name: 'inactive_sponsor_id' },
|
||||
{ data: 'child_user', name: 'child_user_id' },
|
||||
{ data: 'new_sponsor', name: 'new_sponsor_id' },
|
||||
{ data: 'created_at', name: 'created_at' }
|
||||
],
|
||||
"bLengthChange": false,
|
||||
"iDisplayLength": 50,
|
||||
"language": {
|
||||
"url": "/js/datatables-{{ \App::getLocale() }}.json"
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
75
resources/views/admin/user/cleanup/shopping_logs.blade.php
Normal file
75
resources/views/admin/user/cleanup/shopping_logs.blade.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
<h4 class="font-weight-bold py-2 mb-2">
|
||||
<i class="ion ion-md-cart"></i> Kunden-Übertragungen (Shopping User Member Logs)
|
||||
</h4>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<div class="alert alert-info">
|
||||
<strong>Info:</strong> Diese Übersicht zeigt alle Shopping-Kunden-Übertragungen bei User-Löschungen.
|
||||
Wenn ein User gelöscht wird, werden seine Shopping-Kunden dem neuen Sponsor übertragen.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nav-tabs-top mb-4">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin_user_cleanup') }}">
|
||||
<i class="ion ion-ios-people"></i> Deaktivierte/Gelöschte User
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin_user_cleanup_logs') }}">
|
||||
<i class="ion ion-md-git-network"></i> Downline-Übertragungen
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="{{ route('admin_user_cleanup_shopping_logs') }}">
|
||||
<i class="ion ion-md-cart"></i> Kunden-Übertragungen
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="datatables-shopping-logs table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Vorheriger Berater</th>
|
||||
<th>Shopping-Kunde</th>
|
||||
<th>Neuer Berater</th>
|
||||
<th>Übertragen am</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.datatables-shopping-logs').dataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": '{!! route('admin_user_cleanup_shopping_logs_datatable') !!}',
|
||||
"order": [[0, "desc"]],
|
||||
"columns": [
|
||||
{ data: 'id', name: 'id' },
|
||||
{ data: 'pre_member', name: 'pre_member_id' },
|
||||
{ data: 'shopping_user', name: 'shopping_user_id' },
|
||||
{ data: 'new_member', name: 'new_member_id' },
|
||||
{ data: 'created_at', name: 'created_at' }
|
||||
],
|
||||
"bLengthChange": false,
|
||||
"iDisplayLength": 50,
|
||||
"language": {
|
||||
"url": "/js/datatables-{{ \App::getLocale() }}.json"
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
Loading…
Add table
Add a link
Reference in a new issue