Add formula-based product pricing (P/W/MG) for Parsian-style unit prices.

Port FormulaPriceService from colleague app so admins can compute a single unit price from reference mid, weight, and wage instead of offset coefficients.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-10 16:47:29 +03:30
co-authored by Cursor
parent 71a48c9c08
commit f421fcb83f
9 changed files with 515 additions and 9 deletions
@@ -27,6 +27,7 @@ use App\Services\MontzarService;
use App\Services\ConfigService;
use App\Services\ProductPriceService;
use App\Services\ProductDisplayPriceService;
use App\Services\FormulaPriceService;
use App\Services\ReferralGiftService;
use App\Services\WalletBroadcastService;
@@ -127,7 +128,8 @@ class SingleOrderController extends Controller
$data['price_original'] = $this->resolveProductUnitBasePrice($data['product']);
$this->applyCashPriceDiff($config, $data['product'], 1, $data, (float) $data['price_original']);
$data['total_fee'] = $data['number'] * $data['fee'];
$data['total_price_original'] = $data['product']['amount'] * ($data['price_original'] ?? 0);
$data['total_price_original'] = $this->resolveProductOrderPricingAmount($data['product'], 1.0)
* ($data['price_original'] ?? 0);
// Check if the method is cash
if ($data['method'] == "cash") {
@@ -147,7 +149,8 @@ class SingleOrderController extends Controller
$data['price_original'] = $this->resolveProductUnitBasePrice($data['product']);
$this->applyCashPriceDiff($config, $data['product'], 2, $data, (float) $data['price_original']);
$data['total_fee'] = $data['number'] * $data['fee'];
$data['total_price_original'] = $data['product']['amount'] * ($data['price_original'] ?? 0);
$data['total_price_original'] = $this->resolveProductOrderPricingAmount($data['product'], 1.0)
* ($data['price_original'] ?? 0);
$this->assertMinimumSellCash($data);
@@ -394,7 +397,7 @@ class SingleOrderController extends Controller
{
// همان قیمت پایهٔ سفارش (price_original / قیمت اپ) — نه ستون کهنهٔ products.price
$data['price'] = $this->resolveProductOrderUnitPrice($data) + (float) ($data['difference'] ?? 0);
$data['amount'] = $data['number'] * $data['product']['amount'];
$data['amount'] = $this->resolveProductOrderPricingAmount($data['product'], (float) $data['number']);
// محصول تعدادی: کارمزد فقط از ریال (fee_service_charge_percentage)
$feeRate = isset($data['fee_free']) && $data['fee_free'] === true
? 0.0
@@ -452,7 +455,7 @@ class SingleOrderController extends Controller
{
$data['price'] += $data['difference'];
$data['amount'] = $data['number'] * $data['product']['amount'];
$data['amount'] = $this->resolveProductOrderPricingAmount($data['product'], (float) $data['number']);
// محصول تعدادی: کارمزد از ریال (fee_service_charge_percentage)
$feeRate = isset($data['fee_free']) && $data['fee_free'] === true
? 0.0
@@ -670,7 +673,7 @@ class SingleOrderController extends Controller
{
// همان قیمت پایهٔ سفارش (price_original / قیمت اپ) — نه ستون کهنهٔ products.price
$data['price'] = max(0.0, $this->resolveProductOrderUnitPrice($data) - (float) ($data['difference'] ?? 0));
$data['amount'] = $data['number'] * $data['product']['amount'];
$data['amount'] = $this->resolveProductOrderPricingAmount($data['product'], (float) $data['number']);
// محصول تعدادی: کارمزد فقط از ریال
$feeRate = isset($data['fee_free']) && $data['fee_free'] === true
? 0.0
@@ -723,7 +726,7 @@ class SingleOrderController extends Controller
private function processSellTransactionProductByGold(&$data, $wallet, $wallet_interface)
{
$data['price'] -= $data['difference'];
$data['amount'] = $data['number'] * $data['product']['amount'];
$data['amount'] = $this->resolveProductOrderPricingAmount($data['product'], (float) $data['number']);
// محصول تعدادی: کارمزد فقط از ریال
$feeRate = isset($data['fee_free']) && $data['fee_free'] === true
? 0.0
@@ -1100,7 +1103,7 @@ class SingleOrderController extends Controller
if (!empty($data['product_id']) && isset($data['number'])) {
$product = $data['product'] ?? Product::find($data['product_id']);
if ($product) {
return (float) $data['number'] * (float) $product->amount;
return $this->resolveProductOrderPricingAmount($product, (float) $data['number']);
}
}
@@ -1161,7 +1164,7 @@ class SingleOrderController extends Controller
$product = $data['product'] ?? Product::find($data['product_id']);
if ($product) {
$difference = (float) ($data['difference'] ?? 0);
$amount = (float) $data['number'] * (float) $product->amount;
$amount = $this->resolveProductOrderPricingAmount($product, (float) $data['number']);
$sellUnitPrice = max(0.0, $this->resolveProductOrderUnitPrice($data) - $difference);
return $amount * $sellUnitPrice;