fix bug 22/4 2

This commit is contained in:
2026-07-13 19:03:30 +03:30
parent 7eb4650b80
commit 277cf31d93
8 changed files with 217 additions and 29 deletions
@@ -671,6 +671,22 @@ class ProductController extends SuperController
unset($data['direct_price']);
}
if (!Product::hasAppPriceColumn()) {
unset($data['app_price']);
} elseif (array_key_exists('app_price', $data)) {
$data['app_price'] = filter_var($data['app_price'], FILTER_VALIDATE_BOOLEAN);
// قیمت اپ: مرجع خارجی ندارد، متغیر است (هر گرم × وزن) و قیمت دستی نگه داشته نمی‌شود
if ($data['app_price']) {
$data['reading_method'] = null;
if (Product::hasDirectPriceColumn()) {
$data['direct_price'] = 0;
}
$data['price'] = 0;
$data['price_profit'] = 0;
}
}
if (!Product::hasInventoryColumn()) {
unset($data['inventory']);
}
@@ -682,24 +698,35 @@ class ProductController extends SuperController
}
if (!Product::hasPhysicalDeliveryColumns()) {
unset($data['has_physical_delivery'], $data['min_physical_delivery_grams']);
unset(
$data['has_physical_delivery'],
$data['min_physical_delivery_quantity'],
$data['min_physical_delivery_grams']
);
} else {
// سازگاری با نسخهٔ قبلی که فیلد را min_physical_delivery_grams می‌فرستاد
if (!array_key_exists('min_physical_delivery_quantity', $data)
&& array_key_exists('min_physical_delivery_grams', $data)) {
$data['min_physical_delivery_quantity'] = $data['min_physical_delivery_grams'];
}
unset($data['min_physical_delivery_grams']);
$hasDelivery = array_key_exists('has_physical_delivery', $data)
? filter_var($data['has_physical_delivery'], FILTER_VALIDATE_BOOLEAN)
: false;
$data['has_physical_delivery'] = $hasDelivery;
if (!$hasDelivery) {
$data['min_physical_delivery_grams'] = null;
$data['min_physical_delivery_quantity'] = null;
} else {
$rawMin = $data['min_physical_delivery_grams'] ?? null;
$rawMin = $data['min_physical_delivery_quantity'] ?? null;
$min = $this->normalizeCashFeeValue($rawMin);
if ($min <= 0) {
throw new UnprocessableEntityHttpException(
'برای فعال کردن تحویل فیزیکی باید حداقل گرم معتبر وارد شود'
'برای فعال کردن تحویل فیزیکی باید حداقل مقدار معتبر وارد شود'
);
}
$data['min_physical_delivery_grams'] = $min;
$data['min_physical_delivery_quantity'] = $min;
}
}
@@ -417,7 +417,7 @@ class WalletController extends Controller
return response()->json($Withdraw);
}
private function formatGramsNumber(float $value): string
private function formatDeliveryQuantity(float $value): string
{
$rounded = round($value, 3);
if (fmod($rounded, 1.0) === 0.0) {
@@ -466,7 +466,7 @@ class WalletController extends Controller
$availableGold = $assetSummaryService
->productDisplayQuantity($customerId, $ownerType, $productId);
// گیت تحویل فیزیکی per-product — سوییچ محصول و حداقل گرم
// گیت تحویل فیزیکی per-product — سوییچ محصول و حداقل مقدار (به واحد خود محصول)
$walletProduct = $data['wallets'][$key]['wallet']['product'];
if (Product::hasPhysicalDeliveryColumns() && !$walletProduct->physicalDeliveryEnabled()) {
return response()->json([
@@ -474,20 +474,22 @@ class WalletController extends Controller
], 422);
}
$minDeliveryGrams = Product::hasPhysicalDeliveryColumns()
? $walletProduct->minPhysicalDeliveryGrams()
$minDeliveryQuantity = Product::hasPhysicalDeliveryColumns()
? $walletProduct->minPhysicalDeliveryQuantity()
: 0.0;
if ($minDeliveryGrams > 0) {
if ($minDeliveryQuantity > 0) {
// موجودی و حداقل هر دو با واحد خود محصول سنجیده می‌شوند:
// تعدادی → عدد، وزنی → گرم/کیلوگرم (همسان با inventory_cards)
$card = $assetSummaryService->productInventoryCard($customerId, $ownerType, $productId);
$isCount = ($card['display_type'] ?? null) === 'count';
$unitWeight = (float) ($walletProduct['amount'] ?? 0);
$availableGrams = $isCount ? $availableGold * $unitWeight : $availableGold;
$unitLabel = $card['unit'] ?? Controller::productQuantityUnit(
Controller::productUnitPayload($walletProduct)
);
if ($availableGrams + 0.0001 < $minDeliveryGrams) {
$remaining = max(0, $minDeliveryGrams - $availableGrams);
if ($availableGold + 0.0001 < $minDeliveryQuantity) {
$remaining = max(0, $minDeliveryQuantity - $availableGold);
return response()->json([
'message' => $this->formatGramsNumber($remaining)
. " گرم مانده تا رسیدن به حداقل تحویل فیزیکی "
'message' => $this->formatDeliveryQuantity($remaining)
. " {$unitLabel} مانده تا رسیدن به حداقل تحویل فیزیکی "
. "{$walletProduct['title']}"
], 422);
}
@@ -116,7 +116,7 @@ class SingleOrderController extends Controller
$data['service_charge_percentage'] = isset($data['fee_free']) && $data['fee_free'] === true ? 0 : ($data['product']['percent_fee_buy']) * $data['number'];
$data['difference'] = $data['fee'] = $this->resolveCashPriceDiff($config, $data['product'], 1);
$data['total_fee'] = $data['number'] * $data['fee'];
$data['price_original'] = $data['product']['price'] + $data['product']['price_profit'];
$data['price_original'] = $this->resolveProductUnitBasePrice($data['product']);
$data['total_price_original'] = $data['product']['amount'] * ($data['price_original'] ?? 0);
// Check if the method is cash
@@ -134,7 +134,7 @@ class SingleOrderController extends Controller
$data['service_charge_percentage'] = isset($data['fee_free']) && $data['fee_free'] === true ? 0 : ($data['product']['percent_fee_sell']) * $data['number'];
$data['difference'] = $data['fee'] = $this->resolveCashPriceDiff($config, $data['product'], 2);
$data['total_fee'] = $data['number'] * $data['fee'];
$data['price_original'] = $data['product']['price'] + $data['product']['price_profit'];
$data['price_original'] = $this->resolveProductUnitBasePrice($data['product']);
$data['total_price_original'] = $data['product']['amount'] * ($data['price_original'] ?? 0);
$this->assertMinimumSellCash($data);
@@ -1171,6 +1171,22 @@ class SingleOrderController extends Controller
);
}
/**
* قیمت پایهٔ هر واحد محصول (بدون ضرب در وزن — وزن در total_price_original اعمال می‌شود).
* محصول با پرچم «قیمت اپ» → قیمت زندهٔ هر گرم اپ (با تعدیل درصدی)؛
* بقیه → همان قیمت ذخیره‌شدهٔ محصول.
*/
private function resolveProductUnitBasePrice(Product $product): int
{
$display = app(ProductDisplayPriceService::class);
if ($display->usesFlaggedAppPrice($product)) {
return (int) round($display->resolveOrderBasePrice($product));
}
return (int) (($product->price ?? 0) + ($product->price_profit ?? 0));
}
private function bonusGift($customer, $referrer)
{
$bonus = Setting::where('key', 'referral_bonus_amount')->where('is_active', 1)->first();