2025-12-13 13:27:05 +00:00
|
|
|
|
import 'package:drift/drift.dart';
|
2025-12-13 23:35:14 +00:00
|
|
|
|
import 'package:drift_postgres/drift_postgres.dart';
|
2025-12-13 13:27:05 +00:00
|
|
|
|
import '../database.dart';
|
|
|
|
|
|
import '../tables/subscriptions.dart';
|
|
|
|
|
|
import '../tables/users.dart';
|
|
|
|
|
|
|
|
|
|
|
|
part 'subscription_dao.g.dart';
|
|
|
|
|
|
|
|
|
|
|
|
@DriftAccessor(tables: [SubscriptionPlans, UserSubscriptions])
|
|
|
|
|
|
class SubscriptionDao extends DatabaseAccessor<AppDatabase> with _$SubscriptionDaoMixin {
|
|
|
|
|
|
SubscriptionDao(super.db);
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== SubscriptionPlans ====================
|
|
|
|
|
|
|
|
|
|
|
|
/// Получить план подписки по ID
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<SubscriptionPlan?> getPlanById(String id) {
|
2025-12-13 13:27:05 +00:00
|
|
|
|
return (select(subscriptionPlans)..where((p) => p.id.equals(id))).getSingleOrNull();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Получить все планы подписки
|
|
|
|
|
|
Future<List<SubscriptionPlan>> getAllPlans() {
|
|
|
|
|
|
return (select(subscriptionPlans)
|
|
|
|
|
|
..where((p) => p.isDeleted.equals(false))
|
|
|
|
|
|
).get();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Создать план подписки
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<String> createPlan(SubscriptionPlansCompanion plan) async {
|
|
|
|
|
|
final inserted = await into(subscriptionPlans).insertReturning(plan);
|
|
|
|
|
|
return inserted.id;
|
2025-12-13 13:27:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Обновить план подписки
|
|
|
|
|
|
Future<bool> updatePlan(SubscriptionPlan plan) {
|
|
|
|
|
|
return update(subscriptionPlans).replace(plan);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== UserSubscriptions ====================
|
|
|
|
|
|
|
|
|
|
|
|
/// Получить подписку пользователя
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<UserSubscription?> getUserSubscription(String userId) {
|
2025-12-13 13:27:05 +00:00
|
|
|
|
return (select(userSubscriptions)
|
|
|
|
|
|
..where((us) => us.userId.equals(userId))
|
|
|
|
|
|
..orderBy([(us) => OrderingTerm.desc(us.finish)])
|
|
|
|
|
|
).getSingleOrNull();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Получить активную подписку пользователя
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<UserSubscription?> getActiveSubscription(String userId) async {
|
2025-12-13 23:35:14 +00:00
|
|
|
|
final now = PgDateTime(DateTime.now());
|
2025-12-13 13:27:05 +00:00
|
|
|
|
return (select(userSubscriptions)
|
|
|
|
|
|
..where((us) => us.userId.equals(userId))
|
|
|
|
|
|
..where((us) => us.start.isSmallerThanValue(now))
|
|
|
|
|
|
..where((us) => us.finish.isBiggerThanValue(now))
|
|
|
|
|
|
..orderBy([(us) => OrderingTerm.desc(us.finish)])
|
|
|
|
|
|
).getSingleOrNull();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Проверить, есть ли у пользователя активная подписка
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<bool> hasActiveSubscription(String userId) async {
|
2025-12-13 13:27:05 +00:00
|
|
|
|
final subscription = await getActiveSubscription(userId);
|
|
|
|
|
|
return subscription != null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Создать подписку пользователя
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<String> createUserSubscription(UserSubscriptionsCompanion subscription) async {
|
|
|
|
|
|
final inserted = await into(userSubscriptions).insertReturning(subscription);
|
|
|
|
|
|
return inserted.id;
|
2025-12-13 13:27:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Обновить подписку пользователя
|
|
|
|
|
|
Future<bool> updateUserSubscription(UserSubscription subscription) {
|
|
|
|
|
|
return update(userSubscriptions).replace(subscription);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Удалить подписку пользователя
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<void> deleteUserSubscription(String userId) {
|
2025-12-13 13:27:05 +00:00
|
|
|
|
return (delete(userSubscriptions)
|
|
|
|
|
|
..where((us) => us.userId.equals(userId))
|
|
|
|
|
|
).go();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Получить всех пользователей с активными подписками
|
|
|
|
|
|
Future<List<UserSubscription>> getActiveSubscriptions() async {
|
2025-12-13 23:35:14 +00:00
|
|
|
|
final now = PgDateTime(DateTime.now());
|
2025-12-13 13:27:05 +00:00
|
|
|
|
return (select(userSubscriptions)
|
|
|
|
|
|
..where((us) => us.start.isSmallerThanValue(now))
|
|
|
|
|
|
..where((us) => us.finish.isBiggerThanValue(now))
|
|
|
|
|
|
..orderBy([(us) => OrderingTerm.desc(us.finish)])
|
|
|
|
|
|
).get();
|
|
|
|
|
|
}
|
2025-12-13 14:48:00 +00:00
|
|
|
|
|
|
|
|
|
|
/// Получить активную подписку пользователя (alias для getActiveSubscription)
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<UserSubscription?> getActiveUserSubscription(String userId) {
|
2025-12-13 14:48:00 +00:00
|
|
|
|
return getActiveSubscription(userId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Отменить подписку пользователя (установить finish на текущее время)
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<void> cancelUserSubscription(String userId) async {
|
2025-12-13 14:48:00 +00:00
|
|
|
|
final subscription = await getActiveSubscription(userId);
|
|
|
|
|
|
if (subscription != null) {
|
|
|
|
|
|
await update(userSubscriptions).replace(
|
|
|
|
|
|
subscription.copyWith(
|
2025-12-13 23:35:14 +00:00
|
|
|
|
finish: PgDateTime(DateTime.now()),
|
2025-12-13 14:48:00 +00:00
|
|
|
|
),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-13 13:27:05 +00:00
|
|
|
|
}
|