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

conedevelopment / bazar / 20312410163

17 Dec 2025 05:58PM UTC coverage: 64.395% (+0.9%) from 63.48%
20312410163

push

github

web-flow
Merge pull request #235 from conedevelopment/coupons

Coupons & Discounts

204 of 260 new or added lines in 23 files covered. (78.46%)

8 existing lines in 1 file now uncovered.

1096 of 1702 relevant lines covered (64.39%)

18.27 hits per line

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

91.55
/src/Models/Shipping.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Cone\Bazar\Models;
6

7
use Cone\Bazar\Database\Factories\ShippingFactory;
8
use Cone\Bazar\Interfaces\Models\Shipping as Contract;
9
use Cone\Bazar\Support\Facades\Shipping as Manager;
10
use Cone\Bazar\Traits\Addressable;
11
use Cone\Bazar\Traits\InteractsWithTaxes;
12
use Cone\Root\Traits\InteractsWithProxy;
13
use Illuminate\Database\Eloquent\Casts\Attribute;
14
use Illuminate\Database\Eloquent\Factories\HasFactory;
15
use Illuminate\Database\Eloquent\Model;
16
use Illuminate\Database\Eloquent\Relations\MorphTo;
17
use Throwable;
18

19
class Shipping extends Model implements Contract
20
{
21
    use Addressable;
22
    use HasFactory;
23
    use InteractsWithProxy;
24
    use InteractsWithTaxes;
25

26
    /**
27
     * The attributes that should have default values.
28
     *
29
     * @var array<string, mixed>
30
     */
31
    protected $attributes = [
32
        'fee' => 0,
33
    ];
34

35
    /**
36
     * The attributes that are mass assignable.
37
     *
38
     * @var list<string>
39
     */
40
    protected $fillable = [
41
        'fee',
42
        'driver',
43
    ];
44

45
    /**
46
     * The table associated with the model.
47
     *
48
     * @var string
49
     */
50
    protected $table = 'bazar_shippings';
51

52
    /**
53
     * The "booted" method of the model.
54
     */
55
    protected static function booted(): void
56
    {
57
        static::creating(static function (self $shipping): void {
33✔
58
            $shipping->driver = $shipping->driver ?: Manager::getDefaultDriver();
30✔
59
        });
33✔
60
    }
61

62
    /**
63
     * Get the proxied interface.
64
     */
65
    public static function getProxiedInterface(): string
66
    {
67
        return Contract::class;
1✔
68
    }
69

70
    /**
71
     * Create a new factory instance for the model.
72
     */
73
    protected static function newFactory(): ShippingFactory
74
    {
75
        return ShippingFactory::new();
11✔
76
    }
77

78
    /**
79
     * {@inheritdoc}
80
     */
81
    public function getMorphClass(): string
82
    {
83
        return static::getProxiedClass();
26✔
84
    }
85

86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function casts(): array
90
    {
91
        return [
33✔
92
            'fee' => 'float',
33✔
93
        ];
33✔
94
    }
95

96
    /**
97
     * Get the shippable model for the shipping.
98
     */
99
    public function shippable(): MorphTo
100
    {
101
        return $this->morphTo()->withDefault(static function (): Cart {
22✔
102
            return Cart::proxy()->newInstance();
1✔
103
        });
22✔
104
    }
105

106
    /**
107
     * Get the driver attribute.
108
     *
109
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string, never>
110
     */
111
    protected function driver(): Attribute
112
    {
113
        return new Attribute(
30✔
114
            get: static function (?string $value = null): string {
30✔
115
                return $value ?: Manager::getDefaultDriver();
30✔
116
            }
30✔
117
        );
30✔
118
    }
119

120
    /**
121
     * Get the total attribute.
122
     *
123
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<float, never>
124
     */
125
    protected function total(): Attribute
126
    {
127
        return new Attribute(
2✔
128
            get: function (): float {
2✔
129
                return $this->getTotal();
1✔
130
            }
2✔
131
        );
2✔
132
    }
133

134
    /**
135
     * Get the formatted total attribute.
136
     *
137
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string, never>
138
     */
139
    protected function formattedTotal(): Attribute
140
    {
141
        return new Attribute(
2✔
142
            get: function (): string {
2✔
143
                return $this->getFormattedTotal();
1✔
144
            }
2✔
145
        );
2✔
146
    }
147

148
    /**
149
     * Get the subtotal attribute.
150
     *
151
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<float, never>
152
     */
153
    protected function subtotal(): Attribute
154
    {
155
        return new Attribute(
2✔
156
            get: function (): float {
2✔
157
                return $this->getSubtotal();
1✔
158
            }
2✔
159
        );
2✔
160
    }
161

162
    /**
163
     * Get the formatted subtotal attribute.
164
     *
165
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string, never>
166
     */
167
    protected function formattedSubtotal(): Attribute
168
    {
169
        return new Attribute(
2✔
170
            get: function (): string {
2✔
171
                return $this->getFormattedSubtotal();
1✔
172
            }
2✔
173
        );
2✔
174
    }
175

176
    /**
177
     * Get the name of the shipping method.
178
     *
179
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string, never>
180
     */
181
    protected function driverName(): Attribute
182
    {
183
        return new Attribute(
2✔
184
            get: static function (mixed $value, array $attributes): string {
2✔
185
                try {
186
                    return Manager::driver($attributes['driver'])->getName();
1✔
187
                } catch (Throwable $exception) {
1✔
188
                    return $attributes['driver'];
1✔
189
                }
190
            }
2✔
191
        );
2✔
192
    }
193

194
    /**
195
     * Get the name.
196
     */
197
    public function getName(): string
198
    {
199
        return $this->driverName;
×
200
    }
201

202
    /**
203
     * Get the tax base.
204
     */
205
    public function getTaxBase(): float
206
    {
207
        return $this->fee;
2✔
208
    }
209

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

218
    /**
219
     * Get the formatted price.
220
     */
221
    public function getFormattedPrice(): string
222
    {
NEW
223
        return $this->shippable->getCurrency()->format($this->getPrice());
×
224
    }
225

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

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

242
    /**
243
     * Get the shipping's total.
244
     */
245
    public function getTotal(): float
246
    {
247
        return $this->getGrossPrice() * $this->getQuantity();
10✔
248
    }
249

250
    /**
251
     * Get the shipping's formatted total.
252
     */
253
    public function getFormattedTotal(): string
254
    {
255
        return $this->shippable->getCurrency()->format($this->getTotal());
1✔
256
    }
257

258
    /**
259
     * Get the shipping's subtotal.
260
     */
261
    public function getSubtotal(): float
262
    {
263
        return $this->getPrice();
1✔
264
    }
265

266
    /**
267
     * Get the shipping's formatted subtotal.
268
     */
269
    public function getFormattedSubtotal(): string
270
    {
271
        return $this->shippable->getCurrency()->format($this->getSubtotal());
1✔
272
    }
273

274
    /**
275
     * Get the formatted tax total.
276
     */
277
    public function getFormattedTax(): string
278
    {
NEW
279
        return $this->shippable->getCurrency()->format($this->getTax());
×
280
    }
281

282
    /**
283
     * Get the formatted tax total.
284
     */
285
    public function getFormattedTaxTotal(): string
286
    {
NEW
287
        return $this->shippable->getCurrency()->format($this->getTaxTotal());
×
288
    }
289

290
    /**
291
     * Get the quantity.
292
     */
293
    public function getQuantity(): float
294
    {
295
        return 1;
23✔
296
    }
297

298
    /**
299
     * Calculate the fee.
300
     */
301
    public function calculateFee(): float
302
    {
303
        try {
304
            $this->fill([
15✔
305
                'fee' => Manager::driver($this->driver)->calculate($this->shippable),
15✔
306
            ])->save();
15✔
307
        } catch (Throwable $exception) {
×
308
            //
309
        }
310

311
        return $this->fee;
15✔
312
    }
313

314
    /**
315
     * Calculate the taxes.
316
     */
317
    public function calculateTaxes(): float
318
    {
319
        $taxes = TaxRate::proxy()
15✔
320
            ->newQuery()
15✔
321
            ->applicableForShipping()
15✔
322
            ->get()
15✔
323
            ->mapWithKeys(function (TaxRate $taxRate): array {
15✔
324
                return [$taxRate->getKey() => ['value' => $taxRate->calculate($this)]];
1✔
325
            });
15✔
326

327
        $this->taxes()->sync($taxes);
15✔
328

329
        return $this->getTaxTotal();
15✔
330
    }
331
}
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