Price orders at the provider's real trade rate instead of the mid quote.

montzar_live_price is the midpoint between the colleague's buy and sell rates,
so orders priced straight from it charged the customer less than we pay the
provider and the whole spread was lost on every trade, even though the app
already showed the correct side. Order base price now follows the traded side
(base + spread on buy, base - spread on sell), which also makes price_original
the real cost basis so the dashboard stops counting the provider spread as
profit. Conditional order triggers compare against the same displayed price.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-10 19:21:56 +03:30
co-authored by Cursor
parent 279e4bc881
commit fabce6176a
4 changed files with 78 additions and 11 deletions
@@ -66,7 +66,11 @@ class SingleOrderController extends Controller
$orderProductId = (int) ($data['abshode_id'] ?? $data['product_id'] ?? $config->mainProductId() ?? 0);
$orderProduct = $orderProductId > 0 ? Product::find($orderProductId) : null;
$basePrice = app(ProductDisplayPriceService::class)->resolveOrderBasePrice($orderProduct);
$orderDirection = isset($data['direction']) ? (int) $data['direction'] : null;
// پایه وسطِ نرخ خرید/فروش همکار است — سفارش با همان سمتی حساب شود که با همکار معامله می‌کنیم
$basePrice = app(ProductDisplayPriceService::class)
->resolveOrderTradePrice($orderProduct, $orderDirection);
if ($basePrice <= 0) {
if ($config->isOutsideTradingHours()) {
@@ -79,7 +83,7 @@ class SingleOrderController extends Controller
$data['all_price'] = $latestPrice;
$data['price'] = $basePrice;
$data['price_id'] = $latestPrice?->id;
$data['difference'] = $config->orderPriceDiffRial(isset($data['direction']) ? (int) $data['direction'] : null);
$data['difference'] = $config->orderPriceDiffRial($orderDirection);
$data['service_charge_percentage'] = $config->orderServiceChargePercentage();
$fee_free = Setting::where('key', 'fee_free')->where('is_active', true)->value('value');
@@ -125,7 +129,7 @@ class SingleOrderController extends Controller
if (!empty($data['fee_free'])) {
$data['service_charge_percentage'] = 0;
}
$data['price_original'] = $this->resolveProductUnitBasePrice($data['product']);
$data['price_original'] = $this->resolveProductUnitBasePrice($data['product'], 1);
$this->applyCashPriceDiff($config, $data['product'], 1, $data, (float) $data['price_original']);
$data['total_fee'] = $data['number'] * $data['fee'];
$data['total_price_original'] = $this->resolveProductOrderPricingAmount($data['product'], 1.0)
@@ -146,7 +150,7 @@ class SingleOrderController extends Controller
if (!empty($data['fee_free'])) {
$data['service_charge_percentage'] = 0;
}
$data['price_original'] = $this->resolveProductUnitBasePrice($data['product']);
$data['price_original'] = $this->resolveProductUnitBasePrice($data['product'], 2);
$this->applyCashPriceDiff($config, $data['product'], 2, $data, (float) $data['price_original']);
$data['total_fee'] = $data['number'] * $data['fee'];
$data['total_price_original'] = $this->resolveProductOrderPricingAmount($data['product'], 1.0)
@@ -1382,7 +1386,7 @@ class SingleOrderController extends Controller
$base = (float) ($basePriceRial ?? 0);
if ($base <= 0) {
$base = (float) $this->resolveProductUnitBasePrice($product);
$base = (float) $this->resolveProductUnitBasePrice($product, $direction);
}
if ($base <= 0) {
$base = ProductPriceService::productBasePriceRial($product);
@@ -1510,13 +1514,13 @@ class SingleOrderController extends Controller
* - reading_method (مثل شمش zaarbox) → همان قیمت enrichشدهٔ لیست/UI، نه ستون کهنه/صفر DB
* - بقیه → قیمت ذخیره‌شدهٔ محصول
*/
private function resolveProductUnitBasePrice(Product $product): int
private function resolveProductUnitBasePrice(Product $product, ?int $direction = null): int
{
$display = app(ProductDisplayPriceService::class);
// قیمت اپ یا فید مرجع — همان منبع نمایش؛ DB خام برای reading_method اغلب ۰/کهنه است
if ($display->usesAppPrice($product) || $product->reading_method) {
return (int) round($display->resolveOrderBasePrice($product));
return (int) round($display->resolveOrderTradePrice($product, $direction));
}
return (int) (($product->price ?? 0) + ($product->price_profit ?? 0));