Completed
Pull Request — master (#40)
by Бабичев
06:05
created

CartPay::safeRefundCart()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 3
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
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\Model;
11
use Illuminate\Database\Eloquent\ModelNotFoundException;
12
use Illuminate\Support\Facades\DB;
13
use Throwable;
14
use function array_unique;
15
use function count;
16
17
trait CartPay
18
{
19
20
    use HasWallet;
21
22
    /**
23
     * @param Cart $cart
24
     * @return Transfer[]
25
     * @throws
26
     */
27 2
    public function payFreeCart(Cart $cart): array
28
    {
29 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

29
        if (!$cart->canBuy(/** @scrutinizer ignore-type */ $this)) {
Loading history...
30 1
            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

30
            throw new ProductEnded(/** @scrutinizer ignore-type */ trans('wallet::errors.product_stock'));
Loading history...
31
        }
32
33
        return DB::transaction(function () use ($cart) {
34 2
            $results = [];
35 2
            foreach ($cart->getItems() as $product) {
36 2
                $results[] = app(CommonService::class)->transfer(
37 2
                    $this,
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 $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

37
                    /** @scrutinizer ignore-type */ $this,
Loading history...
38 2
                    $product,
39 2
                    0,
40 2
                    $product->getMetaProduct(),
41 2
                    Transfer::STATUS_PAID
42
                );
43
            }
44
45 2
            return $results;
46 2
        });
47
    }
48
49
    /**
50
     * @param Cart $cart
51
     * @param bool $force
52
     * @return Transfer[]
53
     */
54 1
    public function safePayCart(Cart $cart, bool $force = null): array
55
    {
56
        try {
57 1
            return $this->payCart($cart, $force);
58 1
        } catch (Throwable $throwable) {
59 1
            return [];
60
        }
61
    }
62
63
    /**
64
     * @param Cart $cart
65
     * @param bool $force
66
     * @return Transfer[]
67
     * @throws
68
     */
69 8
    public function payCart(Cart $cart, bool $force = null): array
70
    {
71 8
        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

71
        if (!$cart->canBuy(/** @scrutinizer ignore-type */ $this, $force)) {
Loading history...
72 2
            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

72
            throw new ProductEnded(/** @scrutinizer ignore-type */ trans('wallet::errors.product_stock'));
Loading history...
73
        }
74
75
        return DB::transaction(function () use ($cart, $force) {
76
77 8
            $results = [];
78 8
            foreach ($cart->getItems() as $product) {
79 8
                if ($force) {
80 1
                    $results[] = app(CommonService::class)->forceTransfer(
81 1
                        $this,
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 $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

81
                        /** @scrutinizer ignore-type */ $this,
Loading history...
82 1
                        $product,
83 1
                        $product->getAmountProduct(),
84 1
                        $product->getMetaProduct(),
85 1
                        Transfer::STATUS_PAID
86
                    );
87
88 1
                    continue;
89
                }
90
91 7
                $results[] = app(CommonService::class)->transfer(
92 7
                    $this,
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 $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

92
                    /** @scrutinizer ignore-type */ $this,
Loading history...
93 7
                    $product,
94 7
                    $product->getAmountProduct(),
95 7
                    $product->getMetaProduct(),
96 7
                    Transfer::STATUS_PAID
97
                );
98
            }
99
100 8
            return $results;
101
102 8
        });
103
    }
104
105
    /**
106
     * @param Cart $cart
107
     * @return Transfer[]
108
     * @throws
109
     */
110 1
    public function forcePayCart(Cart $cart): array
111
    {
112 1
        return $this->payCart($cart, true);
113
    }
114
115
    /**
116
     * @param Cart $cart
117
     * @param bool $force
118
     * @param bool $gifts
119
     * @return bool
120
     */
121 3
    public function safeRefundCart(Cart $cart, bool $force = null, bool $gifts = null): bool
122
    {
123
        try {
124 3
            return $this->refundCart($cart, $force, $gifts);
125 3
        } catch (Throwable $throwable) {
126 3
            return false;
127
        }
128
    }
129
130
    /**
131
     * @param Cart $cart
132
     * @param bool $force
133
     * @param bool $gifts
134
     * @return bool
135
     * @throws
136
     */
137 7
    public function refundCart(Cart $cart, bool $force = null, bool $gifts = null): bool
138
    {
139
        return DB::transaction(function () use ($cart, $force, $gifts) {
140
141 7
            $results = [];
142 7
            $transfers = $cart->alreadyBuy($this, $gifts);
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

142
            $transfers = $cart->alreadyBuy(/** @scrutinizer ignore-type */ $this, $gifts);
Loading history...
143 7
            foreach ($transfers as $transfer) {
144 7
                if (!$transfer) {
145 2
                    throw (new ModelNotFoundException())
146 7
                        ->setModel($this->transfers()->getMorphClass());
147
                }
148
            }
149
150 7
            foreach ($cart->getItems() as $key => $product) {
151 7
                $transfer = $transfers[$key];
152 7
                $transfer->load('withdraw.wallet');
153
154 7
                if ($force) {
155 2
                    app(CommonService::class)->forceTransfer(
156 2
                        $product,
157 2
                        $transfer->withdraw->wallet,
158 2
                        $transfer->deposit->amount,
159 2
                        $product->getMetaProduct()
160
                    );
161
                } else {
162 7
                    app(CommonService::class)->transfer(
163 7
                        $product,
164 7
                        $transfer->withdraw->wallet,
165 7
                        $transfer->deposit->amount,
166 7
                        $product->getMetaProduct()
167
                    );
168
                }
169
170 7
                $results[] = $transfer->update([
171 7
                    'status' => Transfer::STATUS_REFUND,
172 7
                    'status_last' => $transfer->status,
173
                ]);
174
            }
175
176 7
            return count(array_unique($results)) === 1;
177
178 7
        });
179
    }
180
181
    /**
182
     * @param Cart $cart
183
     * @param bool $gifts
184
     * @return bool
185
     * @throws
186
     */
187 1
    public function forceRefundCart(Cart $cart, bool $gifts = null): bool
188
    {
189 1
        return $this->refundCart($cart, true, $gifts);
190
    }
191
192
    /**
193
     * @param Cart $cart
194
     * @param bool $force
195
     * @return bool
196
     */
197 1
    public function safeRefundGiftCart(Cart $cart, bool $force = null): bool
198
    {
199
        try {
200 1
            return $this->refundGiftCart($cart, $force);
201 1
        } catch (Throwable $throwable) {
202 1
            return false;
203
        }
204
    }
205
206
    /**
207
     * @param Cart $cart
208
     * @param bool $force
209
     * @return bool
210
     * @throws
211
     */
212 1
    public function refundGiftCart(Cart $cart, bool $force = null): bool
213
    {
214 1
        return $this->refundCart($cart, $force, true);
215
    }
216
217
    /**
218
     * @param Cart $cart
219
     * @return bool
220
     * @throws
221
     */
222 1
    public function forceRefundGiftCart(Cart $cart): bool
223
    {
224 1
        return $this->refundGiftCart($cart, true);
225
    }
226
227
    /**
228
     * Checks acquired product your wallet.
229
     *
230
     * @param Product $product
231
     * @param bool $gifts
232
     * @return null|Transfer
233
     */
234 11
    public function paid(Product $product, bool $gifts = null): ?Transfer
235
    {
236 11
        $status = [Transfer::STATUS_PAID];
237 11
        if ($gifts) {
238 2
            $status[] = Transfer::STATUS_GIFT;
239
        }
240
241
        /**
242
         * @var Model $product
243
         * @var Transfer $query
244
         */
245 11
        $query = $this->transfers();
246
        return $query
247 11
            ->where('to_type', $product->getMorphClass())
248 11
            ->where('to_id', $product->getKey())
249 11
            ->whereIn('status', $status)
250 11
            ->orderBy('id', 'desc')
251 11
            ->first();
252
    }
253
254
}
255