Skip to content

ernestosjunior/cubos-checkout

This branch is 8 commits ahead of, 14 commits behind GEspinosa7/cubos-checkout:master.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

b8c8d0e · Jun 29, 2021

History

10 Commits
May 14, 2021
May 14, 2021
May 12, 2021
May 10, 2021
May 10, 2021
May 10, 2021
Jun 29, 2021
May 12, 2021
Jun 29, 2021
May 12, 2021
May 12, 2021
May 12, 2021
May 10, 2021

Repository files navigation

Desafio | Back-end - Módulo 2

Você acabou de ser contratado pela melhor empresa de tecnologia do mundo: a CUBOS. Sua primeira tarefa como desenvolvedor é criar uma API para realizar o CHECKOUT (finalização de compra) de produtos comercializados pela CUBOS, porém antes de realizarmos esse CHECKOUT, nós precisamos manipular o carrinho de compras e estoque desses produtos.

Você poderá usar a API completa para comparar com a sua. (Veja como utilizar no arquivo 'testes.md')

Seu papel é construir uma RESTful API que permita:

  • Adicionar produtos ao carrinho
  • Remover produtos do carrinho
  • Atualizar quantidades dos produtos no carrinho
  • Limpar o carrinho
  • Obter os dados do carrinho atual, incluindo:
    • Os produtos que estão no carrinho, com seus dados
    • O subtotal do carrinho (soma total em produtos)
    • O valor do frete
    • O valor total a pagar
  • Finalizar a venda (CHECKOUT)
  • Manipular estoque subtraindo ou adicionando quantidades de cada produto

Requisitos obrigatórios

  • Sua API deve seguir o padrão REST
  • Seu código deve estar organizado, delimitando as responsabilidades de cada arquivo adequadamente. Ou seja, é esperado que ele tenha, no mínimo:
    • Um arquivo index.js
    • Um arquivo de rotas
    • Um pasta com controladores
  • Evite códigos duplicados. Antes de copiar e colar, pense se não faz sentido esse pedaço de código estar centralizado numa função.

Estoque

Para simular o estoque de produtos, que normalmente ficaria num banco de dados, temos um arquivo JSON contendo um array de produtos chamado 'data.json'

Endpoints obrigatórios

GET /produtos

Essa rota deverá:

  • Listar todos os produtos e devolver no formato de array de produtos;
  • Listar apenas produtos que possuem estoque;
  • Filtrar produtos por categoria;
  • Filtrar produtos por faixa de preço;
  • Filtrar produtos por categoria e por faixa de preço ao mesmo tempo.

Exemplos:

  • /produtos
    • Deverá retornar todos os produtos em estoque
  • /produtos?categoria=bazar
    • Deverá retornar todos os eletrodomésticos que tenham unidades em estoque
  • /produtos?precoInicial=10000&precoFinal=200000
    • Deverá retornar todos os produtos que tenham unidades em estoque e custem entre 100 e 200 reais
  • /produtos?precoInicial=10000&precoFinal=200000&categoria=bazar
    • Deverá retornar todos os produtos que tenham unidades em estoque e custem entre 100 e 200 reais e sejam eletrodomésticos

GET /carrinho

Esta rota deverá retornar:

  • Uma lista (array) contendo os produtos que estão no carrinho, com todas as suas informações:
    • id
    • nome
    • preco
    • categoria
    • quantidade
  • O subtotal, ou seja, o total a pagar em produtos selecionados no carrinho
  • A dataDeEntrega que é fixada em 15 dias úteis para qualquer entrega;
  • O valorDoFrete, que segue a seguinte lógica:
    • Para compras até R$ 200,00 o valor do frete é R$ 50,00 e para compras acima de R$ 200,00 o frete é GRÁTIS;
  • O totalAPagar que é a soma do subtotal com o frete.

Exemplos:

Naturalmente, o retorno dessa chamada deve variar de acordo com as possíveis chamadas que tenham sido feitas anteriormente, adicionando ou removendo produtos do carrinho.

  • Para um carrinho vazio, a chamada a /carrinho deverá retornar
{
    "produtos": [],
    "subtotal": 0,
    "dataDeEntrega": null,
    "valorDoFrete": 0,
    "totalAPagar": 0
}
  • Para um carrinho com produtos, a chamada a /carrinho deverá retornar um objeto no seguinte formato, embora o conteúdo possa variar:
{
  "subTotal": 1518,
  "dataDeEntrega": "2021-05-21T21:30:27.743Z", //requisicao feita em 21/05/2021
  "valorDoFrete": 5000, // porque a compra é menor que 20000
  "totalAPagar": 6518,
  "produtos": [
    {
      "id": 3,
      "quantidade": 1,
      "nome": "Limpador Cif Multiuso 800g Em Pó",
      "preco": 999,
      "categoria": "Limpeza"
    },
    {
      "id": 5,
      "quantidade": 1,
      "nome": "Biscoito BAUDUCCO Choco Biscuit Leite 80g",
      "preco": 519,
      "categoria": "Bazar"
    }
  ]
}


