Passed
Push — master ( 986bed...72bf42 )
by Бабичев
07:46
created

HasGift   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 94
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 28
dl 0
loc 94
ccs 30
cts 30
cp 1
rs 10
c 0
b 0
f 0
wmc 5

3 Methods

Rating   Name   Duplication   Size   Complexity  
A safeGift() 0 6 2
A forceGift() 0 3 1
A gift() 0 51 2
1
<?php
2
3
namespace Bavix\Wallet\Traits;
4
5
use Bavix\Wallet\Interfaces\Product;
6
use Bavix\Wallet\Interfaces\Wallet;
7
use Bavix\Wallet\Models\Transfer;
8
use Bavix\Wallet\Objects\Bring;
9
use Bavix\Wallet\Services\CommonService;
10
use Bavix\Wallet\Services\WalletService;
11
use Illuminate\Support\Facades\DB;
12
use Throwable;
13
use function app;
14
use function get_class;
15
16
/**
17
 * Trait HasGift
18
 * @package Bavix\Wallet\Traits
19
 *
20
 * This trait should be used with the trait HasWallet.
21
 */
22
trait HasGift
23
{
24
25
    /**
26
     * Give the goods safely.
27
     *
28
     * @param Wallet $to
29
     * @param Product $product
30
     * @param bool $force
31
     * @return Transfer|null
32
     */
33 1
    public function safeGift(Wallet $to, Product $product, bool $force = null): ?Transfer
34
    {
35
        try {
36 1
            return $this->gift($to, $product, $force);
37 1
        } catch (Throwable $throwable) {
38 1
            return null;
39
        }
40
    }
41
42
    /**
43
     * From this moment on, each user (wallet) can give
44
     * the goods to another user (wallet).
45
     * This functionality can be organized for gifts.
46
     *
47
     * @param Wallet $to
48
     * @param Product $product
49
     * @param bool $force
50
     * @return Transfer
51
     */
52 2
    public function gift(Wallet $to, Product $product, bool $force = null): Transfer
53
    {
54
        /**
55
         * Who's giving? Let's call him Santa Claus
56
         */
57 2
        $santa = $this;
58
59
        /**
60
         * @return Transfer
61
         */
62
        $callback = function () use ($santa, $product, $force) {
63 2
            $amount = $product->getAmountProduct();
64 2
            $meta = $product->getMetaProduct();
65 2
            $fee = app(WalletService::class)
66 2
                ->fee($product, $amount);
67
68 2
            $commonService = app(CommonService::class);
69
70
            /**
71
             * Santa pays taxes
72
             */
73 2
            if (!$force) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $force of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
74 2
                $commonService->verifyWithdraw($santa, $amount);
0 ignored issues
show
Bug introduced by
$santa of type Bavix\Wallet\Traits\HasGift is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $wallet of Bavix\Wallet\Services\Co...rvice::verifyWithdraw(). ( Ignorable by Annotation )

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

74
                $commonService->verifyWithdraw(/** @scrutinizer ignore-type */ $santa, $amount);
Loading history...
75
            }
76
77 2
            $withdraw = $commonService->forceWithdraw($santa, $amount + $fee, $meta);
0 ignored issues
show
Bug introduced by
$santa of type Bavix\Wallet\Traits\HasG...Wallet\Traits\HasWallet is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $wallet of Bavix\Wallet\Services\Co...ervice::forceWithdraw(). ( Ignorable by Annotation )

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

77
            $withdraw = $commonService->forceWithdraw(/** @scrutinizer ignore-type */ $santa, $amount + $fee, $meta);
Loading history...
78
79 2
            $deposit = $commonService->deposit($product, $amount, $meta);
80
81 2
            $from = app(WalletService::class)
82 2
                ->getWallet($this);
0 ignored issues
show
Bug introduced by
$this of type Bavix\Wallet\Traits\HasGift is incompatible with the type Bavix\Wallet\Interfaces\Wallet expected by parameter $object of Bavix\Wallet\Services\WalletService::getWallet(). ( Ignorable by Annotation )

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

82
                ->getWallet(/** @scrutinizer ignore-type */ $this);
Loading history...
83
84 2
            $transfers = $commonService->assemble([
85 2
                (new Bring())
86 2
                    ->setStatus(Transfer::STATUS_GIFT)
87 2
                    ->setDeposit($deposit)
88 2
                    ->setWithdraw($withdraw)
89 2
                    ->setFrom($from)
90 2
                    ->setTo($product)
91
            ]);
92
93 2
            return current($transfers);
94 2
        };
95
96
        /**
97
         * Unfortunately,
98
         * I think it is wrong to make the "assemble" method public.
99
         * That's why I address him like this!
100
         */
101 2
        return DB::transaction(
102 2
            $callback->bindTo($to, get_class($to))
103
        );
104
    }
105
106
    /**
107
     * to give force)
108
     *
109
     * @param Wallet $to
110
     * @param Product $product
111
     * @return Transfer
112
     */
113 1
    public function forceGift(Wallet $to, Product $product): Transfer
114
    {
115 1
        return $this->gift($to, $product, true);
116
    }
117
118
}
119