PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.0
1.7.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 All 50 releases
← All changes | app/Models/Subscription.php +54 -5 1.6.4 → 1.7.0 View file →
@@ -40,9 +40,9 @@
40 40 protected $table = 'fct_subscriptions';
41 41
42 42 protected $primaryKey = 'id';
43 43
44 - protected $appends = ['url', 'payment_info', 'billingInfo', 'overridden_status', 'currency', 'reactivate_url', 'permissions', 'display_item_name', 'system_charge_state'];
44 + protected $appends = ['url', 'payment_info', 'billingInfo', 'overridden_status', 'currency', 'reactivate_url', 'permissions', 'display_item_name', 'system_charge_state', 'payment_method_title'];
45 45
46 46 protected $guarded = ['id'];
47 47
48 48 protected $fillable = [
@@ -277,8 +277,27 @@
277 277
278 278 return $postTitle !== '' ? $postTitle . ' - ' . $attributeDisplayTitleString : $attributeDisplayTitleString;
279 279 }
280 280
281 + /**
282 + * Display label of the backing gateway ("Authorize.Net", "Cash"), the same
283 + * source StatusHelper stamps into order.payment_method_title. Empty when the
284 + * slug resolves to no registered gateway.
285 + */
286 + public function getPaymentMethodTitleAttribute(): string
287 + {
288 + $gateway = $this->resolveGateway();
289 + if (!$gateway) {
290 + return '';
291 + }
292 +
293 + $title = method_exists($gateway, 'getMeta')
294 + ? $gateway->getMeta('title')
295 + : Arr::get($gateway->meta(), 'title');
296 +
297 + return (string) $title;
298 + }
299 +
281 300 public function getUrlAttribute($value)
282 301 {
283 302 return apply_filters('fluent_cart/subscription/url_' . $this->current_payment_method, '', [
284 303 'vendor_subscription_id' => $this->vendor_subscription_id,
@@ -980,9 +999,13 @@
980 999 Status::SUBSCRIPTION_FAILING,
981 1000 Status::SUBSCRIPTION_EXPIRED,
982 1001 Status::SUBSCRIPTION_EXPIRING,
983 1002 Status::SUBSCRIPTION_PAST_DUE,
984 - ]);
1003 + ]) || (
1004 + in_array($this->status, [Status::SUBSCRIPTION_PENDING, Status::SUBSCRIPTION_INTENDED], true)
1005 + && $this->hasReactivationAttempt()
1006 + && ((int) $this->bill_times === 0 || (int) $this->bill_count < (int) $this->bill_times)
1007 + );
985 1008
986 1009 return (bool) apply_filters('fluent_cart/subscription/can_reactivate', $canReactivate, [
987 1010 'subscription' => $this
988 1011 ]);
@@ -988,8 +1011,34 @@
988 1011 ]);
989 1012 }
990 1013
991 1014 /**
1015 + * Pro records `reactivation_order_id` before a reactivation checkout is paid. A first
1016 + * purchase awaiting gateway activation is also pending/intended and can already be
1017 + * billed, so only this marker separates a retryable reactivation from it.
1018 + */
1019 + public function hasReactivationAttempt(): bool
1020 + {
1021 + return (int) Arr::get($this->config, 'reactivation_order_id', 0) > 0;
1022 + }
1023 +
1024 + public function isVisibleToCustomer(): bool
1025 + {
1026 + return !in_array($this->status, [Status::SUBSCRIPTION_PENDING, Status::SUBSCRIPTION_INTENDED], true)
1027 + || (int) $this->bill_count > 0
1028 + || $this->hasReactivationAttempt();
1029 + }
1030 +
1031 + public function scopeVisibleToCustomer($query)
1032 + {
1033 + return $query->where(function ($query) {
1034 + $query->whereNotIn('status', [Status::SUBSCRIPTION_PENDING, Status::SUBSCRIPTION_INTENDED])
1035 + ->orWhere('bill_count', '>', 0)
1036 + ->orWhere('config', 'LIKE', '%"reactivation_order_id":%');
1037 + });
1038 + }
1039 +
1040 + /**
992 1041 * @deprecated Use canReactivate(). Kept as a backward-compatible alias.
993 1042 * @return bool
994 1043 */
995 1044 public function canReactive()
@@ -1394,13 +1443,13 @@
1394 1443 // lookup either way.
1395 1444
1396 1445 $invalidStatuses = [
1397 1446 Status::SUBSCRIPTION_EXPIRED,
1398 - Status::SUBSCRIPTION_INTENDED,
1399 - Status::SUBSCRIPTION_PENDING
1400 1447 ];
1401 1448
1402 - if (in_array($this->status, $invalidStatuses)) {
1449 + if (in_array($this->status, $invalidStatuses)
1450 + || (in_array($this->status, [Status::SUBSCRIPTION_PENDING, Status::SUBSCRIPTION_INTENDED], true)
1451 + && !$this->hasReactivationAttempt())) {
1403 1452 return false;
1404 1453 }
1405 1454
1406 1455 $nextBillingDate = $this->next_billing_date;