CollectionOrNull::class, 'start_at' => 'datetime:Y-m-d', 'stop_at' => 'datetime:Y-m-d', 'charge_at' => 'datetime:Y-m-d', // The date the charge applies - since it can be different to created_at ]; public const sweep = [ // 0 => 'Daily', // 1 => 'Weekly', // 2 => 'Monthly', // 3 => 'Quarterly', // 4 => 'Semi-Annually', // 5 => 'Annually', 6 => 'Service Rebill', ]; /* RELATIONS */ public function account() { return $this->belongsTo(Account::class); } public function product() { return $this->belongsTo(Product::class); } public function service() { return $this->belongsTo(Service::class); } /* SCOPES */ /** @deprecated use pending */ public function scopeUnprocessed($query) { Log::alert('UMO:! Deprecated function scopeUnprocessed()'); return $this->scopePending(); } public function scopePending($query) { return $query ->active() ->whereNotNull('charge_at') ->whereNotNull('type') ->where(fn($query)=>$query->where('processed',FALSE)->orWhereNull('processed')); } /* ATTRIBUTES */ public function getNameAttribute() { return sprintf('%s %s', $this->description, $this->getAttribute('attributes') ? join('|',unserialize($this->getAttribute('attributes'))) : ''); } public function getSubTotalAttribute(): float { return $this->quantity*$this->amount; } public function getTotalAttribute(): float { return $this->account->taxed($this->getSubTotalAttribute()); } public function getTypeNameAttribute(): string { return Arr::get(InvoiceItem::type,$this->type); } }