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.

Currency.php 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. namespace App\Models\Setting;
  3. use Akaunting\Money\Currency as ISOCurrencies;
  4. use App\Casts\RateCast;
  5. use App\Models\Banking\Account;
  6. use App\Traits\Blamable;
  7. use App\Traits\CompanyOwned;
  8. use App\Traits\SyncsWithCompanyDefaults;
  9. use Database\Factories\Setting\CurrencyFactory;
  10. use Illuminate\Database\Eloquent\Factories\Factory;
  11. use Illuminate\Database\Eloquent\Factories\HasFactory;
  12. use Illuminate\Database\Eloquent\Model;
  13. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  14. use Illuminate\Database\Eloquent\Relations\HasMany;
  15. use Illuminate\Database\Eloquent\Relations\HasOne;
  16. use Illuminate\Support\Facades\DB;
  17. use Wallo\FilamentCompanies\FilamentCompanies;
  18. class Currency extends Model
  19. {
  20. use Blamable, CompanyOwned, SyncsWithCompanyDefaults, HasFactory;
  21. protected $table = 'currencies';
  22. protected $fillable = [
  23. 'company_id',
  24. 'name',
  25. 'code',
  26. 'rate',
  27. 'precision',
  28. 'symbol',
  29. 'symbol_first',
  30. 'decimal_mark',
  31. 'thousands_separator',
  32. 'enabled',
  33. 'created_by',
  34. 'updated_by',
  35. ];
  36. protected $casts = [
  37. 'enabled' => 'boolean',
  38. 'symbol_first' => 'boolean',
  39. 'rate' => RateCast::class,
  40. ];
  41. public function company(): BelongsTo
  42. {
  43. return $this->belongsTo(FilamentCompanies::companyModel(), 'company_id');
  44. }
  45. public function defaultCurrency(): HasOne
  46. {
  47. return $this->hasOne(CompanyDefault::class, 'currency_code', 'code');
  48. }
  49. public function accounts(): HasMany
  50. {
  51. return $this->hasMany(Account::class, 'currency_code', 'code');
  52. }
  53. public function createdBy(): BelongsTo
  54. {
  55. return $this->belongsTo(FilamentCompanies::userModel(), 'created_by');
  56. }
  57. public function updatedBy(): BelongsTo
  58. {
  59. return $this->belongsTo(FilamentCompanies::userModel(), 'updated_by');
  60. }
  61. public static function getAvailableCurrencyCodes(): array
  62. {
  63. $allISOCurrencies = static::getAllCurrencies();
  64. $allISOCurrencyCodes = array_keys($allISOCurrencies);
  65. $storedCurrencyCodes = static::query()
  66. ->pluck('code')
  67. ->toArray();
  68. $availableCurrencyCodes = array_diff($allISOCurrencyCodes, $storedCurrencyCodes);
  69. return array_combine($availableCurrencyCodes, $availableCurrencyCodes);
  70. }
  71. public static function getAllCurrencies(): array
  72. {
  73. return ISOCurrencies::getCurrencies();
  74. }
  75. public static function getDefaultCurrencyCode(): string|null
  76. {
  77. $defaultCurrency = static::query()
  78. ->where('enabled', true)
  79. ->first();
  80. return $defaultCurrency?->code ?? null;
  81. }
  82. public static function convertBalance($balance, $oldCurrency, $newCurrency): int
  83. {
  84. $currencies = self::whereIn('code', [$oldCurrency, $newCurrency])->get();
  85. $oldCurrency = $currencies->firstWhere('code', $oldCurrency);
  86. $newCurrency = $currencies->firstWhere('code', $newCurrency);
  87. $oldRate = DB::table('currencies')
  88. ->where('code', $oldCurrency->code)
  89. ->value('rate');
  90. $newRate = DB::table('currencies')
  91. ->where('code', $newCurrency->code)
  92. ->value('rate');
  93. $precision = max($oldCurrency->precision, $newCurrency->precision);
  94. $scale = 10 ** $precision;
  95. $cleanBalance = (int)filter_var($balance, FILTER_SANITIZE_NUMBER_INT);
  96. return round(($cleanBalance * $newRate * $scale) / ($oldRate * $scale));
  97. }
  98. protected static function newFactory(): Factory
  99. {
  100. return CurrencyFactory::new();
  101. }
  102. }