/app/Abstracts/DocumentModel.php

https://github.com/akaunting/akaunting · PHP · 196 lines · 125 code · 34 blank · 37 comment · 13 complexity · c9c4961ad1ab09ecd85348830dcf29e2 MD5 · raw file

  1. <?php
  2. namespace App\Abstracts;
  3. use App\Abstracts\Model;
  4. use App\Models\Setting\Tax;
  5. use App\Traits\Currencies;
  6. use App\Traits\DateTime;
  7. use App\Traits\Media;
  8. use App\Traits\Recurring;
  9. use Bkwld\Cloner\Cloneable;
  10. abstract class DocumentModel extends Model
  11. {
  12. use Cloneable, Currencies, DateTime, Media, Recurring;
  13. public function totals_sorted()
  14. {
  15. return $this->totals()->orderBy('sort_order');
  16. }
  17. public function scopeDue($query, $date)
  18. {
  19. return $query->whereDate('due_at', '=', $date);
  20. }
  21. public function scopeAccrued($query)
  22. {
  23. return $query->whereNotIn('status', ['draft', 'cancelled']);
  24. }
  25. public function scopePaid($query)
  26. {
  27. return $query->where('status', '=', 'paid');
  28. }
  29. public function scopeNotPaid($query)
  30. {
  31. return $query->where('status', '<>', 'paid');
  32. }
  33. /**
  34. * Get the current balance.
  35. *
  36. * @return string
  37. */
  38. public function getAttachmentAttribute($value)
  39. {
  40. if (!empty($value) && !$this->hasMedia('attachment')) {
  41. return $value;
  42. } elseif (!$this->hasMedia('attachment')) {
  43. return false;
  44. }
  45. return $this->getMedia('attachment')->last();
  46. }
  47. /**
  48. * Get the discount percentage.
  49. *
  50. * @return string
  51. */
  52. public function getDiscountAttribute()
  53. {
  54. $percent = 0;
  55. $discount = $this->totals->where('code', 'discount')->makeHidden('title')->pluck('amount')->first();
  56. if ($discount) {
  57. $sub_total = $this->totals->where('code', 'sub_total')->makeHidden('title')->pluck('amount')->first();
  58. $percent = number_format((($discount * 100) / $sub_total), 0);
  59. }
  60. return $percent;
  61. }
  62. /**
  63. * Get the paid amount.
  64. *
  65. * @return string
  66. */
  67. public function getPaidAttribute()
  68. {
  69. if (empty($this->amount)) {
  70. return false;
  71. }
  72. $paid = 0;
  73. $reconciled = $reconciled_amount = 0;
  74. $code = $this->currency_code;
  75. $rate = config('money.' . $code . '.rate');
  76. $precision = config('money.' . $code . '.precision');
  77. if ($this->transactions->count()) {
  78. foreach ($this->transactions as $item) {
  79. $amount = $item->amount;
  80. if ($code != $item->currency_code) {
  81. $amount = $this->convertBetween($amount, $item->currency_code, $item->currency_rate, $code, $rate);
  82. }
  83. $paid += $amount;
  84. if ($item->reconciled) {
  85. $reconciled_amount = +$amount;
  86. }
  87. }
  88. }
  89. if (bccomp(round($this->amount, $precision), round($reconciled_amount, $precision), $precision) === 0) {
  90. $reconciled = 1;
  91. }
  92. $this->setAttribute('reconciled', $reconciled);
  93. return round($paid, $precision);
  94. }
  95. /**
  96. * Get the status label.
  97. *
  98. * @return string
  99. */
  100. public function getStatusLabelAttribute()
  101. {
  102. switch ($this->status) {
  103. case 'paid':
  104. $label = 'success';
  105. break;
  106. case 'partial':
  107. $label = 'info';
  108. break;
  109. case 'sent':
  110. case 'received':
  111. $label = 'danger';
  112. break;
  113. case 'viewed':
  114. $label = 'warning';
  115. break;
  116. case 'cancelled':
  117. $label = 'dark';
  118. break;
  119. default:
  120. $label = 'primary';
  121. break;
  122. }
  123. return $label;
  124. }
  125. /**
  126. * Get the amount without tax.
  127. *
  128. * @return string
  129. */
  130. public function getAmountWithoutTaxAttribute()
  131. {
  132. $amount = $this->amount;
  133. $this->totals->where('code', 'tax')->each(function ($total) use(&$amount) {
  134. $tax = Tax::name($total->name)->first();
  135. if (!empty($tax) && ($tax->type == 'withholding')) {
  136. return;
  137. }
  138. $amount -= $total->amount;
  139. });
  140. return $amount;
  141. }
  142. /**
  143. * Convert amount to double.
  144. *
  145. * @param string $value
  146. * @return void
  147. */
  148. public function setAmountAttribute($value)
  149. {
  150. $this->attributes['amount'] = (double) $value;
  151. }
  152. /**
  153. * Convert currency rate to double.
  154. *
  155. * @param string $value
  156. * @return void
  157. */
  158. public function setCurrencyRateAttribute($value)
  159. {
  160. $this->attributes['currency_rate'] = (double) $value;
  161. }
  162. }