Completed
Pull Request — master (#40)
by Бабичев
08:10
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 9
    public function payCart(Cart $cart, bool $force = null): array
70
    {
71 9
        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 9
            $results = [];
78 9
            foreach ($cart->getItems() as $product) {
79 9
                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 8
                $results[] = app(CommonService::class)->transfer(
92 8
                    $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 8
                    $product,
94 8
                    $product->getAmountProduct(),
95 8
                    $product->getMetaProduct(),
96 8
                    Transfer::STATUS_PAID
97
                );
98
            }
99
100 9
            return $results;
101
102 9
        });
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 8
    public function refundCart(Cart $cart, bool $force = null, bool $gifts = null): bool
138
    {
139
        return DB::transaction(function () use ($cart, $force, $gifts) {
140
141 8
            $results = [];
142 8
            $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 8
            if (count($transfers) !== count($cart)) {
144 3
                throw (new ModelNotFoundException())
145 3
                    ->setModel($this->transfers()->getMorphClass());
146
            }
147
148 7
            foreach ($cart->getItems() as $key => $product) {
149 7
                $transfer = $transfers[$key];
150 7
                $transfer->load('withdraw.wallet');
151
152 7
                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 7
                    app(CommonService::class)->transfer(
161 7
                        $product,
162 7
                        $transfer->withdraw->wallet,
163 7
                        $transfer->deposit->amount,
164 7
                        $product->getMetaProduct()
165
                    );
166
                }
167
168 7
                $results[] = $transfer->update([
169 7
                    'status' => Transfer::STATUS_REFUND,
170 7
                    'status_last' => $transfer->status,
171
                ]);
172
            }
173
174 7
            return count(array_unique($results)) === 1;
175
176 8
        });
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
     * Checks acquired product your wallet.
227
     *
228
     * @param Product $product
229
     * @param bool $gifts
230
     * @return null|Transfer
231
     */
232 12
    public function paid(Product $product, bool $gifts = null): ?Transfer
233
    {
234 12
        $status = [Transfer::STATUS_PAID];
235 12
        if ($gifts) {
236 2
            $status[] = Transfer::STATUS_GIFT;
237
        }
238
239
        /**
240
         * @var Model $product
241
         * @var Transfer $query
242
         */
243 12
        $query = $this->transfers();
244
        return $query
245 12
            ->where('to_type', $product->getMorphClass())
246 12
            ->where('to_id', $product->getKey())
247 12
            ->whereIn('status', $status)
248 12
            ->orderBy('id', 'desc')
249 12
            ->first();
250
    }
251
252
}
253