397 lines
17 KiB
Dart
397 lines
17 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:kmobile/l10n/app_localizations.dart';
|
|
|
|
class APYRegisterScreen extends StatefulWidget {
|
|
final Map<String, dynamic>? initialData;
|
|
const APYRegisterScreen({super.key, this.initialData});
|
|
|
|
@override
|
|
State<APYRegisterScreen> createState() => _APYRegisterScreenState();
|
|
}
|
|
|
|
class _APYRegisterScreenState extends State<APYRegisterScreen> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
|
|
// Controllers
|
|
late final _titleController = TextEditingController(text: widget.initialData?['customertitle']?.toString());
|
|
late final _firstNameController = TextEditingController(text: widget.initialData?['customerfirstname']?.toString());
|
|
late final _middleNameController = TextEditingController(text: widget.initialData?['customermiddlename']?.toString());
|
|
late final _lastNameController = TextEditingController(text: widget.initialData?['customerlastname']?.toString());
|
|
late final _customerNoController = TextEditingController(text: widget.initialData?['customerno']?.toString());
|
|
late final _accountNoController = TextEditingController(text: widget.initialData?['accountno']?.toString());
|
|
late final _balanceController = TextEditingController(text: widget.initialData?['availablebalance']?.toString());
|
|
late final _dobController = TextEditingController(text: widget.initialData?['customerdob']?.toString());
|
|
late final _genderController = TextEditingController(text: widget.initialData?['gender']?.toString());
|
|
late final _marriedController = TextEditingController(text: widget.initialData?['married']?.toString());
|
|
late final _mobileController = TextEditingController(text: widget.initialData?['mobilenumber']?.toString());
|
|
late final _emailController = TextEditingController(text: widget.initialData?['emailid']?.toString());
|
|
late final _aadhaarController = TextEditingController(text: widget.initialData?['aadharno']?.toString());
|
|
late final _pincodeController = TextEditingController(text: widget.initialData?['pincode']?.toString());
|
|
|
|
late final _pensionAmountController = TextEditingController(text: widget.initialData?['pensionamtoptedfor']?.toString() ?? '1000');
|
|
late final _ageOfJoiningController = TextEditingController(text: widget.initialData?['ageofjoining']?.toString());
|
|
late final _spouseNameController = TextEditingController(text: widget.initialData?['nameofspouse']?.toString());
|
|
late final _incomeTaxPayerController = TextEditingController(text: widget.initialData?['whetherincometaxpayer']?.toString());
|
|
late final _otherSchemeController = TextEditingController(text: widget.initialData?['beneficaryofothersociatysecurityschemes']?.toString());
|
|
late final _collectionChannelController = TextEditingController(text: widget.initialData?['collectionchannel']?.toString() ?? '1');
|
|
late final _contributionTypeController = TextEditingController(text: widget.initialData?['contributionType']?.toString() ?? 'C');
|
|
late final _debitDateController = TextEditingController(text: widget.initialData?['subsequentContributionDebitDate']?.toString());
|
|
|
|
late final _nomineeNameController = TextEditingController(text: widget.initialData?['nomineename']?.toString());
|
|
late final _nomineeRelationController = TextEditingController(text: widget.initialData?['relationwithsubscriber']?.toString());
|
|
late final _nomineeMinorController = TextEditingController(text: widget.initialData?['nomineeminor']?.toString() ?? 'N');
|
|
late final _nomineeDobController = TextEditingController();
|
|
late final _guardianNameController = TextEditingController();
|
|
|
|
late final _fatcaController = TextEditingController(text: widget.initialData?['fatcacrsapplicable']?.toString());
|
|
late final _birthCountryController = TextEditingController(text: widget.initialData?['countryofbirth']?.toString());
|
|
late final _citizenshipCountryController = TextEditingController(text: widget.initialData?['countryofcitizenship']?.toString());
|
|
late final _taxResidenceCountryController = TextEditingController(text: widget.initialData?['countryofresidencefortaxpurpose']?.toString());
|
|
late final _usPersonController = TextEditingController(text: widget.initialData?['uspersonflag']?.toString());
|
|
|
|
final Map<String, String> _yesNoOptions = {
|
|
'Y': 'Yes',
|
|
'N': 'No',
|
|
};
|
|
|
|
final Map<String, String> _titleOptions = {
|
|
'01': 'Mr.',
|
|
'02': 'Mrs.',
|
|
'03': 'Miss',
|
|
};
|
|
|
|
final Map<String, String> _pensionOptions = {
|
|
'1000': '₹1000',
|
|
'2000': '₹2000',
|
|
'3000': '₹3000',
|
|
'4000': '₹4000',
|
|
'5000': '₹5000',
|
|
};
|
|
|
|
final Map<String, String> _collectionChannelOptions = {
|
|
'1': 'Bank',
|
|
};
|
|
|
|
Map<String, String> _getPeriodicityOptions(AppLocalizations l10n) => {
|
|
'C': l10n.monthly,
|
|
'Q': l10n.quarterly,
|
|
'H': l10n.halfYearly,
|
|
};
|
|
|
|
// Contribution Calculation Map
|
|
final Map<String, Map<String, String>> _contributionRates = {
|
|
'C': {
|
|
'1000': '90',
|
|
'2000': '178',
|
|
'3000': '268',
|
|
'4000': '356',
|
|
'5000': '446',
|
|
},
|
|
'Q': {
|
|
'1000': '268',
|
|
'2000': '530',
|
|
'3000': '1061',
|
|
'4000': '356', // Following prompt's example exactly
|
|
'5000': '1329',
|
|
},
|
|
'H': {
|
|
'1000': '531',
|
|
'2000': '1050',
|
|
'3000': '1582',
|
|
'4000': '2101',
|
|
'5000': '2632',
|
|
},
|
|
};
|
|
|
|
String get _calculatedContribution {
|
|
final periodicity = _contributionTypeController.text;
|
|
final amount = _pensionAmountController.text;
|
|
return _contributionRates[periodicity]?[amount] ?? '0';
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_titleController.dispose();
|
|
_firstNameController.dispose();
|
|
_middleNameController.dispose();
|
|
_lastNameController.dispose();
|
|
_customerNoController.dispose();
|
|
_accountNoController.dispose();
|
|
_balanceController.dispose();
|
|
_dobController.dispose();
|
|
_genderController.dispose();
|
|
_marriedController.dispose();
|
|
_mobileController.dispose();
|
|
_emailController.dispose();
|
|
_aadhaarController.dispose();
|
|
_pincodeController.dispose();
|
|
_pensionAmountController.dispose();
|
|
_ageOfJoiningController.dispose();
|
|
_spouseNameController.dispose();
|
|
_incomeTaxPayerController.dispose();
|
|
_otherSchemeController.dispose();
|
|
_collectionChannelController.dispose();
|
|
_contributionTypeController.dispose();
|
|
_debitDateController.dispose();
|
|
_nomineeNameController.dispose();
|
|
_nomineeRelationController.dispose();
|
|
_nomineeMinorController.dispose();
|
|
_nomineeDobController.dispose();
|
|
_guardianNameController.dispose();
|
|
_fatcaController.dispose();
|
|
_birthCountryController.dispose();
|
|
_citizenshipCountryController.dispose();
|
|
_taxResidenceCountryController.dispose();
|
|
_usPersonController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
bool _isFetched(String key) {
|
|
return widget.initialData != null &&
|
|
widget.initialData!.containsKey(key) &&
|
|
widget.initialData![key]?.toString().isNotEmpty == true;
|
|
}
|
|
|
|
void _handleRegister() {
|
|
if (_formKey.currentState!.validate()) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Registration logic to be implemented')),
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final l10n = AppLocalizations.of(context);
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text(l10n.apyRegistration),
|
|
),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
// Tile 1: Customer & APY Details
|
|
Card(
|
|
elevation: 2,
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(l10n.details,
|
|
style: const TextStyle(
|
|
fontSize: 18, fontWeight: FontWeight.bold)),
|
|
const SizedBox(height: 16),
|
|
_buildDropdownField(_titleController, l10n.customerTitle,
|
|
_titleOptions,
|
|
readOnly: _isFetched('customertitle')),
|
|
_buildTextField(
|
|
_firstNameController, l10n.customerFirstName,
|
|
readOnly: _isFetched('customerfirstname')),
|
|
_buildTextField(
|
|
_middleNameController, l10n.customerMiddleName,
|
|
readOnly: _isFetched('customermiddlename')),
|
|
_buildTextField(
|
|
_lastNameController, l10n.customerLastName,
|
|
readOnly: _isFetched('customerlastname')),
|
|
_buildTextField(_accountNoController, l10n.accountNumber,
|
|
keyboardType: TextInputType.number,
|
|
readOnly: _isFetched('accountno')),
|
|
_buildTextField(
|
|
_balanceController, l10n.availableBalance,
|
|
keyboardType: TextInputType.number,
|
|
readOnly: _isFetched('availablebalance')),
|
|
_buildTextField(_dobController, l10n.customerDobFormat,
|
|
mandatory: true, readOnly: _isFetched('customerdob')),
|
|
_buildTextField(_emailController, l10n.emailId,
|
|
keyboardType: TextInputType.emailAddress,
|
|
readOnly: _isFetched('emailid')),
|
|
_buildDropdownField(
|
|
_marriedController, l10n.marriedYesNo, _yesNoOptions,
|
|
mandatory: true),
|
|
_buildTextField(_nomineeNameController, l10n.nomineeName,
|
|
mandatory: true),
|
|
_buildDropdownField(_nomineeMinorController,
|
|
l10n.nomineeMinor, _yesNoOptions,
|
|
mandatory: true, onChanged: (val) {
|
|
setState(() {
|
|
_nomineeMinorController.text = val ?? 'N';
|
|
});
|
|
}),
|
|
if (_nomineeMinorController.text == 'Y') ...[
|
|
_buildTextField(_nomineeDobController, l10n.nomineeDob,
|
|
mandatory: true),
|
|
_buildTextField(
|
|
_guardianNameController, l10n.guardianName,
|
|
mandatory: true),
|
|
],
|
|
_buildDropdownField(_otherSchemeController,
|
|
l10n.isBeneficiaryOtherScheme, _yesNoOptions,
|
|
mandatory: true),
|
|
_buildDropdownField(_incomeTaxPayerController,
|
|
l10n.isIncomeTaxPayer, _yesNoOptions,
|
|
mandatory: true),
|
|
_buildTextField(_spouseNameController, l10n.nameOfSpouse,
|
|
mandatory: true),
|
|
_buildTextField(_ageOfJoiningController, l10n.ageOfJoining,
|
|
keyboardType: TextInputType.number, mandatory: true),
|
|
_buildDropdownField(_collectionChannelController,
|
|
l10n.collectionChannel, _collectionChannelOptions,
|
|
mandatory: true),
|
|
_buildDropdownField(
|
|
_fatcaController, l10n.fatcaApplicable, _yesNoOptions),
|
|
_buildTextField(
|
|
_birthCountryController, l10n.countryOfBirth),
|
|
_buildTextField(
|
|
_citizenshipCountryController, l10n.countryOfCitizenship),
|
|
_buildTextField(_taxResidenceCountryController,
|
|
l10n.countryOfTaxResidence),
|
|
_buildDropdownField(
|
|
_usPersonController, l10n.usPersonFlag, _yesNoOptions),
|
|
const Divider(height: 32),
|
|
_buildDropdownField(_pensionAmountController,
|
|
l10n.pensionAmount, _pensionOptions,
|
|
mandatory: true, onChanged: (val) {
|
|
setState(() {
|
|
_pensionAmountController.text = val ?? '1000';
|
|
});
|
|
}),
|
|
_buildDropdownField(_contributionTypeController,
|
|
l10n.periodicity, _getPeriodicityOptions(l10n),
|
|
mandatory: true, onChanged: (val) {
|
|
setState(() {
|
|
_contributionTypeController.text = val ?? 'C';
|
|
});
|
|
}),
|
|
_buildTextField(
|
|
_debitDateController, l10n.subsequentDebitDate,
|
|
mandatory: true),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
// Tile 2: Contribution Amount
|
|
Card(
|
|
elevation: 2,
|
|
color: Theme.of(context).colorScheme.secondaryContainer,
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
children: [
|
|
Text(
|
|
'${l10n.contributionAmount} (${_getPeriodicityOptions(l10n)[_contributionTypeController.text]})',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
color: Theme.of(context)
|
|
.colorScheme
|
|
.onSecondaryContainer)),
|
|
const SizedBox(height: 8),
|
|
Text('₹ $_calculatedContribution',
|
|
style: TextStyle(
|
|
fontSize: 32,
|
|
fontWeight: FontWeight.bold,
|
|
color: Theme.of(context)
|
|
.colorScheme
|
|
.onSecondaryContainer)),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
ElevatedButton(
|
|
onPressed: _handleRegister,
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
|
|
foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer,
|
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
|
elevation: 4,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
),
|
|
child: Text(
|
|
l10n.register,
|
|
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
const SizedBox(height: 32),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDropdownField(
|
|
TextEditingController controller, String label, Map<String, String> options,
|
|
{bool readOnly = false, bool mandatory = false, void Function(String?)? onChanged}) {
|
|
String? currentValue =
|
|
options.containsKey(controller.text) ? controller.text : null;
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.only(bottom: 16.0),
|
|
child: DropdownButtonFormField<String>(
|
|
value: currentValue,
|
|
onChanged: readOnly ? null : (newValue) {
|
|
if (onChanged != null) {
|
|
onChanged(newValue);
|
|
} else {
|
|
setState(() {
|
|
controller.text = newValue ?? '';
|
|
});
|
|
}
|
|
},
|
|
decoration: InputDecoration(
|
|
labelText: mandatory ? '$label *' : label,
|
|
border: const OutlineInputBorder(),
|
|
contentPadding:
|
|
const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
|
|
),
|
|
validator: (value) {
|
|
if (mandatory && (value == null || value.isEmpty)) {
|
|
return 'This field is required';
|
|
}
|
|
return null;
|
|
},
|
|
items: options.entries.map((entry) {
|
|
return DropdownMenuItem<String>(
|
|
value: entry.key,
|
|
child: Text(entry.value),
|
|
);
|
|
}).toList(),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildTextField(TextEditingController controller, String label,
|
|
{TextInputType keyboardType = TextInputType.text,
|
|
bool readOnly = false,
|
|
bool mandatory = false}) {
|
|
return Padding(
|
|
padding: const EdgeInsets.only(bottom: 16.0),
|
|
child: TextFormField(
|
|
controller: controller,
|
|
readOnly: readOnly,
|
|
decoration: InputDecoration(
|
|
labelText: mandatory ? '$label *' : label,
|
|
border: const OutlineInputBorder(),
|
|
contentPadding:
|
|
const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
|
|
),
|
|
keyboardType: keyboardType,
|
|
validator: (value) {
|
|
if (mandatory && (value == null || value.isEmpty)) {
|
|
return 'This field is required';
|
|
}
|
|
return null;
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|