diff --git a/Gemfile b/Gemfile index 2831a34..14f5861 100644 --- a/Gemfile +++ b/Gemfile @@ -11,6 +11,7 @@ gem "sprockets-rails" gem "sqlite3", "~> 1.4" gem "puma", "~> 5.0" gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] +gem 'rails-i18n' group :development, :test do gem "capybara" diff --git a/Gemfile.lock b/Gemfile.lock index 72989ad..a7fcd3f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -131,6 +131,8 @@ GEM nio4r (2.5.8) nokogiri (1.13.8-arm64-darwin) racc (~> 1.4) + nokogiri (1.13.8-x86_64-linux) + racc (~> 1.4) orm_adapter (0.5.0) popper_js (2.11.6) public_suffix (5.0.0) @@ -159,6 +161,9 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.4.3) loofah (~> 2.3) + rails-i18n (7.0.5) + i18n (>= 0.7, < 2) + railties (>= 6.0.0, < 8) railties (7.0.4) actionpack (= 7.0.4) activesupport (= 7.0.4) @@ -206,6 +211,7 @@ GEM activesupport (>= 5.2) sprockets (>= 3.0.0) sqlite3 (1.5.2-arm64-darwin) + sqlite3 (1.5.2-x86_64-linux) thor (1.2.1) tilt (2.0.11) timeout (0.3.0) @@ -222,6 +228,7 @@ GEM PLATFORMS arm64-darwin-21 + x86_64-linux DEPENDENCIES bootstrap (~> 5.2.1) @@ -231,6 +238,7 @@ DEPENDENCIES importmap-rails puma (~> 5.0) rails (~> 7.0.4) + rails-i18n rspec-rails sprockets-rails sqlite3 (~> 1.4) diff --git a/app/controllers/product_categories_controller.rb b/app/controllers/product_categories_controller.rb deleted file mode 100644 index 180bc41..0000000 --- a/app/controllers/product_categories_controller.rb +++ /dev/null @@ -1,21 +0,0 @@ -class ProductCategoriesController < ApplicationController - def create - ProductCategory.create!(name: params.require(:product_category).permit(:name)) - redirect_to products_path, notice: 'Categoria cadastrada' - end - - def search - nome_a_buscar = params[:busca] - ProductCategory.where("name LIKE :param_busca OR outro_campo LIKE :param_busca OR mais_um_campo LIKE :param_busca ", - { param_busca: "%#{nome_a_buscar}%" } ) - - @transports = find_available_transports - - end - - private - - def find_available_transports() - FreightageFinder.new(transports, order).find() - end -end \ No newline at end of file diff --git a/app/controllers/products_controller.rb b/app/controllers/products_controller.rb index 039a826..2992067 100644 --- a/app/controllers/products_controller.rb +++ b/app/controllers/products_controller.rb @@ -1,61 +1,25 @@ -class ProductsController < ApplicationController - before_action :set_product, only: %i[ show edit update destroy ] - - # GET /products - def index - @products = Product.all - @product = Product.new - @product_category = ProductCategory.new - @product_categories = ProductCategory.all - end - - # GET /products/1 - def show - end - - # GET /products/new - def new - @product = Product.new - end - - # GET /products/1/edit - def edit - end - - # POST /products - def create - @product = Product.new(product_params) - - if @product.save - redirect_to @product, notice: "Product was successfully created." - else - render :new, status: :unprocessable_entity - end - end - - # PATCH/PUT /products/1 - def update - if @product.update(product_params) - redirect_to @product, notice: "Product was successfully updated." - else - render :edit, status: :unprocessable_entity - end - end - - # DELETE /products/1 - def destroy - @product.destroy - redirect_to products_url, notice: "Product was successfully destroyed." - end - - private - # Use callbacks to share common setup or constraints between actions. - def set_product - @product = Product.find(params[:id]) - end - - # Only allow a list of trusted parameters through. - def product_params - params.require(:product).permit(:name, :price, :product_category_id) - end -end +class ProductsController < ApplicationController + def index + @products = Product.all + end + + def new + @product = Product.new + @product_categories = ProductCategory.all + end + + def create + product_params = params.require(:product).permit(:name, :price, :product_category_id) + @product = Product.new(product_params) + + if @product.save + redirect_to root_url, notice: 'Produto cadastrado com sucesso' + + else + @product_categories = ProductCategory.all + + flash.now[:notice] = 'Produto não cadastrado' + render 'new' + end + end +end \ No newline at end of file diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb deleted file mode 100644 index 73ff2dc..0000000 --- a/app/controllers/welcome_controller.rb +++ /dev/null @@ -1,9 +0,0 @@ -class WelcomeController < ApplicationController - - - def index - - end - - -end \ No newline at end of file diff --git a/app/models/product.rb b/app/models/product.rb index a6e4544..fa1e543 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -1,5 +1,7 @@ class Product < ApplicationRecord belongs_to :product_category, optional: true + + validates :name, :price, presence: true end diff --git a/app/views/product_categories/_product_category.html.erb b/app/views/product_categories/_product_category.html.erb deleted file mode 100644 index e216369..0000000 --- a/app/views/product_categories/_product_category.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= product_category.name %> \ No newline at end of file diff --git a/app/views/products/_form.html.erb b/app/views/products/_form.html.erb deleted file mode 100644 index a2a1d8e..0000000 --- a/app/views/products/_form.html.erb +++ /dev/null @@ -1,27 +0,0 @@ -<%= form_with(model: product) do |form| %> - <% if product.errors.any? %> -
-

