| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import '../../core/storage/draft_storage.dart';
- import 'expense_model.dart';
- import 'expense_api.dart';
- const expenseDraftKey = 'expense';
- class ExpenseCreateState {
- final ExpenseModel expense;
- final bool isSubmitting;
- const ExpenseCreateState({required this.expense, this.isSubmitting = false});
- ExpenseCreateState copyWith({ExpenseModel? expense, bool? isSubmitting}) {
- return ExpenseCreateState(
- expense: expense ?? this.expense,
- isSubmitting: isSubmitting ?? this.isSubmitting,
- );
- }
- }
- class ExpenseCreateController extends StateNotifier<ExpenseCreateState> {
- final ExpenseApi _api;
- ExpenseCreateController(this._api, {ExpenseModel? initial})
- : super(
- ExpenseCreateState(
- expense:
- initial ??
- ExpenseModel(
- id: '',
- expenseNo: '',
- createTime: DateTime.now(),
- updateTime: DateTime.now(),
- ),
- ),
- );
- void updateCurrencyCode(String code) {
- state = state.copyWith(expense: state.expense.copyWith(currencyCode: code));
- }
- void updateApprovedAmount(double amount) {
- state = state.copyWith(expense: state.expense.copyWith(approvedAmount: amount));
- }
- void updateDetailApprovedAmount(int index, double amount) {
- final details = [...state.expense.details];
- details[index] = details[index].copyWith(approvedAmount: amount);
- state = state.copyWith(expense: state.expense.copyWith(details: details));
- }
- void updateDetailCustomerVendor(int index, String name) {
- final details = [...state.expense.details];
- details[index] = details[index].copyWith(customerVendorName: name);
- state = state.copyWith(expense: state.expense.copyWith(details: details));
- }
- void updateDetailProjectId(int index, String id) {
- final details = [...state.expense.details];
- details[index] = details[index].copyWith(projectId: id);
- state = state.copyWith(expense: state.expense.copyWith(details: details));
- }
- void updateDetailAcctSubjectId(int index, String id) {
- final details = [...state.expense.details];
- details[index] = details[index].copyWith(acctSubjectId: id);
- state = state.copyWith(expense: state.expense.copyWith(details: details));
- }
- void updateDetailOffsetAmount(int index, double amount) {
- final details = [...state.expense.details];
- details[index] = details[index].copyWith(offsetAmount: amount);
- state = state.copyWith(expense: state.expense.copyWith(details: details));
- }
- void restoreFromDraft(ExpenseModel draft, ExpenseApi api) {
- state = ExpenseCreateState(expense: draft);
- }
- void updatePurpose(String purpose) {
- state = state.copyWith(expense: state.expense.copyWith(purpose: purpose));
- }
- void addDetail(ExpenseDetailModel detail) {
- final details = [...state.expense.details, detail];
- state = state.copyWith(expense: state.expense.copyWith(details: details));
- }
- void removeDetail(int index) {
- final details = [...state.expense.details]..removeAt(index);
- state = state.copyWith(expense: state.expense.copyWith(details: details));
- }
- void recalculateAmount() {
- var totalAmount = 0.0;
- var approvedAmount = 0.0;
- for (final d in state.expense.details) {
- totalAmount += d.totalAmount;
- approvedAmount += d.approvedAmount;
- }
- state = state.copyWith(
- expense: state.expense.copyWith(
- totalAmount: totalAmount,
- approvedAmount: approvedAmount,
- ),
- );
- }
- Future<bool> submit() async {
- state = state.copyWith(isSubmitting: true);
- try {
- await _api.submit(state.expense.copyWith(status: 'pending').toJson());
- await DraftStorage.delete(expenseDraftKey);
- return true;
- } catch (_) {
- return false;
- } finally {
- state = state.copyWith(isSubmitting: false);
- }
- }
- Future<bool> saveDraft() async {
- state = state.copyWith(isSubmitting: true);
- try {
- await DraftStorage.save(expenseDraftKey, state.expense.toJson());
- return true;
- } catch (_) {
- return false;
- } finally {
- state = state.copyWith(isSubmitting: false);
- }
- }
- static Future<ExpenseModel?> loadDraft() async {
- final data = await DraftStorage.load(expenseDraftKey);
- if (data == null) return null;
- try {
- return ExpenseModel.fromJson(data);
- } catch (_) {
- return null;
- }
- }
- static Future<bool> hasDraft() => DraftStorage.has(expenseDraftKey);
- static Future<void> deleteDraft() => DraftStorage.delete(expenseDraftKey);
- }
- final expenseCreateProvider = StateNotifierProvider.autoDispose
- .family<ExpenseCreateController, ExpenseCreateState, String?>((ref, editId) {
- final api = ref.watch(expenseApiProvider);
- return ExpenseCreateController(api);
- });
|