# Solidus Brazilian Adaptations [![CircleCI](https://circleci.com/gh/solidusio-contrib/solidus_brazilian_adaptations.svg?style=shield)](https://circleci.com/gh/solidusio-contrib/solidus_brazilian_adaptations) [![codecov](https://codecov.io/gh/solidusio-contrib/solidus_brazilian_adaptations/branch/master/graph/badge.svg)](https://codecov.io/gh/solidusio-contrib/solidus_brazilian_adaptations) Essa gem tem como objetivo adaptar os modelos do Solidus para se adequar aos padrões brasileiros, tais como a criação dos atributos CPF/CNPJ (tax_id) em Spree::Order, e número (number) do imóvel e bairro (district) em Spree::Address. ## Installation Add solidus_brazilian_adaptations to your Gemfile: ```ruby gem 'solidus_brazilian_adaptations' ``` Bundle your dependencies and run the installation generator: ```shell bin/rails generate solidus_brazilian_adaptations:install ``` ## Usage ### Tradução e moeda padrão Editar `config/initializers/spree.rb` adicionando as seguintes configurações: Mudar moeda e país padrão: ```ruby Spree.config do |config| # ... # Define BRL como moeda padrão config.currency = "BRL" # Preenche automaticamente o campo de pais que vamos remover do formulário de endereço: config.default_country_iso = "BR" # ... end ``` Mudar idioma da interface do admin: ```ruby Spree::Backend::Config.configure do |config| # ... config.locale = 'pt-BR' # ... end ``` Incluir no `config/application.rb` para definir os locales disponiveis: ```ruby module SuaLoja class Application < Rails::Application # ... config.i18n.available_locales = ['pt-BR'] config.i18n.default_locale = 'pt-BR' # ... end end ``` ### Seeds Substituir `Spree::Core::Engine.load_seed` por `SolidusBrazilianAdaptations::Engine.load_seed` em `db/seeds.rb` para utilizar o seeds da gem. ### Configurações A partir do initializer da gem é possivel configurar se será permitido efetuar compras utilizando CNPJ. Por padrão é essa opção é `true`. ### Storefront Essa gem utiliza o starter frontend como base, então os exemplos serão feitos a partir de suas views. Para adicionar os campos de CPF/CNPJ, número e bairro é possivel editar o form da etapa de endereço. Porém a edição é feita em duas partials diferentes: Na partial `app/views/checkouts/_checkout_step.html.erb` o seguinte HTML referente ao **CPF/CNPJ** pode ser inserido logo abaixo ao input de e-mail: ```erb <%= form_for order, url: update_checkout_path(order.state), html: { id: "checkout_form_#{order.state}" } do |form| %> <% if order.state == "address" || !order.email? %>
<%= form.label :email, 'E-Mail:' %> <%= form.email_field :email, required: true, placeholder: 'name@example.com' %>
<% label = SolidusBrazilianAdaptations.config.allow_cnpj ? "CPF/CPNJ" : "CPF" %>
<%= form.label :tax_id, "#{label}:" %> <%= form.text_field :tax_id, required: true, placeholder: label %>
<% end %> <%= render "checkouts/steps/#{order.state}_step", form: form, differentiator: @differentiator %> <% end %> ``` E na partial `app/views/checkouts/steps/address_step/_address_inputs.html.erb` adicionar o seguinte código referente ao **número** e **bairro**, podendo ser alterada a ordem dos campos: ```erb
<%= form.label :number, "Número:" %> <%= form.text_field :number, required: true %>
<%= form.label :address2, "#{I18n.t("spree.street_address_2")}:" %> <%= form.text_field :address2, autocomplete: "#{address_type} address-line2" %>
<%= form.label :district, "Bairro:" %> <%= form.text_field :district, required: true %>
<%= form.label :city, "#{I18n.t("spree.city")}:" %> <%= form.text_field :city, required: true, autocomplete: "#{address_type} address-level2" %>
``` ### Admin Para visualizar os campos de **CPF/CNPJ**, **número** e **bairro** no painel do Admin na aba `Order/Order_Number/Customer Details` é necessário criar as seguintes views em seu projeto: Essas novas views irão sobrescrever as padrões, localizadas na gem `solidus_backend`. Portanto, você deve ficar atento às atualizações do Solidus, pois ao sobrescrever as views as atualizações não serão aplicadas. `app/views/spree/admin/orders/customer_details/_form.html.erb` ```erb
<%= t('spree.account') %>
<%= f.label :email %> <%= f.email_field :email, required: true, class: 'fullwidth' %>
<%= f.label :tax_id, "CPF/CNPJ" %> <%= f.text_field :tax_id, required: true, class: 'fullwidth' %>
<%= label_tag nil, t('spree.guest_checkout') %>
    <% if @order.completed? %>
  • <%= @order.user.nil? ? t('spree.say_yes') : t('spree.say_no') %>
  • <% else %> <% guest = @order.user.nil? %>
  • <%= hidden_field_tag :user_id, @order.user_id %> <% end %>
