Passed
Pull Request — master (#119)
by Бабичев
08:28
created

WalletService::getBalance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Bavix\Wallet\Services;
4
5
use Bavix\Wallet\Exceptions\AmountInvalid;
6
use Bavix\Wallet\Interfaces\Customer;
7
use Bavix\Wallet\Interfaces\Discount;
8
use Bavix\Wallet\Interfaces\MinimalTaxable;
9
use Bavix\Wallet\Interfaces\Product;
10
use Bavix\Wallet\Interfaces\Storable;
11
use Bavix\Wallet\Interfaces\Taxable;
12
use Bavix\Wallet\Interfaces\Wallet;
13
use Bavix\Wallet\Models\Wallet as WalletModel;
14
use Bavix\Wallet\Traits\HasWallet;
15
use function app;
16
17
class WalletService
18
{
19
20
    /**
21
     * @param Wallet $customer
22
     * @param Wallet $product
23
     * @return int
24
     */
25 37
    public function discount(Wallet $customer, Wallet $product): int
26
    {
27 37
        if ($customer instanceof Customer && $product instanceof Discount) {
28 1
            return $product->getDiscountProduct($customer);
29
        }
30
31
        // without discount
32 36
        return 0;
33
    }
34
35
    /**
36
     * @param Wallet $object
37
     * @return int
38
     */
39 11
    public function decimalPlaces(Wallet $object): int
40
    {
41 11
        $decimalPlaces = $this->getWallet($object)->decimal_places ?: 2;
42 11
        return 10 ** $decimalPlaces;
43
    }
44
45
    /**
46
     * Consider the fee that the system will receive.
47
     *
48
     * @param Wallet $wallet
49
     * @param int $amount
50
     * @return int
51
     */
52 38
    public function fee(Wallet $wallet, int $amount): int
53
    {
54 38
        $fee = 0;
55 38
        if ($wallet instanceof Taxable) {
56 4
            $fee = (int)($amount * $wallet->getFeePercent() / 100);
57
        }
58
59
        /**
60
         * Added minimum commission condition
61
         *
62
         * @see https://github.com/bavix/laravel-wallet/issues/64#issuecomment-514483143
63
         */
64 38
        if ($wallet instanceof MinimalTaxable) {
65 1
            $minimal = $wallet->getMinimalFee();
66 1
            if ($fee < $minimal) {
67 1
                $fee = $minimal;
68
            }
69
        }
70
71 38
        return $fee;
72
    }
73
74
    /**
75
     * The amount of checks for errors
76
     *
77
     * @param int $amount
78
     * @throws
79
     */
80 81
    public function checkAmount(int $amount): void
81
    {
82 81
        if ($amount < 0) {
83 3
            throw new AmountInvalid(trans('wallet::errors.price_positive'));
0 ignored issues
show
Bug introduced by
It seems like trans('wallet::errors.price_positive') can also be of type array and array; however, parameter $message of Bavix\Wallet\Exceptions\...tInvalid::__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

83
            throw new AmountInvalid(/** @scrutinizer ignore-type */ trans('wallet::errors.price_positive'));
Loading history...
84
        }
85 78
    }
86
87
    /**
88
     * @param Wallet $object
89
     * @param bool $autoSave
90
     * @return WalletModel
91
     */
92 99
    public function getWallet(Wallet $object, bool $autoSave = true): WalletModel
93
    {
94
        /**
95
         * @var WalletModel $wallet
96
         */
97 99
        $wallet = $object;
98
99 99
        if (!($object instanceof WalletModel)) {
100
            /**
101
             * @var HasWallet $object
102
             */
103 63
            $wallet = $object->wallet;
104
        }
105
106 99
        if ($autoSave) {
107 99
            $wallet->exists or $wallet->save();
108
        }
109
110 99
        return $wallet;
111
    }
112
113
    /**
114
     * @param Wallet $object
115
     * @return int
116
     * @deprecated use Storable::getBalance
117
     */
118 2
    public function getBalance(Wallet $object): int
119
    {
120 2
        return app(Storable::class)
121 2
            ->getBalance($object);
122
    }
123
124
    /**
125
     * @param WalletModel $wallet
126
     * @return bool
127
     */
128 17
    public function refresh(WalletModel $wallet): bool
129
    {
130
        return app(LockService::class)->lock($this, __FUNCTION__, static function () use ($wallet) {
131 17
            app(Storable::class)->getBalance($wallet);
132 17
            $balance = $wallet->getAvailableBalance();
133 17
            $wallet->balance = $balance;
134
135 17
            return app(Storable::class)->setBalance($wallet, $balance) &&
136 17
                $wallet->save();
137 17
        });
138
    }
139
140
}
141