'object', 'line_items' => 'object', 'backup' => 'object', 'updated_at' => 'timestamp', 'created_at' => 'timestamp', 'deleted_at' => 'timestamp', ]; protected $appends = [ 'hashed_id', 'status', ]; protected $touches = []; public function getEntityType() { return self::class; } public function getDateAttribute($value) { if (! empty($value)) { return (new Carbon($value))->format('Y-m-d'); } return $value; } public function getDueDateAttribute($value) { if (! empty($value)) { return (new Carbon($value))->format('Y-m-d'); } return $value; } public function getPartialDueDateAttribute($value) { if (! empty($value)) { return (new Carbon($value))->format('Y-m-d'); } return $value; } public function company() { return $this->belongsTo(Company::class); } public function client() { return $this->belongsTo(Client::class)->withTrashed(); } public function project() { return $this->belongsTo(Project::class)->withTrashed(); } public function user() { return $this->belongsTo(User::class)->withTrashed(); } public function assigned_user() { return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed(); } public function invoices() { return $this->hasMany(Invoice::class, 'id', 'recurring_id')->withTrashed(); } public function invitations() { return $this->hasMany(RecurringInvoiceInvitation::class); } public function documents() { return $this->morphMany(Document::class, 'documentable'); } public function getStatusAttribute() { if ($this->status_id == self::STATUS_ACTIVE && Carbon::parse($this->next_send_date)->isFuture()) { return self::STATUS_PENDING; } else { return $this->status_id; } } public function nextSendDate() :?Carbon { if (!$this->next_send_date) { return null; // $this->next_send_date = now()->format('Y-m-d'); } switch ($this->frequency_id) { case self::FREQUENCY_DAILY: return Carbon::parse($this->next_send_date)->addDay(); case self::FREQUENCY_WEEKLY: return Carbon::parse($this->next_send_date)->addWeek(); case self::FREQUENCY_TWO_WEEKS: return Carbon::parse($this->next_send_date)->addWeeks(2); case self::FREQUENCY_FOUR_WEEKS: return Carbon::parse($this->next_send_date)->addWeeks(4); case self::FREQUENCY_MONTHLY: return Carbon::parse($this->next_send_date)->addMonthNoOverflow(); case self::FREQUENCY_TWO_MONTHS: return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(2); case self::FREQUENCY_THREE_MONTHS: return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(3); case self::FREQUENCY_FOUR_MONTHS: return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(4); case self::FREQUENCY_SIX_MONTHS: return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(6); case self::FREQUENCY_ANNUALLY: return Carbon::parse($this->next_send_date)->addYear(); case self::FREQUENCY_TWO_YEARS: return Carbon::parse($this->next_send_date)->addYears(2); case self::FREQUENCY_THREE_YEARS: return Carbon::parse($this->next_send_date)->addYears(3); default: return null; } } public function nextDateByFrequency($date) { switch ($this->frequency_id) { case self::FREQUENCY_DAILY: return Carbon::parse($date)->addDay(); case self::FREQUENCY_WEEKLY: return Carbon::parse($date)->addWeek(); case self::FREQUENCY_TWO_WEEKS: return Carbon::parse($date)->addWeeks(2); case self::FREQUENCY_FOUR_WEEKS: return Carbon::parse($date)->addWeeks(4); case self::FREQUENCY_MONTHLY: return Carbon::parse($date)->addMonthNoOverflow(); case self::FREQUENCY_TWO_MONTHS: return Carbon::parse($date)->addMonthsNoOverflow(2); case self::FREQUENCY_THREE_MONTHS: return Carbon::parse($date)->addMonthsNoOverflow(3); case self::FREQUENCY_FOUR_MONTHS: return Carbon::parse($date)->addMonthsNoOverflow(4); case self::FREQUENCY_SIX_MONTHS: return Carbon::parse($date)->addMonthsNoOverflow(6); case self::FREQUENCY_ANNUALLY: return Carbon::parse($date)->addYear(); case self::FREQUENCY_TWO_YEARS: return Carbon::parse($date)->addYears(2); case self::FREQUENCY_THREE_YEARS: return Carbon::parse($date)->addYears(3); default: return null; } } public function remainingCycles() : int { if ($this->remaining_cycles == 0) { return 0; } elseif ($this->remaining_cycles == -1) { return -1; } else { return $this->remaining_cycles - 1; } } public function setCompleted() : void { $this->status_id = self::STATUS_COMPLETED; $this->next_send_date = null; $this->remaining_cycles = 0; $this->save(); } public static function badgeForStatus(int $status) { switch ($status) { case self::STATUS_DRAFT: return '