fix(pdf): make footer and all content stay compact and strictly within half-sheet area

This commit is contained in:
=
2026-09-21 22:37:39 -04:00
parent 9263e3486f
commit dc39eab3ae
5 changed files with 91 additions and 60 deletions
@@ -74,9 +74,12 @@ class InsuranceAuthPdfService {
crossAxisAlignment: pw.CrossAxisAlignment.stretch, crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [ children: [
// Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt) // Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt)
pw.Container( pw.ConstrainedBox(
height: 5.5 * PdfPageFormat.inch - 36, constraints: const pw.BoxConstraints(
maxHeight: 5.5 * PdfPageFormat.inch - 36,
),
child: pw.Column( child: pw.Column(
mainAxisSize: pw.MainAxisSize.min,
crossAxisAlignment: pw.CrossAxisAlignment.stretch, crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [ children: [
// 1. Cabecera con Nombre del Doctor y Badge Sutil de Hidalyx Med // 1. Cabecera con Nombre del Doctor y Badge Sutil de Hidalyx Med
@@ -207,9 +210,9 @@ class InsuranceAuthPdfService {
pw.SizedBox(height: 8), pw.SizedBox(height: 8),
// 3. Contenido Formal idéntico a AlfaMedical // 3. Contenido Formal idéntico a AlfaMedical
pw.Expanded( pw.Column(
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.stretch, crossAxisAlignment: pw.CrossAxisAlignment.stretch,
mainAxisSize: pw.MainAxisSize.min,
children: [ children: [
// Señores ARS // Señores ARS
pw.RichText( pw.RichText(
@@ -311,8 +314,14 @@ class InsuranceAuthPdfService {
], ],
], ],
), ),
pw.SizedBox(height: 10),
// Línea divisoria decorativa previa al pie
pw.Container(
height: 0.5,
color: PdfColor.fromHex('CBD5E1'),
), ),
pw.SizedBox(height: 6), pw.SizedBox(height: 5),
// 4. Pie de página con Contacto del Consultorio // 4. Pie de página con Contacto del Consultorio
if (generalContact.isNotEmpty) ...[ if (generalContact.isNotEmpty) ...[
@@ -71,9 +71,12 @@ class PrescriptionPdfService {
crossAxisAlignment: pw.CrossAxisAlignment.stretch, crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [ children: [
// Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt) // Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt)
pw.Container( pw.ConstrainedBox(
height: 5.5 * PdfPageFormat.inch - 36, constraints: const pw.BoxConstraints(
maxHeight: 5.5 * PdfPageFormat.inch - 36,
),
child: pw.Column( child: pw.Column(
mainAxisSize: pw.MainAxisSize.min,
crossAxisAlignment: pw.CrossAxisAlignment.stretch, crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [ children: [
// 1. Cabecera con Nombre del Doctor y Badge Superior de Hidalyx Med // 1. Cabecera con Nombre del Doctor y Badge Superior de Hidalyx Med
@@ -219,9 +222,8 @@ class PrescriptionPdfService {
pw.SizedBox(height: 8), pw.SizedBox(height: 8),
// 3. Contenido de la Receta / Prescripción Médica // 3. Contenido de la Receta / Prescripción Médica
pw.Expanded( pw.Container(
child: pw.Container( padding: const pw.EdgeInsets.symmetric(vertical: 6),
padding: const pw.EdgeInsets.symmetric(vertical: 4),
child: pw.Text( child: pw.Text(
prescriptionText.trim().isNotEmpty prescriptionText.trim().isNotEmpty
? prescriptionText.trim() ? prescriptionText.trim()
@@ -234,13 +236,19 @@ class PrescriptionPdfService {
), ),
), ),
), ),
pw.SizedBox(height: 10),
// Línea sutil previa al pie de página
pw.Container(
height: 0.5,
color: PdfColor.fromHex('CBD5E1'),
), ),
pw.SizedBox(height: 6), pw.SizedBox(height: 5),
// 4. Pie de página con Contacto del Consultorio // 4. Pie de página con Contacto del Consultorio
if (generalContact.isNotEmpty) ...[ if (generalContact.isNotEmpty) ...[
pw.Container( pw.Container(
padding: const pw.EdgeInsets.only(top: 4), padding: const pw.EdgeInsets.only(top: 2),
child: pw.Text( child: pw.Text(
generalContact.toUpperCase(), generalContact.toUpperCase(),
textAlign: pw.TextAlign.center, textAlign: pw.TextAlign.center,
@@ -252,9 +260,8 @@ class PrescriptionPdfService {
), ),
), ),
), ),
],
pw.SizedBox(height: 3), pw.SizedBox(height: 3),
],
// Confirmación institucional // Confirmación institucional
pw.Center( pw.Center(
@@ -69,9 +69,12 @@ class DepartmentReferralPdfService {
crossAxisAlignment: pw.CrossAxisAlignment.stretch, crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [ children: [
// Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt) // Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt)
pw.Container( pw.ConstrainedBox(
height: 5.5 * PdfPageFormat.inch - 36, constraints: const pw.BoxConstraints(
maxHeight: 5.5 * PdfPageFormat.inch - 36,
),
child: pw.Column( child: pw.Column(
mainAxisSize: pw.MainAxisSize.min,
crossAxisAlignment: pw.CrossAxisAlignment.stretch, crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [ children: [
// 1. Cabecera con Nombre del Doctor y Badge Sutil de Hidalyx Med // 1. Cabecera con Nombre del Doctor y Badge Sutil de Hidalyx Med
@@ -168,9 +171,8 @@ class DepartmentReferralPdfService {
pw.SizedBox(height: 8), pw.SizedBox(height: 8),
// 2. Contenido del Referimiento (Idéntico a AlfaMedical) // 2. Contenido del Referimiento (Idéntico a AlfaMedical)
pw.Expanded( pw.Container(
child: pw.Container( padding: const pw.EdgeInsets.symmetric(vertical: 6),
padding: const pw.EdgeInsets.symmetric(vertical: 4),
child: pw.Text( child: pw.Text(
referralText.trim().isNotEmpty referralText.trim().isNotEmpty
? referralText.trim() ? referralText.trim()
@@ -183,8 +185,14 @@ class DepartmentReferralPdfService {
), ),
), ),
), ),
pw.SizedBox(height: 10),
// Línea divisoria decorativa previa al pie
pw.Container(
height: 0.5,
color: PdfColor.fromHex('CBD5E1'),
), ),
pw.SizedBox(height: 6), pw.SizedBox(height: 5),
// 3. Pie de página con Contacto del Consultorio // 3. Pie de página con Contacto del Consultorio
if (generalContact.isNotEmpty) ...[ if (generalContact.isNotEmpty) ...[
@@ -69,9 +69,12 @@ class DoctorReferralPdfService {
crossAxisAlignment: pw.CrossAxisAlignment.stretch, crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [ children: [
// Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt) // Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt)
pw.Container( pw.ConstrainedBox(
height: 5.5 * PdfPageFormat.inch - 36, constraints: const pw.BoxConstraints(
maxHeight: 5.5 * PdfPageFormat.inch - 36,
),
child: pw.Column( child: pw.Column(
mainAxisSize: pw.MainAxisSize.min,
crossAxisAlignment: pw.CrossAxisAlignment.stretch, crossAxisAlignment: pw.CrossAxisAlignment.stretch,
children: [ children: [
// 1. Cabecera con Nombre del Doctor y Badge Sutil de Hidalyx Med // 1. Cabecera con Nombre del Doctor y Badge Sutil de Hidalyx Med
@@ -168,9 +171,8 @@ class DoctorReferralPdfService {
pw.SizedBox(height: 8), pw.SizedBox(height: 8),
// 2. Contenido del Referimiento (Idéntico a AlfaMedical con fontSize 13-14) // 2. Contenido del Referimiento (Idéntico a AlfaMedical con fontSize 13-14)
pw.Expanded( pw.Container(
child: pw.Container( padding: const pw.EdgeInsets.symmetric(vertical: 6),
padding: const pw.EdgeInsets.symmetric(vertical: 4),
child: pw.Text( child: pw.Text(
referralText.trim().isNotEmpty referralText.trim().isNotEmpty
? referralText.trim() ? referralText.trim()
@@ -183,8 +185,14 @@ class DoctorReferralPdfService {
), ),
), ),
), ),
pw.SizedBox(height: 10),
// Línea divisoria decorativa previa al pie
pw.Container(
height: 0.5,
color: PdfColor.fromHex('CBD5E1'),
), ),
pw.SizedBox(height: 6), pw.SizedBox(height: 5),
// 3. Pie de página con Contacto del Consultorio // 3. Pie de página con Contacto del Consultorio
if (generalContact.isNotEmpty) ...[ if (generalContact.isNotEmpty) ...[
+1 -2
View File
@@ -104,7 +104,7 @@ void main() {
}); });
group('PrescriptionPdfService Tests', () { group('PrescriptionPdfService Tests', () {
test('builds prescription pdf bytes with correct page format', () async { test('builds prescription pdf bytes with correct page format and layout', () async {
final bytes = await PrescriptionPdfService.buildPrescriptionPdf( final bytes = await PrescriptionPdfService.buildPrescriptionPdf(
doctorName: 'Dr. Luis A. Castro Sosa', doctorName: 'Dr. Luis A. Castro Sosa',
specialty: 'Cirujano Urólogo', specialty: 'Cirujano Urólogo',
@@ -115,7 +115,6 @@ void main() {
); );
expect(bytes, isNotEmpty); expect(bytes, isNotEmpty);
// Valid PDF magic header %PDF
expect(bytes.sublist(0, 4), equals([0x25, 0x50, 0x44, 0x46])); expect(bytes.sublist(0, 4), equals([0x25, 0x50, 0x44, 0x46]));
}); });
}); });