Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/creating calculators constructor #534

Open
wants to merge 73 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
a8708fe
initial commit
AndriyAndriyovuch Jul 25, 2023
212ffdc
merge from develop
AndriyAndriyovuch Jul 28, 2023
18486f8
commit before merge to update from in calculator
AndriyAndriyovuch Jul 28, 2023
69c8d5c
merge from develop
AndriyAndriyovuch Jul 28, 2023
aa79011
add ability to add product to calculator
AndriyAndriyovuch Jul 28, 2023
cf4c354
add draft show page for universal calculator
AndriyAndriyovuch Jul 28, 2023
c9d5d87
add draft show page for universal calculator
AndriyAndriyovuch Jul 28, 2023
7cfca42
add default usage to product
AndriyAndriyovuch Jul 29, 2023
7e8bbf1
create draft calculator
AndriyAndriyovuch Jul 30, 2023
e7287bb
add draft calculator for all products
AndriyAndriyovuch Jul 30, 2023
456d188
added locales
AndriyAndriyovuch Jul 31, 2023
95acb0c
remove useless relations
AndriyAndriyovuch Jul 31, 2023
e4b32b2
Merge branch 'develop' into feature/creating_calculators_constructor
AndriyAndriyovuch Aug 3, 2023
9e36431
fix relations between calculator and product
AndriyAndriyovuch Aug 3, 2023
5e4f0d5
remove before_action
AndriyAndriyovuch Aug 6, 2023
88efc69
remove useless id from path in category/new view
AndriyAndriyovuch Aug 6, 2023
87b11e1
fix selectors after invalid data in form fields
AndriyAndriyovuch Aug 6, 2023
2388ad9
add migration to clean all prices without category
AndriyAndriyovuch Aug 6, 2023
fa2f751
added alert if admin wants to delete category with related prices
AndriyAndriyovuch Aug 6, 2023
09b6800
add locale for error message
AndriyAndriyovuch Aug 6, 2023
3704ab9
fix all tests due to new logic, small rubocop fixes
AndriyAndriyovuch Aug 6, 2023
3be2d64
created request tests for account/calculators_controller
AndriyAndriyovuch Aug 6, 2023
12802a6
removed code smells
AndriyAndriyovuch Aug 6, 2023
6cbd864
add test for calculate service
AndriyAndriyovuch Aug 6, 2023
412b789
add addiction test for destroying category which have prices
AndriyAndriyovuch Aug 6, 2023
9dd58bd
create tests for api/v1/calculators
AndriyAndriyovuch Aug 6, 2023
e6ee05a
add redirect to all calculators after update
AndriyAndriyovuch Aug 7, 2023
081147b
change image on 'items used'
AndriyAndriyovuch Aug 7, 2023
485a656
add to seeds creating a calculator with related objects
AndriyAndriyovuch Aug 7, 2023
fc272ca
Merge branch 'develop' into feature/creating_calculators_constructor
AndriyAndriyovuch Aug 7, 2023
70ae996
rubocop fixes
AndriyAndriyovuch Aug 7, 2023
c8c24be
add some extra lines, remove migration for deleting all prices withou…
AndriyAndriyovuch Aug 9, 2023
2dd2787
merged from develop
AndriyAndriyovuch Aug 10, 2023
97e7e72
merged develop
AndriyAndriyovuch Nov 14, 2023
fd842e5
merged develop
AndriyAndriyovuch Nov 21, 2023
acd0655
fix turbo in delete methods
AndriyAndriyovuch Nov 21, 2023
bc14bd4
Fixed devise errors and some tests
AndriyAndriyovuch Nov 21, 2023
5addf7c
refactored category destroy method (add validator)
AndriyAndriyovuch Nov 21, 2023
a74832b
rubocop fix
AndriyAndriyovuch Nov 21, 2023
e895ef1
fixed minor issues
AndriyAndriyovuch Nov 21, 2023
d53eb19
convert calculators templates to erb
iryna-borniak Aug 3, 2024
e27c50f
convert categories template to erb
iryna-borniak Aug 4, 2024
d41413d
convert products templates to erb
iryna-borniak Aug 4, 2024
c234958
convert site settings template to erb
iryna-borniak Aug 4, 2024
f5a9b52
merge en locale
iryna-borniak Aug 4, 2024
c87ad72
resolve conflicts
iryna-borniak Aug 9, 2024
946704e
fix edit and new calculators templates
iryna-borniak Aug 9, 2024
eb34f09
fix products templates
iryna-borniak Aug 9, 2024
296967e
delete slim templates
iryna-borniak Aug 9, 2024
41f7f6e
add translations to locales
iryna-borniak Aug 9, 2024
0e1be29
fix tests
iryna-borniak Aug 10, 2024
40a2ace
refactor calculators controller
iryna-borniak Aug 10, 2024
02977de
fix pop up messages
iryna-borniak Aug 10, 2024
48ba5f8
refactor controllers
iryna-borniak Aug 11, 2024
3c58823
fix seeds
iryna-borniak Aug 11, 2024
043c1d5
Merge branch 'develop' into feature/creating_calculators_constructor
iryna-borniak Aug 11, 2024
04920a5
delete description button
iryna-borniak Aug 11, 2024
50cc0db
refactor test
iryna-borniak Aug 12, 2024
e299b8b
refactor calculators controller
iryna-borniak Aug 16, 2024
5dc88bf
refactor service test
iryna-borniak Aug 16, 2024
9a393fc
delete calculator validator, add CalculatorForm with tests
iryna-borniak Aug 18, 2024
64af587
remove diaper calculator validator, add DiaperCalculatorForm
iryna-borniak Aug 19, 2024
5036409
refactor js controller
iryna-borniak Aug 23, 2024
53941e0
remove has-float-label class
iryna-borniak Oct 5, 2024
be27d91
delete options from products form
iryna-borniak Oct 5, 2024
45571d9
refactor migration file
iryna-borniak Oct 5, 2024
d6c0000
refactor templates, naming
iryna-borniak Oct 5, 2024
aa5eff2
refactor tests
iryna-borniak Oct 6, 2024
973f759
refactor template 'show'
iryna-borniak Oct 9, 2024
18fdb98
refactor styles for 'cancel' button
iryna-borniak Oct 13, 2024
9e2a8b8
remove unnecessary seeds
iryna-borniak Oct 13, 2024
49d314d
merge develop
iryna-borniak Oct 13, 2024
0bca812
remove outdated tests
iryna-borniak Oct 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added app/assets/images/thrash_produced.png
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

