• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

conedevelopment / bazar / 20694116184

04 Jan 2026 02:08PM UTC coverage: 68.615% (+4.5%) from 64.117%
20694116184

push

github

iamgergo
version

1679 of 2447 relevant lines covered (68.61%)

25.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.19
/src/Models/Item.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Cone\Bazar\Models;
6

7
use Cone\Bazar\Database\Factories\ItemFactory;
8
use Cone\Bazar\Enums\Currency;
9
use Cone\Bazar\Interfaces\Buyable;
10
use Cone\Bazar\Interfaces\Models\Item as Contract;
11
use Cone\Bazar\Traits\InteractsWithDiscounts;
12
use Cone\Bazar\Traits\InteractsWithTaxes;
13
use Cone\Root\Traits\InteractsWithProxy;
14
use Illuminate\Database\Eloquent\Casts\Attribute;
15
use Illuminate\Database\Eloquent\Concerns\HasUuids;
16
use Illuminate\Database\Eloquent\Factories\HasFactory;
17
use Illuminate\Database\Eloquent\Model;
18
use Illuminate\Database\Eloquent\Relations\MorphTo;
19
use Illuminate\Support\Collection;
20

21
class Item extends Model implements Contract
22
{
23
    use HasFactory;
24
    use HasUuids;
25
    use InteractsWithDiscounts;
26
    use InteractsWithProxy;
27
    use InteractsWithTaxes;
28

29
    /**
30
     * The accessors to append to the model's array form.
31
     *
32
     * @var list<string>
33
     */
34
    protected $appends = [
35
        'subtotal',
36
        'total',
37
    ];
38

39
    /**
40
     * The attributes that should have default values.
41
     *
42
     * @var array<string, mixed>
43
     */
44
    protected $attributes = [
45
        'price' => 0,
46
        'properties' => '[]',
47
        'quantity' => 1,
48
    ];
49

50
    /**
51
     * The attributes that are mass assignable.
52
     *
53
     * @var list<string>
54
     */
55
    protected $fillable = [
56
        'buyable_id',
57
        'buyable_type',
58
        'name',
59
        'price',
60
        'properties',
61
        'quantity',
62
    ];
63

64
    /**
65
     * The attributes that should be hidden for arrays.
66
     *
67
     * @var list<string>
68
     */
69
    protected $hidden = [
70
        'checkoutable',
71
    ];
72

73
    /**
74
     * The table associated with the model.
75
     *
76
     * @var string
77
     */
78
    protected $table = 'bazar_items';
79

80
    /**
81
     * Get the proxied interface.
82
     */
83
    public static function getProxiedInterface(): string
1✔
84
    {
85
        return Contract::class;
1✔
86
    }
87

88
    /**
89
     * Create a new factory instance for the model.
90
     */
91
    protected static function newFactory(): ItemFactory
5✔
92
    {
93
        return ItemFactory::new();
5✔
94
    }
95

96
    /**
97
     * {@inheritdoc}
98
     */
99
    public function getMorphClass(): string
29✔
100
    {
101
        return static::getProxiedClass();
29✔
102
    }
103

104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function casts(): array
77✔
108
    {
109
        return [
77✔
110
            'price' => 'float',
77✔
111
            'properties' => 'array',
77✔
112
            'quantity' => 'float',
77✔
113
        ];
77✔
114
    }
115

116
    /**
117
     * Get the buyable model for the item.
118
     */
119
    public function buyable(): MorphTo
40✔
120
    {
121
        return $this->morphTo();
40✔
122
    }
123

124
    /**
125
     * Get the checkoutable model for the item.
126
     */
127
    public function checkoutable(): MorphTo
19✔
128
    {
129
        return $this->morphTo()->withDefault();
19✔
130
    }
131

132
    /**
133
     * Get the formatted price attribute.
134
     *
135
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string, never>
136
     */
137
    protected function formattedPrice(): Attribute
2✔
138
    {
139
        return new Attribute(
2✔
140
            get: fn (): string => $this->getFormattedPrice(),
2✔
141
        );
2✔
142
    }
143

144
    /**
145
     * Get the formatted gross price attribute.
146
     *
147
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string, never>
148
     */
149
    protected function formattedGrossPrice(): Attribute
1✔
150
    {
151
        return new Attribute(
1✔
152
            get: fn (): string => $this->getFormattedGrossPrice(),
1✔
153
        );
1✔
154
    }
155

156
    /**
157
     * Get the total attribute.
158
     *
159
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<float, never>
160
     */
161
    protected function total(): Attribute
18✔
162
    {
163
        return new Attribute(
18✔
164
            get: fn (): float => $this->getTotal()
18✔
165
        );
18✔
166
    }
167

168
    /**
169
     * Get the formatted total attribute.
170
     *
171
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string, never>
172
     */
173
    protected function formattedTotal(): Attribute
2✔
174
    {
175
        return new Attribute(
2✔
176
            get: fn (): string => $this->getFormattedTotal()
2✔
177
        );
2✔
178
    }
179

180
    /**
181
     * Get the subtotal attribute.
182
     *
183
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<float, never>
184
     */
185
    protected function subtotal(): Attribute
18✔
186
    {
187
        return new Attribute(
18✔
188
            get: fn (): float => $this->getSubtotal()
18✔
189
        );
18✔
190
    }
191

192
    /**
193
     * Get the formatted subtotal attribute.
194
     *
195
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string, never>
196
     */
197
    protected function formattedSubtotal(): Attribute
2✔
198
    {
199
        return new Attribute(
2✔
200
            get: fn (): string => $this->getFormattedSubtotal()
2✔
201
        );
2✔
202
    }
203

204
    /**
205
     * Get the name.
206
     */
207
    public function getName(): string
×
208
    {
209
        return $this->name;
×
210
    }
211

212
    /**
213
     * Get the price.
214
     */
215
    public function getPrice(): float
45✔
216
    {
217
        return $this->price;
45✔
218
    }
219

220
    /**
221
     * Get the formatted price.
222
     */
223
    public function getFormattedPrice(): string
1✔
224
    {
225
        return $this->checkoutable->getCurrency()->format($this->getPrice());
1✔
226
    }
227

228
    /**
229
     * Get the gross price.
230
     */
231
    public function getGrossPrice(): float
23✔
232
    {
233
        return $this->getPrice() + $this->getTax();
23✔
234
    }
235

236
    /**
237
     * Get the formatted price.
238
     */
239
    public function getFormattedGrossPrice(): string
×
240
    {
241
        return $this->checkoutable->getCurrency()->format($this->getGrossPrice());
×
242
    }
243

244
    /**
245
     * Get the total.
246
     */
247
    public function getTotal(): float
23✔
248
    {
249
        return $this->getGrossPrice() * $this->getQuantity();
23✔
250
    }
251

252
    /**
253
     * Get the formatted total.
254
     */
255
    public function getFormattedTotal(): string
1✔
256
    {
257
        return $this->checkoutable->getCurrency()->format($this->getTotal());
1✔
258
    }
259

260
    /**
261
     * Get the subtotal.
262
     */
263
    public function getSubtotal(): float
44✔
264
    {
265
        return $this->getPrice() * $this->getQuantity();
44✔
266
    }
267

268
    /**
269
     * Get the formatted subtotal.
270
     */
271
    public function getFormattedSubtotal(): string
1✔
272
    {
273
        return $this->checkoutable->getCurrency()->format($this->getSubtotal());
1✔
274
    }
275

276
    /**
277
     * Get the tax base.
278
     */
279
    public function getTaxBase(): float
8✔
280
    {
281
        return $this->price;
8✔
282
    }
283

284
    /**
285
     * Get the formatted tax.
286
     */
287
    public function getFormattedTax(): string
×
288
    {
289
        return $this->checkoutable->getCurrency()->format($this->getTax());
×
290
    }
291

292
    /**
293
     * Get the formatted tax.
294
     */
295
    public function getFormattedTaxTotal(): string
×
296
    {
297
        return $this->checkoutable->getCurrency()->format($this->getTaxTotal());
×
298
    }
299

300
    /**
301
     * Get the quantity.
302
     */
303
    public function getQuantity(): float
45✔
304
    {
305
        return $this->quantity;
45✔
306
    }
307

308
    /**
309
     * Determine if the item is a line item.
310
     */
311
    public function isLineItem(): bool
43✔
312
    {
313
        return $this->buyable instanceof Buyable;
43✔
314
    }
315

316
    /**
317
     * Determine if the item is a fee.
318
     */
319
    public function isFee(): bool
23✔
320
    {
321
        return ! $this->isLineItem();
23✔
322
    }
323

324
    /**
325
     * Calculate the taxes.
326
     */
327
    public function calculateTaxes(): float
15✔
328
    {
329
        $this->taxes()->detach();
15✔
330

331
        $this->buyable->taxRates->each->apply($this);
15✔
332

333
        return $this->getTaxTotal();
15✔
334
    }
335

336
    /**
337
     * Get the discountable quantity.
338
     */
339
    public function getDiscountableQuantity(): float
×
340
    {
341
        return $this->getQuantity();
×
342
    }
343

344
    /**
345
     * Get the applicable discount rules.
346
     */
347
    public function getApplicableDiscountRules(): Collection
14✔
348
    {
349
        return $this->checkoutable->getApplicableDiscountRules()
14✔
350
            ->where('discountable_type', $this->buyable_type);
14✔
351
    }
352

353
    /**
354
     * Get the discountable currency.
355
     */
356
    public function getDiscountableCurrency(): Currency
×
357
    {
358
        return $this->checkoutable->getCurrency();
×
359
    }
360
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc