From a8708feb19220a2355ea5f864354cc728ed694bc Mon Sep 17 00:00:00 2001 From: AndriyAndriyovuch Date: Tue, 25 Jul 2023 18:32:36 +0300 Subject: [PATCH 01/63] initial commit --- app/models/category.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/models/category.rb b/app/models/category.rb index 52e40d328..63b49aabd 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -11,8 +11,6 @@ # updated_at :datetime not null # class Category < ApplicationRecord - has_one :price, dependent: :destroy - has_many :category_categoryables, dependent: :restrict_with_exception has_many :categoryables, through: :category_categoryables From 18486f8ff765fa6111d173429b4382e15bfcead8 Mon Sep 17 00:00:00 2001 From: AndriyAndriyovuch Date: Fri, 28 Jul 2023 19:42:09 +0300 Subject: [PATCH 02/63] commit before merge to update from in calculator --- app/controllers/account/calculators_controller.rb | 8 ++++++++ app/models/calculator.rb | 2 ++ app/models/product.rb | 2 ++ app/views/account/calculators/new.html.slim | 3 +++ .../20230728151759_add_product_id_to_calculators.rb | 6 ++++++ db/schema.rb | 4 +++- 6 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20230728151759_add_product_id_to_calculators.rb diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 6d63ff39e..600f84540 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -8,6 +8,10 @@ def show # TODO: fill it end + def new + products_collection + end + def edit collect_fields_for_form end @@ -73,4 +77,8 @@ def updater @calculator.update(calculator_params) end end + + def products_collection + @products = Product.where(calculator: nil) + end end diff --git a/app/models/calculator.rb b/app/models/calculator.rb index 1be929b08..3575bec9e 100644 --- a/app/models/calculator.rb +++ b/app/models/calculator.rb @@ -27,6 +27,8 @@ class Calculator < ApplicationRecord has_many :fields, dependent: :destroy + has_one :product + accepts_nested_attributes_for :fields, allow_destroy: true validates :name, length: { minimum: 2 }, diff --git a/app/models/product.rb b/app/models/product.rb index d57704abc..e7e871fac 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -19,6 +19,8 @@ class Product < ApplicationRecord DIAPER = "diaper" + belongs_to :calculator, required: false + has_many :prices, as: :priceable, dependent: :destroy has_many :categories_by_prices, through: :prices, source: :category diff --git a/app/views/account/calculators/new.html.slim b/app/views/account/calculators/new.html.slim index fefbdd3fd..070ee6d66 100644 --- a/app/views/account/calculators/new.html.slim +++ b/app/views/account/calculators/new.html.slim @@ -13,7 +13,10 @@ .col-1.font-weight-bold= f.label :name .col-1= f.text_field :name .col-2.d-flex.justify-content-end + = f.association :company, as: :radio_buttons, collection: @products = f.submit "", value: t('.create_calculator_button'), class: 'btn btn-success mr-2' = link_to account_calculators_path, class: 'btn btn-danger' do span.mr-1 =t('buttons.cancel') i.fa.fa-times-circle + - @products.each do |product| + = product.title \ No newline at end of file diff --git a/db/migrate/20230728151759_add_product_id_to_calculators.rb b/db/migrate/20230728151759_add_product_id_to_calculators.rb new file mode 100644 index 000000000..ea35b08dd --- /dev/null +++ b/db/migrate/20230728151759_add_product_id_to_calculators.rb @@ -0,0 +1,6 @@ +class AddProductIdToCalculators < ActiveRecord::Migration[6.1] + def change + add_column :calculators, :product_id, :integer + add_column :products, :calculator_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 39650f9e0..9d1f8ea5d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_07_10_212500) do +ActiveRecord::Schema.define(version: 2023_07_28_151759) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -57,6 +57,7 @@ t.datetime "updated_at", precision: 6, null: false t.string "slug" t.boolean "preferable", default: false + t.integer "product_id" t.index ["name"], name: "index_calculators_on_name", unique: true t.index ["slug"], name: "index_calculators_on_slug", unique: true t.index ["uuid"], name: "index_calculators_on_uuid", unique: true @@ -158,6 +159,7 @@ t.bigint "product_type_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.integer "calculator_id" t.index ["product_type_id"], name: "index_products_on_product_type_id" t.index ["uuid"], name: "index_products_on_uuid", unique: true end From aa79011b195ffee6a74d752e7ff606c0a12c8062 Mon Sep 17 00:00:00 2001 From: AndriyAndriyovuch Date: Fri, 28 Jul 2023 21:00:26 +0300 Subject: [PATCH 03/63] add ability to add product to calculator --- app/controllers/account/calculators_controller.rb | 4 ++-- app/views/account/calculators/new.html.slim | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 600f84540..234b8d4ab 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -63,7 +63,7 @@ def collect_fields_for_kind(kind) def calculator_params params.require(:calculator).permit( - :name, :id, :slug, :preferable, + :name, :id, :slug, :preferable, :product_id, fields_attributes: [ :id, :selector, :label, :name, :value, :unit, :from, :to, :type, :kind, :_destroy @@ -79,6 +79,6 @@ def updater end def products_collection - @products = Product.where(calculator: nil) + @products = Product.where(calculator_id: nil) end end diff --git a/app/views/account/calculators/new.html.slim b/app/views/account/calculators/new.html.slim index c718d5c0a..ec1462aa9 100644 --- a/app/views/account/calculators/new.html.slim +++ b/app/views/account/calculators/new.html.slim @@ -11,6 +11,7 @@ .form-group.row .col-12.has-float-label.my-auto = f.input :name, class: 'form-control' + = f.input :product_id, as: :radio_buttons, collection: @products .div.d-flex = f.button :submit, t('.create_calculator_button'), class: 'btn btn-success mr-2 height-auto w-auto' = link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do From cf4c35493142ee24e30b914eca6781198ab014ad Mon Sep 17 00:00:00 2001 From: AndriyAndriyovuch Date: Fri, 28 Jul 2023 22:51:53 +0300 Subject: [PATCH 04/63] add draft show page for universal calculator --- .../account/calculators_controller.rb | 10 ++- app/helpers/calculators_helper.rb | 4 + app/views/account/calculators/new.html.slim | 2 +- app/views/account/calculators/show.html.erb | 84 +++++++++++++++++++ app/views/calculators/show.html.slim | 42 ---------- 5 files changed, 97 insertions(+), 45 deletions(-) create mode 100644 app/views/account/calculators/show.html.erb delete mode 100644 app/views/calculators/show.html.slim diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 234b8d4ab..a61d06b3e 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true class Account::CalculatorsController < Account::BaseController - before_action :calculator, only: [:edit, :update, :destroy] + before_action :calculator, only: [:show, :edit, :update, :destroy] load_and_authorize_resource def show - # TODO: fill it + @prices = product_prices(@calculator.product) + puts @calculator end def new @@ -20,6 +21,7 @@ def create @calculator = Calculator.new(calculator_params) if @calculator.save + Product.find(calculator_params[:product_id]).update(calculator_id: @calculator.id) redirect_to account_calculators_path, notice: t("notifications.calculator_created") else render action: "new" @@ -81,4 +83,8 @@ def updater def products_collection @products = Product.where(calculator_id: nil) end + + def product_prices(product) + product.categories_by_prices + end end diff --git a/app/helpers/calculators_helper.rb b/app/helpers/calculators_helper.rb index faa771f54..a33703a53 100644 --- a/app/helpers/calculators_helper.rb +++ b/app/helpers/calculators_helper.rb @@ -21,4 +21,8 @@ def month_number(style) when "new" then (0..11).to_a end end + + def use_period + ["day", "week", "month", "year"] + end end diff --git a/app/views/account/calculators/new.html.slim b/app/views/account/calculators/new.html.slim index ec1462aa9..2b0667713 100644 --- a/app/views/account/calculators/new.html.slim +++ b/app/views/account/calculators/new.html.slim @@ -11,7 +11,7 @@ .form-group.row .col-12.has-float-label.my-auto = f.input :name, class: 'form-control' - = f.input :product_id, as: :radio_buttons, collection: @products + = f.input :product_id, collection: @products .div.d-flex = f.button :submit, t('.create_calculator_button'), class: 'btn btn-success mr-2 height-auto w-auto' = link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb new file mode 100644 index 000000000..e1b5402b2 --- /dev/null +++ b/app/views/account/calculators/show.html.erb @@ -0,0 +1,84 @@ +
+ +

<%= t 'calculators.buttons.to_main' %>

+ <%= image_tag "arrow-left.svg", class: "z-1" %> +
+
+ <%= simple_form_for(:child, url: "#", html: { class: "simple_form_calculator", + data: { controller: "input-child-info", + input_child_info_url_value: api_v1_diaper_calculators_url, + input_child_info_months_value: month_number("new"), + input_child_info_results_outlet: '.result' }}) do |form| %> +
+ +
+ <%= t('.form.description') %> +
+ +
+ <%= form.input_field :years, + data: { input_child_info_target: 'year', action: 'input-child-info#yearChanged' } %> +
+ +
+ <%= form.input_field :months, + collection: use_period, + prompt: '__', + data: { input_child_info_target: 'month' } %> +
+ +
+ <%= t('.form.price') %> +
+ + <%= form.input_field :product_category, collection: @prices, + selected: t('.form.medium'), + label: t('.form_price'), + class: 'form_fild price_select rounded w-100', + data: { input_child_info_target: 'productCategory' } %> + + <%= form.submit t('calculators.buttons.calculate'), + class: 'calculate-btn result-btn', + data: { action: 'input-child-info#submit' } %> +
+ <% end %> + <%= image_tag "scales.png", class: "scales_img" %> +
+
+ +
+
+
+ <% [{ image: "money_spent_2.png", data_target: "moneySpent", unit: t(".unit"), text: t(".money_spent") }, + "arrow", + { image: "money_to_spent_2.png", data_target: "moneyWillBeSpent", unit: t(".unit"), text: t(".money_will_be_spent") }].each do |item| %> + <% if item == "arrow" %> +
+ <%= image_tag "vector_5.png", class: "vector" %> + <%= image_tag "vector_2.png", class: "vector-mobile" %> +
+ <% else %> +
+ <%= image_tag item[:image], class: "img-margin" %> +

000

+

<%= item[:unit] %>

+

<%= item[:text] %>

+
+ <% end %> + <% end %> +
+
+
+ +
+
+
+ <%= render 'layouts/description_block' %> +
+
+ +
+
+
diff --git a/app/views/calculators/show.html.slim b/app/views/calculators/show.html.slim deleted file mode 100644 index dad5b5c39..000000000 --- a/app/views/calculators/show.html.slim +++ /dev/null @@ -1,42 +0,0 @@ -link href="https://fonts.googleapis.com" rel="preconnect" / -link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect" / -link href="https://fonts.googleapis.com/css2?family=Comfortaa&family=Nunito&display=swap" rel="stylesheet" / -h1.display-4.text-center.mt-5.mb-5 - = t '.welcome_header' -.container.home - .jumbotron - .container - .row.main-container - .rounded.float-left - = image_tag "search.png", height: 70 - .form-container - h3.container.ml-2= t 'calculators.calculator.form_description' - form#form.container.mt-3 action="" - .container.input-group.d-flex.justify-content-between - label.text-center for="" - input#birth.col.datepick placeholder=("#{t 'calculators.calculator.form.childs_birthday_label'}") type="text" / - / .container.ml-3.mt-4.form-check - / input#flexCheckChecked.form-check-input checked="checked" type="checkbox" value="" / - / label.form-check-label for="flexCheckChecked" - / = t 'calculators.calculator.want_recomentation_label' - button.btn.btn-success.ml-3.mt-4 type="submit" - = image_tag "calculator.png", height: 25 - = t 'calculators.calculator.calculate_result_button' -.container.calculation-results - .row - .col-sm.result-card - = image_tag "diapers_bought.png", class:"rounded float-left", height: 70 - p data-type="bought_diapers" 0 - = t 'calculators.calculator.bought_diapers' - .col-sm.result-card - = image_tag "money.png", class:"rounded float-left", height: 70 - p data-type="money_spent" 0 - = t 'calculators.calculator.money_spent' - .col-sm.result-card - = image_tag "naphtha.png", class:"rounded float-left", height: 70 - p data-type="mililiters_of_naphtha" 0 - = t 'calculators.calculator.mililiters_of_naphtha' - .col-sm.last-result-card - = image_tag "plastic.png", class:"rounded float-left", height: 70 - p data-type="garbage_created" 0 - = t 'calculators.calculator.gram_of_plastic' From c9d5d8706b2e75c6adfd64f2152a21fd6c58236d Mon Sep 17 00:00:00 2001 From: AndriyAndriyovuch Date: Fri, 28 Jul 2023 23:04:21 +0300 Subject: [PATCH 05/63] add draft show page for universal calculator --- app/views/account/calculators/show.html.erb | 27 +++++++-------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index e1b5402b2..901bf2ca7 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -11,26 +11,17 @@ input_child_info_results_outlet: '.result' }}) do |form| %>
-
- <%= t('.form.description') %> -
+ Items + <%= form.input_field :items, + data: { input_child_info_target: 'year', action: 'input-child-info#yearChanged' } %> -
- <%= form.input_field :years, - data: { input_child_info_target: 'year', action: 'input-child-info#yearChanged' } %> -
- -
- <%= form.input_field :months, - collection: use_period, - prompt: '__', - data: { input_child_info_target: 'month' } %> -
- -
- <%= t('.form.price') %> -
+ Period + <%= form.input_field :period, + collection: use_period, + prompt: '__', + data: { input_child_info_target: 'month' } %> + Price <%= form.input_field :product_category, collection: @prices, selected: t('.form.medium'), label: t('.form_price'), From 7cfca42d2f79ceefd4e7dafedcacb358b593b9ad Mon Sep 17 00:00:00 2001 From: AndriyAndriyovuch Date: Sat, 29 Jul 2023 17:25:29 +0300 Subject: [PATCH 06/63] add default usage to product --- .../account/products_controller.rb | 2 +- app/views/account/calculators/show.html.erb | 26 +++++-------------- app/views/account/products/edit.html.slim | 1 + app/views/account/products/index.html.slim | 2 ++ app/views/account/products/new.html.slim | 1 + ...07_add_default_usage_per_day_to_product.rb | 5 ++++ db/schema.rb | 3 ++- 7 files changed, 19 insertions(+), 21 deletions(-) create mode 100644 db/migrate/20230729140507_add_default_usage_per_day_to_product.rb diff --git a/app/controllers/account/products_controller.rb b/app/controllers/account/products_controller.rb index 07d9ba7a3..cad7c5c32 100644 --- a/app/controllers/account/products_controller.rb +++ b/app/controllers/account/products_controller.rb @@ -60,7 +60,7 @@ def collection end def product_params - params.require(:product).permit(:title, prices_attributes: [:id, + params.require(:product).permit(:title, :default_usage_per_day, prices_attributes: [:id, :sum, :category_id, :_destroy]) end end diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index 901bf2ca7..d2f79f085 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -10,10 +10,7 @@ input_child_info_months_value: month_number("new"), input_child_info_results_outlet: '.result' }}) do |form| %>
- - Items - <%= form.input_field :items, - data: { input_child_info_target: 'year', action: 'input-child-info#yearChanged' } %> + <%= "#{@calculator.product.title} calculator" %>
Period <%= form.input_field :period, @@ -33,7 +30,6 @@ data: { action: 'input-child-info#submit' } %>
<% end %> - <%= image_tag "scales.png", class: "scales_img" %>
@@ -41,21 +37,13 @@
<% [{ image: "money_spent_2.png", data_target: "moneySpent", unit: t(".unit"), text: t(".money_spent") }, - "arrow", { image: "money_to_spent_2.png", data_target: "moneyWillBeSpent", unit: t(".unit"), text: t(".money_will_be_spent") }].each do |item| %> - <% if item == "arrow" %> -
- <%= image_tag "vector_5.png", class: "vector" %> - <%= image_tag "vector_2.png", class: "vector-mobile" %> -
- <% else %> -
- <%= image_tag item[:image], class: "img-margin" %> -

000

-

<%= item[:unit] %>

-

<%= item[:text] %>

-
- <% end %> +
+ <%= image_tag item[:image], class: "img-margin" %> +

000

+

<%= item[:unit] %>

+

<%= item[:text] %>

+
<% end %>
diff --git a/app/views/account/products/edit.html.slim b/app/views/account/products/edit.html.slim index 2baf5056a..0e1591654 100644 --- a/app/views/account/products/edit.html.slim +++ b/app/views/account/products/edit.html.slim @@ -3,6 +3,7 @@ .form-group.row .col-12.has-float-label.my-auto = f.input :title, label: t('.title'), class: 'form-control col-sm-11' + = f.input :default_usage_per_day, label: 'Default usage per day', class: 'form-control col-sm-11' - if Category.ordered_by_name.exists? = f.simple_fields_for :prices do |prices_form| .checkbox-blocks diff --git a/app/views/account/products/index.html.slim b/app/views/account/products/index.html.slim index b4e0639dc..03f32c25c 100644 --- a/app/views/account/products/index.html.slim +++ b/app/views/account/products/index.html.slim @@ -9,6 +9,7 @@ tr th scope="col" # th scope="col" =t('.table.title') + th scope="col" ="Default usage" th scope="col" =t('.table.prices') th scope="col" =t('.table.actions') @@ -17,6 +18,7 @@ tr td = product.id td = product.title + td = product.default_usage_per_day td - product.prices.includes(:category).each do |price| span = "#{price.category.name}: #{price.sum}" diff --git a/app/views/account/products/new.html.slim b/app/views/account/products/new.html.slim index 17c912d23..c127efecf 100644 --- a/app/views/account/products/new.html.slim +++ b/app/views/account/products/new.html.slim @@ -3,6 +3,7 @@ .form-group.row .col-12.has-float-label.my-auto = f.input :title, label: t('.title'), class: 'form-control col-sm-11' + = f.input :default_usage_per_day, label: 'Default usage per day', class: 'form-control col-sm-11' - Category.ordered_by_name.each do |category| .checkbox-blocks = f.simple_fields_for :prices do |prices_form| diff --git a/db/migrate/20230729140507_add_default_usage_per_day_to_product.rb b/db/migrate/20230729140507_add_default_usage_per_day_to_product.rb new file mode 100644 index 000000000..d5978577c --- /dev/null +++ b/db/migrate/20230729140507_add_default_usage_per_day_to_product.rb @@ -0,0 +1,5 @@ +class AddDefaultUsagePerDayToProduct < ActiveRecord::Migration[6.1] + def change + add_column :products, :default_usage_per_day, :integer, null: false, default: 1 + end +end diff --git a/db/schema.rb b/db/schema.rb index 9d1f8ea5d..4348720ec 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_07_28_151759) do +ActiveRecord::Schema.define(version: 2023_07_29_140507) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -160,6 +160,7 @@ t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.integer "calculator_id" + t.integer "default_usage_per_day", default: 1, null: false t.index ["product_type_id"], name: "index_products_on_product_type_id" t.index ["uuid"], name: "index_products_on_uuid", unique: true end From 7e8bbf1d77b53a454bd609490a9c570c27ec7fe0 Mon Sep 17 00:00:00 2001 From: AndriyAndriyovuch Date: Sun, 30 Jul 2023 16:26:07 +0300 Subject: [PATCH 07/63] create draft calculator --- .../api/v1/calculators_controller.rb | 40 +++++++++++--- .../controllers/calculate_controller.js | 54 +++++++++++++++++++ .../calculationresults_controller.js | 18 +++++++ app/services/calculators/calculate_service.rb | 36 +++++++++++++ app/views/account/calculators/show.html.erb | 33 ++++++------ config/routes.rb | 7 +-- 6 files changed, 159 insertions(+), 29 deletions(-) create mode 100644 app/javascript/controllers/calculate_controller.js create mode 100644 app/javascript/controllers/calculationresults_controller.js create mode 100644 app/services/calculators/calculate_service.rb diff --git a/app/controllers/api/v1/calculators_controller.rb b/app/controllers/api/v1/calculators_controller.rb index d6972ce66..a580baf29 100644 --- a/app/controllers/api/v1/calculators_controller.rb +++ b/app/controllers/api/v1/calculators_controller.rb @@ -1,13 +1,37 @@ # frozen_string_literal: true class Api::V1::CalculatorsController < ApplicationController - VALUES = [ - { name: "bought_diapers", result: 8956 }, - { name: "money_spent", result: 7841 }, - { name: "garbage_created", result: 342 } - ].freeze - - def compute - render json: { result: VALUES } + def calculate + # @validation = CalculatorValidator.new(params) + + # if @validation.valid? + # puts('=' * 30) + # puts params + # puts('=' * 30) + + result = Calculators::CalculateService.new(resource.product, calculator_params).calculate + + render json: result.to_json, status: :ok + # else + # render( + # json: { + # error: @validation.error + # }, status: :unprocessable_entity + # ) + # end + end + + private + + def collection + Calculator.all + end + + def resource + collection.friendly.find(params[:slug]) + end + + def calculator_params + params.permit(:period, :price_id) end end diff --git a/app/javascript/controllers/calculate_controller.js b/app/javascript/controllers/calculate_controller.js new file mode 100644 index 000000000..dcdb75b7f --- /dev/null +++ b/app/javascript/controllers/calculate_controller.js @@ -0,0 +1,54 @@ +import { Controller } from "@hotwired/stimulus"; +import { FetchRequest } from "@rails/request.js"; + +export default class extends Controller { + static targets = ["period", "priceCategory"]; + static outlets = ["calculationresults"]; + static values = { + url: { + type: String, + default: "en/api/v1/diaper_calculators", + }, + }; + + connect() {} + + submit(e) { + e.preventDefault(); + + let formData = { + period: this.periodTarget.value, + price_id: this.priceCategoryTarget.value + }; + + const request = new FetchRequest("POST", this.urlValue, { + responseKind: "json", + body: JSON.stringify(formData), + }); + + this.sendRequest(request); + } + + async sendRequest(request) { + const response = await request.perform(); + const result = await response.json; + + if (response.ok) { + console.log("RESULTS") + console.log(result) + console.log("RESULTS") + this.calculationresultsOutlet.showResults(result); + } else if (response.statusCode == 422) { + toastr.error(result.error); + } + } + + getBasicOption(i) { + let option = document.createElement("option"); + + option.value = i; + option.innerText = i; + + return option; + } +} diff --git a/app/javascript/controllers/calculationresults_controller.js b/app/javascript/controllers/calculationresults_controller.js new file mode 100644 index 000000000..36bf69730 --- /dev/null +++ b/app/javascript/controllers/calculationresults_controller.js @@ -0,0 +1,18 @@ +import { Controller } from "@hotwired/stimulus"; + +export default class extends Controller { + static targets = [ + "moneySpentResult", + "itemsUsedResult", + ]; + + showResults(data) { + console.log(data) + + console.log(data.moneySpent) + console.log(data.itemsUsed) + + this.moneySpentResultTarget.innerHTML = data.moneySpent; + this.itemsUsedResultTarget.innerHTML = data.itemsUsed; + } +} diff --git a/app/services/calculators/calculate_service.rb b/app/services/calculators/calculate_service.rb new file mode 100644 index 000000000..79a3075fa --- /dev/null +++ b/app/services/calculators/calculate_service.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +class Calculators::CalculateService + attr_accessor :product, :period, :items_used, :money_spent, :params + + DAYS = { + "day" => 1, + "week" => 7, + "month" => 30, + "year" => 365 + }.freeze + + def initialize(product, params) + @product = product + @period = DAYS[params[:period]] + @items_used = 0 + @money_spent = 0 + @params = params + end + + def calculate + money_spent = selected_price * period + items_used = product.default_usage_per_day * period + + { + "moneySpent": money_spent, + "itemsUsed": items_used + } + end + + private + + def selected_price + product.prices.find_by(category_id: params[:price_id]).sum + end +end diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index d2f79f085..b39170f9d 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -4,11 +4,10 @@ <%= image_tag "arrow-left.svg", class: "z-1" %>
- <%= simple_form_for(:child, url: "#", html: { class: "simple_form_calculator", - data: { controller: "input-child-info", - input_child_info_url_value: api_v1_diaper_calculators_url, - input_child_info_months_value: month_number("new"), - input_child_info_results_outlet: '.result' }}) do |form| %> + <%= simple_form_for(api_v1_calculate_path, html: { class: "simple_form_calculator", + data: { controller: "calculate", + calculate_url_value: api_v1_calculate_path, + calculate_calculationresults_outlet: '.result' }}) do |form| %>
<%= "#{@calculator.product.title} calculator" %>
@@ -16,31 +15,33 @@ <%= form.input_field :period, collection: use_period, prompt: '__', - data: { input_child_info_target: 'month' } %> + class: 'form_fild price_select rounded w-100', + data: { calculate_target: 'period' } %> Price - <%= form.input_field :product_category, collection: @prices, - selected: t('.form.medium'), - label: t('.form_price'), - class: 'form_fild price_select rounded w-100', - data: { input_child_info_target: 'productCategory' } %> + <%= form.input_field :product_category, + collection: @prices, + prompt: '__', + label: t('.form_price'), + class: 'form_fild price_select rounded w-100', + data: { calculate_target: 'priceCategory' } %> <%= form.submit t('calculators.buttons.calculate'), class: 'calculate-btn result-btn', - data: { action: 'input-child-info#submit' } %> + data: { action: 'calculate#submit' } %>
<% end %>
-
+
- <% [{ image: "money_spent_2.png", data_target: "moneySpent", unit: t(".unit"), text: t(".money_spent") }, - { image: "money_to_spent_2.png", data_target: "moneyWillBeSpent", unit: t(".unit"), text: t(".money_will_be_spent") }].each do |item| %> + <% [{ image: "money_spent_2.png", data_target: "moneySpentResult", unit: t(".unit"), text: "moneySpent" }, + { image: "money_to_spent_2.png", data_target: "itemsUsedResult", unit: t(".unit"), text: "itemsUsed" }].each do |item| %>
<%= image_tag item[:image], class: "img-margin" %> -

000

+

000

<%= item[:unit] %>

<%= item[:text] %>

diff --git a/config/routes.rb b/config/routes.rb index d5155c8b9..51b5c8d1a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -53,11 +53,8 @@ namespace :api do namespace :v1 do - resources :calculators, only: [] do - post :compute, on: :member - end - post "/diaper_calculators", - to: "diaper_calculators#calculate" + post "/calculators/:slug",to: "calculators#calculate", as: "calculate" + post "/diaper_calculators",to: "diaper_calculators#calculate" end namespace :v2 do resources :calculators, only: [] do From e7287bb23de2ddc659c1b7408f3f5b6001e9587f Mon Sep 17 00:00:00 2001 From: AndriyAndriyovuch Date: Sun, 30 Jul 2023 23:46:02 +0300 Subject: [PATCH 08/63] add draft calculator for all products --- .../api/v1/calculators_controller.rb | 30 ++++++++----------- .../api/v1/diaper_calculators_controller.rb | 2 +- .../controllers/calculate_controller.js | 5 +--- .../calculationresults_controller.js | 5 ---- app/services/calculators/calculate_service.rb | 6 ++-- app/validators/calculator_validator.rb | 10 +++---- app/validators/diaper_calculator_validator.rb | 27 +++++++++++++++++ 7 files changed, 50 insertions(+), 35 deletions(-) create mode 100644 app/validators/diaper_calculator_validator.rb diff --git a/app/controllers/api/v1/calculators_controller.rb b/app/controllers/api/v1/calculators_controller.rb index a580baf29..f79489b04 100644 --- a/app/controllers/api/v1/calculators_controller.rb +++ b/app/controllers/api/v1/calculators_controller.rb @@ -2,23 +2,19 @@ class Api::V1::CalculatorsController < ApplicationController def calculate - # @validation = CalculatorValidator.new(params) - - # if @validation.valid? - # puts('=' * 30) - # puts params - # puts('=' * 30) - - result = Calculators::CalculateService.new(resource.product, calculator_params).calculate - - render json: result.to_json, status: :ok - # else - # render( - # json: { - # error: @validation.error - # }, status: :unprocessable_entity - # ) - # end + @validation = CalculatorValidator.new(params) + + if @validation.valid? + result = Calculators::CalculateService.new(resource.product, calculator_params).calculate + + render json: result.to_json, status: :ok + else + render( + json: { + error: @validation.error + }, status: :unprocessable_entity + ) + end end private diff --git a/app/controllers/api/v1/diaper_calculators_controller.rb b/app/controllers/api/v1/diaper_calculators_controller.rb index bf4e1c669..fdd8602d3 100644 --- a/app/controllers/api/v1/diaper_calculators_controller.rb +++ b/app/controllers/api/v1/diaper_calculators_controller.rb @@ -2,7 +2,7 @@ class Api::V1::DiaperCalculatorsController < ApplicationController def calculate - @validation = CalculatorValidator.new(params) + @validation = DiaperCalculatorValidator.new(params) if @validation.valid? diff --git a/app/javascript/controllers/calculate_controller.js b/app/javascript/controllers/calculate_controller.js index dcdb75b7f..56b4df805 100644 --- a/app/javascript/controllers/calculate_controller.js +++ b/app/javascript/controllers/calculate_controller.js @@ -7,7 +7,7 @@ export default class extends Controller { static values = { url: { type: String, - default: "en/api/v1/diaper_calculators", + default: "en/api/v1/calculators", }, }; @@ -34,9 +34,6 @@ export default class extends Controller { const result = await response.json; if (response.ok) { - console.log("RESULTS") - console.log(result) - console.log("RESULTS") this.calculationresultsOutlet.showResults(result); } else if (response.statusCode == 422) { toastr.error(result.error); diff --git a/app/javascript/controllers/calculationresults_controller.js b/app/javascript/controllers/calculationresults_controller.js index 36bf69730..8a3c040d7 100644 --- a/app/javascript/controllers/calculationresults_controller.js +++ b/app/javascript/controllers/calculationresults_controller.js @@ -7,11 +7,6 @@ export default class extends Controller { ]; showResults(data) { - console.log(data) - - console.log(data.moneySpent) - console.log(data.itemsUsed) - this.moneySpentResultTarget.innerHTML = data.moneySpent; this.itemsUsedResultTarget.innerHTML = data.itemsUsed; } diff --git a/app/services/calculators/calculate_service.rb b/app/services/calculators/calculate_service.rb index 79a3075fa..676d47795 100644 --- a/app/services/calculators/calculate_service.rb +++ b/app/services/calculators/calculate_service.rb @@ -6,7 +6,7 @@ class Calculators::CalculateService DAYS = { "day" => 1, "week" => 7, - "month" => 30, + "month" => 30.5, "year" => 365 }.freeze @@ -19,8 +19,8 @@ def initialize(product, params) end def calculate - money_spent = selected_price * period - items_used = product.default_usage_per_day * period + money_spent = (selected_price * period).to_i + items_used = (product.default_usage_per_day * period).to_i { "moneySpent": money_spent, diff --git a/app/validators/calculator_validator.rb b/app/validators/calculator_validator.rb index d6520ec3b..6cc2acd6d 100644 --- a/app/validators/calculator_validator.rb +++ b/app/validators/calculator_validator.rb @@ -8,16 +8,16 @@ def initialize(params) end def valid? - childs_years = params.fetch(:childs_years, nil) - childs_months = params.fetch(:childs_months, nil) + period = params.fetch(:period, nil) + price_id = params.fetch(:price_id, nil) - if childs_years.blank? && childs_months.blank? + if period.blank? && price_id.blank? @error = I18n.t("calculators.errors.year_and_month_error_msg") false - elsif childs_years.blank? + elsif period.blank? @error = I18n.t("calculators.errors.year_error_msg") false - elsif childs_months.blank? + elsif price_id.blank? @error = I18n.t("calculators.errors.month_error_msg") false else diff --git a/app/validators/diaper_calculator_validator.rb b/app/validators/diaper_calculator_validator.rb new file mode 100644 index 000000000..18cf17cf1 --- /dev/null +++ b/app/validators/diaper_calculator_validator.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class DiaperCalculatorValidator + attr_reader :params, :error + + def initialize(params) + @params = params + end + + def valid? + childs_years = params.fetch(:childs_years, nil) + childs_months = params.fetch(:childs_months, nil) + + if childs_years.blank? && childs_months.blank? + @error = I18n.t("calculators.errors.year_and_month_error_msg") + false + elsif childs_years.blank? + @error = I18n.t("calculators.errors.year_error_msg") + false + elsif childs_months.blank? + @error = I18n.t("calculators.errors.month_error_msg") + false + else + true + end + end +end From 456d188212cbddf21a88a97837b9985f1760fbbf Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Mon, 31 Jul 2023 21:35:11 +0300 Subject: [PATCH 09/63] added locales --- .../account/calculators_controller.rb | 2 +- app/helpers/calculators_helper.rb | 7 ++++++- app/models/product.rb | 2 ++ app/validators/calculator_validator.rb | 6 +++--- app/views/account/calculators/show.html.erb | 15 +++++++------ app/views/account/products/edit.html.slim | 2 +- app/views/account/products/index.html.slim | 2 +- app/views/account/products/new.html.slim | 2 +- config/locales/en/en.yml | 19 +++++++++++++++++ config/locales/uk/uk.yml | 21 +++++++++++++++++++ 10 files changed, 64 insertions(+), 14 deletions(-) diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index a61d06b3e..c2332f1a9 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -6,7 +6,6 @@ class Account::CalculatorsController < Account::BaseController def show @prices = product_prices(@calculator.product) - puts @calculator end def new @@ -19,6 +18,7 @@ def edit def create @calculator = Calculator.new(calculator_params) + # TODO render new if product empty (now calculator is saved) if @calculator.save Product.find(calculator_params[:product_id]).update(calculator_id: @calculator.id) diff --git a/app/helpers/calculators_helper.rb b/app/helpers/calculators_helper.rb index a33703a53..4dbc53c59 100644 --- a/app/helpers/calculators_helper.rb +++ b/app/helpers/calculators_helper.rb @@ -23,6 +23,11 @@ def month_number(style) end def use_period - ["day", "week", "month", "year"] + [ + [I18n.t("calculators.date.day"), "day"], + [I18n.t("calculators.date.week"), "week"], + [I18n.t("calculators.date.month"), "month"], + [I18n.t("calculators.date.year"), "year"] + ] end end diff --git a/app/models/product.rb b/app/models/product.rb index e7e871fac..174f19bb5 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -26,6 +26,8 @@ class Product < ApplicationRecord validates :title, presence: true, length: { in: 2..50 } + validates :default_usage_per_day, numericality: { greater_than: 0 } + scope :ordered_by_title, -> { order(:title) } accepts_nested_attributes_for :prices, reject_if: :blank_prices, allow_destroy: true diff --git a/app/validators/calculator_validator.rb b/app/validators/calculator_validator.rb index 6cc2acd6d..409d36d47 100644 --- a/app/validators/calculator_validator.rb +++ b/app/validators/calculator_validator.rb @@ -12,13 +12,13 @@ def valid? price_id = params.fetch(:price_id, nil) if period.blank? && price_id.blank? - @error = I18n.t("calculators.errors.year_and_month_error_msg") + @error = I18n.t("calculators.errors.period_and_price_error_msg") false elsif period.blank? - @error = I18n.t("calculators.errors.year_error_msg") + @error = I18n.t("calculators.errors.period_error_msg") false elsif price_id.blank? - @error = I18n.t("calculators.errors.month_error_msg") + @error = I18n.t("calculators.errors.price_error_msg") false else true diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index b39170f9d..7e43f349f 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -9,17 +9,20 @@ calculate_url_value: api_v1_calculate_path, calculate_calculationresults_outlet: '.result' }}) do |form| %>
- <%= "#{@calculator.product.title} calculator" %>
- Period +
+ <%= "#{@calculator.product.title} calculator" %> +
+ + <%= t("calculators.form.period") %> <%= form.input_field :period, collection: use_period, prompt: '__', class: 'form_fild price_select rounded w-100', data: { calculate_target: 'period' } %> - Price - <%= form.input_field :product_category, + <%= t("calculators.form.price") %> + <%= form.input_field :product_category, collection: @prices, prompt: '__', label: t('.form_price'), @@ -37,8 +40,8 @@
- <% [{ image: "money_spent_2.png", data_target: "moneySpentResult", unit: t(".unit"), text: "moneySpent" }, - { image: "money_to_spent_2.png", data_target: "itemsUsedResult", unit: t(".unit"), text: "itemsUsed" }].each do |item| %> + <% [{ image: "money_spent_2.png", data_target: "moneySpentResult", unit: t("calculators.results.money"), text: t("calculators.results.spent") }, + { image: "money_to_spent_2.png", data_target: "itemsUsedResult", unit: t("calculators.results.unit"), text: t("calculators.results.used") }].each do |item| %>
<%= image_tag item[:image], class: "img-margin" %>