чому не svg?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я просто замалював старий малюнок і зверху намалював сміття щоб хоч +- було ясно що показує

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 21 additions & 28 deletions app/controllers/account/calculators_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# frozen_string_literal: true

class Account::CalculatorsController < Account::BaseController
before_action :calculator, only: [:edit, :update, :destroy]
load_and_authorize_resource

def index
Expand All @@ -10,11 +9,16 @@ def index
end

def show
# TODO: fill it
@calculator = resource
end

def new
@products = products_collection
end

def edit
collect_fields_for_form
@calculator = resource
@products = products_collection
end

def create
Expand All @@ -23,22 +27,26 @@ def create
if @calculator.save
redirect_to account_calculators_path, notice: t("notifications.calculator_created")
else
@products = products_collection
loqimean marked this conversation as resolved.
Show resolved Hide resolved

render :new, status: :unprocessable_entity
end
end

def update
@calculator = resource

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
collect_fields_for_form
@products = products_collection
loqimean marked this conversation as resolved.
Show resolved Hide resolved

render :edit, status: :unprocessable_entity
end
end

def destroy
@calculator.destroy
resource.destroy

redirect_to account_calculators_path, notice: t("notifications.calculator_deleted"), status: :see_other
end
Expand All @@ -49,31 +57,12 @@ def collection
Calculator.ordered_by_name
end

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 }
def resource
collection.friendly.find(params[:slug])
end

def calculator_params
params.require(:calculator).permit(
:name, :id, :slug, :preferable,
fields_attributes: [
:id, :selector, :label, :name, :value, :unit, :from, :to, :type, :kind,
:_destroy
]
)
params.require(:calculator).permit(:name, :slug, :product_id)
end

def updater
Expand All @@ -82,4 +71,8 @@ def updater
@calculator.update(calculator_params)
end
end

def products_collection
Product.ordered_by_title
end
end
5 changes: 2 additions & 3 deletions app/controllers/account/categories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ def update
end

def destroy
@category = resource
@category.destroy
resource.destroy

redirect_to account_categories_path, notice: t("notifications.category_deleted")
redirect_to account_categories_path, notice: t("notifications.category_deleted"), status: :see_other
end

private
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/account/products_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def category_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
40 changes: 32 additions & 8 deletions app/controllers/api/v1/calculators_controller.rb
Original file line number Diff line number Diff line change
@@ -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?
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
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

