npm package: @logicamente.info/mongoose-currency-brl
Description: Adiciona o tipo 'BrazilianCurrency' ao mongoose para tratar dinheiro. Remove caracteres comuns automaticamente (',', 'R$' e letras do alfabeto).
Author: Logicamente Info
Latest version: 1.0.1

# Mongoose-Currency-BRL

[![Travis][build-badge]][build]
[![npm package][npm-badge]][npm]

Menção honrosa a @paulcsmith por disponibilizar o repositório original que tornou este pacote possível.

## O que isto faz

* Salva uma String como Integer (remove não dígitos e multiplica por 100) para prevenir erros de arredondamento ao realizar cálculos ([Ver "Sacadas"](#Sacadas) para detalhes)
* Remove símbolos da string (como símbolo da moeda `$` ou `R$`)
* Remove pontos (e.g. `"1.000,50"` => `100050`)
* Salva apenas os dois primeiros digitos da parte decimal (`"R$ 500,559"` é convertido para `50055` e **não arredonda**)
* Remove [a-zA-Z] das strings
* Aceita strings e números. Número serão armazenados tal como informado.
* Se um ponto flutuante for passado, ele será arredondado. (`500.55` => `501`). **Use apenas inteiros ou strings por segurança**.

## Como usar

```js
import mongoose from "mongoose";
import { BrazilianCurrency } from "@logicamente.info/mongoose-currency-brl";

// Adicione o tipo BrazilianCurrency ao Mongoose (necessário uma única vez, sugestão: coloque no arquivo de criação da conexão)
BrazilianCurrency.loadType(mongoose);

const ProdutoSchema = Schema({
  preco: { type: BrazilianCurrency }
});

const Produto = mongoose.model('Produto', ProdutoSchema);

const produto = new Produto({ preco: "R$ 1.200,55" });
produto.preco; // Número: 120055
produto.preco = 1200;
produto.preco; // Número 1200 não irá arredondar ou multiplicar e deve representar R$ 12,00
```

### Schema options

Aceita o [esquema de opções de números](http://mongoosejs.com/docs/api.html#schema-number-js) do mongoose.

```js
// Irá validar se o mínimo é R$ 200,00 e o máximo é R$ 500,00
var ProdutoSchema = Schema({
  preco: { type: BrazilianCurrency, required: true, min: -20000, max: 50000 }
});
```

### Exibindo para usuários finais (telas, relatórios, etc.)

Para exibir os valores aos usuários finais, lembre-se de dividir por 100, e na sequência você pode mascarar o resultado.

```js
// Se produto.preco = 120055
const preco = produto.preco / 100; // Retorna 1200.55
const opcoes = { style: 'currency', currency: 'BRL' };
Intl.NumberFormat('pt-BR', opcoes).format(preco); // Retorna R$ 1.200,55
```

## Testando

Na raiz do diretório do projeto, execute `npm test`

## Sacadas

O valor é armazenado e retornado como um inteiro. Por que? Porque somar dois pontos flutuantes pode causar erros de arredondamento.

```js
// Isso não é bom
1.03 + 1.19; // 2.2199999999999998
```

### Cálculos com valores usando mongoose-currency-brl

```js
const produto1 = Produto.findById('id1');
const produto2 = Produto.findById('id2');
produto1.preco; // retorna 103 que representa R$ 1,03
produto2.preco; // retorna 119 que representa R$ 1,19
const soma = (produto1.preco + produto2.preco) / 100; // = 222
soma / 100; // retorna um número decimal: 2.22
```

### Exibindo valores para usuários finais

```js
const opcoes = { style: 'currency', currency: 'BRL' };
const registro = Produto.findById('id');
registro.preco; // Supondo 10050
Intl.NumberFormat('pt-BR', opcoes).format(preco); // R$ 100,50
```

Quando você atribui um inteiro, ele NÃO será multiplicado por 100. Será armazenado tal como é!
Isto é de propósito, pois esta biblioteca foi criada principalmente para aceitar entradas realizadas por USUÁRIOS.

```js
produto.preco = 100;
produto.preco; // Retorna 100 e não multiplica por 100. Representa R$ 1,00
```

### Consultas e validadores

Lembre-se que ao fazer consultas para encontrar valores maiores que, menores que, etc. você precisará multiplicar por 100!

Então para retornar valores maiores que R$ 100,00 você precisará realizar a consulta com 100 * 100 e.g. 10000

*Esta é considerada uma boa prática para armazenar valores monetários como inteiros.
Causará muito menos problemas pelo caminhho*

Para uma leitura mais aprofundada: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Apenas **lembre-se dividir por 100** toda vez que você quiser exibir os valores para o usuário.

[build-badge]: https://img.shields.io/travis/logicamenteinfo/mongoose-currency-brl/master.png?style=flat-square
[build]: https://travis-ci.org/logicamenteinfo/mongoose-currency-brl

[npm-badge]: https://img.shields.io/npm/v/@logicamente.info/mongoose-currency-brl.png?style=flat-square
[npm]: https://www.npmjs.org/@logicamente.info/mongoose-currency-brl