000

diff --git a/app/views/account/products/edit.html.slim b/app/views/account/products/edit.html.slim index 0e1591654..f558e794e 100644 --- a/app/views/account/products/edit.html.slim +++ b/app/views/account/products/edit.html.slim @@ -3,7 +3,7 @@ .form-group.row .col-12.has-float-label.my-auto = f.input :title, label: t('.title'), class: 'form-control col-sm-11' - = f.input :default_usage_per_day, label: 'Default usage per day', class: 'form-control col-sm-11' + = f.input :default_usage_per_day, label: t('.default_usage_per_day'), class: 'form-control col-sm-11' - if Category.ordered_by_name.exists? = f.simple_fields_for :prices do |prices_form| .checkbox-blocks diff --git a/app/views/account/products/index.html.slim b/app/views/account/products/index.html.slim index 03f32c25c..4f7ee6787 100644 --- a/app/views/account/products/index.html.slim +++ b/app/views/account/products/index.html.slim @@ -9,7 +9,7 @@ tr th scope="col" # th scope="col" =t('.table.title') - th scope="col" ="Default usage" + th scope="col" =t('.table.default_usage_per_day') th scope="col" =t('.table.prices') th scope="col" =t('.table.actions') diff --git a/app/views/account/products/new.html.slim b/app/views/account/products/new.html.slim index c127efecf..6410c51ff 100644 --- a/app/views/account/products/new.html.slim +++ b/app/views/account/products/new.html.slim @@ -3,7 +3,7 @@ .form-group.row .col-12.has-float-label.my-auto = f.input :title, label: t('.title'), class: 'form-control col-sm-11' - = f.input :default_usage_per_day, label: 'Default usage per day', class: 'form-control col-sm-11' + = f.input :default_usage_per_day, label: t('.default_usage_per_day'), class: 'form-control col-sm-11' - Category.ordered_by_name.each do |category| .checkbox-blocks = f.simple_fields_for :prices do |prices_form| diff --git a/config/locales/en/en.yml b/config/locales/en/en.yml index 3a6d3667e..abbf472a8 100644 --- a/config/locales/en/en.yml +++ b/config/locales/en/en.yml @@ -65,12 +65,27 @@ en: year_and_month_error_msg: "Error: please, select years and months" year_error_msg: "Error: please, select years" month_error_msg: "Error: please, select month" + period_and_price_error_msg: "Error: please select reporting period and price category" + period_error_msg: "Error: please select reporting period" + price_error_msg: "Error: please select price category" + form: + period: Reporting period + price: Price category + results: + unit: pcs + money: uah + used: will be used + spent: will be spent show: welcome_header: "Welcome to ZeroWaste" buttons: to_main: "To main" calculate: "Calculate" date: + day: day + week: week + month: month + year: year months: one: "%{count} month" few: "%{count} months" @@ -175,6 +190,7 @@ en: title: 'Title' prices: 'Prices' actions: 'Actions' + default_usage_per_day: Default usage per day index: add_product_button: 'Add product' confirm_delete: 'Delete product?' @@ -182,8 +198,10 @@ en: confirm_delete: 'Delete product?' edit: title: 'Title' + default_usage_per_day: Default usage per day new: title: 'Title' + default_usage_per_day: Default usage per day created: "A product was successfully created." updated: "A product was successfully updated." deleted: "A product was successfully destroyed." @@ -432,6 +450,7 @@ en: blank: can't be blank too_long: too long (maximum %{count} symbols) too_short: too short (minimum %{count} symbols) + default_usage_per_day: Default usage per day form_errors: one: "One error prohibited %{model} from being saved" other: "%{count} errors prohibited this %{model} from being saved" diff --git a/config/locales/uk/uk.yml b/config/locales/uk/uk.yml index bc602d03a..bb681a6c5 100644 --- a/config/locales/uk/uk.yml +++ b/config/locales/uk/uk.yml @@ -34,6 +34,17 @@ uk: year_and_month_error_msg: "Помилка: будь ласка, виберіть скільки років та місяців дитині" year_error_msg: "Помилка: будь ласка, виберіть скільки років дитині" month_error_msg: "Помилка: будь ласка, виберіть скільки місяців дитині" + period_and_price_error_msg: "Помилка: будь ласка, виберіть звітний період та цінову категорію" + period_error_msg: "Помилка: будь ласка, виберіть звітний період" + price_error_msg: "Помилка: будь ласка, виберіть цінову категорію" + form: + period: Звітний період + price: Цінова категорія + results: + unit: шт + money: грн + used: буде використано + spent: буде витрачено show: welcome_header: "Ласкаво просимо до ZeroWaste" calculate_result_button: "Pозрахувати" @@ -45,6 +56,10 @@ uk: to_main: "На головну" calculate: "Розрахувати" date: + day: день + week: тиждень + month: місяць + year: рік months: one: "%{count} місяць" few: "%{count} місяці" @@ -149,11 +164,14 @@ uk: add_category_button: 'Додати категорію' confirm_delete: 'Видалити категорію?' products: + attributes: + default_usage_per_day: Використання в день за замовчуванням index: table: title: 'Назва' prices: 'Ціни' actions: 'Дії' + default_usage_per_day: Використання в день за замовчуванням add_product_button: 'Додати продукт' confirm_delete: 'Видалити продукт?' show: @@ -164,8 +182,10 @@ uk: confirm_delete: 'Видалити продукт?' edit: title: 'Назва' + default_usage_per_day: Використання в день за замовчуванням new: title: 'Назва' + default_usage_per_day: Використання в день за замовчуванням created: "Продукт був успішно створений." updated: "Продукт був успішно оновлений." deleted: "Продукт був успішно видалений." @@ -379,6 +399,7 @@ uk: priority: "Пріоритет" product: title: "Назва" + default_usage_per_day: Використання в день за замовчуванням errors: models: calculator: From 95acb0c9c7e1b988f59c5f75f19f9016af947093 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Mon, 31 Jul 2023 23:20:10 +0300 Subject: [PATCH 10/63] remove useless relations --- .../account/calculators_controller.rb | 31 +++----- .../api/v1/calculators_controller.rb | 6 +- app/views/account/calculators/edit.html.slim | 77 +++---------------- app/views/account/calculators/show.html.erb | 2 +- ...728151759_add_product_id_to_calculators.rb | 1 - db/schema.rb | 1 - 6 files changed, 27 insertions(+), 91 deletions(-) diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index c2332f1a9..9fc0221b0 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -5,23 +5,22 @@ class Account::CalculatorsController < Account::BaseController load_and_authorize_resource def show - @prices = product_prices(@calculator.product) + @product = product_resource + @prices = product_resource.categories_by_prices end def new - products_collection + @products = products_collection end def edit - collect_fields_for_form + @products = products_collection end def create @calculator = Calculator.new(calculator_params) - # TODO render new if product empty (now calculator is saved) if @calculator.save - Product.find(calculator_params[:product_id]).update(calculator_id: @calculator.id) redirect_to account_calculators_path, notice: t("notifications.calculator_created") else render action: "new" @@ -32,8 +31,6 @@ def update if updater redirect_to edit_account_calculator_path(slug: @calculator), notice: t("notifications.calculator_updated") else - collect_fields_for_form - render action: "edit" end end @@ -50,19 +47,6 @@ def calculator @calculator = Calculator.friendly.find(params[:slug]) end - def collect_fields_for_form - @form_fields = collect_fields_for_kind("form") - @parameter_fields = collect_fields_for_kind("parameter") - @result_fields = collect_fields_for_kind("result") - end - - def collect_fields_for_kind(kind) - @calculator - .fields - .select { |field| field.kind == kind } - .sort_by { |field| field.created_at || Time.zone.now } - end - def calculator_params params.require(:calculator).permit( :name, :id, :slug, :preferable, :product_id, @@ -77,14 +61,19 @@ def updater Calculator.transaction do ::Calculators::PreferableService.new(calculator_params).perform! @calculator.update(calculator_params) + end end def products_collection - @products = Product.where(calculator_id: nil) + Product.all end def product_prices(product) product.categories_by_prices end + + def product_resource + Product.find(@calculator.product_id) + end end diff --git a/app/controllers/api/v1/calculators_controller.rb b/app/controllers/api/v1/calculators_controller.rb index f79489b04..743e72eeb 100644 --- a/app/controllers/api/v1/calculators_controller.rb +++ b/app/controllers/api/v1/calculators_controller.rb @@ -5,7 +5,7 @@ def calculate @validation = CalculatorValidator.new(params) if @validation.valid? - result = Calculators::CalculateService.new(resource.product, calculator_params).calculate + result = Calculators::CalculateService.new(product_resource, calculator_params).calculate render json: result.to_json, status: :ok else @@ -30,4 +30,8 @@ def resource def calculator_params params.permit(:period, :price_id) end + + def product_resource + Product.find(resource.product_id) + end end diff --git a/app/views/account/calculators/edit.html.slim b/app/views/account/calculators/edit.html.slim index 874fb1caf..33aede832 100644 --- a/app/views/account/calculators/edit.html.slim +++ b/app/views/account/calculators/edit.html.slim @@ -1,74 +1,19 @@ -#calculators-edit.container +.container - if @calculator.errors.any? div h2 - = t('activerecord.form_errors', :count => @calculator.errors.count, + = t('activerecord.form_errors', :count => @calculator.errors.count, :model => t('models.calculator').downcase) ul - @calculator.errors.full_messages.each do |error_message| li= error_message -few - = simple_form_for @calculator, url: { action: 'update' }, wrapper: :horizontal_form, html: { novalidate: false } do |f| + = simple_form_for @calculator, url: account_calculator_path do |f| .form-group.row - .col-4.has-float-label.my-auto - = f.input :name, class: 'form-control', required: true - .col-4.has-float-label.my-auto - = f.input :slug, class: 'form-control', required: true - .col-4.has-float-label.my-auto - = f.input :preferable, class: 'form-control' - - h4.mt-5 =t('.add_new_field_label') - - .form-group.row - .col-6 - = select_tag :kind, - options_from_collection_for_select(Field.kinds.keys, :itself, :capitalize), - id: 'calculator_fields_kind', - prompt: t('.form.select_field_kind_label'), - class: 'custom-select', - data: { 'fields-list' => { form: [NamedValue.name, Select.name], - parameter: [Value.name, RangeField.name, Select.name, Calculation.name], - result: [Calculation.name] } } - .col-4 - = select_tag :type, '', id: 'calculator_fields_type', - prompt: t('.form.select_field_type_label'), - class: 'custom-select', - disabled: true - - .col-2 - = link_to t('buttons.create'), '#', - class: 'btn btn-success text-white disabled', - id: 'add-calculator-field', - data: { url: new_account_calculator_field_path(calculator_slug: @calculator) } - - .my-5 - h4.mb-2 =t('.form.form_label') - .form-group.row data-kind='form' data-selector-letter=('form'[0].upcase) data-last-selector=(extract_max_selector(@form_fields)) - - if @form_fields.any? - = f.fields_for :fields, @form_fields do |ff| - = render 'account/calculators/fields/form', f: ff - - else - p.ml-3.my-3.text-black-50 data-empty-text=true =t('.form.no_fields_yet_label') - - h4.mb-2 =t('.form.parameters_label') - .form-group.row data-kind='parameter' data-selector-letter=('parameter'[0].upcase) data-last-selector=(extract_max_selector(@parameter_fields)) - - if @parameter_fields.any? - = f.fields_for :fields, @parameter_fields do |ff| - = render 'account/calculators/fields/form', f: ff - - else - p.ml-3.my-3.text-black-50 data-empty-text=true =t('.form.no_fields_yet_label') - - h4.mb-2 =t('.form.results_label') - .form-group.row data-kind='result' data-selector-letter=('result'[0].upcase) data-last-selector=(extract_max_selector(@result_fields)) - - if @result_fields.any? - = f.fields_for :fields, @result_fields do |ff| - = render 'account/calculators/fields/form', f: ff - - else - p.ml-3.my-3.text-black-50 data-empty-text=true =t('.form.no_fields_yet_label') - - .row.my-4 - .col-12.d-flex.justify-content-end - = f.button :submit, t('.form.update_calculator_button'), class: 'btn btn-success mr-2' - = link_to account_calculator_path, class: 'btn btn-danger' do - span.mr-1 =t('buttons.cancel') - i.fa.fa-times-circle + .col-12.has-float-label.my-auto + = f.input :name, class: 'form-control' + = f.input :product_id, collection: @products + .div.d-flex + = f.button :submit, t('.form.update_calculator_button'), class: 'btn btn-success mr-2 height-auto w-auto' + = link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do + span.mr-1 = t('.cancel_button') + i.fa.fa-times-circle diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index 7e43f349f..d48ce31a1 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -11,7 +11,7 @@
- <%= "#{@calculator.product.title} calculator" %> + <%= "#{@product.title} calculator" %>
<%= t("calculators.form.period") %> diff --git a/db/migrate/20230728151759_add_product_id_to_calculators.rb b/db/migrate/20230728151759_add_product_id_to_calculators.rb index ea35b08dd..7b378d517 100644 --- a/db/migrate/20230728151759_add_product_id_to_calculators.rb +++ b/db/migrate/20230728151759_add_product_id_to_calculators.rb @@ -1,6 +1,5 @@ class AddProductIdToCalculators < ActiveRecord::Migration[6.1] def change add_column :calculators, :product_id, :integer - add_column :products, :calculator_id, :integer end end diff --git a/db/schema.rb b/db/schema.rb index 4348720ec..d211053ea 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -159,7 +159,6 @@ t.bigint "product_type_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false - t.integer "calculator_id" t.integer "default_usage_per_day", default: 1, null: false t.index ["product_type_id"], name: "index_products_on_product_type_id" t.index ["uuid"], name: "index_products_on_uuid", unique: true From 9e36431c63f22b1c7b3900ecdeac4ba3078848d6 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Thu, 3 Aug 2023 23:16:23 +0300 Subject: [PATCH 11/63] fix relations between calculator and product --- .../account/calculators_controller.rb | 41 ++++++------------- app/models/calculator.rb | 2 +- app/models/product.rb | 4 +- app/views/account/calculators/edit.html.slim | 2 +- app/views/account/calculators/new.html.slim | 2 +- app/views/account/calculators/show.html.erb | 4 +- ...728151759_add_product_id_to_calculators.rb | 2 +- db/schema.rb | 3 +- 8 files changed, 24 insertions(+), 36 deletions(-) diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 9fc0221b0..83879e6ee 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -1,20 +1,16 @@ # frozen_string_literal: true class Account::CalculatorsController < Account::BaseController - before_action :calculator, only: [:show, :edit, :update, :destroy] + before_action :products_collection, only: [:new, :edit] + after_action :products_collection, only: [:new, :edit] load_and_authorize_resource def show - @product = product_resource - @prices = product_resource.categories_by_prices - end - - def new - @products = products_collection + @calculator = resourse end def edit - @products = products_collection + @calculator = resourse end def create @@ -23,19 +19,22 @@ def create if @calculator.save redirect_to account_calculators_path, notice: t("notifications.calculator_created") else - render action: "new" + render :new, status: :unprocessable_entity end end def update + @calculator = resourse + if updater redirect_to edit_account_calculator_path(slug: @calculator), notice: t("notifications.calculator_updated") else - render action: "edit" + render :edit, status: :unprocessable_entity end end def destroy + @calculator = resourse @calculator.destroy! redirect_to account_calculators_path, notice: t("notifications.calculator_deleted") @@ -43,18 +42,12 @@ def destroy private - def calculator - @calculator = Calculator.friendly.find(params[:slug]) + def resourse + Calculator.friendly.find(params[:slug]) end def calculator_params - params.require(:calculator).permit( - :name, :id, :slug, :preferable, :product_id, - fields_attributes: [ - :id, :selector, :label, :name, :value, :unit, :from, :to, :type, :kind, - :_destroy - ] - ) + params.require(:calculator).permit(:name, :slug, :product_id) end def updater @@ -66,14 +59,6 @@ def updater end def products_collection - Product.all - end - - def product_prices(product) - product.categories_by_prices - end - - def product_resource - Product.find(@calculator.product_id) + @products = Product.ordered end end diff --git a/app/models/calculator.rb b/app/models/calculator.rb index 3575bec9e..d1c84116e 100644 --- a/app/models/calculator.rb +++ b/app/models/calculator.rb @@ -27,7 +27,7 @@ class Calculator < ApplicationRecord has_many :fields, dependent: :destroy - has_one :product + belongs_to :product accepts_nested_attributes_for :fields, allow_destroy: true diff --git a/app/models/product.rb b/app/models/product.rb index 174f19bb5..e7cb924a2 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -19,7 +19,9 @@ class Product < ApplicationRecord DIAPER = "diaper" - belongs_to :calculator, required: false + scope :ordered, -> { order(title: :asc) } + + has_one :calculator, required: false, dependent: :destroy has_many :prices, as: :priceable, dependent: :destroy has_many :categories_by_prices, through: :prices, source: :category diff --git a/app/views/account/calculators/edit.html.slim b/app/views/account/calculators/edit.html.slim index 33aede832..6f34ae210 100644 --- a/app/views/account/calculators/edit.html.slim +++ b/app/views/account/calculators/edit.html.slim @@ -11,7 +11,7 @@ .form-group.row .col-12.has-float-label.my-auto = f.input :name, class: 'form-control' - = f.input :product_id, collection: @products + = f.input :product_id, collection: @products, include_blank: false .div.d-flex = f.button :submit, t('.form.update_calculator_button'), class: 'btn btn-success mr-2 height-auto w-auto' = link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do diff --git a/app/views/account/calculators/new.html.slim b/app/views/account/calculators/new.html.slim index 2b0667713..72fe5449c 100644 --- a/app/views/account/calculators/new.html.slim +++ b/app/views/account/calculators/new.html.slim @@ -11,7 +11,7 @@ .form-group.row .col-12.has-float-label.my-auto = f.input :name, class: 'form-control' - = f.input :product_id, collection: @products + = f.input :product_id, collection: @products, include_blank: false .div.d-flex = f.button :submit, t('.create_calculator_button'), class: 'btn btn-success mr-2 height-auto w-auto' = link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index d48ce31a1..a0f5f3a73 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -11,7 +11,7 @@
- <%= "#{@product.title} calculator" %> + <%= "#{@calculator.product.title} calculator" %>
<%= t("calculators.form.period") %> @@ -23,7 +23,7 @@ <%= t("calculators.form.price") %> <%= form.input_field :product_category, - collection: @prices, + collection: @calculator.product.categories_by_prices, prompt: '__', label: t('.form_price'), class: 'form_fild price_select rounded w-100', diff --git a/db/migrate/20230728151759_add_product_id_to_calculators.rb b/db/migrate/20230728151759_add_product_id_to_calculators.rb index 7b378d517..709b1b601 100644 --- a/db/migrate/20230728151759_add_product_id_to_calculators.rb +++ b/db/migrate/20230728151759_add_product_id_to_calculators.rb @@ -1,5 +1,5 @@ class AddProductIdToCalculators < ActiveRecord::Migration[6.1] def change - add_column :calculators, :product_id, :integer + add_reference(:calculators, :product) end end diff --git a/db/schema.rb b/db/schema.rb index d211053ea..3b344791e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -57,8 +57,9 @@ t.datetime "updated_at", precision: 6, null: false t.string "slug" t.boolean "preferable", default: false - t.integer "product_id" + t.bigint "product_id" t.index ["name"], name: "index_calculators_on_name", unique: true + t.index ["product_id"], name: "index_calculators_on_product_id" t.index ["slug"], name: "index_calculators_on_slug", unique: true t.index ["uuid"], name: "index_calculators_on_uuid", unique: true end From 5e4f0d521b571e0b8226404da577b9f50140b5be Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 12:49:45 +0300 Subject: [PATCH 12/63] remove before_action --- app/controllers/account/calculators_controller.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 83879e6ee..dd07ef6c7 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -1,16 +1,19 @@ # frozen_string_literal: true class Account::CalculatorsController < Account::BaseController - before_action :products_collection, only: [:new, :edit] - after_action :products_collection, only: [:new, :edit] load_and_authorize_resource + def new + @products = products_collection + end + def show @calculator = resourse end def edit @calculator = resourse + @products = products_collection end def create @@ -54,7 +57,6 @@ def updater Calculator.transaction do ::Calculators::PreferableService.new(calculator_params).perform! @calculator.update(calculator_params) - end end From 88efc69cd8e674bce257c1d678ee7a0ef9620e43 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 14:00:21 +0300 Subject: [PATCH 13/63] remove useless id from path in category/new view --- app/views/account/categories/index.html.slim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/views/account/categories/index.html.slim b/app/views/account/categories/index.html.slim index c48431cdd..73c45eff9 100644 --- a/app/views/account/categories/index.html.slim +++ b/app/views/account/categories/index.html.slim @@ -1,7 +1,6 @@ .container - = form_tag account_category_path(id: @categories), method: :get, class: 'd-flex justify-content-end mb-5' do - .d-flex - = link_to new_account_category_path(id: @categories), class: 'btn btn-success px-4 ml-1' do + .d-flex.flex-row-reverse + = link_to new_account_category_path, class: 'btn btn-success px-4 ml-1 mb-2' do i.fa.fa-plus.mr-2 span =t('.add_category_button') From 87b11e1c3111c724c12f3ec60a8adcd6ff800324 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 16:06:17 +0300 Subject: [PATCH 14/63] fix selectors after invalid data in form fields --- app/controllers/account/calculators_controller.rb | 2 ++ app/controllers/account/products_controller.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index dd07ef6c7..7987d5b82 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -22,6 +22,7 @@ def create if @calculator.save redirect_to account_calculators_path, notice: t("notifications.calculator_created") else + @products = products_collection render :new, status: :unprocessable_entity end end @@ -32,6 +33,7 @@ def update if updater redirect_to edit_account_calculator_path(slug: @calculator), notice: t("notifications.calculator_updated") else + @products = products_collection render :edit, status: :unprocessable_entity end end diff --git a/app/controllers/account/products_controller.rb b/app/controllers/account/products_controller.rb index cad7c5c32..c2d3f0e77 100644 --- a/app/controllers/account/products_controller.rb +++ b/app/controllers/account/products_controller.rb @@ -25,6 +25,7 @@ def create if @product.save redirect_to account_products_path, notice: t(".created") else + @product.prices.build render :new, status: :unprocessable_entity end end @@ -35,6 +36,7 @@ def update if @product.update(product_params) redirect_to account_products_path, notice: t(".updated") else + @product.prices.build render :edit, status: :unprocessable_entity end end From 2388ad904b8fb26850eb64337ced0c1ad69ed950 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 16:13:12 +0300 Subject: [PATCH 15/63] add migration to clean all prices without category --- .../20230806130723_remove_prices_without_categories.rb | 9 +++++++++ db/schema.rb | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20230806130723_remove_prices_without_categories.rb diff --git a/db/migrate/20230806130723_remove_prices_without_categories.rb b/db/migrate/20230806130723_remove_prices_without_categories.rb new file mode 100644 index 000000000..dadae3e57 --- /dev/null +++ b/db/migrate/20230806130723_remove_prices_without_categories.rb @@ -0,0 +1,9 @@ +class RemovePricesWithoutCategories < ActiveRecord::Migration[6.1] + def change + categories = Category.pluck(:id) + + Price.all.each do |price| + price.destroy unless categories.include?(price.category_id) + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 3b344791e..26ce45871 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_07_29_140507) do +ActiveRecord::Schema.define(version: 2023_08_06_130723) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" From fa2f75103f5a8b4784d524505a16bc24e96ed439 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 17:28:48 +0300 Subject: [PATCH 16/63] added alert if admin wants to delete category with related prices --- .../account/categories_controller.rb | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/controllers/account/categories_controller.rb b/app/controllers/account/categories_controller.rb index f44316775..211eeadb7 100644 --- a/app/controllers/account/categories_controller.rb +++ b/app/controllers/account/categories_controller.rb @@ -37,9 +37,22 @@ def update def destroy @category = resource - @category.destroy - redirect_to account_categories_path, notice: t("notifications.category_deleted") + prices = Price.where(category_id: @category.id) + + if prices.any? + products = [] + + prices.each do |price| + products << Product.where(id: price.priceable_id).pluck(:title) + end + + redirect_to account_categories_path, alert: "Please remove prices with this category in next products: #{products.join(', ')}" + else + @category.destroy + + redirect_to account_categories_path, notice: t("notifications.category_deleted") + end end private From 09b680035000a0556c9d42f397d94a1150218304 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 17:44:17 +0300 Subject: [PATCH 17/63] add locale for error message --- app/controllers/account/categories_controller.rb | 2 +- config/locales/en/en.yml | 2 ++ config/locales/uk/uk.yml | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/account/categories_controller.rb b/app/controllers/account/categories_controller.rb index 211eeadb7..fcb59ed7d 100644 --- a/app/controllers/account/categories_controller.rb +++ b/app/controllers/account/categories_controller.rb @@ -47,7 +47,7 @@ def destroy products << Product.where(id: price.priceable_id).pluck(:title) end - redirect_to account_categories_path, alert: "Please remove prices with this category in next products: #{products.join(', ')}" + redirect_to account_categories_path, alert: "#{t('.relation_error')} #{products.join(', ')}" else @category.destroy diff --git a/config/locales/en/en.yml b/config/locales/en/en.yml index f68adf852..9f8850622 100644 --- a/config/locales/en/en.yml +++ b/config/locales/en/en.yml @@ -196,6 +196,8 @@ en: index: add_category_button: 'Add category' confirm_delete: 'Delete category?' + destroy: + relation_error: 'Please remove prices with this category in next products: ' products: table: title: 'Title' diff --git a/config/locales/uk/uk.yml b/config/locales/uk/uk.yml index c7aa43c81..18289069f 100644 --- a/config/locales/uk/uk.yml +++ b/config/locales/uk/uk.yml @@ -174,6 +174,8 @@ uk: priority: 'Пріоритет' add_category_button: 'Додати категорію' confirm_delete: 'Видалити категорію?' + destroy: + relation_error: 'Будь ласка видаліть ціни з цією категорією з наступних продуктів: ' products: attributes: default_usage_per_day: Використання в день за замовчуванням From 3704ab92c91aa1b0be9cb4337ae0fc1c5cba2b34 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 20:21:34 +0300 Subject: [PATCH 18/63] fix all tests due to new logic, small rubocop fixes --- .../account/calculators_controller.rb | 10 +++---- .../account/categories_controller.rb | 2 +- app/controllers/calculators_controller.rb | 4 --- app/services/calculators/calculate_service.rb | 6 ++-- app/validators/calculator_validator.rb | 2 +- config/routes.rb | 4 +-- spec/factories/calculations.rb | 3 +- spec/factories/calculators.rb | 8 +++-- spec/factories/fields.rb | 3 +- spec/factories/named_values.rb | 3 +- spec/factories/range_fields.rb | 3 +- spec/factories/values.rb | 3 +- .../account/create_calculator_spec.rb | 5 +++- .../account/update_calculator_spec.rb | 13 +++++++- spec/features/product_category_spec.rb | 2 +- spec/features/sign_out_spec.rb | 6 ++-- spec/features/visit_calculator_spec.rb | 2 +- spec/features/visit_login_spec.rb | 8 +---- spec/models/calculation_resolver_spec.rb | 2 +- spec/models/calculator_resolver_spec.rb | 2 +- spec/models/calculator_spec.rb | 6 ++-- spec/models/field_spec.rb | 2 +- spec/requests/calculators_spec.rb | 7 +++-- spec/requests/result_calculators_spec.rb | 2 +- spec/requests/values_spec.rb | 30 ------------------- 25 files changed, 60 insertions(+), 78 deletions(-) delete mode 100644 spec/requests/values_spec.rb diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 7987d5b82..1832016bc 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -3,17 +3,17 @@ class Account::CalculatorsController < Account::BaseController load_and_authorize_resource - def new - @products = products_collection - end - def show @calculator = resourse end + def new + @products = products_collection + end + def edit @calculator = resourse - @products = products_collection + @products = products_collection end def create diff --git a/app/controllers/account/categories_controller.rb b/app/controllers/account/categories_controller.rb index fcb59ed7d..583911181 100644 --- a/app/controllers/account/categories_controller.rb +++ b/app/controllers/account/categories_controller.rb @@ -47,7 +47,7 @@ def destroy products << Product.where(id: price.priceable_id).pluck(:title) end - redirect_to account_categories_path, alert: "#{t('.relation_error')} #{products.join(', ')}" + redirect_to account_categories_path, alert: "#{t(".relation_error")} #{products.join(", ")}" else @category.destroy diff --git a/app/controllers/calculators_controller.rb b/app/controllers/calculators_controller.rb index 1e4d20823..cb5ec5550 100644 --- a/app/controllers/calculators_controller.rb +++ b/app/controllers/calculators_controller.rb @@ -3,10 +3,6 @@ class CalculatorsController < ApplicationController before_action :authenticate_user!, only: :receive_recomendations - # def index - # @calculators = collection - # end - def show @calculator = resource end diff --git a/app/services/calculators/calculate_service.rb b/app/services/calculators/calculate_service.rb index 676d47795..be5ee913f 100644 --- a/app/services/calculators/calculate_service.rb +++ b/app/services/calculators/calculate_service.rb @@ -20,11 +20,11 @@ def initialize(product, params) def calculate money_spent = (selected_price * period).to_i - items_used = (product.default_usage_per_day * period).to_i + items_used = (product.default_usage_per_day * period).to_i { - "moneySpent": money_spent, - "itemsUsed": items_used + moneySpent: money_spent, + itemsUsed: items_used } end diff --git a/app/validators/calculator_validator.rb b/app/validators/calculator_validator.rb index 409d36d47..4612b6972 100644 --- a/app/validators/calculator_validator.rb +++ b/app/validators/calculator_validator.rb @@ -8,7 +8,7 @@ def initialize(params) end def valid? - period = params.fetch(:period, nil) + period = params.fetch(:period, nil) price_id = params.fetch(:price_id, nil) if period.blank? && price_id.blank? diff --git a/config/routes.rb b/config/routes.rb index ee5158e01..de18dad25 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -53,8 +53,8 @@ namespace :api do namespace :v1 do - post "/calculators/:slug",to: "calculators#calculate", as: "calculate" - post "/diaper_calculators",to: "diaper_calculators#calculate" + post "/calculators/:slug", to: "calculators#calculate", as: "calculate" + post "/diaper_calculators", to: "diaper_calculators#calculate" end namespace :v2 do resources :calculators, only: [] do diff --git a/spec/factories/calculations.rb b/spec/factories/calculations.rb index 021efd06f..c44314f02 100644 --- a/spec/factories/calculations.rb +++ b/spec/factories/calculations.rb @@ -26,10 +26,11 @@ # FactoryBot.define do factory :calculation do + association :calculator, :diaper_calculator + value { "F1 * P2 / P5" } type { "Calculation" } label { "Label" } kind { "form" } - calculator end end diff --git a/spec/factories/calculators.rb b/spec/factories/calculators.rb index cad0fdd0d..633a92ae4 100644 --- a/spec/factories/calculators.rb +++ b/spec/factories/calculators.rb @@ -20,7 +20,11 @@ # FactoryBot.define do factory :calculator do - name { "Diapers Calculator" } - slug { "diapers" } + trait :diaper_calculator do + association :product, :diaper + + name { "Diapers Calculator" } + slug { "diapers" } + end end end diff --git a/spec/factories/fields.rb b/spec/factories/fields.rb index 87a67e082..3e76abe52 100644 --- a/spec/factories/fields.rb +++ b/spec/factories/fields.rb @@ -26,9 +26,10 @@ # FactoryBot.define do factory :field do + association :calculator, :diaper_calculator + type { "Calculation" } label { "Label" } kind { "form" } - calculator end end diff --git a/spec/factories/named_values.rb b/spec/factories/named_values.rb index bf50de448..375cca6df 100644 --- a/spec/factories/named_values.rb +++ b/spec/factories/named_values.rb @@ -26,12 +26,13 @@ # FactoryBot.define do factory :named_value do + association :calculator, :diaper_calculator + name { "NamedValue" } type { "Calculation" } label { "Label" } kind { "form" } from { 0 } to { 200 } - calculator end end diff --git a/spec/factories/range_fields.rb b/spec/factories/range_fields.rb index 25916ea7c..56d1d8292 100644 --- a/spec/factories/range_fields.rb +++ b/spec/factories/range_fields.rb @@ -26,11 +26,12 @@ # FactoryBot.define do factory :range_field do + association :calculator, :diaper_calculator + from { 0 } type { "RangeField" } label { "Label" } kind { "form" } - calculator to { 200 } value { "10" } end diff --git a/spec/factories/values.rb b/spec/factories/values.rb index 038de0b53..f24a0036f 100644 --- a/spec/factories/values.rb +++ b/spec/factories/values.rb @@ -26,10 +26,11 @@ # FactoryBot.define do factory :value do + association :calculator, :diaper_calculator + value { "Value" } type { "Value" } label { "Label" } kind { "form" } - calculator end end diff --git a/spec/features/account/create_calculator_spec.rb b/spec/features/account/create_calculator_spec.rb index e29f5bc66..8f00797ef 100644 --- a/spec/features/account/create_calculator_spec.rb +++ b/spec/features/account/create_calculator_spec.rb @@ -5,7 +5,9 @@ CREATE_CALCULATOR_BUTTON = "Create calculator" describe "Create Calculator Page", js: true do - let(:calculator) { create(:calculator) } + let!(:product) { create(:product, :diaper) } + let(:calculator) { create(:calculator, :diaper_calculator) } + let(:category) { create(:category) } before do @admin = create(:user, :admin) @@ -16,6 +18,7 @@ context "when user clicks button Create calculator" do it "shows message that calculator has been successfully created" do fill_in "Name", with: "Calculator1" + select product.title, from: "calculator_product_id" click_button CREATE_CALCULATOR_BUTTON expect(page).to have_content("Calculator has been successfully created") end diff --git a/spec/features/account/update_calculator_spec.rb b/spec/features/account/update_calculator_spec.rb index 9d7d9fb86..830c93d4d 100644 --- a/spec/features/account/update_calculator_spec.rb +++ b/spec/features/account/update_calculator_spec.rb @@ -4,7 +4,9 @@ UPDATE_CALCULATOR_BUTTON = "Update calculator" describe "Update Calculator Page", js: true do - let(:calculator) { create(:calculator) } + let!(:product_diaper) { create(:product, :diaper) } + let!(:product_napkin) { create(:product, :napkin) } + let(:calculator) { create(:calculator, :diaper_calculator) } before do @admin = create(:user, :admin) @@ -20,6 +22,15 @@ end end + context "when user clicks button Update calculator with changing product" do + it "shows message that calculator has been successfully updated" do + fill_in "Name", with: "Calculator2" + select product_napkin.title, from: "calculator_product_id" + click_button UPDATE_CALCULATOR_BUTTON + expect(page).to have_content("Calculator has been successfully updated") + end + end + context "when user fill in the Name field with name shorter than 2 symbols" do it "shows message that name is too short" do fill_in "Name", with: "o" diff --git a/spec/features/product_category_spec.rb b/spec/features/product_category_spec.rb index 8ccda8601..3424c56b0 100644 --- a/spec/features/product_category_spec.rb +++ b/spec/features/product_category_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" describe "product category dropdown list in new design", js: true do - let(:calculator) { create(:calculator) } + let(:calculator) { create(:calculator, :diaper_calculator) } include_context :new_calculator_design diff --git a/spec/features/sign_out_spec.rb b/spec/features/sign_out_spec.rb index d5468955d..9708514a5 100644 --- a/spec/features/sign_out_spec.rb +++ b/spec/features/sign_out_spec.rb @@ -4,16 +4,15 @@ describe "sign out", js: true do let(:user) { create(:user) } - let(:calculator) { create(:calculator) } flash_message_disappear_time = 20 + before do - create(:feature_flag, :show_admin_menu) - allow_any_instance_of(ApplicationController).to receive(:after_sign_in_path_for).and_return("/calculators/#{calculator.slug}") visit "/users/sign_in" fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Log in" + Capybara.using_wait_time flash_message_disappear_time do click_link "Log Out" sleep 3 @@ -21,7 +20,6 @@ end it "signs the user out" do - expect(page).to have_current_path("/calculators/#{calculator.slug}") expect(page).to have_content("LOG IN") end end diff --git a/spec/features/visit_calculator_spec.rb b/spec/features/visit_calculator_spec.rb index b1459835b..1151f52f1 100644 --- a/spec/features/visit_calculator_spec.rb +++ b/spec/features/visit_calculator_spec.rb @@ -4,7 +4,7 @@ describe "visit Calculator page", js: true do let(:user) { create(:user) } - let(:calculator) { create(:calculator) } + let(:calculator) { create(:calculator, :diaper_calculator) } it "visits calculator page" do visit "#{I18n.locale}/calculator" diff --git a/spec/features/visit_login_spec.rb b/spec/features/visit_login_spec.rb index 6e619434d..820880409 100644 --- a/spec/features/visit_login_spec.rb +++ b/spec/features/visit_login_spec.rb @@ -4,19 +4,13 @@ describe "visit Login page", js: true do let(:user) { create(:user) } - let(:calculator) { create(:calculator) } it "when sign in with correct login and password" do - allow_any_instance_of(ApplicationController) - .to receive(:after_sign_in_path_for) - .and_return("/calculators/#{calculator.slug}") - allow(Devise::Mailer).to receive(:confirmation_instructions) - .and_return(double(deliver: true)) - create(:feature_flag, :show_admin_menu) visit "/users/sign_in" fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Log in" + expect(page).to have_content("Signed in successfully") expect(page).to have_content("LOG OUT") end diff --git a/spec/models/calculation_resolver_spec.rb b/spec/models/calculation_resolver_spec.rb index 680cdd8c8..6797ab8de 100644 --- a/spec/models/calculation_resolver_spec.rb +++ b/spec/models/calculation_resolver_spec.rb @@ -8,7 +8,7 @@ describe "#result" do let(:value) { "P1 + 2" } let(:parameters) { { p1: 2 } } - let(:calculator) { create(:calculator) } + let(:calculator) { create(:calculator, :diaper_calculator) } let(:calculation) do create(:calculation, value: value, calculator: calculator) end diff --git a/spec/models/calculator_resolver_spec.rb b/spec/models/calculator_resolver_spec.rb index 330ebd173..f08dc2167 100644 --- a/spec/models/calculator_resolver_spec.rb +++ b/spec/models/calculator_resolver_spec.rb @@ -5,7 +5,7 @@ RSpec.describe CalculatorResolver, type: :model do subject { described_class } - let(:calculator) { build(:calculator) } + let(:calculator) { build(:calculator, :diaper_calculator) } let!(:calculation_r1) { create(:calculation, value: "P1 * P2 / P3", type: "Calculation", selector: "R1", label: "one", kind: "result", calculator: calculator) } let!(:calculation_r2) { create(:calculation, value: "10 * P4", type: "Calculation", selector: "R2", label: "one", kind: "result", calculator: calculator) } let!(:calculation_p4) { create(:value, value: "P1 * P5", type: "Calculation", selector: "P4", label: "four", kind: "parameter", calculator: calculator) } diff --git a/spec/models/calculator_spec.rb b/spec/models/calculator_spec.rb index 6a6c4620b..589724ccd 100644 --- a/spec/models/calculator_spec.rb +++ b/spec/models/calculator_spec.rb @@ -23,7 +23,7 @@ LOCAL_PREFIX_CALCULATOR = "activerecord.errors.models.calculator.attributes" RSpec.describe Calculator, type: :model do - subject { build(:calculator) } + subject { build(:calculator, :diaper_calculator) } describe "validations" do it { @@ -48,8 +48,8 @@ describe "scope" do context "finds instances by slug and name" do - let!(:calc) { create(:calculator, slug: "calc") } - let!(:calc2) { create(:calculator, slug: "diapers", name: "Calculator") } + let!(:calc) { create(:calculator, :diaper_calculator, slug: "calc") } + let!(:calc2) { create(:calculator, :diaper_calculator, slug: "diapers", name: "Calculator") } it "finds two instances by slug or name" do expect(Calculator.by_name_or_slug("calc").to_a).to include(calc, calc2) diff --git a/spec/models/field_spec.rb b/spec/models/field_spec.rb index 9c974f438..539d2c803 100644 --- a/spec/models/field_spec.rb +++ b/spec/models/field_spec.rb @@ -58,7 +58,7 @@ end describe "#set_selector" do - let(:calculator) { create(:calculator) } + let(:calculator) { create(:calculator, :diaper_calculator) } let(:field) { build(:field, label: "new", kind: 0, calculator: calculator) } context "when there is no form fields in a database" do diff --git a/spec/requests/calculators_spec.rb b/spec/requests/calculators_spec.rb index 1e3854534..505523a8e 100644 --- a/spec/requests/calculators_spec.rb +++ b/spec/requests/calculators_spec.rb @@ -3,7 +3,8 @@ require "rails_helper" RSpec.describe CalculatorsController, type: :request do - let(:calculator) { create(:calculator) } + let(:product) { create(:product, :diaper) } + let(:calculator) { create(:calculator, :diaper_calculator) } let!(:calculation_r1) do create(:calculation, value: "P1 * P2 / P3", type: "Calculation", selector: "R1", name: "First result", @@ -89,8 +90,8 @@ describe "POST #create" do include_context :authorize_admin - let(:valid_attributes) { { name: "калькулятор", slug: "test" } } - let(:invalid_attributes) { { name: "$калькулятор", slug: "test" } } + let(:valid_attributes) { { name: "калькулятор", slug: "test", product_id: product.id } } + let(:invalid_attributes) { { name: "$калькулятор", slug: "test", product_id: product.id } } context "with valid attributes" do it "creates a calculator" do diff --git a/spec/requests/result_calculators_spec.rb b/spec/requests/result_calculators_spec.rb index 9b8dddee4..a2053a484 100644 --- a/spec/requests/result_calculators_spec.rb +++ b/spec/requests/result_calculators_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe Api::V2::CalculatorsController, type: :request do - let(:calculator) { create(:calculator) } + let(:calculator) { create(:calculator, :diaper_calculator) } let!(:value_p1) do create(:value, value: "10", type: "Value", selector: "P1", label: "one", kind: "parameter", diff --git a/spec/requests/values_spec.rb b/spec/requests/values_spec.rb deleted file mode 100644 index f376badc6..000000000 --- a/spec/requests/values_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -require "rails_helper" - -RSpec.describe "Values", type: :request do - let(:json_response) { JSON.parse(response.body) } - - describe "POST api/v1/calculators/PERMALINK/compute" do - before do - post "/api/v1/calculators/PERMALINK/compute" - end - - it "returns http success" do - expect(response.status).to eq(200) - end - - it "returns JSON data correctly" do - expect(json_response) - .to eq( - "result" => [ - { "name" => "bought_diapers", "result" => 8956 }, - { "name" => "money_spent", "result" => 7841 }, - { "name" => "garbage_created", "result" => 342 } - ] - ) - end - - it "JSON contains response" do - expect(json_response).to be_truthy - end - end -end From 3be2d64353942f030fe9567664d234704c5e37ff Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 22:14:06 +0300 Subject: [PATCH 19/63] created request tests for account/calculators_controller --- spec/requests/account/calculators_spec.rb | 106 ++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 spec/requests/account/calculators_spec.rb diff --git a/spec/requests/account/calculators_spec.rb b/spec/requests/account/calculators_spec.rb new file mode 100644 index 000000000..e43a9c9e9 --- /dev/null +++ b/spec/requests/account/calculators_spec.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe Account::CalculatorsController, type: :request do + let(:calculator) { create(:calculator, :diaper_calculator) } + let(:product) { create(:product, :diaper) } + + let(:valid_attributes) do + { + calculator: { + name: "Test Calculator", + slug: "test-calculator", + product_id: product.id + } + } + end + + let(:invalid_attributes) do + { + calculator: { + name: "%^&*()", + slug: "&", + product_id: nil + } + } + end + + include_context :authorize_admin + + context "GET #index" do + it "returns http success" do + get account_calculators_path + + expect(response).to be_successful + end + end + + context "GET #show" do + it "returns http success" do + get account_calculator_path(calculator) + + expect(response).to be_successful + end + end + + context "GET #new" do + it "returns http success" do + get new_account_calculator_path + expect(response).to be_successful + end + end + + context "GET #edit" do + it "returns http success" do + get edit_account_calculator_path(calculator) + + expect(response).to be_successful + end + end + + context "POST #create" do + it "creates a new calculator" do + expect { post account_calculators_path, params: valid_attributes }.to change(Calculator, :count).by(1) + + expect(response).to redirect_to(account_calculators_path) + expect(flash[:notice]).to eq(I18n.t("notifications.calculator_created")) + end + + it "renders new template with errors if creation fails" do + post account_calculators_path, params: invalid_attributes + expect(response).to have_http_status(:unprocessable_entity) + + expect(response).to render_template(:new) + end + end + + context "PATCH #update" do + it "updates the calculator" do + patch account_calculator_path(calculator), params: { calculator: { name: "Updated Calculator" }} + calculator.reload + + expect(calculator.name).to eq("Updated Calculator") + expect(flash[:notice]).to eq(I18n.t("notifications.calculator_updated")) + end + + it "renders edit template with errors if update fails" do + patch account_calculator_path(calculator), params: invalid_attributes + + expect(response).to have_http_status(:unprocessable_entity) + expect(response).to render_template(:edit) + end + end + + context "DELETE #destroy" do + it "destroys the calculator" do + post account_calculators_path, params: valid_attributes + calculator.reload + + expect { delete account_calculator_path(calculator) }.to change(Calculator, :count).by(-1) + + expect(response).to redirect_to(account_calculators_path) + expect(flash[:notice]).to eq(I18n.t("notifications.calculator_deleted")) + end + end +end From 12802a609c85bc63176984905584da20e761279c Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 22:26:56 +0300 Subject: [PATCH 20/63] removed code smells --- app/javascript/controllers/calculate_controller.js | 2 -- spec/requests/account/calculators_spec.rb | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/javascript/controllers/calculate_controller.js b/app/javascript/controllers/calculate_controller.js index 56b4df805..f48c6020a 100644 --- a/app/javascript/controllers/calculate_controller.js +++ b/app/javascript/controllers/calculate_controller.js @@ -11,8 +11,6 @@ export default class extends Controller { }, }; - connect() {} - submit(e) { e.preventDefault(); diff --git a/spec/requests/account/calculators_spec.rb b/spec/requests/account/calculators_spec.rb index e43a9c9e9..08393e709 100644 --- a/spec/requests/account/calculators_spec.rb +++ b/spec/requests/account/calculators_spec.rb @@ -29,7 +29,7 @@ include_context :authorize_admin context "GET #index" do - it "returns http success" do + it "returns http success and shows all calculators" do get account_calculators_path expect(response).to be_successful @@ -37,7 +37,7 @@ end context "GET #show" do - it "returns http success" do + it "returns http success and shows a calculator" do get account_calculator_path(calculator) expect(response).to be_successful @@ -45,14 +45,14 @@ end context "GET #new" do - it "returns http success" do + it "returns http success and shows a form for new calculator" do get new_account_calculator_path expect(response).to be_successful end end context "GET #edit" do - it "returns http success" do + it "returns http success and shows a form for edit calculator" do get edit_account_calculator_path(calculator) expect(response).to be_successful From 6cbd864c711806af88e65ee54139b9cdce9fe85e Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 23:02:27 +0300 Subject: [PATCH 21/63] add test for calculate service --- app/services/calculators/calculate_service.rb | 2 +- spec/factories/calculate_services.rb | 0 spec/factories/prices.rb | 2 +- spec/services/calculators/calculate_spec.rb | 30 +++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 spec/factories/calculate_services.rb create mode 100644 spec/services/calculators/calculate_spec.rb diff --git a/app/services/calculators/calculate_service.rb b/app/services/calculators/calculate_service.rb index be5ee913f..f9910e25e 100644 --- a/app/services/calculators/calculate_service.rb +++ b/app/services/calculators/calculate_service.rb @@ -19,7 +19,7 @@ def initialize(product, params) end def calculate - money_spent = (selected_price * period).to_i + money_spent = (product.default_usage_per_day * selected_price * period).to_i items_used = (product.default_usage_per_day * period).to_i { diff --git a/spec/factories/calculate_services.rb b/spec/factories/calculate_services.rb new file mode 100644 index 000000000..e69de29bb diff --git a/spec/factories/prices.rb b/spec/factories/prices.rb index 5a4fe0032..1d323d2f3 100644 --- a/spec/factories/prices.rb +++ b/spec/factories/prices.rb @@ -21,7 +21,7 @@ association :priceable, factory: [:product, :diaper] trait :budgetary_price do - sum { 40.2 } + sum { 40 } end trait :invalid_price do diff --git a/spec/services/calculators/calculate_spec.rb b/spec/services/calculators/calculate_spec.rb new file mode 100644 index 000000000..a7f067b31 --- /dev/null +++ b/spec/services/calculators/calculate_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe Calculators::CalculateService do + DAYS = { # rubocop:disable Lint/ConstantDefinitionInBlock + "day" => 1, + "week" => 7, + "month" => 30.5, + "year" => 365 + }.freeze + + let(:product) { create(:product, :diaper, default_usage_per_day: 3) } + let(:category) { create(:category, :budgetary) } + let(:price) { create(:price, :budgetary_price, priceable: product, category: category) } + let(:valid_params) { { period: "week", price_id: price.id } } + + let(:money_spent) { price.sum.to_i * product.default_usage_per_day * DAYS[valid_params[:period]] } + let(:items_used) { product.default_usage_per_day * DAYS[valid_params[:period]] } + + it "calculates correctly" do + calculate_service = Calculators::CalculateService.new(product, valid_params) + + result = calculate_service.calculate + + # Your expectations here + expect(result[:moneySpent]).to eq(money_spent) + expect(result[:itemsUsed]).to eq(items_used) + end +end From 412b789841c05c26c70f6a8636bbc459cfeb020c Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Sun, 6 Aug 2023 23:46:53 +0300 Subject: [PATCH 22/63] add addiction test for destroying category which have prices --- app/helpers/calculators_helper.rb | 4 ++++ app/services/calculators/calculate_service.rb | 2 +- app/views/account/calculators/show.html.erb | 2 +- config/locales/en/en.yml | 2 +- config/locales/uk/uk.yml | 2 +- spec/requests/categories_spec.rb | 17 +++++++++++++---- spec/services/calculators/calculate_spec.rb | 5 +---- 7 files changed, 22 insertions(+), 12 deletions(-) diff --git a/app/helpers/calculators_helper.rb b/app/helpers/calculators_helper.rb index 4dbc53c59..b9ecd71bf 100644 --- a/app/helpers/calculators_helper.rb +++ b/app/helpers/calculators_helper.rb @@ -30,4 +30,8 @@ def use_period [I18n.t("calculators.date.year"), "year"] ] end + + def product_prices(calculator) + calculator.product.prices.map { |price| [price.category.name, price.id] } + end end diff --git a/app/services/calculators/calculate_service.rb b/app/services/calculators/calculate_service.rb index f9910e25e..45e66cc70 100644 --- a/app/services/calculators/calculate_service.rb +++ b/app/services/calculators/calculate_service.rb @@ -31,6 +31,6 @@ def calculate private def selected_price - product.prices.find_by(category_id: params[:price_id]).sum + product.prices.find(params[:price_id]).sum end end diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index a0f5f3a73..464b16dd4 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -23,7 +23,7 @@ <%= t("calculators.form.price") %> <%= form.input_field :product_category, - collection: @calculator.product.categories_by_prices, + collection: product_prices(@calculator), prompt: '__', label: t('.form_price'), class: 'form_fild price_select rounded w-100', diff --git a/config/locales/en/en.yml b/config/locales/en/en.yml index 9f8850622..9cc6c30bd 100644 --- a/config/locales/en/en.yml +++ b/config/locales/en/en.yml @@ -197,7 +197,7 @@ en: add_category_button: 'Add category' confirm_delete: 'Delete category?' destroy: - relation_error: 'Please remove prices with this category in next products: ' + relation_error: 'Please remove prices with this category in next products:' products: table: title: 'Title' diff --git a/config/locales/uk/uk.yml b/config/locales/uk/uk.yml index 18289069f..e1728edae 100644 --- a/config/locales/uk/uk.yml +++ b/config/locales/uk/uk.yml @@ -175,7 +175,7 @@ uk: add_category_button: 'Додати категорію' confirm_delete: 'Видалити категорію?' destroy: - relation_error: 'Будь ласка видаліть ціни з цією категорією з наступних продуктів: ' + relation_error: 'Будь ласка видаліть ціни з цією категорією з наступних продуктів:' products: attributes: default_usage_per_day: Використання в день за замовчуванням diff --git a/spec/requests/categories_spec.rb b/spec/requests/categories_spec.rb index 360cde08f..28b9cb8e9 100644 --- a/spec/requests/categories_spec.rb +++ b/spec/requests/categories_spec.rb @@ -2,10 +2,14 @@ RSpec.describe Account::CategoriesController, type: :request do let!(:category) { create(:category, :budgetary) } + let!(:category_with_prices) { create(:category, :budgetary) } let(:valid_attributes) { { category: { name: "medium" }} } let(:invalid_attributes) { { category: { name: "" }} } let(:new_attributes) { { category: { name: "premium" }} } + let(:product) { create(:product, :diaper) } + let!(:price) { create(:price, :budgetary_price, priceable: product, category: category_with_prices) } + include_context :authorize_admin describe "GET :index" do @@ -79,13 +83,18 @@ end describe "DELETE :destroy" do - it "destroys the requested category" do - expect do - delete account_category_path(id: category) - end.to change(Category, :count).by(-1) + it "destroys the requested category which doesn't have prices" do + expect { delete account_category_path(category) }.to change(Category, :count).by(-1) expect(response).to redirect_to(account_categories_path) expect(flash[:notice]).to eq("Category was successfully destroyed.") end + + it "doesn't destroys the requested category which has prices" do + expect { delete account_category_path(category_with_prices) }.to change(Category, :count).by(0) + + expect(response).to redirect_to(account_categories_path) + expect(flash[:alert]).to eq("#{I18n.t("account.categories.destroy.relation_error")} #{product.title}") + end end end diff --git a/spec/services/calculators/calculate_spec.rb b/spec/services/calculators/calculate_spec.rb index a7f067b31..39bc5d7c2 100644 --- a/spec/services/calculators/calculate_spec.rb +++ b/spec/services/calculators/calculate_spec.rb @@ -19,11 +19,8 @@ let(:items_used) { product.default_usage_per_day * DAYS[valid_params[:period]] } it "calculates correctly" do - calculate_service = Calculators::CalculateService.new(product, valid_params) + result = Calculators::CalculateService.new(product, valid_params).calculate - result = calculate_service.calculate - - # Your expectations here expect(result[:moneySpent]).to eq(money_spent) expect(result[:itemsUsed]).to eq(items_used) end From 9dd58bda7c74a674b9dd149d31e1c53bd772224b Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Mon, 7 Aug 2023 00:12:30 +0300 Subject: [PATCH 23/63] create tests for api/v1/calculators --- spec/requests/api/v1/calculators_spec.rb | 101 +++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 spec/requests/api/v1/calculators_spec.rb diff --git a/spec/requests/api/v1/calculators_spec.rb b/spec/requests/api/v1/calculators_spec.rb new file mode 100644 index 000000000..a17f018ce --- /dev/null +++ b/spec/requests/api/v1/calculators_spec.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe Api::V1::CalculatorsController, type: :request do + DAYS = { # rubocop:disable Lint/ConstantDefinitionInBlock + "day" => 1, + "week" => 7, + "month" => 30.5, + "year" => 365 + }.freeze + + let(:product) { create(:product, :diaper, default_usage_per_day: 3) } + let(:category) { create(:category, :budgetary) } + let(:price) { create(:price, :budgetary_price, priceable: product, category: category) } + let(:calculator) { create(:calculator, :diaper_calculator, product: product) } + let(:valid_params) { { period: "week", price_id: price.id } } + + let(:money_spent) { price.sum.to_i * product.default_usage_per_day * DAYS[valid_params[:period]] } + let(:items_used) { product.default_usage_per_day * DAYS[valid_params[:period]] } + + let(:expected_result) do + { + moneySpent: money_spent, + itemsUsed: items_used + } + end + + let(:invalid_result) do + { + moneySpent: -1, + itemsUsed: -1 + } + end + + describe "POST /api/v1/calculators/slug}" do + context "when no year and no month values" do + let(:period_and_price_error_msg) do + { + error: I18n.t("calculators.errors.period_and_price_error_msg") + } + end + + it "renders preiod and price error" do + post api_v1_calculate_path(calculator) + + expect(response).to be_unprocessable + expect(response.body).to eq(period_and_price_error_msg.to_json) + end + end + + context "when no period value" do + let(:period_error_msg) do + { + error: I18n.t("calculators.errors.period_error_msg") + } + end + + it "renders period error" do + post api_v1_calculate_path(calculator), params: { price_id: price.id } + + expect(response).to be_unprocessable + expect(response.body).to eq(period_error_msg.to_json) + end + end + + context "when no price value" do + let(:price_error_msg) do + { + error: I18n.t("calculators.errors.price_error_msg") + } + end + + it "renders price error" do + post api_v1_calculate_path(calculator), params: { period: "week" } + + expect(response).to be_unprocessable + expect(response.body).to eq(price_error_msg.to_json) + end + end + + context "when get awaited values" do + include_context :app_config_load + + it "got the expected result" do + post api_v1_calculate_path(calculator), params: valid_params + + expect(response.body).to eq(expected_result.to_json) + end + end + + context "when get unawaited values" do + it "got the unexpected result" do + post api_v1_calculate_path(calculator), params: valid_params + + expect(response).to be_successful + expect(response.body).not_to eq(invalid_result.to_json) + end + end + end +end From e6ee05ac5fe5bd40a83dd54584e579dbf1c80747 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Mon, 7 Aug 2023 12:37:21 +0300 Subject: [PATCH 24/63] add redirect to all calculators after update --- app/controllers/account/calculators_controller.rb | 2 +- spec/requests/account/calculators_spec.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 1832016bc..46210abbe 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -31,7 +31,7 @@ def update @calculator = resourse if updater - redirect_to edit_account_calculator_path(slug: @calculator), notice: t("notifications.calculator_updated") + redirect_to account_calculators_path, notice: t("notifications.calculator_updated") else @products = products_collection render :edit, status: :unprocessable_entity diff --git a/spec/requests/account/calculators_spec.rb b/spec/requests/account/calculators_spec.rb index 08393e709..111e660fd 100644 --- a/spec/requests/account/calculators_spec.rb +++ b/spec/requests/account/calculators_spec.rb @@ -81,6 +81,7 @@ calculator.reload expect(calculator.name).to eq("Updated Calculator") + expect(response).to redirect_to(account_calculators_path) expect(flash[:notice]).to eq(I18n.t("notifications.calculator_updated")) end From 081147b8a6cb85545b2ffc1fd832219f2e01fb08 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Mon, 7 Aug 2023 20:02:50 +0300 Subject: [PATCH 25/63] change image on 'items used' --- app/assets/images/thrash_produced.png | Bin 0 -> 5720 bytes app/views/account/calculators/show.html.erb | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 app/assets/images/thrash_produced.png diff --git a/app/assets/images/thrash_produced.png b/app/assets/images/thrash_produced.png new file mode 100644 index 0000000000000000000000000000000000000000..6849318df175866748d1c6e7dbbcc7593c1e5c39 GIT binary patch literal 5720 zcmV-e7N_ZnP)Py05=lfsRCr$PU2AL|Ret}SnYnL2uAhlX0Nb#!9fytGEozBYi5E7osH!Nc)RjtA zl9gI%KU5?FDp6G;s2`9P5M)2>$0n>qrLI%~+O}vnfjC_$+ZB{Jkl@$}u|uBr_2c^5 z_dPSG`k%RTJ$F2FXU31LRP`Xs@x3!==KSXOfB(vkcT18qB+K$% z07(GdoOAk3Kjug?#?qYgw65zHD*qlE7#JAcjE74=GDUtB009ZcFwKEcuJP;U{7hzh znT{dOV6yguvdWIS0ejB?9UmVbQ559>=X`{IHVO!1j6faJH0{In0Q}ae{cm%yBMeCE zV8;QBzI<@h^+EmQ*CRs=`Vq$1^8$SEV=o^3uh;DB*it}E5OrNYVluB>E+Z5QdE)8! zxXMJ+1hA%QuMG?gc8S7Ja59|fHzO?e+Qhsz%~8o%Rl(dJBBLQgfTuo-Yv`W3A=7IfiQpDFGZiP(Loj9 zt)F|%Q*Q~3v6G|Dd%ktPoH~z>Z@+@h*x>Y|ZGZPYKZeT-NbC1+ zo;q-bjFhafo^=5_IXOARxv+G?H?y-!*L6seB-mvaS0^!Fd-H}WFwQrB8+tT|9yaH_ zkv)g8`IC68^Ch%LcTKCR`t0D~;8+mQ>K$vclyqreK(AiC`n;xTq=2g;Zh}TY(!ZUI zjul7(yB@Fv9L*&j7C0m(tyzy><3=Zbn)(^$i<9`lPGL7_qyZf1>+5@WGeCX&%t%sG z`4l)l2n1+FUsmtR%1+X4rki60%PO`ekk-$f7G!0%0j$AJlda}Ce%-LMcmD|?DUN-e zFN#x_N;h$B`4m#cOCJ=q41pVXa8`UdpMl`F66y1vHMD3wYzex+US zSq+gFkoHxX$FI&o>Se8=@&fjk-~27M$An4xas<`Pm!4 z+JBNs>=|ExR>XXbqwHjn?FPt8y#21qR0B?i&T9?=bZ6o*47V9U%@zXsyeFU)14O=7 z%^={cE=)aU+RrVhY240!hPlFJWQsRX(3ZftZg|CZ*R=8(V-lirGa5rX(HY;3?TPP* zzpdAGi^4v-aRlwrzA8hPN;mM?+|O!mtE}hKD$n^Af6g)X(!sOOnv;;FXAIqS0VUT+ zk|c5os`)_z(qy3AHYUOiU0n zMSjr9DG#b2OIj9l`OBCuOkln+iIvg}n507vF-R3a1(+5@1;!lEbq=je$jV5BI?)#E z6Rc~E>=K}w_h=6U==1aQCvh`-PFQ&|PHuzp0K0bWs_I2ARbqZ$NtjH5^W(07x)~u8 zL=ty$kNm{t=7pDvH*s_298&qOuu{4sfP@x?B1IuH%0L;ut92OH)1mP)RJ{PmB>`+h zxC4y%s{1Cm3Pt?VUbAGhHzrV(l@dEZIzaBXxF@A!p z?0b%YRz!WuoXE)yqJ;;s+C^jf0l1!PLMuvD4`3zbnW>S&2Pgr4Td(H8APL~e9lcUjNj^sRpo!0+pP$qOHP zFg-z{skcran1T*aj=&L6tEf8}BPX%axn>v^;ffo6BO}H^LP1?ZrhEgb+&FG!KZP96 zLoI0tX>Hh^*o$Pe2Qj4;3X6i%JZ20pvP=YM9tCX?>B1E5W-p*D&qE2z&~h>CNIZ&; z_yC$h_amw_gF`od=v?|w1O*INGyjQ+rC(yG?GWxy?5hiE5Yac;sdIMt@1Gn!xdzbj z@$o~FB%QE}oz*8KSI9m}+A>sLfTnAP5){ghL1GG4N_TNL_dkM}+43Biq=D-)l96ug zY~`+o5w6V5Vhb zg5mU_=)sVKuj+a1-~Nw?EA4ebtr)1fr54hi;SfJ#va@1CYv-Mqm>^NFvFg?ZTE(20 zsOcpXwKOutn<(lTA+oE-8w|~rQ<%wpfoyq(a04BpNMSUDy3iTlBNnGatuTD;IweU4 z<1%vU9AwM7*)akyyKG!s#2`1+vbyv+`)iBhFo%J4LS<54<&Isn+Ss6o4OMyYIx-q6ZLk6X! ztw7_Ys;^0+D6}8$BkluKUDppgW&W*TnxbAMkrgmIJMCcFjZj(3VX5>DX7d+uJ@Xqh zwCN}nG-&E-wurO?;X$8~I9pvU5^>XI^0X8LdBt^doJTSISPK2kYsd;iI4UE%Amf3? z@1i5R2g%3-xRE=DON+k{F4V5(KXtYIc3pbx{gGs2gZ=^-J3`M)YJFA6axK&LZj5Ngb$nA4!Dv?@T78I-Ujepd)n6ABrgf>FQqHAGOc3Yc*Y ztJWQKjYBQzpx^YdqDY9uWt1{8;SF@g_6Q$Vks_cR>ABfAkyqyhTX!b*VS8){&0*5# ztAljuzfb=SBt<$vKyr>GIL34cBeW(3SY65Fz?7S^{V(t|JoD@VX}!z~Ir>|w6q76D9>p=w2x^b8h@ zQ@E4;3_QFf43<>vz_*f5qdnFS8DYp$*l^_>@~f0Ep%|YcxH7K-h?v}l`TUjFa{64| zy1ls`L6(V$i9Z8C8F<&>$B8HLA4{D;Id)U%JCLv1+M3K`vG@tj&$`b`Yu;W z3r}Jya|%c-2p24r--)4)!@>*L$nfJr)d1>8-2DJbNskMupF@k?HUKTOp{MBys^tjB z-H91)3$+61mL{ZgDcmIS&XwnpDtv`&OQ(UD0jQk64|_ZQ8cpGy8^M!|-0}YYeqS|w zlc6=fr_P1#>M&fpvLZq>=5#;=xu%i?Xdv?D8=ifcg?t*TrAR6vSf6UP_#vU zEe8b$q#tD=rV^7yx124J~#3$heNd$eDKj5G+WOz{><`m*>tEH$Dj zvIAi`E?glxmvX3@UO;1b2VzQ_IEHjN8N=D!C0t(_-3madD$(8B+goiSbH&L^e>$b@ z+$M7al(Iq;4H2_4rQ5Jm)OYx4roEn+BTv!1nfp|}D%K0ba-k|b*Ba~%Y#pHhZ9po2(+ zI)wW{KvMc{CU*gGr2~VlKSVP6ptyFnG>hxYXN4O^BN=%R4>le^BHStdP8Y7@(!#$Y zr>3wizE`C0DAPm^dZus}i{%MiTl#oQ7^>?!HKKX8@34u939{~FIeNyPax*)O+@p#VYfGoFSh{8a8t%nI$tSCB5BZrFQYS^GzpLR7gge#| z+k=SQfR)lL=7g2s8irCYYF}U9uonizP)`eQPU2sV(H zpn)R6dMw>aK*9U>jiWZLQk<&zkvF-@{WF&C9Ss}K!-XGiDI4A%3F<+8=$5RB`fbH@}a_g7;ODZ z5z7ZrT`olOZRM-oA@vw(y&)&VWH{baj>(aZm=P%zeY#D40JXYJ^>pYX?SF;l@B>vV zZ&zb}rO|L51$4bSlv;5pR`>El?SM8#x;CUkTVp+S8+`qM$~phAzrWuzqGXpZ zUw(%%_JY@>c81dN)~9V)VdwPSdKgNKZ;AB66nR4et~vUl_rl8i&51IGh<&j{4_y!i;~RGg96&1bmH5VSbn8EgDFamSYmm*mH%SyU98w* z`FkMpzQRtz$pm!6DZC(7ekOYXck^Sg0!rs+igz%b`4|h8^j&N8VRSb=QR9c2fKm;8 zTO~Q-7f`R{P95p=Wss_XUcP*pwk^MHpD?J4K@7dL@GmGwZ`ah6YK>AQeV6@QWSfS! z{Rqjh;fIR!UFH<5BH!C|P&9!FqgR~5*z5@r%XcLz>AUD2S3h*KYD#V`IgWlgeK<8W zl`NG?B=&2DlQ9bFHf>8hB1#~X51q|^i95OTm@SMUCbeUz<3}Q^BmlJ}n2Alv$V1fx zGks4$kEQ+@d3_F@(IIrjhtUx?@}XWvNwCMEx4_H0q3?tAi&{HJ>L!}~+)RBP+Admm zNSssoap8}~DAMuhe5Eemg-6<+L$XpvHeDyHk@aF|5OJ^SP>a};`&6^5*m`lhBX7SMVyFQq z=}>^>ThT*xc~M4ggDfe~xGHvn5I9tCr$QaI=+L14B-#<8=|usk#KL0dhgr8LhEsu# zS|3AF6T(u1F{iGI(lizSs4B`uT^^#*fdDm=BPK)rM17UD`HJ7IIN19`9V?)ItDaP? z{BrI+l%uzdX0d#WC=++a2Zh)YfX3jWsX=t;Nz_EPI*fj)%0^kSYp%9iT68E=x2TxQ zxP6+7ntG{>JiUAdJhmvhNkWAkc%=O~Q9Tvx38+K;Ryth)tr#aqmioCF661?=zd%O6 zB3c+(xe;CQ@1Q;2FA@|Hsj<56$c$Lbet5B;Q?w>h*R!#B-PoX1X`nSWNf^yuX4GSJ zM^c@h`c&ug6S$N696XePrg1b&-@;(~U(~cH2FTj4Yu}PnkG&&H{Q$aLx{WL8{}654 zDhi^Vks7tAOuS9>W^Su)g0*mR^}Q12R_@A|#vY|gzrI0iqk*xyZQS^tn$%|U7qM8N zjbt;>QHH|eLU-><{s|hx_j#$xHQ%p?oi#etoUy`E@!E%=cR>wXx3a&(T>dMgSwSg7 zS0yBr?P!nndG)jhyV$#=N=VN^bxCLKS#YuBy~ zy^F*%+v=1!33{Wxkn!*ngI+V}@$0qf_O*EeT48F{l?sw9@e8Dvp$ZC4K#NYv4_~c{ ze%9j)P?~6BVuCg}i8m8&_NWI~5HQVS{dNn|I&@v9_v8iIPE>FGz5#UuHOPX!+@Ce# zQzuk(x^564w*pMlfeA!7w~ptaz^<2-)sVIFst&8V@Zqpm*SeWv?%T?{A?*aJQ<<60 zx5v))`lXyI1m?VUKXN0TAnSQ+gJ0GK5_#*S6_<+k)z`eP&3cSeBErs0J5cpl=9bt9 zl8&oHL7Vc*VMi6_7kQ`SXiE+N@&JUfva-nyn0t9ljVKy#z@_clo^Qb22qx=hsEw`k z76^KyZTD&>$e7yB9xI?uRe;sh-0F)6&1*S{xes>I3$c&7z43M<;B7iXZJ-icO<-%H z6eqU2=|=klaZ@2afjnL)6y6yg9`^l$tBnG@DGYT0mejyAR8H}+a9=NKbz-~A;)#*> z97ywCHXTrN;);Hyml{wbn$yenH%f+@^Qk(i>-vZJeE#IUWTbr&TL!50LiGMTUDpZR zXT0`A1wpy;M)0%r`t{a+TM(I_#N0N%?OBeg((J62mO=aLSj zch!&4|8aqHK2|6c#(tknbOZRF16uD%SJXt!AzSU{_+_5o
<% [{ image: "money_spent_2.png", data_target: "moneySpentResult", unit: t("calculators.results.money"), text: t("calculators.results.spent") }, - { image: "money_to_spent_2.png", data_target: "itemsUsedResult", unit: t("calculators.results.unit"), text: t("calculators.results.used") }].each do |item| %> + { image: "thrash_produced.png", data_target: "itemsUsedResult", unit: t("calculators.results.unit"), text: t("calculators.results.used") }].each do |item| %>
<%= image_tag item[:image], class: "img-margin" %>

