Cart::alreadyBuy()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 16
nc 6
nop 2
dl 0
loc 27
ccs 17
cts 17
cp 1
crap 4
rs 9.7333
c 0
b 0
f 0
1
<?php
2
3
namespace Bavix\Wallet\Objects;
4
5
use function array_unique;
6
use Bavix\Wallet\Interfaces\Customer;
7
use Bavix\Wallet\Interfaces\Mathable;
8
use Bavix\Wallet\Interfaces\Product;
9
use Bavix\Wallet\Models\Transfer;
10
use function count;
11
use Countable;
12
use function get_class;
13
14
class Cart implements Countable
15
{
16
    /**
17
     * @var Product[]
18
     */
19
    protected $items = [];
20
21
    /**
22
     * @var int[]
23
     */
24
    protected $quantity = [];
25
26
    /**
27
     * @param Product $product
28
     * @param int $quantity
29
     * @return static
30
     */
31 42
    public function addItem(Product $product, int $quantity = 1): self
32
    {
33 42
        $this->addQuantity($product, $quantity);
34 42
        for ($i = 0; $i < $quantity; $i++) {
35 42
            $this->items[] = $product;
36
        }
37
38 42
        return $this;
39
    }
40
41
    /**
42
     * @param iterable $products
43
     * @return static
44
     */
45 4
    public function addItems(iterable $products): self
46
    {
47 4
        foreach ($products as $product) {
48 4
            $this->addItem($product);
49
        }
50
51 4
        return $this;
52
    }
53
54
    /**
55
     * @return Product[]
56
     */
57 38
    public function getItems(): array
58
    {
59 38
        return $this->items;
60
    }
61
62
    /**
63
     * @return Product[]
64
     */
65 39
    public function getUniqueItems(): array
66
    {
67 39
        return array_unique($this->items);
68
    }
69
70
    /**
71
     * The method returns the transfers already paid for the goods.
72
     *
73
     * @param Customer $customer
74
     * @param bool|null $gifts
75
     * @return Transfer[]
76
     */
77 39
    public function alreadyBuy(Customer $customer, bool $gifts = null): array
78
    {
79 39
        $status = [Transfer::STATUS_PAID];
80 39
        if ($gifts) {
81 8
            $status[] = Transfer::STATUS_GIFT;
82
        }
83
84
        /**
85
         * @var Transfer $query
86
         */
87 39
        $result = [];
88 39
        $query = $customer->transfers();
0 ignored issues
show
Bug introduced by
The method transfers() does not exist on Bavix\Wallet\Interfaces\Customer. Did you maybe mean transfer()? ( Ignorable by Annotation )

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

88
        /** @scrutinizer ignore-call */ 
89
        $query = $customer->transfers();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
89 39
        foreach ($this->getUniqueItems() as $product) {
90 39
            $collect = (clone $query)
91 39
                ->where('to_type', $product->getMorphClass())
92 39
                ->where('to_id', $product->getKey())
93 39
                ->whereIn('status', $status)
94 39
                ->orderBy('id', 'desc')
95 39
                ->limit($this->getQuantity($product))
96 39
                ->get();
97
98 39
            foreach ($collect as $datum) {
99 36
                $result[] = $datum;
100
            }
101
        }
102
103 39
        return $result;
104
    }
105
106
    /**
107
     * @param Customer $customer
108
     * @param bool|null $force
109
     * @return bool
110
     */
111 34
    public function canBuy(Customer $customer, bool $force = null): bool
112
    {
113 34
        foreach ($this->items as $item) {
114 34
            if (! $item->canBuy($customer, $this->getQuantity($item), $force)) {
115 7
                return false;
116
            }
117
        }
118
119 34
        return true;
120
    }
121
122
    /**
123
     * @param Customer $customer
124
     * @return int
125
     */
126 2
    public function getTotal(Customer $customer): string
127
    {
128 2
        $result = 0;
129 2
        $math = app(Mathable::class);
130 2
        foreach ($this->items as $item) {
131 2
            $result = $math->add($result, $item->getAmountProduct($customer));
132
        }
133
134 2
        return $result;
135
    }
136
137
    /**
138
     * @return int
139
     */
140 25
    public function count(): int
141
    {
142 25
        return count($this->items);
143
    }
144
145
    /**
146
     * @param Product $product
147
     * @return int
148
     */
149 42
    public function getQuantity(Product $product): int
150
    {
151 42
        $class = get_class($product);
152 42
        $uniq = $product->getUniqueId();
153
154 42
        return $this->quantity[$class][$uniq] ?? 0;
155
    }
156
157
    /**
158
     * @param Product $product
159
     * @param int $quantity
160
     */
161 42
    protected function addQuantity(Product $product, int $quantity): void
162
    {
163 42
        $class = get_class($product);
164 42
        $uniq = $product->getUniqueId();
165 42
        $math = app(Mathable::class);
166 42
        $this->quantity[$class][$uniq] = $math->add($this->getQuantity($product), $quantity);
167 42
    }
168
}
169