Files
GSB-Construction/Modules/BiddingManagement/app/Models/BidAward.php

74 lines
2.2 KiB
PHP

<?php
namespace Modules\BiddingManagement\Models;
use App\Models\User;
use App\Traits\HasPublicIdentifier;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Modules\BiddingManagement\Enums\BidPackageStatus;
use Modules\BiddingManagement\Enums\BidSubmissionStatus;
class BidAward extends Model
{
use HasPublicIdentifier;
protected $fillable = [
'bid_package_id', 'bid_submission_id', 'awarded_by', 'awarded_at', 'notes',
];
protected function casts(): array
{
return [
'awarded_at' => 'datetime',
];
}
// --- Relationships ---
public function package(): BelongsTo
{
return $this->belongsTo(BidPackage::class, 'bid_package_id');
}
public function submission(): BelongsTo
{
return $this->belongsTo(BidSubmission::class, 'bid_submission_id');
}
public function awardedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'awarded_by');
}
// --- Observer logic (called from controller to keep it explicit) ---
public static function createAward(BidPackage $package, BidSubmission $winning, User $awarder, ?string $notes = null): self
{
// Mark package as awarded
$package->transitionTo(BidPackageStatus::Awarded);
// Mark winning submission as awarded
$winning->transitionTo(BidSubmissionStatus::Awarded);
// Reject all other non-rejected submissions
$package->submissions()
->whereNotIn('bid_submissions.id', [$winning->id])
->whereNotIn('bid_submissions.status', ['rejected'])
->get()
->each(fn ($sub) => $sub->update(['status' => BidSubmissionStatus::Rejected]));
// Link contractor to the project
$contractor = $winning->contractor;
$package->project()->update(['contractor_id' => $contractor->id]);
return self::create([
'bid_package_id' => $package->id,
'bid_submission_id' => $winning->id,
'awarded_by' => $awarder->id,
'awarded_at' => now(),
'notes' => $notes,
]);
}
}