155 lines
4.8 KiB
Dart
155 lines
4.8 KiB
Dart
/// Dialog pour enregistrer un paiement sur une adhésion
|
|
library paiement_adhesion_dialog;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import '../../../../shared/constants/payment_method_assets.dart';
|
|
import '../../bloc/adhesions_bloc.dart';
|
|
|
|
class PaiementAdhesionDialog extends StatefulWidget {
|
|
final String adhesionId;
|
|
final double montantRestant;
|
|
final VoidCallback onPaid;
|
|
|
|
const PaiementAdhesionDialog({
|
|
super.key,
|
|
required this.adhesionId,
|
|
required this.montantRestant,
|
|
required this.onPaid,
|
|
});
|
|
|
|
@override
|
|
State<PaiementAdhesionDialog> createState() => _PaiementAdhesionDialogState();
|
|
}
|
|
|
|
class _PaiementAdhesionDialogState extends State<PaiementAdhesionDialog> {
|
|
final _montantController = TextEditingController();
|
|
final _refController = TextEditingController();
|
|
String? _methode;
|
|
bool _loading = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_montantController.text = widget.montantRestant.toStringAsFixed(0);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_montantController.dispose();
|
|
_refController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
List<DropdownMenuItem<String>> _buildPaymentMethodItems() {
|
|
const codes = ['ESPECES', 'VIREMENT', 'WAVE_MONEY', 'ORANGE_MONEY', 'CHEQUE'];
|
|
const labels = {'ESPECES': 'Espèces', 'VIREMENT': 'Virement', 'WAVE_MONEY': 'Wave Money', 'ORANGE_MONEY': 'Orange Money', 'CHEQUE': 'Chèque'};
|
|
return codes.map((code) {
|
|
final label = labels[code] ?? code;
|
|
return DropdownMenuItem<String>(
|
|
value: code,
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
PaymentMethodIcon(paymentMethodCode: code, width: 24, height: 24),
|
|
const SizedBox(width: 12),
|
|
Text(label),
|
|
],
|
|
),
|
|
);
|
|
}).toList();
|
|
}
|
|
|
|
void _submit() {
|
|
final montant = double.tryParse(_montantController.text.replaceAll(',', '.'));
|
|
if (montant == null || montant <= 0) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Montant invalide')),
|
|
);
|
|
return;
|
|
}
|
|
if (montant > widget.montantRestant) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Le montant ne peut pas dépasser le restant dû')),
|
|
);
|
|
return;
|
|
}
|
|
setState(() => _loading = true);
|
|
context.read<AdhesionsBloc>().add(
|
|
EnregistrerPaiementAdhesion(
|
|
widget.adhesionId,
|
|
montantPaye: montant,
|
|
methodePaiement: _methode,
|
|
referencePaiement: _refController.text.trim().isEmpty
|
|
? null
|
|
: _refController.text.trim(),
|
|
),
|
|
);
|
|
widget.onPaid();
|
|
if (mounted) {
|
|
setState(() => _loading = false);
|
|
Navigator.of(context).pop();
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AlertDialog(
|
|
title: const Text('Enregistrer un paiement'),
|
|
content: SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text('Restant dû : ${widget.montantRestant.toStringAsFixed(0)} FCFA'),
|
|
const SizedBox(height: 16),
|
|
TextField(
|
|
controller: _montantController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Montant payé (FCFA)',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
|
enabled: !_loading,
|
|
),
|
|
const SizedBox(height: 12),
|
|
DropdownButtonFormField<String>(
|
|
value: _methode,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Méthode de paiement',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
items: _buildPaymentMethodItems(),
|
|
onChanged: _loading ? null : (v) => setState(() => _methode = v),
|
|
),
|
|
const SizedBox(height: 12),
|
|
TextField(
|
|
controller: _refController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Référence (optionnel)',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
enabled: !_loading,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: _loading ? null : () => Navigator.of(context).pop(),
|
|
child: const Text('Annuler'),
|
|
),
|
|
FilledButton(
|
|
onPressed: _loading ? null : _submit,
|
|
child: _loading
|
|
? const SizedBox(
|
|
width: 20,
|
|
height: 20,
|
|
child: CircularProgressIndicator(strokeWidth: 2),
|
|
)
|
|
: const Text('Enregistrer'),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|