Aller au contenu

Nombres et décimales


Sujets conseillés

Posté (modifié)

Bonjour, soir,

Pour un traitement spécifique e-commerce, j'ai un souci lors d'une simple condition entre deux nombres.

$e1 = "909,23";
$e2 = "2000,01";
$e3 = $e2 - $e1;
if ($e1 < $e2) echo "inf !!<br>";
echo "e3 = ". $e3 ."<br>";

Je teste donc bêtement, et je me retrouve avec deux problèmes.

Le premier concerne la soustraction en elle-même. Le résultat ci-dessus ($e2 - $e1) me donne 1091. Où sont passées les décimales ? (je sais que jai oublié qlque chose, mais quoi ??)

De plus, la condition de supériorité n'est pas respectée :whistling: ...

Auriez-vous une idée ?

xpatval

[EDIT] Bon, en fait, lorsque l'on est idiot, hein....ça va, j'ai trouvé. [/EDIT]

Modifié par xpatval
Posté

Tu ferais mieux de dire pourquoi ça ne marchait pas pour que tout le monde puisse en profiter au cas où il aurait un problème... Les guillemets non ? Au hasard :P

[marvin, tu m'as grillé et pour répondre autre chose que moi... Je n'utilise jamais de décimales dans mes progs, je viens de me rendre compte de ça !]

Posté

Allez, je vais vous dire mon véritable problème.

Le but du jeu est donc de minorer un prix, en fonction de son appartenance à certaines catégories ET du montant: en gros, si le montant total d'un produit (d'une certaine catégorie) acheté X (multiplié par...) la quantité de ce produit achetée appartient à l'une des fourchettes de prix/catégories définies par l'admin, ce montant total sera minoré d'un certain pourcentage, défini lui-aussi ! :whistling:

C'est clair ? Bon, interro !....

Et donc, ô surprise, lorsque ce montant est de 1 000 pile, et alors même qu'il rentre dans le cadre d'une réduction de x%, rien, que nenni, peau de balle !! Il se fout du 2 000, du 950, tout ça, ça baigne, mais le 1000, non ! L'est faché ! :nono:

Pourquoi ? Mais que diantre, pourquoi ?

ps: Je n'ose vous balancer le code, car c'est casse-tête !

Ah, C'est de l'OsCommerce.

xpatval

Posté
ps: Je n'ose vous balancer le code, car c'est casse-tête !

N'hésites surtout pas, au contraire !!!

C'est avec le code que l'on pourra trouver le problème le plus rapidement possible ;)

Ah,  C'est de l'OsCommerce.

Raison de plus, un certain nombre de membres du Hub ont l'habitude d'Oscommerce. Ils sauront s'y retrouver sans problèmes ;)

Posté

Ok, alors au menu, nous avons

la partie du script d'affichage des montants:

		if ($currencies->display_price_reduct($products[$i]['id'], $products[$i]['final_price'], tep_get_tax_rate($products[$i]['tax_class_id']), $products[$i]['quantity']) < $currencies->display_price($products[$i]['final_price'], tep_get_tax_rate($products[$i]['tax_class_id']), $products[$i]['quantity']))
{
$info_box_contents[$cur_row][] = array('align' => 'right',
'params' => 'class="productListing-data" valign="top"',
'text' => '<b><s>' . $currencies->display_price($products[$i]['final_price'], tep_get_tax_rate($products[$i]['tax_class_id']), $products[$i]['quantity']) . '</s></b>');
$info_box_contents[$cur_row][] = array('align' => 'right',
'params' => 'class="productListing-data" valign="top"',
'text' => '<b>' . $currencies->display_price_reduct($products[$i]['id'], $products[$i]['final_price'], tep_get_tax_rate($products[$i]['tax_class_id']), $products[$i]['quantity']) . '</b>');
}

En clair, les lignes importantes sont celles-ci:

$currencies->display_price($products[$i]['final_price'], tep_get_tax_rate($products[$i]['tax_class_id']), $products[$i]['quantity'])

Celle-ci (au dessus) calcule et affiche le prix total par article, sans réduction.

$currencies->display_price_reduct($products[$i]['id'], $products[$i]['final_price'], tep_get_tax_rate($products[$i]['tax_class_id']), $products[$i]['quantity'])

Celle-ci va calculer et afficher le montant total par produit, AVEC réduction. Elle appelle une fonction (display_price_reduct):

	function display_price_reduct($products_id, $products_price, $products_tax, $quantity = 1) {
     return $this->format($this->moderate($products_id, tep_add_tax($products_price, $products_tax) * $quantity));
   }

Laissons de coté la fonction format(), qui ne sert (enfin presque) qu'à l'affichage du symbole monétaire.

