handelled the update expense

This commit is contained in:
Vaibhav Surve 2025-08-06 11:46:12 +05:30
parent aa76ec60cb
commit 63e5caae24
2 changed files with 171 additions and 149 deletions

View File

@ -170,8 +170,14 @@ class AddExpenseController extends GetxController {
// --- Existing Attachments ---
existingAttachments.clear();
if (data['attachments'] != null && data['attachments'] is List) {
existingAttachments
.addAll(List<Map<String, dynamic>>.from(data['attachments']));
existingAttachments.addAll(
List<Map<String, dynamic>>.from(data['attachments']).map((e) {
return {
...e,
'isActive': true, // default
};
}),
);
}
_logPrefilledData();
@ -369,15 +375,20 @@ class AddExpenseController extends GetxController {
final projectId = projectsMap[selectedProject.value]!;
final selectedDate =
selectedTransactionDate.value?.toUtc() ?? DateTime.now().toUtc();
final existingAttachmentPayloads = existingAttachments
.map((e) => {
final existingAttachmentPayloads = existingAttachments.map((e) {
final isActive = e['isActive'] ?? true;
return {
"documentId": e['documentId'],
"fileName": e['fileName'],
"contentType": e['contentType'],
"fileSize": 0, // optional or populate if known
"fileSize": 0,
"description": "",
"url": e['url'], // custom field if your backend accepts
})
.toList();
"url": e['url'],
"isActive": isActive,
"base64Data": isActive ? e['base64Data'] : null,
};
}).toList();
final newAttachmentPayloads =
await Future.wait(attachments.map((file) async {

View File

@ -44,7 +44,6 @@ class _AddExpenseBottomSheetState extends State<_AddExpenseBottomSheet> {
await showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
@ -55,8 +54,7 @@ class _AddExpenseBottomSheetState extends State<_AddExpenseBottomSheet> {
// Optional cleanup
controller.employeeSearchController.clear();
controller.employeeSearchResults.clear();
}
}
Future<void> _showOptionList<T>(
List<T> options,
@ -277,8 +275,13 @@ class _AddExpenseBottomSheetState extends State<_AddExpenseBottomSheet> {
attachments: controller.attachments,
existingAttachments: controller.existingAttachments,
onRemoveNew: controller.removeAttachment,
onRemoveExisting: (item) =>
controller.existingAttachments.remove(item),
onRemoveExisting: (item) {
final index = controller.existingAttachments.indexOf(item);
if (index != -1) {
controller.existingAttachments[index]['isActive'] = false;
controller.existingAttachments.refresh();
}
},
onAdd: controller.pickAttachments,
),
MySpacing.height(16),
@ -458,7 +461,7 @@ class _TileContainer extends StatelessWidget {
class _AttachmentsSection extends StatelessWidget {
final RxList<File> attachments;
final List<Map<String, dynamic>> existingAttachments;
final RxList<Map<String, dynamic>> existingAttachments;
final ValueChanged<File> onRemoveNew;
final ValueChanged<Map<String, dynamic>>? onRemoveExisting;
final VoidCallback onAdd;
@ -473,10 +476,14 @@ class _AttachmentsSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Obx(() => Column(
return Obx(() {
final activeExistingAttachments =
existingAttachments.where((doc) => doc['isActive'] != false).toList();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (existingAttachments.isNotEmpty) ...[
if (activeExistingAttachments.isNotEmpty) ...[
Text(
"Existing Attachments",
style: const TextStyle(fontWeight: FontWeight.w600),
@ -485,7 +492,7 @@ class _AttachmentsSection extends StatelessWidget {
Wrap(
spacing: 8,
runSpacing: 8,
children: existingAttachments.map((doc) {
children: activeExistingAttachments.map((doc) {
final isImage =
doc['contentType']?.toString().startsWith('image/') ??
false;
@ -498,7 +505,7 @@ class _AttachmentsSection extends StatelessWidget {
GestureDetector(
onTap: () async {
if (isImage) {
final imageDocs = existingAttachments
final imageDocs = activeExistingAttachments
.where((d) => (d['contentType']
?.toString()
.startsWith('image/') ??
@ -516,8 +523,10 @@ class _AttachmentsSection extends StatelessWidget {
);
} else {
if (url != null && await canLaunchUrlString(url)) {
await launchUrlString(url,
mode: LaunchMode.externalApplication);
await launchUrlString(
url,
mode: LaunchMode.externalApplication,
);
} else {
showAppSnackbar(
title: 'Error',
@ -545,8 +554,7 @@ class _AttachmentsSection extends StatelessWidget {
),
const SizedBox(width: 7),
ConstrainedBox(
constraints:
const BoxConstraints(maxWidth: 120),
constraints: const BoxConstraints(maxWidth: 120),
child: Text(
fileName,
overflow: TextOverflow.ellipsis,
@ -564,7 +572,9 @@ class _AttachmentsSection extends StatelessWidget {
child: IconButton(
icon: const Icon(Icons.close,
color: Colors.red, size: 18),
onPressed: () => onRemoveExisting!(doc),
onPressed: () {
onRemoveExisting?.call(doc);
},
),
),
],
@ -574,7 +584,7 @@ class _AttachmentsSection extends StatelessWidget {
const SizedBox(height: 16),
],
// New attachments section - shows preview tiles
// New attachments section
Wrap(
spacing: 8,
runSpacing: 8,
@ -599,7 +609,8 @@ class _AttachmentsSection extends StatelessWidget {
],
),
],
));
);
});
}
}