Fixed UI issue

This commit is contained in:
2026-08-24 18:38:46 +05:30
parent fc0faafa18
commit 71b2389221
58 changed files with 3521 additions and 53 deletions

View File

@@ -312,7 +312,8 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
final newWallet = await ref.read(walletProvider.notifier).createWallet(
name: ctrl.text,
nature: selectedNature,
initialBalance: 0.0,
initialBalance: amt,
initialBalanceDate: openingDate,
subNature: selectedNature == 'PAYABLES' ? selectedSubNature : null,
creditLimit: cl,
fixedAmount: fa,
@@ -320,19 +321,6 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
cycleDate: cd,
);
if (amt != 0) {
final tx = Transaction(
id: 0,
type: amt > 0 ? 'INCOME' : 'EXPENSE',
amount: amt.abs(),
date: openingDate,
description: 'Opening Balance',
fromWalletId: amt < 0 ? newWallet.id : null,
toWalletId: amt > 0 ? newWallet.id : null,
);
await ref.read(transactionProvider.notifier).addTransaction(tx);
}
if (context.mounted) Navigator.pop(ctx);
}
},
@@ -522,6 +510,7 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
error: (e, st) => Center(child: Text('Error: $e')),
data: (allWallets) {
final wallets = allWallets.where((w) {
if (w.nature == 'EQUITY') return false;
final matchSearch = _searchQuery.isEmpty ||
w.name.toLowerCase().contains(_searchQuery.toLowerCase());
final matchNature = _filterNature == null || w.nature == _filterNature;
@@ -601,6 +590,14 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
final editCreditLimitCtrl = TextEditingController(text: w.creditLimit?.toString() ?? '');
final editFixedAmountCtrl = TextEditingController(text: w.fixedAmount?.toString() ?? '');
final editCycleDateCtrl = TextEditingController(text: w.cycleDate?.toString() ?? '');
final allTxs = ref.read(transactionProvider).value ?? [];
final walletTxs = allTxs.where((t) => t.fromWalletId == w.id || t.toWalletId == w.id).toList();
final obTxs = walletTxs.where((t) => t.description == 'Opening Balance');
final hasRealTx = walletTxs.any((t) => t.description != 'Opening Balance');
final editInitialBalanceCtrl = TextEditingController(text: w.balance != 0 ? w.balance.toString() : '');
DateTime editOpeningDate = obTxs.isNotEmpty ? obTxs.first.date : DateTime.now();
String? editPaymentCycle = w.paymentCycle;
final natures = ['CASH', 'SAVINGS', 'EXPENSE', 'INVESTMENTS', 'LOAN', 'LENDING', 'PAYABLES', 'RECEIVABLES', 'INCOME'];
@@ -663,6 +660,58 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
),
const SizedBox(height: 16),
Tooltip(
message: hasRealTx ? 'Opening balance cannot be edited after transactions are recorded' : '',
child: TextField(
controller: editInitialBalanceCtrl,
keyboardType: const TextInputType.numberWithOptions(decimal: true, signed: true),
enabled: !hasRealTx,
decoration: InputDecoration(
hintText: 'Opening Balance (Optional)',
prefixText: 'Rs. ',
filled: true,
fillColor: hasRealTx ? Colors.grey.shade200 : Colors.grey.shade100,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
),
),
),
const SizedBox(height: 16),
Tooltip(
message: hasRealTx ? 'Opening balance date cannot be edited after transactions are recorded' : '',
child: InkWell(
onTap: hasRealTx ? null : () async {
final picked = await showDatePicker(
context: context,
initialDate: editOpeningDate,
firstDate: DateTime.now().subtract(const Duration(days: 365 * 10)),
lastDate: DateTime.now(),
);
if (picked != null) {
setStateDialog(() => editOpeningDate = picked);
}
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
decoration: BoxDecoration(
color: hasRealTx ? Colors.grey.shade200 : Colors.grey.shade100,
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: [
const Icon(LucideIcons.calendar, color: Colors.black54, size: 20),
const SizedBox(width: 12),
Text(
'Opening Date: ${editOpeningDate.day.toString().padLeft(2, '0')}/${editOpeningDate.month.toString().padLeft(2, '0')}/${editOpeningDate.year}',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 15, color: hasRealTx ? Colors.black38 : Colors.black87),
),
],
),
),
),
),
const SizedBox(height: 16),
if (editNature == 'PAYABLES') ...[
DropdownButtonFormField<String>(
value: editSubNature,
@@ -758,15 +807,26 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
ElevatedButton(
onPressed: () async {
if (editCtrl.text.isNotEmpty) {
final double? cl = double.tryParse(editCreditLimitCtrl.text);
final double? fa = double.tryParse(editFixedAmountCtrl.text);
final double? cl = double.tryParse(editCreditLimitCtrl.text.replaceAll(RegExp(r'[^0-9.]'), ''));
final double? fa = double.tryParse(editFixedAmountCtrl.text.replaceAll(RegExp(r'[^0-9.]'), ''));
final int? cd = int.tryParse(editCycleDateCtrl.text);
// Make parsing super robust by stripping everything except digits and dot
final String rawText = editInitialBalanceCtrl.text.replaceAll(RegExp(r'[^0-9.]'), '');
final double? ib = (!hasRealTx && rawText.isNotEmpty) ? double.tryParse(rawText) : null;
print("DEBUG KIFI: editWallet called.");
print("DEBUG KIFI: hasRealTx = $hasRealTx");
print("DEBUG KIFI: rawText = '$rawText'");
print("DEBUG KIFI: parsed ib = $ib");
try {
await ref.read(walletProvider.notifier).editWallet(
w.id,
name: editCtrl.text.trim(),
nature: editNature,
initialBalance: ib,
initialBalanceDate: ib != null ? editOpeningDate : null,
subNature: editNature == 'PAYABLES' ? editSubNature : null,
creditLimit: cl,
fixedAmount: fa,