000

From 485a6569e7a06a0f0813375c25db604a50ffb3b8 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Mon, 7 Aug 2023 20:56:20 +0300 Subject: [PATCH 26/63] add to seeds creating a calculator with related objects --- app/views/account/calculators/show.html.erb | 2 +- db/seeds.rb | 18 ++++++++---------- spec/factories/prices.rb | 6 +++++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index 0266e9e57..b072661ba 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -11,7 +11,7 @@
- <%= "#{@calculator.product.title} calculator" %> + <%= "#{@calculator.product.title} calculator".capitalize %>
<%= t("calculators.form.period") %> diff --git a/db/seeds.rb b/db/seeds.rb index 96dd56a24..cd2791560 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -29,15 +29,13 @@ ) end -FactoryBot.create(:product_type, :hygiene) -FactoryBot.create(:product, :diaper) +# Create a calculator with related objects +bud_category = Category.find_or_create_by(name: "budgetary") +mid_category = Category.find_or_create_by(name: "medium") -FeatureFlag.find_or_create_by!( - name: "feature_budget_category", - enabled: false -) +product = Product.find_or_create_by(title: "Napkin") -FeatureFlag.find_or_create_by!( - name: "show_admin_menu", - enabled: false -) +bud_price = Price.find_or_create_by(priceable: product, category: bud_category, sum: 7) +mid_price = Price.find_or_create_by(priceable: product, category: mid_category, sum: 15) + +calculator = Calculator.find_or_create_by(name: "Napkins Calculator", product: product) diff --git a/spec/factories/prices.rb b/spec/factories/prices.rb index 1d323d2f3..3e01dee7c 100644 --- a/spec/factories/prices.rb +++ b/spec/factories/prices.rb @@ -21,7 +21,11 @@ association :priceable, factory: [:product, :diaper] trait :budgetary_price do - sum { 40 } + sum { 7 } + end + + trait :medium_price do + sum { 15 } end trait :invalid_price do From 70ae9963d27a96348eae3c780ad9f3294dc18e41 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Mon, 7 Aug 2023 21:03:16 +0300 Subject: [PATCH 27/63] rubocop fixes --- db/seeds.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db/seeds.rb b/db/seeds.rb index cd2791560..25b6ebc22 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -35,7 +35,7 @@ product = Product.find_or_create_by(title: "Napkin") -bud_price = Price.find_or_create_by(priceable: product, category: bud_category, sum: 7) -mid_price = Price.find_or_create_by(priceable: product, category: mid_category, sum: 15) +Price.find_or_create_by(priceable: product, category: bud_category, sum: 7) +Price.find_or_create_by(priceable: product, category: mid_category, sum: 15) -calculator = Calculator.find_or_create_by(name: "Napkins Calculator", product: product) +Calculator.find_or_create_by(name: "Napkins Calculator", product: product) From c8c24bed2146c588249a89393d42dcbe1a631290 Mon Sep 17 00:00:00 2001 From: AndriyAndriyovuch Date: Wed, 9 Aug 2023 17:17:13 +0300 Subject: [PATCH 28/63] add some extra lines, remove migration for deleting all prices without products (I'll move it into separate PR), remove required statement from product --- app/controllers/account/calculators_controller.rb | 2 ++ app/controllers/account/products_controller.rb | 2 ++ app/models/product.rb | 4 ++-- .../20230806130723_remove_prices_without_categories.rb | 9 --------- db/schema.rb | 2 +- 5 files changed, 7 insertions(+), 12 deletions(-) delete mode 100644 db/migrate/20230806130723_remove_prices_without_categories.rb diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 46210abbe..f76ff69df 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -23,6 +23,7 @@ def create redirect_to account_calculators_path, notice: t("notifications.calculator_created") else @products = products_collection + render :new, status: :unprocessable_entity end end @@ -34,6 +35,7 @@ def update redirect_to account_calculators_path, notice: t("notifications.calculator_updated") else @products = products_collection + render :edit, status: :unprocessable_entity end end diff --git a/app/controllers/account/products_controller.rb b/app/controllers/account/products_controller.rb index c2d3f0e77..32411cb9d 100644 --- a/app/controllers/account/products_controller.rb +++ b/app/controllers/account/products_controller.rb @@ -26,6 +26,7 @@ def create redirect_to account_products_path, notice: t(".created") else @product.prices.build + render :new, status: :unprocessable_entity end end @@ -37,6 +38,7 @@ def update redirect_to account_products_path, notice: t(".updated") else @product.prices.build + render :edit, status: :unprocessable_entity end end diff --git a/app/models/product.rb b/app/models/product.rb index e7cb924a2..e0f4ead5b 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -19,9 +19,9 @@ class Product < ApplicationRecord DIAPER = "diaper" - scope :ordered, -> { order(title: :asc) } + scope :ordered, -> { order(:title) } - has_one :calculator, required: false, dependent: :destroy + has_one :calculator, dependent: :destroy has_many :prices, as: :priceable, dependent: :destroy has_many :categories_by_prices, through: :prices, source: :category diff --git a/db/migrate/20230806130723_remove_prices_without_categories.rb b/db/migrate/20230806130723_remove_prices_without_categories.rb deleted file mode 100644 index dadae3e57..000000000 --- a/db/migrate/20230806130723_remove_prices_without_categories.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemovePricesWithoutCategories < ActiveRecord::Migration[6.1] - def change - categories = Category.pluck(:id) - - Price.all.each do |price| - price.destroy unless categories.include?(price.category_id) - end - end -end diff --git a/db/schema.rb b/db/schema.rb index 26ce45871..3b344791e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_08_06_130723) do +ActiveRecord::Schema.define(version: 2023_07_29_140507) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" From acd065599cf3d5f51ac19f94f091e56baa4923e8 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Tue, 21 Nov 2023 14:49:45 +0200 Subject: [PATCH 29/63] fix turbo in delete methods --- app/assets/stylesheets/pages/feature_flags.scss | 8 ++++++++ app/controllers/account/calculators_controller.rb | 4 ++-- app/javascript/controllers/application.js | 2 ++ app/views/account/calculators/index.html.slim | 3 +-- app/views/account/categories/index.html.slim | 2 +- app/views/account/products/index.html.slim | 2 +- app/views/account/site_settings/edit.html.slim | 2 +- app/views/account/users/index.html.slim | 3 +-- app/views/devise/sessions/new.html.slim | 2 +- app/views/layouts/_flash_messages.html.slim | 2 +- spec/factories/products.rb | 6 +++--- 11 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app/assets/stylesheets/pages/feature_flags.scss b/app/assets/stylesheets/pages/feature_flags.scss index 0f74fc90b..85080bcf0 100644 --- a/app/assets/stylesheets/pages/feature_flags.scss +++ b/app/assets/stylesheets/pages/feature_flags.scss @@ -57,6 +57,14 @@ input[type="submit"] { .btn-revert { background-color: rgb(255, 65, 65) !important; + border: none; + border-radius: 4px; + color: #fff; + cursor: pointer; + font-size: 16px; + padding: 10px; + min-width: 110px; + &:hover { background-color: darkred !important; diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 9bc99b194..8f7ea86d1 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -46,8 +46,8 @@ def update end def destroy - @calculator = resourse - @calculator.destroy! + # @calculator = resourse + # @calculator.destroy! redirect_to account_calculators_path, notice: t("notifications.calculator_deleted") end diff --git a/app/javascript/controllers/application.js b/app/javascript/controllers/application.js index 4fe698713..509227510 100644 --- a/app/javascript/controllers/application.js +++ b/app/javascript/controllers/application.js @@ -1,9 +1,11 @@ import { Application } from "@hotwired/stimulus" +import { Turbo } from "@hotwired/turbo-rails"; import toastr from "toastr"; window.toastr = toastr const application = Application.start() +Turbo.start(); // Configure Stimulus development experience application.debug = false diff --git a/app/views/account/calculators/index.html.slim b/app/views/account/calculators/index.html.slim index 92b8b820f..97ab3e910 100644 --- a/app/views/account/calculators/index.html.slim +++ b/app/views/account/calculators/index.html.slim @@ -28,6 +28,5 @@ i.fa.fa-eye.mx-2 = link_to edit_account_calculator_path(slug: calculator) do i.fa.fa-pen.mx-2 - = link_to account_calculator_path(slug: calculator), method: :delete, - data: { confirm: t('.confirm_delete') } do + = link_to account_calculator_path(slug: calculator), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do i.fa.fa-trash.mx-2 diff --git a/app/views/account/categories/index.html.slim b/app/views/account/categories/index.html.slim index b987b6b34..e82fe7d3f 100644 --- a/app/views/account/categories/index.html.slim +++ b/app/views/account/categories/index.html.slim @@ -24,5 +24,5 @@ div class="container home" div.d-flex = link_to edit_account_category_path(id: category) do i.fa.fa-pen.mx-2 - = button_to account_category_path(id: category), method: :delete, data: { confirm: t('.confirm_delete') } do + = button_to account_category_path(id: category), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do i.fa.fa-trash.mx-2 diff --git a/app/views/account/products/index.html.slim b/app/views/account/products/index.html.slim index 2ab118f2b..7a17aaaff 100644 --- a/app/views/account/products/index.html.slim +++ b/app/views/account/products/index.html.slim @@ -26,5 +26,5 @@ td.actions = link_to edit_account_product_path(id: product) do i.fa.fa-pen.mx-2 - = link_to account_product_path(id: product), method: :delete, data: { confirm: t('.confirm_delete') } do + = link_to account_product_path(id: product), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do i.fa.fa-trash.mx-2 diff --git a/app/views/account/site_settings/edit.html.slim b/app/views/account/site_settings/edit.html.slim index 040642bc4..a8541b8cb 100644 --- a/app/views/account/site_settings/edit.html.slim +++ b/app/views/account/site_settings/edit.html.slim @@ -13,7 +13,7 @@ fieldset.bordered = f.submit t(".apply_button") - = button_to t("buttons.revert"), revert_account_site_setting_path, onclick: "return confirm('#{j(t('.confirm_default'))}')", class: "btn-revert position-absolute right-bottom" + = button_to t("buttons.revert"), revert_account_site_setting_path, data: { turbo_confirm: t('.confirm_default') }, class: "btn-revert position-absolute right-bottom" fieldset.bordered legend.admin-legend diff --git a/app/views/account/users/index.html.slim b/app/views/account/users/index.html.slim index 762c909ce..983cd1029 100644 --- a/app/views/account/users/index.html.slim +++ b/app/views/account/users/index.html.slim @@ -29,6 +29,5 @@ div class="container home" td = link_to (icon('fa-solid', user.blocked? ? 'lock' : 'lock-open')), account_user_path(id: user, user: {blocked: user.blocked? ? false : true}), onclick: "alert('Are you sure?')", method: :patch - td = link_to account_user_path(id: user), method: :delete, - data: { confirm: t('.confirm_delete') } do + td = link_to account_user_path(id: user), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do i.fa.fa-trash.mx-2 diff --git a/app/views/devise/sessions/new.html.slim b/app/views/devise/sessions/new.html.slim index ad1ca81fb..52b53111e 100644 --- a/app/views/devise/sessions/new.html.slim +++ b/app/views/devise/sessions/new.html.slim @@ -3,7 +3,7 @@ .card-block.p-4 h2.text-center.p-2 = t('.log_in') - = simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| + = simple_form_for(resource, as: resource_name, url: session_path(resource_name), turbo: true) do |f| - flash.each do |type, msg| .alert.alert-danger = msg diff --git a/app/views/layouts/_flash_messages.html.slim b/app/views/layouts/_flash_messages.html.slim index 00d3d6469..75babe4c6 100644 --- a/app/views/layouts/_flash_messages.html.slim +++ b/app/views/layouts/_flash_messages.html.slim @@ -3,4 +3,4 @@ = message button.close[type="button" data-dismiss="alert" aria-label="Close"] span[aria-hidden="true"] - | × + | × diff --git a/spec/factories/products.rb b/spec/factories/products.rb index 418b5a426..0f0d4eac8 100644 --- a/spec/factories/products.rb +++ b/spec/factories/products.rb @@ -19,15 +19,15 @@ FactoryBot.define do factory :product do trait :diaper do - title { "diaper" } + title { "diaper #{SecureRandom.hex(10)}" } end trait :napkin do - title { "napkin" } + title { "napkin #{SecureRandom.hex(10)}" } end trait :huggie do - title { "huggie" } + title { "huggie #{SecureRandom.hex(10)}" } end trait :invalid do From bc14bd4f8cbc9a1604c90f087e6f9e1c92e4014f Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Tue, 21 Nov 2023 15:40:37 +0200 Subject: [PATCH 30/63] Fixed devise errors and some tests --- Gemfile.lock | 14 +++++++------- app/controllers/account/calculators_controller.rb | 4 ++-- app/views/devise/sessions/new.html.slim | 3 --- app/views/layouts/_flash_messages.html.slim | 8 ++++---- config/initializers/devise.rb | 2 ++ spec/features/account/calculators_spec.rb | 4 ++-- spec/features/admin_login_spec.rb | 4 ++-- spec/requests/products_spec.rb | 2 +- 8 files changed, 20 insertions(+), 21 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5bc53bce6..b576725c6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,7 +100,7 @@ GEM autoprefixer-rails (10.4.15.0) execjs (~> 2) base64 (0.2.0) - bcrypt (3.1.16) + bcrypt (3.1.20) bigdecimal (3.0.2) bindex (0.8.1) bootsnap (1.9.3) @@ -160,7 +160,7 @@ GEM date (3.3.4) dentaku (3.4.2) concurrent-ruby - devise (4.8.1) + devise (4.9.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) @@ -266,7 +266,7 @@ GEM listen (3.7.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.21.4) + loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -302,7 +302,7 @@ GEM net-protocol net-ssh (7.0.1) nio4r (2.5.9) - nokogiri (1.15.4) + nokogiri (1.15.5) mini_portile2 (~> 2.8.2) racc (~> 1.4) oauth2 (1.4.7) @@ -420,9 +420,9 @@ GEM rack (>= 1.4) requestjs-rails (0.0.10) rails (>= 6.0.0) - responders (3.0.1) - actionpack (>= 5.0) - railties (>= 5.0) + responders (3.1.1) + actionpack (>= 5.2) + railties (>= 5.2) rexml (3.2.6) rspec-core (3.12.2) rspec-support (~> 3.12.0) diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 8f7ea86d1..9bc99b194 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -46,8 +46,8 @@ def update end def destroy - # @calculator = resourse - # @calculator.destroy! + @calculator = resourse + @calculator.destroy! redirect_to account_calculators_path, notice: t("notifications.calculator_deleted") end diff --git a/app/views/devise/sessions/new.html.slim b/app/views/devise/sessions/new.html.slim index 52b53111e..a62048d1d 100644 --- a/app/views/devise/sessions/new.html.slim +++ b/app/views/devise/sessions/new.html.slim @@ -4,9 +4,6 @@ h2.text-center.p-2 = t('.log_in') = simple_form_for(resource, as: resource_name, url: session_path(resource_name), turbo: true) do |f| - - flash.each do |type, msg| - .alert.alert-danger - = msg = f.input :email, class: 'form-control', autofocus: true, autocomplete: "email" = f.input :password, class: 'form-control', autocomplete: "current-password" = f.input :remember_me, as: :boolean, inline_label: true if devise_mapping.rememberable? diff --git a/app/views/layouts/_flash_messages.html.slim b/app/views/layouts/_flash_messages.html.slim index 75babe4c6..6fd7dc022 100644 --- a/app/views/layouts/_flash_messages.html.slim +++ b/app/views/layouts/_flash_messages.html.slim @@ -1,6 +1,6 @@ - flash_messages.each do |message_type, message| - .alert.alert-dismissible.fade.show.position-absolute.container-fluid.fixed-top class=(message_class_by_name(message_type)) + .alert.alert-dismissible.fade.show.position-absolute.container-fluid.d-flex.fixed-top class=(message_class_by_name(message_type)) = message - button.close[type="button" data-dismiss="alert" aria-label="Close"] - span[aria-hidden="true"] - | × + = button_to('', { type: 'button', 'data-dismiss': 'alert', 'aria-label': 'Close' }, method: :delete, class: 'close ms-2') do + span aria-hidden="true" class="ms-2" + | × diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index fd6620d43..9b5f16b9d 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -309,6 +309,8 @@ # When set to false, does not sign a user in automatically after their password is # changed. Defaults to true, so a user is signed in automatically after changing a password. # config.sign_in_after_change_password = true + config.responder.error_status = :unprocessable_entity + config.responder.redirect_status = :see_other end Devise::Async.setup do |config| diff --git a/spec/features/account/calculators_spec.rb b/spec/features/account/calculators_spec.rb index 4569ddd1e..bb3704caa 100644 --- a/spec/features/account/calculators_spec.rb +++ b/spec/features/account/calculators_spec.rb @@ -3,8 +3,8 @@ require "rails_helper" describe "visit admin page", js: true do - let!(:diaper) { create(:product, :diaper)} - let!(:napkin) { create(:product, :napkin)} + let!(:diaper) { create(:product, :diaper) } + let!(:napkin) { create(:product, :napkin) } let!(:diapers_calculator) { create(:calculator, name: "Diapers Calculator", slug: "diapers", product: diaper) } let!(:napkin_calculator) { create(:calculator, name: "Napkin Calculator", slug: "napkin", product: napkin) } diff --git a/spec/features/admin_login_spec.rb b/spec/features/admin_login_spec.rb index 5452925b9..7f7bcd3a7 100644 --- a/spec/features/admin_login_spec.rb +++ b/spec/features/admin_login_spec.rb @@ -63,8 +63,8 @@ it "redirect to admin page" do visit new_user_session_path click_on LANG_BUTTON_TEXT - fill_in "user_email", with: user.email - fill_in "user_password", with: user.password + fill_in "Електронна пошта", with: user.email + fill_in "Пароль", with: user.password sleep 0.5 click_button "Увійти" sleep 0.5 diff --git a/spec/requests/products_spec.rb b/spec/requests/products_spec.rb index 316cd6db6..fa3d225c6 100644 --- a/spec/requests/products_spec.rb +++ b/spec/requests/products_spec.rb @@ -97,7 +97,7 @@ expect do patch account_product_path(id: price.priceable), params: { product: updated_product_attributes } price.priceable.reload - end.to change(price.priceable, :title).from("diaper").to("huggie") + end.to change(price.priceable, :title).to(updated_product_attributes[:title]) expect(response).to redirect_to(account_products_path) expect(flash[:notice]).to eq(I18n.t("account.products.updated")) From 5addf7c6aa828c31814bac07ba4a4905cbf97646 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Tue, 21 Nov 2023 16:20:09 +0200 Subject: [PATCH 31/63] refactored category destroy method (add validator) --- .../account/categories_controller.rb | 14 ++++-------- app/validators/category_validator.rb | 22 +++++++++++++++++++ app/views/account/categories/index.html.slim | 2 +- 3 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 app/validators/category_validator.rb diff --git a/app/controllers/account/categories_controller.rb b/app/controllers/account/categories_controller.rb index a8d0c09e0..e620e7a40 100644 --- a/app/controllers/account/categories_controller.rb +++ b/app/controllers/account/categories_controller.rb @@ -39,20 +39,14 @@ def update def destroy @category = resource - prices = Price.where(category_id: @category.id) + validator = CategoryValidator.new(@category) - if prices.any? - products = [] - - prices.each do |price| - products << Product.where(id: price.priceable_id).pluck(:title) - end - - redirect_to account_categories_path, alert: "#{t(".relation_error")} #{products.join(", ")}" - else + if validator.valid? @category.destroy redirect_to account_categories_path, notice: t("notifications.category_deleted") + else + redirect_to account_categories_path, alert: "#{t(".relation_error")} #{validator.references}" end end diff --git a/app/validators/category_validator.rb b/app/validators/category_validator.rb new file mode 100644 index 000000000..1e41c83e8 --- /dev/null +++ b/app/validators/category_validator.rb @@ -0,0 +1,22 @@ +class CategoryValidator + attr_reader :category, :prices + + def initialize(category) + @category = category + @prices = Price.where(category_id: category.id) + end + + def valid? + prices.blank? + end + + def references + products = [] + + prices.each do |price| + products << Product.where(id: price.priceable_id).pluck(:title) + end + + products.join(", ") + end +end diff --git a/app/views/account/categories/index.html.slim b/app/views/account/categories/index.html.slim index e82fe7d3f..7b8e70839 100644 --- a/app/views/account/categories/index.html.slim +++ b/app/views/account/categories/index.html.slim @@ -24,5 +24,5 @@ div class="container home" div.d-flex = link_to edit_account_category_path(id: category) do i.fa.fa-pen.mx-2 - = button_to account_category_path(id: category), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do + = link_to account_category_path(id: category.id), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do i.fa.fa-trash.mx-2 From a74832b4791ea5352cdbf96855e07d3ba5d541b3 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Tue, 21 Nov 2023 16:21:56 +0200 Subject: [PATCH 32/63] rubocop fix --- app/validators/category_validator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/validators/category_validator.rb b/app/validators/category_validator.rb index 1e41c83e8..bf9b22208 100644 --- a/app/validators/category_validator.rb +++ b/app/validators/category_validator.rb @@ -3,7 +3,7 @@ class CategoryValidator def initialize(category) @category = category - @prices = Price.where(category_id: category.id) + @prices = Price.where(category_id: category.id) end def valid? From e895ef106705bae4ab5f3d9a0ca04a49129d70c5 Mon Sep 17 00:00:00 2001 From: AndriiAndriyovuch Date: Tue, 21 Nov 2023 16:44:58 +0200 Subject: [PATCH 33/63] fixed minor issues --- app/controllers/account/categories_controller.rb | 2 +- app/helpers/calculators_helper.rb | 7 +------ app/views/account/categories/index.html.slim | 2 +- app/views/account/products/index.html.slim | 2 +- app/views/devise/sessions/new.html.slim | 2 +- app/views/layouts/_flash_messages.html.slim | 2 +- spec/requests/categories_spec.rb | 2 +- 7 files changed, 7 insertions(+), 12 deletions(-) diff --git a/app/controllers/account/categories_controller.rb b/app/controllers/account/categories_controller.rb index e620e7a40..19456b2f3 100644 --- a/app/controllers/account/categories_controller.rb +++ b/app/controllers/account/categories_controller.rb @@ -46,7 +46,7 @@ def destroy redirect_to account_categories_path, notice: t("notifications.category_deleted") else - redirect_to account_categories_path, alert: "#{t(".relation_error")} #{validator.references}" + redirect_to account_categories_path, alert: "#{t(".relation_error")} #{validator.references}", status: :unprocessable_entity end end diff --git a/app/helpers/calculators_helper.rb b/app/helpers/calculators_helper.rb index b9ecd71bf..29124a6ee 100644 --- a/app/helpers/calculators_helper.rb +++ b/app/helpers/calculators_helper.rb @@ -23,12 +23,7 @@ def month_number(style) end def use_period - [ - [I18n.t("calculators.date.day"), "day"], - [I18n.t("calculators.date.week"), "week"], - [I18n.t("calculators.date.month"), "month"], - [I18n.t("calculators.date.year"), "year"] - ] + ["day", "week", "month", "year"].map { |period| [I18n.t("calculators.date.#{period}"), period] } end def product_prices(calculator) diff --git a/app/views/account/categories/index.html.slim b/app/views/account/categories/index.html.slim index 7b8e70839..17dcea415 100644 --- a/app/views/account/categories/index.html.slim +++ b/app/views/account/categories/index.html.slim @@ -24,5 +24,5 @@ div class="container home" div.d-flex = link_to edit_account_category_path(id: category) do i.fa.fa-pen.mx-2 - = link_to account_category_path(id: category.id), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do + = link_to account_category_path(id: category), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do i.fa.fa-trash.mx-2 diff --git a/app/views/account/products/index.html.slim b/app/views/account/products/index.html.slim index 7a17aaaff..d684b2d42 100644 --- a/app/views/account/products/index.html.slim +++ b/app/views/account/products/index.html.slim @@ -9,7 +9,7 @@ tr th scope="col" = sort_link(@q, :id, "#", default_order: :desc) th scope="col" = sort_link(@q, :title, t('.table.title'), default_order: :desc) - th scope="col" =t('.table.default_usage_per_day') + th scope="col" = t('.table.default_usage_per_day') th scope="col" = t('.table.prices') th scope="col" = t('.table.actions') diff --git a/app/views/devise/sessions/new.html.slim b/app/views/devise/sessions/new.html.slim index a62048d1d..49b21776c 100644 --- a/app/views/devise/sessions/new.html.slim +++ b/app/views/devise/sessions/new.html.slim @@ -3,7 +3,7 @@ .card-block.p-4 h2.text-center.p-2 = t('.log_in') - = simple_form_for(resource, as: resource_name, url: session_path(resource_name), turbo: true) do |f| + = simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| = f.input :email, class: 'form-control', autofocus: true, autocomplete: "email" = f.input :password, class: 'form-control', autocomplete: "current-password" = f.input :remember_me, as: :boolean, inline_label: true if devise_mapping.rememberable? diff --git a/app/views/layouts/_flash_messages.html.slim b/app/views/layouts/_flash_messages.html.slim index 6fd7dc022..e58d2da24 100644 --- a/app/views/layouts/_flash_messages.html.slim +++ b/app/views/layouts/_flash_messages.html.slim @@ -1,6 +1,6 @@ - flash_messages.each do |message_type, message| .alert.alert-dismissible.fade.show.position-absolute.container-fluid.d-flex.fixed-top class=(message_class_by_name(message_type)) = message - = button_to('', { type: 'button', 'data-dismiss': 'alert', 'aria-label': 'Close' }, method: :delete, class: 'close ms-2') do + = button_to({'data-dismiss': 'alert', 'aria-label': 'Close' }, method: :delete, class: 'close ms-2') do span aria-hidden="true" class="ms-2" | × diff --git a/spec/requests/categories_spec.rb b/spec/requests/categories_spec.rb index 28b9cb8e9..262e59c2f 100644 --- a/spec/requests/categories_spec.rb +++ b/spec/requests/categories_spec.rb @@ -93,7 +93,7 @@ it "doesn't destroys the requested category which has prices" do expect { delete account_category_path(category_with_prices) }.to change(Category, :count).by(0) - expect(response).to redirect_to(account_categories_path) + expect(response).to be_unprocessable expect(flash[:alert]).to eq("#{I18n.t("account.categories.destroy.relation_error")} #{product.title}") end end From d53eb190b031c21405acb09c969c1cfc7fabd030 Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 4 Aug 2024 01:30:39 +0300 Subject: [PATCH 34/63] convert calculators templates to erb --- app/views/account/calculators/edit.html.erb | 32 +++++++++++++ app/views/account/calculators/edit.html.slim | 19 -------- app/views/account/calculators/index.html.erb | 48 +++++++++++++++++++ app/views/account/calculators/index.html.slim | 32 ------------- app/views/account/calculators/new.html.erb | 32 +++++++++++++ app/views/account/calculators/new.html.slim | 19 -------- 6 files changed, 112 insertions(+), 70 deletions(-) create mode 100644 app/views/account/calculators/edit.html.erb delete mode 100644 app/views/account/calculators/edit.html.slim create mode 100644 app/views/account/calculators/index.html.erb delete mode 100644 app/views/account/calculators/index.html.slim create mode 100644 app/views/account/calculators/new.html.erb delete mode 100644 app/views/account/calculators/new.html.slim diff --git a/app/views/account/calculators/edit.html.erb b/app/views/account/calculators/edit.html.erb new file mode 100644 index 000000000..fde5da840 --- /dev/null +++ b/app/views/account/calculators/edit.html.erb @@ -0,0 +1,32 @@ +
+ <% if @calculator.errors.any? %> +
+

