Schedule send
This commit is contained in:
parent
ee20546276
commit
43a9df00e5
|
|
@ -1034,6 +1034,9 @@ abstract class InvoiceEntity extends Object
|
|||
actions.add(EntityAction.bulkSendEmail);
|
||||
} else {
|
||||
actions.add(EntityAction.sendEmail);
|
||||
if (isUnpaid) {
|
||||
actions.add(EntityAction.schedule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1278,7 +1281,9 @@ abstract class InvoiceEntity extends Object
|
|||
bool get isApplied => isCredit && statusId == kCreditStatusApplied;
|
||||
|
||||
bool get isUnpaid {
|
||||
if (isQuote) {
|
||||
if (isPurchaseOrder) {
|
||||
return !isApproved;
|
||||
} else if (isQuote) {
|
||||
return !isApproved;
|
||||
} else if (isCredit) {
|
||||
return !isApplied;
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ class EntityAction extends EnumClass {
|
|||
static const EntityAction merge = _$merge;
|
||||
static const EntityAction bulkPrint = _$bulkPrint;
|
||||
static const EntityAction autoBill = _$autoBill;
|
||||
static const EntityAction schedule = _$schedule;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ const EntityAction _$convertToProject =
|
|||
const EntityAction _$merge = const EntityAction._('merge');
|
||||
const EntityAction _$bulkPrint = const EntityAction._('bulkPrint');
|
||||
const EntityAction _$autoBill = const EntityAction._('autoBill');
|
||||
const EntityAction _$schedule = const EntityAction._('schedule');
|
||||
|
||||
EntityAction _$valueOf(String name) {
|
||||
switch (name) {
|
||||
|
|
@ -248,6 +249,8 @@ EntityAction _$valueOf(String name) {
|
|||
return _$bulkPrint;
|
||||
case 'autoBill':
|
||||
return _$autoBill;
|
||||
case 'schedule':
|
||||
return _$schedule;
|
||||
default:
|
||||
throw new ArgumentError(name);
|
||||
}
|
||||
|
|
@ -331,6 +334,7 @@ final BuiltSet<EntityAction> _$values =
|
|||
_$merge,
|
||||
_$bulkPrint,
|
||||
_$autoBill,
|
||||
_$schedule,
|
||||
]);
|
||||
|
||||
Serializer<EntityAction> _$entityActionSerializer =
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ 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/redux/settings/settings_actions.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
// Project imports:
|
||||
|
|
@ -488,6 +489,7 @@ Future handleCreditAction(
|
|||
break;
|
||||
case EntityAction.sendEmail:
|
||||
case EntityAction.bulkSendEmail:
|
||||
case EntityAction.schedule:
|
||||
bool emailValid = true;
|
||||
credits.forEach((credit) {
|
||||
final client = state.clientState.get(
|
||||
|
|
@ -517,6 +519,29 @@ Future handleCreditAction(
|
|||
snackBarCompleter<Null>(context, localization.emailedCredit),
|
||||
credit: credit,
|
||||
context: context));
|
||||
} else if (action == EntityAction.schedule) {
|
||||
if (!state.isProPlan) {
|
||||
showMessageDialog(
|
||||
context: context,
|
||||
message: localization.upgradeToPaidPlanToSchedule,
|
||||
secondaryActions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
store.dispatch(
|
||||
ViewSettings(section: kSettingsAccountManagement));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(localization.upgrade.toUpperCase())),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
createEntity(
|
||||
context: context,
|
||||
entity: ScheduleEntity().rebuild((b) => b
|
||||
..template = ScheduleEntity.TEMPLATE_SCHEDULE_ENTITY
|
||||
..parameters.entityType = EntityType.credit.apiValue
|
||||
..parameters.entityId = credit.id));
|
||||
} else {
|
||||
confirmCallback(
|
||||
context: context,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import 'package:flutter/material.dart';
|
|||
import 'package:built_collection/built_collection.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:invoiceninja_flutter/constants.dart';
|
||||
import 'package:invoiceninja_flutter/redux/document/document_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
// Project imports:
|
||||
|
|
@ -607,6 +609,7 @@ void handleInvoiceAction(BuildContext context, List<BaseEntity> invoices,
|
|||
break;
|
||||
case EntityAction.sendEmail:
|
||||
case EntityAction.bulkSendEmail:
|
||||
case EntityAction.schedule:
|
||||
bool emailValid = true;
|
||||
invoices.forEach((invoice) {
|
||||
final client = state.clientState.get(
|
||||
|
|
@ -636,6 +639,29 @@ void handleInvoiceAction(BuildContext context, List<BaseEntity> invoices,
|
|||
snackBarCompleter<Null>(context, localization.emailedInvoice),
|
||||
invoice: invoice,
|
||||
context: context));
|
||||
} else if (action == EntityAction.schedule) {
|
||||
if (!state.isProPlan) {
|
||||
showMessageDialog(
|
||||
context: context,
|
||||
message: localization.upgradeToPaidPlanToSchedule,
|
||||
secondaryActions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
store.dispatch(
|
||||
ViewSettings(section: kSettingsAccountManagement));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(localization.upgrade.toUpperCase())),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
createEntity(
|
||||
context: context,
|
||||
entity: ScheduleEntity().rebuild((b) => b
|
||||
..template = ScheduleEntity.TEMPLATE_SCHEDULE_ENTITY
|
||||
..parameters.entityType = EntityType.invoice.apiValue
|
||||
..parameters.entityId = invoice.id));
|
||||
} else {
|
||||
confirmCallback(
|
||||
context: context,
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:invoiceninja_flutter/constants.dart';
|
||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||
import 'package:invoiceninja_flutter/data/web_client.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/design/design_selectors.dart';
|
||||
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
|
||||
import 'package:invoiceninja_flutter/utils/completers.dart';
|
||||
import 'package:invoiceninja_flutter/utils/dialogs.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
|
|
@ -699,6 +701,7 @@ void handlePurchaseOrderAction(BuildContext context,
|
|||
break;
|
||||
case EntityAction.sendEmail:
|
||||
case EntityAction.bulkSendEmail:
|
||||
case EntityAction.schedule:
|
||||
bool emailValid = true;
|
||||
purchaseOrders.forEach((purchaseOrder) {
|
||||
final vendor = state.vendorState.get(
|
||||
|
|
@ -729,6 +732,29 @@ void handlePurchaseOrderAction(BuildContext context,
|
|||
context, localization.emailedPurchaseOrder),
|
||||
purchaseOrder: purchaseOrder,
|
||||
context: context));
|
||||
} else if (action == EntityAction.schedule) {
|
||||
if (!state.isProPlan) {
|
||||
showMessageDialog(
|
||||
context: context,
|
||||
message: localization.upgradeToPaidPlanToSchedule,
|
||||
secondaryActions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
store.dispatch(
|
||||
ViewSettings(section: kSettingsAccountManagement));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(localization.upgrade.toUpperCase())),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
createEntity(
|
||||
context: context,
|
||||
entity: ScheduleEntity().rebuild((b) => b
|
||||
..template = ScheduleEntity.TEMPLATE_SCHEDULE_ENTITY
|
||||
..parameters.entityType = EntityType.purchaseOrder.apiValue
|
||||
..parameters.entityId = purchaseOrder.id));
|
||||
} else {
|
||||
confirmCallback(
|
||||
context: context,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import 'package:flutter/material.dart';
|
|||
import 'package:built_collection/built_collection.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:invoiceninja_flutter/constants.dart';
|
||||
import 'package:invoiceninja_flutter/redux/document/document_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
// Project imports:
|
||||
|
|
@ -551,6 +553,7 @@ Future handleQuoteAction(
|
|||
break;
|
||||
case EntityAction.sendEmail:
|
||||
case EntityAction.bulkSendEmail:
|
||||
case EntityAction.schedule:
|
||||
bool emailValid = true;
|
||||
quotes.forEach((quote) {
|
||||
final client = state.clientState.get(
|
||||
|
|
@ -580,6 +583,29 @@ Future handleQuoteAction(
|
|||
snackBarCompleter<Null>(context, localization.emailedQuote),
|
||||
quote: quote,
|
||||
context: context));
|
||||
} else if (action == EntityAction.schedule) {
|
||||
if (!state.isProPlan) {
|
||||
showMessageDialog(
|
||||
context: context,
|
||||
message: localization.upgradeToPaidPlanToSchedule,
|
||||
secondaryActions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
store.dispatch(
|
||||
ViewSettings(section: kSettingsAccountManagement));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(localization.upgrade.toUpperCase())),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
createEntity(
|
||||
context: context,
|
||||
entity: ScheduleEntity().rebuild((b) => b
|
||||
..template = ScheduleEntity.TEMPLATE_SCHEDULE_ENTITY
|
||||
..parameters.entityType = EntityType.quote.apiValue
|
||||
..parameters.entityId = quote.id));
|
||||
} else {
|
||||
confirmCallback(
|
||||
context: context,
|
||||
|
|
|
|||
|
|
@ -164,7 +164,8 @@ class _ScheduleEditState extends State<ScheduleEdit> {
|
|||
value: schedule.template,
|
||||
onChanged: (dynamic value) {
|
||||
viewModel.onChanged(
|
||||
schedule.rebuild((b) => b..template = value));
|
||||
schedule.rebuild((b) => b..template = value),
|
||||
);
|
||||
},
|
||||
items: ScheduleEntity.TEMPLATES
|
||||
.map((entry) => DropdownMenuItem(
|
||||
|
|
@ -351,15 +352,13 @@ class _ScheduleEditState extends State<ScheduleEdit> {
|
|||
EntityType.purchaseOrder
|
||||
]
|
||||
.map((entityType) => DropdownMenuItem<String>(
|
||||
value: entityType.toString(),
|
||||
value: entityType.apiValue,
|
||||
child: Text(
|
||||
localization
|
||||
.lookup(entityType.toString()),
|
||||
localization.lookup(entityType.apiValue),
|
||||
),
|
||||
))
|
||||
.toList()),
|
||||
if (parameters.entityType ==
|
||||
EntityType.invoice.toString())
|
||||
if (parameters.entityType == EntityType.invoice.apiValue)
|
||||
EntityDropdown(
|
||||
labelText: localization.invoice,
|
||||
entityType: EntityType.invoice,
|
||||
|
|
@ -371,7 +370,7 @@ class _ScheduleEditState extends State<ScheduleEdit> {
|
|||
},
|
||||
)
|
||||
else if (parameters.entityType ==
|
||||
EntityType.quote.toString())
|
||||
EntityType.quote.apiValue)
|
||||
EntityDropdown(
|
||||
labelText: localization.quote,
|
||||
entityType: EntityType.quote,
|
||||
|
|
@ -383,7 +382,7 @@ class _ScheduleEditState extends State<ScheduleEdit> {
|
|||
},
|
||||
)
|
||||
else if (parameters.entityType ==
|
||||
EntityType.credit.toString())
|
||||
EntityType.credit.apiValue)
|
||||
EntityDropdown(
|
||||
labelText: localization.credit,
|
||||
entityType: EntityType.credit,
|
||||
|
|
@ -395,7 +394,7 @@ class _ScheduleEditState extends State<ScheduleEdit> {
|
|||
},
|
||||
)
|
||||
else if (parameters.entityType ==
|
||||
EntityType.purchaseOrder.toString())
|
||||
EntityType.purchaseOrder.apiValue)
|
||||
EntityDropdown(
|
||||
labelText: localization.purchaseOrder,
|
||||
entityType: EntityType.purchaseOrder,
|
||||
|
|
|
|||
|
|
@ -41,9 +41,13 @@ class ScheduleListItem extends StatelessWidget {
|
|||
|
||||
final filterMatch = filter != null && filter.isNotEmpty
|
||||
? schedule.matchesFilterValue(filter)
|
||||
: localization.lookup(schedule.template) +
|
||||
' • ' +
|
||||
localization.lookup(kFrequencies[schedule.frequencyId]);
|
||||
: (schedule.template == ScheduleEntity.TEMPLATE_SCHEDULE_ENTITY
|
||||
? localization.emailRecord
|
||||
: localization.lookup(schedule.template)) +
|
||||
(schedule.frequencyId.isEmpty
|
||||
? ''
|
||||
: ' • ' +
|
||||
localization.lookup(kFrequencies[schedule.frequencyId]));
|
||||
final subtitle = filterMatch;
|
||||
|
||||
return DismissibleEntity(
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ IconData getEntityActionIcon(EntityAction entityAction) {
|
|||
case EntityAction.resendInvite:
|
||||
case EntityAction.sendNow:
|
||||
return Icons.send;
|
||||
case EntityAction.schedule:
|
||||
return Icons.schedule;
|
||||
case EntityAction.archive:
|
||||
return Icons.archive;
|
||||
case EntityAction.delete:
|
||||
|
|
|
|||
Loading…
Reference in New Issue