added ons
This commit is contained in:
@@ -139,6 +139,7 @@ class ReportController extends Controller
|
|||||||
|
|
||||||
$payload['up'] = $this->buildUpDownPrices();
|
$payload['up'] = $this->buildUpDownPrices();
|
||||||
$payload['last_historical'] = app(ProductDisplayPriceService::class)->resolveHistoricalBasePrice();
|
$payload['last_historical'] = app(ProductDisplayPriceService::class)->resolveHistoricalBasePrice();
|
||||||
|
$payload['gold_ounce'] = $this->resolveGoldOuncePayload();
|
||||||
app(ProductDisplayPriceService::class)->cacheLivePricePayload($payload);
|
app(ProductDisplayPriceService::class)->cacheLivePricePayload($payload);
|
||||||
|
|
||||||
$isFreshPrice = $saveFullCache || request()->boolean('force_refresh');
|
$isFreshPrice = $saveFullCache || request()->boolean('force_refresh');
|
||||||
@@ -164,6 +165,29 @@ class ReportController extends Controller
|
|||||||
return $payload;
|
return $payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function resolveGoldOuncePayload(): ?array
|
||||||
|
{
|
||||||
|
$config = app(ConfigService::class);
|
||||||
|
if (! $config->getBool('show_gold_ounce_price', false)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$zaarbox = app(ZaarboxPriceService::class);
|
||||||
|
if (! $zaarbox->hasApiUrlConfigured()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ounce = $zaarbox->fetchOuncePrice();
|
||||||
|
if (($ounce['price'] ?? 0) <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'price' => (int) $ounce['price'],
|
||||||
|
'label' => trim((string) ($ounce['name'] ?? 'انس طلا')) ?: 'انس طلا',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function lastPrice(Request $request)
|
public function lastPrice(Request $request)
|
||||||
{
|
{
|
||||||
$config = app(ConfigService::class);
|
$config = app(ConfigService::class);
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ class ZaarboxPriceService
|
|||||||
return $url !== '' ? $url : 'https://price.zaarbox.ir/api/free';
|
return $url !== '' ? $url : 'https://price.zaarbox.ir/api/free';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasApiUrlConfigured(): bool
|
||||||
|
{
|
||||||
|
return trim($this->config->getString('zaarbox_api_url', '')) !== '';
|
||||||
|
}
|
||||||
|
|
||||||
/** کلید یا id ردیف در JSON تابلو (settings: zaarbox_price_key) */
|
/** کلید یا id ردیف در JSON تابلو (settings: zaarbox_price_key) */
|
||||||
public function priceIdentifier(): string
|
public function priceIdentifier(): string
|
||||||
{
|
{
|
||||||
@@ -190,6 +195,67 @@ class ZaarboxPriceService
|
|||||||
return $prices;
|
return $prices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int, array<string, mixed>> $prices
|
||||||
|
* @return array<string, mixed>|null
|
||||||
|
*/
|
||||||
|
public function findOunceFeedRow(array $prices): ?array
|
||||||
|
{
|
||||||
|
$row = collect($prices)
|
||||||
|
->map(fn ($item) => is_array($item) ? $item : (array) $item)
|
||||||
|
->filter(function (array $item) {
|
||||||
|
$name = trim((string) ($item['name'] ?? ''));
|
||||||
|
|
||||||
|
return $name !== '' && mb_strpos($name, 'انس') !== false;
|
||||||
|
})
|
||||||
|
->sortBy([
|
||||||
|
fn (array $item) => (bool) ($item['active'] ?? false) ? 0 : 1,
|
||||||
|
fn (array $item) => str_contains(trim((string) ($item['name'] ?? '')), 'انس طلا') ? 0 : 1,
|
||||||
|
fn (array $item) => mb_strlen(trim((string) ($item['name'] ?? ''))),
|
||||||
|
])
|
||||||
|
->first();
|
||||||
|
|
||||||
|
return is_array($row) ? $row : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array{price: int, name: string, raw: array<string, mixed>|null}
|
||||||
|
*/
|
||||||
|
public function fetchOuncePrice(): array
|
||||||
|
{
|
||||||
|
$empty = ['price' => 0, 'name' => '', 'raw' => null];
|
||||||
|
if (! $this->hasApiUrlConfigured()) {
|
||||||
|
return $empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$prices = $this->cachedPriceList(false) ?? $this->fetchPriceList();
|
||||||
|
if (! is_array($prices)) {
|
||||||
|
return $empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = $this->findOunceFeedRow($prices);
|
||||||
|
if ($row === null) {
|
||||||
|
return $empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
$price = $this->resolveReferenceProviderTotal($row);
|
||||||
|
if ($price <= 0) {
|
||||||
|
return $empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'price' => $price,
|
||||||
|
'name' => trim((string) ($row['name'] ?? 'انس طلا')),
|
||||||
|
'raw' => $row,
|
||||||
|
];
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::warning('Zaarbox ounce price fetch failed', ['message' => $e->getMessage()]);
|
||||||
|
|
||||||
|
return $empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array{price: int, order_price: int, raw: array<string, mixed>|null}
|
* @return array{price: int, order_price: int, raw: array<string, mixed>|null}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -209,6 +209,10 @@ INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `de
|
|||||||
SELECT 'show_last_price', 'true', 'نمایش آخرین قیمت DB اگر API قطع شد', 1, 1, NULL
|
SELECT 'show_last_price', 'true', 'نمایش آخرین قیمت DB اگر API قطع شد', 1, 1, NULL
|
||||||
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'show_last_price' LIMIT 1);
|
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'show_last_price' LIMIT 1);
|
||||||
|
|
||||||
|
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`)
|
||||||
|
SELECT 'show_gold_ounce_price', 'false', 'نمایش قیمت انس طلا', 1, 1, NULL
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'show_gold_ounce_price' LIMIT 1);
|
||||||
|
|
||||||
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`)
|
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`)
|
||||||
SELECT 'main_product_price', 'false', 'قیمت از محصول (legacy)', 1, 1, 'از price_provider استفاده کنید'
|
SELECT 'main_product_price', 'false', 'قیمت از محصول (legacy)', 1, 1, 'از price_provider استفاده کنید'
|
||||||
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'main_product_price' LIMIT 1);
|
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'main_product_price' LIMIT 1);
|
||||||
@@ -795,7 +799,7 @@ UPDATE `settings` SET `type` = 'select', `description` = 'bale,telegram,whatsapp
|
|||||||
UPDATE `settings` SET `type` = 'switch' WHERE `key` IN (
|
UPDATE `settings` SET `type` = 'switch' WHERE `key` IN (
|
||||||
'chart_use_local_data',
|
'chart_use_local_data',
|
||||||
'jibit_verification', 'register_jibit_verify', 'open_register', 'auto_active_customer',
|
'jibit_verification', 'register_jibit_verify', 'open_register', 'auto_active_customer',
|
||||||
'close_price', 'show_last_price',
|
'close_price', 'show_last_price', 'show_gold_ounce_price',
|
||||||
'fee_deduct_from_gold',
|
'fee_deduct_from_gold',
|
||||||
'profit_gold_api_enabled', 'payping_round_toman', 'payping_strict_failed_withdraw',
|
'profit_gold_api_enabled', 'payping_round_toman', 'payping_strict_failed_withdraw',
|
||||||
'has_page_earn_money', 'charge_notif', 'group_sms', 'sms_panel',
|
'has_page_earn_money', 'charge_notif', 'group_sms', 'sms_panel',
|
||||||
@@ -1115,6 +1119,7 @@ UPDATE `settings` SET `description` = 'شناسه عددی یا نام reading_m
|
|||||||
UPDATE `settings` SET `description` = 'آدرس پایه API سرویس تابلو آنلاین (بدون مسیر انتهایی). مثال: https://example.com/api' WHERE `key` = 'zaarbox_api_url';
|
UPDATE `settings` SET `description` = 'آدرس پایه API سرویس تابلو آنلاین (بدون مسیر انتهایی). مثال: https://example.com/api' WHERE `key` = 'zaarbox_api_url';
|
||||||
UPDATE `settings` SET `description` = 'کلید یا UUID ردیف قیمت در پاسخ API تابلو. باید با محصول/ردیف موردنظر در سرویس خارجی یکسان باشد.' WHERE `key` = 'zaarbox_price_key';
|
UPDATE `settings` SET `description` = 'کلید یا UUID ردیف قیمت در پاسخ API تابلو. باید با محصول/ردیف موردنظر در سرویس خارجی یکسان باشد.' WHERE `key` = 'zaarbox_price_key';
|
||||||
UPDATE `settings` SET `description` = 'روشن: اگر API قیمت در دسترس نباشد، آخرین قیمت ذخیرهشده در دیتابیس به کاربر نشان داده میشود. خاموش: در قطعی API ممکن است قیمت صفر نمایش داده شود.' WHERE `key` = 'show_last_price';
|
UPDATE `settings` SET `description` = 'روشن: اگر API قیمت در دسترس نباشد، آخرین قیمت ذخیرهشده در دیتابیس به کاربر نشان داده میشود. خاموش: در قطعی API ممکن است قیمت صفر نمایش داده شود.' WHERE `key` = 'show_last_price';
|
||||||
|
UPDATE `settings` SET `description` = 'روشن: اگر آدرس API تابلو (zaarbox_api_url) تنظیم شده باشد، قیمت انس طلا در اپ مشتری نمایش داده میشود. خاموش: نمایش داده نمیشود.' WHERE `key` = 'show_gold_ounce_price';
|
||||||
UPDATE `settings` SET `description` = 'روشن: خارج از بازه «ساعت شروع» تا «ساعت پایان» معامله و نمایش قیمت بسته میشود. خاموش: محدودیت ساعتی سراسری اعمال نمیشود.' WHERE `key` = 'close_price';
|
UPDATE `settings` SET `description` = 'روشن: خارج از بازه «ساعت شروع» تا «ساعت پایان» معامله و نمایش قیمت بسته میشود. خاموش: محدودیت ساعتی سراسری اعمال نمیشود.' WHERE `key` = 'close_price';
|
||||||
UPDATE `settings` SET `description` = 'ساعت شروع فعالیت روزانه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال میشود (مثلاً ۰۹:۰۰).' WHERE `key` = 'startDay';
|
UPDATE `settings` SET `description` = 'ساعت شروع فعالیت روزانه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال میشود (مثلاً ۰۹:۰۰).' WHERE `key` = 'startDay';
|
||||||
UPDATE `settings` SET `description` = 'ساعت پایان فعالیت روزانه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال میشود (مثلاً ۲۲:۰۰).' WHERE `key` = 'endDay';
|
UPDATE `settings` SET `description` = 'ساعت پایان فعالیت روزانه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال میشود (مثلاً ۲۲:۰۰).' WHERE `key` = 'endDay';
|
||||||
@@ -1365,6 +1370,7 @@ UPDATE `settings` SET `title_fa` = 'ارسال به تهحساب' WHERE `key`
|
|||||||
UPDATE `settings` SET `title_fa` = 'آدرس API سرور' WHERE `key` = 'server_url';
|
UPDATE `settings` SET `title_fa` = 'آدرس API سرور' WHERE `key` = 'server_url';
|
||||||
UPDATE `settings` SET `title_fa` = 'کارمزد درصدی (alias)' WHERE `key` = 'service_charge_percentage';
|
UPDATE `settings` SET `title_fa` = 'کارمزد درصدی (alias)' WHERE `key` = 'service_charge_percentage';
|
||||||
UPDATE `settings` SET `title_fa` = 'نمایش آخرین قیمت ذخیرهشده' WHERE `key` = 'show_last_price';
|
UPDATE `settings` SET `title_fa` = 'نمایش آخرین قیمت ذخیرهشده' WHERE `key` = 'show_last_price';
|
||||||
|
UPDATE `settings` SET `title_fa` = 'نمایش قیمت انس طلا' WHERE `key` = 'show_gold_ounce_price';
|
||||||
UPDATE `settings` SET `title_fa` = 'مسیر SSE قیمت' WHERE `key` = 'sse_path';
|
UPDATE `settings` SET `title_fa` = 'مسیر SSE قیمت' WHERE `key` = 'sse_path';
|
||||||
UPDATE `settings` SET `title_fa` = 'ساعت شروع' WHERE `key` = 'startDay';
|
UPDATE `settings` SET `title_fa` = 'ساعت شروع' WHERE `key` = 'startDay';
|
||||||
UPDATE `settings` SET `title_fa` = 'وضعیت فروشگاه' WHERE `key` = 'store_status';
|
UPDATE `settings` SET `title_fa` = 'وضعیت فروشگاه' WHERE `key` = 'store_status';
|
||||||
@@ -1448,7 +1454,7 @@ UPDATE `settings` SET `can_edit` = 1 WHERE `key` IN (
|
|||||||
'open_register',
|
'open_register',
|
||||||
'referral_bonus_amount', 'referral_id', 'referral_limit', 'referral_gift_on_first_order',
|
'referral_bonus_amount', 'referral_id', 'referral_limit', 'referral_gift_on_first_order',
|
||||||
'register_jibit_verify', 'register_referral_bonus_message', 'register_referral_sms_to_referrer',
|
'register_jibit_verify', 'register_referral_bonus_message', 'register_referral_sms_to_referrer',
|
||||||
'sell_fee', 'show_last_price', 'startDay',
|
'sell_fee', 'show_last_price', 'show_gold_ounce_price', 'startDay',
|
||||||
'support_messenger', 'support_messenger_id', 'support_messenger_text',
|
'support_messenger', 'support_messenger_id', 'support_messenger_text',
|
||||||
'deposit_support_message_text', 'deposit_account_holder', 'deposit_card_number', 'deposit_sheba',
|
'deposit_support_message_text', 'deposit_account_holder', 'deposit_card_number', 'deposit_sheba',
|
||||||
'text_about', 'text_rule',
|
'text_about', 'text_rule',
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
-- سوییچ «نمایش قیمت انس طلا» — برای نصبهای موجود
|
||||||
|
-- idempotent: چند بار قابل اجرا
|
||||||
|
-- • اولین بار: INSERT با value='false' (پیشفرض خاموش)
|
||||||
|
-- • اجرای مجدد: value و is_active دست نمیخورند — title_fa / description / type / can_edit همیشه override میشوند
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`)
|
||||||
|
SELECT 'show_gold_ounce_price', 'false', 'نمایش قیمت انس طلا', 1, 1,
|
||||||
|
'روشن: اگر آدرس API تابلو (zaarbox_api_url) تنظیم شده باشد، قیمت انس طلا در اپ مشتری نمایش داده میشود. خاموش: نمایش داده نمیشود.',
|
||||||
|
'switch'
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'show_gold_ounce_price' LIMIT 1);
|
||||||
|
|
||||||
|
UPDATE `settings`
|
||||||
|
SET `title_fa` = 'نمایش قیمت انس طلا',
|
||||||
|
`description` = 'روشن: اگر آدرس API تابلو (zaarbox_api_url) تنظیم شده باشد، قیمت انس طلا در اپ مشتری نمایش داده میشود. خاموش: نمایش داده نمیشود.',
|
||||||
|
`type` = 'switch',
|
||||||
|
`can_edit` = 1
|
||||||
|
WHERE `key` = 'show_gold_ounce_price';
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
SELECT `key`, `title_fa`, LEFT(`description`, 60) AS desc_preview, `can_edit`, `type`
|
||||||
|
FROM `settings`
|
||||||
|
WHERE `key` = 'show_gold_ounce_price';
|
||||||
Reference in New Issue
Block a user