Files
sendico/frontend/pweb/lib/app/router/payout_shell.dart

428 lines
15 KiB
Dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:pshared/controllers/balance_mask/wallets.dart';
import 'package:pshared/controllers/payment/source.dart';
import 'package:pshared/models/ledger/account.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pshared/models/recipient/recipient.dart';
import 'package:pshared/provider/ledger.dart';
import 'package:pshared/provider/organizations.dart';
import 'package:pshared/provider/payment/amount.dart';
import 'package:pshared/provider/payment/flow.dart';
import 'package:pshared/provider/payment/multiple/provider.dart';
import 'package:pshared/provider/payment/multiple/quotation.dart';
import 'package:pshared/provider/payment/payments.dart';
import 'package:pshared/provider/payment/provider.dart';
import 'package:pshared/provider/payment/quotation/quotation.dart';
import 'package:pshared/provider/payment/updates.dart';
import 'package:pshared/provider/payout_verification.dart';
import 'package:pshared/provider/recipient/provider.dart';
import 'package:pshared/provider/recipient/methods_cache.dart';
import 'package:pshared/provider/recipient/pmethods.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/app/router/payout_routes.dart';
import 'package:pweb/controllers/payouts/multiple_payouts.dart';
import 'package:pweb/controllers/payouts/multi_quotation.dart';
import 'package:pweb/controllers/payments/page.dart';
import 'package:pweb/controllers/payouts/payout_verification.dart';
import 'package:pweb/pages/invitations/page/page.dart';
import 'package:pweb/providers/multiple_payouts.dart';
import 'package:pweb/controllers/payouts/quotation.dart';
import 'package:pshared/models/payment/wallet.dart';
import 'package:pweb/pages/address_book/form/page.dart';
import 'package:pweb/pages/address_book/page/page.dart';
import 'package:pweb/pages/dashboard/dashboard.dart';
import 'package:pweb/pages/payout_page/send/page.dart';
import 'package:pweb/pages/payout_page/wallet/edit/page.dart';
import 'package:pweb/pages/report/details/page.dart';
import 'package:pweb/pages/report/page.dart';
import 'package:pweb/pages/settings/profile/page.dart';
import 'package:pweb/pages/wallet_top_up/page.dart';
import 'package:pweb/widgets/dialogs/confirmation_dialog.dart';
import 'package:pweb/utils/error/snackbar.dart';
import 'package:pweb/widgets/sidebar/destinations.dart';
import 'package:pweb/widgets/sidebar/page.dart';
import 'package:pweb/utils/payment/availability.dart';
import 'package:pweb/services/payments/csv_input.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
RouteBase payoutShellRoute() => ShellRoute(
builder: (context, state, child) => MultiProvider(
providers: [
ChangeNotifierProxyProvider2<
OrganizationsProvider,
RecipientsProvider,
PaymentMethodsProvider
>(
create: (_) => PaymentMethodsProvider(),
update: (context, organizations, recipients, provider) =>
provider!..updateProviders(organizations, recipients),
),
ChangeNotifierProxyProvider2<
OrganizationsProvider,
RecipientsProvider,
RecipientMethodsCacheProvider
>(
create: (_) => RecipientMethodsCacheProvider(),
update: (context, organizations, recipients, provider) =>
provider!..updateProviders(organizations, recipients),
),
ChangeNotifierProxyProvider2<
RecipientsProvider,
PaymentMethodsProvider,
PaymentFlowProvider
>(
create: (_) =>
PaymentFlowProvider(initialType: enabledPaymentTypes.first),
update: (context, recipients, methods, provider) =>
provider!..update(recipients, methods),
),
ChangeNotifierProvider(create: (_) => PaymentAmountProvider()),
ChangeNotifierProxyProvider2<
WalletsController,
LedgerAccountsProvider,
PaymentSourceController
>(
create: (_) => PaymentSourceController(),
update: (_, wallets, ledger, controller) =>
controller!..update(wallets, ledger),
),
ChangeNotifierProxyProvider6<
OrganizationsProvider,
PaymentAmountProvider,
PaymentSourceController,
PaymentFlowProvider,
RecipientsProvider,
PaymentMethodsProvider,
QuotationProvider
>(
create: (_) => QuotationProvider(),
update:
(
_,
organization,
payment,
source,
flow,
recipients,
methods,
provider,
) => provider!
..update(
organization,
payment,
source,
flow,
recipients,
methods,
),
),
ChangeNotifierProxyProvider<QuotationProvider, QuotationController>(
create: (_) => QuotationController(),
update: (_, quotation, controller) => controller!..update(quotation),
),
ChangeNotifierProxyProvider2<
OrganizationsProvider,
QuotationProvider,
PaymentProvider
>(
create: (_) => PaymentProvider(),
update: (context, organization, quotation, provider) =>
provider!..update(organization, quotation),
),
ChangeNotifierProvider(create: (_) => PayoutVerificationProvider()),
ChangeNotifierProxyProvider<
PayoutVerificationProvider,
PayoutVerificationController
>(
create: (_) => PayoutVerificationController(),
update: (context, verification, controller) =>
controller!..update(verification),
),
ChangeNotifierProxyProvider4<
PaymentProvider,
QuotationProvider,
PaymentFlowProvider,
RecipientsProvider,
PaymentPageController
>(
create: (_) => PaymentPageController(),
update: (context, payment, quotation, flow, recipients, controller) =>
controller!..update(payment, quotation, flow, recipients),
),
ChangeNotifierProxyProvider<
OrganizationsProvider,
MultiQuotationProvider
>(
create: (_) => MultiQuotationProvider(),
update: (context, organization, provider) =>
provider!..update(organization),
),
ChangeNotifierProxyProvider<
MultiQuotationProvider,
MultiQuotationController
>(
create: (_) => MultiQuotationController(),
update: (_, quotation, controller) => controller!..update(quotation),
),
ChangeNotifierProxyProvider2<
OrganizationsProvider,
MultiQuotationProvider,
MultiPaymentProvider
>(
create: (_) => MultiPaymentProvider(),
update: (context, organization, quotation, provider) =>
provider!..update(organization, quotation),
),
ChangeNotifierProxyProvider3<
PaymentsProvider,
PaymentProvider,
MultiPaymentProvider,
PaymentsUpdatesProvider
>(
create: (_) => PaymentsUpdatesProvider(),
lazy: false,
update: (_, payments, payment, multiPayment, controller) =>
controller!..update(
paymentsProvider: payments,
paymentProvider: payment,
multiPaymentProvider: multiPayment,
),
),
ChangeNotifierProxyProvider2<
MultiQuotationProvider,
MultiPaymentProvider,
MultiplePayoutsProvider
>(
create: (_) => MultiplePayoutsProvider(),
update: (context, quotation, payment, provider) =>
provider!..update(quotation, payment),
),
ChangeNotifierProxyProvider2<
MultiplePayoutsProvider,
PaymentSourceController,
MultiplePayoutsController
>(
create: (_) =>
MultiplePayoutsController(csvInput: WebCsvInputService()),
update: (context, provider, sourceController, controller) =>
controller!..update(provider, sourceController),
),
],
child: PageSelector(child: child, routerState: state),
),
routes: [
GoRoute(
name: PayoutRoutes.dashboard,
path: routerPage(Pages.dashboard),
pageBuilder: (context, _) => NoTransitionPage(
child: DashboardPage(
onRecipientSelected: (recipient) =>
_startPayment(context, recipient: recipient),
onGoToPaymentWithoutRecipient: (type) =>
_startPayment(context, recipient: null, paymentType: type),
onTopUp: (wallet) => _openWalletTopUp(context, wallet),
onLedgerAddFunds: (account) => _openLedgerAddFunds(context, account),
onWalletTap: (wallet) => _openWalletEdit(context, wallet),
onLedgerTap: (account) => _openLedgerEdit(context, account),
),
),
),
GoRoute(
name: PayoutRoutes.recipients,
path: PayoutRoutes.recipientsPath,
pageBuilder: (context, _) {
final loc = AppLocalizations.of(context)!;
return NoTransitionPage(
child: RecipientAddressBookPage(
onRecipientSelected: (recipient) =>
_startPayment(context, recipient: recipient),
onAddRecipient: () => _openAddRecipient(context),
onEditRecipient: (recipient) =>
_openEditRecipient(context, recipient: recipient),
onDeleteRecipient: (recipient) async {
final confirmed = await showConfirmationDialog(
context: context,
title: loc.delete,
message: loc.deleteRecipientConfirmation,
confirmLabel: loc.delete,
);
if (!confirmed) return;
await executeActionWithNotification(
context: context,
action: () async =>
context.read<RecipientsProvider>().delete(recipient.id),
successMessage: loc.recipientDeletedSuccessfully,
errorMessage: loc.errorDeleteRecipient,
);
},
),
);
},
),
GoRoute(
name: PayoutRoutes.invitations,
path: PayoutRoutes.invitationsPath,
pageBuilder: (_, _) => const NoTransitionPage(child: InvitationsPage()),
),
GoRoute(
name: PayoutRoutes.addRecipient,
path: PayoutRoutes.addRecipientPath,
pageBuilder: (context, _) {
final recipient = context.read<RecipientsProvider>().currentObject;
return NoTransitionPage(
child: AddressBookRecipientForm(
recipient: recipient,
onSaved: (_) => _popOrGo(context),
),
);
},
),
GoRoute(
name: PayoutRoutes.editRecipient,
path: PayoutRoutes.editRecipientPath,
pageBuilder: (context, _) {
final recipient = context.read<RecipientsProvider>().currentObject;
return NoTransitionPage(
child: AddressBookRecipientForm(
recipient: recipient,
onSaved: (_) => _popOrGo(context),
),
);
},
),
GoRoute(
name: PayoutRoutes.payment,
path: PayoutRoutes.paymentPath,
pageBuilder: (context, state) {
final fallbackDestination = PayoutDestination.dashboard;
return NoTransitionPage(
child: PaymentPage(
onBack: (_) => _popOrGo(context),
initialPaymentType: PayoutRoutes.paymentTypeFromState(state),
initialDestinationLedgerAccountRef:
PayoutRoutes.destinationLedgerAccountRefFromState(state),
fallbackDestination: fallbackDestination,
),
);
},
),
GoRoute(
name: PayoutRoutes.settings,
path: PayoutRoutes.settingsPath,
pageBuilder: (_, _) =>
const NoTransitionPage(child: ProfileSettingsPage()),
),
GoRoute(
name: PayoutRoutes.reports,
path: PayoutRoutes.reportsPath,
pageBuilder: (_, _) =>
const NoTransitionPage(child: OperationHistoryPage()),
),
GoRoute(
name: PayoutRoutes.reportPayment,
path: PayoutRoutes.reportPaymentPath,
pageBuilder: (_, state) => NoTransitionPage(
child: PaymentDetailsPage(
paymentId:
state.uri.queryParameters[PayoutRoutes.reportPaymentIdQuery] ??
'',
),
),
),
GoRoute(
name: PayoutRoutes.methods,
path: PayoutRoutes.methodsPath,
redirect: (_, state) => PayoutRoutes.dashboardPath,
),
GoRoute(
name: PayoutRoutes.editWallet,
path: PayoutRoutes.editWalletPath,
pageBuilder: (context, state) => NoTransitionPage(
child: WalletEditPage(onBack: () => _popOrGo(context)),
),
),
GoRoute(
name: PayoutRoutes.walletTopUp,
path: PayoutRoutes.walletTopUpPath,
pageBuilder: (context, state) {
return NoTransitionPage(
child: WalletTopUpPage(onBack: () => _popOrGo(context)),
);
},
),
],
);
void _startPayment(
BuildContext context, {
Recipient? recipient,
PaymentType? paymentType,
}) {
context.read<RecipientsProvider>().setCurrentObject(recipient?.id);
context.pushNamed(
PayoutRoutes.payment,
queryParameters: PayoutRoutes.buildQueryParameters(
paymentType: paymentType,
),
);
}
void _openAddRecipient(BuildContext context, {Recipient? recipient}) {
context.read<RecipientsProvider>().setCurrentObject(recipient?.id);
context.pushNamed(PayoutRoutes.addRecipient);
}
void _openEditRecipient(BuildContext context, {required Recipient recipient}) {
context.read<RecipientsProvider>().setCurrentObject(recipient.id);
context.pushNamed(PayoutRoutes.editRecipient);
}
void _openWalletEdit(BuildContext context, Wallet wallet) {
context.read<PaymentSourceController>().selectWallet(wallet);
context.read<WalletsController>().selectWallet(wallet);
context.pushToEditWallet();
}
void _openLedgerEdit(BuildContext context, LedgerAccount account) {
context.read<PaymentSourceController>().selectLedgerByRef(
account.ledgerAccountRef,
);
context.pushToEditWallet();
}
void _openLedgerAddFunds(BuildContext context, LedgerAccount account) {
context.read<PaymentSourceController>().selectLedgerByRef(
account.ledgerAccountRef,
);
context.read<RecipientsProvider>().setCurrentObject(null);
context.pushNamed(
PayoutRoutes.payment,
queryParameters: PayoutRoutes.buildQueryParameters(
paymentType: PaymentType.ledger,
destinationLedgerAccountRef: account.ledgerAccountRef,
),
);
}
void _openWalletTopUp(BuildContext context, Wallet wallet) {
context.read<WalletsController>().selectWallet(wallet);
context.pushToWalletTopUp();
}
void _popOrGo(BuildContext context) {
final router = GoRouter.of(context);
if (router.canPop()) {
router.pop();
} else {
context.goToPayout(PayoutDestination.dashboard);
}
}