Champ de type décimal

3.2
Champ de type décimal
0.0 0
Tags: #<Tag:0x00007f9fa6cb51b8>

#1

Le champ décimal est modifiable, on peut y mettre la valeur 14 000 000 000,00 sans souci, et la sauvegarde se passe bien.

Mais si ce même champ contient 14 000 000 000,00 et qu’il est non modifiable, alors il n’est pas possible de sauvegarder. En effet le socle affiche bien 14 000 000 000,00 mais essaye de stocker 14E9.

Version : Simplicite 3.2


#2

Autre point 1 : Le displayValue d’un decimal renvoie 14E6 et non pas 14 000 000
Autre point 2 : On peut paramétrer plus de 10 décimal mais le socle n’en affiche que 10.

Simplicite : 3.2

Cordialement,

Sébastien


#3

Je vais réexpliquer mon premier point :

J’ai un acteur A qui peut saisir un montant en milliard et qui a deux champs en lecture seule (Taux de change et montant en euro)

J ai un acteur B qui peut saisir le taux de change et qui a deux champs en lecteur seule (Montant et montant en euro)

Le champs montant en euro est calculé à la volée

Scénario : L acteur A saisie le montant, l’acteur B saisie le taux, le montant en euro est calculé, l acteur B sauvegarde. (çà fonctionne). l’acteur B complète d autre données du formulaires et une erreur de type “Décimal non valide: Montant du financement en euro” apparaît.

Ce sont des champs de type décimaux
Simplicite 3.2, Mysql 5.7


#4

Ok je vais tester ça et je reviens vers toi…


#5

Il y a effectivement un problème de perte de précision/digit si le champ devient trop grand, à savoir dépasse la capacité d’un double.

En base et dans Simplicité 3.x, les montants sont hélas traités en “double”, il va falloir changer de précision en passant en BigDecimal au niveau Java + DECIMAL/NUMERIC en base de données afin de ne pas perdre en precision+scale (i.e. dans Simplicité en taille + précision après la virgule).

  • On va changer la précision des champs Float dans le moteur en utilisant le BigDecimal au lieu des doubles Java (les drivers SQL supportent désormais tous bien ce format). On limitera le scale (précision après la virgule à 32 digits = il sera possible de paramétrer un champ en taille 100, précision 32.

Impacts :

  • Le BigDecimal est largement supporté par tous les driver JDBC,et il offre les opérations de base (sauf le SQRT ou le POW(decimal) dans ces cas il faudra repasser par la double précision).

  • Il faut passer les colonnes physiques en DECIMAL(size, prec) sinon cela ne servira à rien. Le ALTER de Simplicité en cas de mise à jour du champ va être modifié en ce sens. On pourra ainsi supporter théoriquement le DECIMAL(100,32) maximum.

  • Enfin il va également falloir revoir les Tableaux croisés + Graphiques pour les passer en précision BigDecimal.

On va le faire sur la V4, et on backportera si possible ce qui est sans risque et opérationnel en 3.2 uniquement.


#6

Il en va de même pour les champs “Integer”, on va devoir les passer en BIGINT / long.


#7

Dernier point dans un champ calculé, l’expression simple :

[VALUE:test_montant] * [VALUE:test_taux]

continue d’être en double précision car l’interpréteur javascript va utiliser des doubles, avec risque de perte de précision/arrondis.

Il faudra donc revoir tous vos calculs et passer par les nouveaux accesseurs BigDecimal :

(function() {
var a = obj.getField(“test_montant”).getDecimal(); // BigDecimal
var b = obj.getField(“test_taux”).getDecimal(); // BigDecimal
return a.multiply(b);
})()

Ainsi avec des champs DECIMAL(100,32)

99 887 766 554 433 221 199,01234567890123456789012345678901 * 0,2000000000
= 19 977 553 310 886 644 239,80246913578024691357802469135780


#8

Pour en revenir au pb d’affichage en format scientifique “E”,
merci de préciser où et comment est calculé le champ montant en euros.

Si le calcul est fait via des doubles c’est normal, il faut penser à reformater la valeur String en résultat, si on veut 2 chiffres après la virgules :

  • via Tool.toFormattedFloat(a * b, 20, 2, “FRA”)
  • ou via du code Java natif comme : new Formatter(Locale.US).format("%.2f", val).toString()

PS : dans la javadoc de Tool.toFormattedFloat, il est indiqué que la précision max est de 10.
Nous allons la passer à 32 dans un futur proche.


#9

C’est calculé en javascript au changement du taux de change.(pour le coté dynamique :slight_smile: )
via une ressource associée à l’objet.


#10

Merci pour cette précision, le pb de formatage client est donc un pb de votre code :

  1. cela me semble insuffisant car la donnée/event peut être modifiée à la main ou planter (via le debugger du navigateur). => Il faut donc également re-forcer la valeur côté serveur (au preValidate).

  2. Votre a*b en javascript client doit sûrement retourner un double et non un String formaté dans la langue de l’utilisateur (séparateur virgule en français et non un point qui doit expliquer le rejet). Le validate doit rejeter le format utilisateur.

Il faut donc que le script client renseigne le champ comme si l’utilisateur devait le saisir :
donc qq chose du style input.value = (a*b).toFixed(2).replace(".", “,”) s’il est en Français


#11

Est ce que le BigDecimal a été implémenté ?


#12

Voir les release notes des dernières versions 3.2 et 4.0.

  • en 3.2 : l’évolution est partielle pour limiter les impacts en évitant juste les erreurs de précision en base (int et float passent en long et decimal). il faut faire des alter sur les colonnes (en faisant une mise à jour qq sur le champs ou en re-important le module).

  • en 4.0 : création d’un nouveau type de champ (décimal 100,32) + tous les calculs back se font en big décimal (tableaux croisés)

Par contre, rien ne corrigera votre code = calcul javascript sur la page qui reste du double.
var total = parseFloat(montant) * parseFloat(prix);

Le big decimal n’étant pas supporté par les navigateurs, il faudra integrer un composant tiers à votre page ou appeler un service back qui fera le calcul via des BigDecimal java et résultat en String (par un objet externe appelé via $.ajax).


#13

Ok merci, quand sera disponible la M06? sur la 3.2

Cordialement,


#14

Il y a quelques modifications structurantes en finalisation/test, donc pas avant 1 ou 2 semaines