completed migrating data scope from user to workspace
This commit is contained in:
@@ -90,10 +90,12 @@ class _BatchCreateScreenState extends State<BatchCreateScreen> {
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final userId = prefs.getString('userId') ?? '';
|
||||
final workspaceId = prefs.getString('workspaceId') ?? '';
|
||||
|
||||
final req = CreateBatchRequest(
|
||||
recipientGroupId: widget.group.id ?? '',
|
||||
userId: userId,
|
||||
workspaceId: workspaceId,
|
||||
currency: _currency,
|
||||
description: _descriptionController.text.trim(),
|
||||
amount: amount,
|
||||
@@ -115,7 +117,7 @@ class _BatchCreateScreenState extends State<BatchCreateScreen> {
|
||||
batch.id!,
|
||||
selectedProvider,
|
||||
selectedProduct,
|
||||
userId,
|
||||
workspaceId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -130,7 +132,7 @@ class _BatchCreateScreenState extends State<BatchCreateScreen> {
|
||||
String batchId,
|
||||
BillProvider provider,
|
||||
BillProduct? product,
|
||||
String userId,
|
||||
String workspaceId,
|
||||
) async {
|
||||
// Fetch the batch items so we can update them
|
||||
final itemsResult = await batchController.listBatchItems(batchId);
|
||||
@@ -154,7 +156,7 @@ class _BatchCreateScreenState extends State<BatchCreateScreen> {
|
||||
|
||||
final updateList = GroupBatchItemUpdateList(
|
||||
items: updateItems,
|
||||
userId: userId,
|
||||
workspaceId: workspaceId,
|
||||
);
|
||||
|
||||
await batchController.updateBatchItems(batchId, updateList);
|
||||
|
||||
@@ -33,12 +33,13 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
ConfirmController? _confirmController;
|
||||
GroupBatchUpdateRequest? _cachedUpdateReq;
|
||||
bool _showPollButton = false;
|
||||
String _userId = '';
|
||||
String _workspaceId = '';
|
||||
bool _initialLoading = true;
|
||||
String? _loadError;
|
||||
PaymentProcessor? _selectedProcessor;
|
||||
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
final TextEditingController _accountController = TextEditingController();
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
bool _editMode = false;
|
||||
@@ -85,9 +86,9 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
|
||||
Future<void> _init() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
_userId = prefs.getString('userId') ?? '';
|
||||
_workspaceId = prefs.getString('workspaceId') ?? '';
|
||||
|
||||
final result = await controller.getBatch(widget.batchId, _userId);
|
||||
final result = await controller.getBatch(widget.batchId, _workspaceId);
|
||||
if (!mounted) return;
|
||||
|
||||
if (result.isSuccess) {
|
||||
@@ -117,6 +118,7 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
@override
|
||||
void dispose() {
|
||||
_searchController.dispose();
|
||||
_accountController.dispose();
|
||||
_scrollController.dispose();
|
||||
_entryController.dispose();
|
||||
_confirmController?.dispose();
|
||||
@@ -136,7 +138,7 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
// Persist the selected payment processor on the batch before confirming
|
||||
final updateReq = GroupBatchUpdateRequest(
|
||||
id: batch.id,
|
||||
userId: _userId,
|
||||
workspaceId: _workspaceId,
|
||||
paymentProcessorLabel: processor.label,
|
||||
paymentProcessorName: processor.name,
|
||||
paymentProcessorImage: processor.image,
|
||||
@@ -152,7 +154,11 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
_cachedUpdateReq = updateReq;
|
||||
|
||||
// Step 2: Confirm the batch
|
||||
final result = await controller.confirmBatch(batch.id!, _userId);
|
||||
final result = await controller.confirmBatch(
|
||||
batch.id!,
|
||||
_workspaceId,
|
||||
_selectedProcessor!.authType,
|
||||
);
|
||||
if (!mounted) return;
|
||||
if (!result.isSuccess) {
|
||||
_showError(result.error ?? 'Confirm failed.');
|
||||
@@ -431,7 +437,7 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
final batch = _batch;
|
||||
if (batch == null) return;
|
||||
|
||||
final result = await controller.requestBatch(batch.id!, _userId);
|
||||
final result = await controller.requestBatch(batch.id!, _workspaceId);
|
||||
if (!mounted) return;
|
||||
|
||||
if (!result.isSuccess) {
|
||||
@@ -484,7 +490,7 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final pollResult = await controller.pollBatch(batch.id!, _userId);
|
||||
final pollResult = await controller.pollBatch(batch.id!, _workspaceId);
|
||||
if (!mounted) return;
|
||||
if (pollResult.isSuccess) {
|
||||
setState(() => _showPollButton = false);
|
||||
@@ -672,7 +678,7 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
Future<void> _onPoll() async {
|
||||
final batch = _batch;
|
||||
if (batch == null) return;
|
||||
final result = await controller.pollBatch(batch.id!, _userId);
|
||||
final result = await controller.pollBatch(batch.id!, _workspaceId);
|
||||
if (!mounted) return;
|
||||
if (result.isSuccess) {
|
||||
setState(() => _showPollButton = false);
|
||||
@@ -685,7 +691,10 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
Future<void> _onDownloadReport() async {
|
||||
final batch = _batch;
|
||||
if (batch == null) return;
|
||||
final result = await controller.downloadBatchReport(batch.id!, _userId);
|
||||
final result = await controller.downloadBatchReport(
|
||||
batch.id!,
|
||||
_workspaceId,
|
||||
);
|
||||
if (!mounted) return;
|
||||
if (result.isSuccess) {
|
||||
final fileUrl = result.data?['fileUrl'] as String?;
|
||||
@@ -1435,7 +1444,10 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
|
||||
if (items.isEmpty) return false;
|
||||
|
||||
final updateList = GroupBatchItemUpdateList(items: items, userId: _userId);
|
||||
final updateList = GroupBatchItemUpdateList(
|
||||
items: items,
|
||||
workspaceId: _workspaceId,
|
||||
);
|
||||
|
||||
final result = await controller.updateBatchItems(batch.id!, updateList);
|
||||
if (!mounted) return false;
|
||||
@@ -1492,6 +1504,8 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
onPressed: () {
|
||||
setSheetState(() {
|
||||
controller.model.batchItemsStatusFilter = null;
|
||||
controller.model.batchItemsRecipientAccount = null;
|
||||
_accountController.clear();
|
||||
});
|
||||
},
|
||||
child: const Text('Clear All'),
|
||||
@@ -1517,14 +1531,18 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
items: const [
|
||||
DropdownMenuItem(value: null, child: Text('All')),
|
||||
DropdownMenuItem(
|
||||
value: 'PENDING',
|
||||
child: Text('Pending'),
|
||||
value: 'CONFIRMED',
|
||||
child: Text('CONFIRMED'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'SUCCESS',
|
||||
child: Text('Success'),
|
||||
value: 'INTEGRATED',
|
||||
child: Text('INTEGRATED'),
|
||||
),
|
||||
DropdownMenuItem(value: 'FAILED', child: Text('FAILED')),
|
||||
DropdownMenuItem(
|
||||
value: 'SKIPPED',
|
||||
child: Text('SKIPPED'),
|
||||
),
|
||||
DropdownMenuItem(value: 'FAILED', child: Text('Failed')),
|
||||
],
|
||||
onChanged: (v) {
|
||||
setSheetState(
|
||||
@@ -1532,6 +1550,24 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
controller: _accountController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Account Number',
|
||||
hintText: 'Filter by account number',
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade100,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
@@ -1546,6 +1582,9 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
? _searchController.text
|
||||
: null,
|
||||
status: controller.model.batchItemsStatusFilter,
|
||||
account: _accountController.text.isNotEmpty
|
||||
? _accountController.text
|
||||
: null,
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -2021,7 +2060,9 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
// Action Bar — search, filter, edit, refresh
|
||||
// ──────────────────────────────────────────────────────────────
|
||||
Widget _buildActionBar(ThemeData theme, bool isDark) {
|
||||
final hasFilters = controller.model.batchItemsStatusFilter != null;
|
||||
final hasFilters =
|
||||
controller.model.batchItemsStatusFilter != null ||
|
||||
controller.model.batchItemsRecipientAccount != null;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -2033,7 +2074,7 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
child: TextFormField(
|
||||
controller: _searchController,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Search by name or phone',
|
||||
hintText: 'Search by recipient name',
|
||||
prefixIcon: const Icon(Icons.search, size: 20),
|
||||
suffixIcon: _searchController.text.isNotEmpty
|
||||
? IconButton(
|
||||
@@ -2046,6 +2087,9 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
batchId,
|
||||
status:
|
||||
controller.model.batchItemsStatusFilter,
|
||||
account: controller
|
||||
.model
|
||||
.batchItemsRecipientAccount,
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -2075,6 +2119,7 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
batchId,
|
||||
search: value.isNotEmpty ? value : null,
|
||||
status: controller.model.batchItemsStatusFilter,
|
||||
account: controller.model.batchItemsRecipientAccount,
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -2147,6 +2192,26 @@ class _BatchDetailScreenState extends State<BatchDetailScreen>
|
||||
search: _searchController.text.isNotEmpty
|
||||
? _searchController.text
|
||||
: null,
|
||||
account: controller.model.batchItemsRecipientAccount,
|
||||
);
|
||||
}
|
||||
},
|
||||
theme,
|
||||
),
|
||||
if (controller.model.batchItemsRecipientAccount != null)
|
||||
_activeFilterChip(
|
||||
'Account: ${controller.model.batchItemsRecipientAccount}',
|
||||
() {
|
||||
controller.model.batchItemsRecipientAccount = null;
|
||||
_accountController.clear();
|
||||
final batchId = _batch?.id ?? '';
|
||||
if (batchId.isNotEmpty) {
|
||||
controller.searchBatchItems(
|
||||
batchId,
|
||||
search: _searchController.text.isNotEmpty
|
||||
? _searchController.text
|
||||
: null,
|
||||
status: controller.model.batchItemsStatusFilter,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -65,10 +65,12 @@ class _CreateGroupFromFileScreenState extends State<CreateGroupFromFileScreen> {
|
||||
}
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final workspaceId = prefs.getString('workspaceId') ?? '';
|
||||
final userId = prefs.getString('userId') ?? '';
|
||||
|
||||
final result = await controller.createGroupFromFile(
|
||||
groupName: _groupNameController.text.trim(),
|
||||
workspaceId: workspaceId,
|
||||
userId: userId,
|
||||
description: _descriptionController.text.trim().isEmpty
|
||||
? null
|
||||
|
||||
@@ -82,6 +82,7 @@ class _GroupCreateScreenState extends State<GroupCreateScreen> {
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final userId = prefs.getString('userId') ?? '';
|
||||
final workspaceId = prefs.getString('workspaceId') ?? '';
|
||||
|
||||
final req = CreateGroupRequest(
|
||||
name: _nameController.text.trim(),
|
||||
@@ -89,6 +90,7 @@ class _GroupCreateScreenState extends State<GroupCreateScreen> {
|
||||
? null
|
||||
: _descriptionController.text.trim(),
|
||||
userId: userId,
|
||||
workspaceId: workspaceId,
|
||||
recipients: recipients,
|
||||
);
|
||||
|
||||
|
||||
@@ -552,7 +552,7 @@ class _GroupDetailScreenState extends State<GroupDetailScreen>
|
||||
await groupController.removeMember(
|
||||
groupId: widget.group.id ?? '',
|
||||
recipientId: member.id ?? '',
|
||||
userId: widget.group.userId ?? '',
|
||||
workspaceId: widget.group.workspaceId ?? '',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -675,7 +675,7 @@ class _GroupDetailScreenState extends State<GroupDetailScreen>
|
||||
}
|
||||
|
||||
void _onDeleteSelected() async {
|
||||
final userId = widget.group.userId ?? '';
|
||||
final workspaceId = widget.group.workspaceId ?? '';
|
||||
final count = batchController.model.selectedBatchIds.length;
|
||||
|
||||
final confirmed = await showDialog<bool>(
|
||||
@@ -700,7 +700,7 @@ class _GroupDetailScreenState extends State<GroupDetailScreen>
|
||||
if (confirmed == true) {
|
||||
await batchController.deleteSelectedBatches(
|
||||
groupId: widget.group.id ?? '',
|
||||
userId: userId,
|
||||
workspaceId: workspaceId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,26 +30,28 @@ class _GroupsScreenState extends State<GroupsScreen> {
|
||||
void _onScroll() {
|
||||
if (_scrollController.position.pixels >=
|
||||
_scrollController.position.maxScrollExtent - 200) {
|
||||
controller.loadNextPage(userId: prefs.getString('userId') ?? '');
|
||||
controller.loadNextPage(
|
||||
workspaceId: prefs.getString('workspaceId') ?? '',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadData() async {
|
||||
prefs = await SharedPreferences.getInstance();
|
||||
final userId = prefs.getString('userId') ?? '';
|
||||
await controller.listGroups(userId: userId);
|
||||
final workspaceId = prefs.getString('workspaceId') ?? '';
|
||||
await controller.listGroups(workspaceId: workspaceId);
|
||||
}
|
||||
|
||||
void _onSearchChanged(String value) {
|
||||
final userId = prefs.getString('userId') ?? '';
|
||||
final workspaceId = prefs.getString('workspaceId') ?? '';
|
||||
controller.searchGroups(
|
||||
userId: userId,
|
||||
workspaceId: workspaceId,
|
||||
name: value.isNotEmpty ? value : null,
|
||||
);
|
||||
}
|
||||
|
||||
void _onDeleteSelected() async {
|
||||
final userId = prefs.getString('userId') ?? '';
|
||||
final workspaceId = prefs.getString('workspaceId') ?? '';
|
||||
final count = controller.model.selectedGroupIds.length;
|
||||
|
||||
final confirmed = await showDialog<bool>(
|
||||
@@ -72,7 +74,7 @@ class _GroupsScreenState extends State<GroupsScreen> {
|
||||
);
|
||||
|
||||
if (confirmed == true) {
|
||||
await controller.deleteSelectedGroups(userId: userId);
|
||||
await controller.deleteSelectedGroups(workspaceId: workspaceId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user