import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; import 'package:redux/redux.dart'; import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; import 'package:invoiceninja_flutter/ui/expense/expense_screen.dart'; import 'package:invoiceninja_flutter/ui/expense/edit/expense_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/expense/view/expense_view_vm.dart'; import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/data/repositories/expense_repository.dart'; import 'package:invoiceninja_flutter/main_app.dart'; List> createStoreExpensesMiddleware([ ExpenseRepository repository = const ExpenseRepository(), ]) { final viewExpenseList = _viewExpenseList(); final viewExpense = _viewExpense(); final editExpense = _editExpense(); final loadExpenses = _loadExpenses(repository); final loadExpense = _loadExpense(repository); final saveExpense = _saveExpense(repository); final archiveExpense = _archiveExpense(repository); final deleteExpense = _deleteExpense(repository); final restoreExpense = _restoreExpense(repository); final saveDocument = _saveDocument(repository); return [ TypedMiddleware(viewExpenseList), TypedMiddleware(viewExpense), TypedMiddleware(editExpense), TypedMiddleware(loadExpenses), TypedMiddleware(loadExpense), TypedMiddleware(saveExpense), TypedMiddleware(archiveExpense), TypedMiddleware(deleteExpense), TypedMiddleware(restoreExpense), TypedMiddleware(saveDocument), ]; } Middleware _editExpense() { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as EditExpense; next(action); store.dispatch(UpdateCurrentRoute(ExpenseEditScreen.route)); if (store.state.prefState.isMobile) { navigatorKey.currentState.pushNamed(ExpenseEditScreen.route); } }; } Middleware _viewExpense() { return (Store store, dynamic dynamicAction, NextDispatcher next) async { final action = dynamicAction as ViewExpense; next(action); store.dispatch(UpdateCurrentRoute(ExpenseViewScreen.route)); if (store.state.prefState.isMobile) { navigatorKey.currentState.pushNamed(ExpenseViewScreen.route); } }; } Middleware _viewExpenseList() { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as ViewExpenseList; next(action); if (store.state.isStale) { store.dispatch(RefreshData()); } store.dispatch(UpdateCurrentRoute(ExpenseScreen.route)); if (store.state.prefState.isMobile) { navigatorKey.currentState.pushNamedAndRemoveUntil( ExpenseScreen.route, (Route route) => false); } }; } Middleware _archiveExpense(ExpenseRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as ArchiveExpenseRequest; final prevExpenses = action.expenseIds .map((id) => store.state.expenseState.map[id]) .toList(); repository .bulkAction( store.state.credentials, action.expenseIds, EntityAction.archive) .then((List expenses) { store.dispatch(ArchiveExpenseSuccess(expenses)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(ArchiveExpenseFailure(prevExpenses)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _deleteExpense(ExpenseRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as DeleteExpenseRequest; final prevExpenses = action.expenseIds .map((id) => store.state.expenseState.map[id]) .toList(); repository .bulkAction( store.state.credentials, action.expenseIds, EntityAction.delete) .then((List expenses) { store.dispatch(DeleteExpenseSuccess(expenses)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(DeleteExpenseFailure(prevExpenses)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _restoreExpense(ExpenseRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as RestoreExpenseRequest; final prevExpenses = action.expenseIds .map((id) => store.state.expenseState.map[id]) .toList(); repository .bulkAction( store.state.credentials, action.expenseIds, EntityAction.restore) .then((List expenses) { store.dispatch(RestoreExpenseSuccess(expenses)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(RestoreExpenseFailure(prevExpenses)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _saveExpense(ExpenseRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as SaveExpenseRequest; repository .saveData(store.state.credentials, action.expense) .then((ExpenseEntity expense) { if (action.expense.isNew) { store.dispatch(AddExpenseSuccess(expense)); } else { store.dispatch(SaveExpenseSuccess(expense)); } action.completer.complete(expense); }).catchError((Object error) { print(error); store.dispatch(SaveExpenseFailure(error)); action.completer.completeError(error); }); next(action); }; } Middleware _loadExpense(ExpenseRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as LoadExpense; store.dispatch(LoadExpenseRequest()); repository .loadItem(store.state.credentials, action.expenseId) .then((expense) { store.dispatch(LoadExpenseSuccess(expense)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); store.dispatch(LoadExpenseFailure(error)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _loadExpenses(ExpenseRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as LoadExpenses; final state = store.state; store.dispatch(LoadExpensesRequest()); repository.loadList(state.credentials, state.createdAtLimit).then((data) { store.dispatch(LoadExpensesSuccess(data)); if (action.completer != null) { action.completer.complete(null); } store.dispatch(PersistData()); }).catchError((Object error) { print(error); store.dispatch(LoadExpensesFailure(error)); if (action.completer != null) { action.completer.completeError(error); } }); next(action); }; } Middleware _saveDocument(ExpenseRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as SaveExpenseDocumentRequest; if (store.state.isEnterprisePlan) { repository .uploadDocument( store.state.credentials, action.expense, action.multipartFile) .then((expense) { store.dispatch(SaveExpenseSuccess(expense)); action.completer.complete(null); }).catchError((Object error) { print(error); store.dispatch(SaveExpenseDocumentFailure(error)); action.completer.completeError(error); }); } else { const error = 'Uploading documents requires an enterprise plan'; store.dispatch(SaveExpenseDocumentFailure(error)); action.completer.completeError(error); } next(action); }; }