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

CartPay::paid()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

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

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

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

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

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

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

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

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

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

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