fix(pdf): make footer and all content stay compact and strictly within half-sheet area
This commit is contained in:
@@ -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,10 +210,10 @@ 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(
|
||||||
text: pw.TextSpan(
|
text: pw.TextSpan(
|
||||||
@@ -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,28 +222,33 @@ 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()
|
: 'Sin prescripciones anotadas.',
|
||||||
: 'Sin prescripciones anotadas.',
|
style: pw.TextStyle(
|
||||||
style: pw.TextStyle(
|
font: regular,
|
||||||
font: regular,
|
fontSize: 10,
|
||||||
fontSize: 10,
|
lineSpacing: 3,
|
||||||
lineSpacing: 3,
|
color: PdfColor.fromHex('1E293B'),
|
||||||
color: PdfColor.fromHex('1E293B'),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
pw.SizedBox(height: 6),
|
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: 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,10 +260,9 @@ class PrescriptionPdfService {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
pw.SizedBox(height: 3),
|
||||||
],
|
],
|
||||||
|
|
||||||
pw.SizedBox(height: 3),
|
|
||||||
|
|
||||||
// Confirmación institucional
|
// Confirmación institucional
|
||||||
pw.Center(
|
pw.Center(
|
||||||
child: pw.Text(
|
child: pw.Text(
|
||||||
|
|||||||
@@ -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,23 +171,28 @@ 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()
|
: 'Sin detalles de referimiento.',
|
||||||
: 'Sin detalles de referimiento.',
|
style: pw.TextStyle(
|
||||||
style: pw.TextStyle(
|
font: regular,
|
||||||
font: regular,
|
fontSize: 10.5,
|
||||||
fontSize: 10.5,
|
lineSpacing: 3.5,
|
||||||
lineSpacing: 3.5,
|
color: PdfColor.fromHex('1E293B'),
|
||||||
color: PdfColor.fromHex('1E293B'),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
pw.SizedBox(height: 6),
|
pw.SizedBox(height: 10),
|
||||||
|
|
||||||
|
// Línea divisoria decorativa previa al pie
|
||||||
|
pw.Container(
|
||||||
|
height: 0.5,
|
||||||
|
color: PdfColor.fromHex('CBD5E1'),
|
||||||
|
),
|
||||||
|
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,23 +171,28 @@ 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()
|
: 'Sin detalles de referimiento.',
|
||||||
: 'Sin detalles de referimiento.',
|
style: pw.TextStyle(
|
||||||
style: pw.TextStyle(
|
font: regular,
|
||||||
font: regular,
|
fontSize: 10.5,
|
||||||
fontSize: 10.5,
|
lineSpacing: 3.5,
|
||||||
lineSpacing: 3.5,
|
color: PdfColor.fromHex('1E293B'),
|
||||||
color: PdfColor.fromHex('1E293B'),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
pw.SizedBox(height: 6),
|
pw.SizedBox(height: 10),
|
||||||
|
|
||||||
|
// Línea divisoria decorativa previa al pie
|
||||||
|
pw.Container(
|
||||||
|
height: 0.5,
|
||||||
|
color: PdfColor.fromHex('CBD5E1'),
|
||||||
|
),
|
||||||
|
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) ...[
|
||||||
|
|||||||
@@ -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]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user