fix scadule for getting price

This commit is contained in:
2026-09-02 18:14:32 +03:30
parent 0b1e5c687b
commit 92d8f2e9b3
5 changed files with 149 additions and 67 deletions
@@ -1,23 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Services\ColleagueOrderCallbackService;
use Illuminate\Console\Command;
class PollPendingColleagueOrdersCommand extends Command
{
protected $signature = 'colleague:poll-pending-orders';
protected $description = 'Poll colleague for pending cover orders every 35s when callback is on';
public function handle(ColleagueOrderCallbackService $service): int
{
$first = $service->pollDueOrders();
sleep(ColleagueOrderCallbackService::POLL_SECONDS);
$second = $service->pollDueOrders();
$this->info(json_encode(['first' => $first, 'second' => $second], JSON_UNESCAPED_UNICODE));
return self::SUCCESS;
}
}
-5
View File
@@ -53,11 +53,6 @@ class Kernel extends ConsoleKernel
->everyMinute() ->everyMinute()
->name('automations_run') ->name('automations_run')
->withoutOverlapping(50); ->withoutOverlapping(50);
$schedule->command('colleague:poll-pending-orders')
->everyMinute()
->name('colleague_poll_pending_orders')
->withoutOverlapping(58);
} }
protected function commands() protected function commands()
@@ -2054,20 +2054,27 @@ class SingleOrderController extends Controller
public function pendingColleague() public function pendingColleague()
{ {
$order = app(ColleagueOrderCallbackService::class) $service = app(ColleagueOrderCallbackService::class);
->pendingForCustomer((int) auth('customer')->id()); $order = $service->pendingForCustomer((int) auth('customer')->id());
if ($order) {
$order = $service->refreshIfDue($order);
}
return response()->json(app(ColleagueOrderCallbackService::class)->publicStatusPayload($order)); return response()->json($service->publicStatusPayload($order));
} }
public function colleagueStatus(int $id) public function colleagueStatus(int $id)
{ {
$service = app(ColleagueOrderCallbackService::class);
$order = Order::query() $order = Order::query()
->where('id', $id) ->where('id', $id)
->where('customer_id', auth('customer')->id()) ->where('customer_id', auth('customer')->id())
->first(); ->first();
if ($order) {
$order = $service->refreshIfDue($order);
}
return response()->json(app(ColleagueOrderCallbackService::class)->publicStatusPayload($order)); return response()->json($service->publicStatusPayload($order));
} }
/** /**
+45 -30
View File
@@ -52,42 +52,27 @@ class ColleagueOrderCallbackService
return $this->applyProviderSts($order, $sts, $body); return $this->applyProviderSts($order, $sts, $body);
} }
public function pollDueOrders(): int public function refreshIfDue(Order $order): Order
{ {
if (!Schema::hasTable('orders') || !Schema::hasColumn('orders', 'sts')) { if ((int) $order->sts !== 4) {
return 0; return $order;
} }
$cutoff = now()->subSeconds(self::POLL_SECONDS); if (!$this->isPollDue($order)) {
$handled = 0; return $order;
$query = Order::query()->where('sts', 4)->whereNotNull('provider_id');
if (Schema::hasColumn('orders', 'colleague_last_poll_at')) {
$query->where(function ($q) use ($cutoff) {
$q->where(function ($inner) use ($cutoff) {
$inner->whereNull('colleague_last_poll_at')
->where('created_at', '<=', $cutoff);
})->orWhere('colleague_last_poll_at', '<=', $cutoff);
});
} else {
$query->where('created_at', '<=', $cutoff);
} }
$orders = $query->orderBy('id')->limit(80)->get(); try {
foreach ($orders as $order) { $this->pollOne($order);
try { } catch (\Throwable $e) {
$this->pollOne($order); Log::warning('Colleague pending poll failed', [
$handled++; 'order_id' => $order->id,
} catch (\Throwable $e) { 'error' => $e->getMessage(),
Log::warning('Colleague pending poll failed', [ ]);
'order_id' => $order->id, $this->touchPollAt($order);
'error' => $e->getMessage(),
]);
$this->touchPollAt($order);
}
} }
return $handled; return Order::query()->find($order->id) ?? $order;
} }
public function pollOne(Order $order): array public function pollOne(Order $order): array
@@ -110,7 +95,17 @@ class ColleagueOrderCallbackService
return ['ok' => true, 'state' => 'wait']; return ['ok' => true, 'state' => 'wait'];
} }
return $this->applyProviderSts($order, $sts, $body); // جدول سفارش همکار همان sts مدل است (۲ موفق / ۳ ناموفق / ۴ هنوز باز).
// کالبک جداست: آن‌جا ۴ و ۶ یعنی رد.
if (in_array($sts, [3, 6], true)) {
return $this->rejectPending($order, $body);
}
if ($sts === 2) {
return $this->approvePending($order, $body);
}
return ['ok' => true, 'state' => 'wait', 'sts' => (int) $order->sts];
} }
/** /**
@@ -286,12 +281,32 @@ class ColleagueOrderCallbackService
$order->save(); $order->save();
} }
private function isPollDue(Order $order): bool
{
$cutoff = now()->subSeconds(self::POLL_SECONDS);
$last = $order->colleague_last_poll_at ?? null;
if ($last) {
return $last <= $cutoff;
}
$created = $order->created_at;
return !$created || $created <= $cutoff;
}
/** /**
* @param array<string, mixed> $body * @param array<string, mixed> $body
*/ */
public function providerStsFromBody(array $body): ?int public function providerStsFromBody(array $body): ?int
{ {
$rows = [$body, $body['data'] ?? null, $body['order'] ?? null]; $rows = [$body, $body['data'] ?? null, $body['order'] ?? null];
if (isset($body['rows']) && is_array($body['rows'])) {
foreach ($body['rows'] as $row) {
if (is_array($row)) {
$rows[] = $row;
}
}
}
foreach ($body as $item) { foreach ($body as $item) {
if (!is_array($item)) { if (!is_array($item)) {
continue; continue;
+93 -5
View File
@@ -638,7 +638,7 @@ class MontzarService
} }
/** /**
* GET وضعیت سفارش روی نود همکار — مسیر از setting + شناسه سفارش همکار. * وضعیت سفارش روی نود همکار — اول GET مسیر+شناسه، اگر sts نبود POST جدول همان مسیر.
* *
* @return array<string, mixed>|null * @return array<string, mixed>|null
*/ */
@@ -652,12 +652,97 @@ class MontzarService
if ($path === '') { if ($path === '') {
$path = '/server/customer/order'; $path = '/server/customer/order';
} }
$path = rtrim($path, '/');
$url = $this->endpoint(rtrim($path, '/') . '/' . $providerOrderId); $got = $this->montzarJson('GET', $this->endpoint($path . '/' . $providerOrderId));
$row = $this->colleagueOrderRowFromBody($got, $providerOrderId);
if ($row) {
return $row;
}
foreach ($this->colleagueOrderTableUrls($path) as $url) {
$body = $this->montzarJson('POST', $url, [
'filters' => [[
'field' => 'id',
'cr' => 'and',
'type' => 'text',
'op' => 'eq',
'value' => (string) $providerOrderId,
]],
'limit' => 12,
'page' => 1,
'search' => '',
]);
$row = $this->colleagueOrderRowFromBody($body, $providerOrderId);
if ($row) {
return $row;
}
}
return is_array($got) ? $got : null;
}
/**
* @return list<string>
*/
private function colleagueOrderTableUrls(string $path): array
{
$urls = [$this->endpoint($path . '/table')];
if (str_ends_with($path, '/order') && !str_contains($path, '/single/')) {
$urls[] = $this->endpoint(str_replace('/customer/order', '/customer/single/order', $path) . '/table');
}
return array_values(array_unique($urls));
}
/**
* @param array<string, mixed>|null $body
* @return array<string, mixed>|null
*/
private function colleagueOrderRowFromBody(?array $body, int $providerOrderId): ?array
{
if (!is_array($body)) {
return null;
}
$candidates = [$body, $body['data'] ?? null, $body['order'] ?? null];
if (isset($body['rows']) && is_array($body['rows'])) {
foreach ($body['rows'] as $row) {
if (is_array($row)) {
$candidates[] = $row;
}
}
}
$matched = null;
foreach ($candidates as $row) {
if (!is_array($row) || !array_key_exists('sts', $row)) {
continue;
}
$id = (int) ($row['id'] ?? $row['order_id'] ?? 0);
if ($id === $providerOrderId) {
return $row;
}
if ($id === 0 && $matched === null) {
$matched = $row;
}
}
return $matched;
}
/**
* @param array<string, mixed> $payload
* @return array<string, mixed>|null
*/
private function montzarJson(string $method, string $url, array $payload = []): ?array
{
$token = $this->getToken(); $token = $this->getToken();
try { try {
$httpResponse = $this->http(15)->withToken($token)->get($url); $http = $this->http(15)->withToken($token);
$httpResponse = strtoupper($method) === 'POST'
? $http->post($url, $payload)
: $http->get($url);
} catch (\Throwable $e) { } catch (\Throwable $e) {
Log::warning('Montzar order status request failed', [ Log::warning('Montzar order status request failed', [
'url' => $url, 'url' => $url,
@@ -670,7 +755,10 @@ class MontzarService
$body = $this->decodeMontzarHttpBody($httpResponse); $body = $this->decodeMontzarHttpBody($httpResponse);
if (is_array($body) && ($body['message'] ?? null) === 'no authorised') { if (is_array($body) && ($body['message'] ?? null) === 'no authorised') {
$token = $this->montzarLogin(); $token = $this->montzarLogin();
$httpResponse = $this->http(15)->withToken($token)->get($url); $http = $this->http(15)->withToken($token);
$httpResponse = strtoupper($method) === 'POST'
? $http->post($url, $payload)
: $http->get($url);
$body = $this->decodeMontzarHttpBody($httpResponse); $body = $this->decodeMontzarHttpBody($httpResponse);
} }