You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BudgetItem.php 2.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. namespace App\Models\Accounting;
  3. use App\Casts\MoneyCast;
  4. use App\Concerns\Blamable;
  5. use App\Concerns\CompanyOwned;
  6. use Illuminate\Database\Eloquent\Casts\Attribute;
  7. use Illuminate\Database\Eloquent\Factories\HasFactory;
  8. use Illuminate\Database\Eloquent\Model;
  9. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  10. class BudgetItem extends Model
  11. {
  12. use Blamable;
  13. use CompanyOwned;
  14. use HasFactory;
  15. protected $fillable = [
  16. 'company_id',
  17. 'budget_id',
  18. 'account_id',
  19. 'start_date',
  20. 'end_date',
  21. 'amount', // in cents
  22. 'created_by',
  23. 'updated_by',
  24. ];
  25. protected $casts = [
  26. 'start_date' => 'date',
  27. 'end_date' => 'date',
  28. 'amount' => MoneyCast::class,
  29. ];
  30. public function budget(): BelongsTo
  31. {
  32. return $this->belongsTo(Budget::class);
  33. }
  34. public function account(): BelongsTo
  35. {
  36. return $this->belongsTo(Account::class);
  37. }
  38. /**
  39. * Get actual transaction amount for this account and date range.
  40. */
  41. protected function actualAmount(): Attribute
  42. {
  43. return Attribute::make(
  44. get: function () {
  45. return Transaction::whereHas('journalEntries', function ($query) {
  46. $query->where('account_id', $this->account_id);
  47. })
  48. ->whereBetween('posted_at', [$this->start_date, $this->end_date])
  49. ->sum('amount');
  50. }
  51. );
  52. }
  53. /**
  54. * Get variance (budget - actual) for this budget item.
  55. */
  56. protected function variance(): Attribute
  57. {
  58. return Attribute::make(
  59. get: function () {
  60. return $this->amount - $this->actualAmount;
  61. }
  62. );
  63. }
  64. /**
  65. * Get variance percentage for this budget item.
  66. */
  67. protected function variancePercentage(): Attribute
  68. {
  69. return Attribute::make(
  70. get: function () {
  71. if ($this->amount == 0) {
  72. return 0;
  73. }
  74. return ($this->variance / $this->amount) * 100;
  75. }
  76. );
  77. }
  78. }