Passed
Push — master ( 158a9b...1877fd )
by Бабичев
17:27 queued 12s
created

WalletService::discount()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

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

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