+ <%= t('activerecord.form_errors', count: @calculator.errors.count, + model: t('models.calculator').downcase) %> +

+
    + <% @calculator.errors.full_messages.each do |error_message| %> +
  • <%= error_message %>
  • + <% end %> +
+
+ <% end %> + + <%= simple_form_for @calculator, url: account_calculator_path do |f| %> +
+
+ <%= f.input :name, class: 'form-control' %> + <%= f.input :product_id, collection: @products, include_blank: false %> +
+
+ +
+ <%= f.button :submit, t('.form.update_calculator_button'), class: 'btn btn-success mr-2 height-auto w-auto' %> + <%= link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do %> + <%= t('.cancel_button') %> + + <% end %> +
+ <% end %> +
diff --git a/app/views/account/calculators/edit.html.slim b/app/views/account/calculators/edit.html.slim deleted file mode 100644 index 6f34ae210..000000000 --- a/app/views/account/calculators/edit.html.slim +++ /dev/null @@ -1,19 +0,0 @@ -.container - - if @calculator.errors.any? - div - h2 - = t('activerecord.form_errors', :count => @calculator.errors.count, - :model => t('models.calculator').downcase) - ul - - @calculator.errors.full_messages.each do |error_message| - li= error_message - = simple_form_for @calculator, url: account_calculator_path do |f| - .form-group.row - .col-12.has-float-label.my-auto - = f.input :name, class: 'form-control' - = f.input :product_id, collection: @products, include_blank: false - .div.d-flex - = f.button :submit, t('.form.update_calculator_button'), class: 'btn btn-success mr-2 height-auto w-auto' - = link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do - span.mr-1 = t('.cancel_button') - i.fa.fa-times-circle diff --git a/app/views/account/calculators/index.html.erb b/app/views/account/calculators/index.html.erb new file mode 100644 index 000000000..6020e8b03 --- /dev/null +++ b/app/views/account/calculators/index.html.erb @@ -0,0 +1,48 @@ +
+ <%= form_tag account_calculators_path, method: :get, class: 'd-flex justify-content-end mb-5' do %> +
+ <%= text_field_tag :search, params[:search], class: 'form-control me-sm-2', placeholder: t('.search_placeholder') %> + <%= button_tag type: :submit, name: nil, class: 'btn btn-primary px-4 d-flex align-items-center' do %> + + <%= t('.search_button') %> + <% end %> +
+ + <%= link_to new_account_calculator_path, class: 'btn btn-success px-4 ms-1' do %> + + <%= t('.add_calculator_button') %> + <% end %> + <% end %> + + + + + + + + + + + + + <% @calculators.each do |calculator| %> + + + + + + + <% end %> + +
<%= sort_link(@q, :id, "#", default_order: :desc) %><%= sort_link(@q, :slug, t('.table.calculator_slug'), default_order: :desc) %><%= sort_link(@q, :name, t('.table.calculator_name'), default_order: :desc) %><%= t('.table.calculator_actions') %>
<%= calculator.id %><%= calculator.slug %><%= calculator.name %> + <%= link_to account_calculator_path(slug: calculator) do %> + + <% end %> + <%= link_to edit_account_calculator_path(slug: calculator) do %> + + <% end %> + <%= link_to account_calculator_path(slug: calculator), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do %> + + <% end %> +
+
diff --git a/app/views/account/calculators/index.html.slim b/app/views/account/calculators/index.html.slim deleted file mode 100644 index 97ab3e910..000000000 --- a/app/views/account/calculators/index.html.slim +++ /dev/null @@ -1,32 +0,0 @@ -.container - = form_tag account_calculators_path, method: :get, class: 'd-flex justify-content-end mb-5' do - .d-flex - = text_field_tag :search, params[:search], class: 'form-control me-sm-2', placeholder: t('.search_placeholder') - = button_tag type: :submit, name: nil, class: 'btn btn-primary px-4 d-flex align-items-center' do - i.fa.fa-search.me-2 - span =t('.search_button') - = link_to new_account_calculator_path, class: 'btn btn-success px-4 ms-1' do - i.fa.fa-plus.me-2 - span =t('.add_calculator_button') - - table.table.admin-table - thead - tr - th[scope="col"] = sort_link(@q, :id, "#", default_order: :desc) - th[scope="col"] = sort_link(@q, :slug, t('.table.calculator_slug'), default_order: :desc) - th[scope="col"] = sort_link(@q, :name, t('.table.calculator_name'), default_order: :desc) - th[scope="col"] = t('.table.calculator_actions') - - tbody.admin-table-links - - @calculators.each do |calculator| - tr class=(calculator.preferable ? 'table-success' : 'table-light') - td= calculator.id - td= calculator.slug - td= calculator.name - td.actions - = link_to account_calculator_path(slug: calculator) do - i.fa.fa-eye.mx-2 - = link_to edit_account_calculator_path(slug: calculator) do - i.fa.fa-pen.mx-2 - = link_to account_calculator_path(slug: calculator), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do - i.fa.fa-trash.mx-2 diff --git a/app/views/account/calculators/new.html.erb b/app/views/account/calculators/new.html.erb new file mode 100644 index 000000000..3584d48eb --- /dev/null +++ b/app/views/account/calculators/new.html.erb @@ -0,0 +1,32 @@ +
+ <% if @calculator.errors.any? %> +
+

