diff --git a/lib/core/services/api_service.dart b/lib/core/services/api_service.dart index 021ffaf..2266257 100644 --- a/lib/core/services/api_service.dart +++ b/lib/core/services/api_service.dart @@ -655,7 +655,7 @@ class ApiService { } else if (role == 'staff') { url = Uri.parse('${Env.apiUrl}staff/changeStaffStatus'); } else { - url = Uri.parse('${Env.apiUrl}/api/agent/changeAgentStatus'); + url = Uri.parse('${Env.apiUrl}agent/changeAgentStatus'); } // final token = await getToken(); // Fetch token diff --git a/lib/presentation/screens/UserManagement/Agent/agent.dart b/lib/presentation/screens/UserManagement/Agent/agent.dart index c428481..322baab 100644 --- a/lib/presentation/screens/UserManagement/Agent/agent.dart +++ b/lib/presentation/screens/UserManagement/Agent/agent.dart @@ -219,7 +219,10 @@ class AgentState extends ConsumerState { } Future createUserData(Map userData) async { - final bool isUpdating = widget.id != null && widget.id != 'create'; + + final String cleanedId = widget.id?.toString().replaceAll(' ', '').toUpperCase() ?? ''; + final bool isUpdating = cleanedId.isNotEmpty && cleanedId != 'CREATE' && cleanedId != '0'; + final id = widget.id; final uri = Uri.parse( // isUpdating diff --git a/lib/presentation/screens/UserManagement/Staff/staffList.dart b/lib/presentation/screens/UserManagement/Staff/staffList.dart index 783425d..e99fc5f 100644 --- a/lib/presentation/screens/UserManagement/Staff/staffList.dart +++ b/lib/presentation/screens/UserManagement/Staff/staffList.dart @@ -133,6 +133,7 @@ class StaffListState extends ConsumerState { (item['email'] ?? '').toString().toLowerCase().contains(q) || (item['mobile'] ?? '').toString().toLowerCase().contains(q) || (item['address'] ?? '').toString().toLowerCase().contains(q) || + (item['role'] ?? '').toString().toLowerCase().contains(q) || (item['emp_id'] ?? item['agent_code'] ?? '') .toString() .toLowerCase() diff --git a/lib/presentation/screens/staff/Enquiry/Proposal_QuickCreation/Proposal_QuickCreation.dart b/lib/presentation/screens/staff/Enquiry/Proposal_QuickCreation/Proposal_QuickCreation.dart index 537251e..c5123d9 100644 --- a/lib/presentation/screens/staff/Enquiry/Proposal_QuickCreation/Proposal_QuickCreation.dart +++ b/lib/presentation/screens/staff/Enquiry/Proposal_QuickCreation/Proposal_QuickCreation.dart @@ -479,9 +479,11 @@ class CreateProposal_QuickFormState } void addQuotationRow() { + String amountText = controllers["premium_Amount"]?.text ?? ""; + double? amount = double.tryParse(amountText); if (selectedInsurer != null && selectedInsPlanType != null && - controllers["premium_Amount"]?.text.isNotEmpty == true) { + amount != null && amount > 0) { setState(() { quotationList.add({ "insurer_id": selectedInsurer, @@ -502,6 +504,10 @@ class CreateProposal_QuickFormState if (isSingleSave) { handleDone(); } + } else { + print('Please enter a valid Premium Amount greater than 0'); + ToastHelper.showErrorToast(context, 'Please enter a valid Premium Amount'); + return; // ❌ stop execution } } diff --git a/lib/presentation/screens/staff/policy/policy_list.dart b/lib/presentation/screens/staff/policy/policy_list.dart index 20a201e..13dd8bf 100644 --- a/lib/presentation/screens/staff/policy/policy_list.dart +++ b/lib/presentation/screens/staff/policy/policy_list.dart @@ -1221,46 +1221,48 @@ class AuditHistoryModalState extends ConsumerState { : getAuditHistoryData.isEmpty ? const Center(child: Text("No Audit History Data Found")) : SingleChildScrollView( - scrollDirection: Axis.vertical, - child: Theme( - data: Theme.of(context).copyWith( - dividerColor: Colors.grey.shade200, + scrollDirection: Axis.vertical, + child: SizedBox( + width: double.infinity, + child: Theme( + data: Theme.of(context).copyWith( + dividerColor: Colors.grey.shade200, + ), + child: DataTable( + headingRowColor: WidgetStateProperty.all(Color(0xFFF8FAFC)), + columnSpacing: 20, + columns: [ + DataColumn(label: Text("Column Name", style: _headerStyle())), + DataColumn(label: Text("Message", style: _headerStyle())), + DataColumn(label: Text("Changed On", style: _headerStyle())), + DataColumn(label: Text("Changed By", style: _headerStyle())), + ], + // Inside your build method's DataTable + rows: getAuditHistoryData.map((data) { + return DataRow(cells: [ + DataCell(Text(data['column_name'] ?? "-", style: _cellStyle())), + DataCell( + SizedBox( + width: 300, // Give message more width + child: Text( + data['message'] ?? "-", + style: _cellStyle(), + softWrap: true, // Ensure text wraps to next line + ), + ) + ), + DataCell(Text( + formatIndianDate(data['changed_on'] ?? ""), + style: _cellStyle(), + )), + DataCell(Text(data['changed_by'] ?? "-", style: _cellStyle())), + ]); + }).toList(), + ), + ), + ), ), - child: DataTable( - headingRowColor: WidgetStateProperty.all(Color(0xFFF8FAFC)), - columnSpacing: 20, - columns: [ - DataColumn(label: Text("Column Name", style: _headerStyle())), - DataColumn(label: Text("Message", style: _headerStyle())), - DataColumn(label: Text("Changed On", style: _headerStyle())), - DataColumn(label: Text("Changed By", style: _headerStyle())), - ], - // Inside your build method's DataTable - rows: getAuditHistoryData.map((data) { - return DataRow(cells: [ - DataCell(Text(data['column_name'] ?? "-", style: _cellStyle())), - DataCell( - SizedBox( - width: 300, // Give message more width - child: Text( - data['message'] ?? "-", - style: _cellStyle(), - softWrap: true, // Ensure text wraps to next line - ), - ) - ), - DataCell(Text( - formatIndianDate(data['changed_on'] ?? ""), - style: _cellStyle(), - )), - DataCell(Text(data['changed_by'] ?? "-", style: _cellStyle())), - ]); - }).toList(), - ), - ), - ), - ), - + ) ], ), ), diff --git a/lib/presentation/screens/staff/policy/policy_validation.dart b/lib/presentation/screens/staff/policy/policy_validation.dart index d14971d..95123f4 100644 --- a/lib/presentation/screens/staff/policy/policy_validation.dart +++ b/lib/presentation/screens/staff/policy/policy_validation.dart @@ -260,8 +260,13 @@ class _policyValidationState extends ConsumerState { getFuelType(); getPolicyFilePath(); }); + + controllers['commission_amount']?.addListener(() { + setState(() {}); + }); } + @override void dispose() { for (final controller in controllers.values) { @@ -548,9 +553,9 @@ class _policyValidationState extends ConsumerState { } Future _fetchCommision() async { - print('_fetchCommision'); + print('_fetchCommision IN'); final policyId = widget.item?['policy_id']; - final payload = buildCommissionPayload(); + if (policyId == null) { ToastHelper.showWarningToast(context, 'Missing policy id'); return; @@ -573,7 +578,7 @@ class _policyValidationState extends ConsumerState { // ...dataDetails(), // // "insurance_plan_type": // }; - print('_fetchCommision1'); + // print('_fetchCommision1'); // setState(() { // isLoading = true; // payload['insurance_plan_type'] = selectedInsurancPlanType; @@ -583,23 +588,37 @@ class _policyValidationState extends ConsumerState { // print('payload2 - ${payload['insurance_plan_type']}'); // print('payload - $payload'); // }); - print('_fetchCommision2'); + // print('_fetchCommision2'); + + // 👉 CRITICAL FIX: Set loading to true BEFORE the API call starts + setState(() { isLoading = true; }); + try { - debugPrint('FINAL SAVE PAYLOAD 1=> $payload'); + + final payload = buildCommissionPayload(); + debugPrint('Payload in fetchCommission: $payload'); final result = await apiService.calculateCommissionRequest(payload); - debugPrint('updatePolicy result => $result'); + debugPrint('Result in fetchCommission: $result'); + if (result != null && result['status'] == 'success') { if (!mounted) return; - setState(() => isLoading = false); + // setState(() => isLoading = false); // context.pop(); - ToastHelper.showSuccessToast(context, "Policy updated successfully"); + // Extract commission_amount from response final commissionAmount = result['data']?['commission_amount']; - if (commissionAmount != null) { - controllers["commission_amount"]?.text = commissionAmount - .toStringAsFixed(2); - } + + setState(() { + isLoading = false; // Stop loading + if (commissionAmount != null) { + // Update controller so the Confirm button becomes active + controllers["commission_amount"]?.text = + double.parse(commissionAmount.toString()).toStringAsFixed(2); + } + }); + + ToastHelper.showSuccessToast(context, "Commission calculated successfully"); // WidgetsBinding.instance.addPostFrameCallback((_) { // // Now safe to do navigation + provider updates @@ -612,17 +631,98 @@ class _policyValidationState extends ConsumerState { setState(() => isLoading = false); ToastHelper.showErrorToast( context, - result?['message']?.toString() ?? 'Error updating policy', + result?['message']?.toString() ?? 'Error calculating commission', ); } } catch (e, st) { - debugPrint('Exception in updatePolicy: $e\n$st'); + debugPrint('Exception in fetchCommission: $e\n$st'); if (!mounted) return; setState(() => isLoading = false); ToastHelper.showWarningToast(context, 'Exception: $e'); } + print('_fetchCommision OUT'); } + // Old Code For Backup purpose + // Future _fetchCommision() async { + // print('_fetchCommision'); + // final policyId = widget.item?['policy_id']; + // final payload = buildCommissionPayload(); + // if (policyId == null) { + // ToastHelper.showWarningToast(context, 'Missing policy id'); + // return; + // } + // + // if (!_formKey.currentState!.validate()) { + // ToastHelper.showWarningToast(context, "Please fill all required fields"); + // return; + // } + // + // // if (widget.item?['is_data_accuracy_checked'] == "1") { + // // ToastHelper.showWarningToast(context, "Data already confirmed"); + // // return; + // // } + // + // // final payload = { + // // "id": policyId, + // // 'insurance_plan_type': controllers['insurance_plan_type'], + // // "updated_by": userId, + // // ...dataDetails(), + // // // "insurance_plan_type": + // // }; + // print('_fetchCommision1'); + // // setState(() { + // // isLoading = true; + // // payload['insurance_plan_type'] = selectedInsurancPlanType; + // // payload['insurer_id'] = selectedInsuranceId; + // // payload['id'] = policyId; + // // payload['updated_by'] = userId; + // // print('payload2 - ${payload['insurance_plan_type']}'); + // // print('payload - $payload'); + // // });// debugPrint('FINAL SAVE PAYLOAD 1=> $payload'); + // final result = await apiService.calculateCommissionRequest(payload); + // debugPrint('updatePolicy result => $result'); + + // print('_fetchCommision2'); + // try { + // debugPrint('FINAL SAVE PAYLOAD 1=> $payload'); + // final result = await apiService.calculateCommissionRequest(payload); + // debugPrint('updatePolicy result => $result'); + // + // if (result != null && result['status'] == 'success') { + // if (!mounted) return; + // setState(() => isLoading = false); + // // context.pop(); + // ToastHelper.showSuccessToast(context, "Policy updated successfully"); + // // Extract commission_amount from response + // final commissionAmount = result['data']?['commission_amount']; + // if (commissionAmount != null) { + // controllers["commission_amount"]?.text = commissionAmount + // .toStringAsFixed(2); + // } + // + // // WidgetsBinding.instance.addPostFrameCallback((_) { + // // // Now safe to do navigation + provider updates + // // final container = ProviderScope.containerOf(context); + // // container.read(policyDataAcurancyRefreshProvider.notifier).state = + // // true; + // // }); + // } else { + // if (!mounted) return; + // setState(() => isLoading = false); + // ToastHelper.showErrorToast( + // context, + // result?['message']?.toString() ?? 'Error updating policy', + // ); + // } + // } catch (e, st) { + // debugPrint('Exception in updatePolicy: $e\n$st'); + // if (!mounted) return; + // setState(() => isLoading = false); + // ToastHelper.showWarningToast(context, 'Exception: $e'); + // } + // } + Widget buildVehicleType(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -919,34 +1019,19 @@ class _policyValidationState extends ConsumerState { child: Row( mainAxisAlignment: MainAxisAlignment.end, // 👉 move button to right children: [ - ElevatedButton( - onPressed: widget.item?['is_data_accuracy_checked'] == '1' - ? null - : _fetchCommision, - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF2E7D6E), - foregroundColor: Colors.white, - padding: const EdgeInsets.symmetric( - vertical: 10, - horizontal: 20, // 👉 smaller width - ), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - child: const Text( - 'Fetch Commission', - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), - ), - ), - SizedBox(width: 10), ElevatedButton( // onPressed: widget.item?['is_data_accuracy_checked'] == '1' - onPressed: - widget.item?['is_data_accuracy_checked'] != '1' || - (controllers['commission_amount']?.text.isEmpty ?? true) - ? null - : _save, + // onPressed: + // widget.item?['is_data_accuracy_checked'] != '1' || + // (controllers['commission_amount']?.text.isEmpty ?? true) + // ? null + // : _save, + onPressed: ( + widget.item?['is_data_accuracy_checked']?.toString() == '0' && + ((double.tryParse(controllers["commission_amount"]?.text ?? '0') ?? 0).floor() >= 1) + ) + ? _save + : null, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF2E7D6E), foregroundColor: Colors.white, @@ -958,11 +1043,57 @@ class _policyValidationState extends ConsumerState { borderRadius: BorderRadius.circular(8), ), ), - child: const Text( - 'Confirm Data Accuracy', + child: Text( + 'Confirm Data Accuracy ', + // '(${controllers["commission_amount"]?.text ?? '0'} | ' + // '${widget.item?['is_data_accuracy_checked'] ?? '0'})', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), ), ), + // ElevatedButton( + // onPressed: widget.item?['is_data_accuracy_checked'] == '1' + // ? null + // : _fetchCommision, + // style: ElevatedButton.styleFrom( + // backgroundColor: const Color(0xFF2E7D6E), + // foregroundColor: Colors.white, + // padding: const EdgeInsets.symmetric( + // vertical: 10, + // horizontal: 20, // 👉 smaller width + // ), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: const Text( + // 'Fetch Commission', + // style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), + // ), + // ), + // SizedBox(width: 10), + // ElevatedButton( + // // onPressed: widget.item?['is_data_accuracy_checked'] == '1' + // onPressed: + // widget.item?['is_data_accuracy_checked'] != '1' || + // (controllers['commission_amount']?.text.isEmpty ?? true) + // ? null + // : _save, + // style: ElevatedButton.styleFrom( + // backgroundColor: const Color(0xFF2E7D6E), + // foregroundColor: Colors.white, + // padding: const EdgeInsets.symmetric( + // vertical: 10, + // horizontal: 20, // 👉 smaller width + // ), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: const Text( + // 'Confirm Data Accuracy', + // style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), + // ), + // ), ], ), ), @@ -1549,6 +1680,25 @@ class _policyValidationState extends ConsumerState { ), ], ), + Row( + mainAxisAlignment: MainAxisAlignment.end, // Pushes children to the right + children: [ + TextButton( + onPressed: (widget.item?['is_data_accuracy_checked'] == '1' || isLoading) + ? null // Disable if already checked or currently loading + : _fetchCommision, + child: Text(isLoading ? "Calculating..." : "Calculate", + style: TextStyle( + color: (widget.item?['is_data_accuracy_checked'] == '1' || isLoading) + ? Colors.grey + : const Color(0xFF2E7D6E), + fontWeight: FontWeight.bold, + ) + ), + + ), + ], + ) ], ), ),