Skip to content

Commit

Permalink
Merge pull request #13 from bavix/dev
Browse files Browse the repository at this point in the history
add force method's
  • Loading branch information
rez1dent3 authored Nov 10, 2018
2 parents 2a11a16 + e385973 commit 9edf842
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 19 deletions.
25 changes: 21 additions & 4 deletions src/Interfaces/Customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,26 @@ interface Customer extends Wallet

/**
* @param Product $product
* @param bool $force
* @return Transfer
* @throws
*/
public function pay(Product $product): Transfer;
public function pay(Product $product, bool $force = false): Transfer;

/**
* @param Product $product
* @param bool $force
* @return null|Transfer
* @throws
*/
public function safePay(Product $product): ?Transfer;
public function safePay(Product $product, bool $force = false): ?Transfer;

/**
* @param Product $product
* @return Transfer
* @throws
*/
public function forcePay(Product $product): Transfer;

/**
* @param Product $product
Expand All @@ -29,15 +38,23 @@ public function paid(Product $product): ?Transfer;

/**
* @param Product $product
* @param bool $force
* @return bool
* @throws
*/
public function refund(Product $product): bool;
public function refund(Product $product, bool $force = false): bool;

/**
* @param Product $product
* @param bool $force
* @return bool
*/
public function safeRefund(Product $product, bool $force = false): bool;

/**
* @param Product $product
* @return bool
*/
public function safeRefund(Product $product): bool;
public function forceRefund(Product $product): bool;

}
3 changes: 2 additions & 1 deletion src/Interfaces/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ interface Product extends Wallet

/**
* @param Customer $customer
* @param bool $force
*
* @return bool
*/
public function canBuy(Customer $customer): bool;
public function canBuy(Customer $customer, bool $force = false): bool;

