fix scadule for getting price
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -53,11 +53,6 @@ class Kernel extends ConsoleKernel
|
||||
->everyMinute()
|
||||
->name('automations_run')
|
||||
->withoutOverlapping(50);
|
||||
|
||||
$schedule->command('colleague:poll-pending-orders')
|
||||
->everyMinute()
|
||||
->name('colleague_poll_pending_orders')
|
||||
->withoutOverlapping(58);
|
||||
}
|
||||
|
||||
protected function commands()
|
||||
|
||||
@@ -2054,20 +2054,27 @@ class SingleOrderController extends Controller
|
||||
|
||||
public function pendingColleague()
|
||||
{
|
||||
$order = app(ColleagueOrderCallbackService::class)
|
||||
->pendingForCustomer((int) auth('customer')->id());
|
||||
$service = app(ColleagueOrderCallbackService::class);
|
||||
$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)
|
||||
{
|
||||
$service = app(ColleagueOrderCallbackService::class);
|
||||
$order = Order::query()
|
||||
->where('id', $id)
|
||||
->where('customer_id', auth('customer')->id())
|
||||
->first();
|
||||
if ($order) {
|
||||
$order = $service->refreshIfDue($order);
|
||||
}
|
||||
|
||||
return response()->json(app(ColleagueOrderCallbackService::class)->publicStatusPayload($order));
|
||||
return response()->json($service->publicStatusPayload($order));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,42 +52,27 @@ class ColleagueOrderCallbackService
|
||||
return $this->applyProviderSts($order, $sts, $body);
|
||||
}
|
||||
|
||||
public function pollDueOrders(): int
|
||||
public function refreshIfDue(Order $order): Order
|
||||
{
|
||||
if (!Schema::hasTable('orders') || !Schema::hasColumn('orders', 'sts')) {
|
||||
return 0;
|
||||
if ((int) $order->sts !== 4) {
|
||||
return $order;
|
||||
}
|
||||
|
||||
$cutoff = now()->subSeconds(self::POLL_SECONDS);
|
||||
$handled = 0;
|
||||
|
||||
$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);
|
||||
if (!$this->isPollDue($order)) {
|
||||
return $order;
|
||||
}
|
||||
|
||||
$orders = $query->orderBy('id')->limit(80)->get();
|
||||
foreach ($orders as $order) {
|
||||
try {
|
||||
$this->pollOne($order);
|
||||
$handled++;
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Colleague pending poll failed', [
|
||||
'order_id' => $order->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$this->touchPollAt($order);
|
||||
}
|
||||
try {
|
||||
$this->pollOne($order);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Colleague pending poll failed', [
|
||||
'order_id' => $order->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$this->touchPollAt($order);
|
||||
}
|
||||
|
||||
return $handled;
|
||||
return Order::query()->find($order->id) ?? $order;
|
||||
}
|
||||
|
||||
public function pollOne(Order $order): array
|
||||
@@ -110,7 +95,17 @@ class ColleagueOrderCallbackService
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
public function providerStsFromBody(array $body): ?int
|
||||
{
|
||||
$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) {
|
||||
if (!is_array($item)) {
|
||||
continue;
|
||||
|
||||
@@ -638,7 +638,7 @@ class MontzarService
|
||||
}
|
||||
|
||||
/**
|
||||
* GET وضعیت سفارش روی نود همکار — مسیر از setting + شناسه سفارش همکار.
|
||||
* وضعیت سفارش روی نود همکار — اول GET مسیر+شناسه، اگر sts نبود POST جدول همان مسیر.
|
||||
*
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
@@ -652,12 +652,97 @@ class MontzarService
|
||||
if ($path === '') {
|
||||
$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();
|
||||
|
||||
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) {
|
||||
Log::warning('Montzar order status request failed', [
|
||||
'url' => $url,
|
||||
@@ -670,7 +755,10 @@ class MontzarService
|
||||
$body = $this->decodeMontzarHttpBody($httpResponse);
|
||||
if (is_array($body) && ($body['message'] ?? null) === 'no authorised') {
|
||||
$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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user