'date', 'lettura_precedente' => 'decimal:3', 'lettura_attuale' => 'decimal:3', 'dati_telelettura' => 'array', 'validata' => 'boolean' ]; /** * Relazione con Contatore */ public function contatore() { return $this->belongsTo(Contatore::class, 'contatore_id', 'id'); } /** * Relazione con User creatore */ public function createdBy() { return $this->belongsTo(User::class, 'created_by', 'id'); } /** * Accessor per consumo calcolato */ public function getConsumoCalcolatoAttribute(): float { return $this->lettura_attuale - $this->lettura_precedente; } /** * Scope per letture validate */ public function scopeValidate($query) { return $query->where('validata', true); } /** * Scope per periodo */ public function scopePerPeriodo($query, $dataInizio, $dataFine) { return $query->whereBetween('data_lettura', [$dataInizio, $dataFine]); } /** * Scope per tipo lettura */ public function scopePerTipo($query, $tipo) { return $query->where('tipo_lettura', $tipo); } /** * Verifica se la lettura è anomala */ public function isAnomala(): bool { // Implementa logica per rilevare letture anomale $consumo = $this->consumo_calcolato; // Consumo negativo è sempre anomalo if ($consumo < 0) { return true; } // Consumo eccessivo potrebbe essere anomalo // TODO: implementare soglie dinamiche per tipo contatore if ($consumo > 1000) { return true; } return false; } /** * Ottieni lettura precedente dal database */ public function calcolaLetturaPrecedente(): float { $precedente = self::where('contatore_id', $this->contatore_id) ->where('data_lettura', '<', $this->data_lettura) ->orderBy('data_lettura', 'desc') ->first(); return $precedente ? $precedente->lettura_attuale : $this->contatore->lettura_iniziale; } /** * Aggiorna automaticamente lettura precedente */ protected static function boot() { parent::boot(); static::creating(function ($lettura) { if (is_null($lettura->lettura_precedente)) { $lettura->lettura_precedente = $lettura->calcolaLetturaPrecedente(); } }); } }