claim form download
This commit is contained in:
parent
41160cbfaf
commit
2937984b56
@ -1,11 +1,13 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
import 'package:nhance_app_pwa/customAppBar/customAppBar.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/service/svg_service.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:video_player/video_player.dart';
|
||||
@ -14,6 +16,9 @@ import 'package:video_player/video_player.dart';
|
||||
import '../../customAppBar/responsive.dart';
|
||||
import '../../customAppBar/tabs.dart';
|
||||
import '../../customAppBar/toastHelper.dart';
|
||||
import '../helpers/custom_download_snackbar.dart';
|
||||
import '../helpers/ecard_download_notification_service.dart';
|
||||
import '../helpers/ecard_download_service.dart';
|
||||
import '../service/SessionManager.dart';
|
||||
import '../service/TokenService.dart';
|
||||
import '../service/multi_video_player.dart';
|
||||
@ -37,6 +42,12 @@ import 'package:nhance_app_pwa/logger.dart';
|
||||
dynamic empCodeString;
|
||||
dynamic empPrimaryId;
|
||||
dynamic client_id;
|
||||
dynamic mobileNo;
|
||||
dynamic client_branch_id;
|
||||
dynamic emailId;
|
||||
List<Map<String, dynamic>> policyList = [];
|
||||
bool _isDownloadingClaimForm = false;
|
||||
final EcardDownloadService _ecardDownloadService = const EcardDownloadService();
|
||||
dynamic cashLessClaimsDetails;
|
||||
dynamic reimbursementClaimsDetails;
|
||||
dynamic cashLessSectionName;
|
||||
@ -91,11 +102,354 @@ import 'package:nhance_app_pwa/logger.dart';
|
||||
logDebug(empCodeString); // Check if emp_code is correct
|
||||
empPrimaryId = session.empPrimaryId;
|
||||
client_id = session.client_id;
|
||||
mobileNo = session.mobileNo;
|
||||
client_branch_id = session.empClientBranchId;
|
||||
emailId = session.empEmailCorporate ?? '';
|
||||
logDebug(client_id);
|
||||
getCashlessAndReimbursement();
|
||||
getActiveAndInactivePolicyDetails();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getActiveAndInactivePolicyDetails() async {
|
||||
if (client_id == null || empCodeString == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final responseActive = await apiService.getActiveAndInactivePolicyDetails(
|
||||
client_id!, empCodeString!, 'Active', client_branch_id, mobileNo, emailId);
|
||||
|
||||
final responseInactive = await apiService.getActiveAndInactivePolicyDetails(
|
||||
client_id!, empCodeString!, 'Inactive', client_branch_id, mobileNo, emailId);
|
||||
|
||||
final bool isActiveSuccess = responseActive['status'] == 'success' &&
|
||||
responseActive['data'] != null;
|
||||
final bool isInactiveSuccess = responseInactive['status'] == 'success' &&
|
||||
responseInactive['data'] != null;
|
||||
|
||||
final List<Map<String, dynamic>> activeData = isActiveSuccess
|
||||
? List<Map<String, dynamic>>.from(responseActive['data'])
|
||||
: [];
|
||||
|
||||
final List<Map<String, dynamic>> inactiveData = isInactiveSuccess
|
||||
? List<Map<String, dynamic>>.from(responseInactive['data'])
|
||||
: [];
|
||||
|
||||
final retailPolicyDetails =
|
||||
List.from(responseActive['retail_policy_data'] ?? []);
|
||||
|
||||
final filteredRetail = retailPolicyDetails
|
||||
.where((item) => item.containsKey('policy_transaction_id'))
|
||||
.toList();
|
||||
|
||||
final combinedPolicies = [...activeData, ...inactiveData, ...filteredRetail];
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
policyList = combinedPolicies
|
||||
.where((policy) =>
|
||||
policy['client_policy_id'] != null &&
|
||||
policy['client_policy_id'].toString().trim().isNotEmpty)
|
||||
.map((policy) => Map<String, dynamic>.from(policy))
|
||||
.toList();
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
logDebug('Error fetching policies for claim form: $e');
|
||||
}
|
||||
}
|
||||
|
||||
String _policyDropdownLabel(Map<String, dynamic> policy) {
|
||||
final name = policy['policy_name'] ?? policy['heading'] ?? '';
|
||||
final no = policy['policy_no'] ?? '';
|
||||
if (name.toString().isNotEmpty && no.toString().isNotEmpty) {
|
||||
return '$name - $no';
|
||||
}
|
||||
return name.toString().isNotEmpty ? name.toString() : no.toString();
|
||||
}
|
||||
|
||||
bool _isApiSuccess(Map<String, dynamic> response) {
|
||||
final status = response['status'];
|
||||
return status == true || status == 'success';
|
||||
}
|
||||
|
||||
String? _extractDownloadUrl(dynamic data) {
|
||||
if (data == null) return null;
|
||||
if (data is Map && data['download_url'] != null) {
|
||||
final url = data['download_url'].toString().trim();
|
||||
if (url.isNotEmpty) return url;
|
||||
}
|
||||
if (data is String && data.trim().isNotEmpty) return data.trim();
|
||||
return null;
|
||||
}
|
||||
|
||||
void _showInsurerClaimFormPopup() {
|
||||
if (policyList.isEmpty) {
|
||||
ToastHelper.showErrorToast(context, 'No policies available');
|
||||
return;
|
||||
}
|
||||
|
||||
String? selectedClientPolicyId = policyList.first['client_policy_id']?.toString();
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
builder: (dialogContext) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, setDialogState) {
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
title: Text(
|
||||
'Insurer Claim Form',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context) ? 20 : 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: const Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
content: SizedBox(
|
||||
width: Responsive.isDesktop(context) ? 420 : double.maxFinite,
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: selectedClientPolicyId,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Select Policy',
|
||||
border: const OutlineInputBorder(),
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
color: const Color(0xFF636363),
|
||||
),
|
||||
),
|
||||
items: policyList.map((policy) {
|
||||
final clientPolicyId =
|
||||
policy['client_policy_id']?.toString() ?? '';
|
||||
return DropdownMenuItem<String>(
|
||||
value: clientPolicyId,
|
||||
child: Text(
|
||||
_policyDropdownLabel(policy),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
color: const Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (value) {
|
||||
setDialogState(() {
|
||||
selectedClientPolicyId = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(dialogContext),
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: GoogleFonts.poppins(
|
||||
color: const Color(0xFF636363),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: _isDownloadingClaimForm ||
|
||||
selectedClientPolicyId == null ||
|
||||
selectedClientPolicyId!.isEmpty
|
||||
? null
|
||||
: () async {
|
||||
await _downloadInsurerClaimForm(
|
||||
selectedClientPolicyId!,
|
||||
dialogContext,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
'Download',
|
||||
style: GoogleFonts.poppins(
|
||||
color: const Color(0xFFE26728),
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _downloadInsurerClaimForm(
|
||||
String clientPolicyId,
|
||||
BuildContext dialogContext,
|
||||
) async {
|
||||
if (_isDownloadingClaimForm) return;
|
||||
|
||||
setState(() => _isDownloadingClaimForm = true);
|
||||
|
||||
try {
|
||||
final response =
|
||||
await apiService.getInsurerClaimFormDownloadUrl(clientPolicyId);
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
if (!_isApiSuccess(response)) {
|
||||
ToastHelper.showErrorToast(
|
||||
context,
|
||||
response['message']?.toString() ?? 'Unable to download claim form',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final downloadUrl = _extractDownloadUrl(response['data']);
|
||||
if (downloadUrl == null || downloadUrl.isEmpty) {
|
||||
ToastHelper.showErrorToast(
|
||||
context,
|
||||
response['message']?.toString() ?? 'Claim form is not available',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final successMessage = response['message']?.toString() ??
|
||||
'Claim form downloaded successfully';
|
||||
|
||||
final selectedPolicy = policyList.firstWhere(
|
||||
(policy) =>
|
||||
policy['client_policy_id']?.toString() == clientPolicyId,
|
||||
orElse: () => {},
|
||||
);
|
||||
final policyNo = selectedPolicy['policy_no']?.toString();
|
||||
final safePolicyNo =
|
||||
policyNo?.replaceAll(RegExp(r'[^\w\-.]'), '_') ?? clientPolicyId;
|
||||
final fileName = 'claim_form_$safePolicyNo.pdf';
|
||||
|
||||
if (!kIsWeb) {
|
||||
CustomDownloadSnackbar.show(
|
||||
context,
|
||||
message: 'Downloading claim form...',
|
||||
);
|
||||
}
|
||||
|
||||
final token = await TokenService.getPostToken();
|
||||
final result = await _ecardDownloadService.downloadEcard(
|
||||
url: downloadUrl,
|
||||
fileName: fileName,
|
||||
headers: {
|
||||
'APP-SIGNATURE':
|
||||
'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
|
||||
if (token != null && token.isNotEmpty)
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
if (result.success) {
|
||||
if (dialogContext.mounted) {
|
||||
Navigator.pop(dialogContext);
|
||||
}
|
||||
ToastHelper.showSuccessToast(context, successMessage);
|
||||
if (!kIsWeb &&
|
||||
result.savedPath != null &&
|
||||
result.savedPath!.isNotEmpty) {
|
||||
await EcardDownloadNotificationService.showDownloadCompleted(
|
||||
filePath: result.savedPath!,
|
||||
fileName: fileName,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
ToastHelper.showErrorToast(
|
||||
context,
|
||||
result.message ?? 'Could not download claim form',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
logDebug('Claim form download error: $e');
|
||||
if (mounted) {
|
||||
ToastHelper.showErrorToast(
|
||||
context,
|
||||
'Unable to download claim form. Please try again.',
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() => _isDownloadingClaimForm = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildInsurerClaimFormButton(BuildContext context) {
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: _showInsurerClaimFormPopup,
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: const BorderSide(
|
||||
color: Color(0xFFD9D9D9),
|
||||
width: 1.0,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? const EdgeInsets.symmetric(
|
||||
vertical: 15, horizontal: 15)
|
||||
: const EdgeInsets.symmetric(
|
||||
vertical: 20, horizontal: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 11,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.string(
|
||||
SvgService.getSvg('general'),
|
||||
width: 25,
|
||||
height: 25,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
'Insurer Claim Form',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: const Color(0xFF404040),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Expanded(
|
||||
flex: 1,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: Color(0xFFE26728),
|
||||
size: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getCashlessAndReimbursement() async {
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
@ -511,7 +865,8 @@ import 'package:nhance_app_pwa/logger.dart';
|
||||
|
||||
]),
|
||||
),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 40 : 10),
|
||||
_buildInsurerClaimFormButton(context),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 40 : 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -163,6 +163,21 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getInsurerClaimFormDownloadUrl(
|
||||
String clientPolicyId) async {
|
||||
logDebug(_postToken);
|
||||
if (_postToken == null) {
|
||||
await _initializeToken();
|
||||
}
|
||||
final url = Uri.parse(
|
||||
'${Environment.apiUrl}getInsurerClaimFormDownloadUrl?client_policy_id=$clientPolicyId');
|
||||
final headers = {
|
||||
'Authorization': 'Bearer $_postToken' ?? '',
|
||||
};
|
||||
final response = await _makeGetRequest(url, headers);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getWellnessLink(
|
||||
empPrimaryId, client_policy_id) async {
|
||||
logDebug(_postToken);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user