You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
372 lines
12 KiB
372 lines
12 KiB
import 'dart:io';
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:open_file/open_file.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
import 'package:pdf/pdf.dart';
|
|
import 'package:pdf/widgets.dart' as pw;
|
|
|
|
import '../Components/cartItem.dart';
|
|
import '../accueil.dart';
|
|
|
|
class TicketPage extends StatelessWidget {
|
|
final String businessName;
|
|
final String businessAddress;
|
|
final String businessPhoneNumber;
|
|
final List<CartItem> cartItems;
|
|
final double totalCartPrice;
|
|
final double amountPaid;
|
|
|
|
const TicketPage({
|
|
Key? key,
|
|
required this.businessName,
|
|
required this.businessAddress,
|
|
required this.businessPhoneNumber,
|
|
required this.cartItems,
|
|
required this.totalCartPrice,
|
|
required this.amountPaid,
|
|
}) : super(key: key);
|
|
|
|
|
|
Future<void> _generateAndSavePDF() async {
|
|
final pdf = pw.Document();
|
|
|
|
// Ajoutez le contenu de votre ticket au document ici
|
|
pdf.addPage(
|
|
pw.Page(
|
|
build: (context) {
|
|
return pw.Column(
|
|
children: [
|
|
pw.Text('Ticket de caisse',
|
|
style: const pw.TextStyle(fontSize: 24)),
|
|
pw.SizedBox(height: 16),
|
|
pw.Text('Entreprise : $businessName',
|
|
style: const pw.TextStyle(fontSize: 18)),
|
|
pw.SizedBox(height: 8),
|
|
pw.Text('Adresse : $businessAddress',
|
|
style: const pw.TextStyle(fontSize: 16)),
|
|
pw.SizedBox(height: 8),
|
|
pw.Text('Numéro de téléphone : $businessPhoneNumber',
|
|
style: const pw.TextStyle(fontSize: 16)),
|
|
pw.SizedBox(height: 24),
|
|
pw.Table.fromTextArray(
|
|
border: null,
|
|
headerStyle: pw.TextStyle(fontWeight: pw.FontWeight.bold),
|
|
headerDecoration:
|
|
const pw.BoxDecoration(color: PdfColors.grey300),
|
|
headers: ['Produit', 'Quantité', 'Prix unitaire', 'Total'],
|
|
data: [
|
|
...cartItems.map((cartItem) {
|
|
final product = cartItem.product;
|
|
final quantity = cartItem.quantity;
|
|
final productTotal = product.price * quantity;
|
|
|
|
return [
|
|
product.name,
|
|
quantity.toString(),
|
|
'${product.price.toStringAsFixed(2)} MGA',
|
|
'${productTotal.toStringAsFixed(2)} MGA',
|
|
];
|
|
}).toList(),
|
|
],
|
|
),
|
|
pw.SizedBox(height: 16),
|
|
pw.Divider(height: 8, thickness: 1, color: PdfColors.black),
|
|
pw.SizedBox(height: 8),
|
|
pw.Row(
|
|
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
pw.Text('Total :',
|
|
style: pw.TextStyle(
|
|
fontSize: 18, fontWeight: pw.FontWeight.bold)),
|
|
pw.Text('${totalCartPrice.toStringAsFixed(2)} MGA',
|
|
style: pw.TextStyle(
|
|
fontSize: 18, fontWeight: pw.FontWeight.bold)),
|
|
],
|
|
),
|
|
pw.SizedBox(height: 8),
|
|
pw.Divider(height: 8, thickness: 0, color: PdfColors.black),
|
|
pw.SizedBox(height: 8),
|
|
pw.Row(
|
|
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
pw.Text('Somme remise :',
|
|
style: const pw.TextStyle(fontSize: 16)),
|
|
pw.Text('${amountPaid.toStringAsFixed(2)} MGA',
|
|
style: const pw.TextStyle(fontSize: 16)),
|
|
],
|
|
),
|
|
pw.SizedBox(height: 8),
|
|
pw.Row(
|
|
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
pw.Text('Somme rendue :',
|
|
style: const pw.TextStyle(fontSize: 16)),
|
|
pw.Text(
|
|
'${(amountPaid - totalCartPrice).toStringAsFixed(2)} MGA',
|
|
style: const pw.TextStyle(fontSize: 16)),
|
|
],
|
|
),
|
|
pw.SizedBox(height: 24),
|
|
pw.Text('Youmaz vous remercie pour votre achat!!!',
|
|
style: pw.TextStyle(
|
|
fontSize: 18, fontWeight: pw.FontWeight.bold)),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
|
|
// Obtenez le répertoire de documents de l'utilisateur
|
|
final directory = await getApplicationDocumentsDirectory();
|
|
final path = '${directory.path}/ticket.pdf';
|
|
|
|
// Enregistrez le PDF localement
|
|
final file = File(path);
|
|
await file.writeAsBytes(await pdf.save());
|
|
|
|
// Ouvrez le PDF après l'avoir enregistré
|
|
final result = await OpenFile.open(path);
|
|
|
|
if (result.type == ResultType.done) {
|
|
Get.snackbar('Ouverture PDF', 'Ticket PDF ouvert avec succès');
|
|
} else {
|
|
Get.snackbar('Ouverture PDF', 'Impossible d\'ouvrir le PDF');
|
|
}
|
|
|
|
Get.snackbar('Enregistrement PDF', 'Ticket PDF enregistré avec succès');
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
double totalOrderAmount = 0;
|
|
|
|
// Calculer la somme totale de la commande
|
|
for (final cartItem in cartItems) {
|
|
final product = cartItem.product;
|
|
final quantity = cartItem.quantity;
|
|
final productTotal = product.price * quantity;
|
|
totalOrderAmount += productTotal;
|
|
}
|
|
|
|
// Obtenir la date actuelle
|
|
|
|
|
|
// Calculer la somme rendue
|
|
final double change = amountPaid - totalOrderAmount;
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Ticket Youmaz'),
|
|
actions: [
|
|
IconButton(
|
|
onPressed: () {
|
|
Get.to(
|
|
() => const AccueilPage()); // Naviguez vers la page d'accueil
|
|
},
|
|
icon: const Icon(Icons.home),
|
|
alignment: Alignment.centerLeft,
|
|
),
|
|
IconButton(
|
|
onPressed: _generateAndSavePDF,
|
|
icon: const Icon(Icons.print),
|
|
alignment: Alignment.centerLeft,
|
|
),
|
|
],
|
|
),
|
|
body: Center(
|
|
child: Container(
|
|
width: MediaQuery.of(context).size.width * 0.5,
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text(
|
|
'Ticket de caisse',
|
|
style: TextStyle(
|
|
fontSize: 24,
|
|
fontWeight: FontWeight.bold,
|
|
decoration: TextDecoration.underline,
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
'Entreprise : $businessName',
|
|
style: const TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
'Adresse : $businessAddress',
|
|
style: const TextStyle(fontSize: 16),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
'Numéro de téléphone : $businessPhoneNumber',
|
|
style: const TextStyle(fontSize: 16),
|
|
),
|
|
const SizedBox(height: 24),
|
|
Table(
|
|
columnWidths: const {
|
|
0: FlexColumnWidth(2),
|
|
1: FlexColumnWidth(1),
|
|
2: FlexColumnWidth(1),
|
|
3: FlexColumnWidth(1),
|
|
},
|
|
children: [
|
|
const TableRow(
|
|
children: [
|
|
TableCell(
|
|
child: Text(
|
|
'Produit',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
TableCell(
|
|
child: Center(
|
|
child: Text(
|
|
'Quantité',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
),
|
|
TableCell(
|
|
child: Center(
|
|
child: Text(
|
|
'Prix unitaire',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
),
|
|
TableCell(
|
|
child: Center(
|
|
child: Text(
|
|
'Total',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
...cartItems.map((cartItem) {
|
|
final product = cartItem.product;
|
|
final quantity = cartItem.quantity;
|
|
final productTotal = product.price * quantity;
|
|
|
|
return TableRow(
|
|
children: [
|
|
TableCell(
|
|
child: Text(product.name),
|
|
),
|
|
TableCell(
|
|
child: Center(
|
|
child: Text(quantity.toString()),
|
|
),
|
|
),
|
|
TableCell(
|
|
child: Center(
|
|
child: Text(
|
|
'${product.price.toStringAsFixed(2)} MGA',
|
|
),
|
|
),
|
|
),
|
|
TableCell(
|
|
child: Center(
|
|
child: Text(
|
|
'${productTotal.toStringAsFixed(2)} MGA',
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}).toList(),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
const Divider(
|
|
height: 8,
|
|
thickness: 1,
|
|
color: Colors.black,
|
|
),
|
|
const SizedBox(height: 8),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
const Text(
|
|
'Total :',
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
Text(
|
|
'${totalOrderAmount.toStringAsFixed(2)} MGA',
|
|
style: const TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 8),
|
|
const Divider(
|
|
height: 8,
|
|
thickness: 0,
|
|
color: Colors.black,
|
|
),
|
|
const SizedBox(height: 8),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
const Text(
|
|
'Somme remise :',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
Text(
|
|
'${amountPaid.toStringAsFixed(2)} MGA',
|
|
style: const TextStyle(
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 8),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
const Text(
|
|
'Somme rendue :',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
Text(
|
|
'${change.toStringAsFixed(2)} MGA',
|
|
style: const TextStyle(
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 24),
|
|
const Text(
|
|
'Youmaz vous remercie pour votre achat!!!',
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|