J'ai rajouté la fonction moderate():

	function moderate($products,$total)
{
 $sql = "select accord_reduct.categories_id, reduction, montant_inf, montant_sup from
   quentinf.reduct_product, quentinf.accord_reduct, quentinf.products_to_categories where
   products_to_categories.products_id = '". $products ."' and
   products_to_categories.categories_id = accord_reduct.categories_id and
   accord_reduct.id_reduct_product = reduct_product.id_reduct_product"; # and
 $r = mysql_query($sql);
 while ($i = mysql_fetch_array($r))
 {
 if (($total >= $i['montant_inf']) && ($total <= $i['montant_sup']))
 {
   $total /= $i['reduction'];
 }
 }
 return $total;
}

Et dans ma table accord_reduct, deux champs me servent de limite à mes fourchettes de prix.

Les données contenues dans ces champs sont de la forme int(4) pour "montant_inf", et decimal(6,2) pour "montant_sup".

Leurs valeurs sont égales à, par exemple, 300 pour la limite basse, et 799.99 pour la limite haute.

Dans le cas des 1000 , ce prix est compris entre 300 pour la limite inf, et 99999.99 pour la supérieure. Mais il n'y a aucune réduction d'attribuée...

Et je tiens à préciser que la valeur du montant (1000.00) a un point (dot in english) pour séparateur décimal.

Suis-je clair...? :whistling:

xpatval

Posté

Bonjour xpatval,

Je suis aussi sur oscommerce et quand je fais des calculs, je les fais toujours avec mes valeurs brutes issues de mes tables, c'est à dire, avant application des calculs de TVA, application de la monnaie, mise en forme.

Posté

Oui, bien sur, mais dans mon cas, aucune taxe ni tva n'est appliquée. La valeur d'achat avant mise en forme, est la même qu'après !

xpatval

Posté

cela ne marche pas pour les 1000. Est ce que c'est lié au montant? ou bien au produit ?, as tu essayé de garder le même produit, mais avec un autre montant que 1000 ?

As tu vérifié que le produit est bien dans la bonne catégorie et que la catégorie est bien dans accord_reducts ?

Posté

Yep, mister Loulou.

c'est un produit à 40 * 25 = 1000 .

Le problème ne survient pas avec 24 produits de la même sorte (960), ou 26 (1040), ni même 50 (2000) ! :whistling:

Où est Chouchou ? ^_^

xpatval

Posté

Et ta limite haute, elle est de combien : 799.99 ou alors 99999.99 ?

je n'ai pas compris dans ton message.

Si c'est 99999.99, alors ça devrait marcher. Si c'est 799.99, il se peut que tu ais une autre tranche dans pour la quelle il n'y a pas de réduc ou pas de tranche du tout :

de 300 à 799.99 reduc de 5%

de 800 à 1039.99 réduc de x%

de 1040 à 1099.99...

c'est lequl la femme : loulou ou chouchou ?

Posté (modifié)

Ce prix entre dans une fourchette 300 - 99999.99

[EDIT] Sorry, MISS Loulou...[/EDIT]

Modifié par xpatval
Posté
Et dans ma table accord_reduct, deux champs me servent de limite à mes fourchettes de prix.

Tu peux nous mettre le contenu de ta table accord_reduct, s'il te plait ?

Nico.

Posté

Le contenu de la table.


id_accord_reduct | categories_id | id_reduct_product | montant_inf | montant_sup
1 31 1 300 749.99
2 31 3 750 99999.99
3 32 1 150 299.99
4 32 2 300 399.99
5 32 3 400 99999.99
6 34 1 100 199.99
7 34 2 200 299.99
8 34 3 300 99999.99
9 35 1 100 199.99
10 35 2 200 299.99
11 35 3 300 99999.99
12 36 1 100 199.99
13 36 2 200 299.99
14 36 3 300 99999.99
15 37 1 100 199.99
16 37 2 200 299.99
17 37 3 300 99999.99
18 38 1 100 199.99
19 38 2 200 299.99
20 38 3 300 99999.99

En fait, le souci apparaît aussi avec une somme à 4 chiffres, commençant par 10 (1040, ou 1065 ), en plus de celui avec les 1000.

J'en ai marre :angry:

xpatval

Posté

Là :

 while ($i = mysql_fetch_array($r))
{
 if (($total >= $i['montant_inf']) && ($total <= $i['montant_sup']))
 {
  $total /= $i['reduction'];
 }
}

Ne devrais tu pas rajouter une condition ?

  if (($total >= $i['montant_inf']) && ($total <= $i['montant_sup']))
 {
  $total /= $i['reduction'];
 }
else{
$total = $total;
}

Laissons de coté la fonction format(), qui ne sert (enfin presque) qu'à l'affichage du symbole monétaire.

Quoique..

