Update: 2026-05-16 01:36:22
This commit is contained in:
@@ -31,7 +31,7 @@ final class QuotaMiddleware
|
||||
|
||||
// Fetch subscription with plan info
|
||||
$stmt = $db->prepare("
|
||||
SELECT s.*, sp.name_ar as plan_name, sp.ai_features, sp.jofotara_enabled
|
||||
SELECT s.*, sp.name_ar as plan_name, sp.ai_features, sp.jofotara_enabled, sp.price_monthly_jod, sp.price_annual_jod
|
||||
FROM subscriptions s
|
||||
LEFT JOIN subscription_plans sp ON s.plan_id = sp.id
|
||||
WHERE s.tenant_id = ?
|
||||
@@ -60,7 +60,9 @@ final class QuotaMiddleware
|
||||
// Auto-reset period counter if billing period has ended
|
||||
if (!empty($sub['current_period_end']) && strtotime($sub['current_period_end']) < time()) {
|
||||
$newStart = date('Y-m-d H:i:s');
|
||||
$newEnd = date('Y-m-d H:i:s', strtotime('+1 year')); // Changed to annual
|
||||
$cycle = $sub['billing_cycle'] ?? 'annual';
|
||||
$interval = ($cycle === 'monthly') ? '+1 month' : '+1 year';
|
||||
$newEnd = date('Y-m-d H:i:s', strtotime($interval));
|
||||
|
||||
$resetStmt = $db->prepare("
|
||||
UPDATE subscriptions
|
||||
|
||||
@@ -15,6 +15,8 @@ return [
|
||||
'max_invoices_month' => 15,
|
||||
'max_users' => 1,
|
||||
'price_jod' => 0.00,
|
||||
'price_monthly_jod' => 0.00,
|
||||
'price_annual_jod' => 0.00,
|
||||
'ai_features' => true,
|
||||
'jofotara_enabled' => true,
|
||||
'badge_color' => 'gray',
|
||||
@@ -29,43 +31,47 @@ return [
|
||||
],
|
||||
'basic' => [
|
||||
'id' => 'basic',
|
||||
'name_ar' => 'الباقة الأساسية (سنوي)',
|
||||
'name_en' => 'Basic Plan (Annual)',
|
||||
'max_companies' => 1,
|
||||
'max_invoices_month' => 12000,
|
||||
'max_users' => 1,
|
||||
'price_jod' => 120.00,
|
||||
'name_ar' => 'الباقة الأساسية',
|
||||
'name_en' => 'Basic Plan',
|
||||
'max_companies' => 3,
|
||||
'max_invoices_month' => 500,
|
||||
'max_users' => 2,
|
||||
'price_jod' => 15.00, // Default legacy price
|
||||
'price_monthly_jod' => 15.00,
|
||||
'price_annual_jod' => 120.00,
|
||||
'ai_features' => true,
|
||||
'jofotara_enabled' => true,
|
||||
'badge_color' => 'blue',
|
||||
'description_ar' => 'للمحاسبين المستقلين والشركات الصغيرة — 12,000 فاتورة سنوياً',
|
||||
'description_ar' => 'للمحاسبين المستقلين والشركات الصغيرة — 3 شركات',
|
||||
'features' => [
|
||||
'استخراج الفواتير بالذكاء الاصطناعي',
|
||||
'الربط المباشر مع جوفوترة',
|
||||
'شركة واحدة فقط',
|
||||
'12,000 فاتورة سنوياً (سخية جداً)',
|
||||
'مستخدم واحد',
|
||||
'حتى 3 شركات (بدلاً من واحدة)',
|
||||
'500 فاتورة شهرياً (سخية جداً)',
|
||||
'مستخدمين اثنين',
|
||||
'دعم فني عبر الواتساب',
|
||||
],
|
||||
],
|
||||
'pro' => [
|
||||
'id' => 'pro',
|
||||
'name_ar' => 'الباقة الاحترافية (سنوي)',
|
||||
'name_en' => 'Pro Plan (Annual)',
|
||||
'name_ar' => 'الباقة الاحترافية',
|
||||
'name_en' => 'Pro Plan',
|
||||
'max_companies' => 9999,
|
||||
'max_invoices_month' => 50000,
|
||||
'max_invoices_month' => 3000,
|
||||
'max_users' => 5,
|
||||
'price_jod' => 250.00,
|
||||
'price_jod' => 35.00, // Default legacy price
|
||||
'price_monthly_jod' => 35.00,
|
||||
'price_annual_jod' => 290.00,
|
||||
'ai_features' => true,
|
||||
'jofotara_enabled' => true,
|
||||
'badge_color' => 'gold',
|
||||
'is_popular' => true,
|
||||
'description_ar' => 'للمكاتب الكبيرة والموزعين — 50,000 فاتورة سنوياً',
|
||||
'description_ar' => 'للمكاتب الكبيرة والموزعين — حجم عمل ضخم',
|
||||
'features' => [
|
||||
'استخراج الفواتير بالذكاء الاصطناعي',
|
||||
'الربط المباشر مع جوفوترة',
|
||||
'عدد شركات غير محدود',
|
||||
'50,000 فاتورة سنوياً',
|
||||
'3,000 فاتورة شهرياً',
|
||||
'5 مستخدمين',
|
||||
'API كامل لتطبيق الهاتف',
|
||||
'مدير حساب مخصص',
|
||||
|
||||
@@ -31,7 +31,7 @@ final class QuotaMiddleware
|
||||
|
||||
// Fetch subscription with plan info
|
||||
$stmt = $db->prepare("
|
||||
SELECT s.*, sp.name_ar as plan_name, sp.ai_features, sp.jofotara_enabled
|
||||
SELECT s.*, sp.name_ar as plan_name, sp.ai_features, sp.jofotara_enabled, sp.price_monthly_jod, sp.price_annual_jod
|
||||
FROM subscriptions s
|
||||
LEFT JOIN subscription_plans sp ON s.plan_id = sp.id
|
||||
WHERE s.tenant_id = ?
|
||||
@@ -60,7 +60,9 @@ final class QuotaMiddleware
|
||||
// Auto-reset period counter if billing period has ended
|
||||
if (!empty($sub['current_period_end']) && strtotime($sub['current_period_end']) < time()) {
|
||||
$newStart = date('Y-m-d H:i:s');
|
||||
$newEnd = date('Y-m-d H:i:s', strtotime('+1 year')); // Changed to annual
|
||||
$cycle = $sub['billing_cycle'] ?? 'annual';
|
||||
$interval = ($cycle === 'monthly') ? '+1 month' : '+1 year';
|
||||
$newEnd = date('Y-m-d H:i:s', strtotime($interval));
|
||||
|
||||
$resetStmt = $db->prepare("
|
||||
UPDATE subscriptions
|
||||
|
||||
@@ -32,8 +32,13 @@ if ($errors) {
|
||||
|
||||
$db = Database::getInstance();
|
||||
$tenantId = $decoded['tenant_id'];
|
||||
$userId = $decoded['user_id'];
|
||||
$planId = $data['plan_id'];
|
||||
$userId = $decoded['user_id'];
|
||||
$planId = $data['plan_id'];
|
||||
$cycle = $data['billing_cycle'] ?? 'annual'; // Default to annual
|
||||
|
||||
if (!in_array($cycle, ['monthly', 'annual'])) {
|
||||
json_error('دورة الفوترة غير صالحة.', 422);
|
||||
}
|
||||
|
||||
try {
|
||||
// 1. Get plan details
|
||||
@@ -45,6 +50,9 @@ try {
|
||||
json_error('الباقة المختارة غير صالحة أو غير نشطة.', 422);
|
||||
}
|
||||
|
||||
// Determine amount based on cycle
|
||||
$amount = ($cycle === 'monthly') ? ($plan['price_monthly_jod'] ?? $plan['price_jod']) : ($plan['price_annual_jod'] ?? ($plan['price_jod'] * 10));
|
||||
|
||||
// 2. Check for existing pending payment for this tenant
|
||||
$stmt = $db->prepare("SELECT id FROM payment_requests WHERE tenant_id = ? AND status = 'pending' LIMIT 1");
|
||||
$stmt->execute([$tenantId]);
|
||||
@@ -68,15 +76,16 @@ try {
|
||||
// 6. Create payment request
|
||||
$paymentId = Database::generateUuid();
|
||||
$stmt = $db->prepare("
|
||||
INSERT INTO payment_requests (id, tenant_id, user_id, plan_id, amount_jod, internal_reference, cliq_alias, payer_name, status, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', NOW())
|
||||
INSERT INTO payment_requests (id, tenant_id, user_id, plan_id, billing_cycle, amount_jod, internal_reference, cliq_alias, payer_name, status, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', NOW())
|
||||
");
|
||||
$stmt->execute([
|
||||
$paymentId,
|
||||
$tenantId,
|
||||
$userId,
|
||||
$planId,
|
||||
$plan['price_jod'],
|
||||
$cycle,
|
||||
$amount,
|
||||
$referenceNumber,
|
||||
$cliqAlias,
|
||||
$user['name'] ?? ''
|
||||
@@ -88,17 +97,17 @@ try {
|
||||
$tenantId,
|
||||
$userId,
|
||||
$paymentId,
|
||||
json_encode(['plan_id' => $planId, 'amount' => $plan['price_jod'], 'ref' => $referenceNumber])
|
||||
json_encode(['plan_id' => $planId, 'cycle' => $cycle, 'amount' => $amount, 'ref' => $referenceNumber])
|
||||
]);
|
||||
|
||||
json_success([
|
||||
'payment_id' => $paymentId,
|
||||
'reference_number' => $referenceNumber,
|
||||
'cliq_alias' => $cliqAlias,
|
||||
'amount_jod' => (float)$plan['price_jod'],
|
||||
'plan_name' => $plan['name_ar'] ?? $plan['name_en'],
|
||||
'amount_jod' => (float)$amount,
|
||||
'plan_name' => ($plan['name_ar'] ?? $plan['name_en']) . " (" . ($cycle === 'monthly' ? 'شهري' : 'سنوي') . ")",
|
||||
'payer_name' => $user['name'] ?? '',
|
||||
'instructions' => "قم بالتحويل عبر CliQ إلى الاسم المستعار: {$cliqAlias} بمبلغ {$plan['price_jod']} دينار أردني.",
|
||||
'instructions' => "قم بالتحويل عبر CliQ إلى الاسم المستعار: {$cliqAlias} بمبلغ {$amount} دينار أردني.",
|
||||
], 'تم إنشاء طلب الدفع بنجاح');
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
|
||||
@@ -13,7 +13,7 @@ $db = Database::getInstance();
|
||||
try {
|
||||
$stmt = $db->query("
|
||||
SELECT id, name_ar, name_en, max_companies, max_invoices_month, max_users,
|
||||
price_jod, ai_features, jofotara_enabled, sort_order
|
||||
price_jod, price_annual_jod, price_monthly_jod, ai_features, jofotara_enabled, sort_order
|
||||
FROM subscription_plans
|
||||
WHERE is_active = 1
|
||||
ORDER BY sort_order ASC
|
||||
@@ -36,6 +36,8 @@ try {
|
||||
$plan['max_invoices_month'] = (int)$plan['max_invoices_month'];
|
||||
$plan['max_users'] = (int)$plan['max_users'];
|
||||
$plan['price_jod'] = (float)$plan['price_jod'];
|
||||
$plan['price_annual_jod'] = (float)$plan['price_annual_jod'];
|
||||
$plan['price_monthly_jod'] = (float)$plan['price_monthly_jod'];
|
||||
$plan['ai_features'] = (bool)$plan['ai_features'];
|
||||
$plan['jofotara_enabled'] = (bool)$plan['jofotara_enabled'];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user