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()
|
->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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user