<% if Spree::Config[:order_bill_address_used] %>
<%= t('spree.billing_address') %>
<%= f.fields_for :bill_address do |ba_form| %> <%= render partial: 'spree/admin/shared/address_form', locals: { f: ba_form, type: "billing" } %> <% end %>
<% end %>
<%= t('spree.shipping_address') %> <% if Spree::Config[:order_bill_address_used] %>
<% end %>
<%= f.fields_for :ship_address do |ba_form| %> <%= render partial: 'spree/admin/shared/address_form', locals: { f: ba_form, type: "shipping" } %> <% end %>
<%= button_tag t('spree.actions.update'), class: 'btn btn-primary' %>
``` `app/views/spree/admin/shared/_address_form.html.erb` ```erb <% s_or_b = type.chars.first %>
"> <%= f.label :name %> <%= f.text_field :name, class: 'fullwidth' %>
<% if Spree::Config[:company] %>
"> <%= f.label :company %> <%= f.text_field :company, class: 'fullwidth' %>
<% end %>
"> <%= f.label :address1 %> <%= f.text_field :address1, class: 'fullwidth' %>
"> <%= f.label :number, "Número" %> <%= f.text_field :number, class: 'fullwidth' %>
"> <%= f.label :address2 %> <%= f.text_field :address2, class: 'fullwidth' %>
"> <%= f.label :district, "Bairro" %> <%= f.text_field :district, class: 'fullwidth' %>
"> <%= f.label :city %> <%= f.text_field :city, class: 'fullwidth' %>
"> <%= f.label :zipcode %> <%= f.text_field :zipcode, class: 'fullwidth' %>
"> <%= f.label :country_id, Spree::Country.model_name.human %> <%= f.collection_select :country_id, available_countries, :id, :name, {}, {class: 'custom-select fullwidth js-country_id'} %>
"> <%= f.label :state_id, Spree::State.model_name.human %> <%= f.hidden_field :state_name, value: nil %> <% states = f.object.country.try(:states).nil? ? [] : f.object.country.states %> <%= f.text_field :state_name, style: "display: #{states.empty? ? 'block' : 'none' };", disabled: !states.empty?, class: 'fullwidth state_name js-state_name' %> <%= f.hidden_field :state_id, value: nil %> <%= f.collection_select :state_id, states.sort, :id, :name, { include_blank: true }, { class: 'custom-select fullwidth js-state_id', style: "display: #{states.empty? ? 'none' : 'block' };", disabled: states.empty? } %>
"> <%= f.label :phone %> <%= f.phone_field :phone, class: 'fullwidth' %>
``` ## Development ### Testing the extension First bundle your dependencies, then run `bin/rake`. `bin/rake` will default to building the dummy app if it does not exist, then it will run specs. The dummy app can be regenerated by using `bin/rake extension:test_app`. ```shell bin/rake ``` To run [Rubocop](https://github.com/bbatsov/rubocop) static code analysis run ```shell bundle exec rubocop ``` When testing your application's integration with this extension you may use its factories. You can load Solidus core factories along with this extension's factories using this statement: ```ruby SolidusDevSupport::TestingSupport::Factories.load_for(SolidusBrazilianAdaptations::Engine) ``` ### Running the sandbox To run this extension in a sandboxed Solidus application, you can run `bin/sandbox`. The path for the sandbox app is `./sandbox` and `bin/rails` will forward any Rails commands to `sandbox/bin/rails`. Here's an example: ``` $ bin/rails server => Booting Puma => Rails 6.0.2.1 application starting in development * Listening on tcp://127.0.0.1:3000 Use Ctrl-C to stop ``` ### Releasing new versions Please refer to the [dedicated page](https://github.com/solidusio/solidus/wiki/How-to-release-extensions) in the Solidus wiki. ## License Copyright (c) 2023 ulysses-bull, released under the New BSD License.