diff --git a/lib/data/models/invoice_model.dart b/lib/data/models/invoice_model.dart index 6afaceee8..6b1f429a8 100644 --- a/lib/data/models/invoice_model.dart +++ b/lib/data/models/invoice_model.dart @@ -328,8 +328,7 @@ abstract class InvoiceEntity extends Object BuiltList get invitations; - bool get isApproved => - statusId == kQuoteStatusApproved || (invoiceId ?? '').isNotEmpty; + bool get isApproved => statusId == kQuoteStatusApproved; bool get hasClient => '${clientId ?? ''}'.isNotEmpty; @@ -472,7 +471,7 @@ abstract class InvoiceEntity extends Object actions.add(EntityAction.sendEmail); } - if (userCompany.canCreate(EntityType.payment) && isUnpaid) { + if (!isQuote && userCompany.canCreate(EntityType.payment) && isUnpaid) { actions.add(EntityAction.newPayment); } @@ -480,9 +479,13 @@ abstract class InvoiceEntity extends Object actions.add(EntityAction.markSent); } - if (!isPaid) { + if (!isQuote && !isPaid) { actions.add(EntityAction.markPaid); } + + if (isQuote && !isApproved) { + actions.add(EntityAction.convert); + } } if (invitations.isNotEmpty && !multiselect) { diff --git a/lib/data/models/models.dart b/lib/data/models/models.dart index a52873afa..2417d42cc 100644 --- a/lib/data/models/models.dart +++ b/lib/data/models/models.dart @@ -48,6 +48,7 @@ class EntityAction extends EnumClass { static const EntityAction cloneToInvoice = _$cloneToInvoice; static const EntityAction cloneToQuote = _$cloneToQuote; static const EntityAction convert = _$convert; + static const EntityAction approve = _$approve; static const EntityAction download = _$download; static const EntityAction sendEmail = _$sendEmail; static const EntityAction markSent = _$markSent; diff --git a/lib/data/models/models.g.dart b/lib/data/models/models.g.dart index cadfbafac..18cae77ed 100644 --- a/lib/data/models/models.g.dart +++ b/lib/data/models/models.g.dart @@ -16,6 +16,7 @@ const EntityAction _$cloneToCredit = const EntityAction._('cloneToCredit'); const EntityAction _$cloneToInvoice = const EntityAction._('cloneToInvoice'); const EntityAction _$cloneToQuote = const EntityAction._('cloneToQuote'); const EntityAction _$convert = const EntityAction._('convert'); +const EntityAction _$approve = const EntityAction._('approve'); const EntityAction _$download = const EntityAction._('download'); const EntityAction _$sendEmail = const EntityAction._('sendEmail'); const EntityAction _$markSent = const EntityAction._('markSent'); @@ -63,6 +64,8 @@ EntityAction _$valueOf(String name) { return _$cloneToQuote; case 'convert': return _$convert; + case 'approve': + return _$approve; case 'download': return _$download; case 'sendEmail': @@ -126,6 +129,7 @@ final BuiltSet _$values = _$cloneToInvoice, _$cloneToQuote, _$convert, + _$approve, _$download, _$sendEmail, _$markSent, diff --git a/lib/redux/quote/quote_actions.dart b/lib/redux/quote/quote_actions.dart index 60dd9fb57..025f18f2c 100644 --- a/lib/redux/quote/quote_actions.dart +++ b/lib/redux/quote/quote_actions.dart @@ -413,14 +413,9 @@ Future handleQuoteAction( entityType: EntityType.invoice); break; case EntityAction.convert: - final Completer completer = Completer(); - store.dispatch(ConvertQuotes(completer, quoteIds)); - completer.future.then((InvoiceEntity invoice) { - viewEntityById( - context: context, - entityType: EntityType.invoice, - entityId: invoice.id); - }); + store.dispatch(ConvertQuotes( + snackBarCompleter(context, localization.convertedQuote), + quoteIds)); break; case EntityAction.markSent: store.dispatch(MarkSentQuotesRequest( diff --git a/lib/redux/quote/quote_middleware.dart b/lib/redux/quote/quote_middleware.dart index ea1b7f1fa..1a3f9ca83 100644 --- a/lib/redux/quote/quote_middleware.dart +++ b/lib/redux/quote/quote_middleware.dart @@ -215,7 +215,7 @@ Middleware _convertQuote(QuoteRepository repository) { store.state.credentials, action.quoteIds, EntityAction.convert) .then((quotes) { store.dispatch(ConvertQuoteSuccess(quotes: quotes)); - action.completer.complete(quotes); + action.completer.complete(null); }).catchError((Object error) { print(error); store.dispatch(ConvertQuoteFailure(error)); diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index 303b5b254..b5b27f789 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -15,6 +15,7 @@ mixin LocalizationsProvider on LocaleCodeAware { static final Map> _localizedValues = { 'en': { // STARTER: lang key - do not remove comment + 'converted_quote': 'Successfully converted quote', 'credit_design': 'Credit Design', 'includes': 'Includes', 'header': 'Header', @@ -32847,6 +32848,8 @@ mixin LocalizationsProvider on LocaleCodeAware { String get partialPaymentEmail => _localizedValues[localeCode]['partial_payment_email']; + String get convertedQuote => _localizedValues[localeCode]['converted_quote']; + String lookup(String key) { final lookupKey = toSnakeCase(key); return _localizedValues[localeCode][lookupKey] ?? diff --git a/lib/utils/icons.dart b/lib/utils/icons.dart index eaebe61d0..a4986d163 100644 --- a/lib/utils/icons.dart +++ b/lib/utils/icons.dart @@ -30,7 +30,9 @@ IconData getEntityActionIcon(EntityAction entityAction) { case EntityAction.restore: return Icons.restore; case EntityAction.convert: - return Icons.check_box; + return Icons.content_copy; + case EntityAction.approve: + return Icons.check_circle_outline; case EntityAction.viewInvoice: return Icons.insert_drive_file; case EntityAction.newInvoice: