stampa ddt
This commit is contained in:
205
lib/features/tickets/utils/ticket_shipping_pdf_service.dart
Normal file
205
lib/features/tickets/utils/ticket_shipping_pdf_service.dart
Normal file
@@ -0,0 +1,205 @@
|
||||
import 'dart:typed_data';
|
||||
import 'package:flux/features/company/models/company_model.dart';
|
||||
import 'package:flux/features/documents/models/shipment_document_model.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_location_model.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_model.dart';
|
||||
import 'package:flux/features/tickets/models/ticket_model.dart';
|
||||
import 'package:pdf/pdf.dart';
|
||||
import 'package:pdf/widgets.dart' as pw;
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class TicketShippingPdfService {
|
||||
static Future<Uint8List> generateDdt({
|
||||
required CompanyModel company,
|
||||
required ProviderModel provider,
|
||||
required ProviderLocationModel location,
|
||||
required ShipmentDocumentModel document,
|
||||
required List<TicketModel> tickets,
|
||||
}) async {
|
||||
final pdf = pw.Document();
|
||||
|
||||
// Formattatore per le date
|
||||
final dateFormat = DateFormat('dd/MM/yyyy');
|
||||
|
||||
pdf.addPage(
|
||||
pw.MultiPage(
|
||||
pageFormat: PdfPageFormat.a4,
|
||||
margin: const pw.EdgeInsets.all(32),
|
||||
// --- INTESTAZIONE (Ripetuta su ogni pagina) ---
|
||||
header: (pw.Context context) {
|
||||
return pw.Column(
|
||||
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||
children: [
|
||||
pw.Row(
|
||||
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Dati Mittente (La tua Company)
|
||||
pw.Expanded(
|
||||
child: pw.Column(
|
||||
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||
children: [
|
||||
pw.Text(
|
||||
company.name,
|
||||
style: pw.TextStyle(
|
||||
fontWeight: pw.FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
pw.Text(company.address),
|
||||
pw.Text(
|
||||
'${company.city} (${company.province}) - ${company.zipCode}',
|
||||
),
|
||||
pw.Text('P.IVA: ${company.vatId}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Dati Destinatario (Il Laboratorio e la Sede)
|
||||
pw.Expanded(
|
||||
child: pw.Container(
|
||||
padding: const pw.EdgeInsets.all(8),
|
||||
decoration: pw.BoxDecoration(
|
||||
border: pw.Border.all(color: PdfColors.grey),
|
||||
borderRadius: const pw.BorderRadius.all(
|
||||
pw.Radius.circular(4),
|
||||
),
|
||||
),
|
||||
child: pw.Column(
|
||||
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||
children: [
|
||||
pw.Text(
|
||||
'DESTINATARIO:',
|
||||
style: pw.TextStyle(
|
||||
fontSize: 10,
|
||||
color: PdfColors.grey700,
|
||||
),
|
||||
),
|
||||
pw.Text(
|
||||
provider.name,
|
||||
style: pw.TextStyle(fontWeight: pw.FontWeight.bold),
|
||||
),
|
||||
pw.SizedBox(height: 4),
|
||||
pw.Text('Destinazione merce:'),
|
||||
pw.Text(location.address),
|
||||
pw.Text(
|
||||
'${location.zipCode} ${location.city} (${location.province})',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
pw.SizedBox(height: 20),
|
||||
// Titolo Documento
|
||||
pw.Center(
|
||||
child: pw.Text(
|
||||
'DOCUMENTO DI TRASPORTO (D.D.T.)',
|
||||
style: pw.TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: pw.FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
pw.SizedBox(height: 10),
|
||||
// Dati Documento
|
||||
pw.Row(
|
||||
mainAxisAlignment: pw.MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
pw.Text(
|
||||
'Numero: ${document.docNumber}',
|
||||
style: pw.TextStyle(fontWeight: pw.FontWeight.bold),
|
||||
),
|
||||
pw.Text(
|
||||
'Data: ${dateFormat.format(document.docDate)}',
|
||||
style: pw.TextStyle(fontWeight: pw.FontWeight.bold),
|
||||
),
|
||||
pw.Text('Causale: ${document.shippingReason}'),
|
||||
],
|
||||
),
|
||||
pw.SizedBox(height: 20),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
||||
// --- IL CORPO (La tabella dei ticket che scorre) ---
|
||||
build: (pw.Context context) {
|
||||
return [
|
||||
pw.TableHelper.fromTextArray(
|
||||
headers: ['Rif. Ticket', 'Modello', 'Difetto / Note', 'Q.tà'],
|
||||
headerStyle: pw.TextStyle(
|
||||
fontWeight: pw.FontWeight.bold,
|
||||
color: PdfColors.white,
|
||||
),
|
||||
headerDecoration: const pw.BoxDecoration(
|
||||
color: PdfColors.blueGrey800,
|
||||
),
|
||||
cellAlignment: pw.Alignment.centerLeft,
|
||||
data: tickets.map((t) {
|
||||
return [
|
||||
t.id?.substring(0, 8).toUpperCase() ??
|
||||
'-', // Magari hai un ID progressivo migliore
|
||||
t.targetModelName ?? 'Sconosciuto',
|
||||
t.request,
|
||||
'1', // Tipicamente 1 per ogni ticket
|
||||
];
|
||||
}).toList(),
|
||||
),
|
||||
];
|
||||
},
|
||||
|
||||
// --- PIÈ DI PAGINA (Ripetuto su ogni pagina, ma con le firme) ---
|
||||
footer: (pw.Context context) {
|
||||
return pw.Column(
|
||||
children: [
|
||||
pw.Divider(),
|
||||
pw.Row(
|
||||
mainAxisAlignment: pw.MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
pw.Text('Colli: ${document.packageCount}'),
|
||||
pw.Text('Peso: ${document.weight ?? '-'} Kg'),
|
||||
pw.Text(
|
||||
'Aspetto: ${document.notes ?? 'Scatola'}',
|
||||
), // Adatta se hai un campo specifico
|
||||
],
|
||||
),
|
||||
pw.SizedBox(height: 20),
|
||||
// Spazio Firme
|
||||
pw.Row(
|
||||
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_buildSignatureBox('Firma Mittente'),
|
||||
_buildSignatureBox('Firma Vettore (Corriere)'),
|
||||
_buildSignatureBox('Firma Destinatario'),
|
||||
],
|
||||
),
|
||||
pw.SizedBox(height: 10),
|
||||
pw.Align(
|
||||
alignment: pw.Alignment.centerRight,
|
||||
child: pw.Text(
|
||||
'Pagina ${context.pageNumber} di ${context.pagesCount}',
|
||||
style: const pw.TextStyle(
|
||||
fontSize: 10,
|
||||
color: PdfColors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
return pdf.save();
|
||||
}
|
||||
|
||||
static pw.Widget _buildSignatureBox(String title) {
|
||||
return pw.Column(
|
||||
children: [
|
||||
pw.Text(title, style: const pw.TextStyle(fontSize: 10)),
|
||||
pw.SizedBox(height: 40),
|
||||
pw.Container(width: 120, height: 1, color: PdfColors.black),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user