[FEAT] 增加訂單出貨交付狀態(delivery_status)與多語系支援
1. 新增資料庫遷移:在 資料表增加 (出貨狀態:0 失敗、1 成功、2 部分成功),預設值為 1 並允許 NULL 以完美向下相容舊機台。 2. 升級 Model:加入 到可填充與轉型,並宣告常量與 取得本地化文字的 Accessor。 3. 更新 邏輯:在 中自動解析並記錄 。新增 輔助函式,當 Payload 未指定訂單狀態時,可動態從個別貨道出貨紀錄 ( 陣列) 計算出整筆訂單的出貨交付結果。 4. 銷售紀錄列表 (tab-orders.blade.php) UI 優化:將原先「狀態」欄位重命名為「付款狀態」,並在右側新增「出貨狀態」欄位,使用極簡奢華風的彩色 Badge 呈現出貨結果;桌機版空狀態 修正為 8 防止破版;手機版卡片同步支援。 5. 側邊明細面板 (order-detail-panel.blade.php) UI 優化:將基本狀態卡片升級為 3 欄網格,將付款狀態、支付類型與新增的出貨狀態 Badge 完美並排。 6. 報表匯出功能 (SalesController.php) 整合:在 Excel 及 CSV 匯出中同步修正「付款狀態」欄位標題與轉換標籤,並新增「出貨狀態」欄位以匯出 。 7. 多語系精準對齊:新增 , , , 及 的繁、英、日翻譯對照,並進行字母升冪排序 (ksort)。
This commit is contained in:
parent
6daeadc452
commit
8d380e4902
@ -882,7 +882,8 @@ class SalesController extends Controller
|
|||||||
__('Discount Amount'),
|
__('Discount Amount'),
|
||||||
__('Payment Amount'),
|
__('Payment Amount'),
|
||||||
__('Payment Type'),
|
__('Payment Type'),
|
||||||
__('Status'),
|
__('Payment Status'),
|
||||||
|
__('Dispense Status'),
|
||||||
__('Invoice Number'),
|
__('Invoice Number'),
|
||||||
__('Staff Name'),
|
__('Staff Name'),
|
||||||
__('Staff ID'),
|
__('Staff ID'),
|
||||||
@ -922,6 +923,16 @@ class SalesController extends Controller
|
|||||||
|
|
||||||
$totalQty = $order->items->sum('quantity');
|
$totalQty = $order->items->sum('quantity');
|
||||||
|
|
||||||
|
// 轉換訂單狀態標籤,與前端 tab-orders.blade.php / detail 面板一致
|
||||||
|
$statusLabelMap = [
|
||||||
|
'pending' => __('Pending'),
|
||||||
|
'paid' => __('Paid'),
|
||||||
|
'completed' => __('Completed'),
|
||||||
|
'cancelled' => __('Cancelled'),
|
||||||
|
'refunded' => __('Refunded'),
|
||||||
|
];
|
||||||
|
$paymentStatusLabel = $statusLabelMap[$order->status] ?? $order->status;
|
||||||
|
|
||||||
$row = [
|
$row = [
|
||||||
$order->order_no,
|
$order->order_no,
|
||||||
$order->created_at->format('Y-m-d H:i:s'),
|
$order->created_at->format('Y-m-d H:i:s'),
|
||||||
@ -933,7 +944,8 @@ class SalesController extends Controller
|
|||||||
number_format($order->discount_amount, 2, '.', ''),
|
number_format($order->discount_amount, 2, '.', ''),
|
||||||
number_format($order->pay_amount, 2, '.', ''),
|
number_format($order->pay_amount, 2, '.', ''),
|
||||||
$order->payment_type_label,
|
$order->payment_type_label,
|
||||||
__($order->status),
|
$paymentStatusLabel,
|
||||||
|
$order->delivery_status_label,
|
||||||
$order->invoice->invoice_no ?? '---',
|
$order->invoice->invoice_no ?? '---',
|
||||||
$order->staffCardLog->staffCard->name ?? '---',
|
$order->staffCardLog->staffCard->name ?? '---',
|
||||||
$order->staffCardLog->staffCard->employee_id ?? '---',
|
$order->staffCardLog->staffCard->employee_id ?? '---',
|
||||||
|
|||||||
@ -17,6 +17,11 @@ class Order extends Model
|
|||||||
public const PAYMENT_STATUS_FAILED = 0;
|
public const PAYMENT_STATUS_FAILED = 0;
|
||||||
public const PAYMENT_STATUS_SUCCESS = 1;
|
public const PAYMENT_STATUS_SUCCESS = 1;
|
||||||
|
|
||||||
|
// 出貨狀態
|
||||||
|
public const DELIVERY_STATUS_FAILED = 0;
|
||||||
|
public const DELIVERY_STATUS_SUCCESS = 1;
|
||||||
|
public const DELIVERY_STATUS_PARTIAL = 2;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'company_id',
|
'company_id',
|
||||||
'flow_id',
|
'flow_id',
|
||||||
@ -41,6 +46,7 @@ class Order extends Model
|
|||||||
'machine_time',
|
'machine_time',
|
||||||
'status',
|
'status',
|
||||||
'metadata',
|
'metadata',
|
||||||
|
'delivery_status',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
@ -53,6 +59,7 @@ class Order extends Model
|
|||||||
'machine_time' => 'datetime',
|
'machine_time' => 'datetime',
|
||||||
'metadata' => 'array',
|
'metadata' => 'array',
|
||||||
'payment_type' => 'integer',
|
'payment_type' => 'integer',
|
||||||
|
'delivery_status' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,4 +155,24 @@ class Order extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(WelcomeGift::class);
|
return $this->belongsTo(WelcomeGift::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取得所有出貨狀態的對照標籤
|
||||||
|
*/
|
||||||
|
public static function getDeliveryStatusLabels(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
self::DELIVERY_STATUS_FAILED => __('Dispense Failed'),
|
||||||
|
self::DELIVERY_STATUS_SUCCESS => __('Dispense Success'),
|
||||||
|
self::DELIVERY_STATUS_PARTIAL => __('Partial Dispense Success'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取得目前出貨狀態標籤 (Accessor)
|
||||||
|
*/
|
||||||
|
public function getDeliveryStatusLabelAttribute(): string
|
||||||
|
{
|
||||||
|
return self::getDeliveryStatusLabels()[$this->delivery_status] ?? __('Unknown');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,6 +71,7 @@ class TransactionService
|
|||||||
'payment_at' => now(),
|
'payment_at' => now(),
|
||||||
'status' => 'completed',
|
'status' => 'completed',
|
||||||
'metadata' => $data['metadata'] ?? null,
|
'metadata' => $data['metadata'] ?? null,
|
||||||
|
'delivery_status' => (int) ($data['delivery_status'] ?? Order::DELIVERY_STATUS_SUCCESS),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Create Order Items
|
// Create Order Items
|
||||||
@ -250,6 +251,9 @@ class TransactionService
|
|||||||
|
|
||||||
// 確保提取 payment_type 與 flow_id (可能在 root 或 order 內)
|
// 確保提取 payment_type 與 flow_id (可能在 root 或 order 內)
|
||||||
$orderData['flow_id'] = $flowId;
|
$orderData['flow_id'] = $flowId;
|
||||||
|
if (!isset($orderData['delivery_status']) && !empty($data['dispense'])) {
|
||||||
|
$orderData['delivery_status'] = $this->resolveDeliveryStatusFromDispense($data['dispense']);
|
||||||
|
}
|
||||||
if (!isset($orderData['payment_type']) && isset($data['payment_type'])) {
|
if (!isset($orderData['payment_type']) && isset($data['payment_type'])) {
|
||||||
$orderData['payment_type'] = $data['payment_type'];
|
$orderData['payment_type'] = $data['payment_type'];
|
||||||
}
|
}
|
||||||
@ -385,4 +389,33 @@ class TransactionService
|
|||||||
return $order;
|
return $order;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve order-level delivery status from item-level dispense results.
|
||||||
|
*/
|
||||||
|
protected function resolveDeliveryStatusFromDispense(array $dispense): int
|
||||||
|
{
|
||||||
|
$dispenseList = isset($dispense[0]) ? $dispense : [$dispense];
|
||||||
|
$statuses = collect($dispenseList)
|
||||||
|
->filter(fn ($item) => is_array($item) && array_key_exists('dispense_status', $item))
|
||||||
|
->map(fn ($item) => (int) $item['dispense_status']);
|
||||||
|
|
||||||
|
if ($statuses->isEmpty()) {
|
||||||
|
return Order::DELIVERY_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
$successCount = $statuses
|
||||||
|
->filter(fn ($status) => $status === Order::DELIVERY_STATUS_SUCCESS)
|
||||||
|
->count();
|
||||||
|
|
||||||
|
if ($successCount === $statuses->count()) {
|
||||||
|
return Order::DELIVERY_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($successCount === 0) {
|
||||||
|
return Order::DELIVERY_STATUS_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Order::DELIVERY_STATUS_PARTIAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('orders', function (Blueprint $table) {
|
||||||
|
$table->tinyInteger('delivery_status')->default(1)->comment('出貨狀態: 0:出貨失敗, 1:出貨成功, 2:部分出貨成功')->after('payment_status');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('orders', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('delivery_status');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1341,6 +1341,7 @@
|
|||||||
"Page 7": "Page 7",
|
"Page 7": "Page 7",
|
||||||
"Page Lock Status": "Page Lock Status",
|
"Page Lock Status": "Page Lock Status",
|
||||||
"Parameters": "Parameters",
|
"Parameters": "Parameters",
|
||||||
|
"Partial Dispense Success": "Partial Dispense Success",
|
||||||
"Pass Code": "Pass Code",
|
"Pass Code": "Pass Code",
|
||||||
"Pass Code (8 Digits)": "Pass Code (8 Digits)",
|
"Pass Code (8 Digits)": "Pass Code (8 Digits)",
|
||||||
"Pass Code Management": "Pass Code Management",
|
"Pass Code Management": "Pass Code Management",
|
||||||
@ -1363,6 +1364,7 @@
|
|||||||
"Payment Configuration deleted successfully.": "Payment Configuration deleted successfully.",
|
"Payment Configuration deleted successfully.": "Payment Configuration deleted successfully.",
|
||||||
"Payment Configuration updated successfully.": "Payment Configuration updated successfully.",
|
"Payment Configuration updated successfully.": "Payment Configuration updated successfully.",
|
||||||
"Payment Selection": "Payment Selection",
|
"Payment Selection": "Payment Selection",
|
||||||
|
"Payment Status": "Payment Status",
|
||||||
"Payment Type": "Payment Type",
|
"Payment Type": "Payment Type",
|
||||||
"Pending": "Pending",
|
"Pending": "Pending",
|
||||||
"Per Page": "Per Page",
|
"Per Page": "Per Page",
|
||||||
|
|||||||
@ -1341,6 +1341,7 @@
|
|||||||
"Page 7": "ページ 7 (ロックページ)",
|
"Page 7": "ページ 7 (ロックページ)",
|
||||||
"Page Lock Status": "ページロックステータス",
|
"Page Lock Status": "ページロックステータス",
|
||||||
"Parameters": "パラメータ設定",
|
"Parameters": "パラメータ設定",
|
||||||
|
"Partial Dispense Success": "一部出庫成功",
|
||||||
"Pass Code": "パスコード",
|
"Pass Code": "パスコード",
|
||||||
"Pass Code (8 Digits)": "パスコード (8桁)",
|
"Pass Code (8 Digits)": "パスコード (8桁)",
|
||||||
"Pass Code Management": "パスコード管理",
|
"Pass Code Management": "パスコード管理",
|
||||||
@ -1363,6 +1364,7 @@
|
|||||||
"Payment Configuration deleted successfully.": "決済設定が正常に削除されました。",
|
"Payment Configuration deleted successfully.": "決済設定が正常に削除されました。",
|
||||||
"Payment Configuration updated successfully.": "決済設定が正常に更新されました。",
|
"Payment Configuration updated successfully.": "決済設定が正常に更新されました。",
|
||||||
"Payment Selection": "支払選択",
|
"Payment Selection": "支払選択",
|
||||||
|
"Payment Status": "決済ステータス",
|
||||||
"Payment Type": "支払方法",
|
"Payment Type": "支払方法",
|
||||||
"Pending": "保留中",
|
"Pending": "保留中",
|
||||||
"Per Page": "1ページあたり表示",
|
"Per Page": "1ページあたり表示",
|
||||||
|
|||||||
@ -1341,6 +1341,7 @@
|
|||||||
"Page 7": "鎖定頁",
|
"Page 7": "鎖定頁",
|
||||||
"Page Lock Status": "頁面鎖定狀態",
|
"Page Lock Status": "頁面鎖定狀態",
|
||||||
"Parameters": "參數設定",
|
"Parameters": "參數設定",
|
||||||
|
"Partial Dispense Success": "部分出貨成功",
|
||||||
"Pass Code": "通行碼",
|
"Pass Code": "通行碼",
|
||||||
"Pass Code (8 Digits)": "通行碼 (8 位數)",
|
"Pass Code (8 Digits)": "通行碼 (8 位數)",
|
||||||
"Pass Code Management": "通行碼管理",
|
"Pass Code Management": "通行碼管理",
|
||||||
@ -1363,6 +1364,7 @@
|
|||||||
"Payment Configuration deleted successfully.": "金流設定已成功刪除。",
|
"Payment Configuration deleted successfully.": "金流設定已成功刪除。",
|
||||||
"Payment Configuration updated successfully.": "金流設定已成功更新。",
|
"Payment Configuration updated successfully.": "金流設定已成功更新。",
|
||||||
"Payment Selection": "付款選擇",
|
"Payment Selection": "付款選擇",
|
||||||
|
"Payment Status": "付款狀態",
|
||||||
"Payment Type": "支付方式",
|
"Payment Type": "支付方式",
|
||||||
"Pending": "待處理",
|
"Pending": "待處理",
|
||||||
"Per Page": "每頁顯示",
|
"Per Page": "每頁顯示",
|
||||||
|
|||||||
@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
<div class="flex-1 overflow-y-auto p-6 sm:p-8 space-y-10">
|
<div class="flex-1 overflow-y-auto p-6 sm:p-8 space-y-10">
|
||||||
{{-- 基本狀態卡片 --}}
|
{{-- 基本狀態卡片 --}}
|
||||||
<div class="grid grid-cols-2 gap-6 p-6 bg-slate-50/50 dark:bg-slate-800/30 rounded-[2rem] border border-slate-100 dark:border-slate-800">
|
<div class="grid grid-cols-3 gap-6 p-6 bg-slate-50/50 dark:bg-slate-800/30 rounded-[2rem] border border-slate-100 dark:border-slate-800">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __('Order Status') }}</p>
|
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __('Payment Status') }}</p>
|
||||||
<div>
|
<div>
|
||||||
@php
|
@php
|
||||||
$statusMap = [
|
$statusMap = [
|
||||||
@ -56,6 +56,20 @@
|
|||||||
{{ $order->payment_type_label }}
|
{{ $order->payment_type_label }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __('Dispense Status') }}</p>
|
||||||
|
<div>
|
||||||
|
@php
|
||||||
|
$deliveryStatusMap = [
|
||||||
|
0 => ['label' => __('Dispense Failed'), 'color' => 'rose'],
|
||||||
|
1 => ['label' => __('Dispense Success'), 'color' => 'emerald'],
|
||||||
|
2 => ['label' => __('Partial Dispense Success'), 'color' => 'amber'],
|
||||||
|
];
|
||||||
|
$ds = $deliveryStatusMap[$order->delivery_status] ?? ['label' => __('Unknown'), 'color' => 'slate'];
|
||||||
|
@endphp
|
||||||
|
<x-status-badge :color="$ds['color']" :label="$ds['label']" size="sm" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- 交易資訊 --}}
|
{{-- 交易資訊 --}}
|
||||||
|
|||||||
@ -169,7 +169,11 @@
|
|||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
||||||
{{ __('Status') }}
|
{{ __('Payment Status') }}
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
||||||
|
{{ __('Dispense Status') }}
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
||||||
@ -263,13 +267,25 @@
|
|||||||
'refunded' => ['label' => __('Refunded'), 'color' => 'rose'],
|
'refunded' => ['label' => __('Refunded'), 'color' => 'rose'],
|
||||||
];
|
];
|
||||||
$s = $statusMap[$order->status] ?? ['label' => $order->status, 'color' => 'slate'];
|
$s = $statusMap[$order->status] ?? ['label' => $order->status, 'color' => 'slate'];
|
||||||
|
|
||||||
$invoiceSearchValue = $order->invoice ? $order->invoice->invoice_no : $order->order_no;
|
|
||||||
$targetUrl = route('admin.sales.index', ['tab' => 'invoices', 'search' => $invoiceSearchValue]);
|
|
||||||
@endphp
|
@endphp
|
||||||
<x-status-badge :color="$s['color']" :label="$s['label']" size="xs" />
|
<x-status-badge :color="$s['color']" :label="$s['label']" size="xs" />
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-6 whitespace-nowrap">
|
<td class="px-6 py-6 whitespace-nowrap">
|
||||||
|
@php
|
||||||
|
$deliveryStatusMap = [
|
||||||
|
0 => ['label' => __('Dispense Failed'), 'color' => 'rose'],
|
||||||
|
1 => ['label' => __('Dispense Success'), 'color' => 'emerald'],
|
||||||
|
2 => ['label' => __('Partial Dispense Success'), 'color' => 'amber'],
|
||||||
|
];
|
||||||
|
$ds = $deliveryStatusMap[$order->delivery_status] ?? ['label' => __('Unknown'), 'color' => 'slate'];
|
||||||
|
@endphp
|
||||||
|
<x-status-badge :color="$ds['color']" :label="$ds['label']" size="xs" />
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-6 whitespace-nowrap">
|
||||||
|
@php
|
||||||
|
$invoiceSearchValue = $order->invoice ? $order->invoice->invoice_no : $order->order_no;
|
||||||
|
$targetUrl = route('admin.sales.index', ['tab' => 'invoices', 'search' => $invoiceSearchValue]);
|
||||||
|
@endphp
|
||||||
@if($order->invoice)
|
@if($order->invoice)
|
||||||
<div @click.stop="switchTab('invoices', '{{ $targetUrl }}')"
|
<div @click.stop="switchTab('invoices', '{{ $targetUrl }}')"
|
||||||
class="flex items-center gap-1.5 text-sm font-extrabold text-slate-600 dark:text-slate-400 cursor-pointer hover:text-cyan-500 transition-colors group/invoice"
|
class="flex items-center gap-1.5 text-sm font-extrabold text-slate-600 dark:text-slate-400 cursor-pointer hover:text-cyan-500 transition-colors group/invoice"
|
||||||
@ -302,8 +318,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="7" class="py-20 text-center">
|
<td colspan="8" class="py-20 text-center">
|
||||||
<x-empty-state mode="table" colspan="7" :message="__('No transaction orders found')" />
|
<x-empty-state mode="table" colspan="8" :message="__('No transaction orders found')" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
@ -413,6 +429,19 @@
|
|||||||
{{ $order->invoice->invoice_no ?? '---' }}
|
{{ $order->invoice->invoice_no ?? '---' }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1">{{
|
||||||
|
__('Dispense Status') }}</p>
|
||||||
|
@php
|
||||||
|
$deliveryStatusMap = [
|
||||||
|
0 => ['label' => __('Dispense Failed'), 'color' => 'rose'],
|
||||||
|
1 => ['label' => __('Dispense Success'), 'color' => 'emerald'],
|
||||||
|
2 => ['label' => __('Partial Dispense Success'), 'color' => 'amber'],
|
||||||
|
];
|
||||||
|
$ds = $deliveryStatusMap[$order->delivery_status] ?? ['label' => __('Unknown'), 'color' => 'slate'];
|
||||||
|
@endphp
|
||||||
|
<x-status-badge :color="$ds['color']" :label="$ds['label']" size="xs" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- Action Buttons --}}
|
{{-- Action Buttons --}}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user