recipient saving
This commit is contained in:
@@ -67,7 +67,7 @@ MNTX_GATEWAY_COMPOSE_PROJECT=sendico-mntx-gateway
|
||||
MNTX_GATEWAY_SERVICE_NAME=sendico_mntx_gateway
|
||||
MNTX_GATEWAY_GRPC_PORT=50075
|
||||
MNTX_GATEWAY_METRICS_PORT=9404
|
||||
MNTX_GATEWAY_HTTP_PORT=8080
|
||||
MNTX_GATEWAY_HTTP_PORT=8084
|
||||
MONETIX_BASE_URL=https://api.txflux.com
|
||||
|
||||
|
||||
|
||||
@@ -3,4 +3,6 @@ import 'package:pshared/models/payment/type.dart';
|
||||
|
||||
abstract class PaymentMethodData {
|
||||
PaymentType get type;
|
||||
}
|
||||
}
|
||||
|
||||
typedef MethodMap = Map<PaymentType, PaymentMethodData?>;
|
||||
@@ -1,7 +1,12 @@
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import 'package:pshared/data/mapper/payment/method.dart';
|
||||
import 'package:pshared/models/describable.dart';
|
||||
import 'package:pshared/models/organization/bound.dart';
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
import 'package:pshared/models/payment/methods/type.dart';
|
||||
import 'package:pshared/models/permissions/bound.dart';
|
||||
import 'package:pshared/models/storable.dart';
|
||||
import 'package:pshared/provider/organizations.dart';
|
||||
import 'package:pshared/provider/recipient/provider.dart';
|
||||
import 'package:pshared/provider/template.dart';
|
||||
@@ -49,6 +54,23 @@ class PaymentMethodsProvider extends GenericProvider<PaymentMethod> {
|
||||
cascade: true,
|
||||
);
|
||||
|
||||
Future<PaymentMethod> create({
|
||||
required String reacipientRef,
|
||||
required PaymentMethodData data,
|
||||
required String name,
|
||||
}) => createObject(
|
||||
_organizations.current.id,
|
||||
PaymentMethod(
|
||||
storable: newStorable(),
|
||||
permissionBound: newPermissionBound(
|
||||
organizationBound: newOrganizationBound(organizationRef: _organizations.current.id),
|
||||
),
|
||||
recipientRef: reacipientRef,
|
||||
data: data,
|
||||
describable: newDescribable(name: name),
|
||||
).toDTO().toJson(),
|
||||
);
|
||||
|
||||
|
||||
Future<void> makeMain(PaymentMethod method) {
|
||||
// TODO: create separate backend method to manage main payment method
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
import 'package:pshared/data/mapper/organization/bound.dart';
|
||||
import 'package:pshared/models/recipient/filter.dart';
|
||||
import 'package:pshared/models/recipient/recipient.dart';
|
||||
import 'package:pshared/models/recipient/status.dart';
|
||||
import 'package:pshared/models/recipient/type.dart';
|
||||
import 'package:pshared/provider/organizations.dart';
|
||||
import 'package:pshared/provider/template.dart';
|
||||
import 'package:pshared/service/recipient/service.dart';
|
||||
@@ -51,6 +53,20 @@ class RecipientsProvider extends GenericProvider<Recipient> {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<Recipient> create({
|
||||
required String name,
|
||||
required String email,
|
||||
}) async => createObject(
|
||||
_organizations.current.id,
|
||||
newRecipient(
|
||||
organizationRef: _organizations.current.id,
|
||||
email: email,
|
||||
name: name,
|
||||
status: RecipientStatus.ready,
|
||||
type: RecipientType.internal,
|
||||
).toDTO().toJson(),
|
||||
);
|
||||
|
||||
void updateProviders(OrganizationsProvider organizations) {
|
||||
_organizations = organizations;
|
||||
if (_organizations.isOrganizationSet) {
|
||||
|
||||
@@ -429,6 +429,11 @@
|
||||
"companyName": "Name of your company",
|
||||
"companynameRequired": "Company name required",
|
||||
|
||||
"errorSaveRecipient": "Failed to save recipient",
|
||||
"@errorSaveRecipient": {
|
||||
"description": "Error message displayed when saving a recipient fails"
|
||||
},
|
||||
|
||||
"errorSignUp": "Error occured while signing up, try again later",
|
||||
"companyDescription": "Company Description",
|
||||
"companyDescriptionHint": "Describe any of the fields of the Company's business",
|
||||
|
||||
@@ -429,6 +429,11 @@
|
||||
"companyName": "Название вашей компании",
|
||||
"companynameRequired": "Необходимо указать название компании",
|
||||
|
||||
"errorSaveRecipient": "Не удалось сохранить получателя",
|
||||
"@errorSaveRecipient": {
|
||||
"description": "Сообщение об ошибке при неудачном сохранении получателя"
|
||||
},
|
||||
|
||||
"errorSignUp": "Произошла ошибка при регистрации, попробуйте позже",
|
||||
"companyDescription": "Описание компании",
|
||||
"companyDescriptionHint": "Опишите любую из сфер деятельности компании",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
|
||||
import 'package:pshared/models/payment/type.dart';
|
||||
|
||||
@@ -9,8 +10,8 @@ import 'package:pweb/pages/payment_methods/icon.dart';
|
||||
class AdressBookPaymentMethodTile extends StatefulWidget {
|
||||
final PaymentType type;
|
||||
final String title;
|
||||
final Map<PaymentType, Object?> methods;
|
||||
final ValueChanged<Object?> onChanged;
|
||||
final MethodMap methods;
|
||||
final ValueChanged<PaymentMethodData?> onChanged;
|
||||
|
||||
final double spacingM;
|
||||
final double spacingS;
|
||||
|
||||
@@ -2,17 +2,22 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
import 'package:pshared/models/payment/type.dart';
|
||||
import 'package:pshared/models/recipient/recipient.dart';
|
||||
import 'package:pshared/models/recipient/status.dart';
|
||||
import 'package:pshared/models/recipient/type.dart';
|
||||
import 'package:pshared/provider/organizations.dart';
|
||||
import 'package:pshared/provider/recipient/pmethods.dart';
|
||||
import 'package:pshared/provider/recipient/provider.dart';
|
||||
|
||||
import 'package:pweb/pages/address_book/form/view.dart';
|
||||
// import 'package:pweb/services/amplitude.dart';
|
||||
import 'package:pweb/utils/error/snackbar.dart';
|
||||
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
import 'package:pweb/utils/payment/label.dart';
|
||||
import 'package:pweb/utils/snackbar.dart';
|
||||
|
||||
|
||||
class AdressBookRecipientForm extends StatefulWidget {
|
||||
@@ -31,7 +36,7 @@ class _AdressBookRecipientFormState extends State<AdressBookRecipientForm> {
|
||||
late TextEditingController _emailCtrl;
|
||||
RecipientType _type = RecipientType.internal;
|
||||
RecipientStatus _status = RecipientStatus.ready;
|
||||
final Map<PaymentType, Object?> _methods = {};
|
||||
final MethodMap _methods = {};
|
||||
late PaymentMethodsProvider _methodsProvider;
|
||||
|
||||
Future<void> _loadMethods() async {
|
||||
@@ -63,31 +68,43 @@ class _AdressBookRecipientFormState extends State<AdressBookRecipientForm> {
|
||||
_loadMethods();
|
||||
}
|
||||
|
||||
Future<Recipient?> _doSave() async {
|
||||
final recipients = context.read<RecipientsProvider>();
|
||||
final methods = context.read<PaymentMethodsProvider>();
|
||||
final recipient = await recipients.create(
|
||||
name: _nameCtrl.text,
|
||||
email: _emailCtrl.text,
|
||||
);
|
||||
if (methods.currentObject == null) return recipient;
|
||||
final data = methods.currentObject!;
|
||||
await methods.create(
|
||||
reacipientRef: recipient.id,
|
||||
name: getPaymentTypeLabel(context, data.type),
|
||||
data: data.data,
|
||||
);
|
||||
return recipient;
|
||||
}
|
||||
|
||||
//TODO: Change when registration is ready
|
||||
void _save() {
|
||||
Future<void> _save() async {
|
||||
if (!_formKey.currentState!.validate() || _methods.isEmpty) {
|
||||
// AmplitudeService.recipientAddCompleted(
|
||||
// _type,
|
||||
// _status,
|
||||
// _methods.keys.toSet(),
|
||||
// );
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.recipientFormRule),
|
||||
),
|
||||
);
|
||||
notifyUser(context, AppLocalizations.of(context)!.errorSaveRecipient);
|
||||
return;
|
||||
}
|
||||
|
||||
final recipient = newRecipient(
|
||||
name: _nameCtrl.text,
|
||||
email: _emailCtrl.text,
|
||||
type: _type,
|
||||
status: _status,
|
||||
avatarUrl: null,
|
||||
organizationRef: context.read<OrganizationsProvider>().current.id
|
||||
// AmplitudeService.recipientAddCompleted(
|
||||
// _type,
|
||||
// _status,
|
||||
// _methods.keys.toSet(),
|
||||
// );
|
||||
final recipient = await executeActionWithNotification(
|
||||
context: context,
|
||||
action: _doSave,
|
||||
errorMessage: AppLocalizations.of(context)!.errorSaveRecipient,
|
||||
successMessage: AppLocalizations.of(context)!.recipientFormRule,
|
||||
);
|
||||
|
||||
|
||||
widget.onSaved?.call(recipient);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
|
||||
import 'package:pshared/models/payment/type.dart';
|
||||
import 'package:pshared/models/recipient/status.dart';
|
||||
@@ -20,10 +21,10 @@ class FormView extends StatelessWidget {
|
||||
final TextEditingController emailCtrl;
|
||||
final RecipientType type;
|
||||
final RecipientStatus status;
|
||||
final Map<PaymentType, Object?> methods;
|
||||
final MethodMap methods;
|
||||
final ValueChanged<RecipientType> onTypeChanged;
|
||||
final ValueChanged<RecipientStatus> onStatusChanged;
|
||||
final void Function(PaymentType, Object?) onMethodsChanged;
|
||||
final void Function(PaymentType, PaymentMethodData?) onMethodsChanged;
|
||||
final VoidCallback onSave;
|
||||
final bool isEditing;
|
||||
final VoidCallback onBack;
|
||||
|
||||
@@ -42,10 +42,10 @@ class SaveButton extends StatelessWidget {
|
||||
child: Text(
|
||||
text ?? AppLocalizations.of(context)!.saveRecipient,
|
||||
style: textStyle ??
|
||||
theme.textTheme.labelLarge?.copyWith(
|
||||
color: theme.colorScheme.onPrimary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
theme.textTheme.labelLarge?.copyWith(
|
||||
color: theme.colorScheme.onPrimary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
import 'package:pshared/models/payment/type.dart';
|
||||
|
||||
import 'package:pweb/pages/payment_methods/form.dart';
|
||||
@@ -12,7 +13,7 @@ class PaymentDetailsSection extends StatelessWidget {
|
||||
final bool isEditable;
|
||||
final VoidCallback? onToggle;
|
||||
final PaymentType? selectedType;
|
||||
final Object? data;
|
||||
final PaymentMethodData? data;
|
||||
|
||||
const PaymentDetailsSection({
|
||||
super.key,
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pshared/models/payment/methods/card.dart';
|
||||
import 'package:pshared/models/payment/methods/crypto_address.dart';
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
import 'package:pshared/models/payment/methods/iban.dart';
|
||||
import 'package:pshared/models/payment/methods/russian_bank.dart';
|
||||
import 'package:pshared/models/payment/methods/wallet.dart';
|
||||
@@ -16,8 +17,8 @@ import 'package:pweb/pages/payment_methods/add/wallet.dart';
|
||||
|
||||
class PaymentMethodForm extends StatelessWidget {
|
||||
final PaymentType? selectedType;
|
||||
final ValueChanged<Object?> onChanged;
|
||||
final Object? initialData;
|
||||
final ValueChanged<PaymentMethodData?> onChanged;
|
||||
final PaymentMethodData? initialData;
|
||||
final bool isEditable;
|
||||
|
||||
const PaymentMethodForm({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
import 'package:pshared/models/payment/type.dart';
|
||||
import 'package:pshared/models/recipient/recipient.dart';
|
||||
|
||||
@@ -31,9 +32,9 @@ class PaymentInfoSection extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context)!;
|
||||
final hasRecipient = recipient != null;
|
||||
final availableTypes = hasRecipient
|
||||
final MethodMap availableTypes = hasRecipient
|
||||
? pageSelector.getAvailablePaymentTypes()
|
||||
: {for (final type in PaymentType.values) type: type};
|
||||
: {for (final type in PaymentType.values) type: null};
|
||||
|
||||
if (hasRecipient && availableTypes.isEmpty) {
|
||||
return Text(loc.recipientNoPaymentDetails);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
|
||||
import 'package:pshared/models/payment/methods/type.dart';
|
||||
import 'package:pshared/models/payment/type.dart';
|
||||
@@ -117,7 +118,7 @@ class PageSelectorProvider extends ChangeNotifier {
|
||||
);
|
||||
}
|
||||
|
||||
Map<PaymentType, Object> getAvailablePaymentTypes() {
|
||||
MethodMap getAvailablePaymentTypes() {
|
||||
final recipient = selectedRecipient;
|
||||
if ((recipient == null) || !methodsProvider.isReady) return {};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
|
||||
import 'package:pshared/models/payment/type.dart';
|
||||
import 'package:pshared/models/recipient/recipient.dart';
|
||||
@@ -8,14 +9,14 @@ import 'package:pweb/providers/page_selector.dart';
|
||||
|
||||
class PaymentFlowProvider extends ChangeNotifier {
|
||||
PaymentType _selectedType;
|
||||
Object? _manualPaymentData;
|
||||
PaymentMethodData? _manualPaymentData;
|
||||
|
||||
PaymentFlowProvider({
|
||||
required PaymentType initialType,
|
||||
}) : _selectedType = initialType;
|
||||
|
||||
PaymentType get selectedType => _selectedType;
|
||||
Object? get manualPaymentData => _manualPaymentData;
|
||||
PaymentMethodData? get manualPaymentData => _manualPaymentData;
|
||||
|
||||
void syncWithSelector(PageSelectorProvider selector) {
|
||||
final recipient = selector.selectedRecipient;
|
||||
@@ -53,7 +54,7 @@ class PaymentFlowProvider extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setManualPaymentData(Object? data) {
|
||||
void setManualPaymentData(PaymentMethodData? data) {
|
||||
_manualPaymentData = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pshared/utils/snackbar.dart';
|
||||
|
||||
import 'package:pweb/utils/error/handler.dart';
|
||||
import 'package:pweb/widgets/error/content.dart';
|
||||
@@ -52,13 +53,18 @@ Future<T?> executeActionWithNotification<T>({
|
||||
required BuildContext context,
|
||||
required Future<T> Function() action,
|
||||
required String errorMessage,
|
||||
String? successMessage,
|
||||
int delaySeconds = 3,
|
||||
}) async {
|
||||
final scaffoldMessenger = ScaffoldMessenger.of(context);
|
||||
final localizations = AppLocalizations.of(context)!;
|
||||
|
||||
try {
|
||||
return await action();
|
||||
final result = await action();
|
||||
if (successMessage != null) {
|
||||
notifyUser(context, successMessage, delaySeconds: delaySeconds);
|
||||
}
|
||||
return result;
|
||||
} catch (e) {
|
||||
// Report the error using your existing notifier.
|
||||
notifyUserOfErrorX(
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pshared/models/payment/methods/data.dart';
|
||||
import 'package:pshared/models/payment/type.dart';
|
||||
|
||||
import 'package:pweb/utils/payment/label.dart';
|
||||
|
||||
|
||||
class PaymentTypeSelector extends StatelessWidget {
|
||||
final Map<PaymentType, Object> availableTypes;
|
||||
final MethodMap availableTypes;
|
||||
final PaymentType selectedType;
|
||||
final ValueChanged<PaymentType> onSelected;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user