'object', 'line_items' => 'object' ]; protected $with = [ 'company', 'client', ]; protected $appends = [ 'hashed_id', 'status' ]; const STATUS_DRAFT = 1; const STATUS_SENT = 2; const STATUS_PARTIAL = 3; const STATUS_PAID = 4; const STATUS_CANCELLED = 5; const STATUS_OVERDUE = -1; const STATUS_UNPAID = -2; const STATUS_REVERSED = -3; public function getStatusAttribute() { if($this->status_id == Invoice::STATUS_SENT && $this->due_date > Carbon::now()) return Invoice::STATUS_UNPAID; else if($this->status_id == Invoice::STATUS_PARTIAL && $this->partial_due_date > Carbon::now()) return Invoice::STATUS_UNPAID; else if($this->status_id == Invoice::STATUS_SENT && $this->due_date < Carbon::now()) return Invoice::STATUS_OVERDUE; else if($this->status_id == Invoice::STATUS_PARTIAL && $this->partial_due_date < Carbon::now()) return Invoice::STATUS_OVERDUE; else return $this->status_id; } public function company() { return $this->belongsTo(Company::class); } public function user() { return $this->belongsTo(User::class); } public function invitations() { return $this->hasMany(InvoiceInvitation::class); } public function client() { return $this->belongsTo(Client::class); } public function documents() { return $this->morphMany(Document::class, 'documentable'); } public function payments() { return $this->morphToMany(Payment::class, 'paymentable'); } public function company_ledger() { return $this->morphMany(CompanyLedger::class, 'company_ledgerable'); } /* ---------------- */ /* Settings getters */ /* ---------------- */ /** * If True, prevents an invoice from being * modified once it has been marked as sent * * @return boolean isLocked */ public function isLocked() : bool { return $this->client->getMergedSettings()->lock_sent_invoices; } /** * Gets the currency from the settings object. * * @return Eloquent Model The currency. */ public function getCurrency() { return Currency::find($this->settings->currency_id); } /** * Determines if invoice overdue. * * @param float $balance The balance * @param date. $due_date The due date * * @return boolean True if overdue, False otherwise. */ public static function isOverdue($balance, $due_date) { if (! $this->formatValue($balance,2) > 0 || ! $due_date) { return false; } // it isn't considered overdue until the end of the day return strtotime($this->createClientDate(date(), $this->client->timezone()->name)) > (strtotime($due_date) + (60 * 60 * 24)); } public function markViewed() { $this->last_viewed = Carbon::now()->format('Y-m-d H:i'); } public function isPayable() { return ($this->status === Invoice::STATUS_UNPAID || $this->status === Invoice::STATUS_OVERDUE); } public static function badgeForStatus(int $status) { switch ($status) { case Invoice::STATUS_DRAFT: return '
'.ctrans('texts.draft').'
'; break; case Invoice::STATUS_SENT: return '
'.ctrans('texts.sent').'
'; break; case Invoice::STATUS_PARTIAL: return '
'.ctrans('texts.partial').'
'; break; case Invoice::STATUS_PAID: return '
'.ctrans('texts.paid').'
'; break; case Invoice::STATUS_CANCELLED: return '
'.ctrans('texts.cancelled').'
'; break; case Invoice::STATUS_OVERDUE: return '
'.ctrans('texts.overdue').'
'; break; case Invoice::STATUS_UNPAID: return '
'.ctrans('texts.unpaid').'
'; break; case Invoice::STATUS_REVERSED: return '
'.ctrans('texts.reversed').'
'; break; default: # code... break; } } /** * Returns the template for the invoice * * @return string Either the template view, OR the template HTML string */ public function design() :string { return File::exists(resource_path($this->settings->design)) ? File::get(resource_path($this->settings->design)) : File::get(resource_path('views/pdf/design1.blade.php')); } /** * Access the invoice calculator object * * @return object The invoice calculator object getters */ public function calc() { $invoice_calc = new InvoiceCalc($this, $this->client->getMergedSettings()); return $invoice_calc->build(); } }