Passed
Push — master ( 38cc9b...2ce834 )
by Moecasts
03:22
created

CanPay::refund()   A

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 0
Metric Value
cc 3
eloc 13
nc 2
nop 2
dl 0
loc 24
ccs 13
cts 13
cp 1
crap 3
rs 9.8333
c 0
b 0
f 0
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 6
    public function pay(Product $product, string $action = Transfer::ACTION_PAID, bool $force = false): Transfer
13
    {
14 6
        if (! $product->canBePaid($this, $force)) {
0 ignored issues
show
Unused Code introduced by
The call to Moecasts\Laravel\Wallet\...es\Product::canBePaid() has too many arguments starting with $this. ( Ignorable by Annotation )

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

14
        if (! $product->/** @scrutinizer ignore-call */ canBePaid($this, $force)) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
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 5
        if ($force) {
19
            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
                $product,
21
                $product->getProductAmount($action),
22
                $product->getProductMeta($action),
23
                $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 safePay(Product $product, string $action = Transfer::ACTION_PAID, bool $force = false): ?Transfer
36
    {
37
        try {
38 1
            return $this->pay($product, $action, $force);
39 1
        } catch (\Throwable $throwable) {
40 1
            return null;
41
        }
42
    }
43
44 4
    public function paid(Product $product, string $action = Transfer::ACTION_PAID): ?Transfer
45
    {
46 4
        $action = [$action];
47
48 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

48
        /** @scrutinizer ignore-call */ 
49
        $query = $this->holderTransfers();
Loading history...
49
50
        return $query
51 4
            ->where('refund', false)
52 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

52
            ->where('to_type', $product->/** @scrutinizer ignore-call */ getMorphClass())
Loading history...
53 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

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