import 'dart:async'; import 'package:built_collection/built_collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.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/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/pdf.dart'; import 'package:url_launcher/url_launcher.dart'; class ViewCreditList extends AbstractNavigatorAction implements PersistUI, StopLoading { ViewCreditList({@required NavigatorState navigator, this.force = false}) : super(navigator: navigator); final bool force; } class ViewCredit extends AbstractNavigatorAction implements PersistUI, PersistPrefs { ViewCredit({ this.creditId, @required NavigatorState navigator, this.force = false, }) : super(navigator: navigator); final String creditId; final bool force; } class EditCredit extends AbstractNavigatorAction implements PersistUI, PersistPrefs { EditCredit( {this.credit, @required NavigatorState navigator, this.creditItemIndex, this.completer, this.force = false}) : super(navigator: navigator); final InvoiceEntity credit; final int creditItemIndex; final Completer completer; final bool force; } class ShowEmailCredit { ShowEmailCredit({this.credit, this.context, this.completer}); final InvoiceEntity credit; final BuildContext context; final Completer completer; } class EditCreditItem implements PersistUI { EditCreditItem([this.creditItemIndex]); final int creditItemIndex; } class UpdateCredit implements PersistUI { UpdateCredit(this.credit); final InvoiceEntity credit; } class UpdateCreditClient implements PersistUI { UpdateCreditClient({this.client}); final ClientEntity client; } class LoadCredit { LoadCredit({this.completer, this.creditId}); final Completer completer; final String creditId; } class LoadCredits { LoadCredits({this.completer, this.force = false}); final Completer completer; final bool force; } class LoadCreditRequest implements StartLoading {} class LoadCreditFailure implements StopLoading { LoadCreditFailure(this.error); final dynamic error; @override String toString() { return 'LoadCreditFailure{error: $error}'; } } class LoadCreditSuccess implements StopLoading, PersistData { LoadCreditSuccess(this.credit); final InvoiceEntity credit; @override String toString() { return 'LoadCreditSuccess{credit: $credit}'; } } class LoadCreditsRequest implements StartLoading {} class LoadCreditsFailure implements StopLoading { LoadCreditsFailure(this.error); final dynamic error; @override String toString() { return 'LoadCreditsFailure{error: $error}'; } } class LoadCreditsSuccess implements StopLoading, PersistData { LoadCreditsSuccess(this.credits); final BuiltList credits; @override String toString() { return 'LoadCreditsSuccess{credits: $credits}'; } } class AddCreditContact implements PersistUI { AddCreditContact({this.contact, this.invitation}); final ContactEntity contact; final InvitationEntity invitation; } class RemoveCreditContact implements PersistUI { RemoveCreditContact({this.invitation}); final InvitationEntity invitation; } class AddCreditItem implements PersistUI { AddCreditItem({this.creditItem}); final InvoiceItemEntity creditItem; } class AddCreditItems implements PersistUI { AddCreditItems(this.creditItems); final List creditItems; } class UpdateCreditItem implements PersistUI { UpdateCreditItem({this.index, this.creditItem}); final int index; final InvoiceItemEntity creditItem; } class DeleteCreditItem implements PersistUI { DeleteCreditItem(this.index); final int index; } class SaveCreditRequest implements StartSaving { SaveCreditRequest({this.completer, this.credit}); final Completer completer; final InvoiceEntity credit; } class SaveCreditSuccess implements StopSaving, PersistData, PersistUI { SaveCreditSuccess(this.credit); final InvoiceEntity credit; } class AddCreditSuccess implements StopSaving, PersistData, PersistUI { AddCreditSuccess(this.credit); final InvoiceEntity credit; } class SaveCreditFailure implements StopSaving { SaveCreditFailure(this.error); final Object error; } class EmailCreditRequest implements StartSaving { EmailCreditRequest( {this.completer, this.creditId, this.template, this.subject, this.body}); final Completer completer; final String creditId; final EmailTemplate template; final String subject; final String body; } class EmailCreditSuccess implements StopSaving, PersistData {} class EmailCreditFailure implements StopSaving { EmailCreditFailure(this.error); final dynamic error; } class MarkSentCreditRequest implements StartSaving { MarkSentCreditRequest(this.completer, this.creditIds); final Completer completer; final List creditIds; } class MarkSentCreditSuccess implements StopSaving, PersistData { MarkSentCreditSuccess(this.credits); final List credits; } class MarkSentCreditFailure implements StopSaving { MarkSentCreditFailure(this.error); final Object error; } class ArchiveCreditsRequest implements StartSaving { ArchiveCreditsRequest(this.completer, this.creditIds); final Completer completer; final List creditIds; } class ArchiveCreditsSuccess implements StopSaving, PersistData { ArchiveCreditsSuccess(this.credits); final List credits; } class ArchiveCreditsFailure implements StopSaving { ArchiveCreditsFailure(this.credits); final List credits; } class DeleteCreditsRequest implements StartSaving { DeleteCreditsRequest(this.completer, this.creditIds); final Completer completer; final List creditIds; } class DeleteCreditsSuccess implements StopSaving, PersistData { DeleteCreditsSuccess(this.credits); final List credits; } class DeleteCreditsFailure implements StopSaving { DeleteCreditsFailure(this.credits); final List credits; } class RestoreCreditsRequest implements StartSaving { RestoreCreditsRequest(this.completer, this.creditIds); final Completer completer; final List creditIds; } class RestoreCreditsSuccess implements StopSaving, PersistData { RestoreCreditsSuccess(this.credits); final List credits; } class RestoreCreditsFailure implements StopSaving { RestoreCreditsFailure(this.credits); final List credits; } class FilterCredits implements PersistUI { FilterCredits(this.filter); final String filter; } class SortCredits implements PersistUI { SortCredits(this.field); final String field; } class FilterCreditsByState implements PersistUI { FilterCreditsByState(this.state); final EntityState state; } class FilterCreditsByStatus implements PersistUI { FilterCreditsByStatus(this.status); final EntityStatus status; } class FilterCreditsByEntity implements PersistUI { FilterCreditsByEntity({this.entityId, this.entityType}); final String entityId; final EntityType entityType; } class FilterCreditDropdown { FilterCreditDropdown(this.filter); final String filter; } class FilterCreditsByCustom1 implements PersistUI { FilterCreditsByCustom1(this.value); final String value; } class FilterCreditsByCustom2 implements PersistUI { FilterCreditsByCustom2(this.value); final String value; } class FilterCreditsByCustom3 implements PersistUI { FilterCreditsByCustom3(this.value); final String value; } class FilterCreditsByCustom4 implements PersistUI { FilterCreditsByCustom4(this.value); final String value; } Future handleCreditAction( BuildContext context, List credits, EntityAction action) async { assert( [ EntityAction.restore, EntityAction.archive, EntityAction.delete, EntityAction.toggleMultiselect ].contains(action) || credits.length == 1, 'Cannot perform this action on more than one credit'); final store = StoreProvider.of(context); final localization = AppLocalization.of(context); final credit = credits.first as InvoiceEntity; final creditIds = credits.map((credit) => credit.id).toList(); switch (action) { case EntityAction.edit: editEntity(context: context, entity: credit); break; case EntityAction.pdf: viewPdf(credit, context); break; case EntityAction.clientPortal: if (await canLaunch(credit.invitationSilentLink)) { await launch(credit.invitationSilentLink, forceSafariVC: false, forceWebView: false); } break; case EntityAction.viewInvoice: viewEntityById( context: context, // TODO fix this // entityId: credit.creditInvoiceId, entityType: EntityType.invoice); break; case EntityAction.markSent: store.dispatch(MarkSentCreditRequest( snackBarCompleter(context, localization.markedCreditAsSent), creditIds)); break; case EntityAction.sendEmail: store.dispatch(ShowEmailCredit( completer: snackBarCompleter(context, localization.emailedCredit), credit: credit, context: context)); break; case EntityAction.cloneToInvoice: createEntity(context: context, entity: credit.clone); break; case EntityAction.cloneToCredit: createEntity(context: context, entity: credit.clone); createEntity(context: context, entity: credit.clone); break; case EntityAction.restore: store.dispatch(RestoreCreditsRequest( snackBarCompleter(context, localization.restoredCredit), creditIds)); break; case EntityAction.archive: store.dispatch(ArchiveCreditsRequest( snackBarCompleter(context, localization.archivedCredit), creditIds)); break; case EntityAction.delete: store.dispatch(DeleteCreditsRequest( snackBarCompleter(context, localization.deletedCredit), creditIds)); break; case EntityAction.toggleMultiselect: if (!store.state.creditListState.isInMultiselect()) { store.dispatch(StartCreditMultiselect()); } if (credits.isEmpty) { break; } for (final credit in credits) { if (!store.state.creditListState.isSelected(credit.id)) { store.dispatch(AddToCreditMultiselect(entity: credit)); } else { store.dispatch(RemoveFromCreditMultiselect(entity: credit)); } } break; } } class StartCreditMultiselect {} class AddToCreditMultiselect { AddToCreditMultiselect({@required this.entity}); final BaseEntity entity; } class RemoveFromCreditMultiselect { RemoveFromCreditMultiselect({@required this.entity}); final BaseEntity entity; } class ClearCreditMultiselect {}