belongsTo(ChartOfAccount::class); } public function term() { return $this->belongsTo(Term::class); } protected static function customerIdForLog($model) { return $model->saleOrder->customer_id ?? null; } protected static function customerLogAs($model) { return 'invoice'; } protected static function writeCustomerChatLog() { return true; } public function saleOrder() { return $this->belongsTo(SaleOrder::class); } public function payments() { return $this->belongsToMany(Payment::class, $this->paymentPivotTable)->withPivot('payment_amount'); } public function retainerInvoices() { return $this->belongsToMany(RetainerInvoice::class)->withPivot('amount'); } public function scopeSent($q) { return $q->where('status', 'sent'); } /** * @param Builder $q * @param mixed|null $exceptPaymentId menjumlahkan total payment kecuali id yang dipassing * @return Builder */ public function scopeUnpaid($q, $exceptPaymentId = null) { return $q->where(function ($q) use ($exceptPaymentId) { return $q->whereStatus('sent')->whereRaw( " CAST(amount AS SIGNED) > ( ( COALESCE( ( SELECT CAST( SUM(payment_amount) AS SIGNED ) FROM {$this->paymentPivotTable} WHERE invoice_id=id " . ($exceptPaymentId ? "AND payment_id != {$exceptPaymentId}" : "") . " ) , 0) ) + ( COALESCE( ( SELECT CAST( SUM(amount) AS SIGNED ) FROM {$this->retInvoicePivotTable} WHERE invoice_id=id ) , 0) ) ) " ); }); } public function scopePaid($q) { return $q->where(function ($q) { return $q->whereStatus('sent')->whereRaw( " CAST(amount AS SIGNED) <= ( ( COALESCE( ( SELECT CAST( SUM(payment_amount) AS SIGNED ) FROM {$this->paymentPivotTable} WHERE invoice_id=id ) , 0) ) + ( COALESCE( ( SELECT CAST( SUM(amount) AS SIGNED ) FROM {$this->retInvoicePivotTable} WHERE invoice_id=id ) , 0) ) ) " ); }); } /** * @param Builder $q * @return Builder */ public function scopeSumTotalAmountDue($q) { return $q->selectRaw( " ( COALESCE( SUM( ( CAST(amount AS SIGNED) - ( ( COALESCE( ( SELECT CAST( SUM(payment_amount) AS SIGNED ) FROM {$this->paymentPivotTable} WHERE invoice_id=id ) , 0) ) + ( COALESCE( ( SELECT CAST( SUM(amount) AS SIGNED ) FROM {$this->retInvoicePivotTable} WHERE invoice_id=id ) , 0) ) ) ) ),0) ) AS total_amount_due " ); } public function getPaymentAmountAttribute() { return $this->payments()->sum("payment_amount") + $this->retainer_amount; } public function getRetainerAmountAttribute() { return $this->retainerInvoices()->sum("invoice_retainer_invoice.amount"); } public function getAmountDueAttribute() { if ($this->amount) { return $this->amount - $this->paymentAmount; } } public function getCurrentStatusAttribute() { if (count($this->payments) > 0 || count($this->retainerInvoices) > 0) { if ($this->amount_due <= 0) { return "paid"; } elseif ($this->amount_due > 0) { return "partially paid"; } } return $this->status; } public function services() { return $this->hasMany(InvoiceService::class); } public function deal() { return $this->belongsTo(Deal::class); } public function reductions() { return $this->hasMany(InvoiceReduction::class); } }