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

conedevelopment / bazar / 20213722262

14 Dec 2025 08:30PM UTC coverage: 63.031% (-0.4%) from 63.48%
20213722262

Pull #235

github

web-flow
Merge 03c6b2b10 into 090ff8496
Pull Request #235: Coupons & Discounts

0 of 3 new or added lines in 2 files covered. (0.0%)

53 existing lines in 11 files now uncovered.

965 of 1531 relevant lines covered (63.03%)

15.16 hits per line

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

86.21
/src/Models/Transaction.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Cone\Bazar\Models;
6

7
use Cone\Bazar\Database\Factories\TransactionFactory;
8
use Cone\Bazar\Events\TransactionCompleted;
9
use Cone\Bazar\Interfaces\Models\Transaction as Contract;
10
use Cone\Bazar\Support\Facades\Gateway;
11
use Cone\Root\Traits\InteractsWithProxy;
12
use Illuminate\Database\Eloquent\Builder;
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\BelongsTo;
17
use Illuminate\Support\Facades\Date;
18
use Throwable;
19

20
class Transaction extends Model implements Contract
21
{
22
    use HasFactory;
23
    use InteractsWithProxy;
24

25
    public const PAYMENT = 'payment';
26

27
    public const REFUND = 'refund';
28

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

39
    /**
40
     * The attributes that should be cast to native types.
41
     *
42
     * @var array<string, string>
43
     */
44
    protected $casts = [
45
        'completed_at' => 'datetime',
46
    ];
47

48
    /**
49
     * The attributes that are mass assignable.
50
     *
51
     * @var list<string>
52
     */
53
    protected $fillable = [
54
        'amount',
55
        'completed_at',
56
        'driver',
57
        'key',
58
        'type',
59
    ];
60

61
    /**
62
     * The table associated with the model.
63
     *
64
     * @var string
65
     */
66
    protected $table = 'bazar_transactions';
67

68
    /**
69
     * Get the proxied interface.
70
     */
71
    public static function getProxiedInterface(): string
72
    {
73
        return Contract::class;
1✔
74
    }
75

76
    /**
77
     * Create a new factory instance for the model.
78
     */
79
    protected static function newFactory(): TransactionFactory
80
    {
81
        return TransactionFactory::new();
6✔
82
    }
83

84
    /**
85
     * {@inheritdoc}
86
     */
87
    public function getMorphClass(): string
88
    {
UNCOV
89
        return static::getProxiedClass();
×
90
    }
91

92
    /**
93
     * Get the order for the transaction.
94
     *
95
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\Cone\Bazar\Models\Order, \Cone\Bazar\Models\Transaction>
96
     */
97
    public function order(): BelongsTo
98
    {
99
        return $this->belongsTo(Order::getProxiedClass());
6✔
100
    }
101

102
    /**
103
     * Get the name of the gateway driver.
104
     *
105
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string|null, never>
106
     */
107
    protected function driverName(): Attribute
108
    {
109
        return new Attribute(
1✔
110
            get: static function (mixed $value, array $attributes): ?string {
1✔
111
                try {
112
                    return Gateway::driver($attributes['driver'])->getName();
1✔
UNCOV
113
                } catch (Throwable $exception) {
×
114
                    return $attributes['driver'];
×
115
                }
116
            }
1✔
117
        );
1✔
118
    }
119

120
    /**
121
     * Get the URL of the transaction.
122
     *
123
     * @return \Illuminate\Database\Eloquent\Casts\Attribute<string|null, never>
124
     */
125
    protected function url(): Attribute
126
    {
127
        return new Attribute(
1✔
128
            get: function (mixed $value, array $attributes): ?string {
1✔
129
                try {
130
                    return Gateway::driver($attributes['driver'])->getTransactionUrl($this);
1✔
131
                } catch (Throwable $exception) {
1✔
132
                    return null;
1✔
133
                }
134
            }
1✔
135
        );
1✔
136
    }
137

138
    /**
139
     * Determine if the payment is completed.
140
     */
141
    public function completed(): bool
142
    {
143
        return ! is_null($this->completed_at);
4✔
144
    }
145

146
    /**
147
     * Determine if the payment is pending.
148
     */
149
    public function pending(): bool
150
    {
151
        return ! $this->completed();
2✔
152
    }
153

154
    /**
155
     * Mark the transaction as completed.
156
     */
157
    public function markAsCompleted(): void
158
    {
159
        if ($this->pending()) {
2✔
160
            $this->setAttribute('completed_at', Date::now())->save();
2✔
161

162
            TransactionCompleted::dispatch($this);
2✔
163
        }
164
    }
165

166
    /**
167
     * Mark the transaction as pending.
168
     */
169
    public function markAsPending(): void
170
    {
171
        if ($this->completed()) {
1✔
UNCOV
172
            $this->setAttribute('completed_at', null)->save();
×
173
        }
174
    }
175

176
    /**
177
     * Scope the query to only include payments.
178
     */
179
    public function scopePayment(Builder $query): Builder
180
    {
181
        return $query->where($query->qualifyColumn('type'), static::PAYMENT);
2✔
182
    }
183

184
    /**
185
     * Scope the query to only include refunds.
186
     */
187
    public function scopeRefund(Builder $query): Builder
188
    {
189
        return $query->where($query->qualifyColumn('type'), static::REFUND);
1✔
190
    }
191

192
    /**
193
     * Scope a query to only include completed transactions.
194
     */
195
    public function scopeCompleted(Builder $query): Builder
196
    {
197
        return $query->whereNotNull($query->qualifyColumn('completed_at'));
1✔
198
    }
199

200
    /**
201
     * Scope a query to only include pending transactions.
202
     */
203
    public function scopePending(Builder $query): Builder
204
    {
205
        return $query->whereNull($query->qualifyColumn('completed_at'));
1✔
206
    }
207
}
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