Skip to content

Commit 1d63a3c

Browse files
committed
[10.x] An example of working with multiprices in products
1 parent 7cd0ad2 commit 1d63a3c

File tree

10 files changed

+188
-9
lines changed

10 files changed

+188
-9
lines changed

phpunit.xml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
33
<coverage>
4-
<include>
5-
<directory suffix=".php">./src/</directory>
6-
</include>
74
<report>
85
<clover outputFile="./build/logs/clover.xml"/>
96
<html outputDirectory="./build/html/"/>
@@ -22,4 +19,9 @@
2219
<env name="DB_PASSWORD" value="wallet"/>
2320
<env name="CACHE_DRIVER" value="array"/>
2421
</php>
22+
<source>
23+
<include>
24+
<directory suffix=".php">./src/</directory>
25+
</include>
26+
</source>
2527
</phpunit>

src/Internal/Service/LockService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public function isBlocked(string $key): bool
9696

9797
private function getLockProvider(): LockProvider
9898
{
99-
if ($this->lockProvider === null) {
99+
if (! $this->lockProvider instanceof LockProvider) {
100100
$store = $this->cache->getStore();
101101
assert($store instanceof LockProvider);
102102

src/Services/EagerLoaderService.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Bavix\Wallet\Internal\Dto\BasketDtoInterface;
88
use Bavix\Wallet\Internal\Repository\WalletRepositoryInterface;
9+
use Bavix\Wallet\Models\Wallet;
910

1011
/**
1112
* @internal
@@ -40,7 +41,7 @@ public function loadWalletsByBasket(BasketDtoInterface $basketDto): void
4041

4142
foreach ($holderIds as $index => $holderId) {
4243
$wallet = $wallets[$holderId] ?? null;
43-
if ($wallet !== null) {
44+
if ($wallet instanceof Wallet) {
4445
$model = $this->castService->getModel($products[$index]);
4546
$model->setRelation('wallet', $wallet);
4647
}

src/Services/TransactionService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public function apply(array $wallets, array $objects): array
6666

6767
foreach ($totals as $walletId => $total) {
6868
$wallet = $wallets[$walletId] ?? null;
69-
assert($wallet !== null);
69+
assert($wallet instanceof Wallet);
7070

7171
$object = $this->castService->getWallet($wallet);
7272
assert($object->getKey() === $walletId);

src/Services/TransferService.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Bavix\Wallet\Internal\Exceptions\TransactionFailedException;
1212
use Bavix\Wallet\Internal\Repository\TransferRepositoryInterface;
1313
use Bavix\Wallet\Internal\Service\DatabaseServiceInterface;
14+
use Bavix\Wallet\Models\Transaction;
1415
use Bavix\Wallet\Models\Transfer;
1516
use Illuminate\Database\RecordsNotFoundException;
1617

@@ -69,10 +70,10 @@ public function apply(array $objects): array
6970
$transfers = [];
7071
foreach ($objects as $object) {
7172
$withdraw = $transactions[$object->getWithdrawDto()->getUuid()] ?? null;
72-
assert($withdraw !== null);
73+
assert($withdraw instanceof Transaction);
7374

7475
$deposit = $transactions[$object->getDepositDto()->getUuid()] ?? null;
75-
assert($deposit !== null);
76+
assert($deposit instanceof Transaction);
7677

7778
$fromWallet = $this->castService->getWallet($object->getFromWallet());
7879
$toWallet = $this->castService->getWallet($object->getToWallet());
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Bavix\Wallet\Test\Infra\Exceptions;
6+
7+
use Bavix\Wallet\Internal\Exceptions\InvalidArgumentExceptionInterface;
8+
use InvalidArgumentException;
9+
10+
final class PriceNotSetException extends InvalidArgumentException implements InvalidArgumentExceptionInterface
11+
{
12+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Bavix\Wallet\Test\Infra\Factories;
6+
7+
use Bavix\Wallet\Test\Infra\Models\ItemMultiPrice;
8+
use Illuminate\Database\Eloquent\Factories\Factory;
9+
10+
/**
11+
* @extends Factory<ItemMultiPrice>
12+
*/
13+
final class ItemMultiPriceFactory extends Factory
14+
{
15+
protected $model = ItemMultiPrice::class;
16+
17+
public function definition(): array
18+
{
19+
$priceUsd = random_int(100, 700);
20+
21+
return [
22+
'name' => fake()
23+
->domainName,
24+
'price' => -1,
25+
'quantity' => random_int(10, 100),
26+
'prices' => [
27+
'USD' => $priceUsd,
28+
],
29+
];
30+
}
31+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Bavix\Wallet\Test\Infra\Models;
6+
7+
use Bavix\Wallet\Interfaces\Customer;
8+
use Bavix\Wallet\Interfaces\ProductLimitedInterface;
9+
use Bavix\Wallet\Models\Wallet;
10+
use Bavix\Wallet\Services\CastService;
11+
use Bavix\Wallet\Test\Infra\Exceptions\PriceNotSetException;
12+
use Bavix\Wallet\Traits\HasWallet;
13+
use Illuminate\Database\Eloquent\Model;
14+
15+
/**
16+
* @property string $name
17+
* @property int $quantity
18+
* @property int $price
19+
* @property array<string, int> $prices
20+
*
21+
* @method int getKey()
22+
*/
23+
final class ItemMultiPrice extends Model implements ProductLimitedInterface
24+
{
25+
use HasWallet;
26+
27+
/**
28+
* @var string[]
29+
*/
30+
protected $fillable = ['name', 'quantity', 'price', 'prices'];
31+
32+
protected $casts = [
33+
'prices' => 'array',
34+
];
35+
36+
public function getTable(): string
37+
{
38+
return 'items';
39+
}
40+
41+
public function canBuy(Customer $customer, int $quantity = 1, bool $force = false): bool
42+
{
43+
$result = $this->quantity >= $quantity;
44+
45+
if ($force) {
46+
return $result;
47+
}
48+
49+
return $result && ! $customer->paid($this);
50+
}
51+
52+
public function getAmountProduct(Customer $customer): int
53+
{
54+
/** @var Wallet $wallet */
55+
$wallet = app(CastService::class)->getWallet($customer);
56+
57+
if (array_key_exists($wallet->currency, $this->prices)) {
58+
return $this->prices[$wallet->currency];
59+
}
60+
61+
throw new PriceNotSetException("Price not set for {$wallet->currency} currency");
62+
}
63+
64+
public function getMetaProduct(): ?array
65+
{
66+
return null;
67+
}
68+
}

tests/Units/Domain/MultiWalletTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515
use Bavix\Wallet\Models\Transfer;
1616
use Bavix\Wallet\Services\BookkeeperServiceInterface;
1717
use Bavix\Wallet\Services\RegulatorServiceInterface;
18+
use Bavix\Wallet\Test\Infra\Exceptions\PriceNotSetException;
1819
use Bavix\Wallet\Test\Infra\Factories\ItemFactory;
20+
use Bavix\Wallet\Test\Infra\Factories\ItemMultiPriceFactory;
1921
use Bavix\Wallet\Test\Infra\Factories\UserCashierFactory;
2022
use Bavix\Wallet\Test\Infra\Factories\UserMultiFactory;
2123
use Bavix\Wallet\Test\Infra\Helpers\Config;
2224
use Bavix\Wallet\Test\Infra\Models\Item;
25+
use Bavix\Wallet\Test\Infra\Models\ItemMultiPrice;
2326
use Bavix\Wallet\Test\Infra\Models\UserCashier;
2427
use Bavix\Wallet\Test\Infra\Models\UserMulti;
2528
use Bavix\Wallet\Test\Infra\PackageModels\Wallet;
@@ -545,6 +548,65 @@ public function testPay(): void
545548
self::assertSame($b->balanceInt, $product->getAmountProduct($b));
546549
}
547550

551+
public function testPayItemMultiPrice(): void
552+
{
553+
/** @var UserMulti $user */
554+
$user = UserMultiFactory::new()->create();
555+
556+
$usd = $user->createWallet([
557+
'name' => 'Dollar USA',
558+
'meta' => [
559+
'currency' => 'USD',
560+
],
561+
]);
562+
563+
/** @var ItemMultiPrice $product */
564+
$product = ItemMultiPriceFactory::new()->create([
565+
'quantity' => 1,
566+
]);
567+
568+
self::assertSame(0, $usd->balanceInt);
569+
570+
$usd->deposit($product->getAmountProduct($usd));
571+
self::assertSame($usd->balanceInt, $product->getAmountProduct($usd));
572+
573+
$transfer = $usd->pay($product);
574+
$paidTransfer = $usd->paid($product);
575+
self::assertNotNull($paidTransfer);
576+
self::assertTrue((bool) $paidTransfer);
577+
self::assertSame($transfer->getKey(), $paidTransfer->getKey());
578+
self::assertInstanceOf(UserMulti::class, $paidTransfer->withdraw->payable);
579+
self::assertSame($user->getKey(), $paidTransfer->withdraw->payable->getKey());
580+
self::assertSame($transfer->from->getKey(), $usd->getKey());
581+
self::assertSame($transfer->to->getKey(), $product->wallet->getKey());
582+
self::assertSame($transfer->status, Transfer::STATUS_PAID);
583+
self::assertSame($usd->balanceInt, 0);
584+
self::assertSame($product->balanceInt, $product->getAmountProduct($usd));
585+
}
586+
587+
public function testPayItemMultiPricePriceNotSetException(): void
588+
{
589+
$this->expectExceptionMessageStrict('Price not set for TRY currency');
590+
$this->expectException(PriceNotSetException::class);
591+
592+
/** @var UserMulti $user */
593+
$user = UserMultiFactory::new()->create();
594+
$try = $user->createWallet([
595+
'name' => 'Turkish lira',
596+
'meta' => [
597+
'currency' => 'TRY',
598+
],
599+
]);
600+
601+
/** @var ItemMultiPrice $product */
602+
$product = ItemMultiPriceFactory::new()->create([
603+
'quantity' => 1,
604+
]);
605+
606+
self::assertSame(0, $try->balanceInt);
607+
$product->getAmountProduct($try);
608+
}
609+
548610
public function testUserCashier(): void
549611
{
550612
/** @var UserCashier $user */

tests/migrations/2018_11_08_214421_create_items_table.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public function up(): void
1313
$table->increments('id');
1414
$table->string('name');
1515
$table->integer('price');
16+
$table->json('prices')
17+
->default('[]');
1618
$table->unsignedSmallInteger('quantity');
1719
$table->timestamps();
1820
});

0 commit comments

Comments
 (0)