mnemo_cards/mnemo_cards_backend/lib/api/subscription/subscription_manager.dart
2025-11-16 14:25:27 +03:00

139 lines
4 KiB
Dart

import 'dart:developer';
import 'package:injectable/injectable.dart';
import 'package:isar/isar.dart';
import 'package:mnemo_cards_backend/api/subscription/extension.dart';
import 'package:mnemo_cards_common_backend/mnemo_cards_common_backend.dart';
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
import '../../main.dart';
@lazySingleton
class SubscriptionManager {
Future<SubscriptionDto> getSubscriptionDto(UserModel user) async {
await user.subscriptionModel.load();
final subscription = user.subscriptionModel.value;
if (subscription != null && subscription.isActive) {
return _activeSubscriptionDto(user, subscription);
} else {
return _buySubscriptionDto(user);
}
}
Future<SubscriptionPlanModel?> getSubscriptionPlan(String id) async {
final intId = int.tryParse(id);
if (intId == null) {
log('Incorrect id: $id');
return null;
}
final model = await isar.txn(() => isar.subscriptionPlanModels.get(intId));
return model;
}
Future<SubscriptionDto> _activeSubscriptionDto(
UserModel user,
UserSubscriptionModel subscription,
) async {
final days = subscription.finish.difference(DateTime.now()).abs().inDays;
return SubscriptionDto(
page: SubscriptionPageDto(
title: 'Ваша подписка',
items: [
TextItem(
title: '',
),
TextItem(
title:
days > 0 ? 'Действует еще ${days} дней' : 'Закончится сегодня',
),
SpacerItem(),
],
plans: [],
),
isActive: true,
start: user.subscriptionModel.value?.start,
finish: user.subscriptionModel.value?.finish,
);
}
Future<SubscriptionDto> _buySubscriptionDto(UserModel user) async {
final plans = await isar.txn(
() => isar.subscriptionPlanModels
.filter()
.paymentSystemEqualTo(PaymentSystem.yookassa)
.findAll(),
);
plans.sort((p, n) => p.durationDays.compareTo(n.durationDays));
return SubscriptionDto(
page: SubscriptionPageDto(
title: 'Подписка',
items: [
SpacerItem(
flex: 1,
height: 10,
),
TextItem(title: 'Открывает все наборы!', color: '#ff'),
TextItem(
title: 'Убирает всю рекламу!',
),
SpacerItem(
flex: 2,
),
],
plans: [
...await Future.wait(
plans.map(
(plan) => plan.toDto(),
),
),
],
),
isActive: false,
start: null,
finish: null,
);
}
Future<List<SubscriptionPlanAdminDto>> getAllSubscriptionPlans() async {
final models =
await isar.txn(() => isar.subscriptionPlanModels.where().findAll());
return Future.wait(models.map((model) => model.toAdminDto()));
}
Future<bool> deleteSubscriptionPlans(String id) async {
final intId = int.parse(id);
return isar.writeTxn(() {
return isar.subscriptionPlanModels.delete(intId);
});
}
Future<bool> addSubscriptionPlans(SubscriptionPlanAdminDto dto) async {
final model = await int.tryParse(dto.id ?? '')
?.let((id) => isar.subscriptionPlanModels.get(id)) ??
SubscriptionPlanModel(
ui: null,
price: dto.price,
currency: dto.currency,
durationDays: dto.durationDays,
features: dto.features,
paymentSystem: dto.paymentSystem,
paymentId: dto.paymentId,
);
final updatedModel = model.copyWith(
id: model.id,
ui: dto.ui.toModel(),
price: dto.price,
currency: dto.currency,
durationDays: dto.durationDays,
features: dto.features,
paymentId: dto.paymentId,
paymentSystem: dto.paymentSystem,
);
await isar.writeTxn(
() => isar.subscriptionPlanModels.put(updatedModel),
);
return true;
}
}