Test Failed
Pull Request — master (#83)
by Бабичев
13:48 queued 09:03
created

CartPay   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 217
Duplicated Lines 0 %

Test Coverage

Coverage 36.9%

Importance

Changes 4
Bugs 1 Features 1
Metric Value
eloc 76
c 4
b 1
f 1
dl 0
loc 217
ccs 31
cts 84
cp 0.369
rs 10
wmc 23

11 Methods

Rating   Name   Duplication   Size   Complexity  
A forcePayCart() 0 3 1
A paid() 0 3 2
A safeRefundCart() 0 6 2
A safeRefundGiftCart() 0 6 2
A refundCart() 0 36 4
A forceRefundCart() 0 3 1
A forceRefundGiftCart() 0 3 1
A safePayCart() 0 6 2
A payFreeCart() 0 23 3
A refundGiftCart() 0 3 1
A payCart() 0 32 4
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 Bavix\Wallet\Objects\Cart;
9
use Bavix\Wallet\Services\CommonService;
10
use Illuminate\Database\Eloquent\ModelNotFoundException;
11
use Illuminate\Support\Facades\DB;
12
use Throwable;
13
use function array_unique;
14
use function count;
15
16
trait CartPay
17
{
18
    use HasWallet;
19
20
    /**
21
     * @param Cart $cart
22
     * @return Transfer[]
23
     * @throws
24
     */
25 2
    public function payFreeCart(Cart $cart): array
26
    {
27 2
        if (!$cart->canBuy($this)) {
0 ignored issues
show
Bug introduced by
$this of type Bavix\Wallet\Traits\CartPay is incompatible with the type Bavix\Wallet\Interfaces\Customer expected by parameter $customer of Bavix\Wallet\Objects\Cart::canBuy(). ( Ignorable by Annotation )

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

27
        if (!$cart->canBuy(/** @scrutinizer ignore-type */ $this)) {
Loading history...
28
            throw new ProductEnded(trans('wallet::errors.product_stock'));
0 ignored issues
show
Bug introduced by
It seems like trans('wallet::errors.product_stock') can also be of type array; however, parameter $message of Bavix\Wallet\Exceptions\...uctEnded::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

28
            throw new ProductEnded(/** @scrutinizer ignore-type */ trans('wallet::errors.product_stock'));
Loading history...
29
        }
30
31 2
        app(CommonService::class)
32 2
            ->verifyWithdraw($this, 0, true);
0 ignored issues
show
Bug introduced by
$this of type Bavix\Wallet\Traits\CartPay is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $wallet of Bavix\Wallet\Services\Co...rvice::verifyWithdraw(). ( Ignorable by Annotation )

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

32
            ->verifyWithdraw(/** @scrutinizer ignore-type */ $this, 0, true);
Loading history...
33
34 2
        $self = $this;
35
        return DB::transaction(static function() use ($self, $cart) {
36 2
            $results = [];
37 2
            foreach ($cart->getItems() as $product) {
38 2
                $results[] = app(CommonService::class)->forceTransfer(
39 2
                    $self,
0 ignored issues
show
Bug introduced by
$self of type Bavix\Wallet\Traits\HasWallet is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $from of Bavix\Wallet\Services\Co...ervice::forceTransfer(). ( Ignorable by Annotation )

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

39
                    /** @scrutinizer ignore-type */ $self,
Loading history...
40 2
                    $product,
41 2
                    0,
42 2
                    $product->getMetaProduct(),
43 2
                    Transfer::STATUS_PAID
44
                );
45
            }
46
47
            return $results;
48 2
        });
49
    }
50
51
    /**
52
     * @param Cart $cart
53
     * @param bool $force
54
     * @return Transfer[]
55
     */
56
    public function safePayCart(Cart $cart, bool $force = null): array
57
    {
58
        try {
59
            return $this->payCart($cart, $force);
60
        } catch (Throwable $throwable) {
61
            return [];
62
        }
63
    }
64
65
    /**
66
     * @param Cart $cart
67
     * @param bool $force
68
     * @return Transfer[]
69
     * @throws
70
     */
71 1
    public function payCart(Cart $cart, bool $force = null): array
72
    {
73 1
        if (!$cart->canBuy($this, $force)) {
0 ignored issues
show
Bug introduced by
$this of type Bavix\Wallet\Traits\CartPay is incompatible with the type Bavix\Wallet\Interfaces\Customer expected by parameter $customer of Bavix\Wallet\Objects\Cart::canBuy(). ( Ignorable by Annotation )

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

73
        if (!$cart->canBuy(/** @scrutinizer ignore-type */ $this, $force)) {
Loading history...
74
            throw new ProductEnded(trans('wallet::errors.product_stock'));
0 ignored issues
show
Bug introduced by
It seems like trans('wallet::errors.product_stock') can also be of type array; however, parameter $message of Bavix\Wallet\Exceptions\...uctEnded::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

74
            throw new ProductEnded(/** @scrutinizer ignore-type */ trans('wallet::errors.product_stock'));
Loading history...
75
        }
76
77 1
        $self = $this;
78
        return DB::transaction(static function() use ($self, $cart, $force) {
79 1
            $results = [];
80 1
            foreach ($cart->getItems() as $product) {
81 1
                if ($force) {
82 1
                    $results[] = app(CommonService::class)->forceTransfer(
83 1
                        $self,
0 ignored issues
show
Bug introduced by
$self of type Bavix\Wallet\Traits\CartPay is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $from of Bavix\Wallet\Services\Co...ervice::forceTransfer(). ( Ignorable by Annotation )

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

83
                        /** @scrutinizer ignore-type */ $self,
Loading history...
84 1
                        $product,
85 1
                        $product->getAmountProduct(),
86 1
                        $product->getMetaProduct(),
87 1
                        Transfer::STATUS_PAID
88
                    );
89
90
                    continue;
91
                }
92
93
                $results[] = app(CommonService::class)->transfer(
94
                    $self,
0 ignored issues
show
Bug introduced by
$self of type Bavix\Wallet\Traits\CartPay is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $from of Bavix\Wallet\Services\CommonService::transfer(). ( Ignorable by Annotation )

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

94
                    /** @scrutinizer ignore-type */ $self,
Loading history...
95
                    $product,
96
                    $product->getAmountProduct(),
97
                    $product->getMetaProduct(),
98
                    Transfer::STATUS_PAID
99
                );
100
            }
101
102
            return $results;
103 1
        });
104
    }
105
106
    /**
107
     * @param Cart $cart
108
     * @return Transfer[]
109
     * @throws
110
     */
111 1
    public function forcePayCart(Cart $cart): array
112
    {
113 1
        return $this->payCart($cart, true);
114
    }
115
116
    /**
117
     * @param Cart $cart
118
     * @param bool $force
119
     * @param bool $gifts
120
     * @return bool
121
     */
122
    public function safeRefundCart(Cart $cart, bool $force = null, bool $gifts = null): bool
123
    {
124
        try {
125
            return $this->refundCart($cart, $force, $gifts);
126
        } catch (Throwable $throwable) {
127
            return false;
128
        }
129
    }
130
131
    /**
132
     * @param Cart $cart
133
     * @param bool $force
134
     * @param bool $gifts
135
     * @return bool
136
     * @throws
137
     */
138
    public function refundCart(Cart $cart, bool $force = null, bool $gifts = null): bool
139
    {
140
        $self = $this;
141
        return DB::transaction(static function() use ($self, $cart, $force, $gifts) {
142
            $results = [];
143
            $transfers = $cart->alreadyBuy($self, $gifts);
0 ignored issues
show
Bug introduced by
$self of type Bavix\Wallet\Traits\CartPay is incompatible with the type Bavix\Wallet\Interfaces\Customer expected by parameter $customer of Bavix\Wallet\Objects\Cart::alreadyBuy(). ( Ignorable by Annotation )

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

143
            $transfers = $cart->alreadyBuy(/** @scrutinizer ignore-type */ $self, $gifts);
Loading history...
144
            if (count($transfers) !== count($cart)) {
145
                throw (new ModelNotFoundException())
146
                    ->setModel($self->transfers()->getMorphClass());
147
            }
148
149
            foreach ($cart->getItems() as $key => $product) {
150
                $transfer = $transfers[$key];
151
                $transfer->load('withdraw.wallet');
152
153
                if (!$force) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $force of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
154
                    app(CommonService::class)->verifyWithdraw(
155
                        $product,
156
                        $transfer->deposit->amount
157
                    );
158
                }
159
160
                app(CommonService::class)->forceTransfer(
161
                    $product,
0 ignored issues
show
Bug introduced by
$product of type Bavix\Wallet\Traits\HasWallet is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $from of Bavix\Wallet\Services\Co...ervice::forceTransfer(). ( Ignorable by Annotation )

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

161
                    /** @scrutinizer ignore-type */ $product,
Loading history...
162
                    $transfer->withdraw->wallet,
163
                    $transfer->deposit->amount,
164
                    $product->getMetaProduct()
0 ignored issues
show
Bug introduced by
It seems like getMetaProduct() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

164
                    $product->/** @scrutinizer ignore-call */ 
165
                              getMetaProduct()
Loading history...
165
                );
166
167
                $results[] = $transfer->update([
168
                    'status' => Transfer::STATUS_REFUND,
169
                    'status_last' => $transfer->status,
170
                ]);
171
            }
172
173
            return count(array_unique($results)) === 1;
174
        });
175
    }
176
177
    /**
178
     * @param Cart $cart
179
     * @param bool $gifts
180
     * @return bool
181
     * @throws
182
     */
183
    public function forceRefundCart(Cart $cart, bool $gifts = null): bool
184
    {
185
        return $this->refundCart($cart, true, $gifts);
186
    }
187
188
    /**
189
     * @param Cart $cart
190
     * @param bool $force
191
     * @return bool
192
     */
193
    public function safeRefundGiftCart(Cart $cart, bool $force = null): bool
194
    {
195
        try {
196
            return $this->refundGiftCart($cart, $force);
197
        } catch (Throwable $throwable) {
198
            return false;
199
        }
200
    }
201
202
    /**
203
     * @param Cart $cart
204
     * @param bool $force
205
     * @return bool
206
     * @throws
207
     */
208
    public function refundGiftCart(Cart $cart, bool $force = null): bool
209
    {
210
        return $this->refundCart($cart, $force, true);
211
    }
212
213
    /**
214
     * @param Cart $cart
215
     * @return bool
216
     * @throws
217
     */
218
    public function forceRefundGiftCart(Cart $cart): bool
219
    {
220
        return $this->refundGiftCart($cart, true);
221
    }
222
223
    /**
224
     * Checks acquired product your wallet.
225
     *
226
     * @param Product $product
227
     * @param bool $gifts
228
     * @return null|Transfer
229
     */
230 2
    public function paid(Product $product, bool $gifts = null): ?Transfer
231
    {
232 2
        return current(Cart::make()->addItem($product)->alreadyBuy($this, $gifts)) ?: null;
0 ignored issues
show
Bug introduced by
$this of type Bavix\Wallet\Traits\CartPay is incompatible with the type Bavix\Wallet\Interfaces\Customer expected by parameter $customer of Bavix\Wallet\Objects\Cart::alreadyBuy(). ( Ignorable by Annotation )

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

232
        return current(Cart::make()->addItem($product)->alreadyBuy(/** @scrutinizer ignore-type */ $this, $gifts)) ?: null;
Loading history...
233
    }
234
235
}
236