first commit
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\service\pharmacy;
|
||||
|
||||
use Closure;
|
||||
use DomainException;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
final class EjPharmacyCallbackWorkflow
|
||||
{
|
||||
private Closure $loadInbox;
|
||||
private Closure $createInbox;
|
||||
private Closure $reloadInbox;
|
||||
private Closure $process;
|
||||
private Closure $markFailed;
|
||||
private Closure $isDuplicateKey;
|
||||
|
||||
public function __construct(
|
||||
callable $loadInbox,
|
||||
callable $createInbox,
|
||||
callable $reloadInbox,
|
||||
callable $process,
|
||||
callable $markFailed,
|
||||
callable $isDuplicateKey
|
||||
) {
|
||||
$this->loadInbox = Closure::fromCallable($loadInbox);
|
||||
$this->createInbox = Closure::fromCallable($createInbox);
|
||||
$this->reloadInbox = Closure::fromCallable($reloadInbox);
|
||||
$this->process = Closure::fromCallable($process);
|
||||
$this->markFailed = Closure::fromCallable($markFailed);
|
||||
$this->isDuplicateKey = Closure::fromCallable($isDuplicateKey);
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $payload @return array<string,mixed> */
|
||||
public function handle(array $payload): array
|
||||
{
|
||||
$eventId = trim((string) ($payload['event_id'] ?? ''));
|
||||
if ($eventId === '') {
|
||||
return ['http_status' => 422, 'message' => 'event_id is required', 'duplicate' => false];
|
||||
}
|
||||
|
||||
$inbox = ($this->loadInbox)($eventId);
|
||||
if (is_array($inbox) && strtoupper((string) ($inbox['process_status'] ?? '')) === 'PROCESSED') {
|
||||
return ['http_status' => 200, 'message' => 'ok', 'duplicate' => true];
|
||||
}
|
||||
|
||||
if (!is_array($inbox)) {
|
||||
try {
|
||||
$inbox = ($this->createInbox)($payload);
|
||||
} catch (Throwable $exception) {
|
||||
if (!(bool) ($this->isDuplicateKey)($exception)) {
|
||||
return ['http_status' => 500, 'message' => $exception->getMessage(), 'duplicate' => false];
|
||||
}
|
||||
$inbox = ($this->reloadInbox)($eventId);
|
||||
if (!is_array($inbox)) {
|
||||
return ['http_status' => 500, 'message' => 'callback inbox race could not be reloaded', 'duplicate' => false];
|
||||
}
|
||||
if (strtoupper((string) ($inbox['process_status'] ?? '')) === 'PROCESSED') {
|
||||
return ['http_status' => 200, 'message' => 'ok', 'duplicate' => true];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
($this->process)($inbox, $payload);
|
||||
return ['http_status' => 200, 'message' => 'ok', 'duplicate' => false];
|
||||
} catch (EjPharmacyCallbackRetryException $exception) {
|
||||
($this->markFailed)($inbox, $exception->getMessage());
|
||||
return ['http_status' => 503, 'message' => $exception->getMessage(), 'duplicate' => false];
|
||||
} catch (InvalidArgumentException|DomainException $exception) {
|
||||
($this->markFailed)($inbox, $exception->getMessage());
|
||||
return ['http_status' => 422, 'message' => $exception->getMessage(), 'duplicate' => false];
|
||||
} catch (Throwable $exception) {
|
||||
($this->markFailed)($inbox, $exception->getMessage());
|
||||
return ['http_status' => 500, 'message' => $exception->getMessage(), 'duplicate' => false];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user