Skip to content

Commit b9a9c0f

Browse files
committed
add forcePay method
1 parent e14734a commit b9a9c0f

File tree

5 files changed

+108
-11
lines changed

5 files changed

+108
-11
lines changed

src/Interfaces/Customer.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,27 @@ interface Customer extends Wallet
99

1010
/**
1111
* @param Product $product
12+
* @param bool $force
1213
* @return Transfer
1314
* @throws
1415
*/
15-
public function pay(Product $product): Transfer;
16+
public function pay(Product $product, bool $force = false): Transfer;
1617

1718
/**
1819
* @param Product $product
20+
* @param bool $force
1921
* @return null|Transfer
2022
* @throws
2123
*/
2224
public function safePay(Product $product): ?Transfer;
2325

26+
/**
27+
* @param Product $product
28+
* @return Transfer
29+
* @throws
30+
*/
31+
public function forcePay(Product $product): Transfer;
32+
2433
/**
2534
* @param Product $product
2635
* @return null|Transfer
@@ -29,15 +38,23 @@ public function paid(Product $product): ?Transfer;
2938

3039
/**
3140
* @param Product $product
41+
* @param bool $force
3242
* @return bool
3343
* @throws
3444
*/
35-
public function refund(Product $product): bool;
45+
public function refund(Product $product, bool $force = false): bool;
46+
47+
/**
48+
* @param Product $product
49+
* @param bool $force
50+
* @return bool
51+
*/
52+
public function safeRefund(Product $product, bool $force = false): bool;
3653

3754
/**
3855
* @param Product $product
3956
* @return bool
4057
*/
41-
public function safeRefund(Product $product): bool;
58+
public function forceRefund(Product $product): bool;
4259

4360
}

src/Interfaces/Product.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ interface Product extends Wallet
77

88
/**
99
* @param Customer $customer
10+
* @param bool $force
1011
*
1112
* @return bool
1213
*/
13-
public function canBuy(Customer $customer): bool;
14+
public function canBuy(Customer $customer, bool $force = false): bool;
1415

