Add ‘Configure gateways’ button to Settings > Online Payments

This commit is contained in:
Hillel Coren 2020-10-22 09:21:41 +03:00
parent 8b03373297
commit 0810ab02d7
13 changed files with 314 additions and 227 deletions

View File

@ -291,19 +291,6 @@ const kAgeGroups = {
kAgeGroup120: 120,
};
/*
const String kEmailTemplateInvoice = 'invoice_email';
const String kEmailTemplateQuote = 'quote_email';
const String kEmailTemplatePayment = 'payment_email';
const String kEmailTemplateReminder1 = 'first_reminder';
const String kEmailTemplateReminder2 = 'second_reminder';
const String kEmailTemplateReminder3 = 'third_reminder';
const String kEmailTemplateReminder4 = 'endless_reminder';
const String kEmailTemplateCustom1 = 'first_custom';
const String kEmailTemplateCustom2 = 'second_custom';
const String kEmailTemplateCustom3 = 'third_custom';
*/
const String kReminderScheduleAfterInvoiceDate = 'after_invoice_date';
const String kReminderScheduleBeforeDueDate = 'before_due_date';
const String kReminderScheduleAfterDueDate = 'after_due_date';
@ -315,8 +302,9 @@ const String kSettingsPaymentTermEdit = 'payment_term_edit';
const String kSettingsUserDetails = 'user_details';
const String kSettingsLocalization = 'localization';
const String kSettingsOnlinePayments = 'online_payments';
const String kSettingsOnlinePaymentsView = 'online_payments_view';
const String kSettingsOnlinePaymentsEdit = 'online_payments_edit';
const String kSettingsCompanyGateways = 'company_gateways';
const String kSettingsCompanyGatewaysView = 'company_gateways_view';
const String kSettingsCompanyGatewaysEdit = 'company_gateways_edit';
const String kSettingsTaxSettings = 'tax_settings';
const String kSettingsTaxRates = 'tax_settings_rates';
const String kSettingsTaxRatesView = 'tax_settings_rates_view';

View File

@ -37,6 +37,7 @@ import 'package:invoiceninja_flutter/ui/reports/reports_screen.dart';
import 'package:invoiceninja_flutter/ui/reports/reports_screen_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/account_management_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/expense_settings_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/online_payments_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/settings_screen_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/tax_settings_vm.dart';
import 'package:invoiceninja_flutter/ui/tax_rate/edit/tax_rate_edit_vm.dart';
@ -292,7 +293,6 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
RecurringInvoiceViewScreen(),
RecurringInvoiceEditScreen.route: (context) =>
RecurringInvoiceEditScreen(),
WebhookScreen.route: (context) => WebhookScreenBuilder(),
WebhookViewScreen.route: (context) => WebhookViewScreen(),
WebhookEditScreen.route: (context) => WebhookEditScreen(),
@ -323,6 +323,8 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
CompanyDetailsScreen(),
UserDetailsScreen.route: (context) => UserDetailsScreen(),
LocalizationScreen.route: (context) => LocalizationScreen(),
OnlinePaymentsScreen.route: (context) =>
OnlinePaymentsScreen(),
CompanyGatewayScreen.route: (context) =>
CompanyGatewayScreenBuilder(),
CompanyGatewayViewScreen.route: (context) =>

View File

