• 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

89.36
/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 are mass assignable.
41
     *
42
     * @var list<string>
43
     */
44
    protected $fillable = [
45
        'amount',
46
        'completed_at',
47
        'driver',
48
        'key',
49
        'type',
50
    ];
51

52
    /**
53
     * The table associated with the model.
54
     *
55
     * @var string
56
     */
57
    protected $table = 'bazar_transactions';
58

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

67
    /**
68
     * Create a new factory instance for the model.
69
     */
70
    protected static function newFactory(): TransactionFactory
6✔
71
    {
72
        return TransactionFactory::new();
6✔
73
    }
74

75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function casts(): array
31✔
79
    {
80
        return [
31✔
81
            'completed_at' => 'datetime',
31✔
82
        ];
31✔
83
    }
84

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

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

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

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

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

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

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

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

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

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

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

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

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