This commit is contained in:
2026-06-11 16:41:28 +03:30
parent 76563be5cd
commit f329419c3a
4 changed files with 170 additions and 4 deletions
@@ -297,13 +297,14 @@ class DashboardController extends Controller
];
// Calculate total gold gifts from transactions
$giftsGold = 0.0;
foreach ($TransactionsAdmin as $TransactionAdmin) {
$response['Gifts'] += $TransactionAdmin->gold;
$giftsGold += (float) $TransactionAdmin->gold;
}
$response['Gifts'] = number_format($response['Gifts'], 3);
$response['Gifts'] = number_format($giftsGold, 3);
// Calculate total price of gold gifts
$response['GiftsPrise'] = floor($response['Gifts'] * Price::latest()->first()->price);
$lastGoldPrice = (float) (Price::latest()->first()?->price ?? 0);
$response['GiftsPrise'] = $lastGoldPrice > 0 ? (int) floor($giftsGold * $lastGoldPrice) : 0;
// Calculate order-related sums
foreach ($ords as $ord) {
$response['fullPriceM1'] += abs($ord->total_price_original - $ord->payment_amount);
@@ -15,6 +15,7 @@ use Illuminate\Support\Facades\Http;
use \App\Http\Controllers\Customer\FundController;
use App\Http\Controllers\Site\ReportController;
use App\Services\ConfigService;
use App\Services\ProductDisplayPriceService;
use App\Services\ProductPriceService;
use Illuminate\Support\Facades\Schema;
@@ -161,6 +162,10 @@ class ProductController extends SuperController
$products = Product::with(['file'])->where('active', 1)->get();
if (str_contains(request()->path(), '/customer/')) {
app(ProductDisplayPriceService::class)->enrichForApi($products);
}
if (Product::hasPriceOffsetColumn() && str_contains(request()->path(), '/customer/')) {
$products->each(function (Product $product) {
if ($product->reading_method) {
@@ -21,6 +21,7 @@ use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Mail;
use Morilog\Jalali\Jalalian;
use App\Services\ConfigService;
use App\Services\ProductDisplayPriceService;
class ReportController extends Controller
@@ -146,6 +147,7 @@ class ReportController extends Controller
protected function appendUpPrices(array $payload): array
{
$payload['up'] = $this->buildUpDownPrices();
app(ProductDisplayPriceService::class)->cacheLivePricePayload($payload);
return $payload;
}
+158
View File
@@ -0,0 +1,158 @@
<?php
namespace App\Services;
use App\Models\Price;
use App\Models\Product;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
/**
* قیمت نمایشی محصولات آبشده با منبع «قیمت اپ» — در DB صفر است، برای API پر می‌شود.
*/
class ProductDisplayPriceService
{
public const LIVE_PRICE_CACHE_KEY = 'live_price_api_payload';
public const LIVE_PRICE_CACHE_SECONDS = 15;
public function usesAppPrice(Product $product): bool
{
if ($product->reading_method) {
return false;
}
if ((int) ($product->direct_price ?? 0) === 1) {
return false;
}
return $this->isMeltedTradeProduct($product);
}
public function enrichForApi(Collection|iterable $products): void
{
$needsLivePrice = false;
foreach ($products as $product) {
if ($product instanceof Product && $this->usesAppPrice($product)) {
$needsLivePrice = true;
break;
}
}
if (!$needsLivePrice) {
return;
}
$basePrice = $this->resolveAppBasePrice();
if ($basePrice <= 0) {
return;
}
foreach ($products as $product) {
if (!$product instanceof Product || !$this->usesAppPrice($product)) {
continue;
}
$offset = Product::hasPriceOffsetColumn()
? (float) ($product->price_offset_percent ?? 0)
: 0.0;
$computed = ProductPriceService::adjustedTotal($basePrice, 0, $offset);
if ($computed <= 0) {
continue;
}
$product->setAttribute('price', $computed);
if (\Illuminate\Support\Facades\Schema::hasColumn($product->getTable(), 'price_profit')) {
$product->setAttribute('price_profit', 0);
}
}
}
/** @param array<string, mixed> $payload */
public function cacheLivePricePayload(array $payload): void
{
Cache::put(self::LIVE_PRICE_CACHE_KEY, [
'price' => (int) ($payload['price'] ?? 0),
'buy' => (int) ($payload['buy'] ?? 0),
'sell' => (int) ($payload['sell'] ?? 0),
'price_last' => (int) ($payload['price_last'] ?? 0),
], now()->addSeconds(self::LIVE_PRICE_CACHE_SECONDS));
}
public function resolveAppBasePrice(): int
{
$payload = $this->livePricePayload();
$price = (int) ($payload['price'] ?? 0);
if ($price > 0) {
return $price;
}
$buy = (int) ($payload['buy'] ?? 0);
$sell = (int) ($payload['sell'] ?? 0);
if ($buy > 0 && $sell > 0) {
return (int) round(($buy + $sell) / 2);
}
return (int) ($payload['price_last'] ?? 0);
}
/** @return array{price: int, buy: int, sell: int, price_last: int} */
private function livePricePayload(): array
{
$cached = Cache::get(self::LIVE_PRICE_CACHE_KEY);
if (is_array($cached)) {
return $cached;
}
return $this->resolveFallbackPayload();
}
/** @return array{price: int, buy: int, sell: int, price_last: int} */
private function resolveFallbackPayload(): array
{
$config = app(ConfigService::class);
$provider = $config->priceProvider();
$price = 0;
if ($provider === 'montzar') {
$price = $config->getInt('montzar_live_price', 0);
} elseif ($provider === 'zaarbox') {
$zaarbox = app(ZaarboxPriceService::class)->fetchPrice();
$price = (int) ($zaarbox['order_price'] ?? 0);
} elseif ($provider === 'main_product') {
$main = $config->mainProduct();
if ($main) {
$price = (int) (($main->price ?? 0) + ($main->price_profit ?? 0));
}
} elseif ($provider === 'taban_gohar') {
$price = $config->getInt('taban_gohar_live_price', 0);
}
if ($price <= 0) {
$last = Price::orderByDesc('id')->first();
if ($last && (float) $last->price > 0) {
$price = (int) $last->price;
}
}
$diffBuy = (int) $config->displayBuySpreadRial();
$diffSell = (int) $config->displaySellSpreadRial();
return [
'price' => $price,
'buy' => $price > 0 ? $price + $diffBuy : 0,
'sell' => $price > 0 ? max(0, $price - $diffSell) : 0,
'price_last' => $price > 0 ? $price + $diffBuy : 0,
];
}
private function isMeltedTradeProduct(Product $product): bool
{
$group = trim((string) ($product->group_type ?? ''));
return in_array($group, ['آبشده', 'کاتد مس'], true);
}
}