paier directement
This commit is contained in:
parent
c2cd893835
commit
e61cd760bd
@ -8,7 +8,7 @@ plugins {
|
||||
android {
|
||||
namespace = "com.example.itrimobe"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = flutter.ndkVersion
|
||||
ndkVersion = "27.0.12077973"
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
|
||||
@ -10,10 +10,21 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
|
||||
<!-- Autorisations pour HTTP non-sécurisé -->
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
|
||||
<!-- Permissions pour l'impression et les fichiers -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="28" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
|
||||
android:minSdkVersion="30" />
|
||||
|
||||
<!-- Permissions pour l'impression -->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<!-- Permissions pour Android 13+ -->
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||
|
||||
<application
|
||||
android:label="itrimobe"
|
||||
|
||||
@ -10,10 +10,10 @@ class CaisseScreen extends StatefulWidget {
|
||||
final int tableNumber;
|
||||
|
||||
const CaisseScreen({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.commandeId,
|
||||
required this.tableNumber,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
@override
|
||||
_CaisseScreenState createState() => _CaisseScreenState();
|
||||
@ -26,26 +26,26 @@ class _CaisseScreenState extends State<CaisseScreen> {
|
||||
bool isProcessingPayment = false;
|
||||
|
||||
final List<PaymentMethod> paymentMethods = [
|
||||
PaymentMethod(
|
||||
const PaymentMethod(
|
||||
id: 'mvola',
|
||||
name: 'MVola',
|
||||
description: 'Paiement mobile MVola',
|
||||
icon: Icons.phone,
|
||||
color: const Color(0xFF4285F4),
|
||||
color: Color(0xFF4285F4),
|
||||
),
|
||||
PaymentMethod(
|
||||
const PaymentMethod(
|
||||
id: 'carte',
|
||||
name: 'Carte Bancaire',
|
||||
description: 'Paiement par carte',
|
||||
icon: Icons.credit_card,
|
||||
color: const Color(0xFF28A745),
|
||||
color: Color(0xFF28A745),
|
||||
),
|
||||
PaymentMethod(
|
||||
const PaymentMethod(
|
||||
id: 'especes',
|
||||
name: 'Espèces',
|
||||
description: 'Paiement en liquide',
|
||||
icon: Icons.attach_money,
|
||||
color: const Color(0xFFFF9500),
|
||||
color: Color(0xFFFF9500),
|
||||
),
|
||||
];
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
@ -9,14 +10,16 @@ import '../layouts/main_layout.dart';
|
||||
class CartPage extends StatefulWidget {
|
||||
final int tableId;
|
||||
final int personne;
|
||||
final String? tablename;
|
||||
final List<dynamic> cartItems;
|
||||
|
||||
const CartPage({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.tableId,
|
||||
required this.personne,
|
||||
required this.cartItems,
|
||||
}) : super(key: key);
|
||||
this.tablename,
|
||||
});
|
||||
|
||||
@override
|
||||
State<CartPage> createState() => _CartPageState();
|
||||
@ -47,7 +50,7 @@ class _CartPageState extends State<CartPage> {
|
||||
nom: item['nom'] ?? 'Article',
|
||||
prix: _parsePrice(item['prix']),
|
||||
quantity: 1,
|
||||
notes: item['notes'] ?? '',
|
||||
commentaire: item['commentaire'] ?? '',
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -97,7 +100,7 @@ class _CartPageState extends State<CartPage> {
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
title: const Text(
|
||||
'Confirmer la commande',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
@ -105,9 +108,9 @@ class _CartPageState extends State<CartPage> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Êtes-vous sûr de vouloir valider cette commande ?'),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
const Text('Êtes-vous sûr de vouloir valider cette commande ?'),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
'Récapitulatif:',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
@ -123,7 +126,8 @@ class _CartPageState extends State<CartPage> {
|
||||
child: Text('Annuler', style: TextStyle(color: Colors.grey[600])),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: _isValidating
|
||||
onPressed:
|
||||
_isValidating
|
||||
? null
|
||||
: () {
|
||||
Navigator.of(context).pop();
|
||||
@ -133,8 +137,9 @@ class _CartPageState extends State<CartPage> {
|
||||
backgroundColor: Colors.green[700],
|
||||
foregroundColor: Colors.white,
|
||||
),
|
||||
child: _isValidating
|
||||
? SizedBox(
|
||||
child:
|
||||
_isValidating
|
||||
? const SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: CircularProgressIndicator(
|
||||
@ -144,7 +149,7 @@ class _CartPageState extends State<CartPage> {
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text('Valider'),
|
||||
: const Text('Valider'),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -165,12 +170,14 @@ class _CartPageState extends State<CartPage> {
|
||||
"reservation_id": 1, // Peut être null si pas de réservation
|
||||
"serveur": "Serveur par défaut", // Valeur par défaut comme demandé
|
||||
"commentaires": _getOrderComments(),
|
||||
"items": _cartItems
|
||||
"items":
|
||||
_cartItems
|
||||
.map(
|
||||
(item) => {
|
||||
"menu_id": item.id,
|
||||
"quantite": item.quantity,
|
||||
"commentaires": item.notes.isNotEmpty ? item.notes : null,
|
||||
"commentaires":
|
||||
item.commentaire.isNotEmpty ? item.commentaire : null,
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
@ -207,9 +214,10 @@ class _CartPageState extends State<CartPage> {
|
||||
|
||||
String _getOrderComments() {
|
||||
// Concaténer toutes les notes des articles pour les commentaires généraux
|
||||
List<String> allNotes = _cartItems
|
||||
.where((item) => item.notes.isNotEmpty)
|
||||
.map((item) => '${item.nom}: ${item.notes}')
|
||||
List<String> allNotes =
|
||||
_cartItems
|
||||
.where((item) => item.commentaire.isNotEmpty)
|
||||
.map((item) => '${item.nom}: ${item.commentaire}')
|
||||
.toList();
|
||||
|
||||
return allNotes.join('; ');
|
||||
@ -225,11 +233,11 @@ class _CartPageState extends State<CartPage> {
|
||||
title: Row(
|
||||
children: [
|
||||
Icon(Icons.check_circle, color: Colors.green[700]),
|
||||
SizedBox(width: 8),
|
||||
Text('Commande validée'),
|
||||
const SizedBox(width: 8),
|
||||
const Text('Commande validée'),
|
||||
],
|
||||
),
|
||||
content: Text(
|
||||
content: const Text(
|
||||
'Votre commande a été envoyée en cuisine avec succès !',
|
||||
),
|
||||
actions: [
|
||||
@ -237,12 +245,13 @@ class _CartPageState extends State<CartPage> {
|
||||
onPressed: () {
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MainLayout(child: TablesScreen()),
|
||||
builder:
|
||||
(context) => const MainLayout(child: TablesScreen()),
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
},
|
||||
child: Text('OK'),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -252,23 +261,26 @@ class _CartPageState extends State<CartPage> {
|
||||
|
||||
Future<void> _updateTableStatus() async {
|
||||
try {
|
||||
final updateResponse = await http.put(
|
||||
final _ = await http.put(
|
||||
Uri.parse(
|
||||
'https://restaurant.careeracademy.mg/api/tables/${widget.tableId}'),
|
||||
'https://restaurant.careeracademy.mg/api/tables/${widget.tableId}',
|
||||
),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json.encode({"status": "occupied"}),
|
||||
);
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print("Erreur lors de la mise à jour du statut de la table: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _showErrorDialog(String message) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Row(
|
||||
title: const Row(
|
||||
children: [
|
||||
Icon(Icons.error, color: Colors.red),
|
||||
SizedBox(width: 8),
|
||||
@ -279,7 +291,7 @@ class _CartPageState extends State<CartPage> {
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: Text('OK'),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -287,6 +299,225 @@ class _CartPageState extends State<CartPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _payerDirectement() async {
|
||||
if (_cartItems.isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Aucun article dans le panier'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculer le total
|
||||
double total = _cartItems.fold(0.0, (sum, item) {
|
||||
return sum + (item.prix * item.quantity);
|
||||
});
|
||||
|
||||
// Confirmer le paiement
|
||||
final bool? confirm = await showDialog<bool>(
|
||||
context: context,
|
||||
builder:
|
||||
(context) => AlertDialog(
|
||||
title: const Text('Confirmer le paiement'),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('${widget.tablename}'),
|
||||
const SizedBox(height: 8),
|
||||
Text('Articles: ${_cartItems.length}'),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Total: ${total.toStringAsFixed(0)} MGA',
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text('Valider et payer cette commande ?'),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
child: const Text('Annuler'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.orange[600],
|
||||
),
|
||||
child: const Text('Confirmer le paiement'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (confirm != true) return;
|
||||
|
||||
setState(() {
|
||||
_isValidating = true;
|
||||
});
|
||||
|
||||
try {
|
||||
// 1. Créer la commande avec les items du panier
|
||||
final response = await http.post(
|
||||
Uri.parse('https://restaurant.careeracademy.mg/api/commandes'),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
'table_id': widget.tableId,
|
||||
'statut': 'payee', // Directement payée
|
||||
'items':
|
||||
_cartItems
|
||||
.map(
|
||||
(item) => {
|
||||
'menu_id': item.id,
|
||||
'quantite': item.quantity,
|
||||
'prix_unitaire': item.prix,
|
||||
'commentaire': item.commentaire,
|
||||
// Pas de réservation
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
'methode_paiement': 'especes',
|
||||
'montant_paye': total,
|
||||
'date_paiement': DateTime.now().toIso8601String(),
|
||||
'client_id': 1, // Valeur par défaut
|
||||
'reservation_id': 1,
|
||||
'serveur': 'Serveur par défaut', // Valeur par défaut
|
||||
}),
|
||||
);
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
final commandeData = jsonDecode(response.body);
|
||||
|
||||
// 2. Libérer la table
|
||||
await http.patch(
|
||||
Uri.parse(
|
||||
'https://restaurant.careeracademy.mg/api/tables/${widget.tableId}',
|
||||
),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'statut': 'libre'}),
|
||||
);
|
||||
|
||||
// 3. Succès
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const MainLayout(child: TablesScreen()),
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
} else {
|
||||
throw Exception('Erreur lors du paiement');
|
||||
}
|
||||
} catch (e) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Erreur: ${e.toString()}'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
setState(() {
|
||||
_isValidating = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _showPaymentSuccessDialog(
|
||||
Map<String, dynamic> commandeData,
|
||||
double total,
|
||||
) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder:
|
||||
(context) => AlertDialog(
|
||||
title: const Row(
|
||||
children: [
|
||||
Icon(Icons.check_circle, color: Colors.green, size: 28),
|
||||
SizedBox(width: 8),
|
||||
Text('Paiement confirmé'),
|
||||
],
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text('Commande #${commandeData['numeroCommande']}'),
|
||||
const SizedBox(height: 8),
|
||||
Text('${widget.tablename} libérée'),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Montant: ${total.toStringAsFixed(2)} €',
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text('Voulez-vous imprimer un reçu ?'),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop(); // Retour au menu principal
|
||||
},
|
||||
child: const Text('Non merci'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
Navigator.of(context).pop();
|
||||
await _imprimerTicketPaiement(commandeData, total);
|
||||
Navigator.of(context).pop(); // Retour au menu principal
|
||||
},
|
||||
child: const Text('Imprimer'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _imprimerTicketPaiement(
|
||||
Map<String, dynamic> commandeData,
|
||||
double total,
|
||||
) async {
|
||||
try {
|
||||
// Préparer les données pour l'impression
|
||||
_cartItems
|
||||
.map(
|
||||
(item) => {
|
||||
'nom': item.nom,
|
||||
'quantite': item.quantity,
|
||||
'prix_unitaire': item.prix,
|
||||
'sous_total': item.prix * item.quantity,
|
||||
},
|
||||
)
|
||||
.toList();
|
||||
|
||||
// Appeler le service d'impression
|
||||
// await PlatformPrintService.printFacture(
|
||||
// commande: widget.commande,
|
||||
// paymentMethod: widget.paymentMethod,
|
||||
// );
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Ticket imprimé avec succès'),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Erreur d\'impression: ${e.toString()}'),
|
||||
backgroundColor: Colors.orange,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -296,9 +527,9 @@ class _CartPageState extends State<CartPage> {
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: Icon(Icons.arrow_back, color: Colors.black),
|
||||
icon: const Icon(Icons.arrow_back, color: Colors.black),
|
||||
),
|
||||
title: Text(
|
||||
title: const Text(
|
||||
'Panier',
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
@ -309,15 +540,16 @@ class _CartPageState extends State<CartPage> {
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(
|
||||
child: const Text(
|
||||
'Retour au menu',
|
||||
style: TextStyle(color: Colors.black, fontSize: 16),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
const SizedBox(width: 16),
|
||||
],
|
||||
),
|
||||
body: _cartItems.isEmpty
|
||||
body:
|
||||
_cartItems.isEmpty
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -327,7 +559,7 @@ class _CartPageState extends State<CartPage> {
|
||||
size: 80,
|
||||
color: Colors.grey[400],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Votre panier est vide',
|
||||
style: TextStyle(fontSize: 18, color: Colors.grey[600]),
|
||||
@ -340,10 +572,10 @@ class _CartPageState extends State<CartPage> {
|
||||
// Header avec infos table
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(20),
|
||||
padding: const EdgeInsets.all(20),
|
||||
color: Colors.white,
|
||||
child: Text(
|
||||
'Table ${widget.tableId} • ${widget.personne} personne${widget.personne > 1 ? 's' : ''}',
|
||||
'${widget.tablename} • ${widget.personne} personne${widget.personne > 1 ? 's' : ''}',
|
||||
style: TextStyle(fontSize: 16, color: Colors.grey[600]),
|
||||
),
|
||||
),
|
||||
@ -351,13 +583,14 @@ class _CartPageState extends State<CartPage> {
|
||||
// Liste des articles
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
padding: EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: _cartItems.length,
|
||||
separatorBuilder: (context, index) => SizedBox(height: 12),
|
||||
separatorBuilder:
|
||||
(context, index) => const SizedBox(height: 12),
|
||||
itemBuilder: (context, index) {
|
||||
final item = _cartItems[index];
|
||||
return Container(
|
||||
padding: EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@ -365,7 +598,7 @@ class _CartPageState extends State<CartPage> {
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -373,12 +606,13 @@ class _CartPageState extends State<CartPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
item.nom,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@ -386,11 +620,11 @@ class _CartPageState extends State<CartPage> {
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => _removeItem(index),
|
||||
icon: Icon(
|
||||
icon: const Icon(
|
||||
Icons.delete_outline,
|
||||
color: Colors.red,
|
||||
),
|
||||
constraints: BoxConstraints(),
|
||||
constraints: const BoxConstraints(),
|
||||
padding: EdgeInsets.zero,
|
||||
),
|
||||
],
|
||||
@ -402,10 +636,10 @@ class _CartPageState extends State<CartPage> {
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
if (item.notes.isNotEmpty) ...[
|
||||
SizedBox(height: 8),
|
||||
if (item.commentaire.isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Notes: ${item.notes}',
|
||||
'Notes: ${item.commentaire}',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600],
|
||||
@ -413,42 +647,45 @@ class _CartPageState extends State<CartPage> {
|
||||
),
|
||||
),
|
||||
],
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// Contrôles de quantité
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () => _updateQuantity(
|
||||
onPressed:
|
||||
() => _updateQuantity(
|
||||
index,
|
||||
item.quantity - 1,
|
||||
),
|
||||
icon: Icon(Icons.remove),
|
||||
icon: const Icon(Icons.remove),
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: Colors.grey[200],
|
||||
minimumSize: Size(40, 40),
|
||||
minimumSize: const Size(40, 40),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
item.quantity.toString(),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
const SizedBox(width: 16),
|
||||
IconButton(
|
||||
onPressed: () => _updateQuantity(
|
||||
onPressed:
|
||||
() => _updateQuantity(
|
||||
index,
|
||||
item.quantity + 1,
|
||||
),
|
||||
icon: Icon(Icons.add),
|
||||
icon: const Icon(Icons.add),
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: Colors.grey[200],
|
||||
minimumSize: Size(40, 40),
|
||||
minimumSize: const Size(40, 40),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -473,7 +710,7 @@ class _CartPageState extends State<CartPage> {
|
||||
|
||||
// Récapitulatif
|
||||
Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(top: BorderSide(color: Colors.grey[200]!)),
|
||||
@ -481,53 +718,62 @@ class _CartPageState extends State<CartPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
const Text(
|
||||
'Récapitulatif',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Articles:', style: TextStyle(fontSize: 16)),
|
||||
const Text(
|
||||
'Articles:',
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
Text(
|
||||
_getTotalArticles().toString(),
|
||||
style: TextStyle(fontSize: 16),
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Table:', style: TextStyle(fontSize: 16)),
|
||||
const Text(
|
||||
'Table:',
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
Text(
|
||||
widget.tableId.toString(),
|
||||
style: TextStyle(fontSize: 16),
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Personnes:', style: TextStyle(fontSize: 16)),
|
||||
const Text(
|
||||
'Personnes:',
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
Text(
|
||||
widget.personne.toString(),
|
||||
style: TextStyle(fontSize: 16),
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Divider(),
|
||||
SizedBox(height: 8),
|
||||
const SizedBox(height: 16),
|
||||
const Divider(),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
const Text(
|
||||
'Total:',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
@ -536,24 +782,25 @@ class _CartPageState extends State<CartPage> {
|
||||
),
|
||||
Text(
|
||||
'${_calculateTotal().toStringAsFixed(2)} MGA',
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
const SizedBox(height: 20),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: _cartItems.isNotEmpty && !_isValidating
|
||||
onPressed:
|
||||
_cartItems.isNotEmpty && !_isValidating
|
||||
? _showConfirmationDialog
|
||||
: null,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.green[700],
|
||||
foregroundColor: Colors.white,
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
@ -563,7 +810,7 @@ class _CartPageState extends State<CartPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (_isValidating) ...[
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
@ -573,8 +820,8 @@ class _CartPageState extends State<CartPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Validation en cours...',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
@ -582,9 +829,9 @@ class _CartPageState extends State<CartPage> {
|
||||
),
|
||||
),
|
||||
] else ...[
|
||||
Icon(Icons.check, size: 20),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
const Icon(Icons.check, size: 20),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Valider la commande',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
@ -596,6 +843,63 @@ class _CartPageState extends State<CartPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Bouton Payer directement
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed:
|
||||
_cartItems.isNotEmpty && !_isValidating
|
||||
? _payerDirectement
|
||||
: null,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.orange[600],
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
disabledBackgroundColor: Colors.grey[300],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (_isValidating) ...[
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Traitement...',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
] else ...[
|
||||
const Icon(Icons.payment, size: 20),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Payer directement',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -610,13 +914,13 @@ class CartItemModel {
|
||||
final String nom;
|
||||
final double prix;
|
||||
int quantity;
|
||||
final String notes;
|
||||
final String commentaire;
|
||||
|
||||
CartItemModel({
|
||||
required this.id,
|
||||
required this.nom,
|
||||
required this.prix,
|
||||
required this.quantity,
|
||||
required this.notes,
|
||||
required this.commentaire,
|
||||
});
|
||||
}
|
||||
@ -311,7 +311,7 @@ class _OrdersManagementScreenState extends State<OrdersManagementScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Table ${order.tableId} - ${order.totalTtc.toStringAsFixed(2)} MGA',
|
||||
'${order.tablename} - ${order.totalTtc.toStringAsFixed(2)} MGA',
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -515,7 +515,6 @@ class _OrdersManagementScreenState extends State<OrdersManagementScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class OrderCard extends StatelessWidget {
|
||||
final Order order;
|
||||
final Function(Order, String, {String? modePaiement}) onStatusUpdate;
|
||||
@ -587,7 +586,7 @@ class OrderCard extends StatelessWidget {
|
||||
GestureDetector(
|
||||
onTap: onViewDetails,
|
||||
child: Text(
|
||||
'Table ${order.tableId}',
|
||||
'${order.tablename}',
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
@ -662,7 +661,6 @@ class OrderCard extends StatelessWidget {
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -861,6 +859,7 @@ class Order {
|
||||
final DateTime createdAt;
|
||||
DateTime updatedAt;
|
||||
final List<OrderItem> items;
|
||||
final String? tablename;
|
||||
|
||||
Order({
|
||||
required this.id,
|
||||
@ -880,6 +879,7 @@ class Order {
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
this.items = const [],
|
||||
this.tablename = '',
|
||||
});
|
||||
|
||||
factory Order.fromJson(Map<String, dynamic> json) {
|
||||
@ -912,6 +912,7 @@ class Order {
|
||||
createdAt: DateTime.parse(json['created_at']),
|
||||
updatedAt: DateTime.parse(json['updated_at']),
|
||||
items: orderItems,
|
||||
tablename: json['tablename'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
@ -925,7 +926,13 @@ class OrderItem {
|
||||
final String? nom;
|
||||
final double? pu;
|
||||
|
||||
OrderItem({required this.menuId, required this.quantite, this.commentaires, this.nom, this.pu});
|
||||
OrderItem({
|
||||
required this.menuId,
|
||||
required this.quantite,
|
||||
this.commentaires,
|
||||
this.nom,
|
||||
this.pu,
|
||||
});
|
||||
|
||||
factory OrderItem.fromJson(Map<String, dynamic> json) {
|
||||
return OrderItem(
|
||||
@ -933,7 +940,8 @@ class OrderItem {
|
||||
quantite: json['quantite'],
|
||||
commentaires: json['commentaires'],
|
||||
nom: json['menu_nom'],
|
||||
pu: json['menu_prix_actuel'] != null
|
||||
pu:
|
||||
json['menu_prix_actuel'] != null
|
||||
? double.tryParse(json['menu_prix_actuel'].toString())
|
||||
: null,
|
||||
);
|
||||
|
||||
@ -116,23 +116,23 @@ class _EncaissementScreenState extends State<EncaissementScreen> {
|
||||
),
|
||||
const Spacer(),
|
||||
// Bouton Commande Directe
|
||||
ElevatedButton.icon(
|
||||
onPressed: _showCommandeDirecteDialog,
|
||||
icon: const Icon(Icons.add_shopping_cart, size: 20),
|
||||
label: const Text('Commande Directe'),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF007BFF),
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 2,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 12,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
// ElevatedButton.icon(
|
||||
// onPressed: _showCommandeDirecteDialog,
|
||||
// icon: const Icon(Icons.add_shopping_cart, size: 20),
|
||||
// label: const Text('Commande Directe'),
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: const Color(0xFF007BFF),
|
||||
// foregroundColor: Colors.white,
|
||||
// elevation: 2,
|
||||
// padding: const EdgeInsets.symmetric(
|
||||
// horizontal: 16,
|
||||
// vertical: 12,
|
||||
// ),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -9,8 +9,14 @@ import 'cart_page.dart'; // Assurez-vous que le fichier cart_page.dart est dans
|
||||
class MenuPage extends StatefulWidget {
|
||||
final int tableId;
|
||||
final int personne;
|
||||
final String? tablename;
|
||||
|
||||
const MenuPage({super.key, required this.tableId, required this.personne});
|
||||
const MenuPage({
|
||||
super.key,
|
||||
required this.tableId,
|
||||
required this.personne,
|
||||
this.tablename,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MenuPage> createState() => _MenuPageState();
|
||||
@ -126,6 +132,7 @@ class _MenuPageState extends State<MenuPage> {
|
||||
(context) => CartPage(
|
||||
tableId: widget.tableId,
|
||||
personne: widget.personne,
|
||||
tablename: widget.tablename,
|
||||
cartItems: List.from(
|
||||
_cart,
|
||||
), // Copie de la liste pour éviter les modifications
|
||||
@ -169,7 +176,7 @@ class _MenuPageState extends State<MenuPage> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
"Table ${widget.tableId} • ${widget.personne} personne${widget.personne > 1 ? 's' : ''}",
|
||||
"${widget.tablename} • ${widget.personne} personne${widget.personne > 1 ? 's' : ''}",
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
),
|
||||
|
||||
@ -470,6 +470,7 @@ class _TablesScreenState extends State<TablesScreen> {
|
||||
tableId: table.id,
|
||||
personne:
|
||||
table.capacity,
|
||||
tablename: table.nom,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
35
macos/Podfile.lock
Normal file
35
macos/Podfile.lock
Normal file
@ -0,0 +1,35 @@
|
||||
PODS:
|
||||
- FlutterMacOS (1.0.0)
|
||||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- printing (1.0.0):
|
||||
- FlutterMacOS
|
||||
- share_plus (0.0.1):
|
||||
- FlutterMacOS
|
||||
|
||||
DEPENDENCIES:
|
||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
||||
- printing (from `Flutter/ephemeral/.symlinks/plugins/printing/macos`)
|
||||
- share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
FlutterMacOS:
|
||||
:path: Flutter/ephemeral
|
||||
path_provider_foundation:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
|
||||
printing:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/printing/macos
|
||||
share_plus:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
printing: c4cf83c78fd684f9bc318e6aadc18972aa48f617
|
||||
share_plus: 3c787998077d6b31e839225a282e9e27edf99274
|
||||
|
||||
PODFILE CHECKSUM: 7eb978b976557c8c1cd717d8185ec483fd090a82
|
||||
|
||||
COCOAPODS: 1.16.2
|
||||
@ -27,6 +27,8 @@
|
||||
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
|
||||
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
|
||||
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
|
||||
DE662059A3043873D5913CE6 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E5CC0BE35805CF999512F9F /* Pods_Runner.framework */; };
|
||||
E133F2EBD00FFD072B98FDDB /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A24478FD7BC43A261DE1A80C /* Pods_RunnerTests.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -60,11 +62,13 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
14210005D136C1BAFBE864EC /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
18B2FC21174471F9C0659F43 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
|
||||
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
|
||||
33CC10ED2044A3C60003C045 /* itrimobe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "itrimobe.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
33CC10ED2044A3C60003C045 /* itrimobe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = itrimobe.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
|
||||
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
@ -76,8 +80,14 @@
|
||||
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
|
||||
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
|
||||
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
|
||||
563FC2B968AB0F12C9DFF280 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
68DB5BB89EB253D2BA9F24BE /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
6DD58FF68D2F20F4B6E1A319 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9E5CC0BE35805CF999512F9F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A24478FD7BC43A261DE1A80C /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C3C31231CF22309AF942A4DA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -85,6 +95,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E133F2EBD00FFD072B98FDDB /* Pods_RunnerTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -92,6 +103,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DE662059A3043873D5913CE6 /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -125,6 +137,7 @@
|
||||
331C80D6294CF71000263BE5 /* RunnerTests */,
|
||||
33CC10EE2044A3C60003C045 /* Products */,
|
||||
D73912EC22F37F3D000D13A0 /* Frameworks */,
|
||||
3FC6292619E15A3F1F8BC3FA /* Pods */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@ -172,9 +185,25 @@
|
||||
path = Runner;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3FC6292619E15A3F1F8BC3FA /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6DD58FF68D2F20F4B6E1A319 /* Pods-Runner.debug.xcconfig */,
|
||||
18B2FC21174471F9C0659F43 /* Pods-Runner.release.xcconfig */,
|
||||
C3C31231CF22309AF942A4DA /* Pods-Runner.profile.xcconfig */,
|
||||
14210005D136C1BAFBE864EC /* Pods-RunnerTests.debug.xcconfig */,
|
||||
563FC2B968AB0F12C9DFF280 /* Pods-RunnerTests.release.xcconfig */,
|
||||
68DB5BB89EB253D2BA9F24BE /* Pods-RunnerTests.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E5CC0BE35805CF999512F9F /* Pods_Runner.framework */,
|
||||
A24478FD7BC43A261DE1A80C /* Pods_RunnerTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@ -186,6 +215,7 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||
buildPhases = (
|
||||
B4AE9C55067DCB5B2D32CDF9 /* [CP] Check Pods Manifest.lock */,
|
||||
331C80D1294CF70F00263BE5 /* Sources */,
|
||||
331C80D2294CF70F00263BE5 /* Frameworks */,
|
||||
331C80D3294CF70F00263BE5 /* Resources */,
|
||||
@ -204,11 +234,13 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
D48CC48A091064CAD0F566B8 /* [CP] Check Pods Manifest.lock */,
|
||||
33CC10E92044A3C60003C045 /* Sources */,
|
||||
33CC10EA2044A3C60003C045 /* Frameworks */,
|
||||
33CC10EB2044A3C60003C045 /* Resources */,
|
||||
33CC110E2044A8840003C045 /* Bundle Framework */,
|
||||
3399D490228B24CF009A79C7 /* ShellScript */,
|
||||
842D90427A1F831501B6294C /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -329,6 +361,67 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
|
||||
};
|
||||
842D90427A1F831501B6294C /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
B4AE9C55067DCB5B2D32CDF9 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
D48CC48A091064CAD0F566B8 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@ -380,6 +473,7 @@
|
||||
/* Begin XCBuildConfiguration section */
|
||||
331C80DB294CF71000263BE5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 14210005D136C1BAFBE864EC /* Pods-RunnerTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@ -394,6 +488,7 @@
|
||||
};
|
||||
331C80DC294CF71000263BE5 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 563FC2B968AB0F12C9DFF280 /* Pods-RunnerTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@ -408,6 +503,7 @@
|
||||
};
|
||||
331C80DD294CF71000263BE5 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 68DB5BB89EB253D2BA9F24BE /* Pods-RunnerTests.profile.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
||||
@ -4,4 +4,7 @@
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
48
pubspec.lock
48
pubspec.lock
@ -312,6 +312,54 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
permission_handler:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: permission_handler
|
||||
sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.4.0"
|
||||
permission_handler_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_android
|
||||
sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.1.0"
|
||||
permission_handler_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_apple
|
||||
sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.4.7"
|
||||
permission_handler_html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_html
|
||||
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.3+5"
|
||||
permission_handler_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_platform_interface
|
||||
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.3.0"
|
||||
permission_handler_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_windows
|
||||
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@ -6,11 +6,14 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <printing/printing_plugin.h>
|
||||
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||
PrintingPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PrintingPlugin"));
|
||||
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
permission_handler_windows
|
||||
printing
|
||||
share_plus
|
||||
url_launcher_windows
|
||||
|
||||
Loading…
Reference in New Issue
Block a user