bavix / laravel-wallet

It's easy to work with a virtual wallet
https://bavix.github.io/laravel-wallet/
MIT License
1.11k stars 222 forks source link

Is it possible to have 2 wallets by default. #950

Closed Meeshalk closed 2 months ago

Meeshalk commented 2 months ago

I need to have 2 wallets, one would be the default one and the other would be an exposure wallet.

Can I add it to the config? Or something else?

Please help! Thanks

rez1dent3 commented 2 months ago

Hello. Two wallets per user or globally? In any case, you need multi-wallets: https://bavix.github.io/laravel-wallet/#/new-wallet

Meeshalk commented 2 months ago

Hello. Two wallets per user or globally? In any case, you need multi-wallets: https://bavix.github.io/laravel-wallet/#/new-wallet

2 wallet globally

And yes I added the Multi wallet trait but not sure how to add the new wallet details in config file.

Or do we have to create every time?

Could we introduce something like;

$user->deposit(100, ... $walletSlug or instance)

And

$user->transfer(100, ... $fromWalletSlug or instance, $toWalletSlug or instance)

Let me know if I can help?

Thanks 🙂

rez1dent3 commented 2 months ago

2 wallet globally

If globally, then you must have a global model in the project. For example, settings. This model must have a wallet.

And yes I added the Multi wallet trait but not sure how to add the new wallet details in config file. Or do we have to create every time?

No way. You must create a wallet if necessary (by yourself).

$user->deposit(100, ... $walletSlug or instance) $user->transfer(100, ... $fromWalletSlug or instance, $toWalletSlug or instance)

Operations are carried out over the wallet. In the case of transfer, the transfer parameter must be a specific wallet.

Deposit: https://github.com/bavix/laravel-wallet/blob/e8c70cc385319a2119fd1c4e2426ec1dddefff56/tests/Units/Domain/MultiWalletTest.php#L87-L100

Transfer: https://github.com/bavix/laravel-wallet/blob/e8c70cc385319a2119fd1c4e2426ec1dddefff56/tests/Units/Domain/MultiWalletTest.php#L305-L330

rez1dent3 commented 2 months ago

You can get a wallet by slug using the getWallet() method:

https://github.com/bavix/laravel-wallet/blob/e8798713a3849d50c6c81b2bddcb62f83a6a97ba/src/Traits/HasWallets.php#L41-L48

Meeshalk commented 2 months ago

Thanks a lot for clarifications.

I'll update my approach soon.

Have a great day.

Meeshalk commented 2 months ago

@rez1dent3 Thanks a lot for your responses, really appreciate it.

Solved the issue with an additional Trail, which manages exposure wallet. Exposure wallet is like a reserve wallet which holds an amount until a certain event. After the event is resolved, this either goes back to the default wallet or credited to someone else. Its like an escrow

private function getExposureWallet(): \Bavix\Wallet\Models\Wallet
{
    if (! $this->hasWallet('exposure')) {
        return $this->createWallet(['name' => 'Exposure Wallet', 'slug' => 'exposure']);
    }

    return $this->getWallet('exposure');
}

/**
 * @throws ExceptionInterface
 */
public function addToExposure(
    float $exposure,
    int $eventId,
    float $parentExposure,
    array $meta = []
): void {
    $exposureWallet = $this->getExposureWallet();
    $transfer = $this->transferFloat(
        $exposureWallet,
        $exposure,
        array_merge(['event_id' => $eventId], $meta)
    );

    if ($this->parent !== null) {
        $this->parent->addToExposure(
            $parentExposure,
            $eventId,
            $parentExposure,
            ['child_exposure_transfer' => $transfer->id]
        );
    }
}

/**
 * @throws ExceptionInterface
 */
public function reverseExposure(
    float $exposure,
    int $eventId,
    float $parentExposure,
    array $meta = []
): void {
    $defaultWallet = $this->getWallet('default');
    $exposureWallet = $this->getExposureWallet();

    $transfer = $exposureWallet->transferFloat(
        $defaultWallet,
        $exposure,
        array_merge(['event_id' => $eventId], $meta)
    );
    if ($this->parent !== null) {
        $this->parent->reverseExposure(
            $parentExposure,
            $eventId,
            $parentExposure,
            ['child_exposure_transfer' => $transfer->id]
        );
    }
}

public function settleExposure(...): void
{
    ...
}