Wallet.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. // Copyright 2019 Hackware SpA <human@hackware.cl>
  3. // This file is part of "Hackware Web Services Wallet" and licensed under
  4. // the terms of the GNU Affero General Public License version 3, or (at your
  5. // option) a later version. You should have received a copy of this license
  6. // along with the software. If not, see <https://www.gnu.org/licenses/>.
  7. namespace Hawese\Wallet;
  8. use Hawese\Core\User;
  9. use Hawese\Core\Exceptions\ModelObjectNotFoundException;
  10. use Illuminate\Database\Query\Builder;
  11. use Illuminate\Support\Carbon;
  12. class Wallet extends TableModel
  13. {
  14. public static $table = 'wallets';
  15. public static $attributes = [
  16. 'user_uid' => ['required', 'string', 'min:3', 'max:100'],
  17. 'currency_code' => [
  18. 'required', 'string', 'size:3', 'exists:currencies,code'
  19. ],
  20. 'created_at' => ['nullable', 'date'],
  21. 'updated_at' => ['nullable', 'date'],
  22. 'deleted_at' => ['nullable', 'date']
  23. ];
  24. public static $primary_key = 'user_uid';
  25. protected static $incrementing = false;
  26. public function __construct($data)
  27. {
  28. // Virtual properties
  29. $this->append('due_at');
  30. $this->append('balance');
  31. parent::__construct($data);
  32. }
  33. public function setDueAt($value) : void
  34. {
  35. $this->dateSetter('due_at', $value);
  36. }
  37. public function getDueAt()
  38. {
  39. if (!array_key_exists('due_at', $this->data)) {
  40. $query = Transaction::select(['due_at'])
  41. ->where('user_uid', '=', $this->user_uid)
  42. ->whereNotNull('due_at')
  43. ->orderBy('due_at', 'asc');
  44. $this->due_at = $query->exists() ? $query->first()->due_at : null;
  45. }
  46. return $this->data['due_at'];
  47. }
  48. public function getBalance()
  49. {
  50. if (!array_key_exists('balance', $this->data)) {
  51. $this->balance = Transaction::select(['balance'])
  52. ->latest()->first()->balance;
  53. }
  54. return $this->data['balance'];
  55. }
  56. /*
  57. // I will leave it here just in case, probably will delete it in future.
  58. // It preprocesses due_at and balance values, but seems too hacky for me.
  59. public static function select(?array $attributes = null) : Builder
  60. {
  61. return app('db')->table(static::$table)
  62. ->select(array_merge(
  63. array_map(
  64. function ($attribute) {
  65. return self::$table . '.' . $attribute;
  66. },
  67. static::attributes()
  68. ),
  69. [app('db')->raw('MIN(due_at) as due_at,' .
  70. '(SELECT balance' .
  71. ' FROM ' . Transaction::$table . ' WHERE ' .
  72. Transaction::$table.'.user_uid = '.self::$table.'.user_uid'
  73. . ' ORDER BY id DESC LIMIT 1) as balance')]
  74. ))
  75. ->leftJoin(
  76. Transaction::$table,
  77. Transaction::$table . '.user_uid',
  78. '=',
  79. self::$table . '.user_uid'
  80. )
  81. ->groupBy(
  82. 'wallets.user_uid',
  83. 'currency_code',
  84. 'wallets.created_at',
  85. 'wallets.updated_at',
  86. 'wallets.deleted_at'
  87. );
  88. }
  89. */
  90. public function insert(): bool
  91. {
  92. // FIXME: Validated twice! Check hawese-core issue #5
  93. $this->validate();
  94. try {
  95. $user = User::find($this->user_uid);
  96. } catch (ModelObjectNotFoundException $e) {
  97. $user = new User(['uid' => $this->user_uid]);
  98. if (strpos($this->user_uid, '@') !== false) {
  99. $user->email = $this->user_uid; // TODO: Sure about this?
  100. }
  101. $user->insert();
  102. }
  103. return parent::insert();
  104. }
  105. public function initialTransaction() : bool
  106. {
  107. $transaction = new Transaction([
  108. 'user_uid' => $this->user_uid,
  109. 'currency_id' => Currency::findByCode($this->currency_code)->id,
  110. 'amount' => '0',
  111. 'type' => 'system',
  112. 'description' => 'Wallet creation'
  113. ]);
  114. return $transaction->insert();
  115. }
  116. public function isOwner(User $user): bool
  117. {
  118. return $this->user_uid === $user->uid;
  119. }
  120. }