POST /carrinho/produtos

Para esta rota, você deverá:

  • Informar id do produto e quantidade a ser inserida;
  • Antes de adicionar verificar se o produto tem estoque suficiente para a adição;
  • Retornar o carrinho, ou seja, a lista de produtos e suas respectivas quantidades, subtotal do carrinho, total a pagar, valor do frete e data de entrega.

Exemplo, ao passar esse JSON no body da requisição...

{
	"id":11,
	"quantidade":1
}

... o retorno deverá ser o carrinho, veja abaixo:

{
  "subTotal": 1199,
  "dataDeEntrega": "2021-05-19T17:42:11.290Z",
  "valorDoFrete": 5000,
  "totalAPagar": 6199,
  "produtos": [
    {
      "id": 11,
      "quantidade": 1,
      "nome": "Oléo de Canola QUALITÁ Pet 900ml",
      "preco": 1199,
      "categoria": "Oleo"
    }
  ]
}

PATCH /carrinho/produtos/:idProduto

Para esta rota, você deverá deverá:

  • Informar o id do produto e a quantidade a ser alterada;
  • Para que a operação funcione, o carrinho deverá já conter algum produto com esse id. Caso contrário, a chamada deverá retornar um erro com uma mensagem adequada.
  • Caso a quantidade informada seja positiva, esse número produtos será adicionados ao carrinho. Para isso, é necessário que haja estoque suficiente. Nunca deve ser possível ter mais produtos no carrinho do que em estoque.
  • Caso a quantidade informada seja negativa, esse número produtos será removido ao carrinho. Caso a quantidade seja maior que o número de itens desse produto no carrinho, a operação deverá retornar erro.
  • A chamada deverá retornar o carrinho completo, como no exemplo de GET /carrinho

Exemplos

  • Para um carrinho como no exemplo de PATCH /carrinho/produtos/3 a chamada passando os seguintes dados:
{
    "quantidade": 5
}

deverá retornar

{
  "subTotal": 6513,
  "dataDeEntrega": "2021-05-18T22:30:46.920Z",
  "valorDoFrete": 5000, // porque a compra é menor que 20000
  "totalAPagar": 11513,
  "produtos": [
    {
      "id": 3,
      "quantidade": 6,
      "nome": "Limpador Cif Multiuso 800g Em Pó",
      "preco": 999,
      "categoria": "Limpeza"
    },
    {
      "id": 5,
      "quantidade": 1,
      "nome": "Biscoito BAUDUCCO Choco Biscuit Leite 80g",
      "preco": 519,
      "categoria": "Bazar"
    }
  ]
}

DELETE /carrinho/produtos/:idProduto

Para esta rota, você deverá:

  • Informar o id do produto a ser excluido do carrinho
  • Verificar se existe esse produto no carrinho. Caso não exista, deverá ser retornada uma mensagem de erro adequada
  • Caso seja possível, você deverá retornar o carrinho, como no exemplo em GET /carrinho

Exemplo:

Para um carrinho como no exemplo de GET /carrinho a chamada do metodo DELETE para /produtos/1 deverá retornar:

{
  "subTotal": 5994,
  "dataDeEntrega": "2021-05-18T22:36:04.749Z", // requisição feita em 18/05/2021
  "valorDoFrete": 5000, // porque a compra é menor que 20000
  "totalAPagar": 10994,
  "produtos": [
    {
      "id": 3,
      "quantidade": 6,
      "nome": "Limpador Cif Multiuso 800g Em Pó",
      "preco": 999,
      "categoria": "Limpeza"
    }
  ]
}

DELETE /carrinho

Nesta rota você deverá limpar o carrinho completamente, removendo todos os produtos. Retorne uma mensagem informando que a operação foi realizada com sucesso.


POST /finalizar-compra

