Files
2026-09-21 04:06:43 +03:00

194 lines
5.4 KiB
Dart

import 'package:please_pay_me/data/api/api_client.dart';
import 'package:please_pay_me/data/models/auth_user.dart';
import 'package:please_pay_me/data/models/budget.dart';
import 'package:please_pay_me/data/models/expense.dart';
import 'package:please_pay_me/data/models/job.dart';
import 'package:please_pay_me/data/models/json.dart';
import 'package:please_pay_me/data/repositories/repositories.dart';
class ApiBudgetRepository implements BudgetRepository {
const ApiBudgetRepository(this._client);
final ApiClient _client;
@override
Future<List<BudgetStatus>> list() async {
final json = await _client.getJson('/api/me/budgets');
return BudgetsList.fromJson(json).items;
}
@override
Future<BudgetStatus> status({int? budgetId}) async {
final json = await _client.getJson(
'/api/me/budget',
query: {if (budgetId != null) 'budget_id': '$budgetId'},
);
return BudgetStatus.fromJson(json);
}
@override
Future<BudgetStatus> create({
required String name,
required double totalAmount,
required DateTime endDate,
DateTime? startDate,
}) async {
final json = await _client.postJson('/api/me/budgets', body: {
'name': name,
'total_amount': totalAmount,
'end_date': formatIsoDate(endDate),
'start_date': startDate == null ? null : formatIsoDate(startDate),
'is_active': true,
'select': true,
});
return BudgetStatus.fromJson(json);
}
@override
Future<BudgetStatus> update({
required int budgetId,
String? name,
double? totalAmount,
DateTime? endDate,
DateTime? startDate,
bool resetExpenses = false,
}) async {
final json = await _client.putJson('/api/me/budgets/$budgetId', body: {
if (name != null) 'name': name,
if (totalAmount != null) 'total_amount': totalAmount,
if (endDate != null) 'end_date': formatIsoDate(endDate),
if (startDate != null) 'start_date': formatIsoDate(startDate),
'reset_expenses': resetExpenses,
});
return BudgetStatus.fromJson(json);
}
@override
Future<BudgetStatus> select(int budgetId) async {
final json = await _client.postJson('/api/me/budgets/$budgetId/select');
return BudgetStatus.fromJson(json);
}
@override
Future<BudgetStatus> setActive(int budgetId, {required bool isActive}) async {
final json = await _client.patchJson(
'/api/me/budgets/$budgetId/active',
body: {'is_active': isActive},
);
return BudgetStatus.fromJson(json);
}
@override
Future<void> delete(int budgetId) => _client.deleteJson('/api/me/budgets/$budgetId');
}
class ApiExpenseRepository implements ExpenseRepository {
const ApiExpenseRepository(this._client);
final ApiClient _client;
@override
Future<ExpensesPage> page({
required int page,
int pageSize = 20,
int? budgetId,
bool all = false,
}) async {
final json = await _client.getJson('/api/me/expenses', query: {
'page': '$page',
'page_size': '$pageSize',
if (all) 'all': 'true' else if (budgetId != null) 'budget_id': '$budgetId',
});
return ExpensesPage.fromJson(json);
}
@override
Future<BudgetStatus> create({
required double amount,
String? note,
DateTime? spentAt,
int? budgetId,
}) async {
final json = await _client.postJson('/api/me/expenses', body: {
'amount': amount,
'note': note,
'spent_at': spentAt == null ? null : formatIsoDate(spentAt),
'budget_id': budgetId,
});
return BudgetStatus.fromJson(json);
}
@override
Future<double> undoLast({int? budgetId}) async {
final json = await _client.deleteJson(
'/api/me/expenses/last',
query: {if (budgetId != null) 'budget_id': '$budgetId'},
);
return asDouble(json['deleted_amount']);
}
}
class ApiJobRepository implements JobRepository {
const ApiJobRepository(this._client);
final ApiClient _client;
@override
Future<List<Job>> list() async {
final json = await _client.getJson('/api/me/jobs');
return JobsList.fromJson(json).items;
}
@override
Future<Job> create({
required String name,
required double salaryAmount,
required List<int> payDays,
required double firstPayPercent,
required WeekendPolicy weekendPolicy,
}) async {
final json = await _client.postJson('/api/me/jobs', body: {
'name': name,
'salary_amount': salaryAmount,
'pay_days': payDays,
'first_pay_percent': firstPayPercent,
'weekend_policy': weekendPolicy.wire,
'is_active': true,
});
return Job.fromJson(json);
}
@override
Future<Job> update({
required int jobId,
required String name,
required double salaryAmount,
required List<int> payDays,
required double firstPayPercent,
required WeekendPolicy weekendPolicy,
bool isActive = true,
}) async {
final json = await _client.putJson('/api/me/jobs/$jobId', body: {
'name': name,
'salary_amount': salaryAmount,
'pay_days': payDays,
'first_pay_percent': firstPayPercent,
'weekend_policy': weekendPolicy.wire,
'is_active': isActive,
});
return Job.fromJson(json);
}
@override
Future<void> delete(int jobId) => _client.deleteJson('/api/me/jobs/$jobId');
}
class ApiUserRepository implements UserRepository {
const ApiUserRepository(this._client);
final ApiClient _client;
@override
Future<AuthUser> me() async => AuthUser.fromJson(await _client.getJson('/api/me'));
}