Teknik Dokümantasyon

Üyelik Uzatma Hesaplama Sistemi

Mevcut üyelik bitmeden yeni üyelik satın alındığında nasıl hesaplanır?

Basit Anlatım (Herkes İçin)

Özet

Günleriniz BİRİKİYOR! Mevcut üyeliğiniz bitmeden yeni paket aldığınızda, kalan günleriniz kaybolmaz. Yeni günler, mevcut bitiş tarihinizin üzerine eklenir.

📅

Örnek 1: Aktif Üyelik

  • Üyeliğiniz: 15 Ocak 2026'da bitiyor
  • 30 günlük paket aldınız
  • Yeni bitiş: 14 Şubat 2026

Örnek 2: Bitmiş Üyelik

  • Üyeliğiniz: Geçen ay bitmiş
  • 30 günlük paket aldınız
  • Yeni bitiş: Bugün + 30 gün

Ne Anlama Geliyor?

  • Erken alırsanız hiçbir gün kaybetmezsiniz
  • İstediğiniz kadar paket üst üste alabilirsiniz
  • Tüm günler tek bir tarihte toplanır

Teknik Detaylar (Geliştiriciler İçin)

Veritabanı Yapısı

Tablo: subscriptions
Kolon Tip Açıklama
current_period_end datetime Ana tarih kolonu - Üyelik bitiş tarihi
current_period_start datetime Mevcut dönem başlangıcı
trial_ends_at datetime Deneme süresi bitiş tarihi
cycle_key string Paket türü (monthly, yearly, vb.)
cycle_metadata JSON Süre bilgileri (duration_days, price, label)

Önemli: Günler ayrı ayrı satırlarda TOPLANMAZ! Tek bir current_period_end kolonu güncellenir.

Uzatma Algoritması

Dosya: Modules/Cart/app/Models/Order.php (satır 241-305)
// 1. Mevcut subscription'ı bul
$existingSubscription = Subscription::where('user_id', $userId)
    ->where('status', 'active')
    ->first();

// 2. Bitiş tarihini hesapla
if ($existingSubscription && $existingSubscription->current_period_end->isFuture()) {
    // Aktif üyelik VAR → Mevcut bitiş + yeni günler
    $newPeriodEnd = $existingSubscription->current_period_end
        ->addDays($durationDays);
} else {
    // Aktif üyelik YOK → Bugün + yeni günler
    $newPeriodEnd = now()->addDays($durationDays);
}

// 3. Subscription güncelle
$subscription->current_period_end = $newPeriodEnd;
$subscription->save();

Kalan Gün Hesabı

Dosya: Modules/Subscription/app/Models/Subscription.php (satır 160-171)
public function daysRemaining(): int
{
    // Trial için trial_ends_at kullan
    if ($this->isTrial() && $this->trial_ends_at) {
        return max(0, (int) floor(
            now()->diffInDays($this->trial_ends_at, false)
        ));
    }

    // Normal üyelik için current_period_end kullan
    if ($this->current_period_end) {
        return max(0, (int) floor(
            now()->diffInDays($this->current_period_end, false)
        ));
    }

    return 0;
}

İlgili Dosyalar

Model
Modules/Subscription/app/Models/Subscription.php

daysRemaining(), isActive(), isTrial()

Uzatma Mantığı
Modules/Cart/app/Models/Order.php

activateSubscriptions() metodu

Service
Modules/Subscription/app/Services/SubscriptionService.php

createTrialForUser(), renewSubscription()

Cart Bridge
Modules/Subscription/app/Services/SubscriptionCartBridge.php

prepareSubscriptionForCart()

Görsel Akış

1

Kullanıcı Yeni Paket Seçer

Üyelik sayfasından 30 günlük, yıllık vb. paket seçilir

cycle_key: "monthly", duration_days: 30
2

Ödeme Başarılı

PayTR callback başarı dönünce Order aktive edilir

Order::activateSubscriptions()
3

Mevcut Üyelik Kontrol

Sistem aktif üyelik var mı kontrol eder

Aktif Varsa
current_period_end + days
Aktif Yoksa
now() + days
4

Tarih Güncellenir

Tek kolon güncellenir, satır eklenmez

UPDATE subscriptions SET current_period_end = '2026-02-14' WHERE user_id = 1

Örnek Senaryolar

Senaryo Mevcut Bitiş Alınan Paket Yeni Bitiş Toplam Gün
Aktif + Aylık 15 Ocak 2026 30 gün 14 Şubat 2026 24 + 30 = 54 gün
Aktif + Yıllık 15 Ocak 2026 365 gün 15 Ocak 2027 24 + 365 = 389 gün
Bitmiş + Aylık 1 Aralık 2025 30 gün 21 Ocak 2026 0 + 30 = 30 gün
Yeni Kullanıcı - 30 gün 21 Ocak 2026 30 gün
3x Aylık Ardarda Bugün 30 + 30 + 30 20 Mart 2026 90 gün

Sonuç

Tek Kolon

Tüm günler current_period_end kolonunda toplanır

Kümülatif

Yeni günler mevcut bitiş tarihine EKLENİR

Kayıp Yok

Erken alınan paketlerde hiçbir gün kaybedilmez