Fixed upto purchases and rate sync process
This commit is contained in:
@@ -570,117 +570,135 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen> {
|
||||
final amount = double.tryParse(amountText);
|
||||
if (amount == null) return;
|
||||
|
||||
if (fromWallet != null && fromWallet!.balance < amount) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Insufficient balance in From Account')));
|
||||
return;
|
||||
final isFromPayableOrLiability = fromWallet != null && (fromWallet!.nature == 'PAYABLES' || fromWallet!.nature == 'LOAN');
|
||||
if (fromWallet != null && !isFromPayableOrLiability) {
|
||||
double effectiveBalance = fromWallet!.balance;
|
||||
if (widget.transaction != null && widget.transaction!.fromWalletId == fromWallet!.id) {
|
||||
effectiveBalance += widget.transaction!.amount;
|
||||
}
|
||||
if (effectiveBalance < amount) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Insufficient balance in From Account')));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setState(() => isSaving = true);
|
||||
|
||||
// Determine internal type based on natures
|
||||
String type = 'TRANSFER';
|
||||
if (fromWallet == null) {
|
||||
type = 'INCOME';
|
||||
} else if (toWallet == null) { // Though toWallet is mandatory, just in case
|
||||
type = 'EXPENSE';
|
||||
} else if (fromWallet?.nature == 'INCOME') {
|
||||
type = 'INCOME';
|
||||
} else if (toWallet?.nature == 'PAYABLES' || toWallet?.nature == 'EXPENSE') {
|
||||
type = 'EXPENSE';
|
||||
} else if (toWallet?.nature == 'INVESTMENTS') {
|
||||
type = 'INVESTMENT';
|
||||
}
|
||||
|
||||
if (isRecurring && widget.transaction == null) {
|
||||
DateTime nextDate = selectedDate;
|
||||
if (recurringFrequency == 'DAILY') {
|
||||
nextDate = nextDate.add(const Duration(days: 1));
|
||||
} else if (recurringFrequency == 'WEEKLY') {
|
||||
nextDate = nextDate.add(const Duration(days: 7));
|
||||
} else if (recurringFrequency == 'MONTHLY') {
|
||||
nextDate = DateTime(nextDate.year, nextDate.month + 1, nextDate.day);
|
||||
try {
|
||||
// Determine internal type based on natures
|
||||
String type = 'TRANSFER';
|
||||
if (fromWallet == null) {
|
||||
type = 'INCOME';
|
||||
} else if (toWallet == null) { // Though toWallet is mandatory, just in case
|
||||
type = 'EXPENSE';
|
||||
} else if (fromWallet?.nature == 'INCOME') {
|
||||
type = 'INCOME';
|
||||
} else if (toWallet?.nature == 'PAYABLES' || toWallet?.nature == 'EXPENSE') {
|
||||
type = 'EXPENSE';
|
||||
} else if (toWallet?.nature == 'INVESTMENTS') {
|
||||
type = 'INVESTMENT';
|
||||
}
|
||||
|
||||
final rt = RecurringTransaction(
|
||||
id: 0,
|
||||
type: type,
|
||||
amount: amount,
|
||||
categoryId: selectedCategory?.id,
|
||||
fromWalletId: fromWallet?.id,
|
||||
toWalletId: toWallet?.id,
|
||||
frequency: recurringFrequency,
|
||||
description: descriptionController.text.trim(),
|
||||
nextExecutionDate: nextDate,
|
||||
status: 'ACTIVE',
|
||||
);
|
||||
await ref.read(recurringTransactionProvider.notifier).addRecurringTransaction(rt);
|
||||
|
||||
final tx = Transaction(
|
||||
id: 0,
|
||||
type: type,
|
||||
amount: amount,
|
||||
date: selectedDate,
|
||||
description: descriptionController.text.trim(),
|
||||
categoryId: selectedCategory?.id,
|
||||
fromWalletId: fromWallet?.id,
|
||||
toWalletId: toWallet?.id,
|
||||
dueDate: dueDate,
|
||||
alertSchedule: alertSchedule == 'NONE' ? null : alertSchedule,
|
||||
alertTime: alertSchedule == 'NONE' ? null : '${alertTime.hour.toString().padLeft(2, '0')}:${alertTime.minute.toString().padLeft(2, '0')}:00',
|
||||
items: lineItems.isNotEmpty ? lineItems : null,
|
||||
);
|
||||
await ref.read(transactionProvider.notifier).addTransaction(tx, base64Attachments: base64Attachments);
|
||||
} else {
|
||||
final tx = Transaction(
|
||||
id: widget.transaction?.id ?? 0,
|
||||
type: type,
|
||||
amount: amount,
|
||||
date: selectedDate,
|
||||
description: descriptionController.text.trim(),
|
||||
categoryId: selectedCategory?.id,
|
||||
fromWalletId: fromWallet?.id,
|
||||
toWalletId: toWallet?.id,
|
||||
dueDate: dueDate,
|
||||
alertSchedule: alertSchedule == 'NONE' ? null : alertSchedule,
|
||||
alertTime: alertSchedule == 'NONE' ? null : '${alertTime.hour.toString().padLeft(2, '0')}:${alertTime.minute.toString().padLeft(2, '0')}:00',
|
||||
items: lineItems.isNotEmpty ? lineItems : null,
|
||||
);
|
||||
if (isRecurring && widget.transaction == null) {
|
||||
DateTime nextDate = selectedDate;
|
||||
if (recurringFrequency == 'DAILY') {
|
||||
nextDate = nextDate.add(const Duration(days: 1));
|
||||
} else if (recurringFrequency == 'WEEKLY') {
|
||||
nextDate = nextDate.add(const Duration(days: 7));
|
||||
} else if (recurringFrequency == 'MONTHLY') {
|
||||
nextDate = DateTime(nextDate.year, nextDate.month + 1, nextDate.day);
|
||||
}
|
||||
|
||||
if (widget.transaction == null) {
|
||||
final rt = RecurringTransaction(
|
||||
id: 0,
|
||||
type: type,
|
||||
amount: amount,
|
||||
categoryId: selectedCategory?.id,
|
||||
fromWalletId: fromWallet?.id,
|
||||
toWalletId: toWallet?.id,
|
||||
frequency: recurringFrequency,
|
||||
description: descriptionController.text.trim(),
|
||||
nextExecutionDate: nextDate,
|
||||
status: 'ACTIVE',
|
||||
);
|
||||
await ref.read(recurringTransactionProvider.notifier).addRecurringTransaction(rt);
|
||||
|
||||
final tx = Transaction(
|
||||
id: 0,
|
||||
type: type,
|
||||
amount: amount,
|
||||
date: selectedDate,
|
||||
description: descriptionController.text.trim(),
|
||||
categoryId: selectedCategory?.id,
|
||||
fromWalletId: fromWallet?.id,
|
||||
toWalletId: toWallet?.id,
|
||||
dueDate: dueDate,
|
||||
alertSchedule: alertSchedule == 'NONE' ? null : alertSchedule,
|
||||
alertTime: alertSchedule == 'NONE' ? null : '${alertTime.hour.toString().padLeft(2, '0')}:${alertTime.minute.toString().padLeft(2, '0')}:00',
|
||||
items: lineItems.isNotEmpty ? lineItems : null,
|
||||
);
|
||||
await ref.read(transactionProvider.notifier).addTransaction(tx, base64Attachments: base64Attachments);
|
||||
} else {
|
||||
await ref.read(transactionProvider.notifier).updateTransaction(
|
||||
tx,
|
||||
base64Attachments: base64Attachments,
|
||||
deletedAttachmentIds: deletedAttachmentIds,
|
||||
final tx = Transaction(
|
||||
id: widget.transaction?.id ?? 0,
|
||||
type: type,
|
||||
amount: amount,
|
||||
date: selectedDate,
|
||||
description: descriptionController.text.trim(),
|
||||
categoryId: selectedCategory?.id,
|
||||
fromWalletId: fromWallet?.id,
|
||||
toWalletId: toWallet?.id,
|
||||
dueDate: dueDate,
|
||||
alertSchedule: alertSchedule == 'NONE' ? null : alertSchedule,
|
||||
alertTime: alertSchedule == 'NONE' ? null : '${alertTime.hour.toString().padLeft(2, '0')}:${alertTime.minute.toString().padLeft(2, '0')}:00',
|
||||
items: lineItems.isNotEmpty ? lineItems : null,
|
||||
);
|
||||
}
|
||||
|
||||
if (alertSchedule != 'NONE' && dueDate != null) {
|
||||
DateTime alertDate = dueDate!;
|
||||
if (alertSchedule == '1_DAY_BEFORE') {
|
||||
alertDate = dueDate!.subtract(const Duration(days: 1));
|
||||
} else if (alertSchedule == '2_DAYS_BEFORE') {
|
||||
alertDate = dueDate!.subtract(const Duration(days: 2));
|
||||
} else if (alertSchedule == '1_WEEK_BEFORE') {
|
||||
alertDate = dueDate!.subtract(const Duration(days: 7));
|
||||
}
|
||||
|
||||
final notifyDate = DateTime(alertDate.year, alertDate.month, alertDate.day, alertTime.hour, alertTime.minute);
|
||||
if (notifyDate.isAfter(DateTime.now())) {
|
||||
NotificationService().scheduleNotification(
|
||||
id: DateTime.now().millisecondsSinceEpoch.remainder(100000),
|
||||
title: 'Payment Due!',
|
||||
body: 'Rs. ${amount.toStringAsFixed(0)} is due for ${toWallet?.name}',
|
||||
scheduledDate: notifyDate,
|
||||
|
||||
if (widget.transaction == null) {
|
||||
await ref.read(transactionProvider.notifier).addTransaction(tx, base64Attachments: base64Attachments);
|
||||
} else {
|
||||
await ref.read(transactionProvider.notifier).updateTransaction(
|
||||
tx,
|
||||
base64Attachments: base64Attachments,
|
||||
deletedAttachmentIds: deletedAttachmentIds,
|
||||
);
|
||||
}
|
||||
|
||||
if (alertSchedule != 'NONE' && dueDate != null) {
|
||||
DateTime alertDate = dueDate!;
|
||||
if (alertSchedule == '1_DAY_BEFORE') {
|
||||
alertDate = dueDate!.subtract(const Duration(days: 1));
|
||||
} else if (alertSchedule == '2_DAYS_BEFORE') {
|
||||
alertDate = dueDate!.subtract(const Duration(days: 2));
|
||||
} else if (alertSchedule == '1_WEEK_BEFORE') {
|
||||
alertDate = dueDate!.subtract(const Duration(days: 7));
|
||||
}
|
||||
|
||||
final notifyDate = DateTime(alertDate.year, alertDate.month, alertDate.day, alertTime.hour, alertTime.minute);
|
||||
if (notifyDate.isAfter(DateTime.now())) {
|
||||
NotificationService().scheduleNotification(
|
||||
id: DateTime.now().millisecondsSinceEpoch.remainder(100000),
|
||||
title: 'Payment Due!',
|
||||
body: 'Rs. ${amount.toStringAsFixed(0)} is due for ${toWallet?.name}',
|
||||
scheduledDate: notifyDate,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
SnackBarService.showSuccess(context, 'Transaction saved successfully');
|
||||
Navigator.pop(context);
|
||||
if (mounted) {
|
||||
SnackBarService.showSuccess(context, 'Transaction saved successfully');
|
||||
Navigator.pop(context);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Error saving transaction: $e');
|
||||
if (mounted) {
|
||||
SnackBarService.showError(context, 'Failed to save transaction: ${e.toString()}');
|
||||
}
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() => isSaving = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user