- Created a database migration to add `team_id` to `collection_logs`. - Created a database migration to backfill `team_id` for past scans using `trip_id` and scanner's active team. - Updated `ScanService` to lookup the scanner's active team and store the `team_id` directly on the `CollectionLog`. - Modified the `CollectionTeam` model's `collectionLogs()` relation to be a direct `HasMany` using the new `team_id` instead of routing through `Trip`. - Updated `AdminTeamReportController` to query metrics directly from `collection_logs.team_id`, ensuring all past and future scans (including those done without an active trip) correctly increment team stats and daily charts.
71 lines
1.7 KiB
PHP
71 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Tenancy\HasTenant;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use MatanYadaev\EloquentSpatial\Objects\Point;
|
|
use MatanYadaev\EloquentSpatial\Traits\HasSpatial;
|
|
|
|
class CollectionLog extends Model
|
|
{
|
|
use HasFactory, HasSpatial, HasTenant;
|
|
|
|
public const STATUS_VALID = 'valid';
|
|
|
|
public const STATUS_INVALID = 'invalid';
|
|
|
|
public const STATUS_DUPLICATE = 'duplicate';
|
|
|
|
public const STATUS_EXPIRED = 'expired';
|
|
|
|
protected $fillable = [
|
|
'tenant_id', 'qr_code_id', 'team_id', 'household_id', 'drop_off_point_id',
|
|
'scanned_by_user_id', 'trip_id', 'trip_stop_id',
|
|
'scanned_at', 'coordinates_at_scan',
|
|
'weight_kg', 'waste_type', 'photo_path', 'notes',
|
|
'verification_status',
|
|
];
|
|
|
|
protected function casts(): array
|
|
{
|
|
return [
|
|
'scanned_at' => 'datetime',
|
|
'coordinates_at_scan' => Point::class,
|
|
'weight_kg' => 'integer',
|
|
];
|
|
}
|
|
|
|
public function qrCode(): BelongsTo
|
|
{
|
|
return $this->belongsTo(QrCode::class);
|
|
}
|
|
|
|
public function household(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Household::class);
|
|
}
|
|
|
|
public function dropOffPoint(): BelongsTo
|
|
{
|
|
return $this->belongsTo(DropOffPoint::class);
|
|
}
|
|
|
|
public function scannedBy(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'scanned_by_user_id');
|
|
}
|
|
|
|
public function trip(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Trip::class);
|
|
}
|
|
|
|
public function team(): BelongsTo
|
|
{
|
|
return $this->belongsTo(CollectionTeam::class, 'team_id');
|
|
}
|
|
}
|