Inventory Management | Customer Management | Invoice Management Done | Commodity Rate Sync Done
This commit is contained in:
@@ -42,9 +42,18 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
|
||||
void _showCreateWalletDialog() {
|
||||
final ctrl = TextEditingController();
|
||||
final amtCtrl = TextEditingController();
|
||||
final creditLimitCtrl = TextEditingController();
|
||||
final fixedAmountCtrl = TextEditingController();
|
||||
final cycleDateCtrl = TextEditingController();
|
||||
DateTime openingDate = DateTime.now();
|
||||
String selectedNature = 'CASH';
|
||||
String? selectedSubNature;
|
||||
String? selectedPaymentCycle;
|
||||
|
||||
final natures = ['CASH', 'SAVINGS', 'INVESTMENTS', 'LOAN', 'LENDING', 'PAYABLES', 'INCOME', 'EXPENSE', 'RECEIVABLES'];
|
||||
final subNatures = ['CREDIT_CARD', 'OD_LIMIT', 'LOAN_EMI', 'POLICY_PREMIUM', 'OTHER'];
|
||||
final paymentCycles = ['DAILY', 'WEEKLY', 'MONTHLY', 'QUARTERLY', 'YEARLY'];
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => StatefulBuilder(
|
||||
@@ -117,14 +126,121 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
|
||||
),
|
||||
items: natures.map((n) => DropdownMenuItem(value: n, child: Text(n))).toList(),
|
||||
onChanged: (val) {
|
||||
if (val != null) setStateDialog(() => selectedNature = val);
|
||||
if (val != null) setStateDialog(() {
|
||||
selectedNature = val;
|
||||
if (val != 'PAYABLES') {
|
||||
selectedSubNature = null;
|
||||
selectedPaymentCycle = null;
|
||||
creditLimitCtrl.clear();
|
||||
fixedAmountCtrl.clear();
|
||||
cycleDateCtrl.clear();
|
||||
} else {
|
||||
selectedSubNature = 'CREDIT_CARD';
|
||||
selectedPaymentCycle = 'MONTHLY';
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
if (selectedNature == 'PAYABLES') ...[
|
||||
DropdownButtonFormField<String>(
|
||||
value: selectedSubNature,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500, color: Colors.black87),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Sub-Nature',
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: const BorderSide(color: Color(0xFF6C63FF), width: 2)),
|
||||
),
|
||||
items: subNatures.map((n) => DropdownMenuItem(value: n, child: Text(n.replaceAll('_', ' ')))).toList(),
|
||||
onChanged: (val) {
|
||||
if (val != null) setStateDialog(() => selectedSubNature = val);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
if (selectedSubNature == 'CREDIT_CARD' || selectedSubNature == 'OD_LIMIT') ...[
|
||||
TextField(
|
||||
controller: creditLimitCtrl,
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true, signed: false),
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Credit Limit (Optional)',
|
||||
prefixText: 'Rs. ',
|
||||
prefixStyle: const TextStyle(color: Colors.black87, fontWeight: FontWeight.w500, fontSize: 16),
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: const BorderSide(color: Color(0xFF6C63FF), width: 2)),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
||||
if (selectedSubNature == 'LOAN_EMI' || selectedSubNature == 'POLICY_PREMIUM') ...[
|
||||
TextField(
|
||||
controller: fixedAmountCtrl,
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true, signed: false),
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Fixed Amount Due (Optional)',
|
||||
prefixText: 'Rs. ',
|
||||
prefixStyle: const TextStyle(color: Colors.black87, fontWeight: FontWeight.w500, fontSize: 16),
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: const BorderSide(color: Color(0xFF6C63FF), width: 2)),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: selectedPaymentCycle,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500, color: Colors.black87),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Cycle',
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: const BorderSide(color: Color(0xFF6C63FF), width: 2)),
|
||||
),
|
||||
items: paymentCycles.map((n) => DropdownMenuItem(value: n, child: Text(n))).toList(),
|
||||
onChanged: (val) {
|
||||
if (val != null) setStateDialog(() => selectedPaymentCycle = val);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: TextField(
|
||||
controller: cycleDateCtrl,
|
||||
keyboardType: TextInputType.number,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Date (1-31)',
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: const BorderSide(color: Color(0xFF6C63FF), width: 2)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
||||
TextField(
|
||||
controller: amtCtrl,
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true, signed: false),
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true, signed: true),
|
||||
textInputAction: TextInputAction.done,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
decoration: InputDecoration(
|
||||
@@ -189,20 +305,30 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
|
||||
onPressed: () async {
|
||||
if (ctrl.text.isNotEmpty) {
|
||||
final double amt = double.tryParse(amtCtrl.text) ?? 0.0;
|
||||
final double? cl = double.tryParse(creditLimitCtrl.text);
|
||||
final double? fa = double.tryParse(fixedAmountCtrl.text);
|
||||
final int? cd = int.tryParse(cycleDateCtrl.text);
|
||||
|
||||
final newWallet = await ref.read(walletProvider.notifier).createWallet(
|
||||
name: ctrl.text,
|
||||
nature: selectedNature,
|
||||
initialBalance: 0.0,
|
||||
subNature: selectedNature == 'PAYABLES' ? selectedSubNature : null,
|
||||
creditLimit: cl,
|
||||
fixedAmount: fa,
|
||||
paymentCycle: selectedNature == 'PAYABLES' ? selectedPaymentCycle : null,
|
||||
cycleDate: cd,
|
||||
);
|
||||
|
||||
if (amt > 0) {
|
||||
if (amt != 0) {
|
||||
final tx = Transaction(
|
||||
id: 0,
|
||||
type: 'INCOME',
|
||||
amount: amt,
|
||||
type: amt > 0 ? 'INCOME' : 'EXPENSE',
|
||||
amount: amt.abs(),
|
||||
date: openingDate,
|
||||
description: 'Opening Balance',
|
||||
toWalletId: newWallet.id,
|
||||
fromWalletId: amt < 0 ? newWallet.id : null,
|
||||
toWalletId: amt > 0 ? newWallet.id : null,
|
||||
);
|
||||
await ref.read(transactionProvider.notifier).addTransaction(tx);
|
||||
}
|
||||
@@ -335,7 +461,6 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
|
||||
final walletsState = ref.watch(walletProvider);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: SafeArea(
|
||||
bottom: false,
|
||||
child: Column(
|
||||
@@ -472,7 +597,16 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
|
||||
onPressed: () {
|
||||
final editCtrl = TextEditingController(text: w.name);
|
||||
String editNature = w.nature ?? 'CASH';
|
||||
String? editSubNature = w.subNature;
|
||||
final editCreditLimitCtrl = TextEditingController(text: w.creditLimit?.toString() ?? '');
|
||||
final editFixedAmountCtrl = TextEditingController(text: w.fixedAmount?.toString() ?? '');
|
||||
final editCycleDateCtrl = TextEditingController(text: w.cycleDate?.toString() ?? '');
|
||||
String? editPaymentCycle = w.paymentCycle;
|
||||
|
||||
final natures = ['CASH', 'SAVINGS', 'EXPENSE', 'INVESTMENTS', 'LOAN', 'LENDING', 'PAYABLES', 'RECEIVABLES', 'INCOME'];
|
||||
final subNatures = ['CREDIT_CARD', 'OD_LIMIT', 'LOAN_EMI', 'POLICY_PREMIUM', 'OTHER'];
|
||||
final paymentCycles = ['DAILY', 'WEEKLY', 'MONTHLY', 'QUARTERLY', 'YEARLY'];
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => StatefulBuilder(
|
||||
@@ -480,9 +614,11 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)),
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(28)),
|
||||
child: GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(28)),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -510,10 +646,107 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
|
||||
),
|
||||
items: natures.map((n) => DropdownMenuItem(value: n, child: Text(n))).toList(),
|
||||
onChanged: (val) {
|
||||
if (val != null) setStateDialog(() => editNature = val);
|
||||
if (val != null) setStateDialog(() {
|
||||
editNature = val;
|
||||
if (val != 'PAYABLES') {
|
||||
editSubNature = null;
|
||||
editPaymentCycle = null;
|
||||
editCreditLimitCtrl.clear();
|
||||
editFixedAmountCtrl.clear();
|
||||
editCycleDateCtrl.clear();
|
||||
} else if (editSubNature == null) {
|
||||
editSubNature = 'CREDIT_CARD';
|
||||
editPaymentCycle = 'MONTHLY';
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
if (editNature == 'PAYABLES') ...[
|
||||
DropdownButtonFormField<String>(
|
||||
value: editSubNature,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Sub-Nature',
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
),
|
||||
items: subNatures.map((n) => DropdownMenuItem(value: n, child: Text(n.replaceAll('_', ' ')))).toList(),
|
||||
onChanged: (val) {
|
||||
if (val != null) setStateDialog(() => editSubNature = val);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
if (editSubNature == 'CREDIT_CARD' || editSubNature == 'OD_LIMIT') ...[
|
||||
TextField(
|
||||
controller: editCreditLimitCtrl,
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true, signed: false),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Credit Limit (Optional)',
|
||||
prefixText: 'Rs. ',
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
||||
if (editSubNature == 'LOAN_EMI' || editSubNature == 'POLICY_PREMIUM') ...[
|
||||
TextField(
|
||||
controller: editFixedAmountCtrl,
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true, signed: false),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Fixed Amount Due (Optional)',
|
||||
prefixText: 'Rs. ',
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: editPaymentCycle,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Cycle',
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
),
|
||||
items: paymentCycles.map((n) => DropdownMenuItem(value: n, child: Text(n))).toList(),
|
||||
onChanged: (val) {
|
||||
if (val != null) setStateDialog(() => editPaymentCycle = val);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: TextField(
|
||||
controller: editCycleDateCtrl,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Date (1-31)',
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@@ -525,11 +758,20 @@ 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 int? cd = int.tryParse(editCycleDateCtrl.text);
|
||||
|
||||
try {
|
||||
await ref.read(walletProvider.notifier).editWallet(
|
||||
w.id,
|
||||
name: editCtrl.text.trim(),
|
||||
nature: editNature,
|
||||
subNature: editNature == 'PAYABLES' ? editSubNature : null,
|
||||
creditLimit: cl,
|
||||
fixedAmount: fa,
|
||||
paymentCycle: editNature == 'PAYABLES' ? editPaymentCycle : null,
|
||||
cycleDate: cd,
|
||||
);
|
||||
if (context.mounted) {
|
||||
Navigator.pop(ctx);
|
||||
@@ -549,6 +791,7 @@ class _AccountsScreenState extends ConsumerState<AccountsScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user