pdf download issue

This commit is contained in:
venbaittech 2025-10-10 13:15:18 +05:30
parent 9528ec2d67
commit 2de35505ab
12 changed files with 135 additions and 95 deletions

File diff suppressed because one or more lines are too long

View File

@ -154,18 +154,44 @@ class ApiService {
}
}
String extractFileName(String? contentDisposition, String fallback) {
if (contentDisposition == null) return fallback;
// Check for extended filename first (RFC 5987)
final filenameStarMatch = RegExp(
r'filename\*\s*=\s*([^;]+)',
).firstMatch(contentDisposition);
if (filenameStarMatch != null) {
String value = filenameStarMatch.group(1)!;
// Remove UTF-8'' prefix if exists
value = value.replaceAll(RegExp(r"UTF-8''"), '');
return Uri.decodeFull(value.replaceAll('"', ''));
}
// Fallback to regular filename=
final filenameMatch = RegExp(
r'filename\s*=\s*"?([^";]+)"?',
).firstMatch(contentDisposition);
if (filenameMatch != null) {
return filenameMatch.group(1)!;
}
// Fallback: use the provided fallback string
return fallback;
}
Future<void> getPdfDownload(
BuildContext context,
// BuildContext context,
String path,
String id,
) async {
print('getPdfDownload 1');
print('getPdfDownload 1 - $path');
if (path.isEmpty) {
ToastHelper.showInfoToast(context, 'No file path found.');
return;
}
// if (path.isEmpty) {
// ToastHelper.showInfoToast(context, 'No file path found.');
// return;
// }
final url = Uri.parse('https://venbait.in/nhance/partner/dev/$path');
await _initializeToken();
@ -195,20 +221,26 @@ class ApiService {
final blobUrl = html.Url.createObjectUrlFromBlob(blob);
print('getPdfDownload $blobUrl');
// --- filename resolution ---
String fileName = 'download_$id';
print('getPdfDownloadfileName $fileName');
// String fileName = 'download_$id';
// print('getPdfDownloadfileName $fileName');
// final contentDisp = response.headers['content-disposition'];
// print('getPdfDownloadcontentDisp $contentDisp');
// if (contentDisp != null && contentDisp.contains('filename=')) {
// print('getPdfDownloadcontentDisp..1');
// fileName = contentDisp.split('filename=')[1].replaceAll('"', '');
// print('getPdfDownloadcontentDisp..2');
// } else {
// print('getPdfDownloadcontentDisp..3');
// // fallback: URL or id
// fileName = path.split('/').last;
// if (id != null) fileName = '${id}_$fileName';
// }
final contentDisp = response.headers['content-disposition'];
print('getPdfDownloadcontentDisp $contentDisp');
if (contentDisp != null && contentDisp.contains('filename=')) {
print('getPdfDownloadcontentDisp..1');
fileName = contentDisp.split('filename=')[1].replaceAll('"', '');
print('getPdfDownloadcontentDisp..2');
} else {
print('getPdfDownloadcontentDisp..3');
// fallback: URL or id
fileName = path.split('/').last;
if (id != null) fileName = '${id}_$fileName';
}
String fileName = extractFileName(contentDisp, path.split('/').last);
print('Resolved fileName: $fileName');
final anchor = html.AnchorElement(href: blobUrl)
..setAttribute('download', fileName)
..click();
@ -261,7 +293,7 @@ class ApiService {
} else if (apiUrl != null) {
print("Download from API: $apiUrl");
print("Download from API: $apiId!");
await getPdfDownload(context, apiUrl, apiId!);
await getPdfDownload(apiUrl, apiId!);
} else {
print("⚠️ No file available to download");
}

View File

@ -354,6 +354,7 @@ class _AddDialogState extends State<AddDialog> {
ThemedFormField(
controller: controllers['policyNum']!,
backgroundColor: Color(0xFFEDF6F5),
readOnly: true,
validator: (value) => Validators.requiredField(value, "name"),
txtwidth: ResponsiveLayout.isMobile(context)
? null
@ -367,7 +368,7 @@ class _AddDialogState extends State<AddDialog> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Claims Description", style: _textStyle),
Text("Claims Description *", style: _textStyle),
SizedBox(height: 10),
ThemedFormField(
backgroundColor: Color(0xFFEDF6F5),
@ -391,7 +392,7 @@ class _AddDialogState extends State<AddDialog> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Claims Type", style: _textStyle),
Text("Claims Type *", style: _textStyle),
SizedBox(height: 10),
Container(
color: Colors.white,
@ -483,7 +484,7 @@ class _AddDialogState extends State<AddDialog> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Endorsement Type", style: _textStyle),
Text("Endorsement Type *", style: _textStyle),
SizedBox(height: 10),
Container(
color: Colors.white,
@ -570,7 +571,7 @@ class _AddDialogState extends State<AddDialog> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Remarks", style: _textStyle),
Text("Remarks *", style: _textStyle),
SizedBox(height: 10),
ThemedFormField(
backgroundColor: Color(0xFFEDF6F5),

View File

@ -441,7 +441,7 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path =
'api/policy/downloadPolicyFile?policy_id=$selectedId&file_type=policy_pdf';
apiService.getPdfDownload(context,path, selectedId);
apiService.getPdfDownload(path, selectedId);
},
child: Container(
padding: const EdgeInsets.all(8),
@ -480,7 +480,7 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path =
'api/policy/downloadPolicyFile?policy_id=$selectedId&file_type=policy_payment_receipt';
apiService.getPdfDownload(context,path, selectedId);
apiService.getPdfDownload(path, selectedId);
},
child: Container(
padding: const EdgeInsets.all(8),
@ -570,50 +570,51 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
Widget _actionEnroll(BuildContext context) {
return Tooltip(
message: 'Add Endorsement',
child: IconButton(
onPressed: () {
showDialog(
context: context,
builder: (ctx) => AddDialog(
userId: userId,
title: "Endorsement",
policyNumber: selectedPolicyNumber,
onSubmit: (value) {
debugPrint("New Endorsement: $value");
enrollKey.currentState?.getEndrosmentList(selectedPolicyNumber);
message: 'Add Endorsement',
child: IconButton(
onPressed: () {
showDialog(
context: context,
builder: (ctx) => AddDialog(
userId: userId,
title: "Endorsement",
policyNumber: selectedPolicyNumber,
onSubmit: (value) {
debugPrint("New Endorsement: $value");
enrollKey.currentState?.getEndrosmentList(selectedPolicyNumber);
// Update claim list or call API
},
),
);
},
icon: Icon(Icons.add),
),);
// Update claim list or call API
},
),
);
},
icon: Icon(Icons.add),
),
);
}
Widget _actionClaims(BuildContext context) {
return Tooltip(
message: 'Add Claim',
child: IconButton(
onPressed: () {
showDialog(
context: context,
builder: (ctx) => AddDialog(
userId: userId,
title: "Claims",
policyNumber: selectedPolicyNumber,
onSubmit: (value) {
debugPrint("New Claim: $value");
claimsKey.currentState?.getClaimsList(selectedPolicyNumber);
message: 'Add Claim',
child: IconButton(
onPressed: () {
showDialog(
context: context,
builder: (ctx) => AddDialog(
userId: userId,
title: "Claims",
policyNumber: selectedPolicyNumber,
onSubmit: (value) {
debugPrint("New Claim: $value");
claimsKey.currentState?.getClaimsList(selectedPolicyNumber);
// Update claim list or call API
},
),
);
},
icon: Icon(Icons.add),
),
// Update claim list or call API
},
),
);
},
icon: Icon(Icons.add),
),
);
}

View File

@ -466,7 +466,7 @@ class UploadIncentiveModalState extends ConsumerState<UploadIncentiveModal> {
showSearchBox: true,
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search agent...",
hintText: "Search partner...",
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.grey,
@ -685,11 +685,7 @@ class UploadIncentiveModalState extends ConsumerState<UploadIncentiveModal> {
final selectedId = file['id'];
final path =
'api/agent/downloadAgentIncentiveFile?id=$selectedId';
apiService.getPdfDownload(
context,
path,
selectedId,
);
apiService.getPdfDownload(path, selectedId);
},
onDelete: () async {
print("Delete ${file['id']}");

View File

@ -274,8 +274,8 @@ class AgentListState extends ConsumerState<AgentList> {
),
SizedBox(width: 10),
ExportBtn(
sheetName: "Agents",
fileName: "agent_list",
sheetName: "Partner",
fileName: "partner_list",
txt: !ResponsiveLayout.isMobile(context)
? true
: false,

View File

@ -292,7 +292,7 @@ class ProfileState extends ConsumerState<Profile> {
path =
'api/agent/downloadAgentIncentiveFile?id=$latestId';
}
apiService.getPdfDownload(context,
apiService.getPdfDownload(
path,
latestId,
);
@ -386,7 +386,7 @@ class ProfileState extends ConsumerState<Profile> {
path =
'api/agent/downloadAgentIncentiveFile?id=$selectedId';
}
apiService.getPdfDownload(context,
apiService.getPdfDownload(
path,
selectedId,
);
@ -552,7 +552,7 @@ class ProfileState extends ConsumerState<Profile> {
path =
'api/agent/downloadAgentIncentiveFile?id=$latestId';
}
apiService.getPdfDownload(context,
apiService.getPdfDownload(
path,
latestId,
);
@ -646,7 +646,7 @@ class ProfileState extends ConsumerState<Profile> {
path =
'api/agent/downloadAgentIncentiveFile?id=$selectedId';
}
apiService.getPdfDownload(context,
apiService.getPdfDownload(
path,
selectedId,
);

View File

@ -288,7 +288,7 @@ class ProfilePopUpState extends ConsumerState<ProfilePopUp> {
path =
'api/agent/downloadAgentIncentiveFile?id=$latestId';
}
apiService.getPdfDownload(context,path, latestId);
apiService.getPdfDownload(path, latestId);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
@ -371,7 +371,7 @@ class ProfilePopUpState extends ConsumerState<ProfilePopUp> {
path =
'api/agent/downloadAgentIncentiveFile?id=$selectedId';
}
apiService.getPdfDownload(context,
apiService.getPdfDownload(
path,
selectedId,
);

View File

@ -235,8 +235,14 @@ class StaffState extends ConsumerState<Staff> {
Tooltip(
message: 'Back',
child: IconButton(
icon: const Icon(Icons.arrow_left_sharp,size: 35,color: Color(0xFF425B5B)),
onPressed: () { context.go(AppRoutes.staffLst); },
icon: const Icon(
Icons.arrow_left_sharp,
size: 35,
color: Color(0xFF425B5B),
),
onPressed: () {
context.go(AppRoutes.staffLst);
},
splashRadius: 28,
hoverColor: Colors.black12,
padding: const EdgeInsets.all(8),
@ -391,11 +397,11 @@ class StaffState extends ConsumerState<Staff> {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Staff Id *", style: _textStyle),
Text("Staff Id ", style: _textStyle),
SizedBox(width: 10),
ThemedFormField(
controller: controllers['code']!,
validator: (value) => Validators.requiredField(value, "id"),
// validator: (value) => Validators.requiredField(value, "id"),
txtwidth: MediaQuery.of(context).size.width * 0.26,
),
],

View File

@ -678,14 +678,14 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
SizedBox(width: 16),
Expanded(
child: Performance(
title: "Performing Agents",
title: "Performing Partner",
data: agentsPerformanceList,
),
),
SizedBox(width: 16),
Expanded(
child: Performance(
title: "Non-Performing Agents",
title: "Non-Performing Partner",
data: nonAgentsPerformanceList,
),
),
@ -1014,7 +1014,9 @@ class agentPendings extends StatelessWidget {
? null
: (role == 'agent')
? () {
print("Clicked Agent role : $role - ${row['id']}");
print(
"Clicked Partner role : $role - ${row['id']}",
);
onEdit!(row['id'].toString());
// onEdit!(row['id']);
}
@ -1445,7 +1447,7 @@ class Performance extends StatelessWidget {
// ),
Expanded(
child: Text(
"Agent Name",
"Partner Name",
textAlign: TextAlign.center,
style: _headerStyle,
),
@ -1459,7 +1461,9 @@ class Performance extends StatelessWidget {
),
Expanded(
child: Text(
title == "Performing Agents" ? "Premium Value" : "Status",
title == "Performing Partners"
? "Premium Value"
: "Status",
textAlign: TextAlign.center,
style: _headerStyle,
),
@ -1514,7 +1518,7 @@ class Performance extends StatelessWidget {
Expanded(
child: Text(
title == "Performing Agents"
title == "Performing Partners"
? formatToCroresLakhsAndThousands(
row['total_premium_value'] ?? 0,
)
@ -1523,7 +1527,7 @@ class Performance extends StatelessWidget {
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w500,
color: title == "Performing Agents"
color: title == "Performing Partners"
? Colors.black
: (row['status']?.toString().toLowerCase() ==
"active"

View File

@ -772,7 +772,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path =
'api/enquiry/downloadEnquiryFile?enquiry_id=$selectedId&file_type=rc';
apiService.getPdfDownload(context, path, selectedId);
apiService.getPdfDownload(path, selectedId);
},
child: Container(
padding: const EdgeInsets.all(8),
@ -813,7 +813,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path =
'api/enquiry/downloadEnquiryFile?enquiry_id=$selectedId&file_type=id_proof';
apiService.getPdfDownload(context, path, selectedId);
apiService.getPdfDownload(path, selectedId);
},
child: Container(
padding: const EdgeInsets.all(8),
@ -850,7 +850,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path =
'api/enquiry/downloadEnquiryFile?enquiry_id=$selectedId&file_type=previous_policy';
apiService.getPdfDownload(context, path, selectedId);
apiService.getPdfDownload(path, selectedId);
},
child: Container(
padding: const EdgeInsets.all(8),
@ -890,7 +890,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
final path =
'api/quotation/downloadAdditionalUploadedFile?id=$acceptedQuotationId';
apiService.getPdfDownload(context, path, selectedId);
apiService.getPdfDownload(path, selectedId);
},
child: Container(
padding: const EdgeInsets.all(8),

View File

@ -543,7 +543,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path =
'api/enquiry/downloadEnquiryFile?enquiry_id=$selectedId&file_type=rc';
apiService.getPdfDownload(context, path, selectedId);
apiService.getPdfDownload(path, selectedId);
},
child: Container(
padding: const EdgeInsets.all(8),
@ -584,7 +584,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path =
'api/enquiry/downloadEnquiryFile?enquiry_id=$selectedId&file_type=id_proof';
apiService.getPdfDownload(context, path, selectedId);
apiService.getPdfDownload(path, selectedId);
},
child: Container(
padding: const EdgeInsets.all(8),
@ -621,7 +621,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path =
'api/enquiry/downloadEnquiryFile?enquiry_id=$selectedId&file_type=previous_policy';
apiService.getPdfDownload(context, path, selectedId);
apiService.getPdfDownload(path, selectedId);
},
child: Container(
padding: const EdgeInsets.all(8),