та одною строкою

end
end

private

def collection
Calculator.all
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.ordered

end

def resource
collection.friendly.find(params[:slug])
end

def calculator_params
params.permit(:period, :price_id)
end

def product_resource
Product.find(resource.product_id)
end
end
2 changes: 1 addition & 1 deletion app/controllers/api/v1/diaper_calculators_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class Api::V1::DiaperCalculatorsController < ApplicationController
def calculate
@validation = CalculatorValidator.new(params)
@validation = DiaperCalculatorValidator.new(params)

if @validation.valid?
calc_service = Calculators::DiaperUsageService.new(params[:childs_years], params[:childs_months], set_category_id)
Expand Down
8 changes: 8 additions & 0 deletions app/helpers/calculators_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,12 @@ def old_calculator_items
{ image: "money_to_spent.png", data_target: "moneyWillBeSpent", text: t(".money_will_be_spent") },
{ image: "money_spent.png", data_target: "moneySpent", text: t(".money_spent") }]
end

def use_period
["day", "week", "month", "year"].map { |period| [I18n.t("calculators.date.#{period}"), period] }
end

def product_prices(calculator)
calculator.product.prices.map { |price| [price.category.name, price.id] }
end
end
50 changes: 50 additions & 0 deletions app/javascript/controllers/calculate_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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"];
static outlets = ["calculationresults"];
static values = {
url: {
type: String,
default: "en/api/v1/calculators",
},
};

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) {
this.calculationresultsOutlet.showResults(result);
} else if (response.statusCode == 422) {
toastUtils.showToast(result.error, "error");
}
}

getBasicOption(i) {
let option = document.createElement("option");

option.value = i;
option.innerText = i;

return option;
}
}
13 changes: 13 additions & 0 deletions app/javascript/controllers/calculationresults_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
static targets = [
"moneySpentResult",
"itemsUsedResult",
];

showResults(data) {
this.moneySpentResultTarget.innerHTML = data.moneySpent;
this.itemsUsedResultTarget.innerHTML = data.itemsUsed;
}
}
2 changes: 2 additions & 0 deletions app/models/calculator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class Calculator < ApplicationRecord

has_many :fields, dependent: :destroy

belongs_to :product
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Посортовано асоціації не гуд
https://github.com/rubocop/rails-style-guide?tab=readme-ov-file#macro-style-methods


accepts_nested_attributes_for :fields, allow_destroy: true

validates :name, presence: true
Expand Down
6 changes: 4 additions & 2 deletions app/models/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
class Product < ApplicationRecord
DIAPER = "diaper"

scope :ordered_by_title, -> { order(:title) }

has_one :calculator, dependent: :destroy
has_many :prices, as: :priceable, dependent: :destroy
has_many :categories_by_prices, through: :prices, source: :category

Expand All @@ -30,6 +29,9 @@ class Product < ApplicationRecord
uniqueness: true,
format: { with: /\A[a-zA-Zа-яієїґ'А-ЯІЄЇҐ0-9\-\s]+\z/ },
if: -> { title.present? }
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

Expand Down
36 changes: 36 additions & 0 deletions app/services/calculators/calculate_service.rb
Original file line number Diff line number Diff line change
@@ -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.5,
"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 = (product.default_usage_per_day * selected_price * period).to_i
items_used = (product.default_usage_per_day * period).to_i

{
moneySpent: money_spent,
itemsUsed: items_used
}
end

private

def selected_price
product.prices.find(params[:price_id]).sum
end
end
16 changes: 8 additions & 8 deletions app/validators/calculator_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ 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?
@error = I18n.t("calculators.errors.year_and_month_error_msg")
if period.blank? && price_id.blank?
@error = I18n.t("calculators.errors.period_and_price_error_msg")
false
elsif childs_years.blank?
@error = I18n.t("calculators.errors.year_error_msg")
elsif period.blank?
@error = I18n.t("calculators.errors.period_error_msg")
false
elsif childs_months.blank?
@error = I18n.t("calculators.errors.month_error_msg")
elsif price_id.blank?
@error = I18n.t("calculators.errors.price_error_msg")
false
else
true
Expand Down
27 changes: 27 additions & 0 deletions app/validators/diaper_calculator_validator.rb
Original file line number Diff line number Diff line change
@@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

це щось не окей, використай для цього форм обджект

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тоді і цей метод буде, і гарний спосіб описання валідацій

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

end
end
Loading
Loading