<%= pluralize(product.errors.count, "error") %> prohibited this product from being saved:

- - -
- <% end %> - -
- <%= form.label :name, style: "display: block" %> - <%= form.text_field :name %> -
- -
- <%= form.label :price, style: "display: block" %> - <%= form.text_field :price %> -
- -
- <%= form.submit %> -
-<% end %> diff --git a/app/views/products/_product.html.erb b/app/views/products/_product.html.erb deleted file mode 100644 index 19ca353..0000000 --- a/app/views/products/_product.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -
-

- Name: - <%= product.name %> -

- -

- Price: - <%= product.price %> -

- -
diff --git a/app/views/products/edit.html.erb b/app/views/products/edit.html.erb deleted file mode 100644 index 90cb860..0000000 --- a/app/views/products/edit.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -

Editing product

- -<%= render "form", product: @product %> - -
- -
- <%= link_to "Show this product", @product %> | - <%= link_to "Back to products", products_path %> -
diff --git a/app/views/products/index.html.erb b/app/views/products/index.html.erb index a84a004..fc14106 100644 --- a/app/views/products/index.html.erb +++ b/app/views/products/index.html.erb @@ -1,50 +1,13 @@ -

<%= notice %>

- -

Products

-
- <% @products.each do |product| %> - <%= render product %> -

- <%= link_to "Show this product", product %> -

- <% end %> -
-
-

Nova Categoria de Produto

-<%= form_with(model: @product_category) do |f| %> - <%= f.label :name %> - <%= f.text_field :name %> - <%= f.submit %> -<% end %> -
- - - -

Novo Produto

-<%= form_with(model: @product) do |form| %> -
- <%= form.label :name, style: "display: block" %> - <%= form.text_field :name %> -
- -
- <%= form.label :price, style: "display: block" %> - <%= form.text_field :price %> -
- -
- <%= form.label :condition_new, 'Produto Novo' %> - <%= form.radio_button :condition, :new %> - - <%= form.label :condition_used, 'Produto Usado' %> - <%= form.radio_button :condition, :used %> -
- -
- <%= form.submit %> -
-<% end %> - - -choose 'Produto Usado' - +

Fretes

+ +<%= link_to 'Cadastrar Produto', new_product_path %> + +<% @products.each do |product| %> +
+

<%= product.name %>

