135 lines
4.2 KiB
PHP
135 lines
4.2 KiB
PHP
<?php
|
|
|
|
use App\Enums\StockOpnameStatus;
|
|
use App\Livewire\Studio\Manage\StockOpname\Index;
|
|
use App\Livewire\Studio\Manage\StockOpname\Manage;
|
|
use App\Models\Perfume;
|
|
use App\Models\StockOpname;
|
|
use App\Models\StockOpnameItem;
|
|
use Livewire\Livewire;
|
|
use Spatie\Permission\Models\Permission;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
beforeEach(function () {
|
|
$this->setupUser();
|
|
$this->outlet = $this->user->outlets->first();
|
|
|
|
// Create permissions
|
|
$permissions = [
|
|
'view stock opname',
|
|
'create stock opname',
|
|
'manage stock opname',
|
|
'show stock opname',
|
|
'delete stock opname',
|
|
];
|
|
|
|
foreach ($permissions as $permission) {
|
|
Permission::firstOrCreate(['name' => $permission]);
|
|
}
|
|
|
|
$role = Role::create(['name' => 'Owner']);
|
|
$role->givePermissionTo($permissions);
|
|
$this->user->assignRole($role);
|
|
});
|
|
|
|
it('renders the stock opname index page', function () {
|
|
Livewire::actingAs($this->user)
|
|
->test(Index::class)
|
|
->assertStatus(200);
|
|
});
|
|
|
|
it('can update physical quantity in manage page', function () {
|
|
// Create pre-existing StockOpname
|
|
$stockOpname = StockOpname::create([
|
|
'outlet_id' => $this->outlet->id,
|
|
'period_month' => now()->format('Y-m'),
|
|
'status' => StockOpnameStatus::PROCESS,
|
|
]);
|
|
|
|
$perfume = Perfume::factory()->create();
|
|
$item = StockOpnameItem::create([
|
|
'stock_opname_id' => $stockOpname->id,
|
|
'user_id' => $this->user->id,
|
|
'itemable_type' => Perfume::class,
|
|
'itemable_id' => $perfume->id,
|
|
'qty_system' => 10,
|
|
]);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Manage::class, ['stockOpname' => $stockOpname])
|
|
->set('form.outlet_stock.'.$item->id, 8) // Physical count is 8
|
|
->assertSet('form.outlet_stock.'.$item->id, 8);
|
|
|
|
// Manage component updates via updated hook, or explicitly called?
|
|
// Manage.php: updated(...) calls form->update().
|
|
|
|
$this->assertDatabaseHas('stock_opname_items', [
|
|
'id' => $item->id,
|
|
'qty_physical' => 8,
|
|
]);
|
|
});
|
|
|
|
it('can request approval for stock opname', function () {
|
|
$stockOpname = StockOpname::create([
|
|
'outlet_id' => $this->outlet->id,
|
|
'period_month' => now()->format('Y-m'),
|
|
'status' => StockOpnameStatus::PROCESS,
|
|
'note' => 'Ready for approval',
|
|
]);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Index::class)
|
|
->call('requestApproval', $stockOpname->id); // Passing ID or Model? Method signature says Model. Livewire handles ID binding.
|
|
|
|
$this->assertDatabaseHas('stock_opname', [
|
|
'id' => $stockOpname->id,
|
|
'status' => StockOpnameStatus::PENDING_APPROVAL->value,
|
|
]);
|
|
});
|
|
|
|
it('can approve stock opname and update outlet stock', function () {
|
|
$stockOpname = StockOpname::create([
|
|
'outlet_id' => $this->outlet->id,
|
|
'period_month' => now()->format('Y-m'),
|
|
'status' => StockOpnameStatus::PENDING_APPROVAL,
|
|
]);
|
|
|
|
$perfume = Perfume::factory()->create();
|
|
// Verify initial stock of perfume in outlet (empty or 0)
|
|
// Attach to outlet first to mimic existing stock
|
|
$this->outlet->perfumes()->attach($perfume->id, ['stock' => 10]);
|
|
|
|
$item = StockOpnameItem::create([
|
|
'stock_opname_id' => $stockOpname->id,
|
|
'user_id' => $this->user->id,
|
|
'itemable_type' => Perfume::class,
|
|
'itemable_id' => $perfume->id,
|
|
'qty_system' => 10,
|
|
'qty_physical' => 8, // Found 8, so stock should become 8 (loss of 2)
|
|
]);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Index::class)
|
|
->call('approveApproval', $stockOpname->id);
|
|
|
|
$this->assertDatabaseHas('stock_opname', [
|
|
'id' => $stockOpname->id,
|
|
'status' => StockOpnameStatus::COMPLETED->value,
|
|
]);
|
|
|
|
// Verify outlet stock updated
|
|
$this->assertEquals(8, $this->outlet->perfumes()->find($perfume->id)->pivot->stock);
|
|
});
|
|
|
|
it('cannot manage stock opname if not in process status', function () {
|
|
$stockOpname = StockOpname::create([
|
|
'outlet_id' => $this->outlet->id,
|
|
'period_month' => now()->format('Y-m'),
|
|
'status' => StockOpnameStatus::COMPLETED,
|
|
]);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Manage::class, ['stockOpname' => $stockOpname])
|
|
->assertForbidden();
|
|
});
|