99 lines
4.2 KiB
PHP
99 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Employee;
|
|
use App\Models\StockVariant;
|
|
use App\Models\UniformItem;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class UniformWorkflowTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->actingAs(User::factory()->create(['is_admin' => true]));
|
|
}
|
|
|
|
private function employee(): Employee
|
|
{
|
|
return Employee::create(['employee_no' => 'E-100', 'name' => 'Test Employee', 'department' => 'Operations']);
|
|
}
|
|
|
|
private function variant(int $quantity = 5): StockVariant
|
|
{
|
|
$item = UniformItem::create(['code' => 'TS-01', 'name' => 'Test Shirt']);
|
|
|
|
return $item->variants()->create(['size' => 'M', 'quantity' => $quantity, 'reorder_level' => 2]);
|
|
}
|
|
|
|
public function test_restock_increases_the_correct_size_balance(): void
|
|
{
|
|
$variant = $this->variant(3);
|
|
$this->post(route('inventory.restock'), ['uniform_item_id' => $variant->uniform_item_id, 'stocks' => [$variant->id => 4]])->assertSessionHasNoErrors();
|
|
$this->assertSame(7, $variant->fresh()->quantity);
|
|
$this->assertDatabaseHas('stock_movements', ['stock_variant_id' => $variant->id, 'type' => 'restock', 'quantity_change' => 4]);
|
|
}
|
|
|
|
public function test_uniform_type_is_created_with_selected_sizes(): void
|
|
{
|
|
$this->post(route('inventory.items.store'), [
|
|
'code' => 'JKT-01',
|
|
'name' => 'Work Jacket',
|
|
'sizes' => ['S', 'M', 'XL'],
|
|
'reorder_level' => 3,
|
|
])->assertSessionHasNoErrors();
|
|
|
|
$item = UniformItem::where('code', 'JKT-01')->firstOrFail();
|
|
$this->assertEqualsCanonicalizing(['S', 'M', 'XL'], $item->variants()->pluck('size')->all());
|
|
}
|
|
|
|
public function test_issuing_a_uniform_reduces_stock(): void
|
|
{
|
|
$employee = $this->employee();
|
|
$variant = $this->variant(5);
|
|
$this->post(route('issues.store'), ['employee_id' => $employee->id, 'stock_variant_id' => $variant->id, 'quantity' => 2, 'issued_at' => '2026-07-13'])->assertSessionHasNoErrors();
|
|
$this->assertSame(3, $variant->fresh()->quantity);
|
|
$this->assertDatabaseHas('uniform_issues', ['employee_id' => $employee->id, 'stock_variant_id' => $variant->id, 'quantity' => 2, 'status' => 'issued']);
|
|
}
|
|
|
|
public function test_issue_is_rejected_when_stock_is_insufficient(): void
|
|
{
|
|
$employee = $this->employee();
|
|
$variant = $this->variant(1);
|
|
$this->post(route('issues.store'), ['employee_id' => $employee->id, 'stock_variant_id' => $variant->id, 'quantity' => 2, 'issued_at' => '2026-07-13'])->assertSessionHasErrors('quantity');
|
|
$this->assertSame(1, $variant->fresh()->quantity);
|
|
}
|
|
|
|
public function test_exit_handover_returns_only_reusable_uniforms_to_stock(): void
|
|
{
|
|
$employee = $this->employee();
|
|
$variant = $this->variant(5);
|
|
$this->post(route('issues.store'), ['employee_id' => $employee->id, 'stock_variant_id' => $variant->id, 'quantity' => 2, 'issued_at' => '2026-07-13']);
|
|
$issue = $employee->issues()->first();
|
|
|
|
$this->post(route('handovers.store', $employee), ['handover_date' => '2026-07-14', 'items' => [['issue_id' => $issue->id, 'condition' => 'reusable']]])->assertSessionHasNoErrors();
|
|
|
|
$this->assertSame(5, $variant->fresh()->quantity);
|
|
$this->assertSame('left', $employee->fresh()->status);
|
|
$this->assertDatabaseHas('uniform_issues', ['id' => $issue->id, 'status' => 'returned', 'returned_quantity' => 2]);
|
|
}
|
|
|
|
public function test_damaged_handover_items_do_not_return_to_available_stock(): void
|
|
{
|
|
$employee = $this->employee();
|
|
$variant = $this->variant(5);
|
|
$this->post(route('issues.store'), ['employee_id' => $employee->id, 'stock_variant_id' => $variant->id, 'quantity' => 1, 'issued_at' => '2026-07-13']);
|
|
$issue = $employee->issues()->first();
|
|
|
|
$this->post(route('handovers.store', $employee), ['handover_date' => '2026-07-14', 'items' => [['issue_id' => $issue->id, 'condition' => 'damaged']]])->assertSessionHasNoErrors();
|
|
|
|
$this->assertSame(4, $variant->fresh()->quantity);
|
|
$this->assertSame('left', $employee->fresh()->status);
|
|
}
|
|
}
|