PluginsClassiques(self::MODULE); $this->lang = isset($_SESSION['navig']->lang) ? intval($_SESSION['navig']->lang) : 0; if ($this->lang == 0) $this->lang = 1; } public function init() { $this->ajout_desc( self::NOMMODULE, "Déclinaisons combinées", "Ce plugin permet de combiner vos déclinaisons, et de gérer stock et surplus pour chaque combinaison", 1); $query = " CREATE TABLE IF NOT EXISTS `".self::TABLE."` ( `id` int(11) NOT NULL AUTO_INCREMENT, `produit` int(11) NOT NULL, `ref` text, `stock` float DEFAULT NULL, `surplus` float DEFAULT NULL, `actif` int(1) DEFAULT '1', PRIMARY KEY (`id`), KEY `ref` (`ref`(64),`produit`), KEY `produit` (`produit`,`actif`) )"; $this->_query($query); CombidecliProduit::init(); CombidecliCommande::init(); } public function destroy() { $this->_query("DROP TABLE IF EXISTS ".self::TABLE); CombidecliProduit::destroy(); CombidecliCommande::destroy(); } public function charger($id) { return $this->getVars("select * from $this->table where id=$id"); } public function charger_ref($ref, $idproduit) { return $this->getVars("select * from $this->table where ref='$ref' and produit=$idproduit"); } public function boucle($texte, $args) { $boucle = strtolower(lireTag($args, 'boucle')); switch($boucle) { case 'combinaison': return $this->boucleCombinaison($texte, $args); break; case 'declidisp': return $this->boucleDeclidisp($texte, $args); break; case 'quantite': return $this->boucleQuantite($texte, $args); break; case 'stock': return $this->boucleStock($texte, $args); break; } } public function action() { global $ref, $quantite, $append, $nouveau, $parent; if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'ajouter_combidecli') { $produit = new Produit(); if ($produit->charger($ref)) { // Construire la combinaison courante $combi = $this->combinaison_courante($produit); // $this->_debug("combi: ",$combi); $surplus = 0; if ($combi) { $perso = array(); $declidisp = new Declidisp(); $declinaison = new Declinaison(); $result = $this->_query(" select d.id as declinaison, dd.id as declidisp from $declidisp->table dd left join $declinaison->table d on dd.declinaison = d.id where dd.id in ($combi->ref) order by d.classement "); $combinees = array(); while ($result && $declidisp = mysql_fetch_object($result, 'Declidisp')) { $tmp = new Perso(); $tmp->declinaison = $declidisp->declinaison ; $tmp->valeur = $declidisp->declidisp; $perso[] = $tmp; $combinees[] = $declidisp->declinaison; } // Ajouter les déclinaisons hors combinaison s'il y en a foreach ($_REQUEST as $key => $valeur) { if (strstr($key, "declinaison")) { $decli = intval(substr($key, 11)); if ($decli > 0 && ! in_array($decli, $combinees)) { $tmp = new Perso(); $tmp->declinaison = $decli; $tmp->valeur = stripslashes($valeur); $perso[] = $tmp; } } } // $this->_debug("Perso: ", $perso); $tabarticle = &$_SESSION['navig']->panier->tabarticle; $avaj = count($tabarticle); // Ajouter le produit au panier (en désactivant temporairement la verif des stocks) $vs = new Variable('verifstock'); $ovs = $vs->valeur; $vs->valeur = 0; $vs->maj(); $_SESSION['navig']->panier->ajouter($ref, $quantite, $perso, $append, $nouveau, $parent); $vs->valeur = $ovs; $vs->maj(); // Ajouter le surplus de la combinaison courante, uniquement si un article a été ajouté au pbnier if ($avaj < count($tabarticle)) { $art = count($tabarticle)-1; // $this->_debug("prix: ",$tabarticle[count($tabarticle)-1]->produit->prix," surp: $combi->surplus"); $tabarticle[$art]->produit->prix += $combi->surplus; $tabarticle[$art]->produit->prix2 += $combi->surplus; if (! isset($_SESSION['combidecli'])) $_SESSION['combidecli'] = array(); $_SESSION['combidecli'][$art] = $combi->id; } } else { ajouter($ref, $quantite, $append, $nouveau, $parent); } } } } // Corriger le stock du produit après une modif. public function modprod($refproduit) { if ($refproduit instanceof Produit) $refproduit = $refproduit->ref; // Si on n'a pas de combi ni de déclis actives, le stock du produit ne sera pas utilisé. $utiliser_stock_produit = true; $produit = new Produit(); if ($produit->charger($refproduit)) { $result = $this->_query("select stock from $this->table where produit = $produit->id and actif <> 0"); $stock_total = 0; while ($result && $combi = mysql_fetch_object($result)) { $utiliser_stock_produit = false; $stock_total += $combi->stock; } // Ajouter le stock des déclinaisons non combinées. $dnc = $this->declinaisons_non_combinees($produit->id, $produit->rubrique); foreach($dnc as $dec) { $utiliser_stock_produit = false; // Lire les déclidps de la combinaison, et ajouter leur stock au stock total $query = " select * from stock s left join declidisp dd on dd.id = s.declidisp where s.produit = $produit->id and dd.declinaison = $dec and dd.id not in (select declidisp from exdecprod where produit = $produit->id) "; $result = $this->_query($query); while ($result && $row = mysql_fetch_object($result)) { $stock_total += $row->valeur; } } if ($utiliser_stock_produit === false) { $produit->stock = $stock_total; $produit->maj(); } } } public function aprescommande($commande) { $idx = 0; foreach($_SESSION['navig']->panier->tabarticle as $art) { if (isset($_SESSION['combidecli'][$idx])) { $combidecli = new Combidecli(); if ($combidecli->charger($_SESSION['combidecli'][$idx])) { $combidecli->stock -= $art->quantite; $combidecli->maj(); // Mettre l'historique à jour $cdc = new CombidecliCommande(); $cdc->commande = $commande->id; $cdc->combidecli = $combidecli->id; $cdc->quantite = $art->quantite; $cdc->add(); } } $idx++; } } // Retour en stock sur les combinaisons public function statut($commande) { if ($commande->statut == 5) { // Remettre en stock les combinaisons concernées. $combicmds = CombidecliCommande::lister_par_commande($commande->id); $combi = new Combidecli(); foreach($combicmds as $combicmd) { if ($combi->charger($combicmd->combidecli)) { $combi->stock += $combicmd->quantite; $combi->maj(); } $combicmd->delete(); } } } // Suppression d'un produit // On reçoit en fait la ref... Donc on ne peut plus retrouver l'ID du produit, il a été supprimé dans produit_modifier.php ! public function supprod($refproduit) { $result = $this->_query("select produit FROM $this->table WHERE produit not in (select id from produit)"); while ($result && $row = mysql_fetch_object($result)) { CombidecliProduit::supprimer_par_produit($row->produit); } } public function _query($sql, $log = false) { if ($log) echo "
SQL:$sql"; $result = mysql_query($sql, $this->link); if ($result === false) die('Erreur SQL:'.mysql_error().': ' . $sql); return $result; } public function _escape($value) { if(get_magic_quotes_gpc()) $value = stripslashes($value); return mysql_real_escape_string($value); } /* * Appelle une boucle et retourne les variables valuées dans une table. * Exemple d'appel: * $this->wrapboucle( * 'boucleProduit', * array('ID', 'REF', 'TITRE'), * array('rubrique' => 12, 'classement' => 'manuel') * ); * * La methode retourne un tableau comportant autant d'éléments que * de 'tours' de boucle, chaque élément étant un tableau associatif * var => valeur. Exemple: * * Array( * [0] => Array( * '#ID' => 1, * '#REF' => 'ABC', * '#TITRE' => 'un produit' * ), * [1] => Array( * '#ID' => 4, * '#REF' => 'DEF', * '#TITRE' => 'un autre produit' * ) * * etc.. * ); */ public function wrapboucle($boucle, $variables_sans_diese, $arguments) { $texte = ''; $resultat = array(); foreach($variables_sans_diese as $var) { $texte .= $var . chr(5) . '#' . $var . chr(6); } $texte .= rtrim($texte, chr(6)) . chr(7); $args = ''; foreach($arguments as $nom => $val) $args .= $nom . '="' . $val . '" '; // $this->_debug('texte', $texte, 'args=', $args); $res = $boucle($texte, $args); // $this->_debug('wrap result', $res); if ($res != '') { $res = rtrim($res, chr(7)); $lignes = explode(chr(7), $res); foreach($lignes as $ligne) { $vars = array(); $colonnes = explode(chr(6), $ligne); foreach($colonnes as $colonne) { list($var, $value) = explode(chr(5), $colonne); $vars['#'.$var] = $value; } $resultat[] = $vars; } } // $this->_debug("Final: ",$resultat); return $resultat; } // Methodes privées // ---------------- public function _debug() { $text = ''; $numargs = func_num_args(); for($idx = 0; $idx < $numargs; $idx++) { $arg = func_get_arg($idx); $text .= is_scalar($arg) ? $arg : print_r($arg, true); } echo '
[DEBUG] ' . htmlspecialchars($text)."
"; } // Valeur courante de paramètres importants pour pour le calcul // de la déclinaison par defaut. // Memorise les paramètres stockmini et classement indiqués dans les boucles, // afin de les réutiliser s'ils ne sont pas spécifiés. private static $valeurs_defaut = array(); protected function lireTagPrev($args, $nom, $type = 'string') { $val = lireTag($args, $nom, $type); //$this->_debug("args: $args, $nom=$val"); if ($val == '') { if (isset(self::$valeurs_defaut[$nom])) $val = self::$valeurs_defaut[$nom]; } else { self::$valeurs_defaut[$nom] = $val; } //$this->_debug("valeur: $nom=$val"); return $val; } // Retourne la liste des déclinaisons non combinées (ou test si une declinaison est combinee si $iddeclinaison != false) protected function declinaisons_non_combinees($idproduit, $idrubrique, $stockmini = 0, $iddeclinaison = false) { $declinaisons = array(); // Verfier qu'il existe des déclidisps actives hors combinaison et avec le stock voulu sur la declinaison courante (à la COMBIX) $rd = new Rubdeclinaison(); $d = new Declinaison(); $dd = new Declidisp(); $s = new Stock(); $ex = new Exdecprod(); $where = $iddeclinaison !== false ? "and dd.declinaison = $iddeclinaison" : ''; $result = $this->_query(" select distinct dd.declinaison as iddeclinaison from $rd->table rd left join $dd->table dd on dd.declinaison = rd.declinaison left join $s->table s on s.declidisp = dd.id left join $d->table d on d.id = dd.declinaison where rd.rubrique = $idrubrique and s.produit = $idproduit $where and s.valeur >= $stockmini and s.declidisp not in (select declidisp from $ex->table where produit = $idproduit) and d.id not in (select declinaison from ".CombidecliProduit::TABLE." where produit = $idproduit) order by d.classement "); while($result && $row = mysql_fetch_object($result)) { $declinaisons[] = $row->iddeclinaison; } return $declinaisons; } // Lire toutes les declidisps pour un produit et éventuellement une déclinaison // Retourne false si aucune combinaison n'a été trouvée (e.g., les combinaisons ne sont pas activées pour le produit) // Sinon, retourne un tableau des declinaisons actives avec le stock requis. private function lire_declidisps_pour_produit($idproduit, $iddeclinaison = 0, $stockmini = 0, $filtre = false) { $like = $filtre ? "AND ref LIKE '$filtre'" : ''; $query = " SELECT * FROM $this->table WHERE produit = $idproduit $like ORDER BY id "; $result = $this->_query($query); if ($result) { if (mysql_numrows($result) > 0) { $declidisps = array(); while ($combinaison = mysql_fetch_object($result, 'Combidecli')) { if ($combinaison->stock >= $stockmini && $combinaison->actif != 0) { $iddeclidisps = explode(',', $combinaison->ref); foreach($iddeclidisps as $iddeclidisp) { $declidisp = new Declidisp(); if ($declidisp->charger($iddeclidisp) && ($iddeclinaison == 0 || $iddeclinaison == $declidisp->declinaison) ) { $declidisps[] = $declidisp; } } } } return $declidisps; } } return false; } // Retrouve l'ordre de base des déclinaisons, celui avec lequel la ref des combinaisons est ordonnée private function ordre_declinaisons($produit) { if (! $this->ordre_manuel) { $this->ordre_manuel = array(); $rd = new Rubdeclinaison(); $d = new Declinaison(); $dd = new Declidisp(); $edp = new Exdecprod(); $cdp = new CombidecliProduit(); // Trouver les declinaisons ayant au moins une déclidisp active sur le produit courant $result = $this->_query(" select distinct d.id from declidisp dd left join $d->table d on d.id = dd.declinaison where dd.id not in (select $dd->table from exdecprod where produit=$produit->id) and d.id in (select declinaison from $rd->table where rubrique=$produit->rubrique) and d.id in (select declinaison from $cdp->table where produit=$produit->id) order by d.classement "); while ($result && $decli = mysql_fetch_object($result)) { $this->ordre_manuel[] = $decli->id; } // Ordre naturel des référence (e.g., triées par ID declidisp croissant) $this->ordre_reference = $this->ordre_manuel; sort($this->ordre_reference); } return count($this->ordre_manuel); } // Determiner si une combinaison (ou une portion de combinaison) est valide private function lire_ref($produit, $stockmini, $ref_combinaison) { // $this->_debug("lire_ref ",$ref_combinaison); $result = $this->_query(" SELECT * from $this->table where produit=$produit->id and stock >= $stockmini and actif <> 0 and ref like '$ref_combinaison' order by id limit 0,1 "); if ($result && $combi = mysql_fetch_object($result, 'Combidecli')) return $combi; else return false; } // Trouver le filtre qui convient pour retrouver les declidisp possibles // de la déclinaison indiquée, en fonction du contexte et de l'ordre // d'affichage des déclinaisons. private function filtre_combinaison($produit, $stockmini, $declinaison = 0) { // Retrouver l'ordre des declinaisons tel qu'utilisé pour calculer la ref combinaison $nbdeclis = $this->ordre_declinaisons($produit); if ($nbdeclis <= 0) return ''; $ref_combinaison = array_fill(0, $nbdeclis, '%'); $idx = 0; // $this->_debug("Ordre declis: ", $this->ordre_manuel); // $this->_debug("Ordre naturel: ", $this->ordre_reference); foreach($this->ordre_manuel as $iddeclinaison) { $test_combinaison = $ref_combinaison; // Trouver la position de la déclinaison courante dans la ref combinaison for($pos = 0; $pos < $nbdeclis; $pos++) { if ($this->ordre_reference[$pos] == $iddeclinaison) break; } $curr_declidisp = intval($_REQUEST['declinaison'.$iddeclinaison]); // $this->_debug("idx=$idx, pos $iddeclinaison=$pos,>declinaison[$iddeclinaison]=$curr_declidisp"); if ($declinaison == $iddeclinaison && (! $exact)) { // $this->_debug("$idx:CURRENT"); // On va récupérer toutes les declidisp possibles (on laisse '%' dans la ref) break; } else if ($curr_declidisp > 0) { // $this->_debug("$idx:DEFINED AND VALIDE:$curr_declidisp"); // On utilise la déclidisp selectionnée $test_combinaison[$pos] = $curr_declidisp; } else { // $this->_debug("$idx:SEARCH"); // Trouver la première combinaison qui matche $search_ref = implode(',', $test_combinaison); if ($combi = $this->lire_ref($produit, $stockmini, implode(',', $test_combinaison))) { // $this->_debug("found ref for $search_ref", $combi->ref); $refs = explode(',', $combi->ref); $test_combinaison[$pos] = $refs[$pos]; } else { // $this->_debug("Nothing found"); break; } } // On arrête dès qu'on ne trouve plus de combinaison valide $valide = $this->lire_ref($produit, $stockmini, implode(',', $test_combinaison)); // $this->_debug("ref:", implode(',', $ref_combinaison),", test=", implode(',', $test_combinaison), ", valide:", ($valide !== false)); // La nouvelle n'est pas valide => on utilise la précédente et on termine if (! $valide) break; $ref_combinaison = $test_combinaison; $idx++; } $ref_combinaison = implode(',', $ref_combinaison); // $this->_debug("Ref pour $declinaison: $ref_combinaison"); return $ref_combinaison; } private function combinaison_courante($produit, $stockmini = 0) { $ref_courante = $this->filtre_combinaison($produit, $stockmini); // $this->_debug("combinaison_courante: $ref_courante"); return $this->lire_ref($produit, $stockmini, $ref_courante); } private function get_declidispdesc_classement($prefixe_table, $classement) { if ($classement == "alpha") return "order by $prefixe_table.titre"; else if ($classement == "alphainv") return "order by $prefixe_table.titre desc"; else if ($classement == "manuel") return "order by $prefixe_table.classement"; else return ''; } // Trouve le stock et le surplus d'un produit ou d'un article. private function trouver_stock_et_surplus($produit, $article, $stockmini, $classement, &$surplus, &$stockproduit) { // $this->_debug("trouver_stock_et_surplus: p=$produit->id, a=$article, s=$stockmini, c=$classement"); $utiliser_stock_produit = true; $combi = false; if ($article !== false) { $produit = $_SESSION['navig']->panier->tabarticle[$article]->produit; if (isset($_SESSION['combidecli'][$article])) { $combi = new Combidecli(); $combi->charger($_SESSION['combidecli'][$article]); } } else if ($produit) { // Construire la combinaison courante $combi = $this->combinaison_courante($produit, $stockmini); } //$this->_debug("Combi = ",$this->combinaison_courante($produit, $stockmini)); $surplus = 0; $stockproduit = 0; if ($combi) { $surplus += $combi->surplus; $stockproduit += $combi->stock; $utiliser_stock_produit = false; } // Retrouver stock & surplus des éventuelles declinaisons non combinees, pour l'ajouter au prix // le stock de ces déclinaisons est ajouté au stock de la combinaison (si elle existe) $declinaisons_nc = $this->declinaisons_non_combinees($produit->id, $produit->rubrique, $stockmini); foreach($declinaisons_nc as $declinaison) { // Trouver la declidisp couramment selectionnee, // ou trouver la 1ere déclidisp a afficher. if (isset($_REQUEST['declinaison'.$declinaison])) { $declidisp = intval($_REQUEST['declinaison'.$declinaison]); $stock = new Stock(); if ($stock->charger($declidisp, $produit->id)) { $surplus += $stock->surplus; $stockproduit += $stock->valeur; $utiliser_stock_produit = false; } } else if ($article !== false) { // Dans le panier, déterminer quelle est la declidisp choisie pour cette declinaison $art = $_SESSION['navig']->panier->tabarticle[$article]; foreach($art->perso as $perso) { if ($perso->declinaison == $declinaison) { $stock = new Stock(); if ($stock->charger($perso->valeur, $art->produit->id)) { $surplus += $stock->surplus; $stockproduit += $stock->valeur; $utiliser_stock_produit = false; } break; } } } else { // Trouver la 1ere déclidisp // ATTENTION: il faut que le classement soit le même que pour l'affichage // des choix de déclidisp, d'ou le paramètre 'classement' $ex = new Exdecprod(); $dd = new Declidisp(); $ddd = new Declidispdesc(); $s = new Stock(); $order = $this->get_declidispdesc_classement('ddd', $classement); $result = $this->_query(" select s.* from $dd->table dd left join $ddd->table as ddd on ddd.declidisp = dd.id left join $s->table s on s.declidisp = dd.id where dd.declinaison = $declinaison and s.produit = $produit->id and s.valeur >= $stockmini and s.declidisp not in (select declidisp from $ex->table where produit = $produit->id) $order limit 1 "); if ($result && $stock = mysql_fetch_object($result, 'Stock')) { $surplus += $stock->surplus; $stockproduit += $stock->valeur; $utiliser_stock_produit = false; } } } // Pas de combinaison ni de declidisp trouvées ? le stock est celui du produit. if ($utiliser_stock_produit === true) { $stockproduit = $produit->stock; } // $this->_debug("$produit->id, $article, $stockmini, $classement, &$surplus, &$stockproduit"); return $combi; } private function boucleCombinaison($texte, $args) { $res = ''; $iddeclinaison = intval(lireTag($args, "id")); $idproduit = intval(lireTag($args, "produit")); $stockmini = intval($this->lireTagPrev($args, "stockmini", 'int')); $forcecombinaisons = intval(lireTag($args, "forcecombinaisons")); $declidisps = $this->lire_declidisps_pour_produit($idproduit, 0, $stockmini); // $this->_debug("declidisps: ", $declidisps); if ($declidisps !== false) { $declinaisons = array(); foreach($declidisps as $declidisp) { if (! in_array($declidisp->declinaison, $declinaisons)) { $declinaisons[] = $declidisp->declinaison; } } if (count($declinaisons) > 0) { $declinaison = new Declinaison(); $declinaisondesc = new Declinaisondesc(); // Afficher les déclinaisons classées dans l'ordre indiqué // Afficher les déclinaisons classées dans l'ordre indiqué $result = $this->_query("SELECT id from $declinaison->table where id in (".implode(',', $declinaisons).") order by classement"); $ids = array(); while ($result && $row = mysql_fetch_object($result)) $ids[] = $row->id; // Il faut masquer le paramètre stockmini, pour ne pas prendre en compte // le stock des déclis dans la boucle declinaison (1.4.4) $pargs = str_replace('stockmini', '_combidecli_stock_mini_', $args); $res = boucleDeclinaison($texte, $pargs . 'id="'.implode(',', $ids).'"'); } } // Afficher aussi les déclinaisons qui ne sont pas combinées, si c'est demandé. if ($forcecombinaisons == 0) { $produit = new Produit(); if ($produit->charger_id($idproduit)) { if ($iddeclinaison != 0) $where = "and dd.declinaison = $iddeclinaison"; // Verfier qu'il existe des déclidisps actives hors combinaison et avec le stock voulu sur la declinaison courante (à la COMBIX) $rd = new Rubdeclinaison(); $d = new Declinaison(); $dd = new Declidisp(); $s = new Stock(); $ex = new Exdecprod(); $result = $this->_query(" select distinct dd.declinaison as iddeclinaison from $rd->table rd left join $dd->table dd on dd.declinaison = rd.declinaison left join $s->table s on s.declidisp = dd.id left join $d->table d on d.id = dd.declinaison where rd.rubrique = $produit->rubrique and s.produit = $idproduit $where and s.valeur >= $stockmini and s.declidisp not in (select declidisp from $ex->table where produit = $idproduit) and d.id not in (select declinaison from ".CombidecliProduit::TABLE." where produit = $idproduit) order by d.classement "); // Retrouver toutes les declinaisons non combinees, ayant au moins une déclidisp avec le stock requis $declinaisons_nc = $this->declinaisons_non_combinees($idproduit, $produit->rubrique, $stockmini); foreach($declinaisons_nc as $declinaison) { $pargs = 'id="'.$declinaison.'" '.preg_replace('/id="[0-9]*"/', '', $args); $res .= boucleDeclinaison($texte, $pargs); } } } return $res; } private function boucleDeclidisp($texte, $args) { $res = ''; $iddeclinaison = intval(lireTag($args, "declinaison")); $idproduit = intval(lireTag($args, "produit")); $stockmini = intval($this->lireTagPrev($args, "stockmini", 'int')); $classement = $this->lireTagPrev($args, "classement", 'string'); $courante = intval(lireTag($args, "courante")); $num = lireTag($args, "num", "int"); $order = $this->get_declidispdesc_classement('ddd', $classement); $produit = new Produit(); if ($produit->charger_id($idproduit)) { $filtre = $this->filtre_combinaison($produit, $stockmini, $iddeclinaison); $declidisps = $this->lire_declidisps_pour_produit($idproduit, $iddeclinaison, $stockmini, $filtre); // $this->_debug("Decli: $iddeclinaison, v=$declidisp, filtre=$filtre, declidisps:", $declidisps); if ($declidisps !== false) { $occ_declidisp = array(); foreach($declidisps as $declidisp) { if (! in_array($declidisp->id, $occ_declidisp)) { $occ_declidisp[] = $declidisp->id; } } // $this->_debug('occ_declidisp:',$occ_declidisp); if (count($occ_declidisp) > 0) { $declidispdesc = new Declidispdesc(); $declidisp = new Declidisp(); // Afficher les declidisp classées dans l'ordre demandé $result = $this->_query(" SELECT dd.*, ddd.titre FROM $declidisp->table dd LEFT JOIN $declidispdesc->table ddd on ddd.declidisp = dd.id and ddd.lang = $this->lang WHERE dd.id in (".implode(',', $occ_declidisp).") $order "); // Trouver la declidisp selectionnée if ( ($curdeclidisp = intval($_REQUEST['declinaison'.$iddeclinaison])) == 0) { - $curdeclidisp = $occ_declidisp[0]; } $count = 0; while ($result && ($num == '' || $count < $num) && $row = mysql_fetch_object($result)) { if ($courante > 0 && $curdeclidisp != $row->id) continue; $temp = $texte; $selected = $curdeclidisp == $row->id ? 1 : 0; $temp = str_replace("#ID", $row->id, $temp); $temp = str_replace("#DECLINAISON", $row->declinaison, $temp); $temp = str_replace("#TITRE", $row->titre, $temp); $temp = str_replace("#PRODUIT", $idproduit, $temp); $temp = str_replace("#SELECTED", $selected, $temp); $res .= $temp; $count++; } } } // Si il existe des déclinaisons non combinées, on affiche ses déclidisp avec la boucle classique, // en ajoutant l'information #SELECTED. On a en principe une seule declinaison, car l'ID de la declinaison // est passée à cette boucle. $declinaisons_nc = $this->declinaisons_non_combinees($idproduit, $produit->rubrique, $stockmini, $iddeclinaison); // $this->_debug('declinaisons non combinées: ', $declinaisons_nc); foreach ($declinaisons_nc as $declinaison) { // Appel (wrappé) de la boucle déclidisp, pour ajouter l'information 'selected' $wrap = $this->wrapboucle( 'boucleDeclidisp', array('ID', 'DECLINAISON', 'TITRE', 'PRODUIT'), array( 'declinaison' => $declinaison, 'produit' => $idproduit, 'stockmini' => $stockmini, 'classement' => $classement, 'num' => $num ) ); // $this->_debug('wrap:',$wrap); // La valeur selectionnée $selected = isset($_REQUEST['declinaison'.$declinaison]) ? intval($_REQUEST['declinaison'.$declinaison]) : 0; foreach($wrap as $ln) { $iddeclidisp = $ln['#ID']; // Si aucune declidisp n'est selectionnée, la première est selectionnée par défaut if ($selected == 0) $selected = $iddeclidisp; $ln['#SELECTED'] = $selected == $iddeclidisp ? 1 : 0; if ($courante > 0 && $ln['#SELECTED'] == 0) continue; $res .= str_replace(array_keys($ln), array_values($ln), $texte); } // $this->_debug('res decli non combinées=', $res); } } return $res; } /* * Le stock est calculé comme suit: * * 1) combinaison totale: stock de la combinaison courante * 2) combinaison partielle: stock de la combinaison courante + somme des stocks des déclidisp courantes * 3) pas de combinaison, déclinaisons actives: somme des stocks des déclidisp courantes * 4) pas de déclinaisons (ou toutes déclidisps désactivées) => stock produit * * Le surplus est calculé comme suit: * * 1) combinaison totale: surplus de la combinaison courante * 2) combinaison partielle: surplus de la combinaison courante + somme des surplus des déclidisp courantes * 3) pas de combinaison, déclinaisons actives: somme des surplus des déclidisp courantes * 4) pas de déclinaisons (ou toutes déclidisps désactivées) => 0 (aucun surplus) */ private function boucleStock($texte, $args) { $res = ''; $idproduit = intval(lireTag($args, "produit")); $stockmini = intval($this->lireTagPrev($args, "stockmini", 'int')); $classement = $this->lireTagPrev($args, "classement", "string"); $produit = new Produit(); if ($produit->charger_id($idproduit)) { $surplus = 0; $stockproduit = 0; $this->trouver_stock_et_surplus($produit, false, $stockmini, $classement, $surplus, $stockproduit); $produit->prix += $surplus; $produit->prix2 += $surplus; $res = $texte; $res = preg_replace("/\#PROMO\[([^]]*)\]\[([^]]*)\]/", $produit->promo == 1 ? "\\1" : "\\2", $res); $res = str_replace("#VALEUR", $stockproduit, $res); $res = str_replace("#PRIX2", $produit->prix2, $res); $res = str_replace("#PRIX", $produit->prix, $res); $res = str_replace("#SURPLUS", $surplus, $res); $res = str_replace("#PRODUIT", $idproduit, $res); } return $res; } private function boucleQuantite($texte, $args) { $res = ''; $article = lireTag($args, "article", "int"); $idproduit = intval(lireTag($args, "produit", "int")); $ref = lireTag($args, "ref", "string"); $max = lireTag($args, "max", "int"); $min = lireTag($args, "min", "int"); $force = lireTag($args, "force", "int"); $valeur = lireTag($args, "valeur", "int"); // Utiliser imperativement les valeurs précedemment indiquées de stockmini et classement, // sinon on ne retrouve pas la combinaison par defaut. $stockmini = intval(self::$valeurs_defaut["stockmini"]); $classement = self::$valeurs_defaut["classement"]; $produit = new Produit(); $surplus = $stockproduit = 0; if ($article != "") { $this->trouver_stock_et_surplus(false, $article, $stockmini, $classement, $surplus, $stockproduit); } else if ( ($ref != "" && $produit->charger($ref)) || ($idproduit > 0 && $produit->charger_id($idproduit)) ) { $this->trouver_stock_et_surplus($produit, false, $stockmini, $classement, $surplus, $stockproduit); } if ($min == '') $min = 1; if ($max == '' || $max > $stockproduit) $max = $stockproduit; if ($force != '' && $valeur != '') { $min = 1; $max = intval($valeur); } if ($stockproduit >= $min) { for($idx = $min; $idx <= $max; $idx++) { if ($idx == $_SESSION['navig']->panier->tabarticle[$article]->quantite) $selected = 'selected="selected"'; else $selected = ''; $temp = str_replace("#NUM", $idx, $texte); $temp = str_replace("#SELECTED", $selected, $temp); $temp = str_replace("#REF", $ref, $temp); $res .= $temp; } } return $res; } } ?>