diff --git a/Gemfile b/Gemfile index 0dfd18292d3..7b89661973e 100644 --- a/Gemfile +++ b/Gemfile @@ -158,6 +158,7 @@ end gem 'autoprefixer-rails', '~> 9.7.4' gem 'bourbon', '~> 6.0.0' gem 'i18n-js', '~> 3.6.0' +gem 'rails-i18n', '~> 6.0.0' gem 'sassc-rails', '~> 2.1.0' gem 'sprockets', '~> 3.7.0' diff --git a/Gemfile.lock b/Gemfile.lock index 20634dbb127..50d1f4c06e0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -739,6 +739,9 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) + rails-i18n (6.0.0) + i18n (>= 0.7, < 2) + railties (>= 6.0.0, < 7) rails_12factor (0.0.3) rails_serve_static_assets rails_stdout_logging @@ -1064,6 +1067,7 @@ DEPENDENCIES rack_session_access rails (~> 6.0.2) rails-controller-testing (~> 1.0.2) + rails-i18n (~> 6.0.0) rails_12factor rdoc (>= 2.4.2) reform (~> 2.2.0) diff --git a/modules/costs/app/helpers/costs/number_helper.rb b/modules/costs/app/helpers/costs/number_helper.rb index 55391a63ad7..f4014d70d69 100644 --- a/modules/costs/app/helpers/costs/number_helper.rb +++ b/modules/costs/app/helpers/costs/number_helper.rb @@ -59,6 +59,11 @@ module Costs::NumberHelper 0.0 end + # Output currency value without unit + def unitless_currency_number(value) + number_to_currency(value, format: '%n') + end + def to_currency_with_empty(rate) rate.nil? ? '0.0' : number_to_currency(rate.rate) end diff --git a/modules/costs/app/views/cost_objects/items/_labor_budget_item.html.erb b/modules/costs/app/views/cost_objects/items/_labor_budget_item.html.erb index b690c0a5e25..d26369bee53 100644 --- a/modules/costs/app/views/cost_objects/items/_labor_budget_item.html.erb +++ b/modules/costs/app/views/cost_objects/items/_labor_budget_item.html.erb @@ -87,7 +87,7 @@ See docs/COPYRIGHT.rdoc for more details. obj-name="<%= "#{name_prefix}[budget]" %>"> " class="costs--edit-planned-costs-btn icon-context icon-edit" title="<%= t(:help_click_to_edit) %>"> <% if labor_budget_item.costs_visible_by?(User.current) %> - <%= cost_form.hidden_field :cost_value, index: id_or_index, value: cost_value %> + <%= cost_form.hidden_field :cost_value, index: id_or_index, value: unitless_currency_number(cost_value) %> <%= number_to_currency(cost_value) %> <% end %> diff --git a/modules/costs/app/views/cost_objects/items/_material_budget_item.html.erb b/modules/costs/app/views/cost_objects/items/_material_budget_item.html.erb index 427e861f856..ac0460132b1 100644 --- a/modules/costs/app/views/cost_objects/items/_material_budget_item.html.erb +++ b/modules/costs/app/views/cost_objects/items/_material_budget_item.html.erb @@ -84,7 +84,7 @@ See docs/COPYRIGHT.rdoc for more details. <% end %> <% cost_value = material_budget_item.budget || material_budget_item.calculated_costs(@cost_object.fixed_date) %> <%= cost_form.hidden_field :currency, index: id_or_index, value: Setting.plugin_openproject_costs['costs_currency'] %> - <%= cost_form.hidden_field :cost_value, index: id_or_index, value: cost_value %> + <%= cost_form.hidden_field :cost_value, index: id_or_index, value: unitless_currency_number(cost_value) %> "> diff --git a/modules/costs/frontend/module/augment/planned-costs-form.ts b/modules/costs/frontend/module/augment/planned-costs-form.ts index def2085cf98..8d0fdfde3cc 100644 --- a/modules/costs/frontend/module/augment/planned-costs-form.ts +++ b/modules/costs/frontend/module/augment/planned-costs-form.ts @@ -91,8 +91,8 @@ export class PlannedCostsFormAugment { jQuery(template).insertAfter(this.obj); let that = this; - jQuery('#' + id + '_costs_cancel').on('click', function () { - jQuery('#' + id + '_costs_section').remove(); + jQuery('#' + id + '_cancel').on('click', function () { + jQuery('#' + id + '_section').remove(); that.obj.show(); return false; }); diff --git a/modules/costs/spec/features/budgets/update_budget_spec.rb b/modules/costs/spec/features/budgets/update_budget_spec.rb index 030b9fd834c..3a4ac283586 100644 --- a/modules/costs/spec/features/budgets/update_budget_spec.rb +++ b/modules/costs/spec/features/budgets/update_budget_spec.rb @@ -133,6 +133,28 @@ describe 'updating a budget', type: :feature, js: true do expect(budget_page.overall_labor_costs).to have_content '75.00 EUR' end + context 'with german locale' do + let(:user) { FactoryBot.create :admin, language: :de } + + it 'retains the overridden budget when opening, but not editing (Regression #32822)' do + budget_page.visit! + click_on 'Bearbeiten' + + budget_page.expect_planned_costs! type: :material, row: 1, expected: '150,00 EUR' + budget_page.expect_planned_costs! type: :labor, row: 1, expected: '125,00 EUR' + + # Open first item + budget_page.open_edit_planned_costs! material_budget_item.id, type: :material + expect(page).to have_field("cost_object_existing_material_budget_item_attributes_#{material_budget_item.id}_costs_edit") + + click_on 'OK' + expect(budget_page).to have_content("Erfolgreich aktualisiert.") + + expect(page).to have_selector('tbody td.currency', text: '150,00 EUR') + expect(page).to have_selector('tbody td.currency', text: '125,00 EUR') + end + end + context 'with two material budget items' do let!(:material_budget_item_2) do FactoryBot.create :material_budget_item, units: 5, diff --git a/modules/costs/spec/support/pages/budget_form.rb b/modules/costs/spec/support/pages/budget_form.rb index ef6722e8218..c62eb43a405 100644 --- a/modules/costs/spec/support/pages/budget_form.rb +++ b/modules/costs/spec/support/pages/budget_form.rb @@ -58,13 +58,21 @@ module Pages fill_in "#{prefix}_comments", with: comment if comment.present? end - def edit_planned_costs!(id, costs:, type: ) + def open_edit_planned_costs!(id, type:) row_id = "#cost_object_existing_#{type}_budget_item_attributes_#{id}" - editor_name = "cost_object_existing_#{type}_budget_item_attributes_#{id}_costs_edit" - page.within row_id do find('.costs--edit-planned-costs-btn').click + end + end + + def edit_planned_costs!(id, costs:, type: ) + open_edit_planned_costs!(id, type: type) + + row_id = "#cost_object_existing_#{type}_budget_item_attributes_#{id}" + editor_name = "cost_object_existing_#{type}_budget_item_attributes_#{id}_costs_edit" + + page.within row_id do fill_in editor_name, with: costs end