Files
compras/tests/Support/order-cancellation-worker.php
nala 63d20b10fc
tests / ci (push) Canceled after 0s
commit de armazens
2026-11-04 09:40:26 +02:00

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";
}