Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Wallet Laravel Package

zotel/laravel-wallet

View on GitHub
Deep Wiki
Context7

Batch Transactions

Sometimes situations arise when there is a need to make multiple changes to wallets. For example, we need to change the balance of many wallets at once. For example, the system administrator accrues a bonus for participating in some promotion. Previously, the code would look like this:

use Zotel\Wallet\Services\AtomicServiceInterface;

app(AtomicServiceInterface::class)->blocks($wallets, function () use ($amount, $wallets) {
    foreach ($wallets as $wallet) {
        $wallet->deposit($amount);
    }
});

The code is working and everything works correctly. But what happens under the hood? Nothing good. For 5 users it will look like this.

Since the operations inside an atomic operation can depend on each other, we will not be able to combine insert queries into a batch. But there is an opportunity to reduce the number of update queries and improve application performance out of the blue.

After small things, the situation will look like this.

As you can see, things are getting better. Still, I would like to be able to tell the package that the changes are independent of each other. In this case, the package will be able to collapse all insert queries into a single query and insert in a batch.

Here new api handles can help us:

// For multiple transactions.
interface TransactionQueryHandlerInterface
{
    /**
     * [@param](https://github.com/param) non-empty-array<TransactionQuery> $objects
     * [@return](https://github.com/return) non-empty-array<string, Transaction>
     * [@throws](https://github.com/throws) ExceptionInterface
     */
    public function apply(array $objects): array;
}

// For multiple transfers of funds.
interface TransferQueryHandlerInterface
{
    /**
     * [@param](https://github.com/param) non-empty-array<TransferQuery> $objects
     * [@return](https://github.com/return) non-empty-array<string, Transfer>
     * [@throws](https://github.com/throws) ExceptionInterface
     */
    public function apply(array $objects): array;
}

Let's use the API handle.

use Zotel\Wallet\External\Api\TransactionQuery;
use Zotel\Wallet\External\Api\TransactionQueryHandlerInterface;

app(TransactionQueryHandlerInterface::class)->apply(
    array_map(
        static fn (Wallet $wallet) => TransactionQuery::createDeposit($wallet, $amount, null),
        $wallets
     )
);

And now look at the result and it is impressive.

But it is worth noting that these are highly efficient api handles and they do not check the balance of the wallet before making changes. If you need it, then you have to do something like this.

use Zotel\Wallet\External\Api\TransactionQuery;
use Zotel\Wallet\External\Api\TransactionQueryHandlerInterface;
use Zotel\Wallet\Services\AtomicServiceInterface;
use Zotel\Wallet\Services\ConsistencyServiceInterface;

app(AtomicServiceInterface::class)->blocks($wallets, function () use ($wallets, $amount) {
    foreach ($wallets as $wallet) {
        app(ConsistencyServiceInterface::class)->checkPotential($wallet, $amount);
    }

    app(TransactionQueryHandlerInterface::class)->apply(
        array_map(
            static fn (Wallet $wallet) => TransactionQuery::createWithdraw($wallet, $amount, null),
            $wallets
        )
    );
});

In version 10.x, it became possible to create transactions with a given uuid (generate on the client side). The main thing is to keep uniqueness.

use Zotel\Wallet\External\Api\TransactionQuery;

// int version
TransactionQuery::createDeposit($wallet, $amount, null, uuid: '5f7820d1-1e82-4d03-9414-05d0c44da9a1');
TransactionQuery::createWithdraw($wallet, $amount, null, uuid: '6e87dbf2-7be7-48c2-b688-f46ba4e25786');

// float version
TransactionFloatQuery::createDeposit($wallet, $amountFloat, null, uuid: '5f7820d1-1e82-4d03-9414-05d0c44da9a1');
TransactionFloatQuery::createWithdraw($wallet, $amountFloat, null, uuid: '6e87dbf2-7be7-48c2-b688-f46ba4e25786');

It's simple!

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle