3
0
mirror of https://github.com/snipe/snipe-it.git synced 2026-08-18 11:15:42 +00:00
Files
snipe-it/database/factories/CheckoutAcceptanceFactory.php
2026-07-25 13:49:18 +01:00

122 lines
3.6 KiB
PHP

<?php
namespace Database\Factories;
use App\Models\Accessory;
use App\Models\Asset;
use App\Models\CheckoutAcceptance;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class CheckoutAcceptanceFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'checkoutable_type' => Asset::class,
'checkoutable_id' => Asset::factory(),
'assigned_to_id' => User::factory(),
];
}
protected static bool $skipActionLog = false;
public function withoutActionLog(): static
{
// turn off for this create() call
static::$skipActionLog = true;
// ensure it turns back on AFTER creating
return $this->afterCreating(function () {
static::$skipActionLog = false;
});
}
public function configure(): static
{
return $this->afterCreating(function (CheckoutAcceptance $acceptance) {
if (static::$skipActionLog) {
return; // short-circuit
}
if ($acceptance->checkoutable instanceof Asset) {
$this->createdAssociatedActionLogEntry($acceptance);
}
if ($acceptance->checkoutable instanceof Asset && $acceptance->assignedTo instanceof User) {
$asset = $acceptance->checkoutable;
$asset->assigned_to = $acceptance->assigned_to_id;
$asset->assigned_type = get_class($acceptance->assignedTo);
$asset->save();
}
});
}
public function forAccessory()
{
return $this->state([
'checkoutable_type' => Accessory::class,
'checkoutable_id' => Accessory::factory(),
]);
}
public function pending()
{
return $this->state([
'accepted_at' => null,
'declined_at' => null,
]);
}
public function accepted()
{
return $this->state([
'accepted_at' => now()->subDay(),
'declined_at' => null,
]);
}
public function withoutAlerting()
{
return $this->state(function () {
return [
'alert_on_response_id' => null,
];
});
}
public function withAlertingTo(User $user)
{
return $this->state(function () use ($user) {
return [
'alert_on_response_id' => $user->id,
];
});
}
private function createdAssociatedActionLogEntry(CheckoutAcceptance $acceptance): void
{
// Match the log entry's created_at to the acceptance's created_at
// explicitly. ReportsController::sentAssetAcceptanceReminder
// joins the two on WHERE created_at = ?, and TIMESTAMP columns
// store second precision — so if the acceptance's default
// timestamp and this insert's default timestamp straddle a second
// boundary (under full-suite load, often enough to matter), the
// join returns nothing and the reminder path bails with an error.
// Passing the acceptance's created_at through makes the pair
// deterministically identical.
$acceptance->checkoutable->assetlog()->create([
'action_type' => 'checkout',
'target_id' => $acceptance->assigned_to_id,
'target_type' => User::class,
'item_id' => $acceptance->checkoutable_id,
'item_type' => $acceptance->checkoutable_type,
'created_at' => $acceptance->created_at,
]);
}
}