CanPay::refund()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 13
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 24
rs 9.8333
ccs 13
cts 13
cp 1
crap 3
1
<?php
2
3
namespace Moecasts\Laravel\Wallet\Traits;
4
5
use Illuminate\Database\Eloquent\ModelNotFoundException;
6
use Moecasts\Laravel\Wallet\Exceptions\ProductEnded;
7
use Moecasts\Laravel\Wallet\Interfaces\Product;
8
use Moecasts\Laravel\Wallet\Interfaces\Refundable;
9
use Moecasts\Laravel\Wallet\Models\Transfer;
10
11
trait CanPay {
12 7
    public function pay(Product $product, string $action = Transfer::ACTION_PAID, bool $force = false): Transfer
13
    {
14 7
        if (! $product->canBePaid($action)) {
15 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 Moecasts\Laravel\Wallet\...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

15
            throw new ProductEnded(/** @scrutinizer ignore-type */ trans('wallet::errors.product_stock'));
Loading history...
16
        }
17
18 6
        if ($force) {
19 1
            return $this->forceTransfer(
0 ignored issues
show
Bug introduced by
It seems like forceTransfer() 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

19
            return $this->/** @scrutinizer ignore-call */ forceTransfer(
Loading history...
20 1
                $product,
21 1
                $product->getProductAmount($action),
22 1
                $product->getProductMeta($action),
23 1
                $action
24
            );
25
        }
26
27 5
        return $this->transfer(
0 ignored issues
show
Bug introduced by
It seems like transfer() 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

27
        return $this->/** @scrutinizer ignore-call */ transfer(
Loading history...
28 5
            $product,
29 5
            $product->getProductAmount($action),
30 5
            $product->getProductMeta($action),
31 5
            $action
32
        );
33
    }
34
35 1
    public function forcePay(Product $product, string $action = Transfer::ACTION_PAID): Transfer
36
    {
37 1
        return $this->pay($product, $action, true);
38
    }
39
40 1
    public function safePay(Product $product, string $action = Transfer::ACTION_PAID, bool $force = false): ?Transfer
41
    {
42
        try {
43 1
            return $this->pay($product, $action, $force);
44 1
        } catch (\Throwable $throwable) {
45 1
            return null;
46
        }
47
    }
48
49 4
    public function paid(Product $product, string $action = Transfer::ACTION_PAID): ?Transfer
50
    {
51 4
        $action = [$action];
52
53 4
        $query = $this->holderTransfers();
0 ignored issues
show
Bug introduced by
It seems like holderTransfers() 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

53
        /** @scrutinizer ignore-call */ 
54
        $query = $this->holderTransfers();
Loading history...
54
55
        return $query
56 4
            ->where('refund', false)
57 4
            ->where('to_type', $product->getMorphClass())
0 ignored issues
show
Bug introduced by
The method getMorphClass() does not exist on Moecasts\Laravel\Wallet\Interfaces\Product. Since it exists in all sub-types, consider adding an abstract or default implementation to Moecasts\Laravel\Wallet\Interfaces\Product. ( Ignorable by Annotation )

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

57
            ->where('to_type', $product->/** @scrutinizer ignore-call */ getMorphClass())
Loading history...
58 4
            ->where('to_id', $product->getKey())
0 ignored issues
show
Bug introduced by
The method getKey() does not exist on Moecasts\Laravel\Wallet\Interfaces\Product. Since it exists in all sub-types, consider adding an abstract or default implementation to Moecasts\Laravel\Wallet\Interfaces\Product. ( Ignorable by Annotation )

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

58
            ->where('to_id', $product->/** @scrutinizer ignore-call */ getKey())
Loading history...
59 4
            ->whereIn('action', $action)
60 4
            ->orderBy('id', 'desc')
61 4
            ->first();
62
    }
63
64 2
    public function refund(Refundable $product, string $action = Transfer::ACTION_PAID)
65
    {
66 2
        $transfer = $this->paid($product, $action);
67
68 2
        if (! $transfer) {
69 2
            throw (new ModelNotFoundException())
70 2
                ->setModel(config('wallet.transfer.model'));
71
        }
72
73
        return \DB::transaction(function () use ($transfer) {
74 1
            $transfer->withdraw->update([
75 1
                'confirmed' => false,
76
            ]);
77
78 1
            $transfer->deposit->update([
79 1
                'confirmed' => false,
80
            ]);
81
82 1
            $transfer->update([
83 1
                'refund' => true,
84
            ]);
85
86 1
            return $transfer->fromWallet->refreshBalance() &&
87 1
                $transfer->toWallet->refreshBalance();
88 1
        });
89
    }
90
91 1
    public function safeRefund(Product $product, string $action = Transfer::ACTION_PAID)
92
    {
93
        try {
94 1
            return $this->refund($product, $action);
95 1
        } catch (\Throwable $throwable) {
96 1
            return false;
97
        }
98
    }
99
}
100