feat(v2.0.4): Corrections diverses et tri des tableaux devis
- Correction affichage email contact dans SAP (models/msap.php) - Ajout fonctionnalité tri des tableaux devis (jsap.js, jdevis.js) - Améliorations diverses vues devis et SAP - Mise à jour contrôleurs et modèles export 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
87
.gitignore
vendored
87
.gitignore
vendored
@@ -1,43 +1,44 @@
|
||||
# Logs
|
||||
*.log
|
||||
logs/
|
||||
log/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
|
||||
# Composer
|
||||
/vendor/
|
||||
|
||||
# Configuration sensible
|
||||
config/conf.local.php
|
||||
.env
|
||||
.env.local
|
||||
|
||||
# Fichiers temporaires
|
||||
*.tmp
|
||||
tmp/
|
||||
temp/
|
||||
cache/
|
||||
|
||||
# Uploads et fichiers utilisateurs
|
||||
pub/files/upload/*
|
||||
!pub/files/upload/.gitkeep
|
||||
|
||||
# Sauvegardes
|
||||
*.bak
|
||||
*.backup
|
||||
# *.sql
|
||||
backup/
|
||||
backups/
|
||||
|
||||
# Sessions PHP
|
||||
sessions/
|
||||
|
||||
# Fichiers système
|
||||
Thumbs.db*.swp
|
||||
# Logs
|
||||
*.log
|
||||
logs/
|
||||
log/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
|
||||
# Composer
|
||||
/vendor/
|
||||
|
||||
# Configuration sensible
|
||||
config/conf.local.php
|
||||
.env
|
||||
.env.local
|
||||
|
||||
# Fichiers temporaires
|
||||
*.tmp
|
||||
tmp/
|
||||
temp/
|
||||
cache/
|
||||
|
||||
# Uploads et fichiers utilisateurs
|
||||
pub/files/upload/*
|
||||
!pub/files/upload/.gitkeep
|
||||
|
||||
# Sauvegardes
|
||||
*.bak
|
||||
*.backup
|
||||
# *.sql
|
||||
backup/
|
||||
backups/
|
||||
|
||||
# Sessions PHP
|
||||
sessions/
|
||||
|
||||
# Fichiers système
|
||||
Thumbs.db*.swp
|
||||
.aider*
|
||||
|
||||
@@ -10,7 +10,7 @@ class Conf {
|
||||
|
||||
public $_appname = "cleo";
|
||||
public $_appscript = "login";
|
||||
public $_appversion = "2.0.3";
|
||||
public $_appversion = "2.0.4";
|
||||
public $_appenv;
|
||||
public $_apptitle = "CLEO - Gestion de devis";
|
||||
|
||||
|
||||
@@ -1368,5 +1368,280 @@ switch ($Route->_action) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "search_devis":
|
||||
eLog("=== search_devis case appelé ===");
|
||||
$rawData = file_get_contents("php://input");
|
||||
eLog("Raw data: " . $rawData);
|
||||
$data = json_decode($rawData);
|
||||
eLog("Data decoded: " . print_r($data, true));
|
||||
eLog("isset term: " . (isset($data->term) ? 'YES' : 'NO'));
|
||||
|
||||
if (isset($data->term)) {
|
||||
$term = nettoie_input($data->term);
|
||||
$context = nettoie_input($data->context);
|
||||
|
||||
if (strlen($term) < 3) {
|
||||
echo json_encode(array("success" => false, "message" => "Le terme de recherche doit contenir au moins 3 caractères"));
|
||||
break;
|
||||
}
|
||||
|
||||
$termSafe = '%' . $term . '%';
|
||||
|
||||
$whereParams = [];
|
||||
switch ($fk_role) {
|
||||
case 1:
|
||||
$whereRole = 'd.fk_user = :fkUser OR d.fk_statut_devis >= 2';
|
||||
$whereParams[':fkUser'] = $fk_user;
|
||||
break;
|
||||
case 2:
|
||||
try {
|
||||
$db = Database::getInstance();
|
||||
$sql = 'SELECT rowid FROM users WHERE fk_parent = :fkParent';
|
||||
$aRR = $db->fetchAll($sql, [':fkParent' => $fk_user]);
|
||||
|
||||
$rrIds = array_column($aRR, 'rowid');
|
||||
if (!empty($rrIds)) {
|
||||
$placeholders = [];
|
||||
foreach ($rrIds as $index => $id) {
|
||||
$placeholder = ':rr' . $index;
|
||||
$placeholders[] = $placeholder;
|
||||
$whereParams[$placeholder] = $id;
|
||||
}
|
||||
$whereRole = 'd.fk_user = :fkUser OR (d.fk_statut_devis >= 3 AND d.fk_user IN (' . implode(',', $placeholders) . '))';
|
||||
$whereParams[':fkUser'] = $fk_user;
|
||||
} else {
|
||||
$whereRole = 'd.fk_user = :fkUser';
|
||||
$whereParams[':fkUser'] = $fk_user;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur récupération RR : " . $e->getMessage());
|
||||
$whereRole = 'd.fk_user = :fkUser';
|
||||
$whereParams[':fkUser'] = $fk_user;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$whereRole = 'd.fk_user = :fkUser';
|
||||
$whereParams[':fkUser'] = $fk_user;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($context === "archives") {
|
||||
$whereStatut = ' AND d.fk_statut_devis = 20';
|
||||
} else {
|
||||
$whereStatut = ' AND d.fk_statut_devis != 20';
|
||||
}
|
||||
|
||||
$whereParams[':term1'] = $termSafe;
|
||||
$whereParams[':term2'] = $termSafe;
|
||||
$whereParams[':term3'] = $termSafe;
|
||||
$whereParams[':term4'] = $termSafe;
|
||||
$whereParams[':term5'] = $termSafe;
|
||||
$whereParams[':term6'] = $termSafe;
|
||||
$whereParams[':term7'] = $termSafe;
|
||||
$whereParams[':term8'] = $termSafe;
|
||||
$whereParams[':term9'] = $termSafe;
|
||||
$whereParams[':term10'] = $termSafe;
|
||||
$whereParams[':term11'] = $termSafe;
|
||||
$whereParams[':term12'] = $termSafe;
|
||||
$whereParams[':term13'] = $termSafe;
|
||||
$whereParams[':term14'] = $termSafe;
|
||||
$whereParams[':term15'] = $termSafe;
|
||||
$whereParams[':term16'] = $termSafe;
|
||||
$whereParams[':term17'] = $termSafe;
|
||||
|
||||
try {
|
||||
$db = Database::getInstance();
|
||||
$sql = 'SELECT DISTINCT d.rowid, d.dossier, d.date_demande, d.date_remise, d.num_opportunite, d.fk_client, d.montant_total_ht_remise, d.marge_totale, d.commentaire, d.chk_speciaux, c.libelle, c.ville, c.cp, d.fk_statut_devis, ';
|
||||
$sql .= 'd.lib_new_client, d.type_new_client, d.adresse1_new_client, d.adresse2_new_client, d.adresse3_new_client, d.cp_new_client, d.ville_new_client, d.comment_devis, d.comment_geste_comm, ';
|
||||
$sql .= 'd.contact_new_nom, d.contact_new_prenom, d.new_telephone, d.new_mobile, d.new_email, d.contact_new_fonction, LEFT(u.prenom,1) AS prenom, u.libelle as nom, ';
|
||||
$sql .= 'xs.libelle as lib_statut, d.chk_new_statut, m.libelle as lib_marche, d.chk_validat, d.fk_user_validat, d.date_validat ';
|
||||
$sql .= 'FROM devis d ';
|
||||
$sql .= 'LEFT JOIN clients c ON c.rowid=d.fk_client ';
|
||||
$sql .= 'LEFT JOIN x_statuts_devis xs ON xs.rowid=d.fk_statut_devis ';
|
||||
$sql .= 'LEFT JOIN marches m ON m.rowid=d.fk_marche ';
|
||||
$sql .= 'LEFT JOIN users u ON u.rowid=d.fk_user ';
|
||||
$sql .= 'LEFT JOIN clients_contacts ct ON ct.fk_client=d.fk_client ';
|
||||
$sql .= 'WHERE (' . $whereRole . ')' . $whereStatut . ' AND (';
|
||||
$sql .= 'd.rowid LIKE :term1 OR ';
|
||||
$sql .= 'c.libelle LIKE :term2 OR ';
|
||||
$sql .= 'c.adresse1 LIKE :term3 OR ';
|
||||
$sql .= 'c.adresse2 LIKE :term4 OR ';
|
||||
$sql .= 'c.adresse3 LIKE :term5 OR ';
|
||||
$sql .= 'c.cp LIKE :term6 OR ';
|
||||
$sql .= 'c.ville LIKE :term7 OR ';
|
||||
$sql .= 'm.libelle LIKE :term8 OR ';
|
||||
$sql .= 'd.num_opportunite LIKE :term9 OR ';
|
||||
$sql .= 'd.lib_new_client LIKE :term10 OR ';
|
||||
$sql .= 'd.cp_new_client LIKE :term11 OR ';
|
||||
$sql .= 'd.ville_new_client LIKE :term12 OR ';
|
||||
$sql .= 'ct.nom LIKE :term13 OR ';
|
||||
$sql .= 'ct.prenom LIKE :term14 OR ';
|
||||
$sql .= 'ct.fonction LIKE :term15 OR ';
|
||||
$sql .= 'ct.email LIKE :term16 OR ';
|
||||
$sql .= 'd.commentaire LIKE :term17) ';
|
||||
$sql .= 'ORDER BY d.dossier, d.date_remise DESC';
|
||||
|
||||
eLog("=== SEARCH DEVIS DEBUG ===");
|
||||
eLog("Terme recherché: " . $term);
|
||||
eLog("Context: " . $context);
|
||||
eLog("SQL: " . $sql);
|
||||
eLog("Params: " . print_r($whereParams, true));
|
||||
|
||||
$pdo = $db->getPDO();
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($whereParams);
|
||||
$devis = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
eLog("Nombre de devis trouvés: " . count($devis));
|
||||
|
||||
$nb_devis = array();
|
||||
foreach ($devis as $dev) {
|
||||
if (!isset($nb_devis[$dev["fk_statut_devis"]])) {
|
||||
$nb_devis[$dev["fk_statut_devis"]] = 1;
|
||||
} else {
|
||||
$nb_devis[$dev["fk_statut_devis"]]++;
|
||||
}
|
||||
}
|
||||
|
||||
$dossiers = array();
|
||||
foreach ($devis as $dev) {
|
||||
if (!in_array($dev["dossier"], array_column($dossiers, 'dossier'))) {
|
||||
$dossiers[] = array("dossier" => $dev["dossier"]);
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode(array(
|
||||
"success" => true,
|
||||
"devis" => $devis,
|
||||
"nb_devis" => $nb_devis,
|
||||
"dossiers" => $dossiers
|
||||
));
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur recherche devis : " . $e->getMessage());
|
||||
echo json_encode(array("success" => false, "message" => "Erreur lors de la recherche : " . $e->getMessage()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "search_devis_sap":
|
||||
eLog("=== search_devis_sap case appelé ===");
|
||||
$rawData = file_get_contents("php://input");
|
||||
eLog("Raw data: " . $rawData);
|
||||
$data = json_decode($rawData);
|
||||
eLog("Data decoded: " . print_r($data, true));
|
||||
eLog("isset term: " . (isset($data->term) ? 'YES' : 'NO'));
|
||||
|
||||
if (isset($data->term)) {
|
||||
$term = nettoie_input($data->term);
|
||||
$context = nettoie_input($data->context);
|
||||
|
||||
if (strlen($term) < 3) {
|
||||
echo json_encode(array("success" => false, "message" => "Le terme de recherche doit contenir au moins 3 caractères"));
|
||||
break;
|
||||
}
|
||||
|
||||
$termSafe = '%' . $term . '%';
|
||||
|
||||
$whereParams = [];
|
||||
$whereRole = '1=1';
|
||||
|
||||
if ($context === "archives") {
|
||||
$whereStatut = ' AND d.fk_statut_devis = 20';
|
||||
} else {
|
||||
$whereStatut = ' AND d.fk_statut_devis != 20';
|
||||
}
|
||||
|
||||
$whereParams[':term1'] = $termSafe;
|
||||
$whereParams[':term2'] = $termSafe;
|
||||
$whereParams[':term3'] = $termSafe;
|
||||
$whereParams[':term4'] = $termSafe;
|
||||
$whereParams[':term5'] = $termSafe;
|
||||
$whereParams[':term6'] = $termSafe;
|
||||
$whereParams[':term7'] = $termSafe;
|
||||
$whereParams[':term8'] = $termSafe;
|
||||
$whereParams[':term9'] = $termSafe;
|
||||
$whereParams[':term10'] = $termSafe;
|
||||
$whereParams[':term11'] = $termSafe;
|
||||
$whereParams[':term12'] = $termSafe;
|
||||
$whereParams[':term13'] = $termSafe;
|
||||
$whereParams[':term14'] = $termSafe;
|
||||
$whereParams[':term15'] = $termSafe;
|
||||
$whereParams[':term16'] = $termSafe;
|
||||
$whereParams[':term17'] = $termSafe;
|
||||
|
||||
try {
|
||||
$db = Database::getInstance();
|
||||
$sql = 'SELECT DISTINCT d.rowid, d.dossier, d.date_demande, d.date_remise, d.num_opportunite, d.fk_client, d.montant_total_ht_remise, d.marge_totale, d.commentaire, d.chk_speciaux, c.libelle, c.ville, c.cp, d.fk_statut_devis, ';
|
||||
$sql .= 'd.lib_new_client, d.type_new_client, d.adresse1_new_client, d.adresse2_new_client, d.adresse3_new_client, d.cp_new_client, d.ville_new_client, d.comment_devis, d.comment_geste_comm, ';
|
||||
$sql .= 'd.contact_new_nom, d.contact_new_prenom, d.new_telephone, d.new_mobile, d.new_email, d.contact_new_fonction, LEFT(u.prenom,1) AS prenom, u.libelle as nom, ';
|
||||
$sql .= 'xs.libelle as lib_statut, d.chk_new_statut, m.libelle as lib_marche, d.chk_validat, d.fk_user_validat, d.date_validat, c.code ';
|
||||
$sql .= 'FROM devis d ';
|
||||
$sql .= 'LEFT JOIN clients c ON c.rowid=d.fk_client ';
|
||||
$sql .= 'LEFT JOIN x_statuts_devis xs ON xs.rowid=d.fk_statut_devis ';
|
||||
$sql .= 'LEFT JOIN marches m ON m.rowid=d.fk_marche ';
|
||||
$sql .= 'LEFT JOIN users u ON u.rowid=d.fk_user ';
|
||||
$sql .= 'LEFT JOIN clients_contacts ct ON ct.fk_client=d.fk_client ';
|
||||
$sql .= 'WHERE (' . $whereRole . ')' . $whereStatut . ' AND (';
|
||||
$sql .= 'd.rowid LIKE :term1 OR ';
|
||||
$sql .= 'c.libelle LIKE :term2 OR ';
|
||||
$sql .= 'c.adresse1 LIKE :term3 OR ';
|
||||
$sql .= 'c.adresse2 LIKE :term4 OR ';
|
||||
$sql .= 'c.adresse3 LIKE :term5 OR ';
|
||||
$sql .= 'c.cp LIKE :term6 OR ';
|
||||
$sql .= 'c.ville LIKE :term7 OR ';
|
||||
$sql .= 'c.code LIKE :term8 OR ';
|
||||
$sql .= 'm.libelle LIKE :term9 OR ';
|
||||
$sql .= 'd.num_opportunite LIKE :term10 OR ';
|
||||
$sql .= 'd.lib_new_client LIKE :term11 OR ';
|
||||
$sql .= 'd.cp_new_client LIKE :term12 OR ';
|
||||
$sql .= 'd.ville_new_client LIKE :term13 OR ';
|
||||
$sql .= 'ct.nom LIKE :term14 OR ';
|
||||
$sql .= 'ct.prenom LIKE :term15 OR ';
|
||||
$sql .= 'ct.fonction LIKE :term16 OR ';
|
||||
$sql .= 'ct.email LIKE :term17) ';
|
||||
$sql .= 'ORDER BY d.dossier, d.date_remise DESC';
|
||||
|
||||
eLog("=== SEARCH DEVIS SAP DEBUG ===");
|
||||
eLog("Terme recherché: " . $term);
|
||||
eLog("Context: " . $context);
|
||||
eLog("SQL: " . $sql);
|
||||
eLog("Params: " . print_r($whereParams, true));
|
||||
|
||||
$pdo = $db->getPDO();
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($whereParams);
|
||||
$devis = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
eLog("Nombre de devis trouvés: " . count($devis));
|
||||
|
||||
$nb_devis = array();
|
||||
foreach ($devis as $dev) {
|
||||
if (!isset($nb_devis[$dev["fk_statut_devis"]])) {
|
||||
$nb_devis[$dev["fk_statut_devis"]] = 1;
|
||||
} else {
|
||||
$nb_devis[$dev["fk_statut_devis"]]++;
|
||||
}
|
||||
}
|
||||
|
||||
$dossiers = array();
|
||||
foreach ($devis as $dev) {
|
||||
if (!in_array($dev["dossier"], array_column($dossiers, 'dossier'))) {
|
||||
$dossiers[] = array("dossier" => $dev["dossier"]);
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode(array(
|
||||
"success" => true,
|
||||
"devis" => $devis,
|
||||
"nb_devis" => $nb_devis,
|
||||
"dossiers" => $dossiers
|
||||
));
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur recherche devis SAP : " . $e->getMessage());
|
||||
echo json_encode(array("success" => false, "message" => "Erreur lors de la recherche : " . $e->getMessage()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
exit();
|
||||
|
||||
@@ -49,6 +49,64 @@ function formate_date($sdate)
|
||||
return $ladate;
|
||||
}
|
||||
|
||||
function syncContactClient($code, $contactNom, $contactPrenom, $contactFonction, $telephone, $mobile, $email, $fkUser)
|
||||
{
|
||||
try {
|
||||
$db = Database::getInstance();
|
||||
|
||||
// 1. Compter les contacts actifs pour ce client
|
||||
$sql = 'SELECT COUNT(*) as nb FROM clients_contacts WHERE fk_client = :code AND active = 1';
|
||||
$countResult = $db->fetchAll($sql, [':code' => $code]);
|
||||
$nbContacts = $countResult[0]['nb'];
|
||||
|
||||
if ($nbContacts == 0) {
|
||||
// Aucun contact : créer directement avec principal=1
|
||||
$principal = 1;
|
||||
} else {
|
||||
// Des contacts existent : vérifier si ce nom+prénom existe (en MAJUSCULES)
|
||||
$sql = 'SELECT rowid FROM clients_contacts
|
||||
WHERE fk_client = :code
|
||||
AND UPPER(nom) = UPPER(:nom)
|
||||
AND UPPER(prenom) = UPPER(:prenom)
|
||||
AND active = 1';
|
||||
$existingContact = $db->fetchAll($sql, [
|
||||
':code' => $code,
|
||||
':nom' => $contactNom,
|
||||
':prenom' => $contactPrenom
|
||||
]);
|
||||
|
||||
if (count($existingContact) > 0) {
|
||||
// Contact déjà présent : ne rien faire
|
||||
eLog("syncContactClient : Contact existe déjà pour client " . $code);
|
||||
return;
|
||||
}
|
||||
|
||||
// Contact pas trouvé : créer avec principal=0
|
||||
$principal = 0;
|
||||
}
|
||||
|
||||
// Créer le contact
|
||||
$sql = 'INSERT INTO clients_contacts SET fk_client = :code, nom = :nom, prenom = :prenom, fonction = :fonction, telephone = :telephone, mobile = :mobile, email = :email, principal = :principal, active = 1, date_creat = NOW(), fk_user_creat = :fk_user';
|
||||
$db->query($sql, [
|
||||
':code' => $code,
|
||||
':nom' => $contactNom,
|
||||
':prenom' => $contactPrenom,
|
||||
':fonction' => $contactFonction,
|
||||
':telephone' => $telephone,
|
||||
':mobile' => $mobile,
|
||||
':email' => $email,
|
||||
':principal' => $principal,
|
||||
':fk_user' => $fkUser
|
||||
]);
|
||||
|
||||
eLog("syncContactClient : Contact créé pour client " . $code . " (principal=" . $principal . ")");
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur syncContactClient : " . $e->getMessage());
|
||||
eLog("Erreur syncContactClient pour client " . $code . " : " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch ($Route->_action) {
|
||||
case "upload_clients":
|
||||
@@ -171,6 +229,10 @@ switch ($Route->_action) {
|
||||
]);
|
||||
$fkClient = $db->lastInsertId();
|
||||
fwrite($fhlog, $row . "--- Ajout client avec requête préparée\r\n");
|
||||
|
||||
// Synchroniser le contact dans clients_contacts
|
||||
syncContactClient($code, $contactNom, $contactPrenom, $contactFonction, $telephone, $mobile, $email, $fkUser);
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur insertion client : " . $e->getMessage());
|
||||
fwrite($fhlog, "Erreur insertion : " . $e->getMessage() . "\r\n");
|
||||
@@ -212,6 +274,10 @@ switch ($Route->_action) {
|
||||
':code' => $code
|
||||
]);
|
||||
fwrite($fhlog, $row . "--- MàJ client avec requête préparée\r\n");
|
||||
|
||||
// Synchroniser le contact dans clients_contacts
|
||||
syncContactClient($code, $contactNom, $contactPrenom, $contactFonction, $telephone, $mobile, $email, $fkUser);
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur mise à jour client : " . $e->getMessage());
|
||||
fwrite($fhlog, "Erreur MàJ : " . $e->getMessage() . "\r\n");
|
||||
|
||||
84
docs/TODO.md
84
docs/TODO.md
@@ -195,12 +195,90 @@ DB_PASSWORD=<PROD_PASSWORD> # À sécuriser
|
||||
- [ ] Scripts de backup automatisés à mettre en place
|
||||
- [ ] Réplication master-slave pour haute disponibilité (optionnel)
|
||||
|
||||
## ⚠️ CRITIQUE - Risque de collision de codes clients (EN ATTENTE CLIENT)
|
||||
|
||||
### Problématique identifiée
|
||||
**Date**: 26 novembre 2025
|
||||
**Statut**: 🔴 EN ATTENTE RÉPONSE CLIENT
|
||||
|
||||
#### Situation actuelle
|
||||
Lorsqu'un commercial crée un nouveau client manuellement dans CLEO (client non présent dans SAP), le système génère automatiquement un code via :
|
||||
```php
|
||||
$newCode = MAX(code) + 1; // cjxdevis.php ligne 1326
|
||||
```
|
||||
|
||||
#### Risque de collision
|
||||
**Scénario catastrophe** :
|
||||
1. Commercial crée un client manuel → code auto = `12345`
|
||||
2. Commercial ajoute des contacts, fait des devis
|
||||
3. **Import SAP suivant** : un nouveau client SAP arrive avec le code `12345`
|
||||
4. L'import trouve le client existant (même code) et **écrase toutes les données** du client manuel
|
||||
5. Les contacts du client manuel deviennent incohérents (pointent vers le mauvais client SAP)
|
||||
6. Les devis du client manuel sont rattachés au mauvais client SAP
|
||||
|
||||
#### Question posée au client
|
||||
**"Que se passe-t-il lorsqu'un devis avec un nouveau client (code = MAX+1) est intégré dans SAP ?"**
|
||||
- Le client manuel reçoit-il un vrai code SAP ?
|
||||
- Le code est-il synchronisé dans CLEO après intégration ?
|
||||
- Existe-t-il un processus de réconciliation ?
|
||||
|
||||
### Solutions techniques envisagées
|
||||
|
||||
#### Option A : Plage réservée pour clients manuels
|
||||
```php
|
||||
// Codes 9000000+ réservés aux créations manuelles
|
||||
$newCode = 9000000 + $compteur;
|
||||
```
|
||||
**Avantages** : Simple, pas de collision possible
|
||||
**Inconvénients** : Nécessite coordination avec SAP
|
||||
|
||||
#### Option B : Codes négatifs pour clients manuels
|
||||
```php
|
||||
// Codes négatifs = clients manuels non SAP
|
||||
$newCode = -1 * (MAX(ABS(code)) + 1);
|
||||
```
|
||||
**Avantages** : Distinction claire SAP/Manuel
|
||||
**Inconvénients** : Peut poser problème avec certains systèmes
|
||||
|
||||
#### Option C : Flag `chk_manual` + protection
|
||||
```sql
|
||||
ALTER TABLE clients ADD COLUMN chk_manual TINYINT DEFAULT 0;
|
||||
```
|
||||
- `chk_manual = 1` → Client créé manuellement, jamais écrasé par import SAP
|
||||
- Lors de l'import SAP, ignorer les clients avec `chk_manual = 1`
|
||||
- Processus manuel de réconciliation si le client est créé dans SAP
|
||||
|
||||
**Avantages** : Protection garantie, traçabilité
|
||||
**Inconvénients** : Nécessite gestion manuelle de la réconciliation
|
||||
|
||||
#### Option D : Code temporaire + synchronisation
|
||||
- Client manuel créé avec code `TEMP_XXXXX`
|
||||
- Lors de l'intégration SAP, récupération du vrai code SAP
|
||||
- Mise à jour du code client + tous les contacts/devis associés
|
||||
|
||||
**Avantages** : Cohérence totale avec SAP
|
||||
**Inconvénients** : Complexe, nécessite API ou process de sync
|
||||
|
||||
### Actions en attente
|
||||
- [ ] **Réponse client** sur le processus actuel d'intégration SAP
|
||||
- [ ] Choix de la solution technique selon la réponse
|
||||
- [ ] Implémentation de la solution retenue
|
||||
- [ ] Tests de non-régression sur imports SAP
|
||||
- [ ] Documentation du processus de gestion des clients manuels
|
||||
|
||||
### Impact sur le code existant
|
||||
**Fichiers concernés** :
|
||||
- `controllers/cjxdevis.php` : fonction `save_new_client` (ligne 1308)
|
||||
- `controllers/cjximport.php` : fonction `upload_clients` (ligne 112)
|
||||
- Documentation utilisateur à mettre à jour
|
||||
|
||||
---
|
||||
|
||||
## Modification Contacts Clients - Migration vers clients.code
|
||||
|
||||
### Contexte
|
||||
La relation entre `clients_contacts` et `clients` utilise actuellement `clients.rowid` comme clé étrangère.
|
||||
Cela pose problème lors des imports SAP qui peuvent écraser ou modifier les `rowid`.
|
||||
Il faut migrer vers `clients.code` (identifiant SAP immuable) pour garantir l'intégrité des relations.
|
||||
La relation entre `clients_contacts` et `clients` utilise `clients.code` comme clé de référence.
|
||||
Le système a été conçu pour utiliser le `code` SAP (clé métier immuable) plutôt que le `rowid` (clé technique auto-incrémentée).
|
||||
|
||||
### Plan de correction
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*M!999999\- enable the sandbox mode */
|
||||
-- MariaDB dump 10.19 Distrib 10.11.9-MariaDB, for debian-linux-gnu (x86_64)
|
||||
-- MariaDB dump 10.19-11.8.3-MariaDB, for debian-linux-gnu (x86_64)
|
||||
--
|
||||
-- Host: localhost Database: uof_linet
|
||||
-- Host: localhost Database: cleo
|
||||
-- ------------------------------------------------------
|
||||
-- Server version 10.11.9-MariaDB-deb12
|
||||
-- Server version 11.4.8-MariaDB-log
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
@@ -14,7 +14,7 @@
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */;
|
||||
|
||||
--
|
||||
-- Table structure for table `clients`
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
DROP TABLE IF EXISTS `clients`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `clients` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`code` int(11) NOT NULL,
|
||||
@@ -51,9 +51,38 @@ CREATE TABLE `clients` (
|
||||
UNIQUE KEY `code_UNIQUE` (`code`),
|
||||
KEY `libelle` (`libelle`),
|
||||
KEY `cp` (`cp`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=5307 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=5309 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `clients_contacts`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `clients_contacts`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `clients_contacts` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_client` int(11) NOT NULL,
|
||||
`nom` varchar(50) DEFAULT NULL,
|
||||
`prenom` varchar(50) DEFAULT NULL,
|
||||
`fonction` varchar(50) DEFAULT NULL,
|
||||
`telephone` varchar(20) DEFAULT NULL,
|
||||
`mobile` varchar(20) DEFAULT NULL,
|
||||
`email` varchar(75) DEFAULT NULL,
|
||||
`principal` tinyint(1) DEFAULT 0 COMMENT 'Contact principal du client',
|
||||
`active` tinyint(1) DEFAULT 1,
|
||||
`date_creat` datetime DEFAULT NULL,
|
||||
`fk_user_creat` int(11) DEFAULT NULL,
|
||||
`date_modif` datetime DEFAULT NULL,
|
||||
`fk_user_modif` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`rowid`),
|
||||
UNIQUE KEY `rowid_UNIQUE` (`rowid`),
|
||||
KEY `fk_client` (`fk_client`),
|
||||
KEY `principal` (`fk_client`,`principal`),
|
||||
KEY `email` (`email`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=8199 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='Contacts multiples par client' `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `clients_sites`
|
||||
@@ -61,7 +90,7 @@ CREATE TABLE `clients` (
|
||||
|
||||
DROP TABLE IF EXISTS `clients_sites`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `clients_sites` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_client` int(11) NOT NULL,
|
||||
@@ -77,22 +106,13 @@ CREATE TABLE `clients_sites` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `clients_sites`
|
||||
--
|
||||
|
||||
LOCK TABLES `clients_sites` WRITE;
|
||||
/*!40000 ALTER TABLE `clients_sites` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `clients_sites` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `commerciaux`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `commerciaux`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `commerciaux` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_entite` int(11) DEFAULT 0,
|
||||
@@ -133,14 +153,13 @@ CREATE TABLE `commerciaux` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `commerciaux_entites`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `commerciaux_entites`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `commerciaux_entites` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`libelle` varchar(45) DEFAULT NULL,
|
||||
@@ -157,26 +176,13 @@ CREATE TABLE `commerciaux_entites` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `commerciaux_entites`
|
||||
--
|
||||
|
||||
LOCK TABLES `commerciaux_entites` WRITE;
|
||||
/*!40000 ALTER TABLE `commerciaux_entites` DISABLE KEYS */;
|
||||
INSERT INTO `commerciaux_entites` VALUES
|
||||
(1,'LINET',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1),
|
||||
(2,'WISSNER-BOSSERHOFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1),
|
||||
(3,'LINET & WI-BO',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1);
|
||||
/*!40000 ALTER TABLE `commerciaux_entites` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `commerciaux_params`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `commerciaux_params`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `commerciaux_params` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_commercial` int(11) DEFAULT NULL,
|
||||
@@ -269,14 +275,13 @@ CREATE TABLE `commerciaux_params` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `devis`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `devis`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `devis` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_user` int(11) NOT NULL DEFAULT 0,
|
||||
@@ -285,6 +290,7 @@ CREATE TABLE `devis` (
|
||||
`date_remise` date DEFAULT NULL,
|
||||
`num_opportunite` varchar(8) NOT NULL DEFAULT '',
|
||||
`fk_client` int(11) NOT NULL DEFAULT 0,
|
||||
`fk_contact` int(11) DEFAULT NULL,
|
||||
`fk_marche` int(11) NOT NULL DEFAULT 0,
|
||||
`fk_statut_devis` int(11) NOT NULL DEFAULT 0,
|
||||
`chk_clients_secteur` tinyint(1) NOT NULL DEFAULT 1,
|
||||
@@ -327,18 +333,18 @@ CREATE TABLE `devis` (
|
||||
KEY `fk_client` (`fk_client`),
|
||||
KEY `fk_statut_devis` (`fk_statut_devis`),
|
||||
KEY `date_demande` (`date_demande`),
|
||||
KEY `dossier` (`fk_user`,`dossier`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4611 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
KEY `dossier` (`fk_user`,`dossier`),
|
||||
KEY `fk_contact` (`fk_contact`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4624 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `devis_histo`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `devis_histo`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `devis_histo` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_devis` int(11) DEFAULT NULL,
|
||||
@@ -350,7 +356,7 @@ CREATE TABLE `devis_histo` (
|
||||
`fk_statut_devis` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`rowid`),
|
||||
KEY `devis_histo_fk_devis_index` (`fk_devis`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=22331 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=22388 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -359,7 +365,7 @@ CREATE TABLE `devis_histo` (
|
||||
|
||||
DROP TABLE IF EXISTS `devis_produits`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `devis_produits` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_devis` int(11) NOT NULL,
|
||||
@@ -392,17 +398,16 @@ CREATE TABLE `devis_produits` (
|
||||
PRIMARY KEY (`rowid`),
|
||||
KEY `devis_produits__devis` (`fk_devis`),
|
||||
KEY `devis_produits__produit` (`fk_produit`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=29277 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=29314 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `devis_speciaux`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `devis_speciaux`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `devis_speciaux` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_devis` int(11) NOT NULL DEFAULT 0,
|
||||
@@ -461,14 +466,13 @@ CREATE TABLE `devis_speciaux` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `entites`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `entites`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entites` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`libelle` varchar(45) DEFAULT '',
|
||||
@@ -513,14 +517,13 @@ CREATE TABLE `entites` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `import_ventes`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `import_ventes`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `import_ventes` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`source` varchar(15) DEFAULT '',
|
||||
@@ -570,7 +573,7 @@ CREATE TABLE `import_ventes` (
|
||||
|
||||
DROP TABLE IF EXISTS `infos`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `infos` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`date_infos` date DEFAULT NULL,
|
||||
@@ -586,14 +589,13 @@ CREATE TABLE `infos` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `marches`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `marches`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `marches` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`numero` varchar(20) NOT NULL DEFAULT '',
|
||||
@@ -642,7 +644,7 @@ CREATE TABLE `marches` (
|
||||
|
||||
DROP TABLE IF EXISTS `marches_listes`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `marches_listes` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_marche` int(11) DEFAULT NULL,
|
||||
@@ -660,7 +662,7 @@ CREATE TABLE `marches_listes` (
|
||||
|
||||
DROP TABLE IF EXISTS `marches_produits`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `marches_produits` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_marche` int(11) DEFAULT 0,
|
||||
@@ -702,7 +704,7 @@ CREATE TABLE `marches_produits` (
|
||||
|
||||
DROP TABLE IF EXISTS `marches_versions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `marches_versions` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Id',
|
||||
`libelle` varchar(75) DEFAULT NULL COMMENT 'Libellé',
|
||||
@@ -713,24 +715,13 @@ CREATE TABLE `marches_versions` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='Version des marchés' `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `marches_versions`
|
||||
--
|
||||
|
||||
LOCK TABLES `marches_versions` WRITE;
|
||||
/*!40000 ALTER TABLE `marches_versions` DISABLE KEYS */;
|
||||
INSERT INTO `marches_versions` VALUES
|
||||
(1,'Version Avril 2022','2022-04-01','0000-00-00',1);
|
||||
/*!40000 ALTER TABLE `marches_versions` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `medias`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `medias`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `medias` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`dir0` varchar(150) DEFAULT NULL,
|
||||
@@ -746,7 +737,7 @@ CREATE TABLE `medias` (
|
||||
PRIMARY KEY (`rowid`),
|
||||
UNIQUE KEY `rowid_UNIQUE` (`rowid`),
|
||||
KEY `support` (`support`,`support_rowid`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3866 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3878 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -755,7 +746,7 @@ CREATE TABLE `medias` (
|
||||
|
||||
DROP TABLE IF EXISTS `notifications`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `notifications` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`dateheure` datetime DEFAULT NULL,
|
||||
@@ -775,7 +766,7 @@ CREATE TABLE `notifications` (
|
||||
|
||||
DROP TABLE IF EXISTS `produits`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `produits` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_marche` int(11) NOT NULL DEFAULT 0,
|
||||
@@ -821,7 +812,7 @@ CREATE TABLE `produits` (
|
||||
|
||||
DROP TABLE IF EXISTS `produits_familles`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `produits_familles` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`groupe` varchar(30) NOT NULL,
|
||||
@@ -841,7 +832,7 @@ CREATE TABLE `produits_familles` (
|
||||
|
||||
DROP TABLE IF EXISTS `regions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `regions` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`libelle` varchar(75) DEFAULT NULL,
|
||||
@@ -851,22 +842,13 @@ CREATE TABLE `regions` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `regions`
|
||||
--
|
||||
|
||||
LOCK TABLES `regions` WRITE;
|
||||
/*!40000 ALTER TABLE `regions` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `regions` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `simul`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `simul`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `simul` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_import_vente` int(11) DEFAULT NULL,
|
||||
@@ -885,14 +867,13 @@ CREATE TABLE `simul` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1057 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `users`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `users` (
|
||||
`rowid` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`fk_entite` int(11) DEFAULT NULL,
|
||||
@@ -940,13 +921,64 @@ CREATE TABLE `users` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `users_entites`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `users_entites`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `users_entites` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`libelle` varchar(45) DEFAULT '',
|
||||
`http_host` varchar(150) DEFAULT '',
|
||||
`adresse1` varchar(45) DEFAULT '',
|
||||
`adresse2` varchar(45) DEFAULT '',
|
||||
`cp` varchar(5) DEFAULT '',
|
||||
`ville` varchar(45) DEFAULT '',
|
||||
`type_entite` varchar(5) DEFAULT 'form',
|
||||
`tva_intra` varchar(15) DEFAULT '',
|
||||
`rcs` varchar(45) DEFAULT '',
|
||||
`siret` varchar(17) DEFAULT NULL,
|
||||
`ape` varchar(5) DEFAULT '',
|
||||
`num_opca` varchar(15) DEFAULT '',
|
||||
`logo` varchar(45) DEFAULT '',
|
||||
`tel1` varchar(20) DEFAULT '',
|
||||
`tel2` varchar(20) DEFAULT '',
|
||||
`couleur` varchar(7) DEFAULT '#FFFAF0',
|
||||
`prefecture` varchar(45) DEFAULT 'Bretagne',
|
||||
`fk_titre_gerant` int(11) DEFAULT 1,
|
||||
`gerant_prenom` varchar(45) DEFAULT '',
|
||||
`gerant_nom` varchar(45) DEFAULT '',
|
||||
`email` varchar(45) DEFAULT '',
|
||||
`site_url` varchar(45) DEFAULT '',
|
||||
`gerant_signature` varchar(45) DEFAULT '',
|
||||
`tampon_signature` varchar(45) DEFAULT '',
|
||||
`rib_banque` varchar(5) DEFAULT '',
|
||||
`rib_guichet` varchar(5) DEFAULT '',
|
||||
`rib_compte` varchar(11) DEFAULT '',
|
||||
`rib_cle` varchar(2) DEFAULT '',
|
||||
`rib_domiciliation` varchar(45) DEFAULT '',
|
||||
`iban` varchar(33) DEFAULT '',
|
||||
`bic` varchar(15) DEFAULT '',
|
||||
`demo` tinyint(1) DEFAULT 0,
|
||||
`genbase` varchar(45) DEFAULT '0',
|
||||
`groupebase` varchar(45) DEFAULT '0',
|
||||
`table_users_gen` varchar(50) DEFAULT '',
|
||||
`appname` varchar(45) DEFAULT '',
|
||||
`raz_num_devis` tinyint(1) DEFAULT 0,
|
||||
`active` tinyint(1) DEFAULT 1,
|
||||
PRIMARY KEY (`rowid`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `ventes`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `ventes`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `ventes` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`source` varchar(45) DEFAULT NULL,
|
||||
@@ -977,22 +1009,13 @@ CREATE TABLE `ventes` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `ventes`
|
||||
--
|
||||
|
||||
LOCK TABLES `ventes` WRITE;
|
||||
/*!40000 ALTER TABLE `ventes` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `ventes` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `x_clients_types`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `x_clients_types`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `x_clients_types` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`code` char(3) DEFAULT NULL,
|
||||
@@ -1004,28 +1027,13 @@ CREATE TABLE `x_clients_types` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `x_clients_types`
|
||||
--
|
||||
|
||||
LOCK TABLES `x_clients_types` WRITE;
|
||||
/*!40000 ALTER TABLE `x_clients_types` DISABLE KEYS */;
|
||||
INSERT INTO `x_clients_types` VALUES
|
||||
(1,'PUB','Public',1),
|
||||
(2,'PRA','Privé Associatif',1),
|
||||
(3,'PRD','Privé Distributeur',1),
|
||||
(4,'PRC','Privé Commercial',1),
|
||||
(5,'ESP','ESPIC',1);
|
||||
/*!40000 ALTER TABLE `x_clients_types` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `x_familles`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `x_familles`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `x_familles` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`libelle` varchar(20) NOT NULL DEFAULT '',
|
||||
@@ -1037,34 +1045,13 @@ CREATE TABLE `x_familles` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `x_familles`
|
||||
--
|
||||
|
||||
LOCK TABLES `x_familles` WRITE;
|
||||
/*!40000 ALTER TABLE `x_familles` DISABLE KEYS */;
|
||||
INSERT INTO `x_familles` VALUES
|
||||
(3,'Lits SBU1',1,1),
|
||||
(4,'Lits SBU2',2,1),
|
||||
(5,'Accessoires SBU1',3,1),
|
||||
(6,'Accessoires SBU2',4,1),
|
||||
(7,'Services',5,1),
|
||||
(8,'Matelas mousse',6,1),
|
||||
(9,'Matelas à air',7,1),
|
||||
(10,'Mobilier',8,1),
|
||||
(11,'Assises',9,1),
|
||||
(12,'Autres',11,1),
|
||||
(13,'Domalys',10,1);
|
||||
/*!40000 ALTER TABLE `x_familles` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `x_regions`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `x_regions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `x_regions` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_entite` int(11) DEFAULT 0,
|
||||
@@ -1075,39 +1062,13 @@ CREATE TABLE `x_regions` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `x_regions`
|
||||
--
|
||||
|
||||
LOCK TABLES `x_regions` WRITE;
|
||||
/*!40000 ALTER TABLE `x_regions` DISABLE KEYS */;
|
||||
INSERT INTO `x_regions` VALUES
|
||||
(1,1,'SUD-OUEST',1),
|
||||
(2,1,'RHONE-ALPES / AUVERGNE',1),
|
||||
(3,1,'PACA',1),
|
||||
(4,1,'EST',1),
|
||||
(5,1,'NORD',1),
|
||||
(6,1,'GRAND-OUEST',1),
|
||||
(7,1,'IDF',1),
|
||||
(8,1,'DOM-TOM',1),
|
||||
(9,2,'WB-NORD',1),
|
||||
(13,2,'WB-SUD OUEST',1),
|
||||
(14,2,'WB-EST',1),
|
||||
(15,2,'WB-ILE DE FRANCE',1),
|
||||
(16,2,'WB-SUD-EST',1),
|
||||
(17,2,'WB-CENTRE-EST ET DOM',1),
|
||||
(18,1,'DIRECTION',1),
|
||||
(19,2,'WB-NORD OUEST',1);
|
||||
/*!40000 ALTER TABLE `x_regions` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `x_roles`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `x_roles`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `x_roles` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`libelle` varchar(45) DEFAULT '',
|
||||
@@ -1118,30 +1079,13 @@ CREATE TABLE `x_roles` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=91 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='Les différents rôles des utilisateurs' `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `x_roles`
|
||||
--
|
||||
|
||||
LOCK TABLES `x_roles` WRITE;
|
||||
/*!40000 ALTER TABLE `x_roles` DISABLE KEYS */;
|
||||
INSERT INTO `x_roles` VALUES
|
||||
(1,'Direction Commerciale','DC',1),
|
||||
(2,'Direction des Ventes','DV',1),
|
||||
(3,'Commercial(e)','RR',1),
|
||||
(4,'Clinicien(ne)','CL',1),
|
||||
(5,'Direction Grands Comptes','GC',1),
|
||||
(20,'Administration des ventes','ADV',1),
|
||||
(90,'Administrateur','ADM',1);
|
||||
/*!40000 ALTER TABLE `x_roles` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `x_statuts_devis`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `x_statuts_devis`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `x_statuts_devis` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`libelle` varchar(30) DEFAULT NULL,
|
||||
@@ -1152,22 +1096,47 @@ CREATE TABLE `x_statuts_devis` (
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `x_statuts_devis`
|
||||
-- Table structure for table `y_pages`
|
||||
--
|
||||
|
||||
LOCK TABLES `x_statuts_devis` WRITE;
|
||||
/*!40000 ALTER TABLE `x_statuts_devis` DISABLE KEYS */;
|
||||
INSERT INTO `x_statuts_devis` VALUES
|
||||
(1,'En cours de création',1),
|
||||
(2,'En cours de validation DIR-CO',1),
|
||||
(3,'En cours de validation DV/DGC',1),
|
||||
(4,'A traiter sur SAP',1),
|
||||
(6,'A vérifier par le RR',1),
|
||||
(7,'A envoyer au client',1),
|
||||
(10,'Envoyé au client',0),
|
||||
(20,'Archivé',1);
|
||||
/*!40000 ALTER TABLE `x_statuts_devis` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE IF EXISTS `y_pages`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `y_pages` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`fk_parent` int(11) DEFAULT 0,
|
||||
`link` varchar(75) DEFAULT NULL,
|
||||
`libelle` varchar(45) DEFAULT NULL,
|
||||
`titre` varchar(75) DEFAULT NULL,
|
||||
`tooltip` varchar(45) DEFAULT NULL,
|
||||
`description` varchar(200) DEFAULT NULL,
|
||||
`keywords` varchar(200) DEFAULT NULL,
|
||||
`script` varchar(45) DEFAULT NULL,
|
||||
`enmaintenance` tinyint(1) DEFAULT 0 COMMENT '0 libre d''accès, 1 en maintenance mais accès aux données, 2 en maintenance sans accès aux données',
|
||||
`admin` tinyint(1) DEFAULT 0,
|
||||
`mail` tinyint(1) DEFAULT 0,
|
||||
`admtools` tinyint(1) DEFAULT 0,
|
||||
`magazine` tinyint(1) DEFAULT 0,
|
||||
`files` tinyint(1) DEFAULT 0,
|
||||
`editor` tinyint(1) DEFAULT 0,
|
||||
`autocomplete` tinyint(1) DEFAULT 0,
|
||||
`print` tinyint(1) DEFAULT 0,
|
||||
`form` tinyint(1) DEFAULT 0,
|
||||
`sidebar` tinyint(1) DEFAULT 0,
|
||||
`chart` tinyint(1) DEFAULT 0,
|
||||
`agenda` tinyint(1) DEFAULT 0,
|
||||
`scheduler` tinyint(1) DEFAULT 0,
|
||||
`osm` tinyint(1) DEFAULT 0,
|
||||
`layout` varchar(45) DEFAULT 'default.php',
|
||||
`in_menu` tinyint(1) DEFAULT 1,
|
||||
`ordre_menu` int(11) DEFAULT 0,
|
||||
`active` tinyint(1) DEFAULT 1,
|
||||
PRIMARY KEY (`rowid`),
|
||||
UNIQUE KEY `rowid_UNIQUE` (`rowid`),
|
||||
KEY `script` (`script`),
|
||||
KEY `admin` (`admin`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `z_history`
|
||||
@@ -1175,7 +1144,7 @@ UNLOCK TABLES;
|
||||
|
||||
DROP TABLE IF EXISTS `z_history`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `z_history` (
|
||||
`fk_user` int(11) NOT NULL,
|
||||
`libelle` varchar(20) NOT NULL DEFAULT 'tiers',
|
||||
@@ -1185,22 +1154,13 @@ CREATE TABLE `z_history` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `z_history`
|
||||
--
|
||||
|
||||
LOCK TABLES `z_history` WRITE;
|
||||
/*!40000 ALTER TABLE `z_history` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `z_history` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `z_logs`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `z_logs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `z_logs` (
|
||||
`date` datetime NOT NULL,
|
||||
`ip` varchar(15) NOT NULL,
|
||||
@@ -1220,7 +1180,7 @@ CREATE TABLE `z_logs` (
|
||||
|
||||
DROP TABLE IF EXISTS `z_sessions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `z_sessions` (
|
||||
`sid` text NOT NULL,
|
||||
`fk_user` int(11) NOT NULL,
|
||||
@@ -1238,7 +1198,7 @@ CREATE TABLE `z_sessions` (
|
||||
|
||||
DROP TABLE IF EXISTS `z_stats`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `z_stats` (
|
||||
`rowid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`libelle` varchar(75) DEFAULT NULL,
|
||||
@@ -1253,6 +1213,10 @@ CREATE TABLE `z_stats` (
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci `PAGE_COMPRESSED`='ON';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping routines for database 'cleo'
|
||||
--
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
@@ -1260,6 +1224,6 @@ CREATE TABLE `z_stats` (
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */;
|
||||
|
||||
-- Dump completed on 2025-09-11 14:44:41
|
||||
-- Dump completed on 2025-12-02 11:57:09
|
||||
@@ -1,8 +1,7 @@
|
||||
<?php
|
||||
global $Route;
|
||||
|
||||
function cleanData(&$str)
|
||||
{
|
||||
function cleanData(&$str) {
|
||||
// Fonction de nettoyage des données pour l'export Excel
|
||||
if ($str == 't') $str = 'TRUE';
|
||||
if ($str == 'f') $str = 'FALSE';
|
||||
@@ -13,8 +12,7 @@ function cleanData(&$str)
|
||||
$str = mb_convert_encoding($str, 'UTF-16LE', 'UTF-8');
|
||||
}
|
||||
|
||||
function filterData(&$str)
|
||||
{
|
||||
function filterData(&$str) {
|
||||
$str = preg_replace("/\t/", "\\t", $str);
|
||||
$str = preg_replace("/\r?\n/", "\\n", $str);
|
||||
if ($str == 't') $str = 'TRUE';
|
||||
@@ -95,7 +93,6 @@ switch ($Route->_action) {
|
||||
$excelData .= implode("\t", array_values($fields)) . "\n";
|
||||
array_walk($contact, 'filterData');
|
||||
$excelData .= implode("\t", array_values($contact)) . "\n";
|
||||
|
||||
} else {
|
||||
// Client existant : données depuis la table clients
|
||||
$sql = 'SELECT c.code, c.libelle, c.adresse1, c.adresse2, c.adresse3, c.cp, c.ville FROM clients c WHERE c.rowid = :client_id';
|
||||
@@ -112,7 +109,7 @@ switch ($Route->_action) {
|
||||
$contact = $db->fetchOne($sql, [':contact_id' => $fkContactSafe]);
|
||||
} else {
|
||||
// Fallback : contact principal du client
|
||||
$sql = 'SELECT cc.nom, cc.prenom, cc.fonction, cc.telephone, cc.mobile, cc.email FROM clients_contacts cc WHERE cc.fk_client = :client_id AND cc.chk_principal = 1 AND cc.active = 1 LIMIT 1';
|
||||
$sql = 'SELECT cc.nom, cc.prenom, cc.fonction, cc.telephone, cc.mobile, cc.email FROM clients_contacts cc WHERE cc.fk_client = :client_id AND cc.principal = 1 AND cc.active = 1 LIMIT 1';
|
||||
$contact = $db->fetchOne($sql, [':client_id' => $fkClientSafe]);
|
||||
}
|
||||
|
||||
@@ -217,12 +214,10 @@ switch ($Route->_action) {
|
||||
header('Content-Disposition: attachment; filename="' . $fileName . '"');
|
||||
header('Cache-Control: max-age=0');
|
||||
echo $excelData;
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur export Excel : " . $e->getMessage());
|
||||
http_response_code(500);
|
||||
echo "Erreur lors de l'export du devis";
|
||||
}
|
||||
exit();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ $aModel = array();
|
||||
$sql = 'SELECT m.* FROM medias m WHERE m.support="devis_pdf_sap" ORDER BY m.support_rowid;';
|
||||
$aModel["medias"] = getinfos($sql, "gen");
|
||||
|
||||
$sql = 'SELECT d.*, c.libelle, c.adresse1, c.adresse2, c.adresse3, c.code, c.cp, c.ville, c.email, u.libelle as nom, u.prenom, s.libelle as lib_statut, m.libelle as lib_marche ';
|
||||
$sql = 'SELECT d.*, c.libelle, c.adresse1, c.adresse2, c.adresse3, c.code, c.cp, c.ville, cc.email, u.libelle as nom, u.prenom, s.libelle as lib_statut, m.libelle as lib_marche ';
|
||||
$sql .= 'FROM devis d ';
|
||||
$sql .= 'LEFT JOIN clients c on d.fk_client = c.rowid ';
|
||||
$sql .= 'LEFT JOIN clients_contacts cc ON d.fk_contact = cc.rowid ';
|
||||
$sql .= 'LEFT JOIN users u ON d.fk_user = u.rowid ';
|
||||
$sql .= 'LEFT JOIN marches m ON d.fk_marche = m.rowid ';
|
||||
$sql .= 'LEFT JOIN x_statuts_devis s ON d.fk_statut_devis = s.rowid ';
|
||||
@@ -24,9 +25,10 @@ foreach ($aModel["devisEnCours"] as $devis) {
|
||||
}
|
||||
}
|
||||
|
||||
$sql = 'SELECT d.*, c.libelle, c.adresse1, c.adresse2, c.adresse3, c.code, c.cp, c.ville, u.libelle as nom, u.prenom, s.libelle as lib_statut, m.libelle as lib_marche ';
|
||||
$sql = 'SELECT d.*, c.libelle, c.adresse1, c.adresse2, c.adresse3, c.code, c.cp, c.ville, cc.email, u.libelle as nom, u.prenom, s.libelle as lib_statut, m.libelle as lib_marche ';
|
||||
$sql .= 'FROM devis d ';
|
||||
$sql .= 'LEFT JOIN clients c on d.fk_client = c.rowid ';
|
||||
$sql .= 'LEFT JOIN clients_contacts cc ON d.fk_contact = cc.rowid ';
|
||||
$sql .= 'LEFT JOIN users u ON d.fk_user = u.rowid ';
|
||||
$sql .= 'LEFT JOIN marches m ON d.fk_marche = m.rowid ';
|
||||
$sql .= 'LEFT JOIN x_statuts_devis s ON d.fk_statut_devis = s.rowid ';
|
||||
|
||||
@@ -37,14 +37,107 @@ let devisTotalRemHT = 0
|
||||
let devisTotalMarge = 0
|
||||
|
||||
let chkRegleSeuilsMarge = false // indique si le marché sélectionné prend en compte les seuils de marge fixés dans les familles de produits
|
||||
let seuilMargeRR = 30 // le seuil de marge du RR sur ce devis, par défaut à 30 %
|
||||
let seuilMargeDV = 20 // le seuil de marge du DV sur ce devis, par défaut à 20 %
|
||||
let seuilMargeRR = 40 // le seuil de marge du RR sur ce devis, par défaut à 40 % (MAJ 05/11/2025)
|
||||
let seuilMargeDV = 30 // le seuil de marge du DV sur ce devis, par défaut à 30 % (MAJ 05/11/2025)
|
||||
|
||||
let intervalRefresh
|
||||
let nbCommentChat = 0
|
||||
|
||||
let draggedElement = null // l'élément qui est en train d'être déplacé (la ligne du produit du devis lors d'un drag and drop)
|
||||
|
||||
const tableSortStates = new Map()
|
||||
|
||||
function initTableSort() {
|
||||
const allTables = document.querySelectorAll('[id^="tblDos"], [id^="tblDosArch"]')
|
||||
|
||||
allTables.forEach(table => {
|
||||
const tableId = table.id
|
||||
const headers = table.querySelectorAll('th[data-sortable="true"]')
|
||||
const tbody = table.querySelector('tbody')
|
||||
|
||||
if (!tbody) return
|
||||
|
||||
if (!tableSortStates.has(tableId)) {
|
||||
tableSortStates.set(tableId, {
|
||||
originalOrder: null,
|
||||
currentSort: { column: null, direction: null }
|
||||
})
|
||||
}
|
||||
|
||||
headers.forEach(header => {
|
||||
header.addEventListener('click', function() {
|
||||
const columnIndex = parseInt(this.getAttribute('data-column-index'))
|
||||
const sortType = this.getAttribute('data-sort-type')
|
||||
sortTable(tableId, columnIndex, sortType, this)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function sortTable(tableId, columnIndex, sortType, headerElement) {
|
||||
const table = document.getElementById(tableId)
|
||||
const tbody = table.querySelector('tbody')
|
||||
const rows = Array.from(tbody.querySelectorAll('tr'))
|
||||
const state = tableSortStates.get(tableId)
|
||||
|
||||
if (!state.originalOrder) {
|
||||
state.originalOrder = rows.slice()
|
||||
}
|
||||
|
||||
const allHeaders = table.querySelectorAll('th[data-sortable="true"]')
|
||||
allHeaders.forEach(h => h.style.fontWeight = 'normal')
|
||||
|
||||
let sortedRows
|
||||
|
||||
if (state.currentSort.column === columnIndex && state.currentSort.direction === 'desc') {
|
||||
sortedRows = state.originalOrder.slice()
|
||||
state.currentSort = { column: null, direction: null }
|
||||
} else {
|
||||
const direction = (state.currentSort.column === columnIndex && state.currentSort.direction === 'asc') ? 'desc' : 'asc'
|
||||
|
||||
sortedRows = rows.slice().sort((a, b) => {
|
||||
const aCell = a.cells[columnIndex]
|
||||
const bCell = b.cells[columnIndex]
|
||||
|
||||
if (!aCell || !bCell) return 0
|
||||
|
||||
let aValue = aCell.textContent.trim()
|
||||
let bValue = bCell.textContent.trim()
|
||||
|
||||
if (sortType === 'number') {
|
||||
aValue = aValue.replace(/[^\d,.-]/g, '').replace(',', '.')
|
||||
bValue = bValue.replace(/[^\d,.-]/g, '').replace(',', '.')
|
||||
aValue = parseFloat(aValue) || 0
|
||||
bValue = parseFloat(bValue) || 0
|
||||
return direction === 'asc' ? aValue - bValue : bValue - aValue
|
||||
} else if (sortType === 'date') {
|
||||
aValue = parseDateFromText(aValue)
|
||||
bValue = parseDateFromText(bValue)
|
||||
if (!aValue && !bValue) return 0
|
||||
if (!aValue) return direction === 'asc' ? 1 : -1
|
||||
if (!bValue) return direction === 'asc' ? -1 : 1
|
||||
return direction === 'asc' ? aValue - bValue : bValue - aValue
|
||||
} else {
|
||||
const comparison = aValue.localeCompare(bValue, 'fr')
|
||||
return direction === 'asc' ? comparison : -comparison
|
||||
}
|
||||
})
|
||||
|
||||
state.currentSort = { column: columnIndex, direction }
|
||||
headerElement.style.fontWeight = 'bold'
|
||||
}
|
||||
|
||||
tbody.innerHTML = ''
|
||||
sortedRows.forEach(row => tbody.appendChild(row))
|
||||
}
|
||||
|
||||
function parseDateFromText(dateText) {
|
||||
const match = dateText.match(/(\d{2})\/(\d{2})[\/\s](\d{4})/)
|
||||
if (!match) return null
|
||||
const [, day, month, year] = match
|
||||
return new Date(year, month - 1, day)
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
console.log('#')
|
||||
|
||||
@@ -3790,6 +3883,148 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
chkVariante.addEventListener('change', calculDevis)
|
||||
})
|
||||
|
||||
let elSearchDevis = document.getElementById('searchDevis')
|
||||
let elBtnResetSearch = document.getElementById('btnResetSearch')
|
||||
let searchTimeout = null
|
||||
|
||||
function restoreSearch() {
|
||||
const savedTerm = sessionStorage.getItem('devisSearchTerm')
|
||||
if (savedTerm && savedTerm.length >= 3) {
|
||||
elSearchDevis.value = savedTerm
|
||||
elBtnResetSearch.style.display = 'inline-block'
|
||||
performSearch(savedTerm)
|
||||
}
|
||||
}
|
||||
|
||||
function performSearch(term) {
|
||||
if (term.length < 3) {
|
||||
return
|
||||
}
|
||||
|
||||
const context = chkShowDevisArchives ? 'archives' : 'encours'
|
||||
|
||||
fetch('/jxdevis/search_devis', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
term: term,
|
||||
context: context,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
const devisIds = data.devis.map((d) => d.rowid)
|
||||
filterDevisTables(devisIds, context)
|
||||
updateBadges(data.nb_devis)
|
||||
} else {
|
||||
console.error('Erreur recherche:', data.message)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Erreur AJAX:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function filterDevisTables(devisIds, context) {
|
||||
if (context === 'encours') {
|
||||
const statuts = document.querySelectorAll('[id^="tblBodyDos"]')
|
||||
statuts.forEach((tbody) => {
|
||||
const rows = tbody.querySelectorAll('tr')
|
||||
rows.forEach((row) => {
|
||||
if (row.id && row.id.startsWith('tr_')) {
|
||||
const rowId = parseInt(row.id.replace('tr_', ''))
|
||||
if (devisIds.includes(rowId)) {
|
||||
row.style.display = ''
|
||||
} else {
|
||||
row.style.display = 'none'
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
const archives = document.querySelectorAll('[id^="tblBodyDosArch"]')
|
||||
archives.forEach((tbody) => {
|
||||
const rows = tbody.querySelectorAll('tr')
|
||||
rows.forEach((row) => {
|
||||
if (row.id && row.id.startsWith('trArch_')) {
|
||||
const rowId = parseInt(row.id.replace('trArch_', ''))
|
||||
if (devisIds.includes(rowId)) {
|
||||
row.style.display = ''
|
||||
} else {
|
||||
row.style.display = 'none'
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function updateBadges(nbDevis) {
|
||||
Object.keys(nbDevis).forEach((statutId) => {
|
||||
const badge = document.querySelector('[id^="liStat"]')
|
||||
if (badge) {
|
||||
badge.setAttribute('data-after-text', nbDevis[statutId])
|
||||
badge.setAttribute('data-after-type', 'orange badge top left')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function resetSearch() {
|
||||
elSearchDevis.value = ''
|
||||
elBtnResetSearch.style.display = 'none'
|
||||
sessionStorage.removeItem('devisSearchTerm')
|
||||
|
||||
const context = chkShowDevisArchives ? 'archives' : 'encours'
|
||||
if (context === 'encours') {
|
||||
const statuts = document.querySelectorAll('[id^="tblBodyDos"]')
|
||||
statuts.forEach((tbody) => {
|
||||
const rows = tbody.querySelectorAll('tr')
|
||||
rows.forEach((row) => {
|
||||
row.style.display = ''
|
||||
})
|
||||
})
|
||||
} else {
|
||||
const archives = document.querySelectorAll('[id^="tblBodyDosArch"]')
|
||||
archives.forEach((tbody) => {
|
||||
const rows = tbody.querySelectorAll('tr')
|
||||
rows.forEach((row) => {
|
||||
row.style.display = ''
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
elSearchDevis.addEventListener('input', function () {
|
||||
const term = this.value.trim()
|
||||
|
||||
if (searchTimeout) {
|
||||
clearTimeout(searchTimeout)
|
||||
}
|
||||
|
||||
if (term.length >= 3) {
|
||||
elBtnResetSearch.style.display = 'inline-block'
|
||||
sessionStorage.setItem('devisSearchTerm', term)
|
||||
searchTimeout = setTimeout(() => {
|
||||
performSearch(term)
|
||||
}, 300)
|
||||
} else if (term.length === 0) {
|
||||
resetSearch()
|
||||
} else {
|
||||
elBtnResetSearch.style.display = 'none'
|
||||
}
|
||||
})
|
||||
|
||||
elBtnResetSearch.addEventListener('click', function () {
|
||||
resetSearch()
|
||||
})
|
||||
|
||||
restoreSearch()
|
||||
|
||||
initTableSort()
|
||||
|
||||
elBtnSideBarDevis.addEventListener('click', function () {
|
||||
if (elVerticalBar.style.width == '10px') {
|
||||
elVerticalBar.style.width = '1100px' // Largeur de la barre lorsqu'elle est ouverte
|
||||
|
||||
@@ -11,6 +11,100 @@ let oldIdLnEnCours;
|
||||
let oldIdLnArchives;
|
||||
let nbCommentChat = 0;
|
||||
let selectedXmlDevis = new Set();
|
||||
let searchSapTimeout = null;
|
||||
|
||||
const tableSortStates = new Map();
|
||||
|
||||
function initTableSort() {
|
||||
const allTables = document.querySelectorAll('[id^="tblDos"], [id^="tblDosArch"]');
|
||||
|
||||
allTables.forEach(table => {
|
||||
const tableId = table.id;
|
||||
const headers = table.querySelectorAll('th[data-sortable="true"]');
|
||||
const tbody = table.querySelector('tbody');
|
||||
|
||||
if (!tbody) return;
|
||||
|
||||
if (!tableSortStates.has(tableId)) {
|
||||
tableSortStates.set(tableId, {
|
||||
originalOrder: null,
|
||||
currentSort: { column: null, direction: null }
|
||||
});
|
||||
}
|
||||
|
||||
headers.forEach(header => {
|
||||
header.addEventListener('click', function() {
|
||||
const columnIndex = parseInt(this.getAttribute('data-column-index'));
|
||||
const sortType = this.getAttribute('data-sort-type');
|
||||
sortTable(tableId, columnIndex, sortType, this);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function sortTable(tableId, columnIndex, sortType, headerElement) {
|
||||
const table = document.getElementById(tableId);
|
||||
const tbody = table.querySelector('tbody');
|
||||
const rows = Array.from(tbody.querySelectorAll('tr'));
|
||||
const state = tableSortStates.get(tableId);
|
||||
|
||||
if (!state.originalOrder) {
|
||||
state.originalOrder = rows.slice();
|
||||
}
|
||||
|
||||
const allHeaders = table.querySelectorAll('th[data-sortable="true"]');
|
||||
allHeaders.forEach(h => h.style.fontWeight = 'normal');
|
||||
|
||||
let sortedRows;
|
||||
|
||||
if (state.currentSort.column === columnIndex && state.currentSort.direction === 'desc') {
|
||||
sortedRows = state.originalOrder.slice();
|
||||
state.currentSort = { column: null, direction: null };
|
||||
} else {
|
||||
const direction = (state.currentSort.column === columnIndex && state.currentSort.direction === 'asc') ? 'desc' : 'asc';
|
||||
|
||||
sortedRows = rows.slice().sort((a, b) => {
|
||||
const aCell = a.cells[columnIndex];
|
||||
const bCell = b.cells[columnIndex];
|
||||
|
||||
if (!aCell || !bCell) return 0;
|
||||
|
||||
let aValue = aCell.textContent.trim();
|
||||
let bValue = bCell.textContent.trim();
|
||||
|
||||
if (sortType === 'number') {
|
||||
aValue = aValue.replace(/[^\d,.-]/g, '').replace(',', '.');
|
||||
bValue = bValue.replace(/[^\d,.-]/g, '').replace(',', '.');
|
||||
aValue = parseFloat(aValue) || 0;
|
||||
bValue = parseFloat(bValue) || 0;
|
||||
return direction === 'asc' ? aValue - bValue : bValue - aValue;
|
||||
} else if (sortType === 'date') {
|
||||
aValue = parseDateFromText(aValue);
|
||||
bValue = parseDateFromText(bValue);
|
||||
if (!aValue && !bValue) return 0;
|
||||
if (!aValue) return direction === 'asc' ? 1 : -1;
|
||||
if (!bValue) return direction === 'asc' ? -1 : 1;
|
||||
return direction === 'asc' ? aValue - bValue : bValue - aValue;
|
||||
} else {
|
||||
const comparison = aValue.localeCompare(bValue, 'fr');
|
||||
return direction === 'asc' ? comparison : -comparison;
|
||||
}
|
||||
});
|
||||
|
||||
state.currentSort = { column: columnIndex, direction };
|
||||
headerElement.style.fontWeight = 'bold';
|
||||
}
|
||||
|
||||
tbody.innerHTML = '';
|
||||
sortedRows.forEach(row => tbody.appendChild(row));
|
||||
}
|
||||
|
||||
function parseDateFromText(dateText) {
|
||||
const match = dateText.match(/(\d{2})\/(\d{2})[\/\s](\d{4})/);
|
||||
if (!match) return null;
|
||||
const [, day, month, year] = match;
|
||||
return new Date(year, month - 1, day);
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
console.log('#');
|
||||
@@ -786,6 +880,201 @@ window.addEventListener('DOMContentLoaded', (event) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
// Fonctions de recherche SAP
|
||||
let elSearchSAP = document.getElementById('searchSAP');
|
||||
let elBtnResetSearchSAP = document.getElementById('btnResetSearchSAP');
|
||||
|
||||
function restoreSearchSAP() {
|
||||
const storageKey = panel === 'enCours' ? 'sapSearchTermEnCours' : 'sapSearchTermArchives';
|
||||
const savedTerm = sessionStorage.getItem(storageKey);
|
||||
if (savedTerm && savedTerm.length >= 3) {
|
||||
elSearchSAP.value = savedTerm;
|
||||
elBtnResetSearchSAP.style.display = 'inline-block';
|
||||
performSearchSAP(savedTerm);
|
||||
} else {
|
||||
elSearchSAP.value = '';
|
||||
elBtnResetSearchSAP.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function performSearchSAP(term) {
|
||||
if (term.length < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
const context = panel === 'archives' ? 'archives' : 'encours';
|
||||
|
||||
fetch('/jxdevis/search_devis_sap', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
term: term,
|
||||
context: context,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
const devisIds = data.devis.map((d) => d.rowid);
|
||||
filterDevisTablesSAP(devisIds, context);
|
||||
updateBadgesSAP(data.nb_devis);
|
||||
} else {
|
||||
console.error('Erreur recherche:', data.message);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Erreur AJAX:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function filterDevisTablesSAP(devisIds, context) {
|
||||
if (context === 'encours') {
|
||||
const statuts = document.querySelectorAll('[id^="tblBodyDos"]');
|
||||
statuts.forEach((tbody) => {
|
||||
const rows = tbody.querySelectorAll('tr.ligEnCours');
|
||||
rows.forEach((row) => {
|
||||
const cells = row.querySelectorAll('.celEnCours');
|
||||
if (cells.length > 0) {
|
||||
const rowId = parseInt(cells[0].getAttribute('data-rid'));
|
||||
if (devisIds.includes(rowId)) {
|
||||
row.style.display = '';
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const archives = document.querySelectorAll('[id^="tblBodyDosArch"]');
|
||||
archives.forEach((tbody) => {
|
||||
const rows = tbody.querySelectorAll('tr');
|
||||
rows.forEach((row) => {
|
||||
if (row.id && (row.id.startsWith('trArch_') || row.id.startsWith('trArchTous_'))) {
|
||||
const rowId = parseInt(row.id.replace('trArch_', '').replace('trArchTous_', ''));
|
||||
if (devisIds.includes(rowId)) {
|
||||
row.style.display = '';
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateBadgesSAP(nbDevis) {
|
||||
Object.keys(nbDevis).forEach((statutId) => {
|
||||
const liElements = document.querySelectorAll('[id^="liStat"]');
|
||||
liElements.forEach((li) => {
|
||||
li.setAttribute('data-after-text', nbDevis[statutId] || '0');
|
||||
li.setAttribute('data-after-type', 'orange badge top left');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function resetSearchSAP() {
|
||||
elSearchSAP.value = '';
|
||||
elBtnResetSearchSAP.style.display = 'none';
|
||||
const storageKey = panel === 'enCours' ? 'sapSearchTermEnCours' : 'sapSearchTermArchives';
|
||||
sessionStorage.removeItem(storageKey);
|
||||
|
||||
const context = panel === 'archives' ? 'archives' : 'encours';
|
||||
if (context === 'encours') {
|
||||
const statuts = document.querySelectorAll('[id^="tblBodyDos"]');
|
||||
statuts.forEach((tbody) => {
|
||||
const rows = tbody.querySelectorAll('tr');
|
||||
rows.forEach((row) => {
|
||||
row.style.display = '';
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const archives = document.querySelectorAll('[id^="tblBodyDosArch"]');
|
||||
archives.forEach((tbody) => {
|
||||
const rows = tbody.querySelectorAll('tr');
|
||||
rows.forEach((row) => {
|
||||
row.style.display = '';
|
||||
});
|
||||
});
|
||||
const tbodyTous = document.getElementById('tblBodyDosArchTous');
|
||||
if (tbodyTous) {
|
||||
const rowsTous = tbodyTous.querySelectorAll('tr');
|
||||
rowsTous.forEach((row) => {
|
||||
row.style.display = '';
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elSearchSAP.addEventListener('input', function () {
|
||||
const term = this.value.trim();
|
||||
|
||||
if (searchSapTimeout) {
|
||||
clearTimeout(searchSapTimeout);
|
||||
}
|
||||
|
||||
if (term.length >= 3) {
|
||||
elBtnResetSearchSAP.style.display = 'inline-block';
|
||||
const storageKey = panel === 'enCours' ? 'sapSearchTermEnCours' : 'sapSearchTermArchives';
|
||||
sessionStorage.setItem(storageKey, term);
|
||||
searchSapTimeout = setTimeout(() => {
|
||||
performSearchSAP(term);
|
||||
}, 300);
|
||||
} else if (term.length === 0) {
|
||||
resetSearchSAP();
|
||||
} else {
|
||||
elBtnResetSearchSAP.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
elBtnResetSearchSAP.addEventListener('click', function () {
|
||||
resetSearchSAP();
|
||||
});
|
||||
|
||||
// Hook sur changement d'onglet pour restaurer la recherche appropriée
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
if ($(this).attr('href') == '#tabEnCours') {
|
||||
panel = 'enCours';
|
||||
restoreSearchSAP();
|
||||
} else if ($(this).attr('href') == '#tabArchives') {
|
||||
panel = 'archives';
|
||||
restoreSearchSAP();
|
||||
}
|
||||
});
|
||||
|
||||
restoreSearchSAP();
|
||||
|
||||
initTableSort();
|
||||
|
||||
// Gestion des états actifs des onglets départements (multiples <ul>)
|
||||
// Utiliser l'événement Bootstrap 'shown.bs.tab' au lieu de 'click'
|
||||
const allDeptTabs = document.querySelectorAll('.dept-tab a');
|
||||
allDeptTabs.forEach((tab) => {
|
||||
$(tab).on('shown.bs.tab', function(e) {
|
||||
// Retirer 'active' de tous les onglets départements sauf celui-ci
|
||||
document.querySelectorAll('.dept-tab').forEach((li) => {
|
||||
if (li !== this.parentElement) {
|
||||
li.classList.remove('active');
|
||||
}
|
||||
});
|
||||
// Retirer 'active' de l'onglet "Tous"
|
||||
const tousLi = document.querySelector('a[href="#dosArchTous"]').parentElement;
|
||||
tousLi.classList.remove('active');
|
||||
});
|
||||
});
|
||||
|
||||
// Gestion du clic sur "Tous"
|
||||
const tousTab = document.querySelector('a[href="#dosArchTous"]');
|
||||
if (tousTab) {
|
||||
$(tousTab).on('shown.bs.tab', function(e) {
|
||||
// Retirer 'active' de tous les onglets départements
|
||||
document.querySelectorAll('.dept-tab').forEach((li) => {
|
||||
li.classList.remove('active');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Add new functions
|
||||
function updateExportButton() {
|
||||
if (selectedXmlDevis.size > 0) {
|
||||
|
||||
@@ -16,6 +16,16 @@ ob_start();
|
||||
<div id="vb-buttons" class="mb-1">
|
||||
<button class="btn btn-default" id="btnDevisArchives" title="Voir les devis archivés"><i class="fa fa-stack-overflow fa-lg"></i> Devis archivés</button>
|
||||
<button class="btn btn-success" id="btnCreateDevis" title="Créer un nouveau devis"><i class="fa fa-plus fa-lg"></i> Créer un devis</button>
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
<div class="input-group mt-1">
|
||||
<input type="text" class="form-control" id="searchDevis" placeholder="Rechercher un devis par le nom du client, du contact, ville, opportunité..." maxlength="30">
|
||||
<span class="input-group-addon">
|
||||
<i class="fa fa-times clickable" id="btnResetSearch" style="display:none;"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($aModel["last_devis"] > 0) {
|
||||
@@ -87,21 +97,23 @@ ob_start();
|
||||
echo '<div class="border cm-scrollbar cm-table-w-scroll table-responsive table-800">';
|
||||
echo '<table class="table table-responsive table-bordered table-fixed" id="tblDos' . $iDos . '">';
|
||||
echo '<thead><tr>';
|
||||
echo '<th class="header" scope="col" width="5%">#</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Demande</th>';
|
||||
echo '<th class="header clickable" scope="col" width="5%" data-sortable="true" data-sort-type="number" data-column-index="0">#</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="date" data-column-index="1">Demande</th>';
|
||||
$colIndex = 2;
|
||||
if (($fkRole == 2 && $iDos == 2) || ($fkRole == 1 && $iDos == 1)) {
|
||||
// C'est un DV et sur le dossier Encours de validation DV
|
||||
// Ou le Dir-CO sur le dossier de validation DIR-CO
|
||||
// on affiche la colonne du nom du RR pour qu'il puisse savoir qui a fait la demande
|
||||
echo '<th class="header" scope="col" width="15%">RR</th>';
|
||||
echo '<th class="header clickable" scope="col" width="15%" data-sortable="true" data-sort-type="text" data-column-index="' . $colIndex . '">RR</th>';
|
||||
$colIndex++;
|
||||
}
|
||||
echo '<th class="header" scope="col" width="10%">Opport.</th>';
|
||||
echo '<th class="header" scope="col" width="5%">CP</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Ville</th>';
|
||||
echo '<th class="header" scope="col" width="15%">Client</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Marché</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Total HT</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Marge Totale</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="' . $colIndex . '">Opport.</th>';
|
||||
echo '<th class="header clickable" scope="col" width="5%" data-sortable="true" data-sort-type="number" data-column-index="' . ($colIndex + 1) . '">CP</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="' . ($colIndex + 2) . '">Ville</th>';
|
||||
echo '<th class="header clickable" scope="col" width="15%" data-sortable="true" data-sort-type="text" data-column-index="' . ($colIndex + 3) . '">Client</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="' . ($colIndex + 4) . '">Marché</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="' . ($colIndex + 5) . '">Total HT</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="' . ($colIndex + 6) . '">Marge Totale</th>';
|
||||
echo '<th class="header" scope="col" width="12%"></th>';
|
||||
echo '</tr></thead>';
|
||||
echo '<tbody id="tblBodyDos' . $iDos . '">';
|
||||
@@ -203,14 +215,14 @@ ob_start();
|
||||
echo '<div class="border cm-scrollbar cm-table-w-scroll table-responsive table-800">';
|
||||
echo '<table class="table table-responsive table-bordered table-fixed" id="tblDosArch' . $iDos . '">';
|
||||
echo '<thead><tr>';
|
||||
echo '<th class="header" scope="col" width="5%">#</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Demande</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Opport.</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Ville</th>';
|
||||
echo '<th class="header" scope="col" width="20%">Client</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Marché</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Total HT</th>';
|
||||
echo '<th class="header" scope="col" width="10%">Marge Totale</th>';
|
||||
echo '<th class="header clickable" scope="col" width="5%" data-sortable="true" data-sort-type="number" data-column-index="0">#</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="date" data-column-index="1">Demande</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="2">Opport.</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="3">Ville</th>';
|
||||
echo '<th class="header clickable" scope="col" width="20%" data-sortable="true" data-sort-type="text" data-column-index="4">Client</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="5">Marché</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="6">Total HT</th>';
|
||||
echo '<th class="header clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="7">Marge Totale</th>';
|
||||
echo '<th class="header" scope="col" width="10%"></th>';
|
||||
echo '</tr></thead>';
|
||||
echo '<tbody id="tblBodyDosArch' . $iDos . '">';
|
||||
|
||||
183
views/vsap.php
183
views/vsap.php
@@ -5,7 +5,37 @@ $metacss = '<link href="/pub/res/css/schat.css" rel="stylesheet" type="text/css"
|
||||
$barre = "";
|
||||
ob_start();
|
||||
?>
|
||||
<div id="divSAP">
|
||||
<style>
|
||||
.dept-tab a {
|
||||
min-width: 50px !important;
|
||||
padding: 8px 10px !important;
|
||||
font-size: 13px;
|
||||
}
|
||||
.table-800 {
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
#tabArchives .table-800 {
|
||||
max-height: 680px !important;
|
||||
}
|
||||
.table-800 thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
</style>
|
||||
<div class="row" style="margin-bottom: 20px;">
|
||||
<div class="col-md-2"></div>
|
||||
<div class="col-md-8">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="searchSAP" placeholder="Rechercher un devis par le nom du client, du contact, ville, opportunité..." maxlength="30">
|
||||
<span class="input-group-addon">
|
||||
<i class="fa fa-times clickable" id="btnResetSearchSAP" style="display:none;"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2"></div>
|
||||
</div>
|
||||
<div id="divSAP" style="margin-top: 20px;">
|
||||
<ul class="nav nav-tabs nav-justified" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#tabEnCours" aria-controls="tabEnCours" role="tab" data-toggle="tab">Les devis en cours</a></li>
|
||||
<li role="presentation"><a href="#tabArchives" aria-controls="tabArchives" role="tab" data-toggle="tab">Les devis archivés</a></li>
|
||||
@@ -40,20 +70,22 @@ ob_start();
|
||||
echo '<div class="border cm-scrollbar cm-table-w-scroll table-responsive table-800">';
|
||||
echo '<table class="table table-responsive table-bordered table-fixed" id="tblDos' . $iDos . '">';
|
||||
echo '<thead><tr>';
|
||||
echo '<th class="header text-center" scope="col" width="5%">#</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Date Demande</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Date Remise</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Responsable Régional</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Code Etabliss.</th>';
|
||||
echo '<th class="header text-center" scope="col" width="15%">Etablissement</th>';
|
||||
echo '<th class="header text-center" scope="col" width="7%">CP</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Ville</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Marché</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Montant Total HT</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Marge totale</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="5%" data-sortable="true" data-sort-type="number" data-column-index="0">#</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="date" data-column-index="1">Date Demande</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="date" data-column-index="2">Date Remise</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="3">Responsable Régional</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="4">Code Etabliss.</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="15%" data-sortable="true" data-sort-type="text" data-column-index="5">Etablissement</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="7%" data-sortable="true" data-sort-type="number" data-column-index="6">CP</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="7">Ville</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="8">Marché</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="9">Montant Total HT</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="10">Marge totale</th>';
|
||||
$colIndexActions = 11;
|
||||
if ($dossier["rowid"] == 7) {
|
||||
// Si le dossier est "A envoyer au client", on affiche la colonne "Email"
|
||||
echo '<th class="header text-center" scope="col" width="10%">Email</th>';
|
||||
$colIndexActions = 12;
|
||||
}
|
||||
echo '<th class="header text-center" scope="col" width="20%">Actions <button class="btn btn-info btn-xs btnExportSelectedXML hidden" title="Export XML SAP des devis sélectionnés"><i class="fa fa-scribd fa-lg"></i></button></th>';
|
||||
echo '</tr></thead>';
|
||||
@@ -167,39 +199,118 @@ ob_start();
|
||||
<div role="tabpanel" class="tab-pane" id="tabArchives">
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
<ul class="nav nav-tabs nav-justified" role="tablist">
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach ($aModel["dossiers"] as $dossier) {
|
||||
if ($i % 15 == 0 && $i > 0) {
|
||||
echo '<div class="spacer"></div>';
|
||||
}
|
||||
$active = ($i == 0) ? "active" : "";
|
||||
$ceDossier = ($dossier["dossier"] == "") ? "?" : $dossier["dossier"];
|
||||
echo '<li role="presentation" class="' . $active . '"><a href="#dosArch' . $i . '" aria-controls="dosArch' . $i . '" role="tab" data-toggle="tab">' . $ceDossier . '</a></li>';
|
||||
$i++;
|
||||
}
|
||||
?>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#dosArchTous" aria-controls="dosArchTous" role="tab" data-toggle="tab">Tous</a></li>
|
||||
</ul>
|
||||
<?php
|
||||
$i = 0;
|
||||
$nbPerLine = 25;
|
||||
$totalDepts = count($aModel["dossiers"]);
|
||||
|
||||
for ($line = 0; $line < 4; $line++) {
|
||||
echo '<ul class="nav nav-tabs" role="tablist">';
|
||||
$start = $line * $nbPerLine;
|
||||
$end = min($start + $nbPerLine, $totalDepts);
|
||||
|
||||
for ($j = $start; $j < $end; $j++) {
|
||||
$dossier = $aModel["dossiers"][$j];
|
||||
$ceDossier = ($dossier["dossier"] == "") ? "?" : $dossier["dossier"];
|
||||
echo '<li role="presentation" class="dept-tab"><a href="#dosArch' . $j . '" aria-controls="dosArch' . $j . '" role="tab" data-toggle="tab">' . $ceDossier . '</a></li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
?>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane p-0 active" id="dosArchTous">
|
||||
<div class="border cm-scrollbar cm-table-w-scroll table-responsive table-800">
|
||||
<table class="table table-responsive table-bordered table-fixed" id="tblDosArchTous">
|
||||
<thead><tr>
|
||||
<th class="header text-center clickable" scope="col" width="5%" data-sortable="true" data-sort-type="number" data-column-index="0">#</th>
|
||||
<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="date" data-column-index="1">Date Demande</th>
|
||||
<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="2">Resp. Régional</th>
|
||||
<th class="header text-center clickable" scope="col" width="7%" data-sortable="true" data-sort-type="text" data-column-index="3">Code Etabliss.</th>
|
||||
<th class="header text-center clickable" scope="col" width="15%" data-sortable="true" data-sort-type="text" data-column-index="4">Etablissement</th>
|
||||
<th class="header text-center clickable" scope="col" width="5%" data-sortable="true" data-sort-type="number" data-column-index="5">CP</th>
|
||||
<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="6">Ville</th>
|
||||
<th class="header text-center clickable" scope="col" width="8%" data-sortable="true" data-sort-type="text" data-column-index="7">Marché</th>
|
||||
<th class="header text-center clickable" scope="col" width="5%" data-sortable="true" data-sort-type="text" data-column-index="8">Dép.</th>
|
||||
<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="9">Montant Total HT</th>
|
||||
<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="10">Marge totale</th>
|
||||
<th class="header text-center" scope="col" width="10%">Actions</th>
|
||||
</tr></thead>
|
||||
<tbody id="tblBodyDosArchTous">
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach ($aModel["devisArchives"] as $devis) {
|
||||
echo '<tr id="trArchTous_' . $devis["rowid"] . '">';
|
||||
echo '<td class="text-center">' . $devis["rowid"] . '</td>';
|
||||
$dateDem = substr($devis["date_demande"], 8, 2) . '/' . substr($devis["date_demande"], 5, 2) . ' ' . substr($devis["date_demande"], 0, 4);
|
||||
if ($devis["chk_speciaux"] == 1) {
|
||||
$cellDateDem = '<span data-after-text="S" data-after-type="blue circle">' . $dateDem . '</span>';
|
||||
} else {
|
||||
$cellDateDem = $dateDem;
|
||||
}
|
||||
echo '<td class="clickable celArchives" data-rid="' . $devis["rowid"] . '">' . $cellDateDem . '</td>';
|
||||
echo '<td class="clickable celArchives" data-rid="' . $devis["rowid"] . '">' . $devis["prenom"] . " " . $devis["nom"] . '</td>';
|
||||
echo '<td class="clickable celArchives" data-rid="' . $devis["rowid"] . '">' . $devis["code"] . '</td>';
|
||||
|
||||
if ($devis["fk_client"] == 0) {
|
||||
$ville = $devis["ville_new_client"];
|
||||
$libelle = '<span data-after-text="N" data-after-type="red circle">' . $devis["lib_new_client"] . '</span>';
|
||||
} else {
|
||||
$ville = $devis["ville"];
|
||||
$libelle = $devis["libelle"];
|
||||
}
|
||||
echo '<td class="clickable celArchives" data-rid="' . $devis["rowid"] . '">' . $libelle . '</td>';
|
||||
echo '<td class="clickable celArchives" data-rid="' . $devis["rowid"] . '">' . $devis["cp"] . '</td>';
|
||||
echo '<td class="clickable celArchives" data-rid="' . $devis["rowid"] . '">' . $ville . '</td>';
|
||||
echo '<td class="clickable celArchives" data-rid="' . $devis["rowid"] . '">' . $devis["lib_marche"] . '</td>';
|
||||
$dossierLabel = ($devis["dossier"] == "") ? "?" : $devis["dossier"];
|
||||
echo '<td class="clickable celArchives text-center" data-rid="' . $devis["rowid"] . '">' . $dossierLabel . '</td>';
|
||||
$montant = floatval($devis["montant_total_ht_remise"]);
|
||||
echo '<td class="clickable celArchives right" data-rid="' . $devis["rowid"] . '">' . number_format($montant, 2, ',', ' ') . ' €</td>';
|
||||
$margeTotale = floatval($devis["marge_totale"]);
|
||||
echo '<td class="clickable celArchives right" data-rid="' . $devis["rowid"] . '">' . number_format($margeTotale, 2, ',', ' ') . ' %</td>';
|
||||
echo '<td class="text-center">';
|
||||
echo '<div class="btn-group">';
|
||||
echo '<button class="btn btn-primary btn-xs btnViewDevisArchives" title="Consulter le devis" data-rid="' . $devis["rowid"] . '"><i class="fa fa-eye fa-lg"></i></button>';
|
||||
echo '<button class="btn btn-info btn-xs btnExportDevisEnCours" title="Export Excel du devis" data-rid="' . $devis["rowid"] . '" data-libelle="' . $devis["libelle"] . '"><i class="fa fa-file-excel-o fa-lg"></i></button>';
|
||||
$typBtn = "btn-success";
|
||||
foreach ($aModel["medias"] as $media) {
|
||||
if ($media["support_rowid"] == $devis["rowid"]) {
|
||||
$typBtn = "btn-warning";
|
||||
break;
|
||||
}
|
||||
}
|
||||
echo '<button class="btn ' . $typBtn . ' btn-xs btnImportPDFEnCours" title="Consulter le PDF SAP du devis" data-rid="' . $devis["rowid"] . '" data-libelle="' . $devis["libelle"] . '"><i class="fa fa-file-pdf-o fa-lg"></i></button>';
|
||||
echo '</div>';
|
||||
echo '</td></tr>';
|
||||
$i++;
|
||||
}
|
||||
if ($i == 0) echo '<tr><td colspan="12" class="center">Aucun devis archivé trouvé</td></tr>';
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$iDos = 0;
|
||||
foreach ($aModel["dossiers"] as $dossier) {
|
||||
$active = ($iDos == 0) ? "active" : "";
|
||||
$active = "";
|
||||
echo '<div role="tabpanel" class="tab-pane p-0 ' . $active . '" id="dosArch' . $iDos . '">';
|
||||
echo '<div class="border cm-scrollbar cm-table-w-scroll table-responsive table-800">';
|
||||
echo '<table class="table table-responsive table-bordered table-fixed" id="tblDosArch' . $iDos . '">';
|
||||
echo '<thead><tr>';
|
||||
echo '<th class="header text-center" scope="col" width="5%">#</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Date Demande</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Resp. Régional</th>';
|
||||
echo '<th class="header text-center" scope="col" width="7%">Code Etabliss.</th>';
|
||||
echo '<th class="header text-center" scope="col" width="20%">Etablissement</th>';
|
||||
echo '<th class="header text-center" scope="col" width="5%">CP</th>';
|
||||
echo '<th class="header text-center" scope="col" width="13%">Ville</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Marché</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Montant Total HT</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Marge totale</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="5%" data-sortable="true" data-sort-type="number" data-column-index="0">#</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="date" data-column-index="1">Date Demande</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="2">Resp. Régional</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="7%" data-sortable="true" data-sort-type="text" data-column-index="3">Code Etabliss.</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="20%" data-sortable="true" data-sort-type="text" data-column-index="4">Etablissement</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="5%" data-sortable="true" data-sort-type="number" data-column-index="5">CP</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="13%" data-sortable="true" data-sort-type="text" data-column-index="6">Ville</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="text" data-column-index="7">Marché</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="8">Montant Total HT</th>';
|
||||
echo '<th class="header text-center clickable" scope="col" width="10%" data-sortable="true" data-sort-type="number" data-column-index="9">Marge totale</th>';
|
||||
echo '<th class="header text-center" scope="col" width="10%">Actions</th>';
|
||||
echo '</tr></thead>';
|
||||
echo '<tbody id="tblBodyDosArch' . $iDos . '">';
|
||||
|
||||
Reference in New Issue
Block a user