Projects/3BIT/winter-semester/IIS/xnecasr00/app/Models/Harvest.php
2026-04-14 19:28:46 +02:00

158 lines
4 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Harvest extends Model
{
use HasFactory;
protected $table = 'harvests';
protected $fillable = [
'vineyard_row_id',
'weight',
'variety_variation_id',
'sugar_content',
'date',
'user_id',
'quality',
'grape_condition',
'notes',
'weather_conditions',
'harvest_time',
];
protected $casts = [
'date' => 'date',
'weight' => 'decimal:2',
'sugar_content' => 'decimal:2',
];
/**
* Get the vineyard row for this harvest.
*/
public function vineyardRow(): BelongsTo
{
return $this->belongsTo(VineyardRow::class, 'vineyard_row_id');
}
/**
* Get the planned task associated with this treatment.
*/
public function plannedTask(): MorphOne
{
return $this->morphOne(PlannedTask::class, 'taskable');
}
/**
* Get the variety variation for this harvest.
*/
public function varietyVariation(): BelongsTo
{
return $this->belongsTo(VarietyVariation::class, 'variety_variation_id');
}
/**
* Get the user who performed this harvest.
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
/**
* Get the wine production records for this harvest.
*/
public function wineProductions(): HasMany
{
return $this->hasMany(WineProduction::class, 'harvest_id');
}
/**
* Get the wines produced from this harvest (many-to-many through wine_productions).
*/
public function wines(): BelongsToMany
{
return $this->belongsToMany(Wine::class, 'wine_productions', 'harvest_id', 'wine_id')
->withPivot('consumed_weight', 'blend_percentage')
->withTimestamps();
}
/**
* Get the total consumed weight from all wine productions.
*/
public function getConsumedWeightAttribute(): float
{
return $this->wineProductions()->sum('consumed_weight') ?? 0;
}
/**
* Get the remaining available weight.
*/
public function getRemainingWeightAttribute(): float
{
return max(0, $this->weight - $this->consumed_weight);
}
/**
* Get the usage percentage.
*/
public function getUsagePercentageAttribute(): float
{
if ($this->weight <= 0) {
return 0;
}
return min(100, ($this->consumed_weight / $this->weight) * 100);
}
/**
* Check if harvest is fully used.
*/
public function isFullyUsed(): bool
{
return $this->remaining_weight <= 0.01; // Allow small floating point difference
}
/**
* Check if harvest is partially used.
*/
public function isPartiallyUsed(): bool
{
return $this->consumed_weight > 0 && !$this->isFullyUsed();
}
/**
* Check if harvest is available (not used at all).
*/
public function isAvailable(): bool
{
return $this->consumed_weight < 0.01; // Allow small floating point difference
}
/**
* Check if there are any wines still in the cellar that were made from this harvest.
* Returns true if any connected wine has bottles in stock.
*/
public function hasWinesInCellar(): bool
{
return $this->wines()->where('bottles_in_stock', '>', 0)->exists();
}
/**
* Check if harvest can be safely deleted.
* A harvest can only be deleted when:
* 1. It has been fully used in wine production
* 2. All wines made from it have been sold out (no bottles in cellar)
*/
public function canBeDeleted(): bool
{
return $this->isFullyUsed() && !$this->hasWinesInCellar();
}
}