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/payments.dart';
|
2025-12-14 20:36:05 +00:00
|
|
|
|
import 'mixins/soft_delete_mixin.dart';
|
2025-12-13 13:27:05 +00:00
|
|
|
|
|
|
|
|
|
|
part 'payment_dao.g.dart';
|
|
|
|
|
|
|
|
|
|
|
|
@DriftAccessor(tables: [Payments])
|
2025-12-20 18:26:15 +00:00
|
|
|
|
class PaymentDao extends DatabaseAccessor<AppDatabase>
|
2025-12-14 20:36:05 +00:00
|
|
|
|
with _$PaymentDaoMixin, SoftDeleteMixin<Payments, Payment> {
|
2025-12-13 13:27:05 +00:00
|
|
|
|
PaymentDao(super.db);
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
@override
|
|
|
|
|
|
TableInfo<Payments, Payment> get table => payments;
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
/// Получить платеж по ID (только активные)
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<Payment?> getPaymentById(String id) {
|
2025-12-14 20:36:05 +00:00
|
|
|
|
return getActiveById(id);
|
2025-12-13 13:27:05 +00:00
|
|
|
|
}
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
/// Получить платежи пользователя (только активные)
|
2025-12-20 18:26:15 +00:00
|
|
|
|
Future<List<Payment>> getPaymentsByUserId(
|
|
|
|
|
|
String userId, {
|
2025-12-13 13:27:05 +00:00
|
|
|
|
int? limit,
|
|
|
|
|
|
int? offset,
|
|
|
|
|
|
}) {
|
2025-12-14 20:36:05 +00:00
|
|
|
|
final query = selectActive()
|
2025-12-13 13:27:05 +00:00
|
|
|
|
..where((p) => p.userId.equals(userId))
|
|
|
|
|
|
..orderBy([(p) => OrderingTerm.desc(p.date)]);
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-13 13:27:05 +00:00
|
|
|
|
if (limit != null) {
|
|
|
|
|
|
query.limit(limit, offset: offset);
|
|
|
|
|
|
}
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-13 13:27:05 +00:00
|
|
|
|
return query.get();
|
|
|
|
|
|
}
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
/// Получить платежи по статусу (только активные)
|
2025-12-13 13:27:05 +00:00
|
|
|
|
Future<List<Payment>> getPaymentsByStatus(String status) {
|
2025-12-14 20:36:05 +00:00
|
|
|
|
return (selectActive()
|
2025-12-20 18:26:15 +00:00
|
|
|
|
..where((p) => p.status.equals(status))
|
|
|
|
|
|
..orderBy([(p) => OrderingTerm.desc(p.date)]))
|
|
|
|
|
|
.get();
|
2025-12-13 13:27:05 +00:00
|
|
|
|
}
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-13 13:27:05 +00:00
|
|
|
|
/// Создать платеж
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<String> createPayment(PaymentsCompanion payment) async {
|
|
|
|
|
|
final inserted = await into(payments).insertReturning(payment);
|
|
|
|
|
|
// Query back to get the id since Payment class doesn't have id field
|
|
|
|
|
|
// (database needs to be regenerated to include id in Payment class)
|
|
|
|
|
|
// Use externalToken if available, otherwise query by unique fields
|
|
|
|
|
|
if (inserted.externalToken != null && inserted.externalToken!.isNotEmpty) {
|
|
|
|
|
|
final result = await (customSelect(
|
|
|
|
|
|
'SELECT id FROM payments WHERE external_token = ? LIMIT 1',
|
|
|
|
|
|
variables: [Variable.withString(inserted.externalToken!)],
|
|
|
|
|
|
readsFrom: {payments},
|
|
|
|
|
|
).map((row) => row.read<String>('id')).getSingleOrNull());
|
|
|
|
|
|
if (result != null) return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
// Fallback: query by userId, date, and amount
|
|
|
|
|
|
final result = await (customSelect(
|
|
|
|
|
|
'SELECT id FROM payments WHERE user_id = ? AND date = ? AND amount = ? ORDER BY created_at DESC LIMIT 1',
|
|
|
|
|
|
variables: [
|
|
|
|
|
|
Variable.withString(payment.userId.value),
|
2025-12-13 23:35:14 +00:00
|
|
|
|
Variable.withDateTime(inserted.date.dateTime),
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Variable.withString(inserted.amount),
|
|
|
|
|
|
],
|
|
|
|
|
|
readsFrom: {payments},
|
|
|
|
|
|
).map((row) => row.read<String>('id')).getSingleOrNull());
|
|
|
|
|
|
if (result != null) return result;
|
|
|
|
|
|
throw Exception('Failed to retrieve payment ID after creation');
|
2025-12-13 13:27:05 +00:00
|
|
|
|
}
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-13 13:27:05 +00:00
|
|
|
|
/// Обновить платеж
|
|
|
|
|
|
Future<bool> updatePayment(Payment payment) {
|
|
|
|
|
|
return update(payments).replace(payment);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Обновить платеж частично
|
2025-12-20 18:26:15 +00:00
|
|
|
|
Future<void> updatePaymentCompanion(
|
|
|
|
|
|
String paymentId,
|
|
|
|
|
|
PaymentsCompanion companion,
|
|
|
|
|
|
) {
|
|
|
|
|
|
return (update(
|
|
|
|
|
|
payments,
|
|
|
|
|
|
)..where((p) => p.id.equals(paymentId))).write(companion);
|
2025-12-13 13:27:05 +00:00
|
|
|
|
}
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-13 13:27:05 +00:00
|
|
|
|
/// Обновить статус платежа
|
2025-12-13 20:55:50 +00:00
|
|
|
|
Future<void> updatePaymentStatus(String paymentId, String status) {
|
2025-12-20 18:26:15 +00:00
|
|
|
|
return (update(payments)..where((p) => p.id.equals(paymentId))).write(
|
|
|
|
|
|
PaymentsCompanion(
|
|
|
|
|
|
status: Value(status),
|
|
|
|
|
|
updatedAt: Value(PgDateTime(DateTime.now())),
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
2025-12-13 13:27:05 +00:00
|
|
|
|
}
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
/// Получить платеж по externalToken (только активные)
|
2025-12-13 13:27:05 +00:00
|
|
|
|
Future<Payment?> getPaymentByExternalToken(String token) {
|
2025-12-14 20:36:05 +00:00
|
|
|
|
return (selectActive()..where((p) => p.externalToken.equals(token)))
|
2025-12-13 13:27:05 +00:00
|
|
|
|
.getSingleOrNull();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
/// Получить платежи по продукту (store ID) (только активные)
|
2025-12-13 13:27:05 +00:00
|
|
|
|
Future<List<Payment>> getPaymentsByProduct(String productId) async {
|
|
|
|
|
|
// Поиск по продуктам в JSON массиве
|
2025-12-20 18:26:15 +00:00
|
|
|
|
final query = selectActive()..where((p) => p.products.like('%$productId%'));
|
2025-12-13 13:27:05 +00:00
|
|
|
|
|
|
|
|
|
|
return query.get();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
/// Получить платежи по статусу с пагинацией (только активные)
|
2025-12-13 13:27:05 +00:00
|
|
|
|
Future<List<Payment>> getPaymentsByStatusPaged(
|
|
|
|
|
|
String status, {
|
|
|
|
|
|
int? limit,
|
|
|
|
|
|
int? offset,
|
|
|
|
|
|
}) {
|
2025-12-14 20:36:05 +00:00
|
|
|
|
final query = selectActive()
|
2025-12-13 13:27:05 +00:00
|
|
|
|
..where((p) => p.status.equals(status))
|
|
|
|
|
|
..orderBy([(p) => OrderingTerm.desc(p.date)]);
|
|
|
|
|
|
|
|
|
|
|
|
if (limit != null) {
|
|
|
|
|
|
query.limit(limit, offset: offset);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return query.get();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
/// Получить все платежи (для админки) (только активные)
|
2025-12-20 18:26:15 +00:00
|
|
|
|
Future<List<Payment>> getAllPayments({int? limit, int? offset}) {
|
|
|
|
|
|
final query = selectActive()..orderBy([(p) => OrderingTerm.desc(p.date)]);
|
2025-12-13 13:27:05 +00:00
|
|
|
|
|
|
|
|
|
|
if (limit != null) {
|
|
|
|
|
|
query.limit(limit, offset: offset);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return query.get();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
/// Подсчитать все платежи (только активные)
|
2025-12-13 13:27:05 +00:00
|
|
|
|
Future<int> countAllPayments() async {
|
|
|
|
|
|
final countExpr = payments.id.count();
|
2025-12-14 20:36:05 +00:00
|
|
|
|
final query = selectOnly(payments)
|
|
|
|
|
|
..addColumns([countExpr])
|
|
|
|
|
|
..where(payments.isDeleted.equals(false));
|
|
|
|
|
|
|
|
|
|
|
|
return await query.map((row) => row.read(countExpr)!).getSingle();
|
|
|
|
|
|
}
|
2025-12-20 18:26:15 +00:00
|
|
|
|
|
2025-12-14 20:36:05 +00:00
|
|
|
|
/// Подсчитать платежи пользователя (только активные)
|
|
|
|
|
|
@override
|
|
|
|
|
|
Future<int> countPaymentsByUserId(String userId) async {
|
|
|
|
|
|
final countExpr = payments.id.count();
|
|
|
|
|
|
final query = selectOnly(payments)
|
|
|
|
|
|
..addColumns([countExpr])
|
2025-12-20 18:26:15 +00:00
|
|
|
|
..where(
|
|
|
|
|
|
payments.userId.equals(userId) & payments.isDeleted.equals(false),
|
|
|
|
|
|
);
|
2025-12-13 13:27:05 +00:00
|
|
|
|
|
|
|
|
|
|
return await query.map((row) => row.read(countExpr)!).getSingle();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|