handle transactions
This commit is contained in:
@@ -155,11 +155,111 @@ class Controller extends BaseController
|
|||||||
return Setting::where('key',$name)->first()->value ?? false;
|
return Setting::where('key',$name)->first()->value ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function metalTypeLabel(): string
|
protected static function metalTypeSettingValue(): ?string
|
||||||
{
|
{
|
||||||
$metalType = Setting::where('key', 'metal_type')->value('value');
|
$metalType = Setting::where('key', 'metal_type')->value('value');
|
||||||
|
if ($metalType === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return ($metalType !== null && trim((string) $metalType) !== '') ? trim((string) $metalType) : 'طلا';
|
$metalType = trim((string) $metalType);
|
||||||
|
|
||||||
|
return $metalType !== '' ? $metalType : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** برچسب موجودی کیف اصلی: مقدار setting یا «طلا» */
|
||||||
|
public static function metalTypeLabel(): string
|
||||||
|
{
|
||||||
|
return self::metalTypeSettingValue() ?? 'طلا';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** برچسب معاملات آبشده: مقدار setting یا «آبشده» */
|
||||||
|
public static function meltedGoldLabel(): string
|
||||||
|
{
|
||||||
|
return self::metalTypeSettingValue() ?? 'آبشده';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function cashTransactionTitles(): array
|
||||||
|
{
|
||||||
|
return ['برداشت وجه نقد', 'واریز وجه نقد'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function legacyMeltedTransactionTitles(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'واریز طلای ابشده',
|
||||||
|
'واریز طلای آبشده',
|
||||||
|
'برداشت طلای ابشده',
|
||||||
|
'برداشت طلای آبشده',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function metalLabelVariants(): array
|
||||||
|
{
|
||||||
|
return array_values(array_unique([
|
||||||
|
self::meltedGoldLabel(),
|
||||||
|
self::metalTypeLabel(),
|
||||||
|
'طلا',
|
||||||
|
'آبشده',
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function genericMetalTransactionTitles(): array
|
||||||
|
{
|
||||||
|
$titles = self::legacyMeltedTransactionTitles();
|
||||||
|
|
||||||
|
foreach (self::metalLabelVariants() as $label) {
|
||||||
|
$titles[] = "موجودی {$label}";
|
||||||
|
$titles[] = "برداشت {$label}";
|
||||||
|
$titles[] = "خرید {$label}";
|
||||||
|
$titles[] = "فروش {$label}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values(array_unique($titles));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isCashTransactionTitle(?string $title): bool
|
||||||
|
{
|
||||||
|
return $title !== null && in_array($title, self::cashTransactionTitles(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isGenericMetalTransactionTitle(?string $title): bool
|
||||||
|
{
|
||||||
|
if ($title === null || self::isCashTransactionTitle($title)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return in_array($title, self::genericMetalTransactionTitles(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function productBuyTitle(string $productTitle): string
|
||||||
|
{
|
||||||
|
return 'خرید ' . $productTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function productSellTitle(string $productTitle): string
|
||||||
|
{
|
||||||
|
return 'فروش ' . $productTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function meltedGoldBuyTitle(): string
|
||||||
|
{
|
||||||
|
return 'خرید ' . self::meltedGoldLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function meltedGoldSellTitle(): string
|
||||||
|
{
|
||||||
|
return 'فروش ' . self::meltedGoldLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function meltedGoldDepositTitle(): string
|
||||||
|
{
|
||||||
|
return 'موجودی ' . self::meltedGoldLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function meltedGoldWithdrawTitle(): string
|
||||||
|
{
|
||||||
|
return 'برداشت ' . self::meltedGoldLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function jibit($method, $p1 = null, $p2 = null, $p3 = null)
|
public static function jibit($method, $p1 = null, $p2 = null, $p3 = null)
|
||||||
|
|||||||
@@ -110,21 +110,28 @@ class WalletController extends Controller
|
|||||||
$wallet = Wallet::with('product')->where('id', $record->wallet)->first();
|
$wallet = Wallet::with('product')->where('id', $record->wallet)->first();
|
||||||
|
|
||||||
if (isset($wallet->product)) {
|
if (isset($wallet->product)) {
|
||||||
if ($record->gold > 0) {
|
$direction = $record->order->direction ?? null;
|
||||||
$record->title = " خرید ";
|
if ((int) $direction === 1) {
|
||||||
|
$record->title = self::productBuyTitle($wallet->product->title);
|
||||||
|
} elseif ((int) $direction === 2) {
|
||||||
|
$record->title = self::productSellTitle($wallet->product->title);
|
||||||
} else {
|
} else {
|
||||||
$record->title = " فروش ";
|
$record->title = ($record->gold > 0 ? self::productBuyTitle($wallet->product->title) : self::productSellTitle($wallet->product->title));
|
||||||
}
|
}
|
||||||
|
|
||||||
$record->title .= $wallet->product->title;
|
|
||||||
$record->unit = "عدد";
|
$record->unit = "عدد";
|
||||||
|
} else {
|
||||||
|
$record->title = $this->resolveMainWalletTransactionTitle($record);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$record->title = $record->type_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
$record->save();
|
$record->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->applyMetalTypeTransactionTitle($record);
|
$this->applyMetalTypeTransactionTitle($record);
|
||||||
|
$this->applyProductTransactionTitle($record);
|
||||||
|
$this->applyProductOrderDisplayFields($record);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($records);
|
return response()->json($records);
|
||||||
@@ -344,15 +351,147 @@ class WalletController extends Controller
|
|||||||
|
|
||||||
private function applyMetalTypeTransactionTitle($record): void
|
private function applyMetalTypeTransactionTitle($record): void
|
||||||
{
|
{
|
||||||
$metalLabel = self::metalTypeLabel();
|
if (!empty($record->product_id)) {
|
||||||
$legacyDepositTitles = ['واریز طلای ابشده', 'واریز طلای آبشده'];
|
return;
|
||||||
$legacyWithdrawTitles = ['برداشت طلای ابشده', 'برداشت طلای آبشده'];
|
}
|
||||||
|
|
||||||
if (in_array($record->title, $legacyDepositTitles, true)) {
|
$wallet = $record->wallet ?? null;
|
||||||
$record->title = "موجودی {$metalLabel}";
|
if ($wallet && !empty($wallet->product)) {
|
||||||
} elseif (in_array($record->title, $legacyWithdrawTitles, true)) {
|
return;
|
||||||
$record->title = "برداشت {$metalLabel}";
|
}
|
||||||
|
|
||||||
|
if (self::isCashTransactionTitle($record->title)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!self::isGenericMetalTransactionTitle($record->title)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/^(موجودی|واریز)/u', (string) $record->title)) {
|
||||||
|
$record->title = self::meltedGoldDepositTitle();
|
||||||
|
} elseif (preg_match('/^برداشت /u', (string) $record->title)) {
|
||||||
|
$record->title = self::meltedGoldWithdrawTitle();
|
||||||
|
} elseif (preg_match('/^خرید /u', (string) $record->title)) {
|
||||||
|
$record->title = self::meltedGoldBuyTitle();
|
||||||
|
} elseif (preg_match('/^فروش /u', (string) $record->title)) {
|
||||||
|
$record->title = self::meltedGoldSellTitle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function applyProductTransactionTitle($record): void
|
||||||
|
{
|
||||||
|
if (empty($record->product_id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::isCashTransactionTitle($record->title)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$productTitle = $record->wallet->product->title ?? $record->product->title ?? null;
|
||||||
|
if (!$productTitle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$expectedBuy = self::productBuyTitle($productTitle);
|
||||||
|
$expectedSell = self::productSellTitle($productTitle);
|
||||||
|
|
||||||
|
if ($record->title === $expectedBuy || $record->title === $expectedSell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!self::isGenericMetalTransactionTitle($record->title)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$direction = $record->order->direction ?? null;
|
||||||
|
if ((int) $direction === 1) {
|
||||||
|
$record->title = $expectedBuy;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((int) $direction === 2) {
|
||||||
|
$record->title = $expectedSell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveMainWalletTransactionTitle($record): string
|
||||||
|
{
|
||||||
|
if ((int) $record->type === 1) {
|
||||||
|
return self::meltedGoldBuyTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((int) $record->type === 2) {
|
||||||
|
return self::meltedGoldSellTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $record->type_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function applyProductOrderDisplayFields($record): void
|
||||||
|
{
|
||||||
|
if (empty($record->order_id) || empty($record->order) || empty($record->product_id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = $record->order;
|
||||||
|
$totalPrice = (int) ($order->total_price ?? $order->payment_amount ?? 0);
|
||||||
|
if ($totalPrice <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((int) ($record->cash ?? 0) === 0) {
|
||||||
|
$direction = (int) ($order->direction ?? 0);
|
||||||
|
$record->cash = $direction === 1 ? -$totalPrice : $totalPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isProductWalletTransaction($record)) {
|
||||||
|
$mainBalanceCash = $this->resolveMainWalletBalanceCashForOrder($record);
|
||||||
|
if ($mainBalanceCash !== null) {
|
||||||
|
$record->balance_cash = $mainBalanceCash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($record->wallet?->product)) {
|
||||||
|
$record->unit = $record->wallet->product->unit ?: 'عدد';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isProductWalletTransaction($record): bool
|
||||||
|
{
|
||||||
|
return !empty($record->wallet?->product);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveMainWalletBalanceCashForOrder($record): ?int
|
||||||
|
{
|
||||||
|
$customerId = $record->customer_id ?? auth('customer')->id();
|
||||||
|
$mainWalletIds = Wallet::where('owner', $customerId)
|
||||||
|
->whereNull('product_id')
|
||||||
|
->whereNull('fund_id')
|
||||||
|
->pluck('id');
|
||||||
|
|
||||||
|
if ($mainWalletIds->isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mainTx = Transaction::where('order_id', $record->order_id)
|
||||||
|
->whereIn('wallet', $mainWalletIds)
|
||||||
|
->whereNotNull('balance_cash')
|
||||||
|
->orderBy('id')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($mainTx) {
|
||||||
|
return (int) $mainTx->balance_cash;
|
||||||
|
}
|
||||||
|
|
||||||
|
$previousTx = Transaction::whereIn('wallet', $mainWalletIds)
|
||||||
|
->where('id', '<', $record->id)
|
||||||
|
->whereNotNull('balance_cash')
|
||||||
|
->orderByDesc('id')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
return $previousTx ? (int) $previousTx->balance_cash : null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ class SingleOrderController extends Controller
|
|||||||
'active' => true,
|
'active' => true,
|
||||||
'order_id' => $order->id,
|
'order_id' => $order->id,
|
||||||
'start_at' => now(),
|
'start_at' => now(),
|
||||||
|
'title' => self::meltedGoldBuyTitle(),
|
||||||
], 1, true, false);
|
], 1, true, false);
|
||||||
$response['1'] = 2;
|
$response['1'] = 2;
|
||||||
//send to provider
|
//send to provider
|
||||||
@@ -253,6 +254,7 @@ class SingleOrderController extends Controller
|
|||||||
'active' => true,
|
'active' => true,
|
||||||
'order_id' => $order->id,
|
'order_id' => $order->id,
|
||||||
'start_at' => now(),
|
'start_at' => now(),
|
||||||
|
'title' => self::productBuyTitle($data['product']['title'] ?? ''),
|
||||||
], 1, true, false);
|
], 1, true, false);
|
||||||
|
|
||||||
|
|
||||||
@@ -285,7 +287,7 @@ class SingleOrderController extends Controller
|
|||||||
'expire_at' => now(),
|
'expire_at' => now(),
|
||||||
'active' => true,
|
'active' => true,
|
||||||
'order_id' => $order->id,
|
'order_id' => $order->id,
|
||||||
'title' => $this->goldWithdrawTitle()
|
'title' => self::productBuyTitle($data['product']['title'] ?? '')
|
||||||
], 12, false, true);
|
], 12, false, true);
|
||||||
$wallet_interface_product = new WalletInterface(auth('customer')->id(), auth('customer')->user()->type, null, $data["product_id"]);
|
$wallet_interface_product = new WalletInterface(auth('customer')->id(), auth('customer')->user()->type, null, $data["product_id"]);
|
||||||
$wallet_interface_product->wallet->gold = intval($wallet_interface_product->wallet->gold);
|
$wallet_interface_product->wallet->gold = intval($wallet_interface_product->wallet->gold);
|
||||||
@@ -297,6 +299,7 @@ class SingleOrderController extends Controller
|
|||||||
'active' => true,
|
'active' => true,
|
||||||
'order_id' => $order->id,
|
'order_id' => $order->id,
|
||||||
'start_at' => now(),
|
'start_at' => now(),
|
||||||
|
'title' => self::productBuyTitle($data['product']['title'] ?? ''),
|
||||||
], 1, true, false);
|
], 1, true, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -319,7 +322,8 @@ class SingleOrderController extends Controller
|
|||||||
"cash" => $data['total_price'],
|
"cash" => $data['total_price'],
|
||||||
'expire_at' => now(),
|
'expire_at' => now(),
|
||||||
'active' => true,
|
'active' => true,
|
||||||
'order_id' => $order->id
|
'order_id' => $order->id,
|
||||||
|
'title' => self::meltedGoldSellTitle(),
|
||||||
], 2, false, true);
|
], 2, false, true);
|
||||||
|
|
||||||
//send to Goldir
|
//send to Goldir
|
||||||
@@ -355,6 +359,7 @@ class SingleOrderController extends Controller
|
|||||||
'active' => true,
|
'active' => true,
|
||||||
'order_id' => $order->id,
|
'order_id' => $order->id,
|
||||||
'start_at' => now(),
|
'start_at' => now(),
|
||||||
|
'title' => self::productSellTitle($data['product']['title'] ?? ''),
|
||||||
], 1, false, false);
|
], 1, false, false);
|
||||||
$data['transaction'][] = new TransactionInterface($wallet_interface, $_inp = [
|
$data['transaction'][] = new TransactionInterface($wallet_interface, $_inp = [
|
||||||
"number" => $data['number'],
|
"number" => $data['number'],
|
||||||
@@ -393,7 +398,7 @@ class SingleOrderController extends Controller
|
|||||||
'expire_at' => now(),
|
'expire_at' => now(),
|
||||||
'active' => true,
|
'active' => true,
|
||||||
'order_id' => $order->id,
|
'order_id' => $order->id,
|
||||||
'title' => $this->goldDepositTitle()
|
'title' => self::productSellTitle($data['product']['title'] ?? '')
|
||||||
], 12, true, false);
|
], 12, true, false);
|
||||||
$wallet_interface_product->wallet->gold = intval($wallet_interface_product->wallet->gold);
|
$wallet_interface_product->wallet->gold = intval($wallet_interface_product->wallet->gold);
|
||||||
$wallet_interface_product->wallet->save();
|
$wallet_interface_product->wallet->save();
|
||||||
@@ -404,6 +409,7 @@ class SingleOrderController extends Controller
|
|||||||
'active' => true,
|
'active' => true,
|
||||||
'order_id' => $order->id,
|
'order_id' => $order->id,
|
||||||
'start_at' => now(),
|
'start_at' => now(),
|
||||||
|
'title' => self::productSellTitle($data['product']['title'] ?? ''),
|
||||||
], 1, false, false);
|
], 1, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,20 +483,20 @@ class SingleOrderController extends Controller
|
|||||||
: 0
|
: 0
|
||||||
);
|
);
|
||||||
$totalPrice = $data['total_price'] ?? ($data['payment_amount'] ?? 0);
|
$totalPrice = $data['total_price'] ?? ($data['payment_amount'] ?? 0);
|
||||||
$productTitle = $data['product']['title'] ?? self::metalTypeLabel();
|
$subjectTitle = $this->transactionSubjectTitle($data);
|
||||||
|
|
||||||
$message = "کاربر {$customer->name} با شماره موبایل {$customer->mobile} اقدام به $transactionType {$productTitle} به مقدار " .
|
$message = "کاربر {$customer->name} با شماره موبایل {$customer->mobile} اقدام به $transactionType {$subjectTitle} به مقدار " .
|
||||||
"{$amount} گرم به مبلغ " . number_format($totalPrice) .
|
"{$amount} گرم به مبلغ " . number_format($totalPrice) .
|
||||||
" ریال کرد. با تشکر، $companyName";
|
" ریال کرد. با تشکر، $companyName";
|
||||||
User::where('send_sms', 1)->get()->each(function ($admin) use ($message, $data, $transactionType, $companyName) {
|
User::where('send_sms', 1)->get()->each(function ($admin) use ($message, $data, $transactionType, $companyName) {
|
||||||
$this->send($admin->mobile, $message);
|
$this->send($admin->mobile, $message);
|
||||||
});
|
});
|
||||||
$wallet = Wallet::where('owner', $data['customer_id'])->whereNull('fund_id')->first();
|
$wallet = Wallet::where('owner', $data['customer_id'])->whereNull('fund_id')->first();
|
||||||
$metalLabel = self::metalTypeLabel();
|
$balanceLabel = self::metalTypeLabel();
|
||||||
// $pricePerGram = $totalPrice / $amount;
|
// $pricePerGram = $totalPrice / $amount;
|
||||||
$customerMessage = "$companyName\n$transactionType {$metalLabel}\nگرم: {$amount}\n" .
|
$customerMessage = "$companyName\n$transactionType {$subjectTitle}\nگرم: {$amount}\n" .
|
||||||
"مبلغ کل: " . number_format($totalPrice) . "\n\n" .
|
"مبلغ کل: " . number_format($totalPrice) . "\n\n" .
|
||||||
"موجودی {$metalLabel}: {$wallet->gold}\n" .
|
"موجودی {$balanceLabel}: {$wallet->gold}\n" .
|
||||||
"مانده ریالی: " . number_format($wallet->cash) . "\n" .
|
"مانده ریالی: " . number_format($wallet->cash) . "\n" .
|
||||||
$this->Config('app_url');
|
$this->Config('app_url');
|
||||||
|
|
||||||
@@ -672,14 +678,18 @@ class SingleOrderController extends Controller
|
|||||||
->count() < (int)$count;
|
->count() < (int)$count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function goldDepositTitle(): string
|
private function isProductOrder(array $data): bool
|
||||||
{
|
{
|
||||||
return 'موجودی ' . self::metalTypeLabel();
|
return !empty($data['product_id']) && !empty($data['product']['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function goldWithdrawTitle(): string
|
private function transactionSubjectTitle(array $data): string
|
||||||
{
|
{
|
||||||
return 'برداشت ' . self::metalTypeLabel();
|
if ($this->isProductOrder($data)) {
|
||||||
|
return $data['product']['title'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::meltedGoldLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function insufficientGoldBalanceMessage(array $data): string
|
private function insufficientGoldBalanceMessage(array $data): string
|
||||||
|
|||||||
@@ -72,16 +72,16 @@ class TransactionInterface
|
|||||||
if (isset($_inp['gold'])){
|
if (isset($_inp['gold'])){
|
||||||
$_inp['gold'] = abs($_inp['gold']) * ($deposit_gold ? 1 : -1);
|
$_inp['gold'] = abs($_inp['gold']) * ($deposit_gold ? 1 : -1);
|
||||||
$wallet->gold += $_inp['gold'];
|
$wallet->gold += $_inp['gold'];
|
||||||
$_inp['balance_gold'] = $wallet->gold;
|
|
||||||
}
|
}
|
||||||
if (isset($_inp['cash'])){
|
if (isset($_inp['cash'])){
|
||||||
$_inp['cash'] = abs($_inp['cash']) * ($deposit_cash ? 1 : -1);
|
$_inp['cash'] = abs($_inp['cash']) * ($deposit_cash ? 1 : -1);
|
||||||
$wallet->cash += $_inp['cash'];
|
$wallet->cash += $_inp['cash'];
|
||||||
$_inp['balance_cash'] = $wallet->cash;
|
|
||||||
}
|
}
|
||||||
if($gold_block != 0){
|
if($gold_block != 0){
|
||||||
$wallet->gold_block += $gold_block;
|
$wallet->gold_block += $gold_block;
|
||||||
}
|
}
|
||||||
|
$_inp['balance_gold'] = $wallet->gold;
|
||||||
|
$_inp['balance_cash'] = $wallet->cash;
|
||||||
$_inp['wallet'] = $wallet->id;
|
$_inp['wallet'] = $wallet->id;
|
||||||
$_inp['type'] = $_type;
|
$_inp['type'] = $_type;
|
||||||
// $_inp['transaction_type'] = $_type;
|
// $_inp['transaction_type'] = $_type;
|
||||||
|
|||||||
Reference in New Issue
Block a user