final commit 07082025 itrimobe
This commit is contained in:
parent
b455feca42
commit
5218acb5aa
@ -13,6 +13,8 @@ import 'package:itrimobe/services/pdf_service.dart';
|
||||
import '../layouts/main_layout.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../services/pdf_impression_commande.dart';
|
||||
import 'commandes_screen.dart';
|
||||
import 'information.dart';
|
||||
|
||||
class CartPage extends StatefulWidget {
|
||||
@ -203,8 +205,10 @@ class _CartPageState extends State<CartPage> {
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
// Succès
|
||||
final commandeData = jsonDecode(response.body);
|
||||
final order = Order.fromJson(commandeData['data']);
|
||||
_updateTableStatus();
|
||||
_showSuccessDialog();
|
||||
_showSuccessDialog(order);
|
||||
} else {
|
||||
// Erreur
|
||||
_showErrorDialog(
|
||||
@ -232,7 +236,7 @@ class _CartPageState extends State<CartPage> {
|
||||
}
|
||||
|
||||
// FONCTION CORRIGÉE POUR LA NAVIGATION VERS LES TABLES
|
||||
void _showSuccessDialog() {
|
||||
void _showSuccessDialog(Order order) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
@ -251,6 +255,7 @@ class _CartPageState extends State<CartPage> {
|
||||
actions: [
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
printOrderPDF(order);
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder:
|
||||
|
||||
@ -5,6 +5,7 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'commande_item_screen.dart';
|
||||
import '../services/pdf_impression_commande.dart';
|
||||
|
||||
class OrdersManagementScreen extends StatefulWidget {
|
||||
const OrdersManagementScreen({super.key});
|
||||
@ -591,40 +592,67 @@ class OrderCard extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Header row
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: onViewDetails,
|
||||
child: Text(
|
||||
'${order.tablename}',
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
// ← Nom de la table
|
||||
GestureDetector(
|
||||
onTap: onViewDetails,
|
||||
child: Text(
|
||||
'${order.tablename}',
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: _getStatusColor(order.statut),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Text(
|
||||
_getStatusText(order.statut),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
|
||||
// → Groupe à droite : bouton + statut
|
||||
Row(
|
||||
children: [
|
||||
// ← Bouton imprimer
|
||||
ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
printOrderPDF(order);
|
||||
},
|
||||
icon: const Icon(Icons.print, color: Colors.white, size: 16),
|
||||
label: const Text(
|
||||
'Imprimer',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.indigo,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(width: 8),
|
||||
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: _getStatusColor(order.statut),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Text(
|
||||
_getStatusText(order.statut),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 8),
|
||||
|
||||
// Time and details
|
||||
|
||||
77
lib/services/pdf_impression_commande.dart
Normal file
77
lib/services/pdf_impression_commande.dart
Normal file
@ -0,0 +1,77 @@
|
||||
import 'package:pdf/widgets.dart' as pw;
|
||||
import 'package:pdf/pdf.dart';
|
||||
import 'package:printing/printing.dart';
|
||||
import '../pages/commandes_screen.dart';
|
||||
Future<void> printOrderPDF(Order order) async {
|
||||
|
||||
String _formatTime(DateTime dateTime) {
|
||||
return '${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')} ${dateTime.day.toString().padLeft(2, '0')}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.year}';
|
||||
}
|
||||
final pdf = pw.Document();
|
||||
|
||||
final pageFormat = PdfPageFormat(
|
||||
204.1, // 72 mm imprimable
|
||||
595.0, // 210 mm
|
||||
marginAll: 0,
|
||||
);
|
||||
|
||||
pdf.addPage(
|
||||
pw.Page(
|
||||
pageFormat: pageFormat,
|
||||
build: (pw.Context context) {
|
||||
return pw.Padding(
|
||||
padding: const pw.EdgeInsets.fromLTRB(6, 6, 6, 18),
|
||||
child: pw.Column(
|
||||
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||
children: [
|
||||
pw.Divider(),
|
||||
pw.Text('Commande n° ${order.numeroCommande}', style: pw.TextStyle(fontSize: 10, fontWeight: pw.FontWeight.bold)),
|
||||
pw.Text('Table: ${order.tablename}', style: pw.TextStyle(fontSize: 8)),
|
||||
pw.Text('Date: ${_formatTime(order.dateCommande)}', style: pw.TextStyle(fontSize: 8)),
|
||||
pw.SizedBox(height: 8),
|
||||
pw.Divider(),
|
||||
pw.SizedBox(height: 8),
|
||||
pw.Row(
|
||||
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
pw.Text('Désignation', style: pw.TextStyle(fontSize: 9, fontWeight: pw.FontWeight.bold)),
|
||||
pw.Text('Cocher', style: pw.TextStyle(fontSize: 9)),
|
||||
],
|
||||
),
|
||||
pw.SizedBox(height: 8),
|
||||
pw.Divider(),
|
||||
...order.items.map(
|
||||
(item) => pw.Row(
|
||||
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
pw.Container(
|
||||
width: 120,
|
||||
child: pw.Text(
|
||||
'${item.quantite} x ${item.nom ?? 'Item'}',
|
||||
style: pw.TextStyle(fontSize: 8),
|
||||
),
|
||||
),
|
||||
pw.Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: pw.BoxDecoration(
|
||||
border: pw.Border.all(width: 1),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
pw.Divider(),
|
||||
pw.Spacer(),
|
||||
pw.SizedBox(height: 10), // marge visible en bas
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
await Printing.layoutPdf(
|
||||
onLayout: (PdfPageFormat format) async => pdf.save(),
|
||||
);
|
||||
}
|
||||
@ -96,6 +96,7 @@ final restaurantContent = template.content ?? 'Adresse inconnue';
|
||||
// TITRE CENTRÉ
|
||||
pw.Container(
|
||||
width: double.infinity,
|
||||
margin: const pw.EdgeInsets.only(right: 20),
|
||||
child: pw.Text(
|
||||
restauranTitle,
|
||||
style: pw.TextStyle(
|
||||
@ -110,11 +111,11 @@ final restaurantContent = template.content ?? 'Adresse inconnue';
|
||||
|
||||
pw.Container(
|
||||
width: double.infinity,
|
||||
margin: const pw.EdgeInsets.only(right: 2),
|
||||
margin: const pw.EdgeInsets.only(right: 20),
|
||||
child: pw.Text(
|
||||
formatTemplateContent(restaurantContent),
|
||||
style: pw.TextStyle(fontSize: smallSize),
|
||||
textAlign: pw.TextAlign.left,
|
||||
textAlign: pw.TextAlign.center,
|
||||
),
|
||||
),
|
||||
pw.SizedBox(height: 2),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user