74 lines
3.5 KiB
PHP
74 lines
3.5 KiB
PHP
<?php
|
|
|
|
use App\Models\OrderCancellation;
|
|
use App\Models\PurchaseOrder;
|
|
use App\Models\User;
|
|
use App\Services\ConflictGuard;
|
|
use App\Services\OrderCancellationWorkflow;
|
|
use App\Services\ReceiptWorkflow;
|
|
use Illuminate\Contracts\Console\Kernel;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
require dirname(__DIR__, 2).'/vendor/autoload.php';
|
|
$app = require dirname(__DIR__, 2).'/bootstrap/app.php';
|
|
$app->make(Kernel::class)->bootstrap();
|
|
if (! app()->environment('testing') || DB::getDriverName() !== 'pgsql' || ! preg_match('/^compras_receipts_test_[a-f0-9]{12}$/D', DB::connection()->getDatabaseName())) {
|
|
throw new LogicException('Disposable test database required.');
|
|
}
|
|
config(['order_cancellation.enabled' => true]);
|
|
require_once __DIR__.'/IssuedOrderCancellationFixture.php';
|
|
$mode = $argv[1];
|
|
if ($mode === 'seed') {
|
|
$fixture = new class extends stdClass
|
|
{
|
|
public function withoutVite(): void {}
|
|
|
|
public function actingAs(User $user): self
|
|
{
|
|
auth()->guard('web')->setUser($user);
|
|
|
|
return $this;
|
|
}
|
|
};
|
|
issuedOrderCancellationFixture($fixture);
|
|
echo json_encode(['order' => $fixture->f['order']->id, 'buyer' => $fixture->buyer->id, 'finance' => $fixture->finance->id, 'receiver' => $fixture->f['receiver']->id,
|
|
'warehouse' => $fixture->f['warehouse']->id, 'stock' => $fixture->f['stock']->id, 'line' => $fixture->f['line']->id, 'input' => $fixture->data], JSON_THROW_ON_ERROR);
|
|
exit;
|
|
}
|
|
$data = json_decode($argv[2], true, 32, JSON_THROW_ON_ERROR);
|
|
$action = $argv[3];
|
|
DB::select("select set_config('application_name', ?, false)", ['cancel-race-'.$mode]);
|
|
$actor = User::query()->findOrFail($data[$action === 'request' ? 'buyer' : ($action === 'receipt' ? 'receiver' : 'finance')]);
|
|
auth()->guard('web')->setUser($actor);
|
|
try {
|
|
DB::transaction(function () use ($data, $actor, $action, $mode) {
|
|
if ($mode === 'hold') {
|
|
app(ConflictGuard::class)->lockCompany($actor);
|
|
echo "LOCKED\n";
|
|
flush();
|
|
$deadline = microtime(true) + 20;
|
|
while (! is_file($data['barrier']) && microtime(true) < $deadline) {
|
|
usleep(20000);
|
|
}
|
|
if (! is_file($data['barrier'])) {
|
|
throw new RuntimeException('Barrier not released.');
|
|
}
|
|
}
|
|
$order = PurchaseOrder::query()->findOrFail($data['order']);
|
|
if ($action === 'request') {
|
|
app(OrderCancellationWorkflow::class)->request($actor, $order, $data['input']);
|
|
} elseif ($action === 'receipt') {
|
|
app(ReceiptWorkflow::class)->confirm($actor, $order, ['idempotency_key' => $data['input']['operation_key'], 'delivery_note' => 'RACE-GUIDE', 'received_on' => today()->toDateString(), 'warehouse_id' => $data['warehouse'],
|
|
'items' => [['purchase_order_item_id' => $data['line'], 'received_quantity' => '0.100', 'accepted_quantity' => '0.100', 'quality_status' => 'compliant', 'stock_item_id' => $data['stock'], 'notes' => null]]]);
|
|
} else {
|
|
$record = OrderCancellation::query()->where('purchase_order_id', $order->id)->where('status', 'pending')->first()
|
|
?? OrderCancellation::query()->where('purchase_order_id', $order->id)->where('status', 'approved')->firstOrFail();
|
|
app(OrderCancellationWorkflow::class)->decide($actor, $record, 'approved', 'Decisão financeira independente concorrente fictícia.');
|
|
}
|
|
});
|
|
echo "OK\n";
|
|
} catch (ValidationException $error) {
|
|
echo "BLOCKED\n";
|
|
}
|