Nesta rota, você deverá, OBRIGATORIAMENTE:

  • Verificar se o carrinho está vazio. Caso esteja, retorne uma mensagem de erro.
  • Verificar se os produtos que estão no carrinho, ainda constam em estoque em quantidades suficientes. Caso não constem, deve-se retornar uma mensagem de erro adequada.
  • Verificar se estão sendo recebidos os dados do cliente, no formato abaixo:
{
      "type": "individual",
      "country": "br",
      "name": "Aardvark Silva",
      "documents": [
        {
          type: "cpf",
          number: "00000000000",
        },
      ],
}
  • Validar dados do usuário antes da emissão do boleto, ou seja verificar se:
    • O campo country tem dois dígitos
    • O campo type é 'individual' (este e-commerce só atende pessoas físicas)
    • O campo name tem, pelo menos, nome e sobrenome.
    • O campo documents contem um cpf com 11 dígitos apenas numéricos.
  • Abater os itens vendidos das quantidades em estoque
  • Limpar o carrinho carrinho
  • Retornar uma mensagem de erro adequada, caso alguma validação não esteja ok.
  • Caso todas as validações estejam ok, você deve retornar:
    • Mensagem de sucesso,
    • Carrinho (itens, quantidades, subtotal, data de entrega e total a pagar)

Parte Opcional

POST finalizar-compra

Além dos itens obrigatórios, neste endpoint, você poderá adicionalmente:

  • Integrar verdadeiramente com a pagar.me, utilizando o token de desenvolvimento da Cubos Academy ak_test_rFF3WFkcS9DRdBK7Ocw6QOzOOQEScS
    • Coloque o vencimento do boleto para 3 dias uteis após a data atual
    • Retorne, em caso de sucesso, o link do boleto com os outros dados.
  • Adicionar essa venda em um arquivo de pedidos, usando o número da transação do PAGARME como id desse pedido
  • Permitir aplicarmos cupons de desconto:
    • Inclua no carrinho um query parameter de cupom e retorne o carrinho com uma campo a mais de descontos.
    • Lembre de, claro, atualizar o total a pagar

Relatórios

Em todo e-commerce é interessante ter relatórios de vendas. Crie novos endpoints, pensando em bons nomes e verbos que você julgar adequados, para que seja possível obter as seguintes informações:

  • Listar vendas por produto;
{
  "relatorioProduto": {
    "id": 11,
    "produto": "Oléo de Canola QUALITÁ Pet 900ml",
    "quantidadeVendida": 1,
    "valorAcumuladoEmVendas": 1199
  }
}
  • Listar vendas por categoria de produto;
{
  "relatorioCategoria": {
    "categoria": "Bazar",
    "quantidadeVendida": 4,
    "valorAcumuladoEmVendas": 6186
  }
}
  • Listar vendas em um intervalo de tempo (dataInicial e dataFinal), esse relatório é exatamente igual aos relatórios por categoria e por produto, a única diferença é que ele filtra por intervalo de duas datas.

Obs.: Os relatórios pode ser filtrados acumulativamente, ou seja, filtrados por produto, categoria e intervalo (dataInicial e dataFinal) ao mesmo tempo. Caso não seja passado categoria, produto e nem intervalo, o end-point deve retornar todas as vendas realizadas, ex.:

[
  {
    "id": 12155857,
    "dataVenda": "2021-05-04T01:18:58.422Z",
    "produtos": [
      {
        "id": 3,
        "quantidade": 5,
        "nome": "Limpador Cif Multiuso 800g Em Pó",
        "preco": 999,
        "categoria": "Limpeza"
      },
      {
        "id": 5,
        "quantidade": 1,
        "nome": "Biscoito BAUDUCCO Choco Biscuit Leite 80g",
        "preco": 519,
        "categoria": "Bazar"
      }
    ],
    "valorVenda": 2102.8,
    "linkBoleto": "https://pagar.me"
  },
  {
    "id": 12160050,
    "dataVenda": "2021-05-04T14:34:45.748Z",
    "produtos": [
      {
        "id": 1,
        "quantidade": 1,
        "nome": "Pipoca para Microondas Manteiga YOKI 50g",
        "preco": 169,
        "categoria": "Bazar"
      },
      {
        "id": 9,
        "quantidade": 2,
        "nome": "Arroz Parboilizado Tipo 1 CAMIL Pacote 5kg",
        "preco": 2749,
        "categoria": "Bazar"
      },
      {
        "id": 11,
        "quantidade": 1,
        "nome": "Oléo de Canola QUALITÁ Pet 900ml",
        "preco": 1199,
        "categoria": "Oleo"
      }
    ],
    "valorVenda": 2373.2,
    "linkBoleto": "https://pagar.me"
  }
]

Repare que para fazer este item opcional, é necessário primero fazer o item opcional de escrever em um arquivo as vendas realizadas.

LEMBRE-SE: é melhor feito do quê perfeito!!!

tags: back-end módulo 2 nodeJS API REST desafio

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%