+ <%= t('activerecord.form_errors', count: @calculator.errors.count, + model: t('models.calculator').downcase) %> +

+
    + <% @calculator.errors.full_messages.each do |error_message| %> +
  • <%= error_message %>
  • + <% end %> +
+
+ <% end %> + + <%= simple_form_for @calculator, url: account_calculators_path do |f| %> +
+
+ <%= f.input :name, class: 'form-control' %> + <%= f.input :product_id, collection: @products, include_blank: false %> +
+
+ +
+ <%= f.button :submit, t('.create_calculator_button'), class: 'btn btn-success me-2 height-auto w-auto' %> + <%= link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do %> + <%= t('.cancel_button') %> + + <% end %> +
+ <% end %> +
diff --git a/app/views/account/calculators/new.html.slim b/app/views/account/calculators/new.html.slim deleted file mode 100644 index 62a4f6d55..000000000 --- a/app/views/account/calculators/new.html.slim +++ /dev/null @@ -1,19 +0,0 @@ -.container - - if @calculator.errors.any? - div - h2 - = t('activerecord.form_errors', :count => @calculator.errors.count, - :model => t('models.calculator').downcase) - ul - - @calculator.errors.full_messages.each do |error_message| - li= error_message - = simple_form_for @calculator, url: account_calculators_path do |f| - .form-group.row - .col-12.has-float-label.my-auto - = f.input :name, class: 'form-control' - = f.input :product_id, collection: @products, include_blank: false - .div.d-flex - = f.button :submit, t('.create_calculator_button'), class: 'btn btn-success me-2 height-auto w-auto' - = link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do - span.me-1 = t('.cancel_button') - i.fa.fa-times-circle From e27c50f94f9f5af99e074edd3dd2c4fac30ec8f5 Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 4 Aug 2024 18:04:21 +0300 Subject: [PATCH 35/63] convert categories template to erb --- app/views/account/categories/index.html.erb | 41 ++++++++++++++++++++ app/views/account/categories/index.html.slim | 28 ------------- 2 files changed, 41 insertions(+), 28 deletions(-) create mode 100644 app/views/account/categories/index.html.erb delete mode 100644 app/views/account/categories/index.html.slim diff --git a/app/views/account/categories/index.html.erb b/app/views/account/categories/index.html.erb new file mode 100644 index 000000000..e7fe49bc5 --- /dev/null +++ b/app/views/account/categories/index.html.erb @@ -0,0 +1,41 @@ +
+
+ <%= link_to new_account_category_path, class: 'btn btn-success px-4 ml-1 mb-2' do %> + + <%= t('.add_category_button') %> + <% end %> +
+ +
+ + + + + + + + + + + + <% @categories.each do |category| %> + + + + + + + <% end %> + +
<%= sort_link(@q, :id, "#", default_order: :desc) %><%= sort_link(@q, :name, t('.table.title'), default_order: :desc) %><%= sort_link(@q, :priority, t('.table.priority'), default_order: :desc) %><%= t('.table.actions') %>
<%= category.id %><%= category.name %><%= category.priority %> +
+ <%= link_to edit_account_category_path(id: category) do %> + + <% end %> + <%= link_to account_category_path(id: category), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do %> + + <% end %> +
+
+
+
diff --git a/app/views/account/categories/index.html.slim b/app/views/account/categories/index.html.slim deleted file mode 100644 index 17dcea415..000000000 --- a/app/views/account/categories/index.html.slim +++ /dev/null @@ -1,28 +0,0 @@ -.container - .d-flex.flex-row-reverse - = link_to new_account_category_path, class: 'btn btn-success px-4 ml-1 mb-2' do - i.fa.fa-plus.mr-2 - span =t('.add_category_button') - -div class="container home" - - table.table - thead - tr - th scope="col" = sort_link(@q, :id, "#", default_order: :desc) - th scope="col" = sort_link(@q, :name, t('.table.title'), default_order: :desc) - th scope="col" = sort_link(@q, :priority, t('.table.priority'), default_order: :desc) - th scope="col" = t('.table.actions') - - tbody - - @categories.each do |category| - tr - th scope="row" = category.id - td = category.name - td = category.priority - td.actions - div.d-flex - = link_to edit_account_category_path(id: category) do - i.fa.fa-pen.mx-2 - = link_to account_category_path(id: category), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do - i.fa.fa-trash.mx-2 From d41413d0996f228c69c512a850a82de72eb6f511 Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 4 Aug 2024 20:15:03 +0300 Subject: [PATCH 36/63] convert products templates to erb --- app/views/account/products/edit.html.erb | 30 +++++++++++++++ app/views/account/products/edit.html.slim | 20 ---------- app/views/account/products/index.html.erb | 43 ++++++++++++++++++++++ app/views/account/products/index.html.slim | 30 --------------- app/views/account/products/new.html.erb | 28 ++++++++++++++ app/views/account/products/new.html.slim | 18 --------- 6 files changed, 101 insertions(+), 68 deletions(-) create mode 100644 app/views/account/products/edit.html.erb delete mode 100644 app/views/account/products/edit.html.slim create mode 100644 app/views/account/products/index.html.erb delete mode 100644 app/views/account/products/index.html.slim create mode 100644 app/views/account/products/new.html.erb delete mode 100644 app/views/account/products/new.html.slim diff --git a/app/views/account/products/edit.html.erb b/app/views/account/products/edit.html.erb new file mode 100644 index 000000000..c601224d7 --- /dev/null +++ b/app/views/account/products/edit.html.erb @@ -0,0 +1,30 @@ +
+ <%= simple_form_for @product, method: :patch, url: account_product_path, data: { controller: "price-form" } do |f| %> +
+
+ <%= f.input :title, label: t('.title'), class: 'form-control col-sm-11' %> + <%= f.input :default_usage_per_day, label: t('.default_usage_per_day'), class: 'form-control col-sm-11' %> + <% if Category.ordered_by_name.exists? %> + <%= f.simple_fields_for :prices do |prices_form| %> +
+ <%= check_box_tag prices_form.object.category.name, 1, true, data: { price_form_target: 'checkbox', action: "click->price-form#removePrice click->price-form#togglePrice" }, class: 'me-1' %> + <%= label_tag prices_form.object.category.name %> +
+ <%= prices_form.input :sum, label: false, input_html: { placeholder: 'Sum', data: { price_form_target: 'priceInput' } } %> + <%= prices_form.hidden_field :category_id, value: prices_form.object.category.id %> + <%= prices_form.hidden_field :_destroy, data: { price_form_target: 'hiddenField' } %> +
+
+ <% end %> + <% end %> +
+ +
+ <%= f.submit t('buttons.create'), class: 'btn btn-success me-2' %> + <%= link_to account_products_path, class: 'btn btn-danger d-flex align-items-center' do %> + <%= t('buttons.cancel') %> + <% end %> +
+
+ <% end %> +
diff --git a/app/views/account/products/edit.html.slim b/app/views/account/products/edit.html.slim deleted file mode 100644 index daa20a43e..000000000 --- a/app/views/account/products/edit.html.slim +++ /dev/null @@ -1,20 +0,0 @@ -.container - = simple_form_for @product, method: :patch, url: account_product_path, data: { controller: "price-form" } do |f| - .form-group.row - .col-12.has-float-label.my-auto - = f.input :title, label: t('.title'), class: 'form-control col-sm-11' - = f.input :default_usage_per_day, label: t('.default_usage_per_day'), class: 'form-control col-sm-11' - - if Category.ordered_by_name.exists? - = f.simple_fields_for :prices do |prices_form| - .checkbox-blocks - = check_box_tag prices_form.object.category.name, 1, true, data: { price_form_target: 'checkbox', action: "click->price-form#removePrice click->price-form#togglePrice" }, class: 'me-1' - = label_tag prices_form.object.category.name - .hidden-sum data-price-form-target="price" name=prices_form.object.category.name - = prices_form.input :sum, label: false, input_html: { placeholder: 'Sum', data: { price_form_target: 'priceInput' } } - = prices_form.hidden_field :category_id, value: prices_form.object.category.id - = prices_form.hidden_field :_destroy, data: { price_form_target: 'hiddenField' } - - .div.d-flex.mt-2 - = f.submit t('buttons.create'), class: 'btn btn-success me-2' - = link_to account_products_path, class: 'btn btn-danger d-flex align-items-center' do - span.me-1 =t('buttons.cancel') diff --git a/app/views/account/products/index.html.erb b/app/views/account/products/index.html.erb new file mode 100644 index 000000000..406065fb6 --- /dev/null +++ b/app/views/account/products/index.html.erb @@ -0,0 +1,43 @@ +
+
+ <%= link_to new_account_product_path, class: 'btn btn-success px-4 ms-1' do %> + + <%= t('.add_product_button') %> + <% end %> +
+ + + + + + + + + + + + + + <% @products.includes(prices: :category).each do |product| %> + + + + + + + + <% end %> + +
<%= sort_link(@q, :id, "#", default_order: :desc) %><%= sort_link(@q, :title, t('.table.title'), default_order: :desc) %><%= t('.table.default_usage_per_day') %><%= t('.table.prices') %><%= t('.table.actions') %>
<%= product.id %><%= product.title %><%= product.default_usage_per_day %> + <% product.prices.includes(:category).each do |price| %> + <%= "#{price.category.name}: #{price.sum}" %>
+ <% end %> +
+ <%= link_to edit_account_product_path(id: product) do %> + + <% end %> + <%= link_to account_product_path(id: product), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do %> + + <% end %> +
+
diff --git a/app/views/account/products/index.html.slim b/app/views/account/products/index.html.slim deleted file mode 100644 index d684b2d42..000000000 --- a/app/views/account/products/index.html.slim +++ /dev/null @@ -1,30 +0,0 @@ -.container - .d-flex.justify-content-end.mb-5 - = link_to new_account_product_path, class: 'btn btn-success px-4 ms-1' do - i.fa.fa-plus.me-2 - span =t('.add_product_button') - - table.table - thead - tr - th scope="col" = sort_link(@q, :id, "#", default_order: :desc) - th scope="col" = sort_link(@q, :title, t('.table.title'), default_order: :desc) - th scope="col" = t('.table.default_usage_per_day') - th scope="col" = t('.table.prices') - th scope="col" = t('.table.actions') - - tbody - - @products.includes(prices: :category).each do |product| - tr - td = product.id - td = product.title - td = product.default_usage_per_day - td - - product.prices.includes(:category).each do |price| - span = "#{price.category.name}: #{price.sum}" - br - td.actions - = link_to edit_account_product_path(id: product) do - i.fa.fa-pen.mx-2 - = link_to account_product_path(id: product), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do - i.fa.fa-trash.mx-2 diff --git a/app/views/account/products/new.html.erb b/app/views/account/products/new.html.erb new file mode 100644 index 000000000..8e5fec012 --- /dev/null +++ b/app/views/account/products/new.html.erb @@ -0,0 +1,28 @@ +
+ <%= simple_form_for @product, url: account_products_path, data: { controller: "price-form" } do |f| %> +
+
+ <%= f.input :title, label: t('.title'), class: 'form-control col-sm-11' %> + <%= f.input :default_usage_per_day, label: t('.default_usage_per_day'), class: 'form-control col-sm-11' %> + <% Category.ordered_by_name.each do |category| %> +
+ <%= f.simple_fields_for :prices do |prices_form| %> + <%= check_box_tag category.name, 1, false, data: { action: "click->price-form#togglePrice", price_form_target: 'checkbox' }, class: 'me-1' %> + <%= label_tag category.name %> +
+ <%= prices_form.input :sum, label: false, input_html: { placeholder: 'Sum', data: { price_form_target: 'priceInput' } } %> + <%= prices_form.hidden_field :category_id, value: category.id %> +
+ <% end %> +
+ <% end %> +
+
+
+ <%= f.submit t('buttons.create'), class: 'btn btn-success me-2 w-auto' %> + <%= link_to account_products_path, class: 'btn btn-danger d-flex align-items-center' do %> + <%= t('buttons.cancel') %> + <% end %> +
+ <% end %> +
diff --git a/app/views/account/products/new.html.slim b/app/views/account/products/new.html.slim deleted file mode 100644 index 15296574d..000000000 --- a/app/views/account/products/new.html.slim +++ /dev/null @@ -1,18 +0,0 @@ -.container - = simple_form_for @product, url: account_products_path, data: { controller: "price-form" } do |f| - .form-group.row - .col-12.has-float-label.my-auto - = f.input :title, label: t('.title'), class: 'form-control col-sm-11' - = f.input :default_usage_per_day, label: t('.default_usage_per_day'), class: 'form-control col-sm-11' - - Category.ordered_by_name.each do |category| - .checkbox-blocks - = f.simple_fields_for :prices do |prices_form| - = check_box_tag category.name, 1, false, data: { action: "click->price-form#togglePrice", price_form_target: 'checkbox' }, class: 'me-1' - = label_tag category.name - .hidden-sum data-price-form-target="price" name=category.name - = prices_form.input :sum, label: false, input_html: { placeholder: 'Sum', data: { price_form_target: 'priceInput' } } - = prices_form.hidden_field :category_id, value: category.id - .div.d-flex.mt-2 - = f.submit t('buttons.create'), class: 'btn btn-success me-2 w-auto' - = link_to account_products_path, class: 'btn btn-danger d-flex align-items-center' do - span.me-1 =t('buttons.cancel') From c234958c0bd67a559ddd7b7fae29b6257cafb884 Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 4 Aug 2024 21:12:14 +0300 Subject: [PATCH 37/63] convert site settings template to erb --- app/views/account/site_settings/edit.html.erb | 39 +++++++++++++++++++ .../account/site_settings/edit.html.slim | 29 -------------- 2 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 app/views/account/site_settings/edit.html.erb delete mode 100644 app/views/account/site_settings/edit.html.slim diff --git a/app/views/account/site_settings/edit.html.erb b/app/views/account/site_settings/edit.html.erb new file mode 100644 index 000000000..686c59e54 --- /dev/null +++ b/app/views/account/site_settings/edit.html.erb @@ -0,0 +1,39 @@ +
+ + <%= t(".site_settings") %> + +
+ <%= simple_form_for @site_setting, url: account_site_setting_path, html: { data: { controller: "handle-browser-tab" } } do |f| %> +
+
+ <%= f.input :title, class: "form-control", input_html: { data: { action: "input->handle-browser-tab#setTitle" } } %> + <%= f.input :favicon, class: "form-control", input_html: { data: { action: "change->handle-browser-tab#setIcon" } } %> +
+ <%= render "browser_tab", site_setting: @site_setting %> +
+
+
+ <%= f.submit t(".apply_button") %> + <% end %> + <%= button_to t("buttons.revert"), revert_account_site_setting_path, data: { turbo_confirm: t('.confirm_default') }, class: "btn-revert position-absolute right-bottom" %> +
+
+ +
+ + <%= t(".site_features") %> + + <%= simple_form_for :feature_flags, url: account_features_flags_path, method: :patch do |f| %> + <% Flipper.features.each do |feature| %> +
+ <%= f.input "#{feature.name}_enabled", as: :boolean, label: t("account.feature_flags.#{feature.name}.name"), input_html: { checked: feature.enabled? } %> +
+ <%= feature.description %> +
+
+ <% end %> +
+ <%= f.submit t("buttons.save") %> +
+ <% end %> +
diff --git a/app/views/account/site_settings/edit.html.slim b/app/views/account/site_settings/edit.html.slim deleted file mode 100644 index a8541b8cb..000000000 --- a/app/views/account/site_settings/edit.html.slim +++ /dev/null @@ -1,29 +0,0 @@ -fieldset.bordered - legend.admin-legend - = t(".site_settings") - div.position-relative - = simple_form_for @site_setting, url: account_site_setting_path, html: { data: { controller: "handle-browser-tab" } } do |f| - .form-group.row - .col-12.has-float-label.my-auto - = f.input :title, class: "form-control", input_html: { data: { action: "input->handle-browser-tab#setTitle" } } - = f.input :favicon, class: "form-control", input_html: { data: { action: "change->handle-browser-tab#setIcon" } } - - .mb-2 - = render "browser_tab", site_setting: @site_setting - - = f.submit t(".apply_button") - - = button_to t("buttons.revert"), revert_account_site_setting_path, data: { turbo_confirm: t('.confirm_default') }, class: "btn-revert position-absolute right-bottom" - -fieldset.bordered - legend.admin-legend - = t(".site_features") - = simple_form_for :feature_flags, url: account_features_flags_path, method: :patch do |f| - - Flipper.features.each do |feature| - .feature-container - = f.input "#{feature.name}_enabled", as: :boolean, label: t("account.feature_flags.#{feature.name}.name"), input_html: { checked: feature.enabled? } - .description-feature - = feature.description - - div - = f.submit t("buttons.save") From f5a9b525fbaf66e206face5c6a9ee3ceca94baac Mon Sep 17 00:00:00 2001 From: aerea Date: Mon, 5 Aug 2024 02:35:57 +0300 Subject: [PATCH 38/63] merge en locale --- config/locales/en/en.yml | 714 +++++++++++++++++++++++++-------------- 1 file changed, 461 insertions(+), 253 deletions(-) diff --git a/config/locales/en/en.yml b/config/locales/en/en.yml index 9d2a684a9..25813c7ec 100644 --- a/config/locales/en/en.yml +++ b/config/locales/en/en.yml @@ -32,13 +32,22 @@ en: uk: "Українська" buttons: - save: 'Save' - update: 'Update' - create: 'Create' - cancel: 'Cancel' - revert: 'Revert' + save: "Save" + update: "Update" + create: "Create" + cancel: "Cancel" + revert: "Revert" + back: "Back" + views: + pagination: + previous: "‹ Prev" + next: "Next ›" + truncate: "…" calculators: + index: + meta-title: "Calculators" new_calculator: + diaper_сalculator: "Diaper calculator" form: description: "Child’s age:" price: "Price category" @@ -51,42 +60,47 @@ en: will_buy_diapers: "to be used in the future" money_spent: "already spent on diapers" money_will_be_spent: "yet to be spent on diapers" - pieces: pcs. - unit: uah + pieces: "pcs." + unit: "uah" old_calculator: form: description: "Child’s age:" - years_prompt: years - months_prompt: months + years_prompt: "years" + months_prompt: "months" bought_diapers: "diapers already used" money_spent: "UAH already spent on diapers" will_buy_diapers: "diapers to be used in the future" money_will_be_spent: "UAH yet to be spent on diapers" errors: - year_and_month_error_msg: "Error: please, select years and months" - year_error_msg: "Error: please, select years" - month_error_msg: "Error: please, select month" - period_and_price_error_msg: "Error: please select reporting period and price category" - period_error_msg: "Error: please select reporting period" - price_error_msg: "Error: please select price category" + year_and_month_error_msg: "Please, select years and months" + year_error_msg: "Please, select years" + month_error_msg: "Please, select month" + period_and_price_error_msg: "Please, select reporting period and price category" + period_error_msg: "Please, select reporting period" + price_error_msg: "Please, select price category" form: - period: Reporting period - price: Price category + period: "Reporting period" + price: "Price category" results: - unit: pcs - money: uah - used: will be used - spent: will be spent + unit: "pcs" + money: "uah" + used: "will be used" + spent: "will be spent" show: welcome_header: "Welcome to ZeroWaste" buttons: to_main: "To main" calculate: "Calculate" + index: + meta-title: "Calculators" + id_column: "ID Column" + calculator_name: "Calculator Name" + calculator_actions: "Calculator Actions" date: - day: day - week: week - month: month - year: year + day: "day" + week: "week" + month: "month" + year: "year" months: one: "%{count} month" few: "%{count} months" @@ -99,57 +113,65 @@ en: other: "%{count} years" layouts: navigation: + about_us: "About us" admin: "Admin" + calculate: "Diaper calculator" log_out: "Log Out" sign_up: "Sign Up" log_in: "Log In" - сontact_us: "Contact us" + contact_us: "Contact us" contacts: "%{contacts:Contacts}" local_lang: "Українська" description_block: - description_block_html: "These are approximate results. The exact numbers for your - family may differ depending on your daily habits and the diaper brand of choice. At any point of using - diapers there is a way to reduce the number of diapers used. You are welcome to learn more about how - this can be done and what reusable alternatives to disposable diapers there are. You can also learn - more about %{calculate_link_one:how we calculate} the number and cost of diapers - or %{calculate_link_two:contact us} with any other questions you may have." + description_block_html: + "These are approximate results. The exact numbers for your + family may differ depending on your daily habits and the diaper brand of choice. At any point of using + diapers there is a way to reduce the number of diapers used. You are welcome to learn more about how + this can be done and what reusable alternatives to disposable diapers there are. You can also learn + more about %{calculate_link_one:how we calculate} the number and cost of diapers + or %{calculate_link_two:contact us} with any other questions you may have." description_button: use_less: "%{use_less_link:HOW TO USE LESS}" homepage: homepage_title: "Welcome to the diaper calculator" - description: "The calculator tells you how many disposable diapers your baby has already used and will use in the future before switching to regular underwear. And also how much money you have already spent on diapers and how much money you have yet to spend." + description: + "The calculator tells you how many disposable diapers your baby has already used and will use in the future before + switching to regular underwear. And also how much money you have already spent on diapers and how much money you have yet to spend." calculate: "Let's go" - visit_website: "Visit WebSite" + visit_website: "Visit website" account_navbar: homepage: "Home page" calculators: "Calculators" histories: "History" users: "Users" messages: "Messages" - app_config: "App Config" site_settings: "Site Settings" - categories: 'Categories' + categories: "Categories" products: "Products" zerowaste_logo: "ZeroWaste logo" + account_footer: + created_with: "Created with" + by: "by" mailer: welcome_mail: subject: "Welcome to ZeroWaste!" user_mailer: welcome_email: - greeting: Welcome to ZeroWaste, %{name} - login_info: You have successfully signed up to zerowaste.com, your login info is + greeting: "Welcome to ZeroWaste, %{name}" + login_info: "You have successfully signed up to zerowaste.com, your login info is" email: "Email: %{email}" password: "Password: %{password}" - to_login: To login to the site, just follow this link - thanks: Thanks for joining and have a great day! + to_login: "To login to the site, just follow this link" + thanks: "Thanks for joining and have a great day!" messages: new: + meta-title: "Contact Us" contact_us_header: "Contact us" email: "Email" message: "Message" title: "Title" send: "Send" - title_hint: "title (min 5 characters)" + title_hint: "Title (min 5 characters)" message_hint: "Your message (min 20 characters)" company_address: "Company address" about_us: "About us" @@ -161,6 +183,17 @@ en: calculator-diapers: "Calculator diapers" calculators: "Calculators" message: "Write us a message" + about_us: + title: "About Us" + description: + first_paragraph: "We work in many directions for the sake of a clean future and sustainable development of our city and country." + second_paragraph: "Zero Waste encourages us to use resources rationally and consciously." + third_paragraph: "The main goal of zero waste is to move to a circular economy, where there is no garbage as such, and what is called garbage becomes a valuable resource." + our_team: + title: "Our Team" + description: + "Zero Waste Lviv and SoftServe present a calculator - an online tool for calculating the number of disposable and reusable items used. + The calculator was developed as part of the charity crowdsourcing platform Open Tech. The technical development is carried out by students of SoftServe Academy." account: account: edit: @@ -168,21 +201,11 @@ en: new_password_label: "New password:" confirm_password_label: "Confirm new password:" change_password_button: "Change password" - app_configs: - edit: - diapers_calculator_config: "Diapers calculator configuration" - first_period: "First period" - second_period: "Second period" - third_period: "Third period" - fourth_period: "Fourth period" - fifth_period: "Fifth period" - sixth_period: "Sixth period" - seventh_period: "Seventh period" - amount: "Amount" - price: "Price" - update: "Update" messages: index: + meta-title: "Messages" + search_placeholder: "Search" + search_button: "Search" table: title: "Title" email: "Email" @@ -197,41 +220,86 @@ en: time_col: "Date" categories: index: - add_category_button: 'Add category' - confirm_delete: 'Delete category?' + meta-title: "Categories" + search_placeholder: "Search" + search_button: "Search" + table: + title: "Title" + actions: "Actions" + priority: "Priority" + edit: "Edit" + delete: "Delete" + add_category_button: "Add category" + confirm_delete: "Delete category?" + cannot_delete: "You cannot delete preferable category." destroy: relation_error: 'Please remove prices with this category in next products:' + edit: + form: + update_category_button: "Update category" + new: + form: + create_category_button: "Create category" products: table: - title: 'Title' - prices: 'Prices' - actions: 'Actions' - default_usage_per_day: Default usage per day + title: "Title" + prices: "Prices" + actions: "Actions" + default_usage_per_day: "Default usage per day" index: - add_product_button: 'Add product' - confirm_delete: 'Delete product?' + meta-title: "Products" + table: + title: "Title" + prices: "Prices" + actions: "Actions" + edit: "Edit" + delete: "Delete" + add_product_button: "Add product" + confirm_delete: "Delete product?" show: - confirm_delete: 'Delete product?' + table: + title: "Title" + prices: "Prices" + actions: "Actions" + confirm_delete: "Delete product?" edit: - title: 'Title' - default_usage_per_day: Default usage per day + title: "Title" + default_usage_per_day: "Default usage per day" new: - title: 'Title' - default_usage_per_day: Default usage per day - created: "A product was successfully created." - updated: "A product was successfully updated." - deleted: "A product was successfully destroyed." + title: "Title" + default_usage_per_day: "Default usage per day" + partials: + new: + form: + title: "Title" + form: + sum: "Sum" + create_product_button: "Create product" + error_sum: "The field can contain only numbers" + edit: + form: + title: "Title" + form: + sum: "Sum" + update_product_button: "Update product" + error_sum: "The field can contain only numbers" + created: "A product was successfully created" + updated: "A product was successfully updated" + deleted: "A product was successfully deleted" users: index: + meta-title: "Users" main_header: "Dashboard" add_user_button: "Add user" + confirm_block: "Are you sure you want to block this user?" + confirm_unblock: "Are you sure you want to unblock this user?" confirm_delete: "Are you sure you want to delete this user?" table: email_col: "Email" first_name: "First name" last_name: "Last name" last_visit_col: "Last visit" - view_info_col: "Show" + show: "Show" edit: "Edit" ban: "Ban" delete: "Delete" @@ -239,8 +307,8 @@ en: table: create_new_user: "Create new user" form: - first_name_label: "First Name" - last_name_label: "Last Name" + first_name_label: "First name" + last_name_label: "Last name" password_hint: "Minimum 8 characters" create_user_button: "Create user" send_credentials_email: "Send email with credentials" @@ -252,7 +320,7 @@ en: name_label: "Name" surname_label: "Surname" password_hint: "Leave blank if you don't want to change it" - avatar_hint: "Avatar must be less than 2 MB. Allowed file types: PNG,JPG and JPEG" + avatar_hint: "Avatar must be less than 2 MB. Allowed file types: PNG, JPG and JPEG" update_user_button: "Update user" show: header: "User information" @@ -267,16 +335,110 @@ en: ban_col: "Status" blocked_label: "Blocked" unblocked_label: "Unblocked" + button: "Back" + calculators: + index: + meta-title: "Calculators" + add_calculator_button: "Add calculator" + confirm_delete: "Are you sure you want to delete calculator?" + table: + calculator_slug: "Slug" + calculator_name: "Name" + calculator_actions: "Actions" + show: "Show" + edit: "Edit" + delete: "Delete" + edit: + add_new_field_label: "Add new field" + form: + select_field_kind_label: "Select field kind" + select_field_type_label: "Select field type" + form_label: "Form" + parameters_label: "Parameters" + results_label: "Results" + no_fields_yet_label: "No fields yet" + update_calculator_button: "Update calculator" + new: + create_calculator_button: "Create calculator" + cancel_button: "Сancel" + prohibited_to_update: " prevent the calculator from updating" + prohibited_to_save: " перешкоджають збереженню калькулятора" + error: "помилки" site_settings: edit: - site_settings: Site settings - site_features: Site features - apply_button: 'Apply' - confirm_default: Are you sure you want to revert the title and favicon to their default settings? + meta-title: "Site Settings" + site_settings: "Site settings" + site_features: "Site features" + dev_features: "Development features" + rails_db_description: "Access to database (read only)" + apply_button: "Save" + confirm_default: "Are you sure you want to revert the title and favicon to their default settings?" + diapers_periods: + partials: + edit: + form: + edit_name: "Edit Diapers Period" + period_start: "Period Start" + period_end: "Period End" + usage_amount: "Usage Amount" + price: "Price" + back_button: "Back" + cannot_edit_period: "You can't edit the start and end of the period" + index: + delete_button: + confirm_delete: "Are you sure you want to delete this period?" + cannot_delete_category: "You can't delete periods in preferable category." + cannot_delete_period: "You can only delete the last period." + add_new_link: + add_new: "Add New Period" + content: + periods_for: "Diapers Periods for category:" + confirm_delete: "Are you sure you want to delete this period?" + period_start: "Period Start" + period_end: "Period End" + usage_amount: "Usage Amount" + price: "Price" + table: + edit: "Edit" + delete: "Delete" + add_new: "Add New Period" + back_button: "Back" + warning: "This category isn't showing in Calculator, because it doesn't cover all periods. Please, add new periods, so the category covers 30 months." + cannot_delete: "You can't delete periods in preferable category." + new: + form: + new_period: "New Diapers Period for Category:" + period_start: "Period Start" + period_end: "Period End" + usage_amount: "Usage Amount" + price: "Price" + back_button: "Back" + cannot_edit_start_period: "You can't edit the start of the period" + categories: + partials: + available: + content: + available: "Select category:" + no_categories_available: "No Available categories. Create new Category." + category_name: "Category name" + confirm_delete: "Are you sure you want to delete all periods?" + back_button: "Back" + table: + add: "Add" + with_periods: + content: + category_name: "Category name" + confirm_delete: "Are you sure you want to delete all periods?" + table: + show: "Show" + delete: "Delete" + no_categories: "No diapers categories found. Add some from Available list." + add_button: "Add New" + tooltip: "This category isn't shown in Calculator, because it doesn't have all periods covered." + cannot_delete_category: "You can't delete periods in preferable category." calculators: index: - search_placeholder: "Search" - search_button: "Search" + meta-title: "Calculators" add_calculator_button: "Add calculator" confirm_delete: "Are you sure you want to delete calculator?" table: @@ -299,41 +461,45 @@ en: submit_button: "Save" new_calculator_design: name: "Enable new calculator design" + show_calculators_list: + name: "Show calculators on the public side" + sandbox_mode: + name: "Enable sandbox mode" sessions: new: - log_in_header: "Log in" - log_in_button: "Log in" + log_in_header: "Log In" + log_in_button: "Log In" form: email: "Email" password: "Password" shared: links: forgot_your_password: "Forgot your password?" - log_in: "Log in" + log_in: "Log In" confirmations: new: resend_confirmation_instructions_header: "Resend confirmation instructions" resend_confirmation_instructions_button: "Resend confirmation instructions" mailer: confirmation_instructions: - greetings_to_user: Welcome, %{recipient}! + greetings_to_user: "Welcome, %{recipient}!" confirmation_email_through_link: "You can confirm your account email through the link below:" confirmation_account_link: "Confirm my account" email_changed: - greeting: Hello %{recipient}! - message_confirmed: We're contacting you to notify you that your email has been changed to %{email}. - message_unconfirmed: We're contacting you to notify you that your email is being changed to %{email}. + greeting: "Hello, %{recipient}!" + message_confirmed: "We're contacting you to notify you that your email has been changed to %{email}." + message_unconfirmed: "We're contacting you to notify you that your email is being changed to %{email}." password_change: - greeting: Hello %{recipient}! + greeting: "Hello, %{recipient}!" successful_change: "We're contacting you to notify you that your password has been changed." reset_password_instructions: - greeting: Hello %{recipient}! + greeting: "Hello, %{recipient}!" change_password_link: "Change my password" request_change_password: "Someone has requested a link to change your password. You can do this through the link below." ignore_email: "If you didn't request this, please ignore this email." access_to_changing: "Your password won't change until you access the link above and create a new one." unlock_instructions: - greeting: Hello %{recipient}! + greeting: "Hello, %{recipient}!" locked_message: "Your account has been locked due to an excessive number of unsuccessful sign in attempts." unlock_your_account: "Click the link below to unlock your account:" unlock_link: "Unlock my account" @@ -358,6 +524,7 @@ en: email_label: "Email" histories: index: + meta-title: "History" history_title: "History" back_link: "Back" table: @@ -371,7 +538,10 @@ en: passwords: new: forgot_password_header: "Forgot your password?" - send_instructions_button: "Send me reset password instructions" + forgot_password_message: "Enter your email address and we'll send you reset instructions." + email_placeholder: "Enter your email" + send_instructions_button: "Reset" + back_to: "Back to" form: email_label: "Email" edit: @@ -383,31 +553,35 @@ en: change_password_button: "Change my password" sessions: new: - log_in: "Log in" + meta-title: "Log In" + log_in: "Log In" + email_placeholder: "Enter your email" + password_placeholder: "Enter your password" shared: links: forgot_your_password: "Forgot your password?" - log_in: "Log in" - sign_up: "Sign up" + log_in: "Log In" + sign_up: "Sign Up" sign_in_with: "Sign in with %{provider}" google_sign_in: "Sign in with Google" registrations: new: + meta-title: "Sign Up" sign_up_header: "Sign Up" form: email_label: "Email" password_label: "Password" - password_characters_minimum_label: "Characters Minimum" - password_confirmation_label: "Password Confirmation" - first_name_label: "First Name" - last_name_label: "Last Name" + password_characters_minimum_label: "Characters minimum" + password_confirmation_label: "Password confirmation" + first_name_label: "First name" + last_name_label: "Last name" sign_up_button: "Sign Up" password_hint: "Minimum 8 characters" edit: update_user_button: "Update information" current_password_label: "Current password:" confirm_password_label: "Confirm new password:" - change_password_button: "Змінити пароль" + change_password_button: "Change my password" delete_account_label: "Delete my profile" are_user_satisfied_question: "Unhappy?" delete_account_button: "Delete profile" @@ -427,66 +601,76 @@ en: field: attributes: type: - blank: " can't be blank" + blank: "can't be blank" label: - blank: " can't be blank" + blank: "can't be blank" kind: - blank: " can't be blank" + blank: "can't be blank" named_value: attributes: name: - too_short: " is too short" + too_short: "is too short" from: - not_an_integer: " must be an integer" - not_a_number: " must be an integer" + not_an_integer: "must be an integer" + not_a_number: "must be an integer" to: - not_an_integer: " must be an integer" - not_a_number: " must be an integer" + not_an_integer: "must be an integer" + not_a_number: "must be an integer" range_field: attributes: from: - not_an_integer: " must be an integer" - not_a_number: " must be an integer" + not_an_integer: "must be an integer" + not_a_number: "must be an integer" to: - not_an_integer: " must be an integer" - not_a_number: " must be an integer" + not_an_integer: "must be an integer" + not_a_number: "must be an integer" value: - too_short: " is too short" + too_short: "is too short" calculation: attributes: value: - too_short: " is too short" + too_short: "is too short" select: attributes: value: - too_short: " is too short" + too_short: "is too short" value: attributes: value: - too_short: " is too short" - invalid: " is invalid" + too_short: "is too short" + invalid: "contains invalid characters" product_type: attributes: title: - blank: "The field 'Title' can't be blank." - too_short: "The field 'Title' is too short." + blank: "The field 'Title' can't be blank" + too_short: "The field 'Title' is too short" invalid: "Invalid value for the field 'Title'" calculator: attributes: name: - blank: " can't be blank" - too_short: " is too short" - invalid: " is invalid" - name_format_validation: must contain only letters or numbers + blank: "can't be blank" + too_short: "is too short (minimum is 2 characters)" + too_long: "is too long (maximum is %{count} characters)" + invalid: "contains invalid characters" + taken: "has already been taken, please choose another one" + category: + attributes: + name: + invalid: "contains invalid characters" + taken: "has already been taken, please choose another one" product: attributes: title: - blank: can't be blank - too_long: too long (maximum %{count} symbols) - too_short: too short (minimum %{count} symbols) - taken: has already been taken, please choose another one - invalid: contains invalid characters - default_usage_per_day: Default usage per day + blank: "can't be blank" + too_long: "is too long (maximum %{count} symbols)" + too_short: "is too short (minimum %{count} symbols)" + taken: "has already been taken, please choose another one" + invalid: "contains invalid characters" + default_usage_per_day: "Default usage per day" + price: + attributes: + sum: + less_than: "is too long" form_errors: one: "One error prohibited %{model} from being saved" other: "%{count} errors prohibited this %{model} from being saved" @@ -498,175 +682,197 @@ en: first_name: "First name" last_name: "Last name" country: "Country" + role: "Role" + remember_me: "Remember me" successful_update: "User info was successfully updated!" admin: remember_me: "Remember me" + site_setting: + title: "Title" + diapers_period: + price: "Price" + period_start: "Period Start" + period_end: "Period End" + usage_amount: "Usage Amount" calculator: name: "Name" slug: "Slug" preferable: "Preferable" + category: + name: "Title" + en_name: "Title in English" + uk_name: "Title in Ukrainian" + priority: "Priority" + preferable: "Main" + price: + sum: "Sum" + product: + sum: "Sum" notifications: calculator_created: "Calculator has been successfully created" calculator_updated: "Calculator has been successfully updated" calculator_deleted: "Calculator has been successfully deleted" user_created: "User has been successfully created" user_updated: "User has been successfully updated" + user_deleted: "User has been successfully deleted" message_sent: "Message has been sent" - category_created: "Category was successfully created." - category_updated: "Category was successfully updated." - category_deleted: "Category was successfully destroyed." + category_created: "Category was successfully created" + category_updated: "Category was successfully updated" + category_deleted: "Category was successfully deleted" feature_flags_updated: "Features updated successfully" site_setting_updated: "Settings were successfully updated" site_setting_reverted: "The title and favicon have been successfully reverted to default" + diapers_period_not_deleted: "Can't delete diapers period." + category_diapers_period_not_deleted: "Can't delete diapers periods from category." # time: # formats: # long: '%A, %d %B, %Y' # short: '%d, %B, %Y' date: abbr_day_names: - - Sun - - Mon - - Tue - - Wed - - Thu - - Fri - - Sat + - Sun + - Mon + - Tue + - Wed + - Thu + - Fri + - Sat abbr_month_names: - - - - Jan - - Feb - - Mar - - Apr - - May - - Jun - - Jul - - Aug - - Sep - - Oct - - Nov - - Dec + - + - Jan + - Feb + - Mar + - Apr + - May + - Jun + - Jul + - Aug + - Sep + - Oct + - Nov + - Dec day_names: - - Sunday - - Monday - - Tuesday - - Wednesday - - Thursday - - Friday - - Saturday + - Sunday + - Monday + - Tuesday + - Wednesday + - Thursday + - Friday + - Saturday formats: default: "%Y-%m-%d" long: "%B %d, %Y" short: "%b %d" month_names: - - - - January - - February - - March - - April - - May - - June - - July - - August - - September - - October - - November - - December + - + - January + - February + - March + - April + - May + - June + - July + - August + - September + - October + - November + - December order: - - :year - - :month - - :day + - :year + - :month + - :day datetime: distance_in_words: about_x_hours: - one: about 1 hour - other: about %{count} hours + one: "about 1 hour" + other: "about %{count} hours" about_x_months: - one: about 1 month - other: about %{count} months + one: "about 1 month" + other: "about %{count} months" about_x_years: - one: about 1 year - other: about %{count} years + one: "about 1 year" + other: "about %{count} years" almost_x_years: - one: almost 1 year - other: almost %{count} years - half_a_minute: half a minute + one: "almost 1 year" + other: "almost %{count} years" + half_a_minute: "half a minute" less_than_x_seconds: - one: less than 1 second - other: less than %{count} seconds + one: "less than 1 second" + other: "less than %{count} seconds" less_than_x_minutes: - one: less than a minute - other: less than %{count} minutes + one: "less than a minute" + other: "less than %{count} minutes" over_x_years: - one: over 1 year - other: over %{count} years + one: "over 1 year" + other: "over %{count} years" x_seconds: - one: 1 second + one: "1 second" other: "%{count} seconds" x_minutes: - one: 1 minute + one: "1 minute" other: "%{count} minutes" x_days: - one: 1 day + one: "1 day" other: "%{count} days" x_months: - one: 1 month + one: "1 month" other: "%{count} months" x_years: - one: 1 year + one: "1 year" other: "%{count} years" prompts: - second: Second - minute: Minute - hour: Hour - day: Day - month: Month - year: Year + second: "Second" + minute: "Minute" + hour: "Hour" + day: "Day" + month: "Month" + year: "Year" errors: format: "%{attribute} %{message}" messages: - accepted: must be accepted - blank: can't be blank - confirmation: doesn't match %{attribute} - empty: can't be empty - equal_to: must be equal to %{count} - even: must be even - exclusion: is reserved - greater_than: must be greater than %{count} - greater_than_or_equal_to: must be greater than or equal to %{count} - in: must be in %{count} - inclusion: is not included in the list - invalid: is invalid - less_than: must be less than %{count} - less_than_or_equal_to: must be less than or equal to %{count} - model_invalid: 'Validation failed: %{errors}' - not_a_number: is not a number - not_an_integer: must be an integer - odd: must be odd - other_than: must be other than %{count} - present: must be blank - required: must exist - taken: has already been taken + accepted: "must be accepted" + blank: "can't be blank" + confirmation: "doesn't match %{attribute}" + empty: "can't be empty" + equal_to: "must be equal to %{count}" + even: "must be even" + exclusion: "is reserved" + greater_than: "must be greater than %{count}" + greater_than_or_equal_to: "must be greater than or equal to %{count}" + in: "must be in %{count}" + inclusion: "is not included in the list" + invalid: "is invalid" + less_than: "must be less than %{count}" + less_than_or_equal_to: "must be less than or equal to %{count}" + model_invalid: "Validation failed: %{errors}" + not_a_number: "is not a number" + not_an_integer: "must be an integer" + odd: "must be odd" + other_than: "must be other than %{count}" + present: "must be blank" + required: "must exist" + taken: "has already been taken" too_long: - one: is too long (maximum is 1 character) - other: is too long (maximum is %{count} characters) + one: "is too long (maximum is 1 character)" + other: "is too long (maximum is %{count} characters)" too_short: - one: is too short (minimum is 1 character) - other: is too short (minimum is %{count} characters) + one: "is too short (minimum is 1 character)" + other: "is too short (minimum is %{count} characters)" wrong_length: - one: is the wrong length (should be 1 character) - other: is the wrong length (should be %{count} characters) + one: "is the wrong length (should be 1 character)" + other: "is the wrong length (should be %{count} characters)" template: - body: 'There were problems with the following fields:' + body: "There were problems with the following fields:" header: - one: 1 error prohibited this %{model} from being saved + one: "1 error prohibited this %{model} from being saved" other: "%{count} errors prohibited this %{model} from being saved" helpers: select: - prompt: Please select + prompt: "Please select" submit: - create: Create %{model} - submit: Save %{model} - update: Update %{model} + create: "Create %{model}" + submit: "Save %{model}" + update: "Update %{model}" number: currency: format: @@ -688,14 +894,14 @@ en: decimal_units: format: "%n %u" units: - billion: Billion - million: Million - quadrillion: Quadrillion - thousand: Thousand - trillion: Trillion - unit: '' + billion: "Billion" + million: "Million" + quadrillion: "Quadrillion" + thousand: "Thousand" + trillion: "Trillion" + unit: "" format: - delimiter: '' + delimiter: "" precision: 3 significant: true strip_insignificant_zeros: true @@ -703,30 +909,32 @@ en: format: "%n %u" units: byte: - one: Byte - other: Bytes - eb: EB - gb: GB - kb: KB - mb: MB - pb: PB - tb: TB + one: "Byte" + other: "Bytes" + eb: "EB" + gb: "GB" + kb: "KB" + mb: "MB" + pb: "PB" + tb: "TB" percentage: format: - delimiter: '' + delimiter: "" format: "%n%" precision: format: - delimiter: '' + delimiter: "" support: array: last_word_connector: ", and " two_words_connector: " and " words_connector: ", " time: - am: am + am: "am" formats: default: "%a, %d %b %Y %H:%M:%S %z" long: "%B %d, %Y %H:%M" short: "%d %b %H:%M" - pm: pm + pm: "pm" + breadcrumbs: + home: "Home" From 946704e585895cd26481c4adabb9157b551b529a Mon Sep 17 00:00:00 2001 From: aerea Date: Fri, 9 Aug 2024 19:50:50 +0300 Subject: [PATCH 39/63] fix edit and new calculators templates --- app/views/account/calculators/edit.html.erb | 75 +++------------------ app/views/account/calculators/new.html.erb | 21 ++++-- 2 files changed, 23 insertions(+), 73 deletions(-) diff --git a/app/views/account/calculators/edit.html.erb b/app/views/account/calculators/edit.html.erb index 10d648a0a..cb1724a87 100644 --- a/app/views/account/calculators/edit.html.erb +++ b/app/views/account/calculators/edit.html.erb @@ -1,78 +1,19 @@
- <%= simple_form_for @calculator, url: { action: 'update' }, wrapper: :horizontal_form, html: { novalidate: false } do |f| %> + <%= simple_form_for @calculator, url: { action: 'update' }, html: { novalidate: false } do |f| %>
-
- <%= f.input :name, class: 'form-control', required: true %> -
-
- <%= f.input :preferable, class: 'form-control' %> -
-
- -

