*/ use HasFactory; use Searchable; public $guarded = []; public $casts = [ 'to' => ReceiverData::class, 'status' => InvoiceStatus::class, 'via' => BillKind::class, 'sent_at' => 'datetime', 'last_remembered_at' => 'datetime', ]; /** * @return HasMany */ public function positions(): HasMany { return $this->hasMany(InvoicePosition::class); } public static function createFromFactory(InvoiceCreator $factory): self { $invoice = new self([ 'to' => $factory->getReceiver(), 'status' => InvoiceStatus::NEW, 'via' => $factory->getVia(), 'usage' => $factory->getUsage(), ]); $invoice->setRelation('positions', $factory->getPositions()->toArray()); return $invoice; } public static function booted(): void { static::deleting(function ($model) { $model->positions()->delete(); }); } /** * @param Builder $query * * @return Builder */ public function scopeWhereNeedsPayment(Builder $query): Builder { return $query->whereIn('status', [InvoiceStatus::NEW->value, InvoiceStatus::SENT->value]); } /** * @param Builder $query * * @return Builder */ public function scopeWhereNeedsBill(Builder $query): Builder { return $query->where('status', InvoiceStatus::NEW); } /** * @param Builder $query * * @return Builder */ public function scopeWhereNeedsRemember(Builder $query, ?int $weeks = null): Builder { $weeks = $weeks ?: app(InvoiceSettings::class)->rememberWeeks; return $query ->where('status', InvoiceStatus::SENT) ->whereNotNull('sent_at') ->whereNotNull('last_remembered_at') ->where('last_remembered_at', '<=', now()->subWeeks($weeks)); } public function getRecipient(): ReceiverData { return $this->to; } public function sent(InvoiceDocument $document): void { if (is_a($document, BillDocument::class)) { $this->update([ 'sent_at' => now(), 'status' => InvoiceStatus::SENT, 'last_remembered_at' => now(), ]); } if (is_a($document, RememberDocument::class)) { $this->update([ 'last_remembered_at' => now(), 'status' => InvoiceStatus::SENT, ]); } } /** * Get the indexable data array for the model. * * @return array */ public function toSearchableArray(): array { return [ 'to' => implode(', ', $this->getRecipient()->toArray()), 'usage' => $this->usage, 'status' => $this->status->value, ]; } }