/**
* @return int
Expand Down
51 changes: 42 additions & 9 deletions src/Traits/CanBePaid.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,47 @@ trait CanBePaid

/**
* @param Product $product
* @param bool $force
* @return Transfer
* @throws
*/
public function pay(Product $product): Transfer
public function pay(Product $product, bool $force = false): Transfer
{
if (!$product->canBuy($this)) {
if (!$product->canBuy($this, $force)) {
throw new ProductEnded('The product is out of stock');
}

if ($force) {
return $this->forceTransfer($product, $product->getAmountProduct(), $product->getMetaProduct());
}

return $this->transfer($product, $product->getAmountProduct(), $product->getMetaProduct());
}

/**
* @param Product $product
* @param bool $force
* @return Transfer|null
*/
public function safePay(Product $product): ?Transfer
public function safePay(Product $product, bool $force = false): ?Transfer
{
try {
return $this->pay($product);
return $this->pay($product, $force);
} catch (\Throwable $throwable) {
return null;
}
}

/**
* @param Product $product
* @return Transfer
* @throws
*/
public function forcePay(Product $product): Transfer
{
return $this->pay($product, true);
}

/**
* @param Product $product
* @return null|Transfer
Expand All @@ -60,10 +76,11 @@ public function paid(Product $product): ?Transfer

/**
* @param Product $product
* @param bool $force
* @return bool
* @throws
*/
public function refund(Product $product): bool
public function refund(Product $product, bool $force = false): bool
{
$transfer = $this->paid($product);

Expand All @@ -72,23 +89,39 @@ public function refund(Product $product): bool
->setModel($this->transfers()->getMorphClass());
}

return DB::transaction(function() use ($product, $transfer) {
$product->transfer($this, $product->getAmountProduct(), $product->getMetaProduct());
return DB::transaction(function() use ($product, $transfer, $force) {
if ($force) {
$product->forceTransfer($this, $product->getAmountProduct(), $product->getMetaProduct());
} else {
$product->transfer($this, $product->getAmountProduct(), $product->getMetaProduct());
}

return $transfer->update(['refund' => 1]);
});
}

/**
* @param Product $product
* @param bool $force
* @return bool
*/
public function safeRefund(Product $product): bool
public function safeRefund(Product $product, bool $force = false): bool
{
try {
return $this->refund($product);
return $this->refund($product, $force);
} catch (\Throwable $throwable) {
return false;
}
}

/**
* @param Product $product
* @return bool
* @throws
*/
public function forceRefund(Product $product): bool
{
return $this->refund($product, true);
}

}
7 changes: 5 additions & 2 deletions src/Traits/HasWallet.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,11 @@ protected function assemble(Wallet $wallet, Transaction $withdraw, Transaction $
*/
protected function change(int $amount, ?array $meta, bool $confirmed): Transaction
{
$this->getBalanceAttribute();
static::$cachedBalances[$this->getKey()] += $amount;
if ($confirmed) {
$this->getBalanceAttribute();
static::$cachedBalances[$this->getKey()] += $amount;
}

return $this->transactions()->create([
'type' => $amount > 0 ? 'deposit' : 'withdraw',
'payable_type' => $this->getMorphClass(),
Expand Down
11 changes: 9 additions & 2 deletions tests/Models/Item.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,19 @@ class Item extends Model implements Product

/**
* @param Customer $customer
* @param bool $force
*
* @return bool
*/
public function canBuy(Customer $customer): bool
public function canBuy(Customer $customer, bool $force = false): bool
{
return $this->quantity > 0 && !$customer->paid($this);
$result = $this->quantity > 0;

if ($force) {
return $result;
}

return $result && !$customer->paid($this);
}

/**
Expand Down
118 changes: 117 additions & 1 deletion tests/ProductTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Bavix\Wallet\Test;

use Bavix\Wallet\Models\Transaction;
use Bavix\Wallet\Test\Models\Buyer;
use Bavix\Wallet\Test\Models\Item;

Expand All @@ -13,6 +14,10 @@ class ProductTest extends TestCase
*/
public function testPay(): void
{
/**
* @var Buyer $buyer
* @var Item $product
*/
$buyer = factory(Buyer::class)->create();
$product = factory(Item::class)->create([
'quantity' => 1,
Expand All @@ -22,7 +27,30 @@ public function testPay(): void
$buyer->deposit($product->price);

$this->assertEquals($buyer->balance, $product->price);
$this->assertNotNull($buyer->pay($product));
$transfer = $buyer->pay($product);
$this->assertNotNull($transfer);

/**
* @var Transaction $withdraw
* @var Transaction $deposit
*/
$withdraw = $transfer->withdraw;
$deposit = $transfer->deposit;

$this->assertInstanceOf(Transaction::class, $withdraw);
$this->assertInstanceOf(Transaction::class, $deposit);

$this->assertInstanceOf(Buyer::class, $withdraw->payable);
$this->assertInstanceOf(Item::class, $deposit->payable);

$this->assertEquals($buyer->getKey(), $withdraw->payable->getKey());
$this->assertEquals($product->getKey(), $deposit->payable->getKey());

$this->assertInstanceOf(Buyer::class, $transfer->from);
$this->assertInstanceOf(Item::class, $transfer->to);

$this->assertEquals($buyer->getKey(), $transfer->from->getKey());
$this->assertEquals($product->getKey(), $transfer->to->getKey());

$this->assertEquals($buyer->balance, 0);
$this->assertNull($buyer->safePay($product));
Expand All @@ -33,6 +61,10 @@ public function testPay(): void
*/
public function testRefund(): void
{
/**
* @var Buyer $buyer
* @var Item $product
*/
$buyer = factory(Buyer::class)->create();
$product = factory(Item::class)->create([
'quantity' => 1,
Expand All @@ -54,4 +86,88 @@ public function testRefund(): void
$this->assertEquals($buyer->balance, 0);
}

/**
* @return void
*/
public function testForceRefund(): void
{
/**
* @var Buyer $buyer
* @var Item $product
*/
$buyer = factory(Buyer::class)->create();
$product = factory(Item::class)->create([
'quantity' => 1,
]);

$this->assertNotEquals($product->balance, 0);
$product->withdraw($product->balance);

$this->assertEquals($buyer->balance, 0);
$buyer->deposit($product->price);

$this->assertEquals($buyer->balance, $product->price);

$buyer->pay($product);
$this->assertEquals($buyer->balance, 0);
$this->assertEquals($product->balance, $product->price);

$product->withdraw($product->balance);
$this->assertEquals($product->balance, 0);

$this->assertFalse($buyer->safeRefund($product));
$this->assertTrue($buyer->forceRefund($product));

$this->assertEquals($product->balance, -$product->price);
$this->assertEquals($buyer->balance, $product->price);
$product->deposit(-$product->balance);
$buyer->withdraw($buyer->balance);

$this->assertEquals($product->balance, 0);
$this->assertEquals($buyer->balance, 0);
}

/**
* @return void
* @expectedException \Bavix\Wallet\Exceptions\ProductEnded
*/
public function testOutOfStock(): void
{
/**
* @var Buyer $buyer
* @var Item $product
*/
$buyer = factory(Buyer::class)->create();
$product = factory(Item::class)->create([
'quantity' => 1,
]);

$buyer->deposit($product->price);
$buyer->pay($product);
$buyer->pay($product);
}

/**
* @return void
*/
public function testForcePay(): void
{
/**
* @var Buyer $buyer
* @var Item $product
*/
$buyer = factory(Buyer::class)->create();
$product = factory(Item::class)->create([
'quantity' => 1,
]);

$this->assertEquals($buyer->balance, 0);
$buyer->forcePay($product);

$this->assertEquals($buyer->balance, -$product->price);

$buyer->deposit(-$buyer->balance);
$this->assertEquals($buyer->balance, 0);
}

}
Loading

0 comments on commit 9edf842

Please sign in to comment.