feat: Version 3.3.4 - Nouvelle architecture pages, optimisations widgets Flutter et API
- Mise à jour VERSION vers 3.3.4 - Optimisations et révisions architecture API (deploy-api.sh, scripts de migration) - Ajout documentation Stripe Tap to Pay complète - Migration vers polices Inter Variable pour Flutter - Optimisations build Android et nettoyage fichiers temporaires - Amélioration système de déploiement avec gestion backups - Ajout scripts CRON et migrations base de données 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -119,9 +119,17 @@ class PassageController {
|
||||
$errors[] = 'La ville est obligatoire';
|
||||
}
|
||||
|
||||
// Validation du nom (chiffré)
|
||||
if (!isset($data['encrypted_name']) && !isset($data['name'])) {
|
||||
$errors[] = 'Le nom est obligatoire';
|
||||
// Validation du nom (chiffré) - obligatoire seulement si (type=1 Effectué ou 5 Lot) ET email présent
|
||||
$fk_type = isset($data['fk_type']) ? (int)$data['fk_type'] : 0;
|
||||
$hasEmail = (isset($data['email']) && !empty(trim($data['email']))) ||
|
||||
(isset($data['encrypted_email']) && !empty($data['encrypted_email']));
|
||||
|
||||
if (($fk_type === 1 || $fk_type === 5) && $hasEmail) {
|
||||
if (!isset($data['encrypted_name']) && !isset($data['name'])) {
|
||||
$errors[] = 'Le nom est obligatoire pour ce type de passage avec email';
|
||||
} elseif (isset($data['name']) && empty(trim($data['name']))) {
|
||||
$errors[] = 'Le nom ne peut pas être vide pour ce type de passage avec email';
|
||||
}
|
||||
}
|
||||
|
||||
// Validation du montant
|
||||
@@ -157,6 +165,15 @@ class PassageController {
|
||||
}
|
||||
}
|
||||
|
||||
// Validation de l'ID Stripe si fourni
|
||||
if (isset($data['stripe_payment_id']) && !empty($data['stripe_payment_id'])) {
|
||||
$stripeId = trim($data['stripe_payment_id']);
|
||||
// L'ID PaymentIntent Stripe doit commencer par 'pi_'
|
||||
if (!preg_match('/^pi_[a-zA-Z0-9]{24,}$/', $stripeId)) {
|
||||
$errors[] = 'Format d\'ID de paiement Stripe invalide';
|
||||
}
|
||||
}
|
||||
|
||||
return empty($errors) ? null : $errors;
|
||||
}
|
||||
|
||||
@@ -210,13 +227,13 @@ class PassageController {
|
||||
|
||||
// Requête principale avec jointures
|
||||
$stmt = $this->db->prepare("
|
||||
SELECT
|
||||
SELECT
|
||||
p.id, p.fk_operation, p.fk_sector, p.fk_user, p.fk_adresse,
|
||||
p.passed_at, p.fk_type, p.numero, p.rue, p.rue_bis, p.ville,
|
||||
p.fk_habitat, p.appt, p.niveau, p.residence, p.gps_lat, p.gps_lng,
|
||||
p.encrypted_name, p.montant, p.fk_type_reglement, p.remarque,
|
||||
p.encrypted_email, p.encrypted_phone, p.nom_recu, p.date_recu,
|
||||
p.chk_email_sent, p.docremis, p.date_repasser, p.nb_passages,
|
||||
p.chk_email_sent, p.stripe_payment_id, p.docremis, p.date_repasser, p.nb_passages,
|
||||
p.chk_mobile, p.anomalie, p.created_at, p.updated_at, p.chk_active,
|
||||
o.libelle as operation_libelle,
|
||||
u.encrypted_name as user_name, u.first_name as user_first_name
|
||||
@@ -389,11 +406,11 @@ class PassageController {
|
||||
$offset = ($page - 1) * $limit;
|
||||
|
||||
$stmt = $this->db->prepare('
|
||||
SELECT
|
||||
SELECT
|
||||
p.id, p.fk_operation, p.fk_sector, p.fk_user, p.passed_at,
|
||||
p.numero, p.rue, p.rue_bis, p.ville, p.gps_lat, p.gps_lng,
|
||||
p.encrypted_name, p.montant, p.fk_type_reglement, p.remarque,
|
||||
p.encrypted_email, p.encrypted_phone, p.chk_email_sent,
|
||||
p.encrypted_email, p.encrypted_phone, p.stripe_payment_id, p.chk_email_sent,
|
||||
p.docremis, p.date_repasser, p.nb_passages, p.chk_mobile,
|
||||
p.anomalie, p.created_at, p.updated_at,
|
||||
u.encrypted_name as user_name, u.first_name as user_first_name
|
||||
@@ -494,7 +511,13 @@ class PassageController {
|
||||
}
|
||||
|
||||
// Chiffrement des données sensibles
|
||||
$encryptedName = isset($data['name']) ? ApiService::encryptData($data['name']) : (isset($data['encrypted_name']) ? $data['encrypted_name'] : '');
|
||||
$encryptedName = '';
|
||||
if (isset($data['name']) && !empty(trim($data['name']))) {
|
||||
$encryptedName = ApiService::encryptData($data['name']);
|
||||
} elseif (isset($data['encrypted_name']) && !empty($data['encrypted_name'])) {
|
||||
$encryptedName = $data['encrypted_name'];
|
||||
}
|
||||
// Le nom peut rester vide si les conditions ne l'exigent pas
|
||||
$encryptedEmail = isset($data['email']) && !empty($data['email']) ?
|
||||
ApiService::encryptSearchableData($data['email']) : '';
|
||||
$encryptedPhone = isset($data['phone']) && !empty($data['phone']) ?
|
||||
@@ -524,6 +547,7 @@ class PassageController {
|
||||
'remarque' => $data['remarque'] ?? '',
|
||||
'encrypted_email' => $encryptedEmail,
|
||||
'encrypted_phone' => $encryptedPhone,
|
||||
'stripe_payment_id' => isset($data['stripe_payment_id']) ? trim($data['stripe_payment_id']) : null,
|
||||
'nom_recu' => $data['nom_recu'] ?? null,
|
||||
'date_recu' => isset($data['date_recu']) ? $data['date_recu'] : null,
|
||||
'docremis' => isset($data['docremis']) ? (int)$data['docremis'] : 0,
|
||||
@@ -646,7 +670,7 @@ class PassageController {
|
||||
}
|
||||
|
||||
$stmt = $this->db->prepare('
|
||||
SELECT p.id, p.fk_operation
|
||||
SELECT p.id, p.fk_operation, p.fk_type, p.fk_user
|
||||
FROM ope_pass p
|
||||
INNER JOIN operations o ON p.fk_operation = o.id
|
||||
WHERE p.id = ? AND o.fk_entite = ? AND p.chk_active = 1
|
||||
@@ -673,6 +697,19 @@ class PassageController {
|
||||
return;
|
||||
}
|
||||
|
||||
// Si le passage était de type 2 et que l'utilisateur actuel est différent du créateur
|
||||
// On force l'attribution du passage à l'utilisateur actuel
|
||||
if ((int)$passage['fk_type'] === 2 && (int)$passage['fk_user'] !== $userId) {
|
||||
$data['fk_user'] = $userId;
|
||||
|
||||
LogService::log('Attribution automatique d\'un passage type 2 à l\'utilisateur', [
|
||||
'level' => 'info',
|
||||
'passageId' => $passageId,
|
||||
'ancien_user' => $passage['fk_user'],
|
||||
'nouveau_user' => $userId
|
||||
]);
|
||||
}
|
||||
|
||||
// Construction de la requête de mise à jour dynamique
|
||||
$updateFields = [];
|
||||
$params = [];
|
||||
@@ -697,6 +734,7 @@ class PassageController {
|
||||
'montant',
|
||||
'fk_type_reglement',
|
||||
'remarque',
|
||||
'stripe_payment_id',
|
||||
'nom_recu',
|
||||
'date_recu',
|
||||
'docremis',
|
||||
@@ -714,9 +752,10 @@ class PassageController {
|
||||
}
|
||||
|
||||
// Gestion des champs chiffrés
|
||||
if (isset($data['name'])) {
|
||||
if (array_key_exists('name', $data)) {
|
||||
$updateFields[] = "encrypted_name = ?";
|
||||
$params[] = ApiService::encryptData($data['name']);
|
||||
// Permettre de vider le nom si les conditions le permettent
|
||||
$params[] = !empty(trim($data['name'])) ? ApiService::encryptData($data['name']) : '';
|
||||
}
|
||||
|
||||
if (isset($data['email'])) {
|
||||
|
||||
Reference in New Issue
Block a user