actingAs($f['receiver']); app(ReceiptWorkflow::class)->confirm($f['receiver'], $f['order'], receiptPayload($f, '120.000')); app(RequisitionCatalogue::class)->save($f['receiver'], $f['stock']->id, ['version' => 0, 'stock_basis' => app(RequisitionCatalogue::class)->basis($f['stock']), 'category' => 'Material', 'purchase_type' => 'consumable', 'published' => true, 'reason' => 'Publicação do artigo para o ensaio sintético integrado.']); $this->actingAs($f['issuer']); $policy = app(SupplyPlanning::class)->save($f['issuer'], 'policy', supplyInput([...supplyPolicy($f), 'purpose' => 'internal', 'origin' => 'local'])); $this->actingAs($f['receiver']); $policy = app(SupplyPlanning::class)->save($f['receiver'], 'policy', supplyInput([], 'approve', $policy)); $this->actingAs($f['issuer']); $rule = app(AutomaticPurchases::class)->save($f['issuer'], ['operation_key' => (string) Str::uuid(), 'version' => 0, 'action' => 'save', 'reason' => 'Estimativa de dez MZN por unidade apenas para o ensaio descartável.', 'data' => ['policy_key' => $policy->record_key, 'requester_id' => $f['issuer']->id, 'cost_center_id' => $f['r']->cost_center_id, 'unit_price' => '10.00', 'tax_rate' => '0', 'needed_days' => 5, 'valid_until' => today()->addMonth()->toDateString()]]); $this->actingAs($f['receiver']); app(AutomaticPurchases::class)->save($f['receiver'], ['operation_key' => (string) Str::uuid(), 'record_key' => $rule->record_key, 'version' => 1, 'action' => 'approve', 'reason' => 'Conferência independente da parametrização sintética.', 'data' => []]); $this->actingAs($f['issuer']); $request = app(WarehouseRequests::class)->draft($f['issuer'], ['operation_key' => (string) Str::uuid(), 'warehouse_id' => $f['warehouse']->id, 'cost_center_id' => $f['r']->cost_center_id, 'destination' => 'Oficina sintética do piloto', 'reason' => 'Necessidade interna de material para manutenção no ensaio.', 'priority' => 'normal', 'lines' => [['stock_item_id' => $f['stock']->id, 'quantity' => '125.000', 'use' => 'internal']]]); $command = function ($actor, string $action, array $extra = []) use ($request) { $this->actingAs($actor); $version = app(WarehouseFulfilment::class)->progress($request)['version']; $this->postJson('/stock/requisicoes/'.$request->id.'/eventos', ['operation_key' => (string) Str::uuid(), 'version' => $version, 'action' => $action, 'reason' => 'Intervenção efectiva no percurso sintético do piloto.', ...$extra])->assertRedirect(); }; $command($f['issuer'], 'submit', ['partial_allowed' => true]); $command($f['receiver'], 'authorize', ['partial_allowed' => true]); app(AutomaticPurchases::class)->evaluate($f['receiver'], $f['stock']->id, $f['warehouse']->id); $need = app(SupplyPlanning::class)->latest('auto_need')->sole(); expect($need->data['purchases'])->toHaveCount(1); $purchase = Requisition::query()->findOrFail($need->data['purchases'][0]['id']); expect($purchase->status)->toBe('draft')->and($purchase->items()->sole()->quantity)->toBe('108.000')->and($purchase->steps()->count())->toBe(0); $this->actingAs($f['otherReceiver'])->get('/stock/requisicoes?view=delivery')->assertOk()->assertInertia(fn (Assert $p) => $p->where('records.total', 1)->where('records.data.0.health.needs_reservation', true)->where('records.data.0.health.delivery_ready', true)); $command($f['otherReceiver'], 'deliver', ['lines' => [['index' => 0, 'quantity' => '100.000']]]); $delivery = WarehouseRequestEvent::query()->where('warehouse_request_id', $request->id)->where('action', 'deliver')->sole(); $command($f['issuer'], 'receive', ['delivery_event_id' => $delivery->id]); expect(app(WarehouseFulfilment::class)->progress($request)['reserved'])->toBe([20000]); $this->actingAs($f['otherReceiver']); // Independent stock can arrive from an already issued order. It does not approve the automatic draft. app(ReceiptWorkflow::class)->confirm($f['otherReceiver'], $f['order'], receiptPayload($f, '108.000')); $command($f['receiver'], 'reserve'); expect(app(WarehouseFulfilment::class)->progress($request)['reserved'])->toBe([25000]); $command($f['otherReceiver'], 'deliver', ['lines' => [['index' => 0, 'quantity' => '25.000']]]); $last = WarehouseRequestEvent::query()->where('warehouse_request_id', $request->id)->where('action', 'deliver')->latest('id')->firstOrFail(); $command($f['issuer'], 'receive', ['delivery_event_id' => $last->id]); $p = app(WarehouseFulfilment::class)->progress($request); expect($p['state'])->toBe('closed')->and($p['reserved'])->toBe([0])->and($p['delivered'])->toBe([125000]) ->and(app(StockWorkflow::class)->balance($f['stock']->id, $f['warehouse']->id)['quantity'])->toBe(103000) ->and($purchase->fresh()->status)->toBe('draft')->and(DB::table('invoices')->count())->toBe(0)->and(DB::table('budget_entries')->count())->toBe(0) ->and(Requisition::query()->where('status', 'draft')->count())->toBe(1); $this->get('/stock/requisicoes?view=receipt')->assertOk()->assertInertia(fn (Assert $p) => $p->where('records.total',0)); });