MIF_E31221361/app/Models/RawMaterial.php

155 lines
4.1 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Helpers\UnitConverter;
class RawMaterial extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = [
'name',
'price',
'stock',
'minimum_stock',
'unit',
'description'
];
protected $casts = [
'stock' => 'decimal:3',
'price' => 'decimal:2',
'minimum_stock' => 'decimal:3',
];
// Available units
const AVAILABLE_UNITS = ['g', 'kg', 'ml', 'l', 'pcs'];
public function logs()
{
return $this->hasMany(RawMaterialLog::class);
}
public function recipes()
{
return $this->hasMany(ProductRecipe::class);
}
public function isLowStock()
{
return $this->stock <= $this->minimum_stock;
}
/**
* Get stock in different unit
*/
public function getStockInUnit($targetUnit)
{
try {
return UnitConverter::convert($this->stock, $this->unit, $targetUnit);
} catch (\InvalidArgumentException $e) {
return null; // Units not compatible
}
}
/**
* Check if stock is sufficient for required amount in any unit
*/
public function hasSufficientStock($requiredAmount, $requiredUnit)
{
try {
$requiredInCurrentUnit = UnitConverter::convert($requiredAmount, $requiredUnit, $this->unit);
return $this->stock >= $requiredInCurrentUnit;
} catch (\InvalidArgumentException $e) {
return false; // Units not compatible
}
}
/**
* Reduce stock by amount in specified unit
*/
public function reduceStock($amount, $unit, $notes = null)
{
try {
$amountInCurrentUnit = UnitConverter::convert($amount, $unit, $this->unit);
if ($this->stock < $amountInCurrentUnit) {
throw new \Exception("Insufficient stock. Available: {$this->stock} {$this->unit}, Required: {$amountInCurrentUnit} {$this->unit}");
}
$this->stock -= $amountInCurrentUnit;
$this->save();
// Log the reduction
RawMaterialLog::create([
'raw_material_id' => $this->id,
'user_id' => auth()->id(),
'type' => 'production',
'quantity' => -$amountInCurrentUnit,
'notes' => $notes ?? "Stock reduced for production: {$amount} {$unit}"
]);
return true;
} catch (\InvalidArgumentException $e) {
throw new \Exception("Cannot convert units: " . $e->getMessage());
}
}
/**
* Add stock by amount in specified unit
*/
public function addStock($amount, $unit, $price = null, $notes = null)
{
try {
$amountInCurrentUnit = UnitConverter::convert($amount, $unit, $this->unit);
$this->stock += $amountInCurrentUnit;
$this->save();
// Log the addition
RawMaterialLog::create([
'raw_material_id' => $this->id,
'user_id' => auth()->id(),
'type' => 'in',
'quantity' => $amountInCurrentUnit,
'price' => $price,
'subtotal' => $price ? $price * $amount : 0,
'notes' => $notes ?? "Stock added: {$amount} {$unit}"
]);
return true;
} catch (\InvalidArgumentException $e) {
throw new \Exception("Cannot convert units: " . $e->getMessage());
}
}
/**
* Get formatted stock with unit
*/
public function getFormattedStock()
{
return UnitConverter::formatValue($this->stock, $this->unit);
}
/**
* Get unit category
*/
public function getUnitCategory()
{
return UnitConverter::getUnitCategory($this->unit);
}
/**
* Get compatible units for this material
*/
public function getCompatibleUnits()
{
$category = $this->getUnitCategory();
return UnitConverter::getUnitsByCategory($category);
}
}