return $this->format($this->moderate($products_id, tep_add_tax($products_price, $products_tax) * $quantity));

Tu peux nous mettre la fonction format, please ;)

Posté

Ne penses tu pas que cela peut venir du format des champs montant_inf et montant_sup ?

Moi, pour tous les champs relatifs à des "prix" je suis en décimal (15.4)

1 31 1 300.0000 749.9900

2 31 3 750.0000 99999.9900

Peut être que c'est là que ça coince ?

Posté
Ne devrais tu pas rajouter une condition ?

<?php   class currencies {
var $currencies;

// class constructor
function currencies() {
$this->currencies = array();
$currencies_query = tep_db_query("select code, title, symbol_left, symbol_right, decimal_point, thousands_point, decimal_places, value from " . TABLE_CURRENCIES);
while ($currencies = tep_db_fetch_array($currencies_query)) {
$this->currencies[$currencies['code']] = array('title' => $currencies['title'],
'symbol_left' => $currencies['symbol_left'],
'symbol_right' => $currencies['symbol_right'],
'decimal_point' => $currencies['decimal_point'],
'thousands_point' => $currencies['thousands_point'],
'decimal_places' => $currencies['decimal_places'],
'value' => $currencies['value']);
}
}

// class methods
function format($number, $calculate_currency_value = true, $currency_type = '', $currency_value = '') {
global $currency;

if (empty($currency_type)) $currency_type = $currency;

if ($calculate_currency_value == true) {
$rate = (tep_not_null($currency_value)) ? $currency_value : $this->currencies[$currency_type]['value'];
$format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(tep_round($number * $rate, $this->currencies[$currency_type]['decimal_places']), $this->currencies[$currency_type]['decimal_places'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
// if the selected currency is in the european euro-conversion and the default currency is euro,
// the currency will displayed in the national currency and euro currency
if ( (DEFAULT_CURRENCY == 'EUR') && ($currency_type == 'DEM' || $currency_type == 'BEF' || $currency_type == 'LUF' || $currency_type == 'ESP' || $currency_type == 'FRF' || $currency_type == 'IEP' || $currency_type == 'ITL' || $currency_type == 'NLG' || $currency_type == 'ATS' || $currency_type == 'PTE' || $currency_type == 'FIM' || $currency_type == 'GRD') ) {
$format_string .= ' <small>[' . $this->format($number, true, 'EUR') . ']</small>';
}
} else {
$format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(tep_round($number, $this->currencies[$currency_type]['decimal_places']), $this->currencies[$currency_type]['decimal_places'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
}
return $format_string;
}

function moderate($products,$total)
{
$sql = "select accord_reduct.categories_id AS cat_id, reduction, montant_inf, montant_sup from
quentinf.reduct_product, quentinf.accord_reduct, quentinf.products_to_categories where
products_to_categories.products_id = '". $products ."' and
products_to_categories.categories_id = accord_reduct.categories_id and
accord_reduct.id_reduct_product = reduct_product.id_reduct_product"; # and
$r = mysql_query($sql);
while ($i = mysql_fetch_array($r))
{
if (($total >= $i['montant_inf']) && ($total <= $i['montant_sup']))
{
$total /= $i['reduction'];
}
}
return $total;
}

function is_set($code) {
if (isset($this->currencies[$code]) && tep_not_null($this->currencies[$code])) {
return true;
} else {
return false;
}
}

function get_value($code) {
return $this->currencies[$code]['value'];
}

function get_decimal_places($code) {
return $this->currencies[$code]['decimal_places'];
}

function display_price($products_price, $products_tax, $quantity = 1) {
return $this->format(tep_add_tax($products_price, $products_tax) * $quantity);
}

function display_price_reduct($products_id, $products_price, $products_tax, $quantity = 1) {
return $this->format($this->moderate($products_id, tep_add_tax($products_price, $products_tax) * $quantity));
}
}
?>

A vot' bon coeur, M'sieurs-dames...

xpatval

Posté (modifié)
Ne penses tu pas que cela peut venir du format des champs montant_inf et montant_sup ?

Moi, pour tous les champs relatifs à des "prix" je suis en décimal (15.4)

1 31 1 300.0000 749.9900

2 31 3 750.0000 99999.9900

Peut être que c'est là que ça coince ?

<{POST_SNAPBACK}>

J'eu pu le pensu, mais j'ai, à ton image, modifié l'attribut des deux champs en décimal (15,4). Les résultats ne varient pas.

Par contre, pour faire suite à l'un de mes précédents posts, ce problème concerne les montant dont le chiffre commence par 10 (hormis 10, que je n'ai pas testé). Un montant de 1040, 10258, 101600 ,n'est pas minoré.

xpatval

Modifié par xpatval

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...