<%= t('.add_new_field_label') %>

- -
-
- <%= select_tag :kind, - options_from_collection_for_select(Field.kinds.keys, :itself, :capitalize), - id: 'calculator_fields_kind', - prompt: t('.form.select_field_kind_label'), - class: 'custom-select', - data: { 'fields-list' => { form: [NamedValue.name, Select.name], - parameter: [Value.name, RangeField.name, Select.name, Calculation.name], - result: [Calculation.name] } } %> -
-
- <%= select_tag :type, '', id: 'calculator_fields_type', - prompt: t('.form.select_field_type_label'), - class: 'custom-select', - disabled: true %> -
-
- <%= link_to t('buttons.create'), '#', - class: 'btn btn-success text-white disabled', - id: 'add-calculator-field', - data: { url: new_account_calculator_field_path(calculator_slug: @calculator) } %> +
+ <%= f.input :name, class: 'form-control' %>
-
-

<%= t('.form.form_label') %>

-
- <% if @form_fields.any? %> - <%= f.fields_for :fields, @form_fields do |ff| %> - <%= render 'account/calculators/fields/form', f: ff %> - <% end %> - <% else %> -

<%= t('.form.no_fields_yet_label') %>

- <% end %> -
- -

<%= t('.form.parameters_label') %>

-
- <% if @parameter_fields.any? %> - <%= f.fields_for :fields, @parameter_fields do |ff| %> - <%= render 'account/calculators/fields/form', f: ff %> - <% end %> - <% else %> -

<%= t('.form.no_fields_yet_label') %>

- <% end %> -
- -

<%= t('.form.results_label') %>

-
- <% if @result_fields.any? %> - <%= f.fields_for :fields, @result_fields do |ff| %> - <%= render 'account/calculators/fields/form', f: ff %> - <% end %> - <% else %> -

<%= t('.form.no_fields_yet_label') %>

