Compare commits
1 Commits
dedde76dd7
...
SEND023
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cb5101ed9 |
@@ -16,8 +16,8 @@ class CardPaymentMethod implements PaymentMethodData {
|
||||
|
||||
const CardPaymentMethod({
|
||||
required this.pan,
|
||||
this.expMonth,
|
||||
this.expYear,
|
||||
required this.expMonth,
|
||||
required this.expYear,
|
||||
required this.firstName,
|
||||
required this.lastName,
|
||||
this.country,
|
||||
|
||||
@@ -165,6 +165,7 @@ class PermissionsProvider extends ChangeNotifier {
|
||||
perm.Action? action,
|
||||
Object? objectRef,
|
||||
}) {
|
||||
if (!_organizations.isOrganizationSet) return false;
|
||||
final orgId = _organizations.current.id;
|
||||
final pd = policyDescriptions.firstWhereOrNull(
|
||||
(policy) =>
|
||||
|
||||
@@ -360,6 +360,7 @@
|
||||
"enterBik": "Enter BIK",
|
||||
"add": "Add",
|
||||
"expiryDate": "Expiry (MM/YY)",
|
||||
"enterExpiryDate": "Enter card expiry date",
|
||||
"firstName": "First Name",
|
||||
"enterFirstName": "Enter First Name",
|
||||
"lastName": "Last Name",
|
||||
|
||||
@@ -360,6 +360,7 @@
|
||||
"enterBik": "Введите БИК",
|
||||
"add": "Добавить",
|
||||
"expiryDate": "Срок действия (ММ/ГГ)",
|
||||
"enterExpiryDate": "Введите срок действия карты",
|
||||
"firstName": "Имя",
|
||||
"enterFirstName": "Введите имя",
|
||||
"lastName": "Фамилия",
|
||||
|
||||
@@ -30,6 +30,7 @@ class _CardFormMinimalState extends State<CardFormMinimal> {
|
||||
late TextEditingController _panController;
|
||||
late TextEditingController _firstNameController;
|
||||
late TextEditingController _lastNameController;
|
||||
late TextEditingController _expiryController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -37,17 +38,23 @@ class _CardFormMinimalState extends State<CardFormMinimal> {
|
||||
_panController = TextEditingController(text: widget.initialData?.pan ?? '');
|
||||
_firstNameController = TextEditingController(text: widget.initialData?.firstName ?? '');
|
||||
_lastNameController = TextEditingController(text: widget.initialData?.lastName ?? '');
|
||||
_expiryController = TextEditingController(text: _formatExpiry(widget.initialData));
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _emitIfValid());
|
||||
}
|
||||
|
||||
void _emitIfValid() {
|
||||
if (_formKey.currentState?.validate() ?? false) {
|
||||
final expiry = _parseExpiry(_expiryController.text);
|
||||
if (expiry == null) return;
|
||||
|
||||
widget.onChanged(
|
||||
CardPaymentMethod(
|
||||
pan: _panController.text.replaceAll(' ', ''),
|
||||
firstName: _firstNameController.text,
|
||||
lastName: _lastNameController.text,
|
||||
expMonth: expiry.month,
|
||||
expYear: expiry.year,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -63,6 +70,7 @@ class _CardFormMinimalState extends State<CardFormMinimal> {
|
||||
_panController.clear();
|
||||
_firstNameController.clear();
|
||||
_lastNameController.clear();
|
||||
_expiryController.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -70,12 +78,14 @@ class _CardFormMinimalState extends State<CardFormMinimal> {
|
||||
final hasPanChange = newData.pan != _panController.text;
|
||||
final hasFirstNameChange = newData.firstName != _firstNameController.text;
|
||||
final hasLastNameChange = newData.lastName != _lastNameController.text;
|
||||
final hasExpiryChange = _formatExpiry(newData) != _expiryController.text;
|
||||
|
||||
if (hasPanChange) _panController.text = newData.pan;
|
||||
if (hasFirstNameChange) _firstNameController.text = newData.firstName;
|
||||
if (hasLastNameChange) _lastNameController.text = newData.lastName;
|
||||
if (hasExpiryChange) _expiryController.text = _formatExpiry(newData);
|
||||
|
||||
if (hasPanChange || hasFirstNameChange || hasLastNameChange) {
|
||||
if (hasPanChange || hasFirstNameChange || hasLastNameChange || hasExpiryChange) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _emitIfValid());
|
||||
}
|
||||
}
|
||||
@@ -115,6 +125,16 @@ class _CardFormMinimalState extends State<CardFormMinimal> {
|
||||
style: getTextFieldStyle(context, widget.isEditable),
|
||||
validator: (v) => (v == null || v.isEmpty) ? l10n.enterLastName : null,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
TextFormField(
|
||||
readOnly: !widget.isEditable,
|
||||
controller: _expiryController,
|
||||
decoration: getInputDecoration(context, l10n.expiryDate, widget.isEditable),
|
||||
style: getTextFieldStyle(context, widget.isEditable),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [CreditCardExpirationDateFormatter()],
|
||||
validator: (v) => _parseExpiry(v ?? '') == null ? l10n.enterExpiryDate : null,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -125,6 +145,35 @@ class _CardFormMinimalState extends State<CardFormMinimal> {
|
||||
_panController.dispose();
|
||||
_firstNameController.dispose();
|
||||
_lastNameController.dispose();
|
||||
_expiryController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
String _formatExpiry(CardPaymentMethod? data) {
|
||||
if (data == null) return '';
|
||||
if (data.expMonth == null || data.expYear == null) return '';
|
||||
final month = data.expMonth!.toString().padLeft(2, '0');
|
||||
final year = (data.expYear! % 100).toString().padLeft(2, '0');
|
||||
return '$month/$year';
|
||||
}
|
||||
|
||||
_CardExpiry? _parseExpiry(String value) {
|
||||
final normalized = value.trim();
|
||||
final match = RegExp(r'^(\d{2})\s*/\s*(\d{2})$').firstMatch(normalized);
|
||||
if (match == null) return null;
|
||||
|
||||
final month = int.tryParse(match.group(1)!);
|
||||
final year = int.tryParse(match.group(2)!);
|
||||
if (month == null || year == null || month < 1 || month > 12) return null;
|
||||
|
||||
final normalizedYear = 2000 + year;
|
||||
return _CardExpiry(month: month, year: normalizedYear);
|
||||
}
|
||||
}
|
||||
|
||||
class _CardExpiry {
|
||||
final int month;
|
||||
final int year;
|
||||
|
||||
const _CardExpiry({required this.month, required this.year});
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:pshared/models/payment/wallet.dart';
|
||||
import 'package:pshared/models/recipient/recipient.dart';
|
||||
import 'package:pshared/provider/recipient/provider.dart';
|
||||
import 'package:pweb/pages/dashboard/payouts/form.dart';
|
||||
|
||||
import 'package:pweb/pages/dashboard/payouts/form.dart';
|
||||
import 'package:pweb/pages/payment_methods/payment_page/back_button.dart';
|
||||
import 'package:pweb/pages/payment_methods/payment_page/header.dart';
|
||||
import 'package:pweb/pages/payment_methods/payment_page/method_selector.dart';
|
||||
|
||||
@@ -23,7 +23,7 @@ class PaymentMethodDropdown extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) => DropdownButtonFormField<Wallet>(
|
||||
dropdownColor: Theme.of(context).colorScheme.onSecondary,
|
||||
value: _getSelectedMethod(),
|
||||
initialValue: _getSelectedMethod(),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context)!.whereGetMoney,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
|
||||
|
||||
Reference in New Issue
Block a user