PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.5.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.5.0
1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 All 49 releases
fluent-cart / app / Models / OrderTransaction.php

OrderTransaction.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.5.0, at app/Models/OrderTransaction.php

269 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Models;
4
5 use FluentCart\Api\StoreSettings;
6 use FluentCart\App\Helpers\Status;
7 use FluentCart\App\Models\Concerns\CanSearch;
8 use FluentCart\App\Modules\PaymentMethods\Core\GatewayManager;
9 use FluentCart\Framework\Database\Orm\Relations\HasOne;
10 use FluentCart\Framework\Support\Arr;
11
12 /**
13 * OrderTransaction Model - DB Model for Transactions
14 *
15 * Database Model
16 *
17 * @package FluentCart\App\Models
18 *
19 * @version 1.0.0
20 */
21 class OrderTransaction extends Model
22 {
23 use CanSearch;
24
25 protected $table = 'fct_order_transactions';
26
27 protected $appends = ['url'];
28 /**
29 * The attributes that are mass assignable.
30 *
31 * @var array
32 */
33 protected $fillable = [
34 'order_id',
35 'order_type',
36 'vendor_charge_id',
37 'payment_method',
38 'payment_mode',
39 'payment_method_type',
40 'currency',
41 'transaction_type',
42 'subscription_id',
43 'card_last_4',
44 'card_brand',
45 'status',
46 'total',
47 'rate',
48 'meta',
49 'uuid',
50 'created_at'
51 ];
52
53 protected $searchable = [
54 'id',
55 'total',
56 'status',
57 'payment_method',
58 'currency',
59 'created_at',
60 'updated_at',
61 ];
62
63 public function setMetaAttribute($value)
64 {
65
66 if ($value) {
67 $decoded = \json_encode($value, true);
68 if (!($decoded)) {
69 $decoded = '[]';
70 }
71 } else {
72 $decoded = '[]';
73 }
74
75 $this->attributes['meta'] = $decoded;
76 }
77
78 public function getMetaAttribute($value)
79 {
80 if (!$value) {
81 return [];
82 }
83
84 return \json_decode($value, true);
85 }
86
87 public function subscription()
88 {
89 return $this->hasOne(Subscription::class, 'id', 'subscription_id');
90 }
91
92 public function order()
93 {
94 return $this->belongsTo(Order::class, 'order_id', 'id');
95 }
96
97
98 public static function boot()
99 {
100 parent::boot();
101 static::creating(function ($model) {
102 if (empty($model->uuid)) {
103 $model->uuid = md5(time() . wp_generate_uuid4());
104 }
105 });
106 }
107
108 public function getUrlAttribute($value)
109 {
110
111 return apply_filters('fluent_cart/transaction/url_' . $this->getAttribute('payment_method'), '', [
112 'transaction' => $this,
113 'payment_mode' => $this->payment_mode,
114 'vendor_charge_id' => $this->vendor_charge_id,
115 'transaction_type' => $this->transaction_type
116 ]);
117 }
118
119 public function scopeOfStatus($query, $status)
120 {
121 return $query->where('status', $status);
122 }
123
124 public function scopeOfPaymentMethod($query, $methodName)
125 {
126 return $query->where('payment_method', $methodName);
127 }
128
129 public function updateStatus($newStatus, $otherData = [])
130 {
131 $oldStatus = $this->status;
132
133 if ($newStatus == $oldStatus) {
134 return $this;
135 }
136
137 $this->status = $newStatus;
138
139 if ($otherData) {
140 $this->fill($otherData);
141 }
142
143 $this->save();
144
145 return $this;
146 }
147
148 public static function bulkDeleteByOrderIds($ids, $params = [])
149 {
150 return static::getQuery()->whereIn('order_id', $ids)->delete();
151 }
152
153 public function orders(): HasOne
154 {
155 return $this->hasOne(Order::class, 'id', 'order_id');
156 }
157
158 public function getMaxRefundableAmount()
159 {
160 if ($this->status !== Status::TRANSACTION_SUCCEEDED) {
161 return 0;
162 }
163 $refundAmount = (int)(Arr::get($this->meta, 'refunded_total', 0));
164 return $this->total - $refundAmount;
165 }
166
167 public function getPaymentMethodText()
168 {
169 if ($this->card_brand && $this->card_last_4) {
170 return sprintf('%1$s ***%2$s', esc_html($this->card_brand), esc_html($this->card_last_4));
171 }
172
173 return $this->payment_method;
174 }
175
176 public function getReceiptPageUrl($filtered = false)
177 {
178 $url = add_query_arg([
179 'trx_hash' => $this->uuid
180 ], (new StoreSettings())->getReceiptPage());
181
182 if ($filtered) {
183 $context = [
184 'transaction' => $this,
185 'order' => $this->order,
186 ];
187 $url = apply_filters_deprecated('fluentcart/transaction/receipt_page_url', [$url, $context], '1.3.16', 'fluent_cart/transaction/receipt_page_url', 'Use fluent_cart/transaction/receipt_page_url instead of fluentcart/transaction/receipt_page_url. It will be removed in v1.4.3.');
188 $url = apply_filters('fluent_cart/transaction/receipt_page_url', $url, $context);
189 }
190
191 return $url;
192 }
193
194 public function acceptDispute($args = [])
195 {
196 if ($this->transaction_type !== Status::TRANSACTION_TYPE_DISPUTE) {
197 return new \WP_Error('No dispute found!', __('The selected transaction is not a dispute', 'fluent-cart'));
198 }
199
200 $gateway = GatewayManager::getInstance($this->payment_method);
201
202 if ($gateway && $gateway->has('dispute_handler')) {
203 $handleRemoteDispute = $gateway->acceptRemoteDispute($this, $args);
204 if (is_wp_error($handleRemoteDispute)) {
205 return $handleRemoteDispute;
206 }
207
208 $this->status = Status::TRANSACTION_DISPUTE_LOST;
209 $this->meta = array_merge($this->meta, [
210 'is_dispute_actionable' => false,
211 'is_charge_refundable' => false
212 ]);
213 $this->save();
214
215 $newPaidAmount = intval($this->order->total_paid - $this->total);
216 $this->order->update([
217 'total_paid' => max($newPaidAmount, 0),
218 'payment_status' => $newPaidAmount > 0 ? Status::PAYMENT_PARTIALLY_PAID : Status::PAYMENT_FAILED,
219 ]);
220
221 if (Arr::get($args, 'dispute_note')) {
222 $this->meta = array_merge($this->meta, [
223 'dispute_note' => $args['dispute_note'],
224 ]);
225 $this->save();
226 }
227
228 fluent_cart_add_log(
229 'Dispute accepted on ' . $this->payment_method,
230 'Dispute accepted! ' . $args['dispute_note'] ?? 'Note: ' . Arr::get($args, 'dispute_note'), 'success', [
231 'module_id' => $this->order->id,
232 'module_name' => 'order',
233 ]
234 );
235 } else {
236 return new \WP_Error('invalid_payment_method', __('This payment method does not support remote dispute management', 'fluent-cart'));
237 }
238 }
239
240 public function scopeSearchByPayerEmail ($query, $data) {
241
242 $operator = Arr::get($data, 'operator', 'contains');
243
244 $search = Arr::get($data, 'value');
245 $search = sanitize_text_field(trim($search));
246
247 switch ($operator) {
248 case 'starts_with':
249 $pattern = $search . '%';
250 break;
251 case 'ends_with':
252 $pattern = '%' . $search;
253 break;
254 case 'equals':
255 $pattern = $search;
256 break;
257 case 'not_like':
258 return $query->whereRaw("JSON_UNQUOTE(JSON_EXTRACT(meta, '$.payer.email_address')) NOT LIKE ?", ['%' . $search . '%']);
259 default: // contains
260 $pattern = '%' . $search . '%';
261 break;
262 }
263
264 return $query->whereRaw("JSON_UNQUOTE(JSON_EXTRACT(meta, '$.payer.email_address')) LIKE ?", [$pattern]);
265
266 }
267
268 }
269