| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- <?php
- namespace Tests\Unit\Models;
- use App\Models\Reservation;
- use App\Models\SparePart;
- use App\Models\SparePartOrder;
- use App\Models\User;
- use Illuminate\Foundation\Testing\RefreshDatabase;
- use Tests\TestCase;
- class SparePartOrderTest extends TestCase
- {
- use RefreshDatabase;
- protected $seed = true;
- public function test_status_names_constant_exists(): void
- {
- $this->assertArrayHasKey(SparePartOrder::STATUS_ORDERED, SparePartOrder::STATUS_NAMES);
- $this->assertArrayHasKey(SparePartOrder::STATUS_IN_STOCK, SparePartOrder::STATUS_NAMES);
- $this->assertArrayHasKey(SparePartOrder::STATUS_SHIPPED, SparePartOrder::STATUS_NAMES);
- }
- public function test_status_name_attribute_returns_correct_name(): void
- {
- $order = SparePartOrder::factory()
- ->inStock()
- ->create();
- $this->assertEquals('На складе', $order->status_name);
- }
- public function test_available_qty_defaults_to_ordered_quantity_on_create(): void
- {
- $sparePart = SparePart::factory()->create();
- $user = User::factory()->create();
- $order = SparePartOrder::create([
- 'spare_part_id' => $sparePart->id,
- 'user_id' => $user->id,
- 'ordered_quantity' => 15,
- 'status' => SparePartOrder::STATUS_IN_STOCK,
- 'with_documents' => false,
- ]);
- $this->assertEquals(15, $order->available_qty);
- }
- public function test_year_defaults_to_current_year_on_create(): void
- {
- $sparePart = SparePart::factory()->create();
- $user = User::factory()->create();
- $order = SparePartOrder::create([
- 'spare_part_id' => $sparePart->id,
- 'user_id' => $user->id,
- 'ordered_quantity' => 10,
- 'status' => SparePartOrder::STATUS_IN_STOCK,
- 'with_documents' => false,
- ]);
- $this->assertEquals((int) date('Y'), $order->year);
- }
- public function test_reserved_qty_calculates_active_reservations(): void
- {
- $order = SparePartOrder::factory()
- ->inStock()
- ->withQuantity(20)
- ->create();
- Reservation::factory()
- ->active()
- ->withQuantity(5)
- ->fromOrder($order)
- ->create();
- Reservation::factory()
- ->active()
- ->withQuantity(3)
- ->fromOrder($order)
- ->create();
- // Cancelled should not count
- Reservation::factory()
- ->cancelled()
- ->withQuantity(10)
- ->fromOrder($order)
- ->create();
- $this->assertEquals(8, $order->reserved_qty);
- }
- public function test_free_qty_calculates_available_minus_reserved(): void
- {
- $order = SparePartOrder::factory()
- ->inStock()
- ->withQuantity(15)
- ->create();
- Reservation::factory()
- ->active()
- ->withQuantity(6)
- ->fromOrder($order)
- ->create();
- // available: 15, reserved: 6, free: 9
- $this->assertEquals(9, $order->free_qty);
- }
- public function test_free_qty_never_goes_negative(): void
- {
- $order = SparePartOrder::factory()
- ->inStock()
- ->withQuantity(5)
- ->create();
- // Create reservation larger than available (edge case)
- Reservation::factory()
- ->active()
- ->withQuantity(10)
- ->fromOrder($order)
- ->create();
- $this->assertEquals(0, $order->free_qty);
- }
- public function test_can_reserve_returns_true_when_sufficient_qty(): void
- {
- $order = SparePartOrder::factory()
- ->inStock()
- ->withQuantity(10)
- ->create();
- $this->assertTrue($order->canReserve(5));
- $this->assertTrue($order->canReserve(10));
- }
- public function test_can_reserve_returns_false_when_insufficient_qty(): void
- {
- $order = SparePartOrder::factory()
- ->inStock()
- ->withQuantity(10)
- ->create();
- Reservation::factory()
- ->active()
- ->withQuantity(8)
- ->fromOrder($order)
- ->create();
- // Only 2 free, trying to reserve 5
- $this->assertFalse($order->canReserve(5));
- }
- public function test_is_in_stock_method(): void
- {
- $orderInStock = SparePartOrder::factory()->inStock()->create();
- $orderOrdered = SparePartOrder::factory()->ordered()->create();
- $this->assertTrue($orderInStock->isInStock());
- $this->assertFalse($orderOrdered->isInStock());
- }
- public function test_is_ordered_method(): void
- {
- $orderOrdered = SparePartOrder::factory()->ordered()->create();
- $orderInStock = SparePartOrder::factory()->inStock()->create();
- $this->assertTrue($orderOrdered->isOrdered());
- $this->assertFalse($orderInStock->isOrdered());
- }
- public function test_is_shipped_method(): void
- {
- $orderShipped = SparePartOrder::factory()->shipped()->create();
- $orderInStock = SparePartOrder::factory()->inStock()->create();
- $this->assertTrue($orderShipped->isShipped());
- $this->assertFalse($orderInStock->isShipped());
- }
- public function test_scope_in_stock(): void
- {
- SparePartOrder::factory()->inStock()->create();
- SparePartOrder::factory()->inStock()->create();
- SparePartOrder::factory()->ordered()->create();
- SparePartOrder::factory()->shipped()->create();
- $inStockOrders = SparePartOrder::inStock()->get();
- $this->assertCount(2, $inStockOrders);
- }
- public function test_scope_with_available(): void
- {
- SparePartOrder::factory()->inStock()->withQuantity(10)->create();
- SparePartOrder::factory()->shipped()->create(); // available_qty = 0
- $withAvailable = SparePartOrder::withAvailable()->get();
- $this->assertCount(1, $withAvailable);
- }
- public function test_scope_with_documents(): void
- {
- SparePartOrder::factory()->withDocuments(true)->create();
- SparePartOrder::factory()->withDocuments(true)->create();
- SparePartOrder::factory()->withDocuments(false)->create();
- $withDocs = SparePartOrder::withDocuments(true)->get();
- $withoutDocs = SparePartOrder::withDocuments(false)->get();
- $this->assertCount(2, $withDocs);
- $this->assertCount(1, $withoutDocs);
- }
- public function test_scope_for_spare_part(): void
- {
- $sparePart1 = SparePart::factory()->create();
- $sparePart2 = SparePart::factory()->create();
- SparePartOrder::factory()->forSparePart($sparePart1)->create();
- SparePartOrder::factory()->forSparePart($sparePart1)->create();
- SparePartOrder::factory()->forSparePart($sparePart2)->create();
- $ordersForPart1 = SparePartOrder::forSparePart($sparePart1->id)->get();
- $this->assertCount(2, $ordersForPart1);
- }
- public function test_scope_available_for_reservation(): void
- {
- $sparePart = SparePart::factory()->create();
- $availableOrder = SparePartOrder::factory()
- ->inStock()
- ->withDocuments(false)
- ->withQuantity(10)
- ->forSparePart($sparePart)
- ->create(['created_at' => now()->subDay()]);
- // Not matching conditions
- SparePartOrder::factory()
- ->ordered() // wrong status
- ->withDocuments(false)
- ->forSparePart($sparePart)
- ->create();
- SparePartOrder::factory()
- ->inStock()
- ->withDocuments(true) // wrong docs type
- ->forSparePart($sparePart)
- ->create();
- SparePartOrder::factory()
- ->shipped() // no available qty
- ->withDocuments(false)
- ->forSparePart($sparePart)
- ->create();
- $available = SparePartOrder::availableForReservation($sparePart->id, false)->get();
- $this->assertCount(1, $available);
- $this->assertEquals($availableOrder->id, $available->first()->id);
- }
- public function test_casts_are_correct(): void
- {
- $order = SparePartOrder::factory()
- ->withDocuments(true)
- ->withQuantity(10)
- ->create();
- $order->refresh();
- $this->assertIsBool($order->with_documents);
- $this->assertIsInt($order->ordered_quantity);
- $this->assertIsInt($order->available_qty);
- $this->assertIsInt($order->year);
- }
- public function test_remaining_quantity_backward_compatibility(): void
- {
- $order = SparePartOrder::factory()
- ->withQuantity(15)
- ->create();
- // Deprecated attribute should still work
- $this->assertEquals($order->available_qty, $order->remaining_quantity);
- }
- public function test_relations_exist(): void
- {
- $order = SparePartOrder::factory()->create();
- $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\BelongsTo::class, $order->sparePart());
- $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\BelongsTo::class, $order->user());
- $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\HasMany::class, $order->reservations());
- $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\HasMany::class, $order->movements());
- }
- }
|