venta_ticket.dart 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import 'package:intl/intl.dart';
  2. import 'package:pdf/pdf.dart';
  3. import 'package:pdf/widgets.dart' as pw;
  4. import 'package:printing/printing.dart';
  5. import '../../models/models.dart';
  6. import 'package:spelling_number/spelling_number.dart';
  7. String toTitleCase(String text) {
  8. if (text.isEmpty) return text;
  9. return text.split(' ').map((word) {
  10. if (word.isNotEmpty) {
  11. return word[0].toUpperCase() + word.substring(1).toLowerCase();
  12. }
  13. return '';
  14. }).join(' ');
  15. }
  16. class VentaTicket {
  17. static Future<void> imprimirResumenPedidos(
  18. List<Pedido> pedidosDelDia, DateTime fecha) async {
  19. final pdf = pw.Document();
  20. String formattedDate = DateFormat('dd-MM-yyyy').format(fecha);
  21. final pedidosNoCancelados =
  22. pedidosDelDia.where((p) => p.estatus != "CANCELADO").toList();
  23. final pedidosCancelados =
  24. pedidosDelDia.where((p) => p.estatus == "CANCELADO").toList();
  25. double totalNoCancelados =
  26. pedidosNoCancelados.fold(0, (sum, p) => sum + (p.totalPedido ?? 0));
  27. double totalCancelados =
  28. pedidosCancelados.fold(0, (sum, p) => sum + (p.totalPedido ?? 0));
  29. double totalEfectivo = pedidosNoCancelados.fold(
  30. 0.0, (sum, p) => sum + (p.cantEfectivo ?? 0.0));
  31. double totalTarjeta =
  32. pedidosNoCancelados.fold(0.0, (sum, p) => sum + (p.cantTarjeta ?? 0.0));
  33. double totalTransferencia = pedidosNoCancelados.fold(
  34. 0.0, (sum, p) => sum + (p.cantTransferencia ?? 0.0));
  35. double totalSinCambio = totalEfectivo + totalTarjeta + totalTransferencia;
  36. double cambio = totalSinCambio - totalNoCancelados;
  37. final spelling = SpellingNumber(lang: 'es');
  38. String totalEnLetras = toTitleCase(spelling.convert(totalNoCancelados));
  39. final numberFormat = NumberFormat('#,##0.00', 'en_US');
  40. String formattedTotalNoCancelados = numberFormat.format(totalNoCancelados);
  41. String formattedTotalCancelados = numberFormat.format(totalCancelados);
  42. String formattedTotalEfectivo = numberFormat.format(totalEfectivo);
  43. String formattedTotalTarjeta = numberFormat.format(totalTarjeta);
  44. String formattedTotalTransferencia =
  45. numberFormat.format(totalTransferencia);
  46. String formattedCambio = numberFormat.format(cambio);
  47. int centavos =
  48. ((totalNoCancelados - totalNoCancelados.floor()) * 100).round();
  49. String centavosEnLetras = centavos.toString().padLeft(2, '0') + "/100 M.N.";
  50. pdf.addPage(pw.Page(
  51. pageFormat: PdfPageFormat.roll57,
  52. build: (pw.Context context) {
  53. return pw.Column(
  54. crossAxisAlignment: pw.CrossAxisAlignment.start,
  55. children: [
  56. pw.Padding(
  57. padding: pw.EdgeInsets.only(bottom: 10),
  58. child: pw.Text('Pedidos del día: $formattedDate',
  59. style: pw.TextStyle(
  60. fontWeight: pw.FontWeight.bold, fontSize: 12)),
  61. ),
  62. pw.Padding(
  63. padding: const pw.EdgeInsets.only(right: 15),
  64. child: pw.Text("Pedidos Completados:",
  65. style: pw.TextStyle(
  66. fontWeight: pw.FontWeight.bold, fontSize: 10)),
  67. ),
  68. ...pedidosNoCancelados.map((pedido) {
  69. return pw.Padding(
  70. padding: const pw.EdgeInsets.only(right: 15),
  71. child: pw.Row(
  72. mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
  73. children: [
  74. pw.Text("Folio: ${pedido.folio}",
  75. style: pw.TextStyle(fontSize: 10)),
  76. pw.Text("\$${pedido.totalPedido?.toStringAsFixed(2)}",
  77. style: pw.TextStyle(fontSize: 10)),
  78. ],
  79. ),
  80. );
  81. }).toList(),
  82. pw.Divider(),
  83. pw.Padding(
  84. padding: const pw.EdgeInsets.only(right: 15),
  85. child: pw.Column(
  86. crossAxisAlignment: pw.CrossAxisAlignment.start,
  87. children: [
  88. if (totalTarjeta > 0)
  89. pw.Text("- Total en Tarjeta: \$${formattedTotalTarjeta}",
  90. style: pw.TextStyle(
  91. fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
  92. if (totalTransferencia > 0)
  93. pw.Text(
  94. "- Total en Transferencia: \$${formattedTotalTransferencia}",
  95. style: pw.TextStyle(
  96. fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
  97. if (totalEfectivo > 0)
  98. pw.Text(
  99. "- Total en Efectivo: \$${formattedTotalEfectivo}",
  100. style: pw.TextStyle(
  101. fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
  102. if (cambio > 0)
  103. pw.Text("- Cambio Entregado: \$${formattedCambio}",
  104. style: pw.TextStyle(
  105. fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
  106. pw.Text("- Total General: \$${formattedTotalNoCancelados}",
  107. style: pw.TextStyle(
  108. fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
  109. pw.Text("Son: $totalEnLetras Pesos $centavosEnLetras",
  110. style: pw.TextStyle(fontSize: 10))
  111. ],
  112. ),
  113. ),
  114. pw.SizedBox(height: 10),
  115. if (pedidosCancelados.isNotEmpty) ...[
  116. pw.Padding(
  117. padding: const pw.EdgeInsets.only(right: 15),
  118. child: pw.Text("Pedidos Cancelados:",
  119. style: pw.TextStyle(
  120. fontWeight: pw.FontWeight.bold, fontSize: 10)),
  121. ),
  122. ...pedidosCancelados.map((pedido) {
  123. return pw.Padding(
  124. padding: const pw.EdgeInsets.only(right: 15),
  125. child: pw.Row(
  126. mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
  127. children: [
  128. pw.Text("Folio: ${pedido.folio} (Cancelado)",
  129. style: pw.TextStyle(fontSize: 10)),
  130. pw.Text("\$${pedido.totalPedido?.toStringAsFixed(2)}",
  131. style: pw.TextStyle(fontSize: 10)),
  132. ],
  133. ),
  134. );
  135. }).toList(),
  136. pw.Divider(),
  137. pw.Padding(
  138. padding: const pw.EdgeInsets.only(right: 15),
  139. child: pw.Text(
  140. "- Total Cancelados: \$${formattedTotalCancelados}",
  141. style: pw.TextStyle(
  142. fontWeight: pw.FontWeight.bold, fontSize: 11)),
  143. ),
  144. ],
  145. pw.SizedBox(height: 40),
  146. pw.Text('.', style: pw.TextStyle(fontSize: 1)),
  147. ],
  148. );
  149. }));
  150. await Printing.layoutPdf(
  151. onLayout: (PdfPageFormat format) async => pdf.save());
  152. }
  153. }