+
Preço:
+
<%= number_to_currency(product.price) %>
+
Categoria:
+
<%= product.product_category.name %>
+
+<% end%> \ No newline at end of file diff --git a/app/views/products/new.html.erb b/app/views/products/new.html.erb index d438e41..b20415e 100644 --- a/app/views/products/new.html.erb +++ b/app/views/products/new.html.erb @@ -1,9 +1,22 @@ -

New product

- -<%= render "form", product: @product %> - -
- -
- <%= link_to "Back to products", products_path %> -
+<% if @product.errors.any? %> +
+ +
+<% end %> + +<%= form_with(model: @product) do |f| %> + <%= f.label :name, 'Nome' %> + <%= f.text_field :name %> + + <%= f.label :price, 'Preço' %> + <%= f.number_field :price, step: 0.01 %> + + <%= f.label :product_category_id, 'Categoria' %> + <%= f.collection_select :product_category_id, @product_categories, :id, :name %> + + <%= f.submit 'Criar' %> +<% end %> \ No newline at end of file diff --git a/app/views/products/show.html.erb b/app/views/products/show.html.erb deleted file mode 100644 index 7e30dc8..0000000 --- a/app/views/products/show.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -

<%= notice %>

- -<%= render @product %> - -<%= render @product.product_category %> - -
- <%= link_to "Edit this product", edit_product_path(@product) %> | - <%= link_to "Back to products", products_path %> - - <%= button_to "Destroy this product", @product, method: :delete %> -
diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb deleted file mode 100644 index 65777a5..0000000 --- a/app/views/welcome/index.html.erb +++ /dev/null @@ -1,42 +0,0 @@ -

<%= translate('.title') %>

