mirror of
https://github.com/snipe/snipe-it.git
synced 2026-08-18 11:15:42 +00:00
92 lines
3.1 KiB
PHP
92 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Accessories;
|
|
|
|
use App\Enums\ActionType;
|
|
use App\Models\Accessory;
|
|
use App\Models\Actionlog;
|
|
use App\Models\Location;
|
|
use App\Models\Order;
|
|
use App\Models\OrderItem;
|
|
use App\Models\Supplier;
|
|
use App\Models\User;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* AccessoryObserver::created writes an initial Order + OrderItem for
|
|
* every new accessory (mirrors AssetObserver's per-asset behavior).
|
|
* The paired `create` action_log entry links back to that OrderItem via
|
|
* order_item_id so history-tab renders can walk to the acquisition
|
|
* context in one hop.
|
|
*/
|
|
class AccessoryObserverOrderTest extends TestCase
|
|
{
|
|
public function test_accessory_create_writes_matching_order_and_order_item(): void
|
|
{
|
|
$actor = User::factory()->createAccessories()->create();
|
|
$supplier = Supplier::factory()->create();
|
|
|
|
$accessory = Accessory::factory()
|
|
->withInitialAcquisition($supplier, 12.34, '2026-04-01')
|
|
->create([
|
|
'created_by' => $actor->id,
|
|
'company_id' => $actor->company_id,
|
|
'qty' => 7,
|
|
]);
|
|
|
|
$line = OrderItem::where('item_type', Accessory::class)
|
|
->where('item_id', $accessory->id)
|
|
->firstOrFail();
|
|
|
|
$this->assertSame(7, (int) $line->qty);
|
|
$this->assertEquals(12.34, (float) $line->price);
|
|
$this->assertSame($actor->id, (int) $line->created_by);
|
|
|
|
$order = Order::findOrFail($line->order_id);
|
|
$this->assertSame($supplier->id, (int) $order->supplier_id);
|
|
$this->assertSame($actor->company_id, $order->company_id);
|
|
$this->assertSame('2026-04-01', $order->purchase_date->toDateString());
|
|
$this->assertSame($actor->id, (int) $order->created_by);
|
|
}
|
|
|
|
public function test_create_action_log_links_to_order_item_id(): void
|
|
{
|
|
$accessory = Accessory::factory()->create(['qty' => 3]);
|
|
|
|
$line = OrderItem::where('item_type', Accessory::class)
|
|
->where('item_id', $accessory->id)
|
|
->firstOrFail();
|
|
|
|
$log = Actionlog::where('item_type', Accessory::class)
|
|
->where('item_id', $accessory->id)
|
|
->where('action_type', ActionType::Create->value)
|
|
->firstOrFail();
|
|
|
|
$this->assertSame($line->id, (int) $log->order_item_id);
|
|
}
|
|
|
|
public function test_order_currency_prefers_location_currency_when_set(): void
|
|
{
|
|
$location = Location::factory()->create(['currency' => 'JPY']);
|
|
$accessory = Accessory::factory()->for($location)->create();
|
|
|
|
$line = $accessory->orderItems()->firstOrFail();
|
|
|
|
$this->assertSame('JPY', $line->order->currency);
|
|
}
|
|
|
|
public function test_every_new_accessory_gets_its_own_order_and_line(): void
|
|
{
|
|
$ordersBefore = Order::count();
|
|
$linesBefore = OrderItem::count();
|
|
|
|
Accessory::factory()->count(3)->create();
|
|
|
|
// Each create fires the observer, which writes 1 Order + 1
|
|
// OrderItem. No dedupe on accessory create (order_number is
|
|
// null so blank-order semantic applies).
|
|
$this->assertSame($ordersBefore + 3, Order::count());
|
|
$this->assertSame($linesBefore + 3, OrderItem::count());
|
|
}
|
|
}
|