trucos hobba hevvo hartico habtium habbo fantasy creditos comandos node.js mongoose currency

node.js - hobba - ¿cómo debo almacenar un precio en mangosta?



hartico (5)

Estoy usando esquemas de mangosta para node.js junto con el validador express (que tiene santizaciones y validadores del validador de nodos).

¿Cuál es una buena forma de almacenar el precio de un artículo?

Actualmente tengo

var ItemSchema = new Schema({ name : { type: String, required: true, trim: true } , price : Number });

El precio es opcional, entonces tengo:

if ( req.body.price ) { req.sanitize(''price'').toFloat(); req.assert(''price'', ''Enter a price (number only)'').isFloat(); }

express-validator me da isNumeric (permite 0 relleno), isDecimal y isInt ... Prefiero simplemente convertir a decimal y quitar todos los caracteres, así que siempre inserto 42.00 en db.

Quiero permitirles ingresar $ 42.00, $ 42, 42, 42.00 y solo almacenar 42.00. ¿Cómo puedo lograr esto? y todavía validar que estoy viendo algo parecido a un número, por ejemplo, si ingresan ''abc'', deseo devolver un error al formulario usando req.assert.

Además, supongo que la divisa eventualmente se convertirá en un problema ...

Actualización, encontré esta publicación que dice que almacenar el precio como un entero en centavos, por lo que 4200 https://dba.stackexchange.com/questions/15729/storing-prices-in-sqlite-what-data-type-to-use

Solo necesito una forma de convertir 4200 a $ 42.00 cuando llamo item.price y también desinfecte y convierta la entrada en 4200.


Sugerencia: El método descrito aquí es básicamente otra implementación de la respuesta de chovy .

Solución para Mongoose 3 y 4:

Si tiene problemas para definir getters y setters directamente en el esquema, también puede usar la función schema.path() para hacer que esto funcione:

var ItemSchema = new Schema({ name: String, price: Number }); // Getter ItemSchema.path(''price'').get(function(num) { return (num / 100).toFixed(2); }); // Setter ItemSchema.path(''price'').set(function(num) { return num * 100; });


Agrega el tipo de esquema "Moneda" a la mangosta para manejar dinero. Elimina automáticamente los caracteres comunes (",", "$" y caracteres alfabéticos)

https://github.com/paulcsmith/mongoose-currency

Que hace:

Guarda una cadena como un entero (eliminando los dígitos y multiplicando por 100) para evitar errores de redondeo al realizar cálculos (ver detalles para obtener detalles) Elimina los símbolos del comienzo de las cadenas (a veces los usuarios incluyen el símbolo de moneda) Quita las comas (a veces los usuarios agregan comas o copian valores pegados en formularios, por ejemplo, "1,000.50). Solo guarde dos dígitos después del punto decimal (" $ 500.559 "se convierte en 50055 y no redondea) Tiras [a-zA-Z] de cadenas Pase una cadena o un número. Los números se almacenarán TAL CUAL. Supone que si establece el valor en un número entero, ya ha realizado la conversión (por ejemplo, 50000 = $ 500.00). Si se pasa un número de coma flotante, lo redondeará (500.55 -> 501). Solo pasa enteros para estar seguro.

Espero que ayude a1.



Esto es lo que terminé haciendo ...

Guardé el precio como centavos en la base de datos, por lo que es 4999 para 49.99 como se describe aquí: https://dba.stackexchange.com/questions/15729/storing-prices-in-sqlite-what-data-type-to-use

el getPrice lo convertirá de nuevo en formato legible, por lo que puedo usar item.price en mis vistas sin modificarlo.

el setPrice lo convierte en centavos.

modelo:

var ItemSchema = new Schema({ name : { type: String, required: true, trim: true } , price : {type: Number, get: getPrice, set: setPrice } }); function getPrice(num){ return (num/100).toFixed(2); } function setPrice(num){ return num*100; }

Opté por solo permitir dígitos y decimales en el campo de precio, sin $. Entonces pueden ingresar 49, 49.99, 49.00, pero no 49.0 o $ 49

validación usando regex:

if ( req.body.price ) { req.assert(''price'', ''Enter a price (numbers only)'').regex(/^/d+(/./d{2})?$/); }

Ojalá hubiera una forma de permitir el $ porque creo que es un problema de usabilidad, solo deja que el usuario lo ingrese, pero despréndete. No estoy seguro de cómo hacer eso y todavía validar que tenemos un precio y no un montón de cartas, por ejemplo.


He estado investigando durante un tiempo sobre este tema, porque quiero almacenar no solo el precio, sino la versión, que pueden tener 0 finales que se cortan cuando se almacenan como un número. Hasta donde yo sé, Mongoose / MongoDB no puede guardar un número con ceros finales.

A menos que guarde el número como una cadena.

Además de almacenar números en decenas o miles y dividir o analizar, también puede almacenarlo como una cadena. Esto significa que siempre puede imprimirlo cuando necesite mostrar "1.0" o "1.00" simplemente usando la variable sin ninguna conversión. Debido a que JavaScript está sin tipo, aún puede compararlo con números (asegúrese de que esté en el lado izquierdo). Var <10, por ejemplo, devolverá la evaluación correcta, incluso cuando var es una cadena. Sin embargo, si comparas dos variables, necesitarás asegurarte de que sean ambas. Cuando necesite un número, puede multiplicar la cadena por uno (var * 1 <var2 * 1), lo que garantizará que JavaScript trate la var como un número, aunque perderá los ceros finales.

Por un lado, almacenarlo como una cadena significa que debe hacer una conversión cada vez que quiera usar la variable como un número. Por otro lado, presumiblemente estarás haciendo una conversión numérica de todos modos (var / 100) cada vez que quieras usar un número de centavos como cantidad en dólares. Esta opción dependerá de la frecuencia con la que necesite su valor como número. También puede causar errores más grandes si olvida que su variable es una cadena que si olvida que su variable está en centavos.

(Sin embargo, es una excelente opción para números de versión que solo se usarían para mostrar y comparar).