Completed
Pull Request — master (#40)
by Бабичев
07:20 queued 01:42
created

CartPay::safeRefundGiftCart()   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 2
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 10
    public function payCart(Cart $cart, bool $force = null): array
70
    {
71 10
        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 10
            $results = [];
78 10
            foreach ($cart->getItems() as $product) {
79 10
                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 9
                $results[] = app(CommonService::class)->transfer(
92 9
                    $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 9
                    $product,
94 9
                    $product->getAmountProduct(),
95 9
                    $product->getMetaProduct(),
96 9
                    Transfer::STATUS_PAID
97
                );
98
            }
99
100 10
            return $results;
101
102 10
        });
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 9
    public function refundCart(Cart $cart, bool $force = null, bool $gifts = null): bool
138
    {
139
        return DB::transaction(function () use ($cart, $force, $gifts) {
140
141 9
            $results = [];
142 9
            $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 9
            if (count($transfers) !== count($cart)) {
144 3
                throw (new ModelNotFoundException())
145 3
                    ->setModel($this->transfers()->getMorphClass());
146
            }
147
148 8
            foreach ($cart->getItems() as $key => $product) {
149 8
                $transfer = $transfers[$key];
150 8
                $transfer->load('withdraw.wallet');
151
152 8
                if ($force) {
153 2
                    app(CommonService::class)->forceTransfer(
154 2
                        $product,
155 2
                        $transfer->withdraw->wallet,
156 2
                        $transfer->deposit->amount,
157 2
                        $product->getMetaProduct()
158
                    );
159
                } else {
160 8
                    app(CommonService::class)->transfer(
161 8
                        $product,
162 8
                        $transfer->withdraw->wallet,
163 8
                        $transfer->deposit->amount,
164 8
                        $product->getMetaProduct()
165
                    );
166
                }
167
168 8
                $results[] = $transfer->update([
169 8
                    'status' => Transfer::STATUS_REFUND,
170 8
                    'status_last' => $transfer->status,
171
                ]);
172
            }
173
174 8
            return count(array_unique($results)) === 1;
175
176 9
        });
177
    }
178
179
    /**
180
     * @param Cart $cart
181
     * @param bool $gifts
182
     * @return bool
183
     * @throws
184
     */
185 1
    public function forceRefundCart(Cart $cart, bool $gifts = null): bool
186
    {
187 1
        return $this->refundCart($cart, true, $gifts);
188
    }
189
190
    /**
191
     * @param Cart $cart
192
     * @param bool $force
193
     * @return bool
194
     */
195 1
    public function safeRefundGiftCart(Cart $cart, bool $force = null): bool
196
    {
197
        try {
198 1
            return $this->refundGiftCart($cart, $force);
199 1
        } catch (Throwable $throwable) {
200 1
            return false;
201
        }
202
    }
203
204
    /**
205
     * @param Cart $cart
206
     * @param bool $force
207
     * @return bool
208
     * @throws
209
     */
210 1
    public function refundGiftCart(Cart $cart, bool $force = null): bool
211
    {
212 1
        return $this->refundCart($cart, $force, true);
213
    }
214
215
    /**
216
     * @param Cart $cart
217
     * @return bool
218
     * @throws
219
     */
220 1
    public function forceRefundGiftCart(Cart $cart): bool
221
    {
222 1
        return $this->refundGiftCart($cart, true);
223
    }
224
225
    /**
226
     * @param Cart $cart
227
     * @param bool $gifts
228
     * @return array
229
     */
230 13
    public function paidCart(Cart $cart, bool $gifts = null): array
231
    {
232 13
        $status = [Transfer::STATUS_PAID];
233 13
        if ($gifts) {
234 2
            $status[] = Transfer::STATUS_GIFT;
235
        }
236
237
        /**
238
         * @var Transfer $query
239
         */
240 13
        $result = [];
241 13
        $query = $this->transfers();
242 13
        foreach ($cart->getUniqueItems() as $product) {
243 13
            $collect = (clone $query)
244 13
                ->where('to_type', $product->getMorphClass())
245 13
                ->where('to_id', $product->getKey())
246 13
                ->whereIn('status', $status)
247 13
                ->orderBy('id', 'desc')
248 13
                ->limit($cart->getQuantity($product))
249 13
                ->get();
250
251 13
            foreach ($collect as $datum) {
252 13
                $result[] = $datum;
253
            }
254
        }
255
256 13
        return $result;
257
    }
258
259
    /**
260
     * Checks acquired product your wallet.
261
     *
262
     * @param Product $product
263
     * @param bool $gifts
264
     * @return null|Transfer
265
     */
266 12
    public function paid(Product $product, bool $gifts = null): ?Transfer
267
    {
268 12
        return current($this->paidCart(Cart::make()->addItem($product), $gifts)) ?: null;
269
    }
270
271
}
272