bug fix in persons

This commit is contained in:
Hesabix 2025-09-28 12:28:41 +03:30
parent a8e5c3d14c
commit b8ab020754
3 changed files with 66 additions and 6 deletions

View file

@ -147,6 +147,7 @@ async def export_persons_excel(
import io import io
import json import json
import datetime import datetime
import re
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
from fastapi.responses import Response from fastapi.responses import Response
@ -243,7 +244,22 @@ async def export_persons_excel(
wb.save(buffer) wb.save(buffer)
buffer.seek(0) buffer.seek(0)
filename = f"persons_export_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx" # Build meaningful filename
biz_name = ""
try:
b = db.query(Business).filter(Business.id == business_id).first()
if b is not None:
biz_name = b.name or ""
except Exception:
biz_name = ""
def slugify(text: str) -> str:
return re.sub(r"[^A-Za-z0-9_-]+", "_", text).strip("_")
base = "persons"
if biz_name:
base += f"_{slugify(biz_name)}"
if selected_only:
base += "_selected"
filename = f"{base}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
content = buffer.getvalue() content = buffer.getvalue()
return Response( return Response(
content=content, content=content,
@ -251,6 +267,7 @@ async def export_persons_excel(
headers={ headers={
"Content-Disposition": f"attachment; filename={filename}", "Content-Disposition": f"attachment; filename={filename}",
"Content-Length": str(len(content)), "Content-Length": str(len(content)),
"Access-Control-Expose-Headers": "Content-Disposition",
}, },
) )
@ -268,6 +285,7 @@ async def export_persons_pdf(
): ):
import json import json
import datetime import datetime
import re
from fastapi.responses import Response from fastapi.responses import Response
from weasyprint import HTML, CSS from weasyprint import HTML, CSS
from weasyprint.text.fonts import FontConfiguration from weasyprint.text.fonts import FontConfiguration
@ -448,13 +466,29 @@ async def export_persons_pdf(
font_config = FontConfiguration() font_config = FontConfiguration()
pdf_bytes = HTML(string=table_html).write_pdf(font_config=font_config) pdf_bytes = HTML(string=table_html).write_pdf(font_config=font_config)
filename = f"persons_export_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf" # Build meaningful filename
biz_name = ""
try:
b = db.query(Business).filter(Business.id == business_id).first()
if b is not None:
biz_name = b.name or ""
except Exception:
biz_name = ""
def slugify(text: str) -> str:
return re.sub(r"[^A-Za-z0-9_-]+", "_", text).strip("_")
base = "persons"
if biz_name:
base += f"_{slugify(biz_name)}"
if selected_only:
base += "_selected"
filename = f"{base}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
return Response( return Response(
content=pdf_bytes, content=pdf_bytes,
media_type="application/pdf", media_type="application/pdf",
headers={ headers={
"Content-Disposition": f"attachment; filename={filename}", "Content-Disposition": f"attachment; filename={filename}",
"Content-Length": str(len(pdf_bytes)), "Content-Length": str(len(pdf_bytes)),
"Access-Control-Expose-Headers": "Content-Disposition",
}, },
) )

View file

@ -60,6 +60,7 @@ class _PersonsPageState extends State<PersonsPage> {
showTableIcon: false, showTableIcon: false,
showRowNumbers: true, showRowNumbers: true,
enableRowSelection: true, enableRowSelection: true,
enableMultiRowSelection: true,
columns: [ columns: [
NumberColumn( NumberColumn(
'code', 'code',

View file

@ -595,12 +595,37 @@ class _DataTableWidgetState<T> extends State<DataTableWidget<T>> {
); );
if (response.data != null) { if (response.data != null) {
// Determine filename from Content-Disposition header if present
String? contentDisposition = response.headers.value('content-disposition');
String filename = 'export_${DateTime.now().millisecondsSinceEpoch}.${format == 'pdf' ? 'pdf' : 'xlsx'}';
if (contentDisposition != null) {
try {
final parts = contentDisposition.split(';').map((s) => s.trim());
for (final p in parts) {
if (p.toLowerCase().startsWith('filename=')) {
var name = p.substring('filename='.length).trim();
if (name.startsWith('"') && name.endsWith('"') && name.length >= 2) {
name = name.substring(1, name.length - 1);
}
if (name.isNotEmpty) {
filename = name;
}
break;
}
}
} catch (_) {
// Fallback to default filename
}
}
final expectedExt = format == 'pdf' ? '.pdf' : '.xlsx';
if (!filename.toLowerCase().endsWith(expectedExt)) {
filename = '$filename$expectedExt';
}
if (format == 'pdf') { if (format == 'pdf') {
// Handle PDF download await _downloadPdf(response.data, filename);
await _downloadPdf(response.data, 'referrals_export_${DateTime.now().millisecondsSinceEpoch}.pdf');
} else if (format == 'excel') { } else if (format == 'excel') {
// Handle Excel download await _downloadExcel(response.data, filename);
await _downloadExcel(response.data, 'referrals_export_${DateTime.now().millisecondsSinceEpoch}.xlsx');
} }
if (mounted) { if (mounted) {