src/Services/PurchaseService.php
<?php
declare(strict_types=1);
namespace Bavix\Wallet\Services;
use Bavix\Wallet\Interfaces\Customer;
use Bavix\Wallet\Internal\Dto\BasketDtoInterface;
use Bavix\Wallet\Models\Transfer;
/**
* @internal
*/
final readonly class PurchaseService implements PurchaseServiceInterface
{
public function __construct(
private CastServiceInterface $castService
) {
}
public function already(Customer $customer, BasketDtoInterface $basketDto, bool $gifts = false): array
{
$status = $gifts
? [Transfer::STATUS_PAID, Transfer::STATUS_GIFT]
: [Transfer::STATUS_PAID];
$arrays = [];
$wallets = [];
$productCounts = [];
$query = $customer->transfers();
foreach ($basketDto->items() as $itemDto) {
$wallet = $this->castService->getWallet($itemDto->getReceiving() ?? $itemDto->getProduct());
$wallets[$wallet->uuid] = $wallet;
$productCounts[$wallet->uuid] = ($productCounts[$wallet->uuid] ?? 0) + count($itemDto);
}
foreach ($wallets as $wallet) {
/**
* As part of my work, "with" was added, it gives a 50x boost for a huge number of returns. In this case,
* it's a crutch. It is necessary to come up with a more correct implementation of the internal and external
* interface for "purchases".
*/
$arrays[] = (clone $query)
->with(['deposit', 'withdraw.wallet'])
->where('to_id', $wallet->getKey())
->whereIn('status', $status)
->orderBy('id', 'desc')
->limit($productCounts[$wallet->uuid])
->get()
->all();
}
return array_merge(...$arrays);
}
}