- <% end %> +
+
+ <%= f.input :product_id, collection: @products, include_blank: false, class: 'form-control' %>
-
-
+
+
<%= f.button :submit, t('.form.update_calculator_button'), class: 'btn btn-green me-2' %> <%= link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center' do %> <%= t('buttons.cancel') %> diff --git a/app/views/account/calculators/new.html.erb b/app/views/account/calculators/new.html.erb index ec4afee47..fbde5af5e 100644 --- a/app/views/account/calculators/new.html.erb +++ b/app/views/account/calculators/new.html.erb @@ -1,15 +1,24 @@
- <%= simple_form_for @calculator, url: account_calculators_path do |f| %> + <%= simple_form_for @calculator, url: { action: 'create' }, html: { novalidate: false } do |f| %>
<%= f.input :name, class: 'form-control' %>
-
- <%= f.button :submit, t('.create_calculator_button'), class: 'btn btn-green me-2 height-auto w-auto' %> - <%= link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do %> - <%= t('buttons.cancel') %> - <% end %> + +
+
+ <%= f.input :product_id, collection: @products, include_blank: false, class: 'form-control' %> +
+
+ +
+
+ <%= f.button :submit, t('.create_calculator_button'), class: 'btn btn-green me-2 height-auto w-auto' %> + <%= link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do %> + <%= t('buttons.cancel') %> + <% end %> +
<% end %>
From eb34f09d344a9a265ac2732384b3aedbc5f3300c Mon Sep 17 00:00:00 2001 From: aerea Date: Fri, 9 Aug 2024 20:48:26 +0300 Subject: [PATCH 40/63] fix products templates --- app/views/account/products/index.html.erb | 2 + .../products/partials/edit/_form.html.erb | 47 ++++++++++--------- .../products/partials/new/_form.html.erb | 1 + spec/requests/account/calculators_spec.rb | 2 +- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/app/views/account/products/index.html.erb b/app/views/account/products/index.html.erb index 61e4a1a0e..c5746dffd 100644 --- a/app/views/account/products/index.html.erb +++ b/app/views/account/products/index.html.erb @@ -21,6 +21,7 @@ <%= sort_link(@q, :id, "#", default_order: :desc) %> <%= sort_link(@q, :title, t('.table.title'), default_order: :desc) %> + <%= t('.table.default_usage_per_day') %> <%= t('.table.prices') %> <%= t('.table.edit') %> <%= t('.table.delete') %> @@ -31,6 +32,7 @@ <%= product.id %> <%= product.title %> + <%= product.default_usage_per_day %> <% product.prices.includes(:category).each do |price| %> <%= "#{price.category.name}: #{price.sum}" %> diff --git a/app/views/account/products/partials/edit/_form.html.erb b/app/views/account/products/partials/edit/_form.html.erb index ce13d5ccf..f36119885 100644 --- a/app/views/account/products/partials/edit/_form.html.erb +++ b/app/views/account/products/partials/edit/_form.html.erb @@ -1,27 +1,28 @@ - <%= simple_form_for product, method: :patch, url: account_product_path, html: { id: dom_id(product, :form) }, data: { controller: "price-form", action: "submit->price-form#submit" } do |f| %> -
-
- <%= f.input :title, label: t('.title'), class: 'form-control col-sm-11' %> - <% if categories.exists? %> - <%= f.simple_fields_for :prices do |prices_form| %> -
- <%= check_box_tag prices_form.object.category.name, 1, true, data: { price_form_target: 'checkbox', action: "click->price-form#removePrice click->price-form#togglePrice" }, class: 'me-1' %> - <%= label_tag prices_form.object.category.name %> -
- <%= prices_form.input :sum, label: false, input_html: { placeholder: t('.form.sum'), data: { price_form_target: 'priceInput' } } %> - <%= prices_form.hidden_field :category_id, value: prices_form.object.category.id %> - <%= prices_form.hidden_field :_destroy, data: { price_form_target: 'hiddenField' } %> - -
+<%= simple_form_for product, method: :patch, url: account_product_path, html: { id: dom_id(product, :form) }, data: { controller: "price-form", action: "submit->price-form#submit" } do |f| %> +
+
+ <%= f.input :title, label: t('.title'), class: 'form-control col-sm-11' %> + <%= f.input :default_usage_per_day, label: t('.default_usage_per_day'), class: 'form-control col-sm-11' %> + <% if categories.exists? %> + <%= f.simple_fields_for :prices do |prices_form| %> +
+ <%= check_box_tag prices_form.object.category.name, 1, true, data: { price_form_target: 'checkbox', action: "click->price-form#removePrice click->price-form#togglePrice" }, class: 'me-1' %> + <%= label_tag prices_form.object.category.name %> +
+ <%= prices_form.input :sum, label: false, input_html: { placeholder: t('.form.sum'), data: { price_form_target: 'priceInput' } } %> + <%= prices_form.hidden_field :category_id, value: prices_form.object.category.id %> + <%= prices_form.hidden_field :_destroy, data: { price_form_target: 'hiddenField' } %> +
- <% end %> +
<% end %> -
-
-
- <%= f.submit t('.form.update_product_button'), class: 'btn btn-green me-2' %> - <%= link_to account_products_path, class: 'btn btn-danger d-flex align-items-center justify-content-center' do %> - <%= t('buttons.cancel') %> <% end %>
- <% end %> +
+
+ <%= f.submit t('.form.update_product_button'), class: 'btn btn-green me-2' %> + <%= link_to account_products_path, class: 'btn btn-danger d-flex align-items-center justify-content-center' do %> + <%= t('buttons.cancel') %> + <% end %> +
+<% end %> diff --git a/app/views/account/products/partials/new/_form.html.erb b/app/views/account/products/partials/new/_form.html.erb index 1d00064f1..74c316f75 100644 --- a/app/views/account/products/partials/new/_form.html.erb +++ b/app/views/account/products/partials/new/_form.html.erb @@ -2,6 +2,7 @@
<%= f.input :title, label: t(".title"), class: "form-control col-sm-11" %> + <%= f.input :default_usage_per_day, label: t(".default_usage_per_day"), class: 'form-control col-sm-11' %> <% categories.each do |category| %>
<%= check_box_tag category.name, 1, false, data: { action: "click->price-form#togglePrice", price_form_target: "checkbox" }, class: "me-1" %> diff --git a/spec/requests/account/calculators_spec.rb b/spec/requests/account/calculators_spec.rb index 086b1c21e..a11ce4dea 100644 --- a/spec/requests/account/calculators_spec.rb +++ b/spec/requests/account/calculators_spec.rb @@ -62,8 +62,8 @@ context "POST #create" do it "creates a new calculator" do - expect { post account_calculators_path, params: valid_attributes }.to change(Calculator, :count).by(1) + expect(response).to redirect_to(account_calculators_path) expect(flash[:notice]).to eq(I18n.t("notifications.calculator_created")) end From 296967ed547762a2efa498d418a598e07eb51bda Mon Sep 17 00:00:00 2001 From: aerea Date: Fri, 9 Aug 2024 23:34:42 +0300 Subject: [PATCH 41/63] delete slim templates --- app/views/account/users/index.html.slim | 33 --------------------- app/views/devise/sessions/new.html.slim | 13 -------- app/views/layouts/_flash_messages.html.slim | 6 ---- 3 files changed, 52 deletions(-) delete mode 100644 app/views/account/users/index.html.slim delete mode 100644 app/views/devise/sessions/new.html.slim delete mode 100644 app/views/layouts/_flash_messages.html.slim diff --git a/app/views/account/users/index.html.slim b/app/views/account/users/index.html.slim deleted file mode 100644 index 983cd1029..000000000 --- a/app/views/account/users/index.html.slim +++ /dev/null @@ -1,33 +0,0 @@ -div class="container home" - .row - .col - .mb-2 - h1.text-body.d-inline = t '.main_header' - h3.float-right.d-inline - = link_to icon('fa-solid', 'download'), account_users_path(format: "csv") - - table.table - thead - tr - td = sort_link(@q, :email, t('.table.email_col'), default_order: :desc) - td = sort_link(@q, :first_name, t('.table.first_name'), default_order: :desc) - td = sort_link(@q, :last_name, t('.table.last_name'), default_order: :desc) - td = sort_link(@q, :updated_at, t('.table.last_visit_col'), default_order: :desc) - td = t '.table.view_info_col' - td = t '.table.edit' - td = t '.table.ban' - td = t '.table.delete' - tbody - - @users.each do |user| - tr id="user-info-#{user.id}" - td = user.email - td = user.first_name - td = user.last_name - td = user.last_sign_in_at - td = link_to icon('fa-solid', 'eye'), account_user_path(id: user.id) - td = link_to icon('fa-solid', 'edit'), edit_account_user_path(id: user.id) - td = link_to (icon('fa-solid', user.blocked? ? 'lock' : 'lock-open')), - account_user_path(id: user, user: {blocked: user.blocked? ? false : true}), - onclick: "alert('Are you sure?')", method: :patch - td = link_to account_user_path(id: user), data: { turbo_method: :delete, turbo_confirm: t('.confirm_delete') } do - i.fa.fa-trash.mx-2 diff --git a/app/views/devise/sessions/new.html.slim b/app/views/devise/sessions/new.html.slim deleted file mode 100644 index 49b21776c..000000000 --- a/app/views/devise/sessions/new.html.slim +++ /dev/null @@ -1,13 +0,0 @@ -.position-block - .card - .card-block.p-4 - h2.text-center.p-2 - = t('.log_in') - = simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| - = f.input :email, class: 'form-control', autofocus: true, autocomplete: "email" - = f.input :password, class: 'form-control', autocomplete: "current-password" - = f.input :remember_me, as: :boolean, inline_label: true if devise_mapping.rememberable? - .d-flex.justify-content-between.flex-wrap.flex-row-reverse.align-content-center - = f.submit t('.log_in'), class: "btn btn-primary" - .d-block - = render "devise/shared/links" diff --git a/app/views/layouts/_flash_messages.html.slim b/app/views/layouts/_flash_messages.html.slim deleted file mode 100644 index e58d2da24..000000000 --- a/app/views/layouts/_flash_messages.html.slim +++ /dev/null @@ -1,6 +0,0 @@ -- flash_messages.each do |message_type, message| - .alert.alert-dismissible.fade.show.position-absolute.container-fluid.d-flex.fixed-top class=(message_class_by_name(message_type)) - = message - = button_to({'data-dismiss': 'alert', 'aria-label': 'Close' }, method: :delete, class: 'close ms-2') do - span aria-hidden="true" class="ms-2" - | × From 41f7f6eb260218509dad30eea1e3b89e9a9db7bc Mon Sep 17 00:00:00 2001 From: aerea Date: Sat, 10 Aug 2024 01:19:13 +0300 Subject: [PATCH 42/63] add translations to locales --- config/locales/en/en.yml | 4 ++++ config/locales/uk/uk.yml | 26 ++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/config/locales/en/en.yml b/config/locales/en/en.yml index 286bc0331..3c08368ef 100644 --- a/config/locales/en/en.yml +++ b/config/locales/en/en.yml @@ -243,6 +243,7 @@ en: meta-title: "Products" table: title: "Title" + default_usage_per_day: "Default usage per day" prices: "Prices" actions: "Actions" edit: "Edit" @@ -259,6 +260,7 @@ en: new: form: title: "Title" + default_usage_per_day: "Default usage per day" form: sum: "Sum" create_product_button: "Create product" @@ -266,6 +268,7 @@ en: edit: form: title: "Title" + default_usage_per_day: "Default usage per day" form: sum: "Sum" update_product_button: "Update product" @@ -693,6 +696,7 @@ en: price: sum: "Sum" product: + default_usage_per_day: "Default usage per day" sum: "Sum" notifications: calculator_created: "Calculator has been successfully created" diff --git a/config/locales/uk/uk.yml b/config/locales/uk/uk.yml index 36c69847f..12a4f3398 100644 --- a/config/locales/uk/uk.yml +++ b/config/locales/uk/uk.yml @@ -52,6 +52,17 @@ uk: year_and_month_error_msg: "Будь ласка, виберіть, скільки років та місяців дитині" year_error_msg: "Будь ласка, виберіть, скільки років дитині" month_error_msg: "Будь ласка, виберіть, скільки місяців дитині" + period_and_price_error_msg: "Будь ласка, виберіть звітний період та цінову категорію" + period_error_msg: "Будь ласка, виберіть звітний період" + price_error_msg: "Будь ласка, виберіть цінову категорію" + form: + period: "Звітний період" + price: "Цінова категорія" + results: + unit: "шт" + money: "грн" + used: "буде використано" + spent: "буде витрачено" show: welcome_header: "Ласкаво просимо до ZeroWaste" calculate_result_button: "Pозрахувати" @@ -68,10 +79,10 @@ uk: calculator_name: "Назва" calculator_actions: "Дії" date: - day: день - week: тиждень - month: місяць - year: рік + day: "день" + week: "тиждень" + month: "місяць" + year: "рік" months: one: "%{count} місяць" few: "%{count} місяці" @@ -209,12 +220,11 @@ uk: form: create_category_button: "Створити категорію" products: - attributes: - default_usage_per_day: Використання в день за замовчуванням index: meta-title: "Продукти" table: title: "Назва" + default_usage_per_day: "Використання в день за замовчуванням" prices: "Ціни" actions: "Дії" edit: "Відредагувати" @@ -231,6 +241,7 @@ uk: new: form: title: "Назва" + default_usage_per_day: "Використання в день за замовчуванням" form: sum: "Сума" create_product_button: "Створити продукт" @@ -238,6 +249,7 @@ uk: edit: form: title: "Назва" + default_usage_per_day: "Використання в день за замовчуванням" form: sum: "Сума" update_product_button: "Оновити продукт" @@ -672,6 +684,7 @@ uk: usage_amount: "Обсяг використання" calculator: name: "Назва" + product_id: "Продукт" slug: "Шлях" preferable: "Бажаний" category: @@ -684,6 +697,7 @@ uk: sum: "Сума" product: title: "Назва" + default_usage_per_day: "Використання в день за замовчуванням" notifications: calculator_created: "Калькулятор було успішно створено" calculator_updated: "Калькулятор було успішно оновлено" From 0e1be2923baf809ea7b05805f2a4b993da4efdc5 Mon Sep 17 00:00:00 2001 From: aerea Date: Sat, 10 Aug 2024 03:43:09 +0300 Subject: [PATCH 43/63] fix tests --- spec/factories/calculate_services.rb | 0 .../account/create_calculator_spec.rb | 19 +++++++++++-------- .../account/update_calculator_spec.rb | 16 ++++++++++++++-- spec/features/visit_login_spec.rb | 6 ------ spec/models/calculator_spec.rb | 6 +++--- spec/requests/api/v1/calculators_spec.rb | 2 -- 6 files changed, 28 insertions(+), 21 deletions(-) delete mode 100644 spec/factories/calculate_services.rb diff --git a/spec/factories/calculate_services.rb b/spec/factories/calculate_services.rb deleted file mode 100644 index e69de29bb..000000000 diff --git a/spec/features/account/create_calculator_spec.rb b/spec/features/account/create_calculator_spec.rb index 488cf46b2..d37480f13 100644 --- a/spec/features/account/create_calculator_spec.rb +++ b/spec/features/account/create_calculator_spec.rb @@ -3,8 +3,10 @@ require "rails_helper" describe "Create Calculator Page", js: true do - let(:calculator) { create(:calculator) } - let(:create_calrulator_button) { "Create calculator" } + let!(:product) { create(:product, :diaper) } + let(:calculator) { create(:calculator, :diaper_calculator) } + let(:category) { create(:category) } + let(:create_calculator_button) { "Create calculator" } include_context :authorize_admin @@ -15,7 +17,8 @@ context "when user clicks button Create calculator" do it "shows message that calculator has been successfully created" do fill_in "Name", with: "Calculator1" - click_button create_calrulator_button + select product.title, from: "calculator_product_id" + click_button create_calculator_button expect(page).to have_content("Calculator has been successfully created") end end @@ -23,7 +26,7 @@ context "when user clicks button Create calculator" do it "redirects to Index calculator page" do fill_in "Name", with: "Calculator2" - click_button create_calrulator_button + click_button create_calculator_button expect(page).to have_current_path(account_calculators_path) end end @@ -31,7 +34,7 @@ context "when user fill in the Name field with name that already exist" do it "shows message that name is already has been taken" do fill_in "Name", with: calculator.name - click_button create_calrulator_button + click_button create_calculator_button expect(page).to have_content("Name has already been taken") end end @@ -39,7 +42,7 @@ context "when user fill in the Name field with name shorter than 2 symbols" do it "shows message that name is too short" do fill_in "Name", with: "i" - click_button create_calrulator_button + click_button create_calculator_button expect(page).to have_content("Name is too short (minimum is 2 characters)") end end @@ -47,7 +50,7 @@ context "when user fill in the Name field with symbols" do it "shows message that name is invalid" do fill_in "Name", with: "i[]p" - click_button create_calrulator_button + click_button create_calculator_button expect(page).to have_content("Name contains invalid characters") end end @@ -55,7 +58,7 @@ context "when user left the Name field blank" do it "shows message that name can't be blank" do fill_in "Name", with: "" - click_button create_calrulator_button + click_button create_calculator_button expect(page).to have_content("Name can't be blank") end end diff --git a/spec/features/account/update_calculator_spec.rb b/spec/features/account/update_calculator_spec.rb index 8341809a7..72f46dd54 100644 --- a/spec/features/account/update_calculator_spec.rb +++ b/spec/features/account/update_calculator_spec.rb @@ -3,7 +3,10 @@ require "rails_helper" describe "Update Calculator Page", js: true do - let(:calculator) { create(:calculator) } + let!(:product_diaper) { create(:product, :diaper) } + let!(:product_napkin) { create(:product, :napkin) } + let(:calculator) { create(:calculator, :diaper_calculator) } + let(:update_calculator_button) { "Update calculator" } include_context :authorize_admin @@ -14,7 +17,16 @@ context "when user clicks button Update calculator" do it "shows message that calculator has been successfully updated" do fill_in "Name", with: "Calculator2" - click_button UPDATE_CALCULATOR_BUTTON + click_button update_calculator_button + expect(page).to have_content("Calculator has been successfully updated") + end + end + + context "when user clicks button Update calculator with changing product" do + it "shows message that calculator has been successfully updated" do + fill_in "Name", with: "Calculator2" + select product_napkin.title, from: "calculator_product_id" + click_button update_calculator_button expect(page).to have_content("Calculator has been successfully updated") end end diff --git a/spec/features/visit_login_spec.rb b/spec/features/visit_login_spec.rb index 971357e99..693df131e 100644 --- a/spec/features/visit_login_spec.rb +++ b/spec/features/visit_login_spec.rb @@ -6,12 +6,6 @@ let(:user) { create(:user) } it "when sign in with correct login and password" do - allow_any_instance_of(ApplicationController) - .to receive(:after_sign_in_path_for) - .and_return("/calculators/#{calculator.slug}") - allow(Devise::Mailer).to receive(:confirmation_instructions) - .and_return(double(deliver: true)) - create(:feature_flag, :show_admin_menu) visit new_user_session_path fill_in "Email", with: user.email fill_in "Password", with: user.password diff --git a/spec/models/calculator_spec.rb b/spec/models/calculator_spec.rb index 82dc17263..53937018e 100644 --- a/spec/models/calculator_spec.rb +++ b/spec/models/calculator_spec.rb @@ -23,7 +23,7 @@ RSpec.describe Calculator, type: :model do let(:local_prefix_calculator) { "activerecord.errors.models.calculator.attributes" } - subject { build(:calculator) } + subject { build(:calculator, :diaper_calculator) } describe "validations" do it "validates the name and message " do @@ -45,7 +45,7 @@ end context "validates the name format" do - let(:calculator) { build(:calculator) } + let(:calculator) { build(:calculator, :diaper_calculator) } it "with valid name" do calculator.name = "Hedgehog і єнот з'їли 2 аґруси" @@ -88,7 +88,7 @@ end describe "versioning", versioning: true do - let!(:calculator) { create(:calculator, name: "Calculator 1") } + let!(:calculator) { create(:calculator, :diaper_calculator, name: "Calculator 1") } it "adds a version when the calculator is updated" do calculator.update!(name: "Calculator 2") diff --git a/spec/requests/api/v1/calculators_spec.rb b/spec/requests/api/v1/calculators_spec.rb index a17f018ce..290bb2ca1 100644 --- a/spec/requests/api/v1/calculators_spec.rb +++ b/spec/requests/api/v1/calculators_spec.rb @@ -80,8 +80,6 @@ end context "when get awaited values" do - include_context :app_config_load - it "got the expected result" do post api_v1_calculate_path(calculator), params: valid_params From 40a2ace2b3d6e74e1216bbe7a452f9fb03b231c0 Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 11 Aug 2024 02:32:12 +0300 Subject: [PATCH 44/63] refactor calculators controller --- .../account/calculators_controller.rb | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 1aa0fef95..f4d279649 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -9,7 +9,7 @@ def index end def show - @calculator = resourse + @calculator = resource end def new @@ -17,7 +17,7 @@ def new end def edit - @calculator = resourse + @calculator = resource @products = products_collection end @@ -34,7 +34,7 @@ def create end def update - @calculator = resourse + @calculator = resource if updater redirect_to account_calculators_path, notice: t("notifications.calculator_updated") @@ -46,15 +46,14 @@ def update end def destroy - @calculator = resourse - @calculator.destroy! + resource.destroy redirect_to account_calculators_path, notice: t("notifications.calculator_deleted"), status: :see_other end private - def resourse + def resource Calculator.friendly.find(params[:slug]) end @@ -62,10 +61,6 @@ def collection Calculator.ordered_by_name end - def calculator - @calculator = Calculator.friendly.find(params[:slug]) - end - def calculator_params params.require(:calculator).permit(:name, :slug, :product_id) end @@ -78,6 +73,6 @@ def updater end def products_collection - @products = Product.ordered_by_title + Product.ordered_by_title end end From 02977de0f89a2c364930cae756ac64c5cb1c6dbb Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 11 Aug 2024 02:37:12 +0300 Subject: [PATCH 45/63] fix pop up messages --- app/javascript/controllers/calculate_controller.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/javascript/controllers/calculate_controller.js b/app/javascript/controllers/calculate_controller.js index f48c6020a..fd1af2348 100644 --- a/app/javascript/controllers/calculate_controller.js +++ b/app/javascript/controllers/calculate_controller.js @@ -1,5 +1,6 @@ import { Controller } from "@hotwired/stimulus"; import { FetchRequest } from "@rails/request.js"; +import { toastUtils } from "helpers/toast_helper"; export default class extends Controller { static targets = ["period", "priceCategory"]; @@ -34,7 +35,7 @@ export default class extends Controller { if (response.ok) { this.calculationresultsOutlet.showResults(result); } else if (response.statusCode == 422) { - toastr.error(result.error); + toastUtils.showToast(result.error, "error"); } } From 48ba5f8620de39025ceb3333d443bf66b65ed0df Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 11 Aug 2024 20:26:57 +0300 Subject: [PATCH 46/63] refactor controllers --- .../account/calculators_controller.rb | 8 +++---- .../account/categories_controller.rb | 12 ++-------- app/validators/category_validator.rb | 22 ------------------- 3 files changed, 6 insertions(+), 36 deletions(-) delete mode 100644 app/validators/category_validator.rb diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index f4d279649..b369a1bc2 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -53,14 +53,14 @@ def destroy private - def resource - Calculator.friendly.find(params[:slug]) - end - def collection Calculator.ordered_by_name end + def resource + collection.friendly.find(params[:slug]) + end + def calculator_params params.require(:calculator).permit(:name, :slug, :product_id) end diff --git a/app/controllers/account/categories_controller.rb b/app/controllers/account/categories_controller.rb index 5eccb1d57..7867b642d 100644 --- a/app/controllers/account/categories_controller.rb +++ b/app/controllers/account/categories_controller.rb @@ -40,17 +40,9 @@ def update end def destroy - @category = resource - - validator = CategoryValidator.new(@category) - - if validator.valid? - @category.destroy + resource.destroy - redirect_to account_categories_path, notice: t("notifications.category_deleted") - else - redirect_to account_categories_path, alert: "#{t(".relation_error")} #{validator.references}", status: :unprocessable_entity - end + redirect_to account_categories_path, notice: t("notifications.category_deleted"), status: :see_other end private diff --git a/app/validators/category_validator.rb b/app/validators/category_validator.rb deleted file mode 100644 index bf9b22208..000000000 --- a/app/validators/category_validator.rb +++ /dev/null @@ -1,22 +0,0 @@ -class CategoryValidator - attr_reader :category, :prices - - def initialize(category) - @category = category - @prices = Price.where(category_id: category.id) - end - - def valid? - prices.blank? - end - - def references - products = [] - - prices.each do |price| - products << Product.where(id: price.priceable_id).pluck(:title) - end - - products.join(", ") - end -end From 3c5882318dec0c94c225a8f8b4916b1841e64a8c Mon Sep 17 00:00:00 2001 From: aerea Date: Mon, 12 Aug 2024 00:09:19 +0300 Subject: [PATCH 47/63] fix seeds --- db/seeds.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db/seeds.rb b/db/seeds.rb index 25b6ebc22..5aad14093 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -30,12 +30,12 @@ end # Create a calculator with related objects -bud_category = Category.find_or_create_by(name: "budgetary") -mid_category = Category.find_or_create_by(name: "medium") +budgetary_category = Category.find_or_create_by(uk_name: "Бюджетна", en_name: "Budgetary") +medium_category = Category.find_or_create_by(uk_name: "Середня", en_name: "Medium") product = Product.find_or_create_by(title: "Napkin") -Price.find_or_create_by(priceable: product, category: bud_category, sum: 7) -Price.find_or_create_by(priceable: product, category: mid_category, sum: 15) +Price.find_or_create_by(priceable: product, category: budgetary_category, sum: 7) +Price.find_or_create_by(priceable: product, category: medium_category, sum: 15) Calculator.find_or_create_by(name: "Napkins Calculator", product: product) From 04920a59bc3a36c39c3cdb67343359700c90dafa Mon Sep 17 00:00:00 2001 From: aerea Date: Mon, 12 Aug 2024 01:57:06 +0300 Subject: [PATCH 48/63] delete description button --- app/views/account/calculators/show.html.erb | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index 1b155dc45..f42fdf6a5 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -1,9 +1,5 @@
- -

<%= t 'calculators.buttons.to_main' %>

- <%= image_tag "icons/arrow-left.svg", class: "z-1" %> -
-
+
<%= simple_form_for(api_v1_calculate_path, html: { class: "simple_form_calculator", data: { controller: "calculate", calculate_url_value: api_v1_calculate_path, @@ -53,15 +49,4 @@
-
-
-
- <%= render 'layouts/description_block' %> -
-
- -
-
-
+<%= render "layouts/description_block" %> From 50cc0db2873a8a01bbfd9ced9919737aefb45d0f Mon Sep 17 00:00:00 2001 From: aerea Date: Mon, 12 Aug 2024 12:45:28 +0300 Subject: [PATCH 49/63] refactor test --- spec/requests/api/v1/calculators_spec.rb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/spec/requests/api/v1/calculators_spec.rb b/spec/requests/api/v1/calculators_spec.rb index 290bb2ca1..54118de79 100644 --- a/spec/requests/api/v1/calculators_spec.rb +++ b/spec/requests/api/v1/calculators_spec.rb @@ -3,21 +3,22 @@ require "rails_helper" RSpec.describe Api::V1::CalculatorsController, type: :request do - DAYS = { # rubocop:disable Lint/ConstantDefinitionInBlock - "day" => 1, - "week" => 7, - "month" => 30.5, - "year" => 365 - }.freeze - + let(:days) do + { + day: 1, + week: 7, + month: 30.5, + year: 365 + } + end let(:product) { create(:product, :diaper, default_usage_per_day: 3) } let(:category) { create(:category, :budgetary) } let(:price) { create(:price, :budgetary_price, priceable: product, category: category) } let(:calculator) { create(:calculator, :diaper_calculator, product: product) } - let(:valid_params) { { period: "week", price_id: price.id } } + let(:valid_params) { { period: :week, price_id: price.id } } - let(:money_spent) { price.sum.to_i * product.default_usage_per_day * DAYS[valid_params[:period]] } - let(:items_used) { product.default_usage_per_day * DAYS[valid_params[:period]] } + let(:money_spent) { price.sum.to_i * product.default_usage_per_day * days[valid_params[:period]] } + let(:items_used) { product.default_usage_per_day * days[valid_params[:period]] } let(:expected_result) do { From e299b8b30a56804b29425655fdcbc5837f9b543c Mon Sep 17 00:00:00 2001 From: aerea Date: Fri, 16 Aug 2024 18:06:25 +0300 Subject: [PATCH 50/63] refactor calculators controller --- app/controllers/api/v1/calculators_controller.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/calculators_controller.rb b/app/controllers/api/v1/calculators_controller.rb index 743e72eeb..91f046ada 100644 --- a/app/controllers/api/v1/calculators_controller.rb +++ b/app/controllers/api/v1/calculators_controller.rb @@ -9,18 +9,14 @@ def calculate render json: result.to_json, status: :ok else - render( - json: { - error: @validation.error - }, status: :unprocessable_entity - ) + render json: { error: @validation.error }, status: :unprocessable_entity end end private def collection - Calculator.all + Calculator.ordered_by_name end def resource From 5dc88bfd334d9f55d877e3d5df6cd1bf1411b42c Mon Sep 17 00:00:00 2001 From: aerea Date: Sat, 17 Aug 2024 02:34:52 +0300 Subject: [PATCH 51/63] refactor service test --- spec/services/calculators/calculate_spec.rb | 31 ++++++++++++--------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/spec/services/calculators/calculate_spec.rb b/spec/services/calculators/calculate_spec.rb index 39bc5d7c2..bd758ae8b 100644 --- a/spec/services/calculators/calculate_spec.rb +++ b/spec/services/calculators/calculate_spec.rb @@ -3,25 +3,30 @@ require "rails_helper" RSpec.describe Calculators::CalculateService do - DAYS = { # rubocop:disable Lint/ConstantDefinitionInBlock - "day" => 1, - "week" => 7, - "month" => 30.5, - "year" => 365 - }.freeze - + let(:days) do + { + day: 1, + week: 7, + month: 30.5, + year: 365 + } + end let(:product) { create(:product, :diaper, default_usage_per_day: 3) } let(:category) { create(:category, :budgetary) } let(:price) { create(:price, :budgetary_price, priceable: product, category: category) } let(:valid_params) { { period: "week", price_id: price.id } } - let(:money_spent) { price.sum.to_i * product.default_usage_per_day * DAYS[valid_params[:period]] } - let(:items_used) { product.default_usage_per_day * DAYS[valid_params[:period]] } + describe "#calculate" do + context "when the period is 'week'" do + let(:money_spent) { price.sum.to_i * product.default_usage_per_day * days[:week] } + let(:items_used) { product.default_usage_per_day * days[:week] } - it "calculates correctly" do - result = Calculators::CalculateService.new(product, valid_params).calculate + subject(:result) { described_class.new(product, valid_params).calculate } - expect(result[:moneySpent]).to eq(money_spent) - expect(result[:itemsUsed]).to eq(items_used) + it "calculates correctly" do + expect(result[:moneySpent]).to eq(money_spent) + expect(result[:itemsUsed]).to eq(items_used) + end + end end end From 9a393fcfaede99780ade62d384a4a4ea206a3073 Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 18 Aug 2024 22:22:36 +0300 Subject: [PATCH 52/63] delete calculator validator, add CalculatorForm with tests --- .../api/v1/calculators_controller.rb | 6 ++--- app/models/calculator_form.rb | 10 +++++++ app/validators/calculator_validator.rb | 27 ------------------- config/locales/en/en.yml | 13 +++++++++ config/locales/uk/uk.yml | 13 +++++++++ spec/factories/calculator_forms.rb | 7 +++++ spec/models/calculator_form_spec.rb | 25 +++++++++++++++++ spec/requests/api/v1/calculators_spec.rb | 6 ++--- 8 files changed, 74 insertions(+), 33 deletions(-) create mode 100644 app/models/calculator_form.rb delete mode 100644 app/validators/calculator_validator.rb create mode 100644 spec/factories/calculator_forms.rb create mode 100644 spec/models/calculator_form_spec.rb diff --git a/app/controllers/api/v1/calculators_controller.rb b/app/controllers/api/v1/calculators_controller.rb index 91f046ada..51f0f0a1e 100644 --- a/app/controllers/api/v1/calculators_controller.rb +++ b/app/controllers/api/v1/calculators_controller.rb @@ -2,14 +2,14 @@ class Api::V1::CalculatorsController < ApplicationController def calculate - @validation = CalculatorValidator.new(params) + @calculator_form = CalculatorForm.new(calculator_params) - if @validation.valid? + if @calculator_form.valid? result = Calculators::CalculateService.new(product_resource, calculator_params).calculate render json: result.to_json, status: :ok else - render json: { error: @validation.error }, status: :unprocessable_entity + render json: { error: @calculator_form.errors.full_messages.join(", ") }, status: :unprocessable_entity end end diff --git a/app/models/calculator_form.rb b/app/models/calculator_form.rb new file mode 100644 index 000000000..23abc55aa --- /dev/null +++ b/app/models/calculator_form.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class CalculatorForm + include ActiveModel::Model + + attr_accessor :period, :product_category, :price_id + + validates :period, presence: true + validates :price_id, presence: true +end diff --git a/app/validators/calculator_validator.rb b/app/validators/calculator_validator.rb deleted file mode 100644 index 4612b6972..000000000 --- a/app/validators/calculator_validator.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -class CalculatorValidator - attr_reader :params, :error - - def initialize(params) - @params = params - end - - def valid? - period = params.fetch(:period, nil) - price_id = params.fetch(:price_id, nil) - - if period.blank? && price_id.blank? - @error = I18n.t("calculators.errors.period_and_price_error_msg") - false - elsif period.blank? - @error = I18n.t("calculators.errors.period_error_msg") - false - elsif price_id.blank? - @error = I18n.t("calculators.errors.price_error_msg") - false - else - true - end - end -end diff --git a/config/locales/en/en.yml b/config/locales/en/en.yml index 3ffc677c1..5f057e6b0 100644 --- a/config/locales/en/en.yml +++ b/config/locales/en/en.yml @@ -705,6 +705,19 @@ en: product: default_usage_per_day: "Default usage per day" sum: "Sum" + activemodel: + attributes: + calculator_form: + period: "Reporting period" + price_id: "Price category" + errors: + models: + calculator_form: + attributes: + period: + blank: "can't be blank" + price_id: + blank: "can't be blank" notifications: calculator_created: "Calculator has been successfully created" calculator_updated: "Calculator has been successfully updated" diff --git a/config/locales/uk/uk.yml b/config/locales/uk/uk.yml index 76aa0b6da..c7fe8a531 100644 --- a/config/locales/uk/uk.yml +++ b/config/locales/uk/uk.yml @@ -705,6 +705,19 @@ uk: product: title: "Назва" default_usage_per_day: "Використання в день за замовчуванням" + activemodel: + attributes: + calculator_form: + period: "Звітний період" + price_id: "Цінова категорія" + errors: + models: + calculator_form: + attributes: + period: + blank: "не може бути порожнім" + price_id: + blank: "не може бути порожньою" notifications: calculator_created: "Калькулятор було успішно створено" calculator_updated: "Калькулятор було успішно оновлено" diff --git a/spec/factories/calculator_forms.rb b/spec/factories/calculator_forms.rb new file mode 100644 index 000000000..67996ecf3 --- /dev/null +++ b/spec/factories/calculator_forms.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory :calculator_form do + period { "week" } + product_category { "Budgetary" } + price_id { 1 } + end +end diff --git a/spec/models/calculator_form_spec.rb b/spec/models/calculator_form_spec.rb new file mode 100644 index 000000000..61afaf141 --- /dev/null +++ b/spec/models/calculator_form_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe CalculatorForm, type: :model do + let(:prefix) { "activemodel.errors.models.calculator_form.attributes" } + + subject { build(:calculator_form) } + + describe "validations" do + it "is valid with valid attributes" do + is_expected.to be_valid + end + + it "validates presence of period with error message" do + is_expected.to validate_presence_of(:period) + .with_message(I18n.t("#{prefix}.price_id.blank")) + end + + it "validates presence of price_id with error message" do + is_expected.to validate_presence_of(:price_id) + .with_message(I18n.t("#{prefix}.price_id.blank")) + end + end +end diff --git a/spec/requests/api/v1/calculators_spec.rb b/spec/requests/api/v1/calculators_spec.rb index 54118de79..75aa18beb 100644 --- a/spec/requests/api/v1/calculators_spec.rb +++ b/spec/requests/api/v1/calculators_spec.rb @@ -38,7 +38,7 @@ context "when no year and no month values" do let(:period_and_price_error_msg) do { - error: I18n.t("calculators.errors.period_and_price_error_msg") + error: "Reporting period can't be blank, Price category can't be blank" } end @@ -53,7 +53,7 @@ context "when no period value" do let(:period_error_msg) do { - error: I18n.t("calculators.errors.period_error_msg") + error: "Reporting period can't be blank" } end @@ -68,7 +68,7 @@ context "when no price value" do let(:price_error_msg) do { - error: I18n.t("calculators.errors.price_error_msg") + error: "Price category can't be blank" } end From 64af5870807cdbc88eb8ebd9eee822607d44d2e8 Mon Sep 17 00:00:00 2001 From: aerea Date: Mon, 19 Aug 2024 14:36:09 +0300 Subject: [PATCH 53/63] remove diaper calculator validator, add DiaperCalculatorForm --- .../api/v1/diaper_calculators_controller.rb | 10 ++++--- app/models/diaper_calculator_form.rb | 21 +++++++++++++++ app/validators/diaper_calculator_validator.rb | 27 ------------------- 3 files changed, 28 insertions(+), 30 deletions(-) create mode 100644 app/models/diaper_calculator_form.rb delete mode 100644 app/validators/diaper_calculator_validator.rb diff --git a/app/controllers/api/v1/diaper_calculators_controller.rb b/app/controllers/api/v1/diaper_calculators_controller.rb index 5bc47d4db..808448aa5 100644 --- a/app/controllers/api/v1/diaper_calculators_controller.rb +++ b/app/controllers/api/v1/diaper_calculators_controller.rb @@ -2,16 +2,16 @@ class Api::V1::DiaperCalculatorsController < ApplicationController def calculate - @validation = DiaperCalculatorValidator.new(params) + @form = DiaperCalculatorForm.new(calculator_params) - if @validation.valid? + if @form.valid? calc_service = Calculators::DiaperUsageService.new(params[:childs_years], params[:childs_months], set_category_id) calc_service.calculate calculator_decorator = CalculatorDecorator.new(calc_service.result) render json: calculator_decorator.to_json, status: :ok else - render json: { error: @validation.error }, status: :unprocessable_entity + render json: { error: @form.errors.full_messages.join(", ") }, status: :unprocessable_entity end end @@ -20,4 +20,8 @@ def calculate def set_category_id params[:category_id].presence || Category.preferable.first.id end + + def calculator_params + params.permit(:childs_years, :childs_months) + end end diff --git a/app/models/diaper_calculator_form.rb b/app/models/diaper_calculator_form.rb new file mode 100644 index 000000000..ca305bfd6 --- /dev/null +++ b/app/models/diaper_calculator_form.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class DiaperCalculatorForm + include ActiveModel::Model + + attr_accessor :childs_years, :childs_months + + validate :validate_child_age + + private + + def validate_child_age + if childs_years.blank? && childs_months.blank? + errors.add(:base, I18n.t("calculators.errors.year_and_month_error_msg")) + elsif childs_years.blank? + errors.add(:base, I18n.t("calculators.errors.year_error_msg")) + elsif childs_months.blank? + errors.add(:base, I18n.t("calculators.errors.month_error_msg")) + end + end +end diff --git a/app/validators/diaper_calculator_validator.rb b/app/validators/diaper_calculator_validator.rb deleted file mode 100644 index 18cf17cf1..000000000 --- a/app/validators/diaper_calculator_validator.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -class DiaperCalculatorValidator - attr_reader :params, :error - - def initialize(params) - @params = params - end - - def valid? - childs_years = params.fetch(:childs_years, nil) - childs_months = params.fetch(:childs_months, nil) - - if childs_years.blank? && childs_months.blank? - @error = I18n.t("calculators.errors.year_and_month_error_msg") - false - elsif childs_years.blank? - @error = I18n.t("calculators.errors.year_error_msg") - false - elsif childs_months.blank? - @error = I18n.t("calculators.errors.month_error_msg") - false - else - true - end - end -end From 5036409e8f0c4c960116a788a6ca4e942462b8dd Mon Sep 17 00:00:00 2001 From: aerea Date: Sat, 24 Aug 2024 02:20:01 +0300 Subject: [PATCH 54/63] refactor js controller --- app/javascript/controllers/calculate_controller.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/javascript/controllers/calculate_controller.js b/app/javascript/controllers/calculate_controller.js index fd1af2348..a54e7a42d 100644 --- a/app/javascript/controllers/calculate_controller.js +++ b/app/javascript/controllers/calculate_controller.js @@ -38,13 +38,4 @@ export default class extends Controller { toastUtils.showToast(result.error, "error"); } } - - getBasicOption(i) { - let option = document.createElement("option"); - - option.value = i; - option.innerText = i; - - return option; - } } From 53941e012d03d5aeafbf64496b1123ab2c3ca969 Mon Sep 17 00:00:00 2001 From: aerea Date: Sat, 5 Oct 2024 18:21:23 +0300 Subject: [PATCH 55/63] remove has-float-label class --- app/views/account/calculators/edit.html.erb | 6 +++--- app/views/account/calculators/new.html.erb | 6 +++--- app/views/account/products/partials/edit/_form.html.erb | 2 +- app/views/account/products/partials/new/_form.html.erb | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/account/calculators/edit.html.erb b/app/views/account/calculators/edit.html.erb index cb1724a87..9ae6c6c1b 100644 --- a/app/views/account/calculators/edit.html.erb +++ b/app/views/account/calculators/edit.html.erb @@ -1,14 +1,14 @@
<%= simple_form_for @calculator, url: { action: 'update' }, html: { novalidate: false } do |f| %>
-
+
<%= f.input :name, class: 'form-control' %>
-
- <%= f.input :product_id, collection: @products, include_blank: false, class: 'form-control' %> +
+ <%= f.input :product_id, collection: @products, include_blank: false, class: 'form-select' %>
diff --git a/app/views/account/calculators/new.html.erb b/app/views/account/calculators/new.html.erb index fbde5af5e..85c5508e8 100644 --- a/app/views/account/calculators/new.html.erb +++ b/app/views/account/calculators/new.html.erb @@ -1,14 +1,14 @@
<%= simple_form_for @calculator, url: { action: 'create' }, html: { novalidate: false } do |f| %>
-
+
<%= f.input :name, class: 'form-control' %>
-
- <%= f.input :product_id, collection: @products, include_blank: false, class: 'form-control' %> +
+ <%= f.input :product_id, collection: @products, include_blank: false, class: 'form-select' %>
diff --git a/app/views/account/products/partials/edit/_form.html.erb b/app/views/account/products/partials/edit/_form.html.erb index f36119885..36ffd981e 100644 --- a/app/views/account/products/partials/edit/_form.html.erb +++ b/app/views/account/products/partials/edit/_form.html.erb @@ -1,6 +1,6 @@ <%= simple_form_for product, method: :patch, url: account_product_path, html: { id: dom_id(product, :form) }, data: { controller: "price-form", action: "submit->price-form#submit" } do |f| %>
-
+
<%= f.input :title, label: t('.title'), class: 'form-control col-sm-11' %> <%= f.input :default_usage_per_day, label: t('.default_usage_per_day'), class: 'form-control col-sm-11' %> <% if categories.exists? %> diff --git a/app/views/account/products/partials/new/_form.html.erb b/app/views/account/products/partials/new/_form.html.erb index 74c316f75..afa87fa0d 100644 --- a/app/views/account/products/partials/new/_form.html.erb +++ b/app/views/account/products/partials/new/_form.html.erb @@ -1,6 +1,6 @@ <%= simple_form_for product, url: account_products_path, html: { id: dom_id(product, :form) }, data: { controller: "price-form" } do |f| %>
-
+
<%= f.input :title, label: t(".title"), class: "form-control col-sm-11" %> <%= f.input :default_usage_per_day, label: t(".default_usage_per_day"), class: 'form-control col-sm-11' %> <% categories.each do |category| %> From be27d91988feae0f1e5e6caa8faa2edb8be74653 Mon Sep 17 00:00:00 2001 From: aerea Date: Sat, 5 Oct 2024 19:21:07 +0300 Subject: [PATCH 56/63] delete options from products form --- app/views/account/products/partials/edit/_form.html.erb | 2 +- app/views/account/products/partials/new/_form.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/account/products/partials/edit/_form.html.erb b/app/views/account/products/partials/edit/_form.html.erb index 36ffd981e..2b216354d 100644 --- a/app/views/account/products/partials/edit/_form.html.erb +++ b/app/views/account/products/partials/edit/_form.html.erb @@ -1,4 +1,4 @@ -<%= simple_form_for product, method: :patch, url: account_product_path, html: { id: dom_id(product, :form) }, data: { controller: "price-form", action: "submit->price-form#submit" } do |f| %> +<%= simple_form_for product, url: account_product_path, data: { controller: "price-form", action: "submit->price-form#submit" } do |f| %>
<%= f.input :title, label: t('.title'), class: 'form-control col-sm-11' %> diff --git a/app/views/account/products/partials/new/_form.html.erb b/app/views/account/products/partials/new/_form.html.erb index afa87fa0d..c77d6efbc 100644 --- a/app/views/account/products/partials/new/_form.html.erb +++ b/app/views/account/products/partials/new/_form.html.erb @@ -1,4 +1,4 @@ -<%= simple_form_for product, url: account_products_path, html: { id: dom_id(product, :form) }, data: { controller: "price-form" } do |f| %> +<%= simple_form_for product, url: account_products_path, data: { controller: "price-form" } do |f| %>
<%= f.input :title, label: t(".title"), class: "form-control col-sm-11" %> From 45571d9ef9113507a760dffc396e1ddf7eedd32f Mon Sep 17 00:00:00 2001 From: aerea Date: Sat, 5 Oct 2024 19:33:41 +0300 Subject: [PATCH 57/63] refactor migration file --- db/migrate/20230728151759_add_product_id_to_calculators.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20230728151759_add_product_id_to_calculators.rb b/db/migrate/20230728151759_add_product_id_to_calculators.rb index 709b1b601..898b5292e 100644 --- a/db/migrate/20230728151759_add_product_id_to_calculators.rb +++ b/db/migrate/20230728151759_add_product_id_to_calculators.rb @@ -1,5 +1,5 @@ class AddProductIdToCalculators < ActiveRecord::Migration[6.1] def change - add_reference(:calculators, :product) + add_reference :calculators, :product end end From d6c000085804a1dc3b42d19d03bb89a592c020ff Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 6 Oct 2024 00:10:55 +0300 Subject: [PATCH 58/63] refactor templates, naming --- app/javascript/controllers/calculate_controller.js | 4 ++-- ...ults_controller.js => calculation_results_controller.js} | 0 app/models/calculator.rb | 4 ++-- app/views/account/calculators/edit.html.erb | 2 +- app/views/account/calculators/new.html.erb | 2 +- app/views/account/calculators/show.html.erb | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) rename app/javascript/controllers/{calculationresults_controller.js => calculation_results_controller.js} (100%) diff --git a/app/javascript/controllers/calculate_controller.js b/app/javascript/controllers/calculate_controller.js index a54e7a42d..883d0b0aa 100644 --- a/app/javascript/controllers/calculate_controller.js +++ b/app/javascript/controllers/calculate_controller.js @@ -4,7 +4,7 @@ import { toastUtils } from "helpers/toast_helper"; export default class extends Controller { static targets = ["period", "priceCategory"]; - static outlets = ["calculationresults"]; + static outlets = ["calculation-results"]; static values = { url: { type: String, @@ -33,7 +33,7 @@ export default class extends Controller { const result = await response.json; if (response.ok) { - this.calculationresultsOutlet.showResults(result); + this.calculationResultsOutlet.showResults(result); } else if (response.statusCode == 422) { toastUtils.showToast(result.error, "error"); } diff --git a/app/javascript/controllers/calculationresults_controller.js b/app/javascript/controllers/calculation_results_controller.js similarity index 100% rename from app/javascript/controllers/calculationresults_controller.js rename to app/javascript/controllers/calculation_results_controller.js diff --git a/app/models/calculator.rb b/app/models/calculator.rb index 29d935501..39cf3395b 100644 --- a/app/models/calculator.rb +++ b/app/models/calculator.rb @@ -26,10 +26,10 @@ class Calculator < ApplicationRecord has_paper_trail - has_many :fields, dependent: :destroy - belongs_to :product + has_many :fields, dependent: :destroy + accepts_nested_attributes_for :fields, allow_destroy: true validates :name, presence: true diff --git a/app/views/account/calculators/edit.html.erb b/app/views/account/calculators/edit.html.erb index 9ae6c6c1b..1eee3cad4 100644 --- a/app/views/account/calculators/edit.html.erb +++ b/app/views/account/calculators/edit.html.erb @@ -8,7 +8,7 @@
- <%= f.input :product_id, collection: @products, include_blank: false, class: 'form-select' %> + <%= f.association :product, collection: @products, include_blank: false, class: 'form-select' %>
diff --git a/app/views/account/calculators/new.html.erb b/app/views/account/calculators/new.html.erb index 85c5508e8..f02b51635 100644 --- a/app/views/account/calculators/new.html.erb +++ b/app/views/account/calculators/new.html.erb @@ -8,7 +8,7 @@
- <%= f.input :product_id, collection: @products, include_blank: false, class: 'form-select' %> + <%= f.association :product, collection: @products, include_blank: false, class: 'form-select' %>
diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index f42fdf6a5..e60f934e1 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -3,7 +3,7 @@ <%= simple_form_for(api_v1_calculate_path, html: { class: "simple_form_calculator", data: { controller: "calculate", calculate_url_value: api_v1_calculate_path, - calculate_calculationresults_outlet: '.result' }}) do |form| %> + calculate_calculation_results_outlet: '.result' }}) do |form| %>
@@ -33,14 +33,14 @@
-
+
<% [{ image: "money_spent_2.png", data_target: "moneySpentResult", unit: t("calculators.results.money"), text: t("calculators.results.spent") }, { image: "thrash_produced.png", data_target: "itemsUsedResult", unit: t("calculators.results.unit"), text: t("calculators.results.used") }].each do |item| %>
<%= image_tag item[:image], class: "img-margin" %> -

000

+

000

<%= item[:unit] %>

<%= item[:text] %>

From aa5eff212d85d42bd8420ac4a2a296556ba16b2b Mon Sep 17 00:00:00 2001 From: aerea Date: Mon, 7 Oct 2024 00:53:08 +0300 Subject: [PATCH 59/63] refactor tests --- spec/factories/calculator_forms.rb | 7 ------- spec/models/calculator_form_spec.rb | 6 ++++-- spec/requests/account/calculators_spec.rb | 4 ++-- spec/requests/api/v1/calculators_spec.rb | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) delete mode 100644 spec/factories/calculator_forms.rb diff --git a/spec/factories/calculator_forms.rb b/spec/factories/calculator_forms.rb deleted file mode 100644 index 67996ecf3..000000000 --- a/spec/factories/calculator_forms.rb +++ /dev/null @@ -1,7 +0,0 @@ -FactoryBot.define do - factory :calculator_form do - period { "week" } - product_category { "Budgetary" } - price_id { 1 } - end -end diff --git a/spec/models/calculator_form_spec.rb b/spec/models/calculator_form_spec.rb index 61afaf141..0c81af361 100644 --- a/spec/models/calculator_form_spec.rb +++ b/spec/models/calculator_form_spec.rb @@ -4,8 +4,10 @@ RSpec.describe CalculatorForm, type: :model do let(:prefix) { "activemodel.errors.models.calculator_form.attributes" } + let(:price) { create(:price, :budgetary_price) } + let(:valid_params) { { period: "week", price_id: price.id } } - subject { build(:calculator_form) } + subject { described_class.new(valid_params) } describe "validations" do it "is valid with valid attributes" do @@ -14,7 +16,7 @@ it "validates presence of period with error message" do is_expected.to validate_presence_of(:period) - .with_message(I18n.t("#{prefix}.price_id.blank")) + .with_message(I18n.t("#{prefix}.period.blank")) end it "validates presence of price_id with error message" do diff --git a/spec/requests/account/calculators_spec.rb b/spec/requests/account/calculators_spec.rb index a11ce4dea..73bcd4cd9 100644 --- a/spec/requests/account/calculators_spec.rb +++ b/spec/requests/account/calculators_spec.rb @@ -72,7 +72,7 @@ post account_calculators_path, params: invalid_attributes expect(response).to have_http_status(:unprocessable_entity) - expect(response).to render_template(:new) + expect(response.body).to include(I18n.t("activerecord.errors.models.calculator.attributes.name.invalid")) end end @@ -90,7 +90,7 @@ patch account_calculator_path(calculator), params: invalid_attributes expect(response).to have_http_status(:unprocessable_entity) - expect(response).to render_template(:edit) + expect(response.body).to include(I18n.t("activerecord.errors.models.calculator.attributes.name.invalid")) end end diff --git a/spec/requests/api/v1/calculators_spec.rb b/spec/requests/api/v1/calculators_spec.rb index 75aa18beb..31ff5e7e6 100644 --- a/spec/requests/api/v1/calculators_spec.rb +++ b/spec/requests/api/v1/calculators_spec.rb @@ -34,7 +34,7 @@ } end - describe "POST /api/v1/calculators/slug}" do + describe "POST #calculate" do context "when no year and no month values" do let(:period_and_price_error_msg) do { From 973f7597c2a95f0e66415db0075b18853aa82629 Mon Sep 17 00:00:00 2001 From: aerea Date: Thu, 10 Oct 2024 00:28:12 +0300 Subject: [PATCH 60/63] refactor template 'show' --- app/helpers/account/calculators_helper.rb | 10 +++++++ app/views/account/calculators/show.html.erb | 30 ++++++++++----------- config/locales/en/en.yml | 3 --- config/locales/en/simple_form.en.yml | 2 ++ config/locales/uk/simple_form.uk.yml | 2 ++ config/locales/uk/uk.yml | 3 --- 6 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 app/helpers/account/calculators_helper.rb diff --git a/app/helpers/account/calculators_helper.rb b/app/helpers/account/calculators_helper.rb new file mode 100644 index 000000000..f19caa7a6 --- /dev/null +++ b/app/helpers/account/calculators_helper.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Account::CalculatorsHelper + def calculation_items + [ + { image: "money_spent_2.png", data_target: "moneySpentResult", unit: t("calculators.results.money"), text: t("calculators.results.spent") }, + { image: "thrash_produced.png", data_target: "itemsUsedResult", unit: t("calculators.results.unit"), text: t("calculators.results.used") } + ] + end +end diff --git a/app/views/account/calculators/show.html.erb b/app/views/account/calculators/show.html.erb index e60f934e1..59da6ca80 100644 --- a/app/views/account/calculators/show.html.erb +++ b/app/views/account/calculators/show.html.erb @@ -10,20 +10,21 @@ <%= "#{@calculator.product.title} calculator".capitalize %>
- <%= t("calculators.form.period") %> - <%= form.input_field :period, - collection: use_period, - prompt: '__', - class: 'form_fild price_select rounded w-100', - data: { calculate_target: 'period' } %> + <%= form.input :period, + collection: use_period, + prompt: '__', + input_html: { + class: 'form_fild price_select rounded w-100', + data: { calculate_target: 'period' } + } %> - <%= t("calculators.form.price") %> - <%= form.input_field :product_category, - collection: product_prices(@calculator), - prompt: '__', - label: t('.form_price'), - class: 'form_fild price_select rounded w-100', - data: { calculate_target: 'priceCategory' } %> + <%= form.input :product_category, + collection: product_prices(@calculator), + prompt: '__', + input_html: { + class: 'form_fild price_select rounded w-100', + data: { calculate_target: 'priceCategory' } + } %> <%= form.submit t('calculators.buttons.calculate'), class: 'calculate-btn result-btn', @@ -36,8 +37,7 @@
- <% [{ image: "money_spent_2.png", data_target: "moneySpentResult", unit: t("calculators.results.money"), text: t("calculators.results.spent") }, - { image: "thrash_produced.png", data_target: "itemsUsedResult", unit: t("calculators.results.unit"), text: t("calculators.results.used") }].each do |item| %> + <% calculation_items.each do |item| %>
<%= image_tag item[:image], class: "img-margin" %>

000

diff --git a/config/locales/en/en.yml b/config/locales/en/en.yml index 5f057e6b0..ffc96cee4 100644 --- a/config/locales/en/en.yml +++ b/config/locales/en/en.yml @@ -78,9 +78,6 @@ en: period_and_price_error_msg: "Please, select reporting period and price category" period_error_msg: "Please, select reporting period" price_error_msg: "Please, select price category" - form: - period: "Reporting period" - price: "Price category" results: unit: "pcs" money: "uah" diff --git a/config/locales/en/simple_form.en.yml b/config/locales/en/simple_form.en.yml index 5852f3db0..aab00a1b3 100644 --- a/config/locales/en/simple_form.en.yml +++ b/config/locales/en/simple_form.en.yml @@ -3,6 +3,8 @@ en: labels: defaults: required: "%{text} %{mark}" + period: "Reporting period" + product_category: "Price category" required: text: "Required" mark: "*" diff --git a/config/locales/uk/simple_form.uk.yml b/config/locales/uk/simple_form.uk.yml index 3eae859de..4fd608b48 100644 --- a/config/locales/uk/simple_form.uk.yml +++ b/config/locales/uk/simple_form.uk.yml @@ -3,6 +3,8 @@ uk: labels: defaults: required: "%{text} %{mark}" + period: "Звітний період" + product_category: "Цінова категорія" required: text: "Обовʼязкове поле" mark: "*" diff --git a/config/locales/uk/uk.yml b/config/locales/uk/uk.yml index c7fe8a531..4018f2495 100644 --- a/config/locales/uk/uk.yml +++ b/config/locales/uk/uk.yml @@ -55,9 +55,6 @@ uk: period_and_price_error_msg: "Будь ласка, виберіть звітний період та цінову категорію" period_error_msg: "Будь ласка, виберіть звітний період" price_error_msg: "Будь ласка, виберіть цінову категорію" - form: - period: "Звітний період" - price: "Цінова категорія" results: unit: "шт" money: "грн" From 18fdb98a13a4b06aa48b936e6b025097fb726f1b Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 13 Oct 2024 15:48:49 +0300 Subject: [PATCH 61/63] refactor styles for 'cancel' button --- app/assets/stylesheets/components/buttons.css | 5 +++++ app/assets/stylesheets/pages/account.scss | 10 ---------- app/views/account/calculators/edit.html.erb | 4 ++-- app/views/account/calculators/new.html.erb | 2 +- app/views/account/categories/edit.html.erb | 4 ++-- app/views/account/categories/new.html.erb | 2 +- .../account/products/partials/edit/_form.html.erb | 4 ++-- app/views/account/products/partials/new/_form.html.erb | 4 ++-- app/views/account/users/edit.html.erb | 4 ++-- config/tailwind.config.js | 4 ++++ 10 files changed, 21 insertions(+), 22 deletions(-) diff --git a/app/assets/stylesheets/components/buttons.css b/app/assets/stylesheets/components/buttons.css index 29d339358..86ee4affe 100644 --- a/app/assets/stylesheets/components/buttons.css +++ b/app/assets/stylesheets/components/buttons.css @@ -30,6 +30,11 @@ .btn-grey { @apply text-white rounded hover:text-white bg-grey hover:bg-dark_gray; } + + .btn-cancel { + @apply text-white rounded hover:text-white active:text-white bg-red hover:bg-dark_red active:bg-active_red border-none min-w-120 flex items-center justify-center; + } + .btn-space { @apply py-3; } diff --git a/app/assets/stylesheets/pages/account.scss b/app/assets/stylesheets/pages/account.scss index 27f6d6be6..55e1c8843 100644 --- a/app/assets/stylesheets/pages/account.scss +++ b/app/assets/stylesheets/pages/account.scss @@ -81,14 +81,4 @@ $burger-size: 20px; .btn { min-width: 120px; } - - .btn-danger { - border: none; - border-radius: 4px; - padding: 10px; - - &:hover { - color: white; - } - } } diff --git a/app/views/account/calculators/edit.html.erb b/app/views/account/calculators/edit.html.erb index 1eee3cad4..60d955e1c 100644 --- a/app/views/account/calculators/edit.html.erb +++ b/app/views/account/calculators/edit.html.erb @@ -15,8 +15,8 @@
<%= f.button :submit, t('.form.update_calculator_button'), class: 'btn btn-green me-2' %> - <%= link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center' do %> - <%= t('buttons.cancel') %> + <%= link_to account_calculators_path, class: 'btn-cancel' do %> + <%= t('buttons.cancel') %> <% end %>
diff --git a/app/views/account/calculators/new.html.erb b/app/views/account/calculators/new.html.erb index f02b51635..a41008bcb 100644 --- a/app/views/account/calculators/new.html.erb +++ b/app/views/account/calculators/new.html.erb @@ -15,7 +15,7 @@
<%= f.button :submit, t('.create_calculator_button'), class: 'btn btn-green me-2 height-auto w-auto' %> - <%= link_to account_calculators_path, class: 'btn btn-danger d-flex align-items-center justify-content-center height-auto w-auto' do %> + <%= link_to account_calculators_path, class: 'btn-cancel' do %> <%= t('buttons.cancel') %> <% end %>
diff --git a/app/views/account/categories/edit.html.erb b/app/views/account/categories/edit.html.erb index 54d857a93..0a11088b3 100644 --- a/app/views/account/categories/edit.html.erb +++ b/app/views/account/categories/edit.html.erb @@ -20,8 +20,8 @@
<%= f.submit t(".form.update_category_button"), class: 'btn btn-green me-2 height w-auto' %> - <%= link_to account_categories_path, class: 'btn btn-danger d-flex align-items-center justify-content-center' do %> - <%= t('buttons.cancel') %> + <%= link_to account_categories_path, class: 'btn-cancel' do %> + <%= t('buttons.cancel') %> <% end %>
<% end %> diff --git a/app/views/account/categories/new.html.erb b/app/views/account/categories/new.html.erb index f9f6156d6..79648f4a0 100644 --- a/app/views/account/categories/new.html.erb +++ b/app/views/account/categories/new.html.erb @@ -8,7 +8,7 @@
<%= f.submit t(".form.create_category_button"), class: "btn btn-green me-2" %> - <%= link_to account_categories_path, class: "btn btn-danger d-flex align-items-center justify-content-center" do %> + <%= link_to account_categories_path, class: "btn-cancel" do %> <%= t("buttons.cancel") %> <% end %>
diff --git a/app/views/account/products/partials/edit/_form.html.erb b/app/views/account/products/partials/edit/_form.html.erb index 2b216354d..014483c6d 100644 --- a/app/views/account/products/partials/edit/_form.html.erb +++ b/app/views/account/products/partials/edit/_form.html.erb @@ -21,8 +21,8 @@
<%= f.submit t('.form.update_product_button'), class: 'btn btn-green me-2' %> - <%= link_to account_products_path, class: 'btn btn-danger d-flex align-items-center justify-content-center' do %> - <%= t('buttons.cancel') %> + <%= link_to account_products_path, class: 'btn-cancel' do %> + <%= t('buttons.cancel') %> <% end %>
<% end %> diff --git a/app/views/account/products/partials/new/_form.html.erb b/app/views/account/products/partials/new/_form.html.erb index c77d6efbc..a6d0d03db 100644 --- a/app/views/account/products/partials/new/_form.html.erb +++ b/app/views/account/products/partials/new/_form.html.erb @@ -20,8 +20,8 @@
<%= f.submit t(".form.create_product_button"), class: "btn btn-green me-2 w-auto" %> - <%= link_to account_products_path, class: "btn btn-danger d-flex align-items-center justify-content-center" do %> - <%= t("buttons.cancel") %> + <%= link_to account_products_path, class: "btn-cancel" do %> + <%= t("buttons.cancel") %> <% end %>
<% end %> diff --git a/app/views/account/users/edit.html.erb b/app/views/account/users/edit.html.erb index a5c6bbb99..d9baf2c95 100644 --- a/app/views/account/users/edit.html.erb +++ b/app/views/account/users/edit.html.erb @@ -21,8 +21,8 @@ <%= f.input :avatar, as: :file, direct_upload: true, class: 'm-3', label: t('.avatar'), hint: t('.form.avatar_hint'), wrapper: :horizontal_form %>
<%= f.submit t('.form.update_user_button'), class: 'btn btn-green me-2 height w-auto' %> - <%= link_to account_users_path, class: 'btn btn-danger d-flex align-items-center justify-content-center' do %> - <%= t('buttons.cancel') %> + <%= link_to account_users_path, class: 'btn-cancel' do %> + <%= t('buttons.cancel') %> <% end %>
<% end %> diff --git a/config/tailwind.config.js b/config/tailwind.config.js index 1f926b862..aa8d98204 100644 --- a/config/tailwind.config.js +++ b/config/tailwind.config.js @@ -27,9 +27,13 @@ module.exports = { white: '#ffffff', blue: '#007bff', dark_blue: '#0069d9', + red: '#dc3545', + dark_red: '#bb2d3b', + active_red: '#b02a37', }, minWidth: { '36': '36px', + '120': '120px', }, maxWidth: { '1230': '1230px', From 9e2a8b8053f2c2ffafcad1998adb21cd430a09d2 Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 13 Oct 2024 17:27:15 +0300 Subject: [PATCH 62/63] remove unnecessary seeds --- db/seeds.rb | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/db/seeds.rb b/db/seeds.rb index 5aad14093..2cc45bf2e 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -28,14 +28,3 @@ role: "admin" ) end - -# Create a calculator with related objects -budgetary_category = Category.find_or_create_by(uk_name: "Бюджетна", en_name: "Budgetary") -medium_category = Category.find_or_create_by(uk_name: "Середня", en_name: "Medium") - -product = Product.find_or_create_by(title: "Napkin") - -Price.find_or_create_by(priceable: product, category: budgetary_category, sum: 7) -Price.find_or_create_by(priceable: product, category: medium_category, sum: 15) - -Calculator.find_or_create_by(name: "Napkins Calculator", product: product) From 0bca812208d8317305d682d9405903ca99648983 Mon Sep 17 00:00:00 2001 From: aerea Date: Sun, 13 Oct 2024 20:25:49 +0300 Subject: [PATCH 63/63] remove outdated tests --- .ruby-version | 2 +- spec/requests/account/calculators_spec.rb | 23 ----------------- spec/requests/values_spec.rb | 30 ----------------------- 3 files changed, 1 insertion(+), 54 deletions(-) delete mode 100644 spec/requests/values_spec.rb diff --git a/.ruby-version b/.ruby-version index ab96aa90d..b347b11ea 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -ruby-3.2.3 +3.2.3 diff --git a/spec/requests/account/calculators_spec.rb b/spec/requests/account/calculators_spec.rb index 46e266077..73bcd4cd9 100644 --- a/spec/requests/account/calculators_spec.rb +++ b/spec/requests/account/calculators_spec.rb @@ -104,27 +104,4 @@ expect(flash[:notice]).to eq(I18n.t("notifications.calculator_deleted")) end end - - describe "GET #index" do - context "when in production environment" do - include_context :in_production_environment - - it "renders the 'under_construction' template" do - get account_calculators_path - - expect(response).to render_template("shared/under_construction") - end - end - - context "when in local environment" do - include_context :in_local_environment - - it "loads calculators and renders the index template" do - get account_calculators_path - - expect(response).to render_template(:index) - expect(assigns(:calculators)).to include(calculator) - end - end - end end diff --git a/spec/requests/values_spec.rb b/spec/requests/values_spec.rb deleted file mode 100644 index 8f24ace0b..000000000 --- a/spec/requests/values_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -require "rails_helper" - -RSpec.describe "Values", type: :request do - let(:json_response) { response.parsed_body } - - describe "POST api/v1/calculators/PERMALINK/compute" do - before do - post "/api/v1/calculators/PERMALINK/compute" - end - - it "returns http success" do - expect(response.status).to eq(200) - end - - it "returns JSON data correctly" do - expect(json_response) - .to eq( - "result" => [ - { "name" => "bought_diapers", "result" => 8956 }, - { "name" => "money_spent", "result" => 7841 }, - { "name" => "garbage_created", "result" => 342 } - ] - ) - end - - it "JSON contains response" do - expect(json_response).to be_truthy - end - end -end