Changeset View
Changeset View
Standalone View
Standalone View
src/app/Wallet.php
<?php | <?php | ||||
namespace App; | namespace App; | ||||
use App\User; | |||||
use App\Traits\SettingsTrait; | use App\Traits\SettingsTrait; | ||||
use App\Traits\UuidStrKeyTrait; | use App\Traits\UuidStrKeyTrait; | ||||
use Carbon\Carbon; | use Carbon\Carbon; | ||||
use Iatstuti\Database\Support\NullableFields; | use Dyrynda\Database\Support\NullableFields; | ||||
use Illuminate\Database\Eloquent\Model; | use Illuminate\Database\Eloquent\Model; | ||||
use Illuminate\Support\Facades\DB; | use Illuminate\Support\Facades\DB; | ||||
/** | /** | ||||
* The eloquent definition of a wallet -- a container with a chunk of change. | * The eloquent definition of a wallet -- a container with a chunk of change. | ||||
* | * | ||||
* A wallet is owned by an {@link \App\User}. | * A wallet is owned by an {@link \App\User}. | ||||
* | * | ||||
* @property int $balance Current balance in cents | * @property int $balance Current balance in cents | ||||
* @property string $currency Currency code | * @property string $currency Currency code | ||||
* @property ?string $description Description | * @property ?string $description Description | ||||
* @property string $id Unique identifier | * @property string $id Unique identifier | ||||
* @property ?\App\User $owner Owner (can be null when owner is deleted) | * @property ?\App\User $owner Owner (can be null when owner is deleted) | ||||
* @property int $user_id Owner's identifier | * @property int $user_id Owner's identifier | ||||
*/ | */ | ||||
class Wallet extends Model | class Wallet extends Model | ||||
{ | { | ||||
use NullableFields; | use NullableFields; | ||||
use SettingsTrait; | use SettingsTrait; | ||||
use UuidStrKeyTrait; | use UuidStrKeyTrait; | ||||
public $timestamps = false; | public $timestamps = false; | ||||
/** | /** @var array The attributes' default values */ | ||||
* The attributes' default values. | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $attributes = [ | protected $attributes = [ | ||||
'balance' => 0, | 'balance' => 0, | ||||
]; | ]; | ||||
/** | /** @var array<int, string> The attributes that are mass assignable */ | ||||
* The attributes that are mass assignable. | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $fillable = [ | protected $fillable = [ | ||||
'currency', | 'currency', | ||||
'description' | 'description' | ||||
]; | ]; | ||||
/** | /** @var array<int, string> The attributes that can be not set */ | ||||
* The attributes that can be not set. | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $nullable = [ | protected $nullable = [ | ||||
'description', | 'description', | ||||
]; | ]; | ||||
/** | /** @var array<string, string> The types of attributes to which its values will be cast */ | ||||
* The types of attributes to which its values will be cast | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $casts = [ | protected $casts = [ | ||||
'balance' => 'integer', | 'balance' => 'integer', | ||||
]; | ]; | ||||
/** | /** | ||||
* Add a controller to this wallet. | * Add a controller to this wallet. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | public function chargeEntitlements($apply = true): int | ||||
$entitlement->save(); | $entitlement->save(); | ||||
if ($cost == 0) { | if ($cost == 0) { | ||||
continue; | continue; | ||||
} | } | ||||
$entitlementTransactions[] = $entitlement->createTransaction( | $entitlementTransactions[] = $entitlement->createTransaction( | ||||
\App\Transaction::ENTITLEMENT_BILLED, | Transaction::ENTITLEMENT_BILLED, | ||||
$cost | $cost | ||||
); | ); | ||||
} | } | ||||
} | } | ||||
if ($apply) { | if ($apply) { | ||||
$this->debit($charges, '', $entitlementTransactions); | $this->debit($charges, '', $entitlementTransactions); | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | class Wallet extends Model | ||||
/** | /** | ||||
* Controllers of this wallet. | * Controllers of this wallet. | ||||
* | * | ||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany | * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany | ||||
*/ | */ | ||||
public function controllers() | public function controllers() | ||||
{ | { | ||||
return $this->belongsToMany( | return $this->belongsToMany( | ||||
'App\User', // The foreign object definition | User::class, // The foreign object definition | ||||
'user_accounts', // The table name | 'user_accounts', // The table name | ||||
'wallet_id', // The local foreign key | 'wallet_id', // The local foreign key | ||||
'user_id' // The remote foreign key | 'user_id' // The remote foreign key | ||||
); | ); | ||||
} | } | ||||
/** | /** | ||||
* Retrieve the costs per day of everything charged to this wallet. | * Retrieve the costs per day of everything charged to this wallet. | ||||
* | * | ||||
Show All 19 Lines | class Wallet extends Model | ||||
* @return Wallet Self | * @return Wallet Self | ||||
*/ | */ | ||||
public function credit(int $amount, string $description = ''): Wallet | public function credit(int $amount, string $description = ''): Wallet | ||||
{ | { | ||||
$this->balance += $amount; | $this->balance += $amount; | ||||
$this->save(); | $this->save(); | ||||
\App\Transaction::create( | Transaction::create( | ||||
[ | [ | ||||
'object_id' => $this->id, | 'object_id' => $this->id, | ||||
'object_type' => \App\Wallet::class, | 'object_type' => Wallet::class, | ||||
'type' => \App\Transaction::WALLET_CREDIT, | 'type' => Transaction::WALLET_CREDIT, | ||||
'amount' => $amount, | 'amount' => $amount, | ||||
'description' => $description | 'description' => $description | ||||
] | ] | ||||
); | ); | ||||
return $this; | return $this; | ||||
} | } | ||||
Show All 11 Lines | public function debit(int $amount, string $description = '', array $eTIDs = []): Wallet | ||||
if ($amount == 0) { | if ($amount == 0) { | ||||
return $this; | return $this; | ||||
} | } | ||||
$this->balance -= $amount; | $this->balance -= $amount; | ||||
$this->save(); | $this->save(); | ||||
$transaction = \App\Transaction::create( | $transaction = Transaction::create( | ||||
[ | [ | ||||
'object_id' => $this->id, | 'object_id' => $this->id, | ||||
'object_type' => \App\Wallet::class, | 'object_type' => Wallet::class, | ||||
'type' => \App\Transaction::WALLET_DEBIT, | 'type' => Transaction::WALLET_DEBIT, | ||||
'amount' => $amount * -1, | 'amount' => $amount * -1, | ||||
'description' => $description | 'description' => $description | ||||
] | ] | ||||
); | ); | ||||
if (!empty($eTIDs)) { | if (!empty($eTIDs)) { | ||||
\App\Transaction::whereIn('id', $eTIDs)->update(['transaction_id' => $transaction->id]); | Transaction::whereIn('id', $eTIDs)->update(['transaction_id' => $transaction->id]); | ||||
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* The discount assigned to the wallet. | * The discount assigned to the wallet. | ||||
* | * | ||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
*/ | */ | ||||
public function discount() | public function discount() | ||||
{ | { | ||||
return $this->belongsTo('App\Discount', 'discount_id', 'id'); | return $this->belongsTo(Discount::class, 'discount_id', 'id'); | ||||
} | } | ||||
/** | /** | ||||
* Entitlements billed to this wallet. | * Entitlements billed to this wallet. | ||||
* | * | ||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany | * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
*/ | */ | ||||
public function entitlements() | public function entitlements() | ||||
{ | { | ||||
return $this->hasMany('App\Entitlement'); | return $this->hasMany(Entitlement::class); | ||||
} | } | ||||
/** | /** | ||||
* Calculate the expected charges to this wallet. | * Calculate the expected charges to this wallet. | ||||
* | * | ||||
* @return int | * @return int | ||||
*/ | */ | ||||
public function expectedCharges() | public function expectedCharges() | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | class Wallet extends Model | ||||
/** | /** | ||||
* The owner of the wallet -- the wallet is in his/her back pocket. | * The owner of the wallet -- the wallet is in his/her back pocket. | ||||
* | * | ||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
*/ | */ | ||||
public function owner() | public function owner() | ||||
{ | { | ||||
return $this->belongsTo('App\User', 'user_id', 'id'); | return $this->belongsTo(User::class, 'user_id', 'id'); | ||||
} | } | ||||
/** | /** | ||||
* Payments on this wallet. | * Payments on this wallet. | ||||
* | * | ||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany | * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
*/ | */ | ||||
public function payments() | public function payments() | ||||
{ | { | ||||
return $this->hasMany('App\Payment'); | return $this->hasMany(Payment::class); | ||||
} | } | ||||
/** | /** | ||||
* Remove a controller from this wallet. | * Remove a controller from this wallet. | ||||
* | * | ||||
* @param \App\User $user The user to remove as a controller from this wallet. | * @param \App\User $user The user to remove as a controller from this wallet. | ||||
* | * | ||||
* @return void | * @return void | ||||
*/ | */ | ||||
public function removeController(User $user) | public function removeController(User $user) | ||||
{ | { | ||||
if ($this->controllers->contains($user)) { | if ($this->controllers->contains($user)) { | ||||
$this->controllers()->detach($user); | $this->controllers()->detach($user); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Retrieve the transactions against this wallet. | * Retrieve the transactions against this wallet. | ||||
* | * | ||||
* @return \Illuminate\Database\Eloquent\Builder Query builder | * @return \Illuminate\Database\Eloquent\Builder Query builder | ||||
*/ | */ | ||||
public function transactions() | public function transactions() | ||||
{ | { | ||||
return \App\Transaction::where( | return Transaction::where( | ||||
[ | [ | ||||
'object_id' => $this->id, | 'object_id' => $this->id, | ||||
'object_type' => \App\Wallet::class | 'object_type' => Wallet::class | ||||
] | ] | ||||
); | ); | ||||
} | } | ||||
/** | /** | ||||
* Force-update entitlements' updated_at, charge if needed. | * Force-update entitlements' updated_at, charge if needed. | ||||
* | * | ||||
* @param bool $withCost When enabled the cost will be charged | * @param bool $withCost When enabled the cost will be charged | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | public function updateEntitlements($withCost = true): int | ||||
if ($cost == 0) { | if ($cost == 0) { | ||||
continue; | continue; | ||||
} | } | ||||
$charges += $cost; | $charges += $cost; | ||||
// FIXME: Shouldn't we store also cost=0 transactions (to have the full history)? | // FIXME: Shouldn't we store also cost=0 transactions (to have the full history)? | ||||
$entitlementTransactions[] = $entitlement->createTransaction( | $entitlementTransactions[] = $entitlement->createTransaction( | ||||
\App\Transaction::ENTITLEMENT_BILLED, | Transaction::ENTITLEMENT_BILLED, | ||||
$cost | $cost | ||||
); | ); | ||||
} | } | ||||
if ($charges > 0) { | if ($charges > 0) { | ||||
$this->debit($charges, '', $entitlementTransactions); | $this->debit($charges, '', $entitlementTransactions); | ||||
} | } | ||||
DB::commit(); | DB::commit(); | ||||
return $charges; | return $charges; | ||||
} | } | ||||
} | } |