Commit e2854d1b648972bfdb0280bb07d4d5f6e9a63954
Committed by
Daniela Feitosa
1 parent
87ef45c5
Exists in
master
and in
28 other branches
Fixing some things when a cost is added or removed
(ActionItem1413)
Showing
7 changed files
with
91 additions
and
46 deletions
Show diff stats
app/helpers/manage_products_helper.rb
@@ -277,9 +277,9 @@ module ManageProductsHelper | @@ -277,9 +277,9 @@ module ManageProductsHelper | ||
277 | prompt_msg = _('Insert the name of the new cost:') | 277 | prompt_msg = _('Insert the name of the new cost:') |
278 | error_msg = _('Something went wrong. Please, try again') | 278 | error_msg = _('Something went wrong. Please, try again') |
279 | select_tag('price_details[][production_cost_id]', | 279 | select_tag('price_details[][production_cost_id]', |
280 | + '<option value="" disabled="disabled">' + _('Select...') + '</option>' + | ||
280 | options_for_select(product.available_production_costs.map {|item| [truncate(item.name, 10, '...'), item.id]} + [[_('Other cost'), '']], selected), | 281 | options_for_select(product.available_production_costs.map {|item| [truncate(item.name, 10, '...'), item.id]} + [[_('Other cost'), '']], selected), |
281 | - {:include_blank => _('Select the cost'), | ||
282 | - :class => 'production-cost-selection', | 282 | + {:class => 'production-cost-selection', |
283 | :onchange => "productionCostTypeChange(this, '#{url}', '#{prompt_msg}', '#{error_msg}')"}) | 283 | :onchange => "productionCostTypeChange(this, '#{url}', '#{prompt_msg}', '#{error_msg}')"}) |
284 | end | 284 | end |
285 | 285 | ||
@@ -288,6 +288,6 @@ module ManageProductsHelper | @@ -288,6 +288,6 @@ module ManageProductsHelper | ||
288 | production_cost = args[:production_cost_value] || product.formatted_value(:total_production_cost) | 288 | production_cost = args[:production_cost_value] || product.formatted_value(:total_production_cost) |
289 | product_price = args[:product_price] || product.formatted_value(:price) | 289 | product_price = args[:product_price] || product.formatted_value(:price) |
290 | 290 | ||
291 | - _("%{currency} %{production_cost} of %{currency} %{product_price}") % {:currency => currency, :production_cost => content_tag('span', production_cost, :class => '.production_cost'), :product_price => content_tag('span', product_price, :class => 'product_price')} | 291 | + _("%{currency} %{production_cost} of %{currency} %{product_price}") % {:currency => currency, :production_cost => content_tag('span', production_cost, :class => 'production_cost'), :product_price => content_tag('span', product_price, :class => 'product_price')} |
292 | end | 292 | end |
293 | end | 293 | end |
app/models/input.rb
@@ -59,4 +59,9 @@ class Input < ActiveRecord::Base | @@ -59,4 +59,9 @@ class Input < ActiveRecord::Base | ||
59 | return 0 if self.amount_used.blank? || self.price_per_unit.blank? | 59 | return 0 if self.amount_used.blank? || self.price_per_unit.blank? |
60 | self.amount_used * self.price_per_unit | 60 | self.amount_used * self.price_per_unit |
61 | end | 61 | end |
62 | + | ||
63 | + def cost | ||
64 | + return 0 if self.amount_used.blank? || self.price_per_unit.blank? | ||
65 | + self.amount_used * self.price_per_unit | ||
66 | + end | ||
62 | end | 67 | end |
app/views/manage_products/_edit_price_details.rhtml
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | <td> | 5 | <td> |
6 | <%= link_to_remote(_('Remove'), | 6 | <%= link_to_remote(_('Remove'), |
7 | :update => "price-detail-#{price_detail.id}", | 7 | :update => "price-detail-#{price_detail.id}", |
8 | - :success => "jQuery('#manage-product-details-form input.submit').removeAttr('disabled').removeClass('disabled');", | 8 | + :complete => "calculateValuesForBar();", |
9 | :confirm => _('Are you sure that you want to remove this cost?'), | 9 | :confirm => _('Are you sure that you want to remove this cost?'), |
10 | :url => { :action => 'remove_price_detail', :id => price_detail, :product => @product }) %> | 10 | :url => { :action => 'remove_price_detail', :id => price_detail, :product => @product }) %> |
11 | </tr> | 11 | </tr> |
app/views/manage_products/_inputs_cost.rhtml
1 | -<%= float_to_currency(@product.inputs_cost) %> | 1 | +<span><%= float_to_currency(@product.inputs_cost) %></span> |
2 | 2 | ||
3 | <div id='price-described-notice' style='display:none;'> | 3 | <div id='price-described-notice' style='display:none;'> |
4 | <%= _("Congratulations! Now the product's price is open to the public") %> | 4 | <%= _("Congratulations! Now the product's price is open to the public") %> |
app/views/manage_products/_manage_product_details.rhtml
@@ -30,8 +30,10 @@ | @@ -30,8 +30,10 @@ | ||
30 | <table id='new-cost-fields'> | 30 | <table id='new-cost-fields'> |
31 | <tr> | 31 | <tr> |
32 | <td><%= select_production_cost(@product) %></td> | 32 | <td><%= select_production_cost(@product) %></td> |
33 | - <td><%= labelled_form_field(environment.currency_unit, text_field_tag('price_details[][price]', nil, :class => 'price-details-price')) %></td> | 33 | + <td><%= labelled_form_field(environment.currency_unit, text_field_tag('price_details[][price]', nil, :class => 'numbers-only price-details-price')) %></td> |
34 | <td><%= link_to(_('Cancel'), '#', {:class => 'cancel-new-cost'}) %></td> | 34 | <td><%= link_to(_('Cancel'), '#', {:class => 'cancel-new-cost'}) %></td> |
35 | </tr> | 35 | </tr> |
36 | </table> | 36 | </table> |
37 | </div> | 37 | </div> |
38 | + | ||
39 | +<%= render :partial => 'shared/numbers_only_javascript' %> |
app/views/manage_products/_price_composition_bar.rhtml
1 | <% javascript_tag do %> | 1 | <% javascript_tag do %> |
2 | - var value = <%= @product.price_description_percentage %> | ||
3 | - var total_cost = <%= @product.total_production_cost %> | ||
4 | - var price = <%= @product.price %> | 2 | + var value = <%= @product.price_description_percentage %>; |
3 | + var total_cost = <%= @product.total_production_cost %>; | ||
4 | + var price = '<%= @product.formatted_value(:price) %>'; | ||
5 | var described = false; | 5 | var described = false; |
6 | + var currency_format = { separator : '<%= environment.currency_separator %>', delimiter : '<%= environment.currency_delimiter %>', unit : '<%= environment.currency_unit %>' }; | ||
6 | if (<%= @product.price_described? %>) { | 7 | if (<%= @product.price_described? %>) { |
7 | var described = true; | 8 | var described = true; |
8 | } | 9 | } |
public/javascripts/manage-products.js
@@ -44,6 +44,7 @@ | @@ -44,6 +44,7 @@ | ||
44 | 44 | ||
45 | $(".cancel-new-cost").live('click', function() { | 45 | $(".cancel-new-cost").live('click', function() { |
46 | $(this).parents('tr').remove(); | 46 | $(this).parents('tr').remove(); |
47 | + calculateValuesForBar(); | ||
47 | return false; | 48 | return false; |
48 | }); | 49 | }); |
49 | 50 | ||
@@ -57,25 +58,12 @@ | @@ -57,25 +58,12 @@ | ||
57 | updatePriceCompositionBar(form); | 58 | updatePriceCompositionBar(form); |
58 | inputs_cost_update_url = $(form).find('#inputs-cost-update-url').val(); | 59 | inputs_cost_update_url = $(form).find('#inputs-cost-update-url').val(); |
59 | $.get(inputs_cost_update_url, function(data){ | 60 | $.get(inputs_cost_update_url, function(data){ |
60 | - $(".inputs-cost").html(data); | 61 | + $(".inputs-cost span").html(data); |
61 | }); | 62 | }); |
62 | return false; | 63 | return false; |
63 | }); | 64 | }); |
64 | 65 | ||
65 | - $("#manage-product-details-form .price-details-price").live('keydown', function(data) { | ||
66 | - $('.cancel-price-details').addClass('form-changed'); | ||
67 | - var product_price = parseFloat($('form #product_price').val()); | ||
68 | - var total_cost = parseFloat($('#product_inputs_cost').val()); | ||
69 | - | ||
70 | - $('form .price-details-price').each(function() { | ||
71 | - total_cost = total_cost + parseFloat($(this).val()); | ||
72 | - }); | ||
73 | - enablePriceDetailSubmit(); | ||
74 | - | ||
75 | - var described = (product_price - total_cost) == 0; | ||
76 | - var percentage = total_cost * 100 / product_price; | ||
77 | - priceCompositionBar(percentage, described, total_cost, product_price); | ||
78 | - }); | 66 | + $("#manage-product-details-form .price-details-price").live('blur', function(data) { calculateValuesForBar(); }); |
79 | 67 | ||
80 | function cancelPriceDetailsEdition() { | 68 | function cancelPriceDetailsEdition() { |
81 | $("#manage-product-details-button").show(); | 69 | $("#manage-product-details-button").show(); |
@@ -87,35 +75,84 @@ | @@ -87,35 +75,84 @@ | ||
87 | bar_url = $(form).find('.bar-update-url').val(); | 75 | bar_url = $(form).find('.bar-update-url').val(); |
88 | $.get(bar_url, function(data){ | 76 | $.get(bar_url, function(data){ |
89 | $("#price-composition-bar").html(data); | 77 | $("#price-composition-bar").html(data); |
78 | + $('form #product_price').val(currencyToFloat($('#progressbar-text .product_price').html(), currency_format.separator, currency_format.delimiter)); | ||
79 | + $('form #product_inputs_cost').val(currencyToFloat($('#display-product-price-details .inputs-cost span').html(), currency_format.separator, currency_format.delimiter, currency_format.unit)); | ||
80 | + calculateValuesForBar(); | ||
90 | }); | 81 | }); |
91 | }; | 82 | }; |
92 | 83 | ||
93 | - function enablePriceDetailSubmit() { | ||
94 | - $('#manage-product-details-form input.submit').removeAttr("disabled").removeClass('disabled'); | ||
95 | - }; | ||
96 | - | ||
97 | })(jQuery); | 84 | })(jQuery); |
98 | 85 | ||
86 | +function enablePriceDetailSubmit() { | ||
87 | + jQuery('#manage-product-details-form input.submit').removeAttr("disabled").removeClass('disabled'); | ||
88 | +} | ||
89 | + | ||
90 | +function calculateValuesForBar() { | ||
91 | + jQuery('.cancel-price-details').addClass('form-changed'); | ||
92 | + var product_price = parseFloat(jQuery('form #product_price').val()); | ||
93 | + var total_cost = parseFloat(jQuery('form #product_inputs_cost').val()); | ||
94 | + | ||
95 | + jQuery('form .price-details-price').each(function() { | ||
96 | + var this_val = parseFloat(jQuery(this).val()) || 0; | ||
97 | + total_cost = total_cost + this_val; | ||
98 | + }); | ||
99 | + enablePriceDetailSubmit(); | ||
100 | + | ||
101 | + var described = (product_price - total_cost) == 0; | ||
102 | + var percentage = total_cost * 100 / product_price; | ||
103 | + priceCompositionBar(percentage, described, total_cost, product_price); | ||
104 | +} | ||
105 | + | ||
106 | +function addCommas(nStr) { | ||
107 | + nStr += ''; | ||
108 | + var x = nStr.split('.'); | ||
109 | + var x1 = x[0]; | ||
110 | + var x2 = x.length > 1 ? '.' + x[1] : ''; | ||
111 | + var rgx = /(\d+)(\d{3})/; | ||
112 | + while (rgx.test(x1)) { | ||
113 | + x1 = x1.replace(rgx, '$1' + ',' + '$2'); | ||
114 | + } | ||
115 | + return x1 + x2; | ||
116 | +} | ||
117 | + | ||
118 | +function floatToCurrency(value, sep, del, cur) { | ||
119 | + var ret = ''; | ||
120 | + if (cur) ret = cur + ' '; | ||
121 | + if (!sep) sep = '.'; | ||
122 | + if (!del) del = ','; | ||
123 | + return ret + addCommas(parseFloat(value).toFixed(2).toString()).replace('.', '%sep%').replace(',', del).replace('%sep%', sep); | ||
124 | +} | ||
125 | + | ||
126 | +function currencyToFloat(value, sep, del, cur) { | ||
127 | + var val = value; | ||
128 | + if (cur) val.replace(cur + ' ', ''); | ||
129 | + if (!sep) sep = '.'; | ||
130 | + if (!del) del = ','; | ||
131 | + return parseFloat(val.replace(del, '').replace(sep, '.')); | ||
132 | +} | ||
133 | + | ||
99 | function productionCostTypeChange(select, url, question, error_msg) { | 134 | function productionCostTypeChange(select, url, question, error_msg) { |
100 | if (select.value == '') { | 135 | if (select.value == '') { |
101 | var newType = prompt(question); | 136 | var newType = prompt(question); |
102 | - jQuery.ajax({ | ||
103 | - url: url + "/" + newType, | ||
104 | - dataType: 'json', | ||
105 | - success: function(data, status, ajax){ | ||
106 | - if (data.ok) { | ||
107 | - var opt = jQuery('<option value="' + data.id + '">' + newType + '</option>'); | ||
108 | - opt.insertBefore(jQuery("option:last", select)); | ||
109 | - select.selectedIndex = select.options.length - 2; | ||
110 | - opt.clone().insertBefore('#new-cost-fields .production-cost-selection option:last'); | ||
111 | - } else { | ||
112 | - alert(data.error_msg); | 137 | + if (newType) { |
138 | + jQuery.ajax({ | ||
139 | + url: url + "/" + newType, | ||
140 | + dataType: 'json', | ||
141 | + success: function(data, status, ajax){ | ||
142 | + if (data.ok) { | ||
143 | + var opt = jQuery('<option value="' + data.id + '">' + newType + '</option>'); | ||
144 | + opt.insertBefore(jQuery("option:last", select)); | ||
145 | + select.selectedIndex = select.options.length - 2; | ||
146 | + opt.clone().insertBefore('#new-cost-fields .production-cost-selection option:last'); | ||
147 | + } else { | ||
148 | + alert(data.error_msg); | ||
149 | + } | ||
150 | + }, | ||
151 | + error: function(ajax, status, error){ | ||
152 | + alert(error_msg); | ||
113 | } | 153 | } |
114 | - }, | ||
115 | - error: function(ajax, status, error){ | ||
116 | - alert(error_msg); | ||
117 | - } | ||
118 | - }); | 154 | + }); |
155 | + } | ||
119 | } | 156 | } |
120 | } | 157 | } |
121 | 158 | ||
@@ -125,8 +162,8 @@ function priceCompositionBar(value, described, total_cost, price) { | @@ -125,8 +162,8 @@ function priceCompositionBar(value, described, total_cost, price) { | ||
125 | $(bar_area).find('#progressbar').progressbar({ | 162 | $(bar_area).find('#progressbar').progressbar({ |
126 | value: value | 163 | value: value |
127 | }); | 164 | }); |
128 | - $(bar_area).find('.production-cost').html(total_cost.toFixed(2)); | ||
129 | - $(bar_area).find('.product_price').html(price.toFixed(2)); | 165 | + $(bar_area).find('.production_cost').html(floatToCurrency(total_cost, currency_format.separator, currency_format.delimiter)); |
166 | + $(bar_area).find('.product_price').html(floatToCurrency(price, currency_format.separator, currency_format.delimiter)); | ||
130 | if (described) { | 167 | if (described) { |
131 | $(bar_area).find('#progressbar-icon').addClass('ui-icon-check'); | 168 | $(bar_area).find('#progressbar-icon').addClass('ui-icon-check'); |
132 | $(bar_area).find('#progressbar-icon').attr('title', $('#price-described-message').html()); | 169 | $(bar_area).find('#progressbar-icon').attr('title', $('#price-described-message').html()); |