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( Future<void> getPdfDownload(
BuildContext context, // BuildContext context,
String path, String path,
String id, String id,
) async { ) async {
print('getPdfDownload 1'); print('getPdfDownload 1');
print('getPdfDownload 1 - $path'); print('getPdfDownload 1 - $path');
if (path.isEmpty) { // if (path.isEmpty) {
ToastHelper.showInfoToast(context, 'No file path found.'); // ToastHelper.showInfoToast(context, 'No file path found.');
return; // return;
} // }
final url = Uri.parse('https://venbait.in/nhance/partner/dev/$path'); final url = Uri.parse('https://venbait.in/nhance/partner/dev/$path');
await _initializeToken(); await _initializeToken();
@ -195,20 +221,26 @@ class ApiService {
final blobUrl = html.Url.createObjectUrlFromBlob(blob); final blobUrl = html.Url.createObjectUrlFromBlob(blob);
print('getPdfDownload $blobUrl'); print('getPdfDownload $blobUrl');
// --- filename resolution --- // --- filename resolution ---
String fileName = 'download_$id'; // String fileName = 'download_$id';
print('getPdfDownloadfileName $fileName'); // 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']; final contentDisp = response.headers['content-disposition'];
print('getPdfDownloadcontentDisp $contentDisp'); print('getPdfDownloadcontentDisp $contentDisp');
if (contentDisp != null && contentDisp.contains('filename=')) {
print('getPdfDownloadcontentDisp..1'); String fileName = extractFileName(contentDisp, path.split('/').last);
fileName = contentDisp.split('filename=')[1].replaceAll('"', ''); print('Resolved fileName: $fileName');
print('getPdfDownloadcontentDisp..2');
} else {
print('getPdfDownloadcontentDisp..3');
// fallback: URL or id
fileName = path.split('/').last;
if (id != null) fileName = '${id}_$fileName';
}
final anchor = html.AnchorElement(href: blobUrl) final anchor = html.AnchorElement(href: blobUrl)
..setAttribute('download', fileName) ..setAttribute('download', fileName)
..click(); ..click();
@ -261,7 +293,7 @@ class ApiService {
} else if (apiUrl != null) { } else if (apiUrl != null) {
print("Download from API: $apiUrl"); print("Download from API: $apiUrl");
print("Download from API: $apiId!"); print("Download from API: $apiId!");
await getPdfDownload(context, apiUrl, apiId!); await getPdfDownload(apiUrl, apiId!);
} else { } else {
print("⚠️ No file available to download"); print("⚠️ No file available to download");
} }

View File

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

View File

@ -441,7 +441,7 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId'; // 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path = final path =
'api/policy/downloadPolicyFile?policy_id=$selectedId&file_type=policy_pdf'; 'api/policy/downloadPolicyFile?policy_id=$selectedId&file_type=policy_pdf';
apiService.getPdfDownload(context,path, selectedId); apiService.getPdfDownload(path, selectedId);
}, },
child: Container( child: Container(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
@ -480,7 +480,7 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId'; // 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
final path = final path =
'api/policy/downloadPolicyFile?policy_id=$selectedId&file_type=policy_payment_receipt'; 'api/policy/downloadPolicyFile?policy_id=$selectedId&file_type=policy_payment_receipt';
apiService.getPdfDownload(context,path, selectedId); apiService.getPdfDownload(path, selectedId);
}, },
child: Container( child: Container(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
@ -589,7 +589,8 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
); );
}, },
icon: Icon(Icons.add), icon: Icon(Icons.add),
),); ),
);
} }
Widget _actionClaims(BuildContext context) { Widget _actionClaims(BuildContext context) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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