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() async { final json = await _client.getJson('/api/me/budgets'); return BudgetsList.fromJson(json).items; } @override Future 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 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 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 select(int budgetId) async { final json = await _client.postJson('/api/me/budgets/$budgetId/select'); return BudgetStatus.fromJson(json); } @override Future 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 delete(int budgetId) => _client.deleteJson('/api/me/budgets/$budgetId'); } class ApiExpenseRepository implements ExpenseRepository { const ApiExpenseRepository(this._client); final ApiClient _client; @override Future 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 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 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() async { final json = await _client.getJson('/api/me/jobs'); return JobsList.fromJson(json).items; } @override Future create({ required String name, required double salaryAmount, required List 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 update({ required int jobId, required String name, required double salaryAmount, required List 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 delete(int jobId) => _client.deleteJson('/api/me/jobs/$jobId'); } class ApiUserRepository implements UserRepository { const ApiUserRepository(this._client); final ApiClient _client; @override Future me() async => AuthUser.fromJson(await _client.getJson('/api/me')); }