96 lines
2.5 KiB
Dart
96 lines
2.5 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:please_pay_me/core/state/async_value.dart';
|
|
import 'package:please_pay_me/data/api/api_client.dart';
|
|
import 'package:please_pay_me/data/models/job.dart';
|
|
import 'package:please_pay_me/data/repositories/repositories.dart';
|
|
|
|
class JobsController extends ChangeNotifier {
|
|
JobsController({required JobRepository jobs}) : _jobs = jobs;
|
|
|
|
final JobRepository _jobs;
|
|
|
|
AsyncValue<List<Job>> _state = const AsyncValue.loading();
|
|
bool _mutating = false;
|
|
|
|
AsyncValue<List<Job>> get state => _state;
|
|
bool get isMutating => _mutating;
|
|
List<Job> get items => _state.valueOrNull ?? const [];
|
|
|
|
/// Nearest payday across all jobs — shown on the overview screen.
|
|
UpcomingPay? get nextPay {
|
|
final pays = items.expand((job) => job.nextPays).toList()
|
|
..sort((a, b) => a.date.compareTo(b.date));
|
|
return pays.isEmpty ? null : pays.first;
|
|
}
|
|
|
|
Future<void> load({bool silent = false}) async {
|
|
if (!silent) {
|
|
_state = const AsyncValue.loading();
|
|
notifyListeners();
|
|
}
|
|
|
|
try {
|
|
_state = AsyncValue.data(await _jobs.list());
|
|
} on ApiException catch (error) {
|
|
_state = AsyncValue.error(error.message);
|
|
}
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<String?> create({
|
|
required String name,
|
|
required double salaryAmount,
|
|
required List<int> payDays,
|
|
required double firstPayPercent,
|
|
required WeekendPolicy weekendPolicy,
|
|
}) {
|
|
return _mutate(
|
|
() => _jobs.create(
|
|
name: name,
|
|
salaryAmount: salaryAmount,
|
|
payDays: payDays,
|
|
firstPayPercent: firstPayPercent,
|
|
weekendPolicy: weekendPolicy,
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<String?> update({
|
|
required int jobId,
|
|
required String name,
|
|
required double salaryAmount,
|
|
required List<int> payDays,
|
|
required double firstPayPercent,
|
|
required WeekendPolicy weekendPolicy,
|
|
}) {
|
|
return _mutate(
|
|
() => _jobs.update(
|
|
jobId: jobId,
|
|
name: name,
|
|
salaryAmount: salaryAmount,
|
|
payDays: payDays,
|
|
firstPayPercent: firstPayPercent,
|
|
weekendPolicy: weekendPolicy,
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<String?> delete(int jobId) => _mutate(() => _jobs.delete(jobId));
|
|
|
|
Future<String?> _mutate(Future<void> Function() action) async {
|
|
_mutating = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
await action();
|
|
await load(silent: true);
|
|
return null;
|
|
} on ApiException catch (error) {
|
|
return error.message;
|
|
} finally {
|
|
_mutating = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
}
|