@ -34,6 +34,7 @@ import 'package:invoiceninja_flutter/ui/reports/reports_screen.dart';
import 'package:invoiceninja_flutter/ui/reports/reports_screen_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/account_management_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/expense_settings_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/online_payments_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/settings_screen_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/tax_settings_vm.dart';
import 'package:invoiceninja_flutter/ui/token/edit/token_edit_vm.dart';
@ -380,12 +381,15 @@ class SettingsScreens extends StatelessWidget {
screen = LocalizationScreen();
break;
case kSettingsOnlinePayments:
screen = OnlinePaymentsScreen();
break;
case kSettingsCompanyGateways:
screen = CompanyGatewayScreenBuilder();
break;
case kSettingsOnlinePaymentsView:
case kSettingsCompanyGatewaysView:
screen = CompanyGatewayViewScreen();
break;
case kSettingsOnlinePaymentsEdit:
case kSettingsCompanyGatewaysEdit:
screen = CompanyGatewayEditScreen();
break;
case kSettingsTaxSettings:

View File

@ -1,18 +1,10 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/company_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/forms/app_dropdown_button.dart';
import 'package:invoiceninja_flutter/ui/app/forms/app_form.dart';
import 'package:invoiceninja_flutter/ui/app/forms/bool_dropdown_button.dart';
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_list_item.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_list_vm.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class CompanyGatewayList extends StatelessWidget {
const CompanyGatewayList({
@ -29,19 +21,10 @@ class CompanyGatewayList extends StatelessWidget {
final listUIState = state.uiState.companyGatewayUIState.listUIState;
final isInMultiselect = listUIState.isInMultiselect();
return ListView(
shrinkWrap: true,
children: <Widget>[
_OnlinePaymentForm(
viewModel: viewModel,
key: ValueKey('__settings_${state.settingsUIState.updatedAt}__'),
),
!viewModel.state.isLoaded && viewModel.companyGatewayList.isEmpty
return !viewModel.state.isLoaded && viewModel.companyGatewayList.isEmpty
? LoadingIndicator()
: RefreshIndicator(
onRefresh: () => viewModel.onRefreshed(context),
child: SizedBox(
height: (viewModel.companyGatewayList.length * 80.0) + 100,
child: ReorderableListView(
onReorder: (oldIndex, newIndex) {
// https://stackoverflow.com/a/54164333/497368
@ -55,8 +38,7 @@ class CompanyGatewayList extends StatelessWidget {
viewModel.onSortChanged(oldIndex, newIndex);
},
children:
viewModel.companyGatewayList.map((companyGatewayId) {
children: viewModel.companyGatewayList.map((companyGatewayId) {
final companyGateway =
viewModel.companyGatewayMap[companyGatewayId];
return CompanyGatewayListItem(
@ -64,155 +46,13 @@ class CompanyGatewayList extends StatelessWidget {
user: state.userCompany.user,
filter: viewModel.filter,
companyGateway: companyGateway,
onRemovePressed: viewModel
.state.settingsUIState.isFiltered
? () =>
viewModel.onRemovePressed(companyGatewayId)
onRemovePressed: viewModel.state.settingsUIState.isFiltered
? () => viewModel.onRemovePressed(companyGatewayId)
: null,
isChecked: isInMultiselect &&
listUIState.isSelected(companyGateway.id));
}).toList(),
),
),
),
],
);
}
}
class _OnlinePaymentForm extends StatefulWidget {
const _OnlinePaymentForm({Key key, @required this.viewModel})
: super(key: key);
final CompanyGatewayListVM viewModel;
@override
__OnlinePaymentFormState createState() => __OnlinePaymentFormState();
}
class __OnlinePaymentFormState extends State<_OnlinePaymentForm> {
static final GlobalKey<FormState> _formKey =
GlobalKey<FormState>(debugLabel: '_companyGatewayList');
final FocusScopeNode _focusNode = FocusScopeNode();
//bool _autoValidate = false;
final _minimumAmountController = TextEditingController();
List<TextEditingController> _controllers = [];
@override
void didChangeDependencies() {
_controllers = [
_minimumAmountController,
];
_controllers
.forEach((dynamic controller) => controller.removeListener(_onChanged));
_minimumAmountController.text = formatNumber(
widget.viewModel.settings.clientPortalUnderPaymentMinimum, context,
formatNumberType: FormatNumberType.inputMoney);
_controllers
.forEach((dynamic controller) => controller.addListener(_onChanged));
super.didChangeDependencies();
}
@override
void dispose() {
_controllers.forEach((dynamic controller) {
controller.removeListener(_onChanged);
controller.dispose();
});
_focusNode.dispose();
super.dispose();
}
void _onChanged() {
final viewModel = widget.viewModel;
final settings = viewModel.settings.rebuild((b) => b
..clientPortalUnderPaymentMinimum =
parseDouble(_minimumAmountController.text));
if (settings != viewModel.settings) {
viewModel.onSettingsChanged(settings);
}
}
@override
Widget build(BuildContext context) {
final localization = AppLocalization.of(context);
final viewModel = widget.viewModel;
final company = viewModel.state.settingsUIState.company;
final settings = viewModel.settings;
return AppForm(
formKey: _formKey,
focusNode: _focusNode,
child: FormCard(children: [
AppDropdownButton<String>(
labelText: localization.autoBillOn,
value: settings.autoBillDate,
onChanged: (dynamic value) => viewModel.onSettingsChanged(
settings.rebuild((b) => b..autoBillDate = value)),
items: [
DropdownMenuItem(
child: Text(localization.sendDate),
value: SettingsEntity.AUTO_BILL_ON_SEND_DATE,
),
DropdownMenuItem(
child: Text(localization.dueDate),
value: SettingsEntity.AUTO_BILL_ON_DUE_DATE,
),
],
),
AppDropdownButton<String>(
labelText: localization.useAvailableCredits,
value: company.useCreditsPayment,
onChanged: (dynamic value) {
viewModel.onCompanyChanged(
company.rebuild((b) => b..useCreditsPayment = value));
},
items: [
DropdownMenuItem(
child: Text(localization.always),
value: CompanyEntity.USE_CREDITS_ALWAYS,
),
DropdownMenuItem(
child: Text(localization.showOption),
value: CompanyEntity.USE_CREDITS_OPTION,
),
DropdownMenuItem(
child: Text(localization.off),
value: CompanyEntity.USE_CREDITS_OFF,
),
]),
SizedBox(height: 16),
BoolDropdownButton(
label: localization.allowOverPayment,
value: settings.clientPortalAllowOverPayment,
helpLabel: localization.allowOverPaymentHelp,
onChanged: (value) => viewModel.onSettingsChanged(
settings.rebuild((b) => b..clientPortalAllowOverPayment = value)),
),
BoolDropdownButton(
label: localization.allowUnderPayment,
value: settings.clientPortalAllowUnderPayment,
helpLabel: localization.allowUnderPaymentHelp,
onChanged: (value) => viewModel.onSettingsChanged(settings
.rebuild((b) => b..clientPortalAllowUnderPayment = value)),
),
if (settings.clientPortalAllowUnderPayment == true)
Padding(
padding: const EdgeInsets.only(top: 16),
child: DecoratedFormField(
label: localization.minimumUnderPaymentAmount,
controller: _minimumAmountController,
),
),
]),
);
}
}

View File

@ -1,7 +1,6 @@
import 'dart:async';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
import 'package:redux/redux.dart';
import 'package:flutter/material.dart';
@ -45,9 +44,6 @@ class CompanyGatewayListVM {
@required this.onRefreshed,
@required this.onSortChanged,
@required this.onRemovePressed,
@required this.onSettingsChanged,
@required this.settings,
@required this.onCompanyChanged,
});
static CompanyGatewayListVM fromStore(Store<AppState> store) {
@ -81,9 +77,6 @@ class CompanyGatewayListVM {
state: state,
listState: state.companyGatewayListState,
companyGatewayList: gatewayIds,
settings: state.uiState.settingsUIState.settings,
onCompanyChanged: (company) =>
store.dispatch(UpdateCompany(company: company)),
companyGatewayMap: state.companyGatewayState.map,
filter: state.companyGatewayUIState.listUIState.filter,
onCompanyGatewayTap: (context, companyGateway) {
@ -111,8 +104,6 @@ class CompanyGatewayListVM {
.rebuild((b) => b..companyGatewayIds = gatewayIds.join(','));
store.dispatch(UpdateSettings(settings: settings));
},
onSettingsChanged: (settings) =>
store.dispatch(UpdateSettings(settings: settings)),
);
}
@ -125,7 +116,4 @@ class CompanyGatewayListVM {
final Function(BuildContext) onRefreshed;
final Function(int, int) onSortChanged;
final Function(String) onRemovePressed;
final SettingsEntity settings;
final Function(SettingsEntity) onSettingsChanged;
final Function(CompanyEntity) onCompanyChanged;
}

View File

@ -24,7 +24,7 @@ class CompanyGatewayScreen extends StatelessWidget {
@required this.viewModel,
}) : super(key: key);
static const String route = '/$kSettings/$kSettingsOnlinePayments';
static const String route = '/$kSettings/$kSettingsCompanyGateways';
final CompanyGatewayScreenVM viewModel;

View File

@ -17,7 +17,7 @@ import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class CompanyGatewayEditScreen extends StatelessWidget {
const CompanyGatewayEditScreen({Key key}) : super(key: key);
static const String route = '/$kSettings/$kSettingsOnlinePaymentsEdit';
static const String route = '/$kSettings/$kSettingsCompanyGatewaysEdit';
@override
Widget build(BuildContext context) {

View File

@ -22,7 +22,7 @@ class CompanyGatewayViewScreen extends StatelessWidget {
}) : super(key: key);
final bool isFilter;
static const String route = '/$kSettings/$kSettingsOnlinePaymentsView';
static const String route = '/$kSettings/$kSettingsCompanyGatewaysView';
@override
Widget build(BuildContext context) {

View File

@ -0,0 +1,163 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/company_model.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/forms/app_dropdown_button.dart';
import 'package:invoiceninja_flutter/ui/app/forms/app_form.dart';
import 'package:invoiceninja_flutter/ui/app/forms/bool_dropdown_button.dart';
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/settings/online_payments_vm.dart';
import 'package:invoiceninja_flutter/ui/app/edit_scaffold.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class OnlinePayments extends StatefulWidget {
const OnlinePayments({
Key key,
@required this.viewModel,
}) : super(key: key);
final OnlinePaymentsVM viewModel;
@override
_OnlinePaymentsState createState() => _OnlinePaymentsState();
}
class _OnlinePaymentsState extends State<OnlinePayments> {
static final GlobalKey<FormState> _formKey =
GlobalKey<FormState>(debugLabel: '_onlinePayments');
FocusScopeNode _focusNode;
final _minimumAmountController = TextEditingController();
List<TextEditingController> _controllers = [];
@override
void initState() {
super.initState();
_focusNode = FocusScopeNode();
}
@override
void didChangeDependencies() {
_controllers = [
_minimumAmountController,
];
_controllers
.forEach((dynamic controller) => controller.removeListener(_onChanged));
_minimumAmountController.text = formatNumber(
widget.viewModel.settings.clientPortalUnderPaymentMinimum, context,
formatNumberType: FormatNumberType.inputMoney);
_controllers
.forEach((dynamic controller) => controller.addListener(_onChanged));
super.didChangeDependencies();
}
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
void _onChanged() {
final viewModel = widget.viewModel;
final settings = viewModel.settings.rebuild((b) => b
..clientPortalUnderPaymentMinimum =
parseDouble(_minimumAmountController.text));
if (settings != viewModel.settings) {
viewModel.onSettingsChanged(settings);
}
}
@override
Widget build(BuildContext context) {
final localization = AppLocalization.of(context);
final viewModel = widget.viewModel;
final company = viewModel.company;
final settings = viewModel.settings;
return EditScaffold(
title: localization.onlinePayments,
onSavePressed: viewModel.onSavePressed,
body: AppForm(
formKey: _formKey,
focusNode: _focusNode,
children: <Widget>[
FormCard(children: <Widget>[
AppDropdownButton<String>(
labelText: localization.autoBillOn,
value: settings.autoBillDate,
onChanged: (dynamic value) => viewModel.onSettingsChanged(
settings.rebuild((b) => b..autoBillDate = value)),
items: [
DropdownMenuItem(
child: Text(localization.sendDate),
value: SettingsEntity.AUTO_BILL_ON_SEND_DATE,
),
DropdownMenuItem(
child: Text(localization.dueDate),
value: SettingsEntity.AUTO_BILL_ON_DUE_DATE,
),
],
),
AppDropdownButton<String>(
labelText: localization.useAvailableCredits,
value: company.useCreditsPayment,
onChanged: (dynamic value) {
viewModel.onCompanyChanged(
company.rebuild((b) => b..useCreditsPayment = value));
},
items: [
DropdownMenuItem(
child: Text(localization.always),
value: CompanyEntity.USE_CREDITS_ALWAYS,
),
DropdownMenuItem(
child: Text(localization.showOption),
value: CompanyEntity.USE_CREDITS_OPTION,
),
DropdownMenuItem(
child: Text(localization.off),
value: CompanyEntity.USE_CREDITS_OFF,
),
]),
SizedBox(height: 16),
BoolDropdownButton(
label: localization.allowOverPayment,
value: settings.clientPortalAllowOverPayment,
helpLabel: localization.allowOverPaymentHelp,
onChanged: (value) => viewModel.onSettingsChanged(settings
.rebuild((b) => b..clientPortalAllowOverPayment = value)),
),
BoolDropdownButton(
label: localization.allowUnderPayment,
value: settings.clientPortalAllowUnderPayment,
helpLabel: localization.allowUnderPaymentHelp,
onChanged: (value) => viewModel.onSettingsChanged(settings
.rebuild((b) => b..clientPortalAllowUnderPayment = value)),
),
if (settings.clientPortalAllowUnderPayment == true)
Padding(
padding: const EdgeInsets.only(top: 16),
child: DecoratedFormField(
label: localization.minimumUnderPaymentAmount,
controller: _minimumAmountController,
),
),
]),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: AppButton(
iconData: Icons.settings,
label: localization.configureGateways.toUpperCase(),
onPressed: () => viewModel.onConfigureGatewaysPressed(context),
),
),
],
),
);
}
}

View File

@ -0,0 +1,97 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/client_model.dart';
import 'package:invoiceninja_flutter/data/models/company_model.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/data/models/group_model.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
import 'package:invoiceninja_flutter/redux/group/group_actions.dart';
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
import 'package:invoiceninja_flutter/ui/settings/online_payments.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class OnlinePaymentsScreen extends StatelessWidget {
const OnlinePaymentsScreen({Key key}) : super(key: key);
static const String route = '/$kSettings/$kSettingsOnlinePayments';
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, OnlinePaymentsVM>(
converter: OnlinePaymentsVM.fromStore,
builder: (context, viewModel) {
return OnlinePayments(
viewModel: viewModel,
key: ValueKey(viewModel.state.settingsUIState.updatedAt),
);
},
);
}
}
class OnlinePaymentsVM {
OnlinePaymentsVM({
@required this.state,
@required this.company,
@required this.onCompanyChanged,
@required this.onSavePressed,
@required this.onSettingsChanged,
@required this.settings,
@required this.onConfigureGatewaysPressed,
});
static OnlinePaymentsVM fromStore(Store<AppState> store) {
final state = store.state;
return OnlinePaymentsVM(
state: state,
company: state.uiState.settingsUIState.company,
settings: state.uiState.settingsUIState.settings,
onCompanyChanged: (company) =>
store.dispatch(UpdateCompany(company: company)),
onSettingsChanged: (settings) =>
store.dispatch(UpdateSettings(settings: settings)),
onSavePressed: (context) {
final settingsUIState = state.uiState.settingsUIState;
switch (settingsUIState.entityType) {
case EntityType.company:
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).savedSettings);
store.dispatch(SaveCompanyRequest(
completer: completer, company: settingsUIState.company));
break;
case EntityType.group:
final completer = snackBarCompleter<GroupEntity>(
context, AppLocalization.of(context).savedSettings);
store.dispatch(SaveGroupRequest(
completer: completer, group: settingsUIState.group));
break;
case EntityType.client:
final completer = snackBarCompleter<ClientEntity>(
context, AppLocalization.of(context).savedSettings);
store.dispatch(SaveClientRequest(
completer: completer, client: settingsUIState.client));
break;
}
},
onConfigureGatewaysPressed: (context) {
store.dispatch(ViewSettings(
navigator: Navigator.of(context),
section: kSettingsCompanyGateways));
},
);
}
final AppState state;
final CompanyEntity company;
final SettingsEntity settings;
final Function(BuildContext) onSavePressed;
final Function(CompanyEntity) onCompanyChanged;
final Function(SettingsEntity) onSettingsChanged;
final Function(BuildContext) onConfigureGatewaysPressed;
}

View File

@ -284,7 +284,7 @@ class SettingsSearch extends StatelessWidget {
'first_month_of_the_year',
'custom_labels',
],
kSettingsOnlinePayments: [
kSettingsCompanyGateways: [
'accepted_card_logos',
'limits_and_fees',
],

View File

@ -570,7 +570,8 @@ mixin LocalizationsProvider on LocaleCodeAware {
'invoice_tax_rates': 'Invoice Tax Rates',
'item_tax_rates': 'Item Tax Rates',
'no_client_selected': 'No client selected',
'configure_rates': 'Configure rates',
'configure_rates': 'Configure Rates',
'configure_gateways': 'Configure Gateways',
'tax_settings': 'Tax Settings',
'tax_settings_rates': 'Tax Rates',
'accent_color': 'Accent Color',
@ -3128,6 +3129,9 @@ mixin LocalizationsProvider on LocaleCodeAware {
String get configureRates =>
_localizedValues[localeCode]['configure_rates'] ?? '';
String get configureGateways =>
_localizedValues[localeCode]['configure_gateways'] ?? '';
String get taxSettingsRates =>
_localizedValues[localeCode]['tax_settings_rates'] ?? '';

View File

@ -150,6 +150,7 @@ IconData getSettingIcon(String section) {
case kSettingsLocalization:
return Icons.language;
case kSettingsOnlinePayments:
case kSettingsCompanyGateways:
return MdiIcons.creditCard;
case kSettingsTaxSettings:
case kSettingsTaxRates: