invoice/lib/redux/quote/quote_middleware.dart

499 lines
16 KiB
Dart

// Flutter imports:
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/constants.dart';
// Package imports:
import 'package:redux/redux.dart';
// Project imports:
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/data/repositories/quote_repository.dart';
import 'package:invoiceninja_flutter/main_app.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/quote/edit/quote_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/quote/quote_email_vm.dart';
import 'package:invoiceninja_flutter/ui/quote/quote_pdf_vm.dart';
import 'package:invoiceninja_flutter/ui/quote/quote_screen.dart';
import 'package:invoiceninja_flutter/ui/quote/view/quote_view_vm.dart';
List<Middleware<AppState>> createStoreQuotesMiddleware([
QuoteRepository repository = const QuoteRepository(),
]) {
final viewQuoteList = _viewQuoteList();
final viewQuote = _viewQuote();
final editQuote = _editQuote();
final showEmailQuote = _showEmailQuote();
final showPdfQuote = _showPdfQuote();
final convertQuotesToInvoices = _convertQuotesToInvoices(repository);
final convertQuotesToProjects = _convertQuotesToProjects(repository);
final approveQuote = _approveQuote(repository);
final loadQuotes = _loadQuotes(repository);
final loadQuote = _loadQuote(repository);
final saveQuote = _saveQuote(repository);
final archiveQuote = _archiveQuote(repository);
final deleteQuote = _deleteQuote(repository);
final restoreQuote = _restoreQuote(repository);
final emailQuote = _emailQuote(repository);
final bulkEmailQuotes = _bulkEmailQuotes(repository);
final markSentQuote = _markSentQuote(repository);
final downloadQuotes = _downloadQuotes(repository);
final saveDocument = _saveDocument(repository);
return [
TypedMiddleware<AppState, ViewQuoteList>(viewQuoteList),
TypedMiddleware<AppState, ViewQuote>(viewQuote),
TypedMiddleware<AppState, EditQuote>(editQuote),
TypedMiddleware<AppState, ConvertQuotesToInvoices>(convertQuotesToInvoices),
TypedMiddleware<AppState, ConvertQuotesToProjects>(convertQuotesToProjects),
TypedMiddleware<AppState, ApproveQuotes>(approveQuote),
TypedMiddleware<AppState, ShowEmailQuote>(showEmailQuote),
TypedMiddleware<AppState, ShowPdfQuote>(showPdfQuote),
TypedMiddleware<AppState, LoadQuotes>(loadQuotes),
TypedMiddleware<AppState, LoadQuote>(loadQuote),
TypedMiddleware<AppState, SaveQuoteRequest>(saveQuote),
TypedMiddleware<AppState, ArchiveQuotesRequest>(archiveQuote),
TypedMiddleware<AppState, DeleteQuotesRequest>(deleteQuote),
TypedMiddleware<AppState, RestoreQuotesRequest>(restoreQuote),
TypedMiddleware<AppState, EmailQuoteRequest>(emailQuote),
TypedMiddleware<AppState, BulkEmailQuotesRequest>(bulkEmailQuotes),
TypedMiddleware<AppState, MarkSentQuotesRequest>(markSentQuote),
TypedMiddleware<AppState, DownloadQuotesRequest>(downloadQuotes),
TypedMiddleware<AppState, SaveQuoteDocumentRequest>(saveDocument),
];
}
Middleware<AppState> _viewQuote() {
return (Store<AppState> store, dynamic dynamicAction,
NextDispatcher next) async {
final action = dynamicAction as ViewQuote;
next(action);
store.dispatch(UpdateCurrentRoute(QuoteViewScreen.route));
if (store.state.prefState.isMobile) {
await navigatorKey.currentState.pushNamed(QuoteViewScreen.route);
}
};
}
Middleware<AppState> _viewQuoteList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewQuoteList;
next(action);
if (store.state.isStale) {
store.dispatch(RefreshData());
}
store.dispatch(UpdateCurrentRoute(QuoteScreen.route));
if (store.state.prefState.isMobile) {
navigatorKey.currentState.pushNamedAndRemoveUntil(
QuoteScreen.route, (Route<dynamic> route) => false);
}
};
}
Middleware<AppState> _editQuote() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as EditQuote;
next(action);
store.dispatch(UpdateCurrentRoute(QuoteEditScreen.route));
if (store.state.prefState.isMobile) {
navigatorKey.currentState.pushNamed(QuoteEditScreen.route);
}
};
}
Middleware<AppState> _showEmailQuote() {
return (Store<AppState> store, dynamic dynamicAction,
NextDispatcher next) async {
final action = dynamicAction as ShowEmailQuote;
next(action);
store.dispatch(UpdateCurrentRoute(QuoteEmailScreen.route));
if (store.state.prefState.isMobile) {
final emailWasSent =
await navigatorKey.currentState.pushNamed(QuoteEmailScreen.route);
if (action.completer != null && emailWasSent != null && emailWasSent) {
action.completer.complete(null);
}
}
};
}
Middleware<AppState> _showPdfQuote() {
return (Store<AppState> store, dynamic dynamicAction,
NextDispatcher next) async {
final action = dynamicAction as ShowPdfQuote;
next(action);
store.dispatch(UpdateCurrentRoute(QuotePdfScreen.route));
if (store.state.prefState.isMobile) {
navigatorKey.currentState.pushNamed(QuotePdfScreen.route);
}
};
}
Middleware<AppState> _archiveQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ArchiveQuotesRequest;
final prevQuotes =
action.quoteIds.map((id) => store.state.quoteState.map[id]).toList();
repository
.bulkAction(
store.state.credentials, action.quoteIds, EntityAction.archive)
.then((List<InvoiceEntity> quotes) {
store.dispatch(ArchiveQuotesSuccess(quotes));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(ArchiveQuotesFailure(prevQuotes));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _deleteQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as DeleteQuotesRequest;
final prevQuotes =
action.quoteIds.map((id) => store.state.quoteState.map[id]).toList();
repository
.bulkAction(
store.state.credentials, action.quoteIds, EntityAction.delete)
.then((List<InvoiceEntity> quotes) {
store.dispatch(DeleteQuotesSuccess(quotes));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(DeleteQuotesFailure(prevQuotes));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _restoreQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as RestoreQuotesRequest;
final prevQuotes =
action.quoteIds.map((id) => store.state.quoteState.map[id]).toList();
repository
.bulkAction(
store.state.credentials, action.quoteIds, EntityAction.restore)
.then((List<InvoiceEntity> quotes) {
store.dispatch(RestoreQuotesSuccess(quotes));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(RestoreQuotesFailure(prevQuotes));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _convertQuotesToInvoices(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ConvertQuotesToInvoices;
repository
.bulkAction(store.state.credentials, action.quoteIds,
EntityAction.convertToInvoice)
.then((quotes) {
store.dispatch(ConvertQuotesToInvoicesSuccess(quotes: quotes));
store.dispatch(RefreshData());
action.completer.complete(null);
}).catchError((Object error) {
print(error);
store.dispatch(ConvertQuotesToInvoicesFailure(error));
action.completer.completeError(error);
});
next(action);
};
}
Middleware<AppState> _convertQuotesToProjects(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ConvertQuotesToProjects;
repository
.bulkAction(store.state.credentials, action.quoteIds,
EntityAction.convertToProject)
.then((quotes) {
store.dispatch(ConvertQuotesToProjectsSuccess(quotes: quotes));
store.dispatch(RefreshData());
action.completer.complete(null);
}).catchError((Object error) {
print(error);
store.dispatch(ConvertQuotesToProjectsFailure(error));
action.completer.completeError(error);
});
next(action);
};
}
Middleware<AppState> _approveQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ApproveQuotes;
repository
.bulkAction(
store.state.credentials, action.quoteIds, EntityAction.approve)
.then((quotes) {
store.dispatch(ApproveQuoteSuccess(quotes: quotes));
store.dispatch(RefreshData());
action.completer.complete(null);
}).catchError((Object error) {
print(error);
store.dispatch(ApproveQuoteFailure(error));
action.completer.completeError(error);
});
next(action);
};
}
Middleware<AppState> _markSentQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as MarkSentQuotesRequest;
repository
.bulkAction(
store.state.credentials, action.quoteIds, EntityAction.markSent)
.then((quotes) {
store.dispatch(MarkSentQuoteSuccess(quotes));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(MarkSentQuoteFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _emailQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as EmailQuoteRequest;
final origQuote = store.state.quoteState.map[action.quoteId];
repository
.emailQuote(store.state.credentials, origQuote, action.template,
action.subject, action.body, action.ccEmail,)
.then((quote) {
store.dispatch(EmailQuoteSuccess(quote));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(EmailQuoteFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _saveQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as SaveQuoteRequest;
// remove any empty line items
final updatedQuote = action.quote.rebuild((b) => b
..lineItems
.replace(action.quote.lineItems.where((item) => !item.isEmpty)));
repository
.saveData(store.state.credentials, updatedQuote, action.action)
.then((InvoiceEntity quote) {
if (action.quote.isNew) {
store.dispatch(AddQuoteSuccess(quote));
} else {
store.dispatch(SaveQuoteSuccess(quote));
}
if (action.action == EntityAction.convertToInvoice) {
store.dispatch(RefreshData());
}
action.completer.complete(quote);
}).catchError((Object error) {
print(error);
store.dispatch(SaveQuoteFailure(error));
action.completer.completeError(error);
});
next(action);
};
}
Middleware<AppState> _loadQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadQuote;
store.dispatch(LoadQuoteRequest());
repository.loadItem(store.state.credentials, action.quoteId).then((quote) {
store.dispatch(LoadQuoteSuccess(quote));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(LoadQuoteFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _downloadQuotes(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as DownloadQuotesRequest;
repository
.bulkAction(store.state.credentials, action.invoiceIds,
EntityAction.bulkDownload)
.then((invoices) {
store.dispatch(DownloadQuotesSuccess());
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(DownloadQuotesFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _bulkEmailQuotes(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as BulkEmailQuotesRequest;
repository
.bulkAction(
store.state.credentials, action.quoteIds, EntityAction.sendEmail)
.then((List<InvoiceEntity> quotes) {
store.dispatch(BulkEmailQuotesSuccess(quotes));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(BulkEmailQuotesFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _loadQuotes(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadQuotes;
final state = store.state;
store.dispatch(LoadQuotesRequest());
repository
.loadList(
state.credentials,
action.page,
state.createdAtLimit,
state.filterDeletedClients,
)
.then((data) {
store.dispatch(LoadQuotesSuccess(data));
if (data.length == kMaxRecordsPerPage) {
store.dispatch(LoadQuotes(
completer: action.completer,
page: action.page + 1,
));
} else {
if (action.completer != null) {
action.completer.complete(null);
}
store.dispatch(LoadCredits());
}
}).catchError((Object error) {
print(error);
store.dispatch(LoadQuotesFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _saveDocument(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as SaveQuoteDocumentRequest;
if (store.state.isEnterprisePlan) {
repository
.uploadDocument(
store.state.credentials, action.quote, action.multipartFile)
.then((quote) {
store.dispatch(SaveQuoteSuccess(quote));
action.completer.complete(null);
}).catchError((Object error) {
print(error);
store.dispatch(SaveQuoteDocumentFailure(error));
action.completer.completeError(error);
});
} else {
const error = 'Uploading documents requires an enterprise plan';
store.dispatch(SaveQuoteDocumentFailure(error));
action.completer.completeError(error);
}
next(action);
};
}