invoice/lib/redux/client/client_actions.dart

542 lines
13 KiB
Dart

// Dart imports:
import 'dart:async';
// Flutter imports:
import 'package:flutter/widgets.dart';
// Package imports:
import 'package:built_collection/built_collection.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:http/http.dart';
import 'package:invoiceninja_flutter/redux/document/document_actions.dart';
import 'package:invoiceninja_flutter/utils/dialogs.dart';
import 'package:url_launcher/url_launcher.dart';
// Project imports:
import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class ViewClientList implements PersistUI {
ViewClientList({
this.force = false,
});
final bool force;
}
class ViewClient implements PersistUI, PersistPrefs {
ViewClient({
@required this.clientId,
this.force = false,
});
final String clientId;
final bool force;
}
class EditClient implements PersistUI, PersistPrefs {
EditClient(
{@required this.client,
this.contact,
this.completer,
this.cancelCompleter,
this.force = false});
final ClientEntity client;
final ClientContactEntity contact;
final Completer completer;
final Completer cancelCompleter;
final bool force;
}
class EditContact implements PersistUI {
EditContact([this.contact]);
final ClientContactEntity contact;
}
class ShowPdfClient {
ShowPdfClient({this.client, this.context});
final ClientEntity client;
final BuildContext context;
}
class UpdateClient implements PersistUI {
UpdateClient(this.client);
final ClientEntity client;
}
class LoadClient {
LoadClient({this.completer, this.clientId});
final Completer completer;
final String clientId;
}
class LoadClientActivity {
LoadClientActivity({this.completer, this.clientId});
final Completer completer;
final String clientId;
}
class LoadClients {
LoadClients({this.completer, this.page = 1});
final Completer completer;
final int page;
}
class LoadClientRequest implements StartLoading {}
class LoadClientFailure implements StopLoading {
LoadClientFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadClientFailure{error: $error}';
}
}
class LoadClientSuccess implements StopLoading, PersistData {
LoadClientSuccess(this.client);
final ClientEntity client;
@override
String toString() {
return 'LoadClientSuccess{client: $client}';
}
}
class LoadClientsRequest implements StartLoading {}
class LoadClientsFailure implements StopLoading {
LoadClientsFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadClientsFailure{error: $error}';
}
}
class LoadClientsSuccess implements StopLoading {
LoadClientsSuccess(this.clients);
final BuiltList<ClientEntity> clients;
@override
String toString() {
return 'LoadClientsSuccess{clients: $clients}';
}
}
class AddContact implements PersistUI {
AddContact([this.contact]);
final ClientContactEntity contact;
}
class UpdateContact implements PersistUI {
UpdateContact({this.index, this.contact});
final int index;
final ClientContactEntity contact;
}
class DeleteContact implements PersistUI {
DeleteContact(this.index);
final int index;
}
class SaveClientRequest implements StartSaving {
SaveClientRequest({this.completer, this.client});
final Completer completer;
final ClientEntity client;
}
class SaveClientSuccess implements StopSaving, PersistData, PersistUI {
SaveClientSuccess(this.client);
final ClientEntity client;
}
class AddClientSuccess implements StopSaving, PersistData, PersistUI {
AddClientSuccess(this.client);
final ClientEntity client;
}
class SaveClientFailure implements StopSaving {
SaveClientFailure(this.error);
final Object error;
}
class ArchiveClientsRequest implements StartSaving {
ArchiveClientsRequest(this.completer, this.clientIds);
final Completer completer;
final List<String> clientIds;
}
class ArchiveClientsSuccess implements StopSaving, PersistData {
ArchiveClientsSuccess(this.clients);
final List<ClientEntity> clients;
}
class ArchiveClientsFailure implements StopSaving {
ArchiveClientsFailure(this.clients);
final List<ClientEntity> clients;
}
class DeleteClientsRequest implements StartSaving {
DeleteClientsRequest(this.completer, this.clientIds);
final Completer completer;
final List<String> clientIds;
}
class DeleteClientsSuccess implements StopSaving, PersistData {
DeleteClientsSuccess(this.clients);
final List<ClientEntity> clients;
}
class DeleteClientsFailure implements StopSaving {
DeleteClientsFailure(this.clients);
final List<ClientEntity> clients;
}
class PurgeClientRequest implements StartSaving {
PurgeClientRequest({
@required this.completer,
@required this.clientId,
@required this.password,
@required this.idToken,
});
final Completer completer;
final String clientId;
final String password;
final String idToken;
}
class PurgeClientSuccess implements StopSaving, PersistData {}
class PurgeClientFailure implements StopSaving {
PurgeClientFailure(this.error);
final Object error;
}
class RestoreClientsRequest implements StartSaving {
RestoreClientsRequest(this.completer, this.clientIds);
final Completer completer;
final List<String> clientIds;
}
class RestoreClientSuccess implements StopSaving, PersistData {
RestoreClientSuccess(this.clients);
final List<ClientEntity> clients;
}
class RestoreClientFailure implements StopSaving {
RestoreClientFailure(this.clients);
final List<ClientEntity> clients;
}
class FilterClients implements PersistUI {
FilterClients(this.filter);
final String filter;
}
class SortClients implements PersistUI, PersistPrefs {
SortClients(this.field);
final String field;
}
class FilterClientsByState implements PersistUI {
FilterClientsByState(this.state);
final EntityState state;
}
class FilterClientsByCustom1 implements PersistUI {
FilterClientsByCustom1(this.value);
final String value;
}
class FilterClientsByCustom2 implements PersistUI {
FilterClientsByCustom2(this.value);
final String value;
}
class FilterClientsByCustom3 implements PersistUI {
FilterClientsByCustom3(this.value);
final String value;
}
class FilterClientsByCustom4 implements PersistUI {
FilterClientsByCustom4(this.value);
final String value;
}
void handleClientAction(
BuildContext context, List<BaseEntity> clients, EntityAction action) async {
if (clients.isEmpty) {
return;
}
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final localization = AppLocalization.of(context);
final clientIds = clients.map((client) => client.id).toList();
final client = clients[0] as ClientEntity;
switch (action) {
case EntityAction.edit:
editEntity(entity: client);
break;
case EntityAction.viewStatement:
store.dispatch(ShowPdfClient(client: client, context: context));
break;
case EntityAction.clientPortal:
final contact = client.contacts
.firstWhere((contact) => contact.link.isNotEmpty, orElse: null);
if (contact != null) {
launch(contact.silentLink);
}
break;
case EntityAction.settings:
store.dispatch(ViewSettings(
client: client,
section: kSettingsLocalization,
));
break;
case EntityAction.newTask:
createEntity(
context: context,
entity:
TaskEntity(state: state).rebuild((b) => b..clientId = client.id));
break;
case EntityAction.newInvoice:
createEntity(
context: context,
entity: InvoiceEntity(state: state, client: client));
break;
case EntityAction.newRecurringInvoice:
createEntity(
context: context,
entity: InvoiceEntity(
state: state,
client: client,
entityType: EntityType.recurringInvoice));
break;
case EntityAction.newRecurringExpense:
createEntity(
context: context,
entity: ExpenseEntity(
state: state,
client: client,
entityType: EntityType.recurringExpense));
break;
case EntityAction.newQuote:
createEntity(
context: context,
entity: InvoiceEntity(
state: state,
client: client,
entityType: EntityType.quote,
));
break;
case EntityAction.newCredit:
createEntity(
context: context,
entity: InvoiceEntity(
state: state,
client: client,
entityType: EntityType.credit,
),
);
break;
case EntityAction.newExpense:
createEntity(
context: context,
entity: ExpenseEntity(state: state, client: client),
);
break;
case EntityAction.newPayment:
createEntity(
context: context,
entity:
PaymentEntity(state: state).rebuild((b) => b.clientId = client.id),
);
break;
case EntityAction.newProject:
createEntity(
context: context,
entity:
ProjectEntity(state: state).rebuild((b) => b.clientId = client.id),
);
break;
case EntityAction.restore:
final message = clientIds.length > 1
? localization.restoredClients
.replaceFirst(':value', clientIds.length.toString())
: localization.restoredClient;
store.dispatch(RestoreClientsRequest(
snackBarCompleter<Null>(context, message), clientIds));
break;
case EntityAction.archive:
final message = clientIds.length > 1
? localization.archivedClients
.replaceFirst(':value', clientIds.length.toString())
: localization.archivedClient;
store.dispatch(ArchiveClientsRequest(
snackBarCompleter<Null>(context, message), clientIds));
break;
case EntityAction.delete:
final message = clientIds.length > 1
? localization.deletedClients
.replaceFirst(':value', clientIds.length.toString())
: localization.deletedClient;
store.dispatch(DeleteClientsRequest(
snackBarCompleter<Null>(context, message), clientIds));
break;
case EntityAction.purge:
confirmCallback(
context: context,
message: '${localization.purge} - ${client.displayName}',
callback: (_) {
passwordCallback(
alwaysRequire: true,
context: context,
callback: (password, idToken) {
store.dispatch(
PurgeClientRequest(
completer: snackBarCompleter<Null>(
context, localization.purgedClient),
clientId: client.id,
password: password,
idToken: idToken),
);
});
});
break;
case EntityAction.toggleMultiselect:
if (!store.state.clientListState.isInMultiselect()) {
store.dispatch(StartClientMultiselect());
}
if (clients.isEmpty) {
break;
}
for (final client in clients) {
if (!state.clientListState.isSelected(client.id)) {
store.dispatch(AddToClientMultiselect(entity: client));
} else {
store.dispatch(RemoveFromClientMultiselect(entity: client));
}
}
break;
case EntityAction.more:
showEntityActionsDialog(
entities: [client],
);
break;
case EntityAction.documents:
final documentIds = <String>[];
for (var client in clients) {
for (var document in (client as ClientEntity).documents) {
documentIds.add(document.id);
}
}
store.dispatch(
DownloadDocumentsRequest(
documentIds: documentIds,
completer: snackBarCompleter<Null>(
context,
localization.exportedData,
),
),
);
break;
default:
print('## Error: action $action not handled in client_actions');
}
}
class StartClientMultiselect {}
class AddToClientMultiselect {
AddToClientMultiselect({@required this.entity});
final BaseEntity entity;
}
class RemoveFromClientMultiselect {
RemoveFromClientMultiselect({@required this.entity});
final BaseEntity entity;
}
class ClearClientMultiselect {}
class SaveClientDocumentRequest implements StartSaving {
SaveClientDocumentRequest({
@required this.completer,
@required this.multipartFile,
@required this.client,
});
final Completer completer;
final MultipartFile multipartFile;
final ClientEntity client;
}
class SaveClientDocumentSuccess implements StopSaving, PersistData, PersistUI {
SaveClientDocumentSuccess(this.document);
final DocumentEntity document;
}
class SaveClientDocumentFailure implements StopSaving {
SaveClientDocumentFailure(this.error);
final Object error;
}
class UpdateClientTab implements PersistUI {
UpdateClientTab({this.tabIndex});
final int tabIndex;
}