Completed
Pull Request — master (#14)
by Бабичев
03:18
created

CanBePaid   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Test Coverage

Coverage 89.74%

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 126
ccs 35
cts 39
cp 0.8974
rs 10
c 0
b 0
f 0
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A refund() 0 17 3
A pay() 0 11 3
A forceRefund() 0 3 1
A safeRefund() 0 6 2
A forcePay() 0 3 1
A safePay() 0 6 2
A payFree() 0 7 2
A paid() 0 11 1
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
     */
21
    public function payFree(Product $product): Transfer
22
    {
23
        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

23
        if (!$product->canBuy(/** @scrutinizer ignore-type */ $this)) {
Loading history...
24
            throw new ProductEnded(trans('wallet::errors.product_stock'));
25
        }
26
27
        return $this->transfer($product, 0, $product->getMetaProduct());
28
    }
29
30
    /**
31
     * @param Product $product
32
     * @param bool $force
33
     * @return Transfer
34
     * @throws
35
     */
36 5
    public function pay(Product $product, bool $force = false): Transfer
37
    {
38 5
        if (!$product->canBuy($this, $force)) {
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

38
        if (!$product->canBuy(/** @scrutinizer ignore-type */ $this, $force)) {
Loading history...
39 2
            throw new ProductEnded(trans('wallet::errors.product_stock'));
40
        }
41
42 5
        if ($force) {
43 1
            return $this->forceTransfer($product, $product->getAmountProduct(), $product->getMetaProduct());
44
        }
45
46 4
        return $this->transfer($product, $product->getAmountProduct(), $product->getMetaProduct());
47
    }
48
49
    /**
50
     * @param Product $product
51
     * @param bool $force
52
     * @return Transfer|null
53
     */
54 1
    public function safePay(Product $product, bool $force = false): ?Transfer
55
    {
56
        try {
57 1
            return $this->pay($product, $force);
58 1
        } catch (\Throwable $throwable) {
59 1
            return null;
60
        }
61
    }
62
63
    /**
64
     * @param Product $product
65
     * @return Transfer
66
     * @throws
67
     */
68 1
    public function forcePay(Product $product): Transfer
69
    {
70 1
        return $this->pay($product, true);
71
    }
72
73
    /**
74
     * @param Product $product
75
     * @return null|Transfer
76
     */
77 4
    public function paid(Product $product): ?Transfer
78
    {
79
        /**
80
         * @var Model $product
81
         */
82 4
        return $this->transfers()
83 4
            ->where('to_type', $product->getMorphClass())
84 4
            ->where('to_id', $product->getKey())
85 4
            ->where('refund', 0)
86 4
            ->orderBy('id', 'desc')
87 4
            ->first();
88
    }
89
90
    /**
91
     * @param Product $product
92
     * @param bool $force
93
     * @return bool
94
     * @throws
95
     */
96 2
    public function refund(Product $product, bool $force = false): bool
97
    {
98 2
        $transfer = $this->paid($product);
99
100 2
        if (!$transfer) {
101 1
            throw (new ModelNotFoundException())
102 1
                ->setModel($this->transfers()->getMorphClass());
103
        }
104
105
        return DB::transaction(function() use ($product, $transfer, $force) {
106 2
            if ($force) {
107 1
                $product->forceTransfer($this, $transfer->deposit->amount, $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

107
                $product->forceTransfer(/** @scrutinizer ignore-type */ $this, $transfer->deposit->amount, $product->getMetaProduct());
Loading history...
108
            } else {
109 2
                $product->transfer($this, $transfer->deposit->amount, $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

109
                $product->transfer(/** @scrutinizer ignore-type */ $this, $transfer->deposit->amount, $product->getMetaProduct());
Loading history...
110
            }
111
112 2
            return $transfer->update(['refund' => 1]);
113 2
        });
114
    }
115
116
    /**
117
     * @param Product $product
118
     * @param bool $force
119
     * @return bool
120
     */
121 2
    public function safeRefund(Product $product, bool $force = false): bool
122
    {
123
        try {
124 2
            return $this->refund($product, $force);
125 2
        } catch (\Throwable $throwable) {
126 2
            return false;
127
        }
128
    }
129
130
    /**
131
     * @param Product $product
132
     * @return bool
133
     * @throws
134
     */
135 1
    public function forceRefund(Product $product): bool
136
    {
137 1
        return $this->refund($product, true);
138
    }
139
140
}
141