1516
/**
1617
* @return int

src/Traits/CanBePaid.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,47 @@ trait CanBePaid
1616

1717
/**
1818
* @param Product $product
19+
* @param bool $force
1920
* @return Transfer
2021
* @throws
2122
*/
22-
public function pay(Product $product): Transfer
23+
public function pay(Product $product, bool $force = false): Transfer
2324
{
24-
if (!$product->canBuy($this)) {
25+
if (!$product->canBuy($this, $force)) {
2526
throw new ProductEnded('The product is out of stock');
2627
}
2728

29+
if ($force) {
30+
return $this->forceTransfer($product, $product->getAmountProduct(), $product->getMetaProduct());
31+
}
32+
2833
return $this->transfer($product, $product->getAmountProduct(), $product->getMetaProduct());
2934
}
3035

3136
/**
3237
* @param Product $product
38+
* @param bool $force
3339
* @return Transfer|null
3440
*/
35-
public function safePay(Product $product): ?Transfer
41+
public function safePay(Product $product, bool $force = false): ?Transfer
3642
{
3743
try {
38-
return $this->pay($product);
44+
return $this->pay($product, $force);
3945
} catch (\Throwable $throwable) {
4046
return null;
4147
}
4248
}
4349

50+
/**
51+
* @param Product $product
52+
* @return Transfer
53+
* @throws
54+
*/
55+
public function forcePay(Product $product): Transfer
56+
{
57+
return $this->pay($product, true);
58+
}
59+
4460
/**
4561
* @param Product $product
4662
* @return null|Transfer
@@ -101,6 +117,7 @@ public function safeRefund(Product $product, bool $force = false): bool
101117
/**
102118
* @param Product $product
103119
* @return bool
120+
* @throws
104121
*/
105122
public function forceRefund(Product $product): bool
106123
{

tests/Models/Item.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,19 @@ class Item extends Model implements Product
2727

2828
/**
2929
* @param Customer $customer
30+
* @param bool $force
3031
*
3132
* @return bool
3233
*/
33-
public function canBuy(Customer $customer): bool
34+
public function canBuy(Customer $customer, bool $force = false): bool
3435
{
35-
return $this->quantity > 0 && !$customer->paid($this);
36+
$result = $this->quantity > 0;
37+
38+
if ($force) {
39+
return $result;
40+
}
41+
42+
return $result && !$customer->paid($this);
3643
}
3744

3845
/**

tests/ProductTest.php

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

33
namespace Bavix\Wallet\Test;
44

5+
use Bavix\Wallet\Models\Transaction;
56
use Bavix\Wallet\Test\Models\Buyer;
67
use Bavix\Wallet\Test\Models\Item;
78

@@ -13,6 +14,10 @@ class ProductTest extends TestCase
1314
*/
1415
public function testPay(): void
1516
{
17+
/**
18+
* @var Buyer $buyer
19+
* @var Item $product
20+
*/
1621
$buyer = factory(Buyer::class)->create();
1722
$product = factory(Item::class)->create([
1823
'quantity' => 1,
@@ -22,7 +27,30 @@ public function testPay(): void
2227
$buyer->deposit($product->price);
2328

2429
$this->assertEquals($buyer->balance, $product->price);
25-
$this->assertNotNull($buyer->pay($product));
30+
$transfer = $buyer->pay($product);
31+
$this->assertNotNull($transfer);
32+
33+
/**
34+
* @var Transaction $withdraw
35+
* @var Transaction $deposit
36+
*/
37+
$withdraw = $transfer->withdraw;
38+
$deposit = $transfer->deposit;
39+
40+
$this->assertInstanceOf(Transaction::class, $withdraw);
41+
$this->assertInstanceOf(Transaction::class, $deposit);
42+
43+
$this->assertInstanceOf(Buyer::class, $withdraw->payable);
44+
$this->assertInstanceOf(Item::class, $deposit->payable);
45+
46+
$this->assertEquals($buyer->getKey(), $withdraw->payable->getKey());
47+
$this->assertEquals($product->getKey(), $deposit->payable->getKey());
48+
49+
$this->assertInstanceOf(Buyer::class, $transfer->from);
50+
$this->assertInstanceOf(Item::class, $transfer->to);
51+
52+
$this->assertEquals($buyer->getKey(), $transfer->from->getKey());
53+
$this->assertEquals($product->getKey(), $transfer->to->getKey());
2654

2755
$this->assertEquals($buyer->balance, 0);
2856
$this->assertNull($buyer->safePay($product));
@@ -33,6 +61,10 @@ public function testPay(): void
3361
*/
3462
public function testRefund(): void
3563
{
64+
/**
65+
* @var Buyer $buyer
66+
* @var Item $product
67+
*/
3668
$buyer = factory(Buyer::class)->create();
3769
$product = factory(Item::class)->create([
3870
'quantity' => 1,
@@ -115,4 +147,27 @@ public function testOutOfStock(): void
115147
$buyer->pay($product);
116148
}
117149

150+
/**
151+
* @return void
152+
*/
153+
public function testForcePay(): void
154+
{
155+
/**
156+
* @var Buyer $buyer
157+
* @var Item $product
158+
*/
159+
$buyer = factory(Buyer::class)->create();
160+
$product = factory(Item::class)->create([
161+
'quantity' => 1,
162+
]);
163+
164+
$this->assertEquals($buyer->balance, 0);
165+
$buyer->forcePay($product);
166+
167+
$this->assertEquals($buyer->balance, -$product->price);
168+
169+
$buyer->deposit(-$buyer->balance);
170+
$this->assertEquals($buyer->balance, 0);
171+
}
172+
118173
}

0 commit comments

Comments
 (0)