Completed
Pull Request — master (#13)
by Бабичев
02:04
created

CanBePaid   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 96
ccs 31
cts 31
cp 1
rs 10
c 0
b 0
f 0
wmc 11

6 Methods

Rating   Name   Duplication   Size   Complexity  
A paid() 0 11 1
A pay() 0 7 2
A safePay() 0 6 2
A refund() 0 17 3
A forceRefund() 0 3 1
A safeRefund() 0 6 2
1
<?php
2
3
namespace Bavix\Wallet\Traits;
4
5
use Bavix\Wallet\Exceptions\ProductEnded;
6
use Bavix\Wallet\Interfaces\Product;
7
use Bavix\Wallet\Models\Transfer;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Database\Eloquent\ModelNotFoundException;
10
use Illuminate\Support\Facades\DB;
11
12
trait CanBePaid
13
{
14
15
    use HasWallet;
16
17
    /**
18
     * @param Product $product
19
     * @return Transfer
20
     * @throws
21
     */
22 3
    public function pay(Product $product): Transfer
23
    {
24 3
        if (!$product->canBuy($this)) {
0 ignored issues
show
Bug introduced by
$this of type Bavix\Wallet\Traits\CanBePaid is incompatible with the type Bavix\Wallet\Interfaces\Customer expected by parameter $customer of Bavix\Wallet\Interfaces\Product::canBuy(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

24
        if (!$product->canBuy(/** @scrutinizer ignore-type */ $this)) {
Loading history...
25 1
            throw new ProductEnded('The product is out of stock');
26
        }
27
28 3
        return $this->transfer($product, $product->getAmountProduct(), $product->getMetaProduct());
29
    }
30
31
    /**
32
     * @param Product $product
33
     * @return Transfer|null
34
     */
35 1
    public function safePay(Product $product): ?Transfer
36
    {
37
        try {
38 1
            return $this->pay($product);
39 1
        } catch (\Throwable $throwable) {
40 1
            return null;
41
        }
42
    }
43
44
    /**
45
     * @param Product $product
46
     * @return null|Transfer
47
     */
48 3
    public function paid(Product $product): ?Transfer
49
    {
50
        /**
51
         * @var Model $product
52
         */
53 3
        return $this->transfers()
54 3
            ->where('to_type', $product->getMorphClass())
55 3
            ->where('to_id', $product->getKey())
56 3
            ->where('refund', 0)
57 3
            ->orderBy('id', 'desc')
58 3
            ->first();
59
    }
60
61
    /**
62
     * @param Product $product
63
     * @param bool $force
64
     * @return bool
65
     * @throws
66
     */
67 2
    public function refund(Product $product, bool $force = false): bool
68
    {
69 2
        $transfer = $this->paid($product);
70
71 2
        if (!$transfer) {
72 1
            throw (new ModelNotFoundException())
73 1
                ->setModel($this->transfers()->getMorphClass());
74
        }
75
76
        return DB::transaction(function() use ($product, $transfer, $force) {
77 2
            if ($force) {
78 1
                $product->forceTransfer($this, $product->getAmountProduct(), $product->getMetaProduct());
0 ignored issues
show
Bug introduced by
$this of type Bavix\Wallet\Traits\CanBePaid is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $wallet of Bavix\Wallet\Interfaces\Wallet::forceTransfer(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

78
                $product->forceTransfer(/** @scrutinizer ignore-type */ $this, $product->getAmountProduct(), $product->getMetaProduct());
Loading history...
79
            } else {
80 2
                $product->transfer($this, $product->getAmountProduct(), $product->getMetaProduct());
0 ignored issues
show
Bug introduced by
$this of type Bavix\Wallet\Traits\CanBePaid is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $wallet of Bavix\Wallet\Interfaces\Wallet::transfer(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

80
                $product->transfer(/** @scrutinizer ignore-type */ $this, $product->getAmountProduct(), $product->getMetaProduct());
Loading history...
81
            }
82
83 2
            return $transfer->update(['refund' => 1]);
84 2
        });
85
    }
86
87
    /**
88
     * @param Product $product
89
     * @param bool $force
90
     * @return bool
91
     */
92 2
    public function safeRefund(Product $product, bool $force = false): bool
93
    {
94
        try {
95 2
            return $this->refund($product, $force);
96 2
        } catch (\Throwable $throwable) {
97 2
            return false;
98
        }
99
    }
100
101
    /**
102
     * @param Product $product
103
     * @return bool
104
     */
105 1
    public function forceRefund(Product $product): bool
106
    {
107 1
        return $this->refund($product, true);
108
    }
109
110
}
111