venta_ticket.dart 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. final spelling = SpellingNumber(lang: 'es');
  36. String totalEnLetras = toTitleCase(spelling.convert(totalNoCancelados));
  37. final numberFormat = NumberFormat('#,##0.00', 'en_US');
  38. String formattedTotalNoCancelados = numberFormat.format(totalNoCancelados);
  39. String formattedTotalCancelados = numberFormat.format(totalCancelados);
  40. String formattedTotalEfectivo = numberFormat.format(totalEfectivo);
  41. String formattedTotalTarjeta = numberFormat.format(totalTarjeta);
  42. String formattedTotalTransferencia =
  43. numberFormat.format(totalTransferencia);
  44. int centavos =
  45. ((totalNoCancelados - totalNoCancelados.floor()) * 100).round();
  46. String centavosEnLetras = centavos.toString().padLeft(2, '0') + "/100 M.N.";
  47. print("Total en letras: $totalEnLetras $centavosEnLetras");
  48. print("Total formateado: $formattedTotalNoCancelados");
  49. pdf.addPage(pw.Page(
  50. pageFormat: PdfPageFormat.roll57,
  51. build: (pw.Context context) {
  52. return pw.Column(
  53. crossAxisAlignment: pw.CrossAxisAlignment.start,
  54. children: [
  55. pw.Padding(
  56. padding: pw.EdgeInsets.only(bottom: 10),
  57. child: pw.Text('Pedidos del día: $formattedDate',
  58. style: pw.TextStyle(
  59. fontWeight: pw.FontWeight.bold, fontSize: 12)),
  60. ),
  61. pw.Padding(
  62. padding: const pw.EdgeInsets.only(right: 15),
  63. child: pw.Text("Pedidos Completados:",
  64. style: pw.TextStyle(
  65. fontWeight: pw.FontWeight.bold, fontSize: 10)),
  66. ),
  67. ...pedidosNoCancelados.map((pedido) {
  68. return pw.Padding(
  69. padding: const pw.EdgeInsets.only(right: 15),
  70. child: pw.Row(
  71. mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
  72. children: [
  73. pw.Text("Folio: ${pedido.folio}",
  74. style: pw.TextStyle(fontSize: 10)),
  75. pw.Text("\$${pedido.totalPedido?.toStringAsFixed(2)}",
  76. style: pw.TextStyle(fontSize: 10)),
  77. ],
  78. ),
  79. );
  80. }).toList(),
  81. pw.Divider(),
  82. pw.Padding(
  83. padding: const pw.EdgeInsets.only(right: 15),
  84. child: pw.Column(
  85. crossAxisAlignment: pw.CrossAxisAlignment.start,
  86. children: [
  87. pw.Text("- Total en Efectivo: \$${formattedTotalEfectivo}",
  88. style: pw.TextStyle(
  89. fontWeight: pw.FontWeight.bold, fontSize: 11)),
  90. pw.Text("- Total en Tarjeta: \$${formattedTotalTarjeta}",
  91. style: pw.TextStyle(
  92. fontWeight: pw.FontWeight.bold, fontSize: 11)),
  93. pw.Text(
  94. "- Total en Transferencia: \$${formattedTotalTransferencia}",
  95. style: pw.TextStyle(
  96. fontWeight: pw.FontWeight.bold, fontSize: 11)),
  97. pw.Text("- Total General: \$${formattedTotalNoCancelados}",
  98. style: pw.TextStyle(
  99. fontWeight: pw.FontWeight.bold, fontSize: 11)),
  100. pw.Text("Son: $totalEnLetras Pesos $centavosEnLetras",
  101. style: pw.TextStyle(fontSize: 10))
  102. ],
  103. ),
  104. ),
  105. pw.SizedBox(height: 10),
  106. if (pedidosCancelados.isNotEmpty) ...[
  107. pw.Padding(
  108. padding: const pw.EdgeInsets.only(right: 15),
  109. child: pw.Text("Pedidos Cancelados:",
  110. style: pw.TextStyle(
  111. fontWeight: pw.FontWeight.bold, fontSize: 10)),
  112. ),
  113. ...pedidosCancelados.map((pedido) {
  114. return pw.Padding(
  115. padding: const pw.EdgeInsets.only(right: 15),
  116. child: pw.Row(
  117. mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
  118. children: [
  119. pw.Text("Folio: ${pedido.folio} (Cancelado)",
  120. style: pw.TextStyle(fontSize: 10)),
  121. pw.Text("\$${pedido.totalPedido?.toStringAsFixed(2)}",
  122. style: pw.TextStyle(fontSize: 10)),
  123. ],
  124. ),
  125. );
  126. }).toList(),
  127. pw.Divider(),
  128. pw.Padding(
  129. padding: const pw.EdgeInsets.only(right: 15),
  130. child: pw.Text(
  131. "- Total Cancelados: \$${formattedTotalCancelados}",
  132. style: pw.TextStyle(
  133. fontWeight: pw.FontWeight.bold, fontSize: 11)),
  134. ),
  135. ],
  136. pw.SizedBox(height: 40),
  137. pw.Text('.', style: pw.TextStyle(fontSize: 1)),
  138. ],
  139. );
  140. }));
  141. await Printing.layoutPdf(
  142. onLayout: (PdfPageFormat format) async => pdf.save());
  143. }
  144. }