- -
-
- <%= image_tag 'delivery.png', class: 'img-fluid' %> -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#FirstLastHandle
1MarkOtto@mdo
2JacobThornton@fat
3Larry the Bird@twitter
-
-
- - -<%= link_to 'Início', root_path, class: 'btn btn-primary btn-lg' %> diff --git a/config/initializers/locale.rb b/config/initializers/locale.rb new file mode 100644 index 0000000..3c19019 --- /dev/null +++ b/config/initializers/locale.rb @@ -0,0 +1,5 @@ +# Permitted locales available for the application +I18n.available_locales = [:en, :'pt-BR'] + +# Set default locale to something other than :en +I18n.default_locale = :'pt-BR' \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml deleted file mode 100644 index 8ca56fc..0000000 --- a/config/locales/en.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Files in the config/locales directory are used for internationalization -# and are automatically loaded by Rails. If you want to use locales other -# than English, add the necessary files in this directory. -# -# To use the locales, use `I18n.t`: -# -# I18n.t "hello" -# -# In views, this is aliased to just `t`: -# -# <%= t("hello") %> -# -# To use a different locale, set it with `I18n.locale`: -# -# I18n.locale = :es -# -# This would use the information in config/locales/es.yml. -# -# The following keys must be escaped otherwise they will not be retrieved by -# the default I18n backend: -# -# true, false, on, off, yes, no -# -# Instead, surround them with single quotes. -# -# en: -# "true": "foo" -# -# To learn more, please read the Rails Internationalization guide -# available at https://guides.rubyonrails.org/i18n.html. - -en: - hello: "Hello world" diff --git a/config/locales/products-pt-BR.yml b/config/locales/products-pt-BR.yml new file mode 100644 index 0000000..efd4781 --- /dev/null +++ b/config/locales/products-pt-BR.yml @@ -0,0 +1,12 @@ +pt-BR: + activerecord: + models: + product: + one: "Produto" + other: "Produtos" + attributes: + product: + name: "Nome" + price: "Preço" + product_category: "Categoria" + product_category_id: "Categoria" \ No newline at end of file diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml deleted file mode 100644 index 68c10cf..0000000 --- a/config/locales/pt-BR.yml +++ /dev/null @@ -1,14 +0,0 @@ -en: - transport_mode: - error: - not_available: 'Não existe modalidade disponível' - - welcome: - index: - title: 'Sistema de Frete e Transporatdoras' - outro: - outro: - outro: - - -I18n.translate('transport_mode.error.not_available') \ No newline at end of file diff --git a/config/locales/rails-pt-BR.yml b/config/locales/rails-pt-BR.yml new file mode 100644 index 0000000..7abc6d3 --- /dev/null +++ b/config/locales/rails-pt-BR.yml @@ -0,0 +1,222 @@ +pt-BR: + activerecord: + errors: + messages: + record_invalid: 'A validação falhou: %{errors}' + restrict_dependent_destroy: + has_one: Não é possível excluir o registro pois existe um %{record} dependente + has_many: Não é possível excluir o registro pois existem %{record} dependentes + date: + abbr_day_names: + - dom + - seg + - ter + - qua + - qui + - sex + - sáb + abbr_month_names: + - + - jan + - fev + - mar + - abr + - mai + - jun + - jul + - ago + - set + - out + - nov + - dez + day_names: + - domingo + - segunda-feira + - terça-feira + - quarta-feira + - quinta-feira + - sexta-feira + - sábado + formats: + default: "%d/%m/%Y" + long: "%d de %B de %Y" + short: "%d de %B" + month_names: + - + - janeiro + - fevereiro + - março + - abril + - maio + - junho + - julho + - agosto + - setembro + - outubro + - novembro + - dezembro + order: + - :day + - :month + - :year + datetime: + distance_in_words: + about_x_hours: + one: aproximadamente 1 hora + other: aproximadamente %{count} horas + about_x_months: + one: aproximadamente 1 mês + other: aproximadamente %{count} meses + about_x_years: + one: aproximadamente 1 ano + other: aproximadamente %{count} anos + almost_x_years: + one: quase 1 ano + other: quase %{count} anos + half_a_minute: meio minuto + less_than_x_seconds: + one: menos de 1 segundo + other: menos de %{count} segundos + less_than_x_minutes: + one: menos de um minuto + other: menos de %{count} minutos + over_x_years: + one: mais de 1 ano + other: mais de %{count} anos + x_seconds: + one: 1 segundo + other: "%{count} segundos" + x_minutes: + one: 1 minuto + other: "%{count} minutos" + x_days: + one: 1 dia + other: "%{count} dias" + x_months: + one: 1 mês + other: "%{count} meses" + x_years: + one: 1 ano + other: "%{count} anos" + prompts: + second: Segundo + minute: Minuto + hour: Hora + day: Dia + month: Mês + year: Ano + errors: + format: "%{attribute} %{message}" + messages: + accepted: deve ser aceito + blank: não pode ficar em branco + confirmation: não é igual a %{attribute} + empty: não pode ficar vazio + equal_to: deve ser igual a %{count} + even: deve ser par + exclusion: não está disponível + greater_than: deve ser maior que %{count} + greater_than_or_equal_to: deve ser maior ou igual a %{count} + inclusion: não está incluído na lista + invalid: não é válido + less_than: deve ser menor que %{count} + less_than_or_equal_to: deve ser menor ou igual a %{count} + model_invalid: 'A validação falhou: %{errors}' + not_a_number: não é um número + not_an_integer: não é um número inteiro + odd: deve ser ímpar + other_than: deve ser diferente de %{count} + present: deve ficar em branco + required: é obrigatório(a) + taken: já está em uso + too_long: + one: 'é muito longo (máximo: 1 caracter)' + other: 'é muito longo (máximo: %{count} caracteres)' + too_short: + one: 'é muito curto (mínimo: 1 caracter)' + other: 'é muito curto (mínimo: %{count} caracteres)' + wrong_length: + one: não possui o tamanho esperado (1 caracter) + other: não possui o tamanho esperado (%{count} caracteres) + template: + body: 'Por favor, verifique o(s) seguinte(s) campo(s):' + header: + one: 'Não foi possível gravar %{model}: 1 erro' + other: 'Não foi possível gravar %{model}: %{count} erros' + helpers: + select: + prompt: Por favor selecione + submit: + create: Criar %{model} + submit: Salvar %{model} + update: Atualizar %{model} + number: + currency: + format: + delimiter: "." + format: "%u %n" + precision: 2 + separator: "," + significant: false + strip_insignificant_zeros: false + unit: R$ + format: + delimiter: "." + precision: 3 + separator: "," + significant: false + strip_insignificant_zeros: false + human: + decimal_units: + format: "%n %u" + units: + billion: + one: bilhão + other: bilhões + million: + one: milhão + other: milhões + quadrillion: + one: quatrilhão + other: quatrilhões + thousand: mil + trillion: + one: trilhão + other: trilhões + unit: '' + format: + delimiter: '' + precision: 3 + significant: true + strip_insignificant_zeros: true + storage_units: + format: "%n %u" + units: + byte: + one: Byte + other: Bytes + eb: EB + gb: GB + kb: KB + mb: MB + pb: PB + tb: TB + percentage: + format: + delimiter: "." + format: "%n%" + precision: + format: + delimiter: "." + support: + array: + last_word_connector: " e " + two_words_connector: " e " + words_connector: ", " + time: + am: '' + formats: + default: "%a, %d de %B de %Y, %H:%M:%S %z" + long: "%d de %B de %Y, %H:%M" + short: "%d de %B, %H:%M" + pm: '' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index e23c4d5..a173c08 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,8 +1,7 @@ Rails.application.routes.draw do - resources :products - resources :product_categories, only: [:create, :show] do - resources :products, only: [:create] - end devise_for :users - root 'welcome#index' + + root to: 'products#index' + + resources :products, only: [:new, :create, :index] end diff --git a/db/seeds.rb b/db/seeds.rb index fbaf120..555c37c 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -4,15 +4,4 @@ # Examples: # # movies = Movie.create([{ name: "Star Wars" }, { name: "Lord of the Rings" }]) -# Character.create(name: "Luke", movie: movies.first) - -User.create(email: user@email.com, password: ) -Company.create(name: , cnpj: ) -Product.create(name: , price: , company: ) - - - - - - -User.create(email: user@email.com, password: ) \ No newline at end of file +# Character.create(name: "Luke", movie: movies.first) \ No newline at end of file diff --git a/spec/system/user_register_product_spec.rb b/spec/system/user_register_product_spec.rb new file mode 100644 index 0000000..5c84cfb --- /dev/null +++ b/spec/system/user_register_product_spec.rb @@ -0,0 +1,42 @@ +require 'rails_helper' + +describe 'Usuário cadastra produto' do + it 'com sucesso' do + #Arrange + ProductCategory.create!(name: "Categoria A") + ProductCategory.create!(name: "Categoria B") + + #Act + visit root_path + click_on "Cadastrar Produto" + fill_in "Nome", with: "Produto A" + fill_in "Preço", with: 15.00 + select "Categoria B", from: "Categoria" + click_on "Criar" + + #Assert + expect(page).to have_content "Fretes" + expect(page).to have_content "Produto cadastrado com sucesso" + expect(page).to have_content "Produto A" + expect(page).to have_content "Preço: R$ 15,00" + expect(page).to have_content "Categoria: Categoria B" + end + + it 'e não preenche todos os campos' do + #Arrange + ProductCategory.create!(name: "Categoria A") + ProductCategory.create!(name: "Categoria B") + + #Act + visit root_path + click_on "Cadastrar Produto" + fill_in "Nome", with: "" + fill_in "Preço", with: "" + click_on "Criar" + + #Assert + expect(page).to have_content "Produto não cadastrado" + expect(page).to have_content "Nome não pode ficar em branco" + expect(page).to have_content "Preço não pode ficar em branco" + end +end