Commit 31868a1af19ba6c59d9c2fe104c7328a20772ab0

Authored by Braulio Bhavamitra
1 parent bb150fb8

Move products into a plugin

This will many further improvements to the products, such as:
- Interaction with other plugins such as suppliers, stock and
currencies. The inteface can change in such a way that if done
usings hotspots would hurt usability and coherence.
- More autonomy to develop and integrate other features
(in the next months we will integrate batch edition and stock,
currencies might come next)
- More declouping from core and other components
Showing 299 changed files with 8263 additions and 7886 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 299 files displayed.

app/controllers/admin/categories_controller.rb
@@ -7,7 +7,6 @@ class CategoriesController < AdminController @@ -7,7 +7,6 @@ class CategoriesController < AdminController
7 def index 7 def index
8 @categories = environment.categories.where("parent_id is null AND type is null") 8 @categories = environment.categories.where("parent_id is null AND type is null")
9 @regions = environment.regions.where(:parent_id => nil) 9 @regions = environment.regions.where(:parent_id => nil)
10 - @product_categories = environment.product_categories.where(:parent_id => nil)  
11 end 10 end
12 11
13 def get_children 12 def get_children
app/controllers/admin/edit_template_controller.rb
1 class EditTemplateController < AdminController 1 class EditTemplateController < AdminController
2 - 2 +
3 protect 'edit_environment_design', :environment 3 protect 'edit_environment_design', :environment
4 - 4 +
5 #FIXME 5 #FIXME
6 #design_editor :holder => 'environment', :autosave => true, :block_types => :block_types 6 #design_editor :holder => 'environment', :autosave => true, :block_types => :block_types
7 7
@@ -9,7 +9,6 @@ class EditTemplateController &lt; AdminController @@ -9,7 +9,6 @@ class EditTemplateController &lt; AdminController
9 %w[ 9 %w[
10 FavoriteLinks 10 FavoriteLinks
11 ListBlock 11 ListBlock
12 - SellersSearchBlock  
13 ] 12 ]
14 end 13 end
15 14
app/controllers/admin/environment_design_controller.rb
1 class EnvironmentDesignController < BoxOrganizerController 1 class EnvironmentDesignController < BoxOrganizerController
2 - 2 +
3 protect 'edit_environment_design', :environment 3 protect 'edit_environment_design', :environment
4 4
5 def available_blocks 5 def available_blocks
6 - @available_blocks ||= [ ArticleBlock, LoginBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] 6 + @available_blocks ||= [ ArticleBlock, LoginBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ]
7 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) 7 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment)
8 end 8 end
9 9
app/controllers/my_profile/cms_controller.rb
@@ -409,9 +409,6 @@ class CmsController &lt; MyProfileController @@ -409,9 +409,6 @@ class CmsController &lt; MyProfileController
409 ] 409 ]
410 articles += special_article_types if params && params[:cms] 410 articles += special_article_types if params && params[:cms]
411 parent_id = params ? params[:parent_id] : nil 411 parent_id = params ? params[:parent_id] : nil
412 - if profile.enterprise?  
413 - articles << EnterpriseHomepage  
414 - end  
415 if @parent && @parent.blog? 412 if @parent && @parent.blog?
416 articles -= Article.folder_types.map(&:constantize) 413 articles -= Article.folder_types.map(&:constantize)
417 end 414 end
app/controllers/my_profile/manage_products_controller.rb
@@ -1,229 +0,0 @@ @@ -1,229 +0,0 @@
1 -class ManageProductsController < ApplicationController  
2 - needs_profile  
3 -  
4 - protect 'manage_products', :profile, :except => [:show]  
5 - before_filter :check_environment_feature  
6 - before_filter :login_required, :except => [:show]  
7 - before_filter :create_product?, :only => [:new]  
8 -  
9 - protected  
10 -  
11 - def check_environment_feature  
12 - unless profile.environment.enabled?('products_for_enterprises')  
13 - render_not_found  
14 - return  
15 - end  
16 - end  
17 -  
18 - def create_product?  
19 - if !profile.create_product?  
20 - render_access_denied  
21 - return  
22 - end  
23 - end  
24 -  
25 - public  
26 -  
27 - def index  
28 - @products = @profile.products.paginate(:per_page => 10, :page => params[:page])  
29 - end  
30 -  
31 - def show  
32 - @product = @profile.products.find(params[:id])  
33 - @inputs = @product.inputs  
34 - @allowed_user = user && user.has_permission?('manage_products', profile)  
35 - end  
36 -  
37 - def categories_for_selection  
38 - @category = environment.categories.find_by id: params[:category_id]  
39 - @object_name = params[:object_name]  
40 - if @category  
41 - @categories = @category.children  
42 - @level = @category.leaf? ? @category.level : @categories.first.level  
43 - else  
44 - @categories = ProductCategory.top_level_for(environment)  
45 - @level = 0  
46 - end  
47 - render :partial => 'categories_for_selection', :locals => { :categories => @categories, :level => @level }  
48 - end  
49 -  
50 - def new  
51 - @no_design_blocks = true  
52 - @category = params[:selected_category_id] ? Category.find(params[:selected_category_id]) : nil  
53 - @product = @profile.products.build(:product_category => @category)  
54 - @categories = ProductCategory.top_level_for(environment)  
55 - @level = 0  
56 - if request.post?  
57 - if @product.save  
58 - session[:notice] = _('Product succesfully created')  
59 - render :partial => 'shared/redirect_via_javascript',  
60 - :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) }  
61 - else  
62 - render_dialog_error_messages 'product'  
63 - end  
64 - end  
65 - end  
66 -  
67 - def edit  
68 - @product = @profile.products.find(params[:id])  
69 - field = params[:field]  
70 - if request.post?  
71 - begin  
72 - @product.update!(params[:product])  
73 - render :partial => "display_#{field}", :locals => {:product => @product}  
74 - rescue Exception => e  
75 - render :partial => "edit_#{field}", :locals => {:product => @product, :errors => true}  
76 - end  
77 - else  
78 - render :partial => "edit_#{field}", :locals => {:product => @product, :errors => false}  
79 - end  
80 - end  
81 -  
82 - def edit_category  
83 - @product = @profile.products.find(params[:id])  
84 - @category = @product.product_category || ProductCategory.first  
85 - @categories = ProductCategory.top_level_for(environment)  
86 - @edit = true  
87 - @level = @category.level  
88 - if request.post?  
89 - if @product.update({:product_category_id => params[:selected_category_id]}, :without_protection => true)  
90 - render :partial => 'shared/redirect_via_javascript',  
91 - :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) }  
92 - else  
93 - render_dialog_error_messages 'product'  
94 - end  
95 - end  
96 - end  
97 -  
98 - def show_category_tree  
99 - @category = environment.categories.find params[:category_id]  
100 - render :partial => 'selected_category_tree'  
101 - end  
102 -  
103 - def search_categories  
104 - @term = params[:term].downcase  
105 - conditions = ['LOWER(name) LIKE ? OR LOWER(name) LIKE ?', "#{@term}%", "% #{@term}%"]  
106 - @categories = ProductCategory.where(conditions).limit(10)  
107 - render :json => (@categories.map do |category|  
108 - {:label => category.name, :value => category.id}  
109 - end)  
110 - end  
111 -  
112 - def add_input  
113 - @product = @profile.products.find(params[:id])  
114 - @input = @product.inputs.build  
115 - @categories = ProductCategory.top_level_for(environment)  
116 - @level = 0  
117 - if request.post?  
118 - if @input.update(:product_category_id => params[:selected_category_id])  
119 - @inputs = @product.inputs  
120 - render :partial => 'display_inputs'  
121 - else  
122 - render_dialog_error_messages 'product'  
123 - end  
124 - else  
125 - render :partial => 'add_input'  
126 - end  
127 - end  
128 -  
129 - def manage_product_details  
130 - @product = @profile.products.find(params[:id])  
131 - if request.post?  
132 - @product.update_price_details(params[:price_details]) if params[:price_details]  
133 - render :partial => 'display_price_details'  
134 - else  
135 - render :partial => 'manage_product_details'  
136 - end  
137 - end  
138 -  
139 - def remove_price_detail  
140 - @product = @profile.products.find(params[:product])  
141 - @price_detail = @product.price_details.find(params[:id])  
142 - @product = @price_detail.product  
143 - if request.post?  
144 - @price_detail.destroy  
145 - render :nothing => true  
146 - end  
147 - end  
148 -  
149 - def display_price_composition_bar  
150 - @product = @profile.products.find(params[:id])  
151 - render :partial => 'price_composition_bar'  
152 - end  
153 -  
154 - def display_inputs_cost  
155 - @product = @profile.products.find(params[:id])  
156 - render :inline => "<%= float_to_currency(@product.inputs_cost) %>"  
157 - end  
158 -  
159 - def destroy  
160 - @product = @profile.products.find(params[:id])  
161 - if @product.destroy  
162 - session[:notice] = _('Product succesfully removed')  
163 - redirect_back_or_default :action => 'index'  
164 - else  
165 - session[:notice] = _('Could not remove the product')  
166 - redirect_back_or_default :action => 'show', :id => @product  
167 - end  
168 - end  
169 -  
170 - def edit_input  
171 - if request.xhr?  
172 - @input = @profile.inputs.find_by id: params[:id]  
173 - if @input  
174 - if request.post?  
175 - if @input.update(params[:input])  
176 - render :partial => 'display_input', :locals => {:input => @input}  
177 - else  
178 - render :partial => 'edit_input'  
179 - end  
180 - else  
181 - render :partial => 'edit_input'  
182 - end  
183 - else  
184 - render :text => _('The input was not found')  
185 - end  
186 - end  
187 - end  
188 -  
189 - def order_inputs  
190 - @product = @profile.products.find(params[:id])  
191 - @product.order_inputs!(params[:input]) if params[:input]  
192 - render :nothing => true  
193 - end  
194 -  
195 - def remove_input  
196 - @input = @profile.inputs.find(params[:id])  
197 - @product = @input.product  
198 - if request.post?  
199 - if @input.destroy  
200 - @inputs = @product.inputs  
201 - render :partial => 'display_inputs'  
202 - else  
203 - render_dialog_error_messages 'input'  
204 - end  
205 - end  
206 - end  
207 -  
208 - def certifiers_for_selection  
209 - @qualifier = Qualifier.exists?(:id => params[:id]) ? Qualifier.find(params[:id]) : nil  
210 - render :update do |page|  
211 - page.replace_html params[:certifier_area], :partial => 'certifiers_for_selection'  
212 - end  
213 - end  
214 -  
215 - def create_production_cost  
216 - cost = @profile.production_costs.create(:name => params[:id])  
217 - if cost.valid?  
218 - cost.save  
219 - render :text => {:name => cost.name,  
220 - :id => cost.id,  
221 - :ok => true  
222 - }.to_json  
223 - else  
224 - render :text => {:ok => false,  
225 - :error_msg => _(cost.errors['name'].join('\n')) % {:fn => _('Name')}  
226 - }.to_json  
227 - end  
228 - end  
229 -end  
app/controllers/my_profile/profile_design_controller.rb
@@ -45,17 +45,10 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -45,17 +45,10 @@ class ProfileDesignController &lt; BoxOrganizerController
45 if profile.enterprise? 45 if profile.enterprise?
46 blocks << DisabledEnterpriseMessageBlock 46 blocks << DisabledEnterpriseMessageBlock
47 blocks << HighlightsBlock 47 blocks << HighlightsBlock
48 - blocks << ProductCategoriesBlock  
49 - blocks << FeaturedProductsBlock  
50 blocks << FansBlock 48 blocks << FansBlock
51 blocks += plugins.dispatch(:extra_blocks, :type => Enterprise) 49 blocks += plugins.dispatch(:extra_blocks, :type => Enterprise)
52 end 50 end
53 51
54 - # product block exclusive for enterprises in environments that permits it  
55 - if profile.enterprise? && profile.environment.enabled?('products_for_enterprises')  
56 - blocks << ProductsBlock  
57 - end  
58 -  
59 # block exclusive to profiles that have blog 52 # block exclusive to profiles that have blog
60 if profile.has_blog? 53 if profile.has_blog?
61 blocks << BlogArchivesBlock 54 blocks << BlogArchivesBlock
app/controllers/public/catalog_controller.rb
@@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
1 -class CatalogController < PublicController  
2 - needs_profile  
3 -  
4 - before_filter :check_enterprise_and_environment  
5 -  
6 - def index  
7 - extend CatalogHelper  
8 - catalog_load_index  
9 - end  
10 -  
11 - protected  
12 -  
13 - def check_enterprise_and_environment  
14 - unless profile.enterprise? && @profile.environment.enabled?('products_for_enterprises')  
15 - redirect_to :controller => 'profile', :profile => profile.identifier, :action => 'index'  
16 - end  
17 - end  
18 -  
19 -end  
app/controllers/public/search_controller.rb
@@ -52,7 +52,6 @@ class SearchController &lt; PublicController @@ -52,7 +52,6 @@ class SearchController &lt; PublicController
52 [ 52 [
53 [ :people, _('People'), :recent_people ], 53 [ :people, _('People'), :recent_people ],
54 [ :enterprises, _('Enterprises'), :recent_enterprises ], 54 [ :enterprises, _('Enterprises'), :recent_enterprises ],
55 - [ :products, _('Products'), :recent_products ],  
56 [ :events, _('Upcoming events'), :upcoming_events ], 55 [ :events, _('Upcoming events'), :upcoming_events ],
57 [ :communities, _('Communities'), :recent_communities ], 56 [ :communities, _('Communities'), :recent_communities ],
58 [ :articles, _('Contents'), :recent_articles ] 57 [ :articles, _('Contents'), :recent_articles ]
@@ -78,16 +77,17 @@ class SearchController &lt; PublicController @@ -78,16 +77,17 @@ class SearchController &lt; PublicController
78 full_text_search 77 full_text_search
79 end 78 end
80 79
81 - def products  
82 - @scope = @environment.products  
83 - full_text_search  
84 - end  
85 -  
86 def enterprises 80 def enterprises
87 @scope = visible_profiles(Enterprise) 81 @scope = visible_profiles(Enterprise)
88 full_text_search 82 full_text_search
89 end 83 end
90 84
  85 + # keep URL compatibility
  86 + def products
  87 + return render_not_found unless defined? ProductsPlugin
  88 + redirect_to url_for(params.merge controller: 'products_plugin/search', action: :products)
  89 + end
  90 +
91 def communities 91 def communities
92 @scope = visible_profiles(Community) 92 @scope = visible_profiles(Community)
93 full_text_search 93 full_text_search
@@ -186,7 +186,6 @@ class SearchController &lt; PublicController @@ -186,7 +186,6 @@ class SearchController &lt; PublicController
186 people: _('People'), 186 people: _('People'),
187 communities: _('Communities'), 187 communities: _('Communities'),
188 enterprises: _('Enterprises'), 188 enterprises: _('Enterprises'),
189 - products: _('Products and Services'),  
190 events: _('Events'), 189 events: _('Events'),
191 } 190 }
192 end 191 end
@@ -260,12 +259,11 @@ class SearchController &lt; PublicController @@ -260,12 +259,11 @@ class SearchController &lt; PublicController
260 end 259 end
261 260
262 def available_assets 261 def available_assets
263 - assets = { 262 + {
264 articles: _('Contents'), 263 articles: _('Contents'),
265 enterprises: _('Enterprises'), 264 enterprises: _('Enterprises'),
266 people: _('People'), 265 people: _('People'),
267 communities: _('Communities'), 266 communities: _('Communities'),
268 - products: _('Products and Services'),  
269 } 267 }
270 end 268 end
271 269
app/helpers/action_tracker_helper.rb
@@ -67,24 +67,6 @@ module ActionTrackerHelper @@ -67,24 +67,6 @@ module ActionTrackerHelper
67 } 67 }
68 end 68 end
69 69
70 - def create_product_description ta  
71 - _('created the product %{title}') % {  
72 - title: link_to(truncate(ta.get_name), ta.get_url),  
73 - }  
74 - end  
75 -  
76 - def update_product_description ta  
77 - _('updated the product %{title}') % {  
78 - title: link_to(truncate(ta.get_name), ta.get_url),  
79 - }  
80 - end  
81 -  
82 - def remove_product_description ta  
83 - _('removed the product %{title}') % {  
84 - title: truncate(ta.get_name),  
85 - }  
86 - end  
87 -  
88 def favorite_enterprise_description ta 70 def favorite_enterprise_description ta
89 _('favorited enterprise %{title}') % { 71 _('favorited enterprise %{title}') % {
90 title: link_to(truncate(ta.get_enterprise_name), ta.get_enterprise_url), 72 title: link_to(truncate(ta.get_enterprise_name), ta.get_enterprise_url),
app/helpers/application_helper.rb
@@ -44,8 +44,6 @@ module ApplicationHelper @@ -44,8 +44,6 @@ module ApplicationHelper
44 44
45 include TokenHelper 45 include TokenHelper
46 46
47 - include CatalogHelper  
48 -  
49 include PluginsHelper 47 include PluginsHelper
50 48
51 include ButtonsHelper 49 include ButtonsHelper
@@ -787,7 +785,7 @@ module ApplicationHelper @@ -787,7 +785,7 @@ module ApplicationHelper
787 return "" if categories.blank? 785 return "" if categories.blank?
788 content_tag(:ul) do 786 content_tag(:ul) do
789 categories.map do |category| 787 categories.map do |category|
790 - category_path = category.kind_of?(ProductCategory) ? {:controller => 'search', :action => 'assets', :asset => 'products', :product_category => category.id} : { :controller => 'search', :action => 'category_index', :category_path => category.explode_path } 788 + category_path = { :controller => 'search', :action => 'category_index', :category_path => category.explode_path }
791 if category.display_in_menu? 789 if category.display_in_menu?
792 content_tag(:li) do 790 content_tag(:li) do
793 if !category.is_leaf_displayable_in_menu? 791 if !category.is_leaf_displayable_in_menu?
app/helpers/catalog_helper.rb
@@ -1,45 +0,0 @@ @@ -1,45 +0,0 @@
1 -module CatalogHelper  
2 -  
3 - include DisplayHelper  
4 - include ManageProductsHelper  
5 -  
6 - def catalog_load_index options = {:page => params[:page], :show_categories => true}  
7 - if options[:show_categories]  
8 - @category = params[:level] ? ProductCategory.find(params[:level]) : nil  
9 - @categories = ProductCategory.on_level(params[:level]).order(:name)  
10 - end  
11 -  
12 - @products = profile.products.from_category(@category).  
13 - reorder('available desc, highlighted desc, name asc').  
14 - paginate(:per_page => @profile.products_per_catalog_page, :page => options[:page])  
15 - end  
16 -  
17 - def breadcrumb(category)  
18 - start = link_to(_('Start'), {:controller => :catalog, :action => 'index'})  
19 - ancestors = category.ancestors.map { |c| link_to(c.name, {:controller => :catalog, :action => 'index', :level => c.id}) }.reverse  
20 - current_level = content_tag('strong', category.name)  
21 - all_items = [start] + ancestors + [current_level]  
22 - content_tag('div', safe_join(all_items, ' &rarr; '), :id => 'breadcrumb')  
23 - end  
24 -  
25 - def category_link(category)  
26 - count = profile.products.from_category(category).count  
27 - name = truncate(category.name, :length => 22 - count.to_s.size)  
28 - link = link_to(name, {:controller => 'catalog', :action => 'index', :level => category.id}, :title => category.name)  
29 - content_tag('div', "#{link} <span class=\"count\">#{count}</span>".html_safe) if count > 0  
30 - end  
31 -  
32 - def category_with_sub_list(category)  
33 - content_tag 'li', "#{category_link(category)}\n#{sub_category_list(category)}".html_safe  
34 - end  
35 -  
36 - def sub_category_list(category)  
37 - sub_categories = []  
38 - category.children.order(:name).each do |sub_category|  
39 - cat_link = category_link sub_category  
40 - sub_categories << content_tag('li', cat_link) unless cat_link.nil?  
41 - end  
42 - content_tag('ul', sub_categories.join.html_safe) if sub_categories.size > 0  
43 - end  
44 -  
45 -end  
app/helpers/categories_helper.rb
@@ -2,7 +2,6 @@ module CategoriesHelper @@ -2,7 +2,6 @@ module CategoriesHelper
2 2
3 TYPES = [ 3 TYPES = [
4 [ _('General Category'), Category.to_s ], 4 [ _('General Category'), Category.to_s ],
5 - [ _('Product Category'), ProductCategory.to_s ],  
6 [ _('Region'), Region.to_s ], 5 [ _('Region'), Region.to_s ],
7 ] 6 ]
8 7
app/helpers/display_helper.rb
1 module DisplayHelper 1 module DisplayHelper
2 2
3 - def link_to_product(product, opts={})  
4 - return _('No product') unless product  
5 - target = product_path(product)  
6 - link_to content_tag( 'span', product.name ),  
7 - target,  
8 - opts  
9 - end  
10 -  
11 def themed_path(file) 3 def themed_path(file)
12 if File.exists?(File.join(Rails.root, 'public', theme_path, file)) 4 if File.exists?(File.join(Rails.root, 'public', theme_path, file))
13 File.join(theme_path, file) 5 File.join(theme_path, file)
@@ -16,42 +8,21 @@ module DisplayHelper @@ -16,42 +8,21 @@ module DisplayHelper
16 end 8 end
17 end 9 end
18 10
19 - def image_link_to_product(product, opts={})  
20 - return _('No product') unless product  
21 - target = product_path(product)  
22 - link_to image_tag(product.default_image(:big), :alt => product.name),  
23 - target,  
24 - opts  
25 - end  
26 -  
27 def price_span(price, options = {}) 11 def price_span(price, options = {})
28 content_tag 'span', 12 content_tag 'span',
29 number_to_currency(price, :unit => environment.currency_unit, :delimiter => environment.currency_delimiter, :separator => environment.currency_separator), 13 number_to_currency(price, :unit => environment.currency_unit, :delimiter => environment.currency_delimiter, :separator => environment.currency_separator),
30 options 14 options
31 end 15 end
32 16
33 - def product_path(product)  
34 - product.enterprise.enabled? ? product.enterprise.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => product) : product.enterprise.url  
35 - end  
36 -  
37 def link_to_tag(tag, html_options = {}) 17 def link_to_tag(tag, html_options = {})
38 link_to tag.name, {:controller => 'search', :action => 'tag', :tag => tag.name}, html_options 18 link_to tag.name, {:controller => 'search', :action => 'tag', :tag => tag.name}, html_options
39 end 19 end
40 20
41 def link_to_category(category, full = true, html_options = {}) 21 def link_to_category(category, full = true, html_options = {})
42 - return _('Uncategorized product') unless category  
43 name = full ? category.full_name(' &rarr; ') : category.name 22 name = full ? category.full_name(' &rarr; ') : category.name
44 link_to name, Noosfero.url_options.merge({:controller => 'search', :action => 'category_index', :category_path => category.path.split('/'),:host => category.environment.default_hostname }), html_options 23 link_to name, Noosfero.url_options.merge({:controller => 'search', :action => 'category_index', :category_path => category.path.split('/'),:host => category.environment.default_hostname }), html_options
45 end 24 end
46 25
47 - def link_to_product_category(category)  
48 - if category  
49 - link_to(category.name, :controller => 'search', :action => 'products', :category_path => category.explode_path)  
50 - else  
51 - _('Uncategorized product')  
52 - end  
53 - end  
54 -  
55 def txt2html(txt) 26 def txt2html(txt)
56 ret = txt.strip. 27 ret = txt.strip.
57 gsub( /\s*\n\s*\n\s*/, "\r<p/>\r" ). 28 gsub( /\s*\n\s*\n\s*/, "\r<p/>\r" ).
app/helpers/enterprise_homepage_helper.rb
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -module EnterpriseHomepageHelper  
2 -  
3 - def display_profile_info(profile)  
4 - data = ''  
5 - [  
6 - [ _('Contact person:'), :contact_person ],  
7 - [ _('e-Mail:'), :contact_email ],  
8 - [ _('Phone(s):'), :contact_phone ],  
9 - [ _('Location:'), :location ],  
10 - [ _('Address:'), :address ],  
11 - [ _('Economic activity:'), :economic_activity ]  
12 - ].each { | name, att |  
13 - if profile.send( att ) and not profile.send( att ).blank?  
14 - data << content_tag( 'li', content_tag('strong', name) +' '+ profile.send( att ).to_s ) +"\n"  
15 - end  
16 - }  
17 - if profile.respond_to?(:distance) and !profile.distance.nil?  
18 - data << content_tag( 'li',  
19 - content_tag('strong',_('Distance:')) +' '+  
20 - "%.2f%" % profile.distance  
21 - ) + "\n"  
22 - end  
23 - content_tag('div', content_tag('ul', data), :class => 'enterprise-info')  
24 - end  
25 -end  
app/helpers/manage_products_helper.rb
@@ -1,289 +0,0 @@ @@ -1,289 +0,0 @@
1 -# encoding: UTF-8  
2 -  
3 -module ManageProductsHelper  
4 -  
5 - def remote_function_to_update_categories_selection(container_id, options = {})  
6 - remote_function({  
7 - :update => container_id,  
8 - :url => { :action => "categories_for_selection" },  
9 - :loading => "loading('hierarchy_navigation', '#{ _('loading…') }'); loading('#{container_id}', '&nbsp;')",  
10 - :complete => "loading_done('hierarchy_navigation'); loading_done('#{container_id}')"  
11 - }.merge(options))  
12 - end  
13 -  
14 - def hierarchy_category_item(category, make_links, title = nil)  
15 - title ||= category.name  
16 - if make_links  
17 - link_to(title, '#',  
18 - :title => title,  
19 - :onclick => remote_function_to_update_categories_selection("categories_container_level#{ category.level + 1 }",  
20 - :with => "'category_id=#{ category.id }'"  
21 - )  
22 - )  
23 - else  
24 - title  
25 - end  
26 - end  
27 -  
28 - def hierarchy_category_navigation(current_category, options = {})  
29 - hierarchy = []  
30 - if current_category  
31 - hierarchy << current_category.name unless options[:hide_current_category]  
32 - ancestors = current_category.ancestors  
33 - ancestors.each do |category|  
34 - hierarchy << hierarchy_category_item(category, options[:make_links])  
35 - end  
36 - end  
37 - hierarchy.reverse.join(options[:separator] || ' &rarr; ')  
38 - end  
39 -  
40 - def options_for_select_categories(categories, selected = nil)  
41 - safe_join(categories.sort_by{ |cat|  
42 - cat.name.transliterate}.map do |category|  
43 - selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '')  
44 - "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{category.name + (category.leaf? ? '': ' &raquo;')}</option>".html_safe  
45 - end, "\n")  
46 - end  
47 -  
48 - def build_selects_for_ancestors(ancestors, current_category)  
49 - current_ancestor = ancestors.shift  
50 - if current_ancestor.nil?  
51 - select_for_new_category(current_category.children, current_category.level + 1)  
52 - else  
53 - content_tag('div',  
54 - select_tag('category_id',  
55 - options_for_select_categories(current_ancestor.siblings + [current_ancestor], current_ancestor),  
56 - :size => 10,  
57 - :onchange => remote_function_to_update_categories_selection("categories_container_level#{ current_ancestor.level + 1 }", :with => "'category_id=' + this.value")  
58 - ) +  
59 - build_selects_for_ancestors(ancestors, current_category),  
60 - :class => 'categories_container',  
61 - :id => "categories_container_level#{ current_ancestor.level }"  
62 - )  
63 - end  
64 - end  
65 -  
66 - def selects_for_all_ancestors(current_category)  
67 - build_selects_for_ancestors(current_category.ancestors.reverse + [current_category], current_category)  
68 - end  
69 -  
70 - def select_for_new_category(categories, level)  
71 - content_tag('div',  
72 - render(:partial => 'categories_for_selection', :locals => { :categories => categories, :level => level }),  
73 - :class => 'categories_container',  
74 - :id => "categories_container_level#{ level }"  
75 - )  
76 - end  
77 -  
78 - def categories_container(categories_selection_html, hierarchy_html = '')  
79 - content_tag 'div',  
80 - safe_join(  
81 - [  
82 - render('categories_autocomplete'),  
83 - hidden_field_tag('selected_category_id'),  
84 - content_tag('div', hierarchy_html, :id => 'hierarchy_navigation'),  
85 - content_tag('div', categories_selection_html, :id => 'categories_container_wrapper')  
86 - ], ''),  
87 - :id => 'categories-container'  
88 - end  
89 -  
90 - def select_for_categories(categories, level = 0)  
91 - if categories.empty?  
92 - content_tag('div', '', :id => 'no_subcategories')  
93 - else  
94 - select_tag('category_id',  
95 - options_for_select_categories(categories),  
96 - :size => 10,  
97 - :onchange => remote_function_to_update_categories_selection("categories_container_level#{ level + 1 }", :with => "'category_id=' + this.value")  
98 - ) +  
99 - content_tag('div', '', :class => 'categories_container', :id => "categories_container_level#{ level + 1 }")  
100 - end  
101 - end  
102 -  
103 - def edit_link(label, url, html_options = {})  
104 - return '' unless (user && user.has_permission?('manage_products', profile))  
105 - link_to(label, url, html_options)  
106 - end  
107 -  
108 - def edit_product_link_to_remote(product, field, label, html_options = {})  
109 - return '' unless (user && user.has_permission?('manage_products', profile))  
110 - options = html_options.merge(:id => 'link-edit-product-' + field)  
111 - options[:class] = options[:class] ? options[:class] + ' link-to-remote' : 'link-to-remote'  
112 -  
113 - link_to_remote(label,  
114 - {:update => "product-#{field}",  
115 - :url => { :controller => 'manage_products', :action => "edit", :id => product.id, :field => field },  
116 - :method => :get,  
117 - :loading => "loading_for_button('#link-edit-product-#{field}')"},  
118 - options)  
119 - end  
120 -  
121 - def edit_button(type, label, url, html_options = {})  
122 - return '' unless (user && user.has_permission?('manage_products', profile))  
123 - button(type, label, url, html_options)  
124 - end  
125 -  
126 - def edit_product_button_to_remote(product, field, label, html_options = {})  
127 - the_class = 'button with-text icon-edit'  
128 - if html_options.has_key?(:class)  
129 - the_class << ' ' << html_options[:class]  
130 - end  
131 - edit_product_link_to_remote(product, field, label, html_options.merge(:class => the_class))  
132 - end  
133 -  
134 - def edit_ui_button(label, url, html_options = {})  
135 - return '' unless (user && user.has_permission?('manage_products', profile))  
136 - ui_button(label, url, html_options)  
137 - end  
138 -  
139 - def edit_product_ui_button_to_remote(product, field, label, html_options = {})  
140 - return '' unless (user && user.has_permission?('manage_products', profile))  
141 - id = 'edit-product-remote-button-ui-' + field  
142 - options = html_options.merge(:id => id)  
143 -  
144 - ui_button_to_remote(label,  
145 - {:update => "product-#{field}",  
146 - :url => { :controller => 'manage_products', :action => "edit", :id => product.id, :field => field },  
147 - :complete => "jQuery('#edit-product-button-ui-#{field}').hide()",  
148 - :method => :get,  
149 - :loading => "loading_for_button('##{id}')"},  
150 - options)  
151 - end  
152 -  
153 - def cancel_edit_product_link(product, field, html_options = {})  
154 - return '' unless (user && user.has_permission?('manage_products', profile))  
155 - button_to_function(:cancel, _('Cancel'), nil, html_options) do |page|  
156 - page.replace_html "product-#{field}", CGI::escapeHTML(render :partial => "display_#{field}", :locals => {:product => product})  
157 - end  
158 - end  
159 -  
160 - def edit_product_category_link(product, html_options = {})  
161 - return '' unless (user && user.has_permission?('manage_products', profile))  
162 - options = html_options.merge(:id => 'link-edit-product-category')  
163 - link_to(_('Change category'), { :action => 'edit_category', :id => product.id}, options)  
164 - end  
165 -  
166 - def display_value(product)  
167 - price = product.price  
168 - return '' if price.blank? || price.zero?  
169 - discount = product.discount  
170 - if discount.blank? || discount.zero?  
171 - result = display_price(_('Price: '), price)  
172 - else  
173 - result = display_price_with_discount(price, product.price_with_discount)  
174 - end  
175 - content_tag('span', content_tag('span', result, :class => 'product-price'), :class => "#{product.available? ? '' : 'un'}available-product")  
176 - end  
177 -  
178 - def display_availability(product)  
179 - if !product.available?  
180 - ui_highlight(_('Product not available!'))  
181 - end  
182 - end  
183 -  
184 - def display_price(label, price)  
185 - content_tag('span', label, :class => 'field-name') +  
186 - content_tag('span', float_to_currency(price), :class => 'field-value')  
187 - end  
188 -  
189 - def display_price_with_discount(price, price_with_discount)  
190 - original_value = content_tag('span', display_price(_('List price: '), price), :class => 'list-price')  
191 - discount_value = content_tag('span', display_price(_('On sale: '), price_with_discount), :class => 'on-sale-price')  
192 - original_value + tag('br') + discount_value  
193 - end  
194 -  
195 - def display_qualifiers(product)  
196 - data = ''  
197 - product.product_qualifiers.each do |pq|  
198 - certified_by = ''  
199 - certifier = pq.certifier  
200 - if certifier  
201 - certifier_name = certifier.link.blank? ? certifier.name : link_to(certifier.name, certifier.link)  
202 - certified_by = _('certified by %s') % certifier_name  
203 - else  
204 - certified_by = _('(Self declared)')  
205 - end  
206 - data << content_tag('li', "✔ #{pq.qualifier.name} #{certified_by}", :class => 'product-qualifiers-item')  
207 - end  
208 - content_tag('ul', data, :id => 'product-qualifiers')  
209 - end  
210 -  
211 - def qualifiers_for_select  
212 - [[_('Select...'), nil]] + environment.qualifiers.sort.map{ |c| [c.name, c.id] }  
213 - end  
214 - def certifiers_for_select(qualifier)  
215 - [[_('Self declared'), nil]] + qualifier.certifiers.sort.map{ |c| [c.name, c.id] }  
216 - end  
217 - def select_qualifiers(product, selected = nil)  
218 - select_tag('selected_qualifier', options_for_select(qualifiers_for_select, selected),  
219 - :onchange => remote_function(  
220 - :url => {:action => 'certifiers_for_selection'},  
221 - :with => "'id=' + value + '&certifier_area=' + jQuery(this).parent().next().attr('id')",  
222 - :before => "small_loading(jQuery(this).parent().next().attr('id'), '&nbsp;')"  
223 - ),  
224 - :id => nil  
225 - )  
226 - end  
227 - def select_certifiers(qualifier, product = nil)  
228 - if qualifier  
229 - selected = product ? product.product_qualifiers.find_by(qualifier_id: qualifier.id).certifier_id : nil  
230 - select_tag("product[qualifiers_list][#{qualifier.id}]", options_for_select(certifiers_for_select(qualifier), selected))  
231 - else  
232 - select_tag("product[qualifiers_list][nil]")  
233 - end  
234 - end  
235 -  
236 - def remove_qualifier_button  
237 - button_to_function(:delete, content_tag('span', _('Delete qualifier')), "jQuery(this).parents('tr').remove()")  
238 - end  
239 -  
240 - def select_unit(object)  
241 - collection_select(object.class.name.downcase, :unit_id, environment.units, :id, :singular, {:include_blank => _('Select the unit')})  
242 - end  
243 -  
244 - def input_icon(input)  
245 - if input.is_from_solidarity_economy?  
246 - hint = _('Product from solidarity economy')  
247 - image_tag("/images/solidarity-economy.png", :class => 'solidatiry-economy-icon', :alt => hint, :title => hint)  
248 - end  
249 - end  
250 -  
251 - def display_price_by(unit)  
252 - selected_unit = content_tag('span', unit, :class => 'selected-unit')  
253 - content_tag('span', _('by') + ' ' + selected_unit, :class => 'price-by-unit')  
254 - end  
255 -  
256 - def label_amount_used(input)  
257 - product_unit = input.product.unit  
258 - if product_unit.blank?  
259 - _('Amount used in this product or service')  
260 - else  
261 - _('Amount used by %s of this product or service') % product_unit.singular.downcase  
262 - end  
263 - end  
264 -  
265 - def display_unit(input)  
266 - input_amount_used = content_tag('span', input.formatted_amount, :class => 'input-amount-used')  
267 - return input_amount_used if input.unit.blank?  
268 - n_('1 %{singular_unit}', '%{num} %{plural_unit}', input.amount_used.to_f) % { :num => input_amount_used, :singular_unit => content_tag('span', input.unit.singular, :class => 'input-unit'), :plural_unit => content_tag('span', input.unit.plural, :class => 'input-unit') }  
269 - end  
270 -  
271 - def select_production_cost(product,selected=nil)  
272 - url = url_for( :controller => 'manage_products', :action => 'create_production_cost' )  
273 - prompt_msg = _('Insert the name of the new cost:')  
274 - error_msg = _('Something went wrong. Please, try again')  
275 - select_tag('price_details[][production_cost_id]',  
276 - '<option value="" disabled="disabled">' + _('Select...') + '</option>' +  
277 - options_for_select(product.available_production_costs.map {|item| [truncate(item.name, {:length => 10, :omission => '...'}), item.id]} + [[_('Other cost'), '']], selected),  
278 - {:class => 'production-cost-selection',  
279 - :onchange => "productionCostTypeChange(this, '#{url}', '#{prompt_msg}', '#{error_msg}')"})  
280 - end  
281 -  
282 - def price_composition_progressbar_text(product, args = {})  
283 - currency = environment.currency_unit  
284 - production_cost = args[:production_cost_value] || product.formatted_value(:total_production_cost)  
285 - product_price = args[:product_price] || product.formatted_value(:price)  
286 -  
287 - _("%{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')}  
288 - end  
289 -end  
app/helpers/profile_image_helper.rb
@@ -82,7 +82,6 @@ module ProfileImageHelper @@ -82,7 +82,6 @@ module ProfileImageHelper
82 ] 82 ]
83 elsif profile.kind_of?(Enterprise) 83 elsif profile.kind_of?(Enterprise)
84 [ 84 [
85 - {_('Products') => {:href => catalog_path(profile.identifier)}},  
86 {_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}}, 85 {_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}},
87 {_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}}, 86 {_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}},
88 {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}}, 87 {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}},
app/models/article.rb
@@ -604,7 +604,7 @@ class Article &lt; ApplicationRecord @@ -604,7 +604,7 @@ class Article &lt; ApplicationRecord
604 end 604 end
605 605
606 def accept_category?(cat) 606 def accept_category?(cat)
607 - !cat.is_a?(ProductCategory) 607 + true
608 end 608 end
609 609
610 def public? 610 def public?
app/models/box.rb
@@ -41,7 +41,6 @@ class Box &lt; ApplicationRecord @@ -41,7 +41,6 @@ class Box &lt; ApplicationRecord
41 ProfileImageBlock, 41 ProfileImageBlock,
42 RawHTMLBlock, 42 RawHTMLBlock,
43 RecentDocumentsBlock, 43 RecentDocumentsBlock,
44 - SellersSearchBlock,  
45 TagsBlock ] 44 TagsBlock ]
46 end 45 end
47 46
@@ -54,21 +53,17 @@ class Box &lt; ApplicationRecord @@ -54,21 +53,17 @@ class Box &lt; ApplicationRecord
54 EnterprisesBlock, 53 EnterprisesBlock,
55 FansBlock, 54 FansBlock,
56 FavoriteEnterprisesBlock, 55 FavoriteEnterprisesBlock,
57 - FeaturedProductsBlock,  
58 FeedReaderBlock, 56 FeedReaderBlock,
59 HighlightsBlock, 57 HighlightsBlock,
60 LinkListBlock, 58 LinkListBlock,
61 LocationBlock, 59 LocationBlock,
62 LoginBlock, 60 LoginBlock,
63 MyNetworkBlock, 61 MyNetworkBlock,
64 - ProductsBlock,  
65 - ProductCategoriesBlock,  
66 ProfileImageBlock, 62 ProfileImageBlock,
67 ProfileInfoBlock, 63 ProfileInfoBlock,
68 ProfileSearchBlock, 64 ProfileSearchBlock,
69 RawHTMLBlock, 65 RawHTMLBlock,
70 RecentDocumentsBlock, 66 RecentDocumentsBlock,
71 - SellersSearchBlock,  
72 SlideshowBlock, 67 SlideshowBlock,
73 TagsBlock 68 TagsBlock
74 ] 69 ]
app/models/category.rb
@@ -35,8 +35,6 @@ class Category &lt; ApplicationRecord @@ -35,8 +35,6 @@ class Category &lt; ApplicationRecord
35 has_many :people, :through => :profile_categorizations, :source => :profile, :class_name => 'Person' 35 has_many :people, :through => :profile_categorizations, :source => :profile, :class_name => 'Person'
36 has_many :communities, :through => :profile_categorizations, :source => :profile, :class_name => 'Community' 36 has_many :communities, :through => :profile_categorizations, :source => :profile, :class_name => 'Community'
37 37
38 - has_many :products, :through => :enterprises  
39 -  
40 acts_as_having_image 38 acts_as_having_image
41 39
42 before_save :normalize_display_color 40 before_save :normalize_display_color
@@ -64,10 +62,6 @@ class Category &lt; ApplicationRecord @@ -64,10 +62,6 @@ class Category &lt; ApplicationRecord
64 self.communities.reorder('created_at DESC, id DESC').paginate(page: 1, per_page: limit) 62 self.communities.reorder('created_at DESC, id DESC').paginate(page: 1, per_page: limit)
65 end 63 end
66 64
67 - def recent_products(limit = 10)  
68 - self.products.reorder('created_at DESC, id DESC').paginate(page: 1, per_page: limit)  
69 - end  
70 -  
71 def recent_articles(limit = 10) 65 def recent_articles(limit = 10)
72 self.articles.recent(limit) 66 self.articles.recent(limit)
73 end 67 end
app/models/certifier.rb
@@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
1 -class Certifier < ApplicationRecord  
2 -  
3 - attr_accessible :name, :environment  
4 -  
5 - SEARCHABLE_FIELDS = {  
6 - :name => {:label => _('Name'), :weight => 10},  
7 - :description => {:label => _('Description'), :weight => 3},  
8 - :link => {:label => _('Link'), :weight => 1},  
9 - }  
10 -  
11 - belongs_to :environment  
12 -  
13 - has_many :qualifier_certifiers, :dependent => :destroy  
14 - has_many :qualifiers, :through => :qualifier_certifiers  
15 -  
16 - has_many :product_qualifiers  
17 - has_many :products, :through => :product_qualifiers, :source => :product  
18 -  
19 - validates_presence_of :environment_id  
20 - validates_presence_of :name  
21 -  
22 - def destroy  
23 - product_qualifiers.each { |pq| pq.update! :certifier => nil }  
24 - super  
25 - end  
26 -  
27 - def link  
28 - self[:link] || ''  
29 - end  
30 -  
31 - def <=>(b)  
32 - self.name.downcase.transliterate <=> b.name.downcase.transliterate  
33 - end  
34 -  
35 -end  
app/models/enterprise.rb
1 -# An enterprise is a kind of organization. According to the system concept,  
2 -# only enterprises can offer products and services.  
3 class Enterprise < Organization 1 class Enterprise < Organization
4 2
5 - attr_accessible :business_name, :address_reference, :district, :tag_list, :organization_website, :historic_and_current_context, :activities_short_description, :products_per_catalog_page 3 + attr_accessible :business_name, :address_reference, :district, :tag_list,
  4 + :organization_website, :historic_and_current_context, :activities_short_description
6 5
7 SEARCH_FILTERS = { 6 SEARCH_FILTERS = {
8 :order => %w[more_recent more_popular more_active], 7 :order => %w[more_recent more_popular more_active],
@@ -17,11 +16,6 @@ class Enterprise &lt; Organization @@ -17,11 +16,6 @@ class Enterprise &lt; Organization
17 16
18 acts_as_trackable after_add: proc{ |p, t| notify_activity t } 17 acts_as_trackable after_add: proc{ |p, t| notify_activity t }
19 18
20 - has_many :products, :foreign_key => :profile_id, :dependent => :destroy  
21 - has_many :product_categories, :through => :products  
22 - has_many :inputs, :through => :products  
23 - has_many :production_costs, :as => :owner  
24 -  
25 has_many :favorite_enterprise_people 19 has_many :favorite_enterprise_people
26 has_many :fans, source: :person, through: :favorite_enterprise_people 20 has_many :fans, source: :person, through: :favorite_enterprise_people
27 21
@@ -29,10 +23,6 @@ class Enterprise &lt; Organization @@ -29,10 +23,6 @@ class Enterprise &lt; Organization
29 23
30 settings_items :organization_website, :historic_and_current_context, :activities_short_description 24 settings_items :organization_website, :historic_and_current_context, :activities_short_description
31 25
32 - settings_items :products_per_catalog_page, :type => :integer, :default => 6  
33 - alias_method :products_per_catalog_page_before_type_cast, :products_per_catalog_page  
34 - validates_numericality_of :products_per_catalog_page, :allow_nil => true, :greater_than => 0  
35 -  
36 extend SetProfileRegionFromCityState::ClassMethods 26 extend SetProfileRegionFromCityState::ClassMethods
37 set_profile_region_from_city_state 27 set_profile_region_from_city_state
38 28
@@ -66,10 +56,6 @@ class Enterprise &lt; Organization @@ -66,10 +56,6 @@ class Enterprise &lt; Organization
66 environment ? environment.active_enterprise_fields : [] 56 environment ? environment.active_enterprise_fields : []
67 end 57 end
68 58
69 - def highlighted_products_with_image(options = {})  
70 - Product.where(:highlighted => true).joins(:image)  
71 - end  
72 -  
73 def required_fields 59 def required_fields
74 environment ? environment.required_enterprise_fields : [] 60 environment ? environment.required_enterprise_fields : []
75 end 61 end
@@ -136,19 +122,14 @@ class Enterprise &lt; Organization @@ -136,19 +122,14 @@ class Enterprise &lt; Organization
136 links = [ 122 links = [
137 {:name => _("Enterprises's profile"), :address => '/profile/{profile}', :icon => 'ok'}, 123 {:name => _("Enterprises's profile"), :address => '/profile/{profile}', :icon => 'ok'},
138 {:name => _('Blog'), :address => '/{profile}/blog', :icon => 'edit'}, 124 {:name => _('Blog'), :address => '/{profile}/blog', :icon => 'edit'},
139 - {:name => _('Products'), :address => '/catalog/{profile}', :icon => 'new'},  
140 ] 125 ]
141 blocks = [ 126 blocks = [
142 [MainBlock.new], 127 [MainBlock.new],
143 [ ProfileImageBlock.new, 128 [ ProfileImageBlock.new,
144 LinkListBlock.new(:links => links), 129 LinkListBlock.new(:links => links),
145 - ProductCategoriesBlock.new  
146 ], 130 ],
147 [LocationBlock.new] 131 [LocationBlock.new]
148 ] 132 ]
149 - if environment.enabled?('products_for_enterprises')  
150 - blocks[2].unshift ProductsBlock.new  
151 - end  
152 blocks 133 blocks
153 end 134 end
154 135
@@ -189,14 +170,6 @@ class Enterprise &lt; Organization @@ -189,14 +170,6 @@ class Enterprise &lt; Organization
189 {:title => _('Enterprise Info and settings'), :icon => 'edit-profile-enterprise'} 170 {:title => _('Enterprise Info and settings'), :icon => 'edit-profile-enterprise'}
190 end 171 end
191 172
192 - def create_product?  
193 - true  
194 - end  
195 -  
196 - def catalog_url  
197 - { :profile => identifier, :controller => 'catalog'}  
198 - end  
199 -  
200 def more_recent_label 173 def more_recent_label
201 '' 174 ''
202 end 175 end
@@ -205,5 +178,4 @@ class Enterprise &lt; Organization @@ -205,5 +178,4 @@ class Enterprise &lt; Organization
205 super or self.fans.where(id: person.id).count > 0 178 super or self.fans.where(id: person.id).count > 0
206 end 179 end
207 180
208 -  
209 end 181 end
app/models/enterprise_homepage.rb
@@ -1,42 +0,0 @@ @@ -1,42 +0,0 @@
1 -class EnterpriseHomepage < Article  
2 -  
3 - def self.type_name  
4 - _('Homepage')  
5 - end  
6 -  
7 - def self.short_description  
8 - _('Enterprise homepage')  
9 - end  
10 -  
11 - def self.description  
12 - _('Display the summary of profile.')  
13 - end  
14 -  
15 - def name  
16 - profile.nil? ? _('Homepage') : profile.name  
17 - end  
18 -  
19 - def to_html(options = {})  
20 - enterprise_homepage = self  
21 - proc do  
22 - extend EnterpriseHomepageHelper  
23 - extend CatalogHelper  
24 - catalog_load_index :page => 1, :show_categories => false  
25 - render :partial => 'content_viewer/enterprise_homepage', :object => enterprise_homepage  
26 - end  
27 - end  
28 -  
29 - # disable cache because of products  
30 - def cache_key params = {}, the_profile = nil, language = 'en'  
31 - rand  
32 - end  
33 -  
34 - def can_display_hits?  
35 - false  
36 - end  
37 -  
38 - def can_display_media_panel?  
39 - true  
40 - end  
41 -  
42 -end  
app/models/environment.rb
@@ -128,7 +128,6 @@ class Environment &lt; ApplicationRecord @@ -128,7 +128,6 @@ class Environment &lt; ApplicationRecord
128 'disable_asset_enterprises' => _('Disable search for enterprises'), 128 'disable_asset_enterprises' => _('Disable search for enterprises'),
129 'disable_asset_people' => _('Disable search for people'), 129 'disable_asset_people' => _('Disable search for people'),
130 'disable_asset_communities' => _('Disable search for communities'), 130 'disable_asset_communities' => _('Disable search for communities'),
131 - 'disable_asset_products' => _('Disable search for products'),  
132 'disable_asset_events' => _('Disable search for events'), 131 'disable_asset_events' => _('Disable search for events'),
133 'disable_categories' => _('Disable categories'), 132 'disable_categories' => _('Disable categories'),
134 'disable_header_and_footer' => _('Disable header/footer editing by users'), 133 'disable_header_and_footer' => _('Disable header/footer editing by users'),
@@ -139,7 +138,6 @@ class Environment &lt; ApplicationRecord @@ -139,7 +138,6 @@ class Environment &lt; ApplicationRecord
139 'disable_contact_community' => _('Disable contact for groups/communities'), 138 'disable_contact_community' => _('Disable contact for groups/communities'),
140 'forbid_destroy_profile' => _('Forbid users of removing profiles'), 139 'forbid_destroy_profile' => _('Forbid users of removing profiles'),
141 140
142 - 'products_for_enterprises' => _('Enable products for enterprises'),  
143 'enterprise_registration' => _('Enterprise registration'), 141 'enterprise_registration' => _('Enterprise registration'),
144 'enterprise_activation' => _('Enable activation of enterprises'), 142 'enterprise_activation' => _('Enable activation of enterprises'),
145 'enterprises_are_disabled_when_created' => _('Enterprises are disabled when created'), 143 'enterprises_are_disabled_when_created' => _('Enterprises are disabled when created'),
@@ -226,7 +224,6 @@ class Environment &lt; ApplicationRecord @@ -226,7 +224,6 @@ class Environment &lt; ApplicationRecord
226 224
227 has_many :organizations 225 has_many :organizations
228 has_many :enterprises 226 has_many :enterprises
229 - has_many :products, :through => :enterprises  
230 has_many :people 227 has_many :people
231 has_many :communities 228 has_many :communities
232 has_many :licenses 229 has_many :licenses
@@ -236,23 +233,16 @@ class Environment &lt; ApplicationRecord @@ -236,23 +233,16 @@ class Environment &lt; ApplicationRecord
236 order('display_color').where('display_color is not null and parent_id is null') 233 order('display_color').where('display_color is not null and parent_id is null')
237 }, class_name: 'Category' 234 }, class_name: 'Category'
238 235
239 - has_many :product_categories, -> { where type: 'ProductCategory'}  
240 has_many :regions 236 has_many :regions
241 has_many :states 237 has_many :states
242 has_many :cities 238 has_many :cities
243 239
244 has_many :roles, :dependent => :destroy 240 has_many :roles, :dependent => :destroy
245 241
246 - has_many :qualifiers  
247 - has_many :certifiers  
248 -  
249 has_many :mailings, :class_name => 'EnvironmentMailing', :foreign_key => :source_id, :as => 'source' 242 has_many :mailings, :class_name => 'EnvironmentMailing', :foreign_key => :source_id, :as => 'source'
250 243
251 acts_as_accessible 244 acts_as_accessible
252 245
253 - has_many :units, -> { order 'position' }  
254 - has_many :production_costs, :as => :owner  
255 -  
256 def superior_intances 246 def superior_intances
257 [self, nil] 247 [self, nil]
258 end 248 end
@@ -441,9 +431,7 @@ class Environment &lt; ApplicationRecord @@ -441,9 +431,7 @@ class Environment &lt; ApplicationRecord
441 end 431 end
442 432
443 DEFAULT_FEATURES = %w( 433 DEFAULT_FEATURES = %w(
444 - disable_asset_products  
445 disable_gender_icon 434 disable_gender_icon
446 - products_for_enterprises  
447 disable_select_city_for_contact 435 disable_select_city_for_contact
448 enterprise_registration 436 enterprise_registration
449 media_panel 437 media_panel
@@ -968,10 +956,6 @@ class Environment &lt; ApplicationRecord @@ -968,10 +956,6 @@ class Environment &lt; ApplicationRecord
968 end 956 end
969 end 957 end
970 958
971 - def highlighted_products_with_image(options = {})  
972 - self.products.where(highlighted: true).joins(:image).order('created_at ASC')  
973 - end  
974 -  
975 settings_items :home_cache_in_minutes, :type => :integer, :default => 5 959 settings_items :home_cache_in_minutes, :type => :integer, :default => 5
976 settings_items :general_cache_in_minutes, :type => :integer, :default => 15 960 settings_items :general_cache_in_minutes, :type => :integer, :default => 15
977 settings_items :profile_cache_in_minutes, :type => :integer, :default => 15 961 settings_items :profile_cache_in_minutes, :type => :integer, :default => 15
app/models/featured_products_block.rb
@@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
1 -class FeaturedProductsBlock < Block  
2 -  
3 - attr_accessible :product_ids, :groups_of, :speed, :reflect  
4 -  
5 - settings_items :product_ids, :type => Array, :default => []  
6 - settings_items :groups_of, :type => :integer, :default => 3  
7 - settings_items :speed, :type => :integer, :default => 1000  
8 - settings_items :reflect, :type => :boolean, :default => true  
9 -  
10 - before_save do |block|  
11 - if block.owner.kind_of?(Environment) && block.product_ids.blank?  
12 - total = block.owner.products.count  
13 - offset = rand([(total - block.groups_of * 3) + 1, 1].max)  
14 - block.product_ids = block.owner.highlighted_products_with_image.offset(offset).limit(block.groups_of * 3).map(&:id)  
15 - end  
16 - block.groups_of = block.groups_of.to_i  
17 - end  
18 -  
19 - def self.description  
20 - _('Featured Products')  
21 - end  
22 -  
23 - def self.pretty_name  
24 - _('Featured Products')  
25 - end  
26 -  
27 - def products  
28 - Product.find(self.product_ids) || []  
29 - end  
30 -  
31 - def products_for_selection  
32 - self.owner.highlighted_products_with_image  
33 - end  
34 -  
35 -end  
app/models/input.rb
@@ -1,71 +0,0 @@ @@ -1,71 +0,0 @@
1 -class Input < ApplicationRecord  
2 -  
3 - attr_accessible :product, :product_id, :product_category, :product_category_id,  
4 - :amount_used, :unit_id, :price_per_unit, :relevant_to_price, :is_from_solidarity_economy  
5 -  
6 - belongs_to :product  
7 - belongs_to :product_category  
8 -  
9 - validates_presence_of :product  
10 - validates_presence_of :product_category  
11 -  
12 - acts_as_list scope: -> input { where product_id: input.product_id }  
13 -  
14 - belongs_to :unit  
15 -  
16 - scope :relevant_to_price, -> { where relevant_to_price: true }  
17 -  
18 - include FloatHelper  
19 -  
20 - def price_per_unit=(value)  
21 - if value.is_a?(String)  
22 - super(decimal_to_float(value))  
23 - else  
24 - super(value)  
25 - end  
26 - end  
27 -  
28 - def amount_used=(value)  
29 - if value.is_a?(String)  
30 - super(decimal_to_float(value))  
31 - else  
32 - super(value)  
33 - end  
34 - end  
35 -  
36 - def name  
37 - product_category.name  
38 - end  
39 -  
40 - def formatted_value(value)  
41 - ("%.2f" % self[value]).to_s.gsub('.', product.enterprise.environment.currency_separator) if self[value]  
42 - end  
43 -  
44 - def formatted_amount  
45 - amount = self.amount_used  
46 - return '' if amount.blank? || amount.zero?  
47 - ("%.2f" % amount).to_s.gsub('.00', '').gsub('.', product.enterprise.environment.currency_separator)  
48 - end  
49 -  
50 - def has_price_details?  
51 - %w[price_per_unit amount_used].each do |field|  
52 - return true unless self.send(field).blank?  
53 - end  
54 - false  
55 - end  
56 -  
57 - def has_all_price_details?  
58 - %w[price_per_unit unit amount_used].each do |field|  
59 - return false if self.send(field).blank?  
60 - end  
61 - true  
62 - end  
63 -  
64 - def cost  
65 - return 0 if self.amount_used.blank? || self.price_per_unit.blank?  
66 - self.amount_used * self.price_per_unit  
67 - end  
68 -  
69 - alias_method :price, :cost  
70 -  
71 -end  
app/models/price_detail.rb
@@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
1 -class PriceDetail < ApplicationRecord  
2 -  
3 - attr_accessible :price, :production_cost_id  
4 -  
5 - belongs_to :product  
6 - validates_presence_of :product_id  
7 -  
8 - belongs_to :production_cost  
9 - # Do not validates_presence_of production_cost. We may have undefined other costs.  
10 - validates_uniqueness_of :production_cost_id, :scope => :product_id  
11 -  
12 - def name  
13 - production_cost.nil? ? _('Other costs') : production_cost.name  
14 - end  
15 -  
16 - def price  
17 - self[:price] || 0  
18 - end  
19 -  
20 - include FloatHelper  
21 - def price=(value)  
22 - if value.is_a?(String)  
23 - super(decimal_to_float(value))  
24 - else  
25 - super(value)  
26 - end  
27 - end  
28 -  
29 - def formatted_value(value)  
30 - ("%.2f" % self[value]).to_s.gsub('.', product.enterprise.environment.currency_separator) if self[value]  
31 - end  
32 -  
33 -end  
app/models/product.rb
@@ -1,291 +0,0 @@ @@ -1,291 +0,0 @@
1 -class Product < ApplicationRecord  
2 -  
3 - SEARCHABLE_FIELDS = {  
4 - :name => {:label => _('Name'), :weight => 10},  
5 - :description => {:label => _('Description'), :weight => 1},  
6 - }  
7 -  
8 - SEARCH_FILTERS = {  
9 - :order => %w[more_recent],  
10 - :display => %w[full map]  
11 - }  
12 -  
13 - attr_accessible :name, :product_category, :profile, :profile_id, :enterprise,  
14 - :highlighted, :price, :image_builder, :description, :available, :qualifiers, :unit_id, :discount, :inputs, :qualifiers_list  
15 -  
16 - def self.default_search_display  
17 - 'full'  
18 - end  
19 -  
20 - belongs_to :profile  
21 - # backwards compatibility  
22 - belongs_to :enterprise, :foreign_key => :profile_id, :class_name => 'Profile'  
23 - alias_method :enterprise=, :profile=  
24 - alias_method :enterprise, :profile  
25 -  
26 - has_one :region, :through => :profile  
27 - validates_presence_of :profile  
28 -  
29 - belongs_to :product_category  
30 -  
31 - has_many :inputs, -> { order 'position' }, dependent: :destroy  
32 - has_many :price_details, :dependent => :destroy  
33 - has_many :production_costs, :through => :price_details  
34 -  
35 - has_many :product_qualifiers, :dependent => :destroy  
36 - has_many :qualifiers, :through => :product_qualifiers  
37 - has_many :certifiers, :through => :product_qualifiers  
38 -  
39 - acts_as_having_settings :field => :data  
40 -  
41 - track_actions :create_product, :after_create, :keep_params => [:name, :url ], :if => Proc.new { |a| a.is_trackable? }, :custom_user => :action_tracker_user  
42 - track_actions :update_product, :before_update, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? }, :custom_user => :action_tracker_user  
43 - track_actions :remove_product, :before_destroy, :keep_params => [:name], :if => Proc.new { |a| a.is_trackable? }, :custom_user => :action_tracker_user  
44 -  
45 - validates_uniqueness_of :name, :scope => :profile_id, :allow_nil => true, :if => :validate_uniqueness_of_column_name?  
46 -  
47 - validates_presence_of :product_category_id  
48 - validates_associated :product_category  
49 -  
50 - validates_numericality_of :price, :allow_nil => true  
51 - validates_numericality_of :discount, :allow_nil => true  
52 -  
53 - scope :more_recent, -> { order 'created_at DESC' }  
54 -  
55 - scope :from_category, -> category {  
56 - joins(:product_category).where('categories.path LIKE ?', "%#{category.slug}%") if category  
57 - }  
58 -  
59 - scope :visible_for_person, lambda { |person|  
60 - joins('INNER JOIN "profiles" enterprises ON enterprises."id" = "products"."profile_id"')  
61 - .joins('LEFT JOIN "role_assignments" ON ("role_assignments"."resource_id" = enterprises."id"  
62 - AND "role_assignments"."resource_type" = \'Profile\') OR (  
63 - "role_assignments"."resource_id" = enterprises."environment_id" AND  
64 - "role_assignments"."resource_type" = \'Environment\' )')  
65 - .joins('LEFT JOIN "roles" ON "role_assignments"."role_id" = "roles"."id"')  
66 - .where(  
67 - ['( (roles.key = ? OR roles.key = ?) AND role_assignments.accessor_type = \'Profile\' AND role_assignments.accessor_id = ? )  
68 - OR  
69 - ( ( ( role_assignments.accessor_type = \'Profile\' AND  
70 - role_assignments.accessor_id = ? ) OR  
71 - ( enterprises.public_profile = ? AND enterprises.enabled = ? ) ) AND  
72 - ( enterprises.visible = ? ) )',  
73 - 'profile_admin', 'environment_administrator', person.id, person.id,  
74 - true, true, true]  
75 - ).uniq  
76 - }  
77 -  
78 - scope :recent, -> limit=nil { order('id DESC').limit(limit) }  
79 -  
80 - after_update :save_image  
81 -  
82 - def lat  
83 - self.profile.lat  
84 - end  
85 - def lng  
86 - self.profile.lng  
87 - end  
88 -  
89 - xss_terminate :only => [ :name ], :on => 'validation'  
90 - xss_terminate :only => [ :description ], :with => 'white_list', :on => 'validation'  
91 -  
92 - belongs_to :unit  
93 -  
94 - include FloatHelper  
95 -  
96 - include WhiteListFilter  
97 - filter_iframes :description  
98 -  
99 - def iframe_whitelist  
100 - self.profile && self.profile.environment && self.profile.environment.trusted_sites_for_iframe  
101 - end  
102 -  
103 - def name  
104 - self[:name].blank? ? category_name : self[:name]  
105 - end  
106 -  
107 - def name=(value)  
108 - if (value == category_name)  
109 - self[:name] = nil  
110 - else  
111 - self[:name] = value  
112 - end  
113 - end  
114 -  
115 - def name_is_blank?  
116 - self[:name].blank?  
117 - end  
118 -  
119 - def default_image(size='thumb')  
120 - image ? image.public_filename(size) : '/images/icons-app/product-default-pic-%s.png' % size  
121 - end  
122 -  
123 - acts_as_having_image  
124 -  
125 - def save_image  
126 - image.save if image  
127 - end  
128 -  
129 - def category_name  
130 - product_category ? product_category.name : _('Uncategorized product')  
131 - end  
132 -  
133 - def url  
134 - self.profile.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => id)  
135 - end  
136 -  
137 - def public?  
138 - self.profile.public?  
139 - end  
140 -  
141 - def formatted_value(method)  
142 - value = self[method] || self.send(method)  
143 - ("%.2f" % value).to_s.gsub('.', self.profile.environment.currency_separator) if value  
144 - end  
145 -  
146 - def price_with_discount  
147 - discount ? (price - discount) : price  
148 - end  
149 -  
150 - def price=(value)  
151 - if value.is_a?(String)  
152 - super(decimal_to_float(value))  
153 - else  
154 - super(value)  
155 - end  
156 - end  
157 -  
158 - def discount=(value)  
159 - if value.is_a?(String)  
160 - super(decimal_to_float(value))  
161 - else  
162 - super(value)  
163 - end  
164 - end  
165 -  
166 - def inputs_prices?  
167 - return false if self.inputs.count <= 0  
168 - self.inputs.each do |input|  
169 - return false if input.has_price_details? == false  
170 - end  
171 - true  
172 - end  
173 -  
174 - def any_inputs_details?  
175 - return false if self.inputs.count <= 0  
176 - self.inputs.each do |input|  
177 - return true if input.has_all_price_details? == true  
178 - end  
179 - false  
180 - end  
181 -  
182 - def has_basic_info?  
183 - %w[unit price discount].each do |field|  
184 - return true if !self.send(field).blank?  
185 - end  
186 - false  
187 - end  
188 -  
189 - def qualifiers_list=(qualifiers)  
190 - self.product_qualifiers.destroy_all  
191 - qualifiers.each do |qualifier_id, certifier_id|  
192 - if qualifier_id != 'nil'  
193 - product_qualifier = ProductQualifier.new  
194 - product_qualifier.product = self  
195 - product_qualifier.qualifier_id = qualifier_id  
196 - product_qualifier.certifier_id = certifier_id  
197 - product_qualifier.save!  
198 - end  
199 - end  
200 - end  
201 -  
202 - def order_inputs!(order = [])  
203 - order.each_with_index do |input_id, array_index|  
204 - input = self.inputs.find(input_id)  
205 - input.position = array_index + 1  
206 - input.save!  
207 - end  
208 - end  
209 -  
210 - def name_with_unit  
211 - unit.blank? ? name : "#{name} - #{unit.name.downcase}"  
212 - end  
213 -  
214 - def display_supplier_on_search?  
215 - true  
216 - end  
217 -  
218 - def inputs_cost  
219 - return 0 if inputs.empty?  
220 - inputs.relevant_to_price.map(&:cost).inject { |sum,price| sum + price }  
221 - end  
222 -  
223 - def total_production_cost  
224 - return inputs_cost if price_details.empty?  
225 - inputs_cost + price_details.map(&:price).inject(0){ |sum,price| sum + price }  
226 - end  
227 -  
228 - def price_described?  
229 - return false if price.blank? or price == 0  
230 - (price - total_production_cost.to_f).zero?  
231 - end  
232 -  
233 - def update_price_details(new_price_details)  
234 - price_details.destroy_all  
235 - new_price_details.each do |detail|  
236 - price_details.create(detail)  
237 - end  
238 - reload # to remove temporary duplicated price_details  
239 - price_details  
240 - end  
241 -  
242 - def price_description_percentage  
243 - return 0 if price.blank? || price.zero?  
244 - total_production_cost * 100 / price  
245 - end  
246 -  
247 - def available_production_costs  
248 - self.profile.environment.production_costs + self.profile.production_costs  
249 - end  
250 -  
251 - include Rails.application.routes.url_helpers  
252 - def price_composition_bar_display_url  
253 - url_for({:host => self.profile.default_hostname, :controller => 'manage_products', :action => 'display_price_composition_bar', :profile => self.profile.identifier, :id => self.id }.merge(Noosfero.url_options))  
254 - end  
255 -  
256 - def inputs_cost_update_url  
257 - url_for({:host => self.profile.default_hostname, :controller => 'manage_products', :action => 'display_inputs_cost', :profile => self.profile.identifier, :id => self.id }.merge(Noosfero.url_options))  
258 - end  
259 -  
260 - def percentage_from_solidarity_economy  
261 - se_i = t_i = 0  
262 - self.inputs.each{ |i| t_i += 1; se_i += 1 if i.is_from_solidarity_economy }  
263 - t_i = 1 if t_i == 0 # avoid division by 0  
264 - p = case (se_i.to_f/t_i)*100  
265 - when 0 then [0, '']  
266 - when 0..24.999 then [0, _("0%")];  
267 - when 25..49.999 then [25, _("25%")];  
268 - when 50..74.999 then [50, _("50%")];  
269 - when 75..99.999 then [75, _("75%")];  
270 - when 100 then [100, _("100%")];  
271 - end  
272 - end  
273 -  
274 - delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :profile, allow_nil: true  
275 -  
276 - protected  
277 -  
278 - def validate_uniqueness_of_column_name?  
279 - true  
280 - end  
281 -  
282 - def is_trackable?  
283 - # shopping_cart create products without profile  
284 - self.profile.present?  
285 - end  
286 -  
287 - def action_tracker_user  
288 - self.profile  
289 - end  
290 -  
291 -end  
app/models/product_categories_block.rb
@@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
1 -class ProductCategoriesBlock < Block  
2 -  
3 - def self.description  
4 - _('Product category menu')  
5 - end  
6 -  
7 - # the title of the block. Probably will be overriden in subclasses.  
8 - def default_title  
9 - _('Catalog')  
10 - end  
11 -  
12 - def help  
13 - _('Helps to filter the products catalog.')  
14 - end  
15 -  
16 - DISPLAY_OPTIONS = DISPLAY_OPTIONS.merge('catalog_only' => _('Only on the catalog'))  
17 -  
18 - def display  
19 - settings[:display].nil? ? 'catalog_only' : super  
20 - end  
21 -  
22 - def display_catalog_only(context)  
23 - context[:params][:controller] == 'catalog'  
24 - end  
25 -  
26 - def visible?(*args)  
27 - box.environment.enabled?('products_for_enterprises') ? super(*args) : false  
28 - end  
29 -  
30 -end  
app/models/product_category.rb
@@ -1,29 +0,0 @@ @@ -1,29 +0,0 @@
1 -class ProductCategory < Category  
2 - # FIXME: do not allow category with products or inputs to be destroyed  
3 - has_many :products  
4 - has_many :inputs  
5 -  
6 - attr_accessible :name, :parent, :environment  
7 -  
8 - scope :unique, -> { select 'DISTINCT ON (path) categories.*' }  
9 - scope :by_enterprise, -> enterprise {  
10 - distinct.joins(:products).  
11 - where('products.profile_id = ?', enterprise.id)  
12 - }  
13 - scope :by_environment, -> environment {  
14 - where 'environment_id = ?', environment.id  
15 - }  
16 -  
17 - scope :unique_by_level, lambda { |level| {  
18 - :select => "DISTINCT ON (filtered_category) split_part(path, '/', #{level.to_i}) AS filtered_category, categories.*"  
19 - }}  
20 -  
21 - def all_products  
22 - Product.where(product_category_id: (all_children << self).map(&:id))  
23 - end  
24 -  
25 - def self.menu_categories(top_category, env)  
26 - top_category ? top_category.children : top_level_for(env).select{|c|c.kind_of?(ProductCategory)}  
27 - end  
28 -  
29 -end  
app/models/product_qualifier.rb
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 -class ProductQualifier < ApplicationRecord  
2 -  
3 - attr_accessible :qualifier, :product, :certifier  
4 -  
5 - belongs_to :qualifier  
6 - belongs_to :product  
7 - belongs_to :certifier  
8 -end  
app/models/production_cost.rb
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -class ProductionCost < ApplicationRecord  
2 -  
3 - attr_accessible :name, :owner  
4 -  
5 - belongs_to :owner, :polymorphic => true  
6 - validates_presence_of :owner  
7 - validates_presence_of :name  
8 - validates_length_of :name, :maximum => 30, :allow_blank => true  
9 - validates_uniqueness_of :name, :scope => [:owner_id, :owner_type]  
10 -  
11 -end  
app/models/products_block.rb
@@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
1 -class ProductsBlock < Block  
2 -  
3 - attr_accessible :product_ids  
4 -  
5 - include ActionView::Helpers::TagHelper  
6 - include ActionView::Helpers::UrlHelper  
7 - include ActionView::Helpers  
8 - include Rails.application.routes.url_helpers  
9 -  
10 - def self.description  
11 - _('Products')  
12 - end  
13 -  
14 - def default_title  
15 - _('Products')  
16 - end  
17 -  
18 - def help  
19 - _('This block presents a list of your products.')  
20 - end  
21 -  
22 - settings_items :product_ids, type: Array  
23 - def product_ids=(array)  
24 - self.settings[:product_ids] = array  
25 - if self.settings[:product_ids]  
26 - self.settings[:product_ids] = self.settings[:product_ids].map(&:to_i)  
27 - end  
28 - end  
29 -  
30 - def products(reload = false)  
31 - if product_ids.blank?  
32 - owner.products.order('RANDOM()').limit([4,owner.products.count].min)  
33 - else  
34 - owner.products.where(:id => product_ids)  
35 - end.compact  
36 - end  
37 -  
38 -end  
app/models/profile.rb
@@ -812,7 +812,7 @@ private :generate_url, :url_options @@ -812,7 +812,7 @@ private :generate_url, :url_options
812 end 812 end
813 813
814 def accept_category?(cat) 814 def accept_category?(cat)
815 - forbidden = [ ProductCategory, Region ] 815 + forbidden = [ Region ]
816 !forbidden.include?(cat.class) 816 !forbidden.include?(cat.class)
817 end 817 end
818 818
app/models/qualifier.rb
@@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
1 -class Qualifier < ApplicationRecord  
2 -  
3 - attr_accessible :name, :environment  
4 -  
5 - SEARCHABLE_FIELDS = {  
6 - :name => {:label => _('Name'), :weight => 1},  
7 - }  
8 -  
9 - belongs_to :environment  
10 -  
11 - has_many :qualifier_certifiers, :dependent => :destroy  
12 - has_many :certifiers, :through => :qualifier_certifiers  
13 -  
14 - def used_certs  
15 - Certifier.joins('INNER JOIN product_qualifiers' +  
16 - ' ON certifiers.id = product_qualifiers.certifier_id')  
17 - .where(product_qualifiers: {qualifier_id: self.id})  
18 - end  
19 -  
20 - has_many :product_qualifiers, :dependent => :destroy  
21 - has_many :products, :through => :product_qualifiers, :source => :product  
22 -  
23 - validates_presence_of :environment_id  
24 - validates_presence_of :name  
25 -  
26 - def <=>(b)  
27 - self.name.downcase.transliterate <=> b.name.downcase.transliterate  
28 - end  
29 -  
30 -end  
app/models/qualifier_certifier.rb
@@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
1 -class QualifierCertifier < ApplicationRecord  
2 - belongs_to :qualifier  
3 - belongs_to :certifier  
4 -  
5 - validates_presence_of :qualifier  
6 -end  
app/models/sellers_search_block.rb
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -class SellersSearchBlock < Block  
2 -  
3 - attr_accessible :title  
4 -  
5 - def self.description  
6 - _('Search for enterprises and products')  
7 - end  
8 -  
9 - def self.short_description  
10 - _('Products/Enterprises search')  
11 - end  
12 -  
13 - def self.pretty_name  
14 - _('Sellers Search')  
15 - end  
16 -  
17 - def default_title  
18 - _('Search for sellers')  
19 - end  
20 -  
21 - def help  
22 - _('This block presents a search engine for products.')  
23 - end  
24 -  
25 -end  
app/models/unit.rb
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -class Unit < ApplicationRecord  
2 -  
3 - acts_as_list scope: -> unit { where environment_id: unit.environment_id }  
4 -  
5 - attr_accessible :name, :singular, :plural, :environment  
6 -  
7 - validates_presence_of :singular  
8 - validates_presence_of :plural  
9 -  
10 - belongs_to :environment  
11 -  
12 - validates_presence_of :environment_id  
13 - validates_presence_of :singular  
14 - validates_presence_of :plural  
15 -  
16 - def name  
17 - self.singular  
18 - end  
19 - def name=(value)  
20 - self.singular = value  
21 - end  
22 -  
23 -end  
app/views/blocks/footers/products.html.erb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -<%= link_to(_('View all products'), block.owner.public_profile_url.merge(:controller => 'catalog', :action => 'index')) %>  
app/views/blocks/product_categories.html.erb
@@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
1 -<%  
2 - if @categories.nil? or @categories.length == 0  
3 - categories = ProductCategory.on_level(nil).order(:name)  
4 - else  
5 - categories = @categories  
6 - end  
7 -%>  
8 -  
9 -<%= link_to _('Catalog start'), block.owner.catalog_url, :class=>'catalog-home-link' %>  
10 -<ul class="catalog-categories-list">  
11 - <% categories.each do |category| %>  
12 - <%= category_with_sub_list(category) %>  
13 - <% end %>  
14 -</ul>  
15 -<% if @categories and @categories.length == 0 %>  
16 - <div class="catalog-categories-notice">  
17 - <%= _('There are no sub-categories for %s') % @category.name %>  
18 - </div>  
19 -<% end %>  
app/views/blocks/products.html.erb
@@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
1 -<%= block_title(block.title, block.subtitle) %>  
2 -  
3 -<ul>  
4 - <% block.products.each do |product| %>  
5 - <li class='product'>  
6 - <%= link_to(product.name, product.url, :style => 'background-image:url(%s)' % product.default_image('minor')) %>  
7 - </li>  
8 - <% end %>  
9 -</ul>  
app/views/blocks/profile_info.html.erb
@@ -16,9 +16,6 @@ @@ -16,9 +16,6 @@
16 <ul class="profile-info-data"> 16 <ul class="profile-info-data">
17 <li><%= link_to _('Homepage'), block.owner.url, :class => 'url' %></li> 17 <li><%= link_to _('Homepage'), block.owner.url, :class => 'url' %></li>
18 <li><%= link_to _('View profile'), block.owner.public_profile_url %></li> 18 <li><%= link_to _('View profile'), block.owner.public_profile_url %></li>
19 - <% if block.owner.enterprise? && block.owner.environment.enabled?('products_for_enterprises') %>  
20 - <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) %></li>  
21 - <% end %>  
22 <% if !user.nil? and user.has_permission?('edit_profile', profile) %> 19 <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
23 <li><%= link_to _('Control panel'), block.owner.admin_url %></li> 20 <li><%= link_to _('Control panel'), block.owner.admin_url %></li>
24 <% end %> 21 <% end %>
app/views/blocks/sellers_search.html.erb
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -<h3><%= block.title %></h3>  
2 -  
3 -<%= form_tag({:controller => 'search', :action => 'assets'}, {:method => 'get'}) do %>  
4 -  
5 - <div class="search-in-opt"><%= _('Search in:') %>  
6 - <dir>  
7 - <%= labelled_radio_button _('Enterprises'), 'asset', 'enterprises', true %><br />  
8 - <%= labelled_radio_button _('Products'), 'asset', 'products', false %>  
9 - </dir>  
10 - </div>  
11 -  
12 - <div class="formfield search-from-opt">  
13 - <%= select_city(true) %>  
14 - </div>  
15 -  
16 - <div class="formfield search-distance-opt">  
17 - <%= labelled_select(_('Distance:'), 'radius', :first, :last, nil, [15, 30, 50, 100, 150, 200, 300, 400, 500, 1000].map{|n|[n, n.to_s + 'km']}) %>  
18 - </div>  
19 -  
20 - <div class="button-bar">  
21 - <%= submit_button :search, _('Search') %>  
22 - </div>  
23 -  
24 -<% end %>  
app/views/box_organizer/_featured_products_block.html.erb
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 -<strong><%= _('Featured Products') %></strong>  
2 -<div id='edit-featured-products-block'>  
3 - <p><%= label_tag _('Choose some products') %></p>  
4 - <p><%= select_tag 'block[product_ids][]', options_for_select(@block.products_for_selection.map{|p| [p.name, p.id.to_s]}, @block.product_ids), :multiple => true %></p>  
5 - <p><%= labelled_form_field check_box(:block, :reflect) + _('Reflect products'), '' %></p>  
6 - <p><%= labelled_form_field(_('Transition speed (in seconds)'), select('block', 'speed', (1..10).to_a.collect{|i| [i, i*1000] })) %>  
7 - <p><%= labelled_form_field(_('In groups of'), select('block', 'groups_of', (1..10).to_a)) %>  
8 -</div>  
app/views/box_organizer/_products_block.html.erb
@@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
1 -<strong></strong>  
2 -  
3 -<p>  
4 -<strong>  
5 -<%= _('Select the products that must be shown.') %>  
6 -</strong>  
7 -</p>  
8 -  
9 -<% for product in @block.owner.products %>  
10 - <%= check_box_tag("block[product_ids][]", product.id, (!@block.product_ids.blank? && @block.product_ids.include?(product.id)), :id => "block_product_ids_#{product.id}" ) %>  
11 - <label for="block_product_ids_<%= product.id %>"><%= product.name %></label>  
12 - <br/>  
13 -<% end %>  
app/views/box_organizer/edit.html.erb
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %> 6 <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %>
7 <%= labelled_form_field(_('Custom subtitle for this block: '), text_field(:block, :subtitle)) %> 7 <%= labelled_form_field(_('Custom subtitle for this block: '), text_field(:block, :subtitle)) %>
8 8
9 - <%= render :partial => partial_for_class(@block.class) %> 9 + <%= render_partial_for_class @block.class %>
10 10
11 <div class="display"> 11 <div class="display">
12 <%= labelled_form_field _('Display this block:'), 12 <%= labelled_form_field _('Display this block:'),
app/views/catalog/index.html.erb
@@ -1,130 +0,0 @@ @@ -1,130 +0,0 @@
1 -<% extra_content = [] %>  
2 -<% extra_content_list = [] %>  
3 -  
4 -<div id="product-catalog">  
5 -<% if !user.nil? && ( user.is_admin?(profile.environment) || user.is_admin?(profile) ) %>  
6 - <div class="product-catalog-ctrl">  
7 - <%= button :product, _('Manage Products/Services'), :controller => 'manage_products' %>  
8 - </div>  
9 -<% end %>  
10 -  
11 -<h1><%= _('Products/Services') %></h1>  
12 -  
13 -<%= breadcrumb(@category) if params[:level] %>  
14 -  
15 -<ul id="product-list">  
16 - <% @products.each do |product| %>  
17 - <% extra_content = @plugins.dispatch(:catalog_item_extras, product).collect { |content| instance_exec(&content) } %>  
18 - <% extra_content_list = @plugins.dispatch(:catalog_list_item_extras, product).collect { |content| instance_exec(&content) } %>  
19 -  
20 - <% status = [] %>  
21 - <% status << 'not-available' if !product.available %>  
22 - <% status << 'highlighted' if product.highlighted %>  
23 -  
24 - <li id="product-<%= product.id %>" class="product <%= status.join(' ') %>">  
25 - <ul>  
26 - <li class="product-image-link">  
27 - <% if product.highlighted? %>  
28 - <%= link_to image_tag(themed_path('/images/star.png'), :class => 'star', :alt => _('Highlighted product')), product_path(product) %>  
29 - <% end %>  
30 - <% if product.image %>  
31 - <div class="zoomable-image">  
32 - <%= link_to_product product, :class => 'product-big', :style => "background-image: url(#{product.default_image(:big)})" %>  
33 - <%= link_to content_tag(:span, _('Zoom in')), product.default_image(:big).gsub('_big',''), :class => 'zoomify-image' %>  
34 - </div>  
35 - <% else %>  
36 - <div class="no-image"><%= _('No image') %></div>  
37 - <% end %>  
38 - <div class="catalog-item-extras"><%= safe_join(extra_content, "\n") %></div>  
39 - </li>  
40 -  
41 - <li class="product-link"><%= link_to_product product %></li>  
42 -  
43 - <li class="product-price-line">  
44 - <% unless product.discount.blank? or product.discount == 0 %>  
45 - <span class="product-discount">  
46 - <span><%= _('from ') + price_span(product.price) %></span>  
47 - <span class="product-discount-by"><%= _('by ') %></span>  
48 - </span>  
49 - <% end %>  
50 - <% unless product.price.blank? or product.price == 0 %>  
51 - <span class="product-price">  
52 - <%= price_span product.price_with_discount, :class => "product-price #{'with-discount' unless product.discount}" %>  
53 - <span class="product-unit"><%= _(' / ') + (product.unit ? product.unit.singular : _('unit')) %></span>  
54 - </span>  
55 - <% end %>  
56 - <div style="clear: both"></div>  
57 - </li>  
58 -  
59 - <% if product.description %>  
60 - <li class="product-description expand-box">  
61 - <span class="product-description-button"><%= _('description') %></span>  
62 - <div class="float-box">  
63 - <div class="arrow"></div>  
64 - <div class="content"><%= product.description %></div>  
65 - </div>  
66 - </li>  
67 - <% end %>  
68 -  
69 - <% if product.price_described? %>  
70 - <li class="product-price-composition expand-box">  
71 - <span class="product-price-composition-button"><%= _('price composition') %></span>  
72 - <div class="float-box">  
73 - <div class="arrow"></div>  
74 - <div class="content">  
75 - <% product.inputs.relevant_to_price.each do |i| %>  
76 - <div class="search-product-input-dots-to-price">  
77 - <div class="search-product-input-name"><%= i.product_category.name %></div>  
78 - <%= price_span i.cost, :class => 'search-product-input-price' %>  
79 - </div>  
80 - <% end %>  
81 - <% product.price_details.each do |i| %>  
82 - <div class="search-product-input-dots-to-price">  
83 - <div class="search-product-input-name"><%= i.name %></div>  
84 - <%= price_span i.price, :class => 'search-product-input-price' %>  
85 - </div>  
86 - <% end %>  
87 - </div>  
88 - </div>  
89 - </li>  
90 - <% end %>  
91 -  
92 - <% if product.inputs.count > 0 %>  
93 - <li class="product-inputs expand-box">  
94 - <span id="inputs-button"><%= _('inputs and raw materials') %></span>  
95 - <div class="float-box">  
96 - <div class="arrow"></div>  
97 - <div class="content">  
98 - <% product.inputs.each do |i| %>  
99 - <div>  
100 - <%= _('%{amount_used} %{unit} of') % {:amount_used => i.amount_used, :unit => i.unit.singular} + ' ' if i.has_all_price_details? %>  
101 - <%= i.product_category.name %>  
102 - </div>  
103 - <% end %>  
104 - </div>  
105 - </div>  
106 - </li>  
107 - <% end %>  
108 -  
109 - <% unless product.qualifiers.blank? %>  
110 - <li class="product-qualifiers">  
111 - <span><%= _('qualifiers') if product.product_qualifiers.count > 0 %></span>  
112 - <div><%= render :partial => 'shared/product/qualifiers', :locals => {:product => product} %></div>  
113 - <% end %>  
114 -  
115 - <% extra_content_list.map do |content| %>  
116 - <li class="catalog-list-item-extras"><%= content %></li>  
117 - <% end %>  
118 -  
119 - <li class="product-unavailable"><%= _('product unavailable') unless product.available %></li>  
120 - </ul>  
121 - </li>  
122 - <% end %>  
123 -</ul><!-- end id="product-list" -->  
124 -  
125 -<%= pagination_links @products, :params => {:controller => :catalog, :action => :index, :profile => profile.identifier} %>  
126 -  
127 -<%= add_zoom_to_images %>  
128 -  
129 -<br style="clear:both"/>  
130 -</div><!-- end id="product-catalog" -->  
app/views/categories/index.html.erb
@@ -7,15 +7,6 @@ @@ -7,15 +7,6 @@
7 <%= link_to _('New category'), :action => 'new' %> 7 <%= link_to _('New category'), :action => 'new' %>
8 </div> 8 </div>
9 9
10 -<h1><%= _('Product Categories') %></h1>  
11 -<ul class='tree'>  
12 - <%= render :partial => 'category', :collection => @product_categories %>  
13 -</ul>  
14 -  
15 -<div>  
16 - <%= link_to _('New category'), :action => 'new', :type => 'ProductCategory' %>  
17 -</div>  
18 -  
19 <h1><%= _('Regions') %></h1> 10 <h1><%= _('Regions') %></h1>
20 <ul class='tree'> 11 <ul class='tree'>
21 <%= render :partial => 'category', :collection => @regions %> 12 <%= render :partial => 'category', :collection => @regions %>
app/views/manage_products/_add_input.html.erb
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -<div id='request_result_message' style='display: none'></div>  
2 -  
3 -<%= form_for(:input,  
4 - :url => {:action => 'add_input', :id => @product},  
5 - :html => {:method => 'post', :id => 'input-category-form'}  
6 - ) do |f| %>  
7 -  
8 - <h3><%= _('Choose an input or raw material to this product:') %><span class='loading-area'></span></h3>  
9 -  
10 - <%= categories_container(select_for_new_category(@categories, @level)) %>  
11 -  
12 - <div id='categories_selection_actionbar'>  
13 - <span id='save_and_continue_wrapper'>  
14 - <%= submit_button(:save, _('Save and continue'), :id => 'save_and_continue') %>  
15 - <span class='tooltip' id='save_and_continue_disabled_tooltip'>  
16 - <%= ui_icon('ui-icon-alert') %>  
17 - <%= _('This category does not allow registration of products, select a more specific category') %>  
18 - </span>  
19 - </span>  
20 - <%= button :cancel, _('Cancel'), '#', :class => 'cancel-add-input' %>  
21 - </div>  
22 -  
23 -<% end %>  
24 -  
25 -<%= javascript_tag "add_input_stuff()" %>  
app/views/manage_products/_categories_autocomplete.html.erb
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 -<%= text_field_tag 'product_category_id', '', :placeholder => _('type a category for the product') %>  
2 -  
3 -<%= javascript_include_tag '/javascripts/product_categories.js' %>  
4 -<%= javascript_tag do %>  
5 - product_categories.autocomplete.search_url = <%= url_for(:controller => :manage_products, :action => :search_categories).to_json %>  
6 - product_categories.autocomplete.select_url = <%= url_for(:controller => :manage_products, :action => :show_category_tree).to_json %>  
7 - product_categories.autocomplete.load('#product_category_id')  
8 -<% end %>  
app/views/manage_products/_categories_for_selection.html.erb
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
1 -<%= select_for_categories(categories, level) %>  
2 -  
3 -<%= javascript_tag do %>  
4 - jQuery(document).ready(function() {  
5 - jQuery('#categories_container_wrapper').scrollTo('100%', 1000)  
6 - jQuery('#selected_category_id').val(<%= @category.id rescue nil %>)  
7 - jQuery('#hierarchy_navigation').html(<%= hierarchy_category_navigation(@category, :make_links => true).to_json %>)  
8 - toggleDisabled(<%= (!!(@category && @category.accept_products?)).to_json %>, jQuery('#save_and_continue'))  
9 - });  
10 -<% end %>  
app/views/manage_products/_certifiers_for_selection.html.erb
@@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
1 -<%= select_certifiers(@qualifier) + remove_qualifier_button %>  
2 -<%= javascript_tag do %>  
3 - jQuery('#product-qualifiers-list *').removeClass('small-loading')  
4 -<% end %>  
app/views/manage_products/_display_category.html.erb
@@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
1 -<div id='display-product-category'>  
2 - <p class='hierarchy-category'></p>  
3 - <%= edit_link( _('Change category'), { :action => 'edit_category', :id => @product.id}, :id => 'link-edit-product-category') %>  
4 -</div>  
app/views/manage_products/_display_description.html.erb
@@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
1 -<%= render :file => 'shared/tiny_mce', :locals => {:mode => 'simple'} %>  
2 -<% if !@product.description.blank? %>  
3 - <%= @product.description %>  
4 - <%= edit_product_button_to_remote(@product, 'description', _('Edit description'), :title => _('Edit the description of your product and give consumers more information about what you are advertising')) %>  
5 -<% else %>  
6 - <%= edit_product_ui_button_to_remote(  
7 - @product,  
8 - 'description',  
9 - _('Add some description to your product'),  
10 - 'data-primary-icon' => 'ui-icon-pencil',  
11 - 'data-secondary-icon' => 'ui-icon-triangle-1-s',  
12 - :title => _('Add a description to your product and give consumers more information about what you are advertising')  
13 - ) %>  
14 - <%= javascript_tag("render_jquery_ui_buttons('edit-product-remote-button-ui-description')") %>  
15 -<% end%>  
app/views/manage_products/_display_image.html.erb
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -<div id='display-product-image'>  
2 - <%= image_tag (@product.reload.default_image('big')), :class => 'product-pic' %>  
3 -</div>  
4 -  
5 -<% if @product.image %>  
6 - <%= link_to content_tag(:span, _('Zoom in')), @product.image.public_filename,  
7 - :class => 'zoomify-image' %>  
8 -<% end %>  
9 -<%= add_zoom_to_images %>  
10 -  
11 -<%= edit_product_link_to_remote(@product, 'image', _('Change image')) %>  
app/views/manage_products/_display_info.html.erb
@@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
1 -<div id='display-product-info'>  
2 - <%= display_value(@product) %>  
3 - <%= display_availability(@product) %>  
4 - <%= display_qualifiers(@product) %>  
5 -  
6 - <% if @product.has_basic_info? %>  
7 - <%= edit_product_button_to_remote(@product, 'info', _('Edit basic information'), :title => _('Click here to edit price, discount and qualifiers/certifiers to make your product more attractive and detailed for the consumers')) %>  
8 - <% else %>  
9 - <%= edit_product_ui_button_to_remote(@product, 'info', _('Add price and other basic information'),  
10 - :title => _('Click here to add price, discount and qualifiers/certifiers to make your product more attractive and detailed for the consumers'),  
11 - 'data-primary-icon' => 'ui-icon-pencil',  
12 - 'data-secondary-icon' => 'ui-icon-triangle-1-s')  
13 - %>  
14 - <%= javascript_tag("render_jquery_ui_buttons('edit-product-remote-button-ui-info')") %>  
15 - <% end%>  
16 -  
17 -</div>  
app/views/manage_products/_display_input.html.erb
@@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
1 - <div class='input-informations input-form-closed'>  
2 - <div class='input-name'> <%= input.name %> <%= input_icon(input) %> </div>  
3 - <div class='input-details'>  
4 - <% button_bar do %>  
5 - <% if input.has_price_details? %>  
6 - <%= edit_button(:edit, _('Edit'), {:action => 'edit_input', :id => input}, :class => 'edit-input', :id => "edit-input-#{input.id}") %>  
7 - <% end %>  
8 - <%= edit_button(:remove, _('Remove'), {action: 'remove_input', id: input}, data: {confirm: _('Are you sure that you want to remove this input or raw material?')}, class: 'remove-input', id: "remove-input-#{input.id}") %>  
9 - <% end %>  
10 - <% if input.has_price_details? %>  
11 - <%= display_unit(input) %>  
12 - <% else %>  
13 - <%= edit_link(_('Click here to add price and the amount used'), {:action => 'edit_input', :id => input}, :class => 'add-input-details', :id => "add-input-#{input.id}-details") %>  
14 - <% end %>  
15 - </div>  
16 - <div id='input-<%= input.id %>-form' class='input-details-form'> </div>  
17 - </div>  
18 -  
19 - <% if user && user.has_permission?('manage_products', profile) %>  
20 - <%= javascript_tag "input_javascript_stuff(#{input.id})" %>  
21 - <% end %>  
app/views/manage_products/_display_inputs.html.erb
@@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
1 -<div id='new-product-input'></div>  
2 -  
3 -<div id='display-add-input-button'>  
4 - <% if @product.inputs.empty? %>  
5 - <%= edit_ui_button(  
6 - _('Add the inputs or raw material used by this product'),  
7 - {:action => 'add_input', :id => @product.id},  
8 - :id => 'add-input-button',  
9 - 'data-primary-icon' => 'ui-icon-pencil',  
10 - 'data-secondary-icon' => 'ui-icon-triangle-1-s',  
11 - :title => _('Add inputs or raw materials used by this product and give more transparency to consumers about your enterprise')  
12 - ) %>  
13 - <%= javascript_tag("render_jquery_ui_buttons('add-input-button')") %>  
14 - <% else %>  
15 - <%= edit_button(:add, _('Add new input or raw material'), {:action => 'add_input', :id => @product.id}, :id => 'add-input-button', :title => _('Add new input or raw material used by this product and give more transparency to consumers about your enterprise')) %>  
16 - <%= content_tag('span', _('Drag the input with the mouse to change the order'), :class => 'hint', :style => 'display: none') %>  
17 - <% end %>  
18 - <span class='loading-area'></span>  
19 -</div>  
20 -  
21 -<div id='display-product-inputs'>  
22 - <ul class='input-list'>  
23 - <%= render :partial => 'manage_products/input', :collection => @inputs %>  
24 - </ul>  
25 - <%= edit_link(_('Order inputs'), {:action => 'order_inputs', :id => @product.id}, :class => "order-inputs", :style => 'display:none') %>  
26 -</div>  
27 -  
28 -<% if user && user.has_permission?('manage_products', profile) %>  
29 - <% if @product.inputs.size > 1 %>  
30 - <%= javascript_tag "input_javascript_ordering_stuff()" %>  
31 - <% end %>  
32 - <%= javascript_tag "display_input_stuff()" %>  
33 -<% end %>  
app/views/manage_products/_display_name.html.erb
@@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
1 -<div id='display-product-name'>  
2 - <h2><%= @product.name_with_unit %></h2>  
3 - <%= edit_product_link_to_remote(@product, 'name', _('Edit name and unit'), :title => _('Click here to edit the name of your product and the unit')) %>  
4 -</div>  
5 -<%= javascript_tag do %>  
6 - jQuery('#display-product-category .hierarchy-category').first().html('<%=  
7 - escape_javascript(hierarchy_category_navigation(  
8 - @product.product_category,  
9 - :make_links => false,  
10 - :hide_current_category => @product.name_is_blank?)  
11 - )  
12 - %>')  
13 -<% end %>  
app/views/manage_products/_display_price_details.html.erb
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
1 -<div id='display-manage-price-details'></div>  
2 -  
3 -<div id='display-price-details'>  
4 - <ul class='price-details-list'>  
5 - <li>  
6 - <div class='price-detail-name'><%= _('Inputs:') %></div>  
7 - <div class='price-detail-price inputs-cost'>  
8 - <span><%= float_to_currency(@product.inputs_cost) %></span>  
9 - </div>  
10 - </li>  
11 - <% @product.price_details.each do |price_detail| %>  
12 - <li>  
13 - <div class='price-detail-name'><%= "%s:" % price_detail.name %></div>  
14 - <div class='price-detail-price'><%= float_to_currency(price_detail.price) %></div>  
15 - </li>  
16 - <% end %>  
17 - </ul>  
18 -</div>  
app/views/manage_products/_edit_description.html.erb
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -<%= render :file => 'shared/tiny_mce', :locals => {:mode => 'simple'} %>  
2 -<%= remote_form_for(@product,  
3 - :loading => "small_loading('product-description-form')",  
4 - :update => 'product-description',  
5 - :url => {:controller => 'manage_products', :action => 'edit', :id => @product, :field => 'description'},  
6 - :html => {:id => 'product-description-form', :method => 'post'}) do |f| %>  
7 -  
8 - <%= labelled_form_field(_('Description:'), f.text_area(:description, :rows => 15, :style => 'width: 90%;', :class => 'mceEditor')) %>  
9 - <% button_bar do %>  
10 - <%= submit_button :save, _('Save') %>  
11 - <%= cancel_edit_product_link(@product, 'description') %>  
12 - <% end %>  
13 -  
14 -<% end %>  
app/views/manage_products/_edit_image.html.erb
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -<div id='display-product-image'>  
2 - <%= image_tag (@product.reload.default_image('thumb')), :class => 'product-pic' %>  
3 -</div>  
4 -  
5 -<%= form_for(:product, :url => { :controller => 'manage_products', :action => 'edit', :id => @product, :field => 'image' }, :html => { :method => 'post', :id => 'uploadForm', :multipart => true}) do |f| %>  
6 - <%= f.fields_for :image_builder, @product.image do |i| %>  
7 - <%= i.file_field( :uploaded_data, { :size => 10 } ) %>  
8 - <p><%= _("Max size: %s (.jpg, .gif, .png)")% Image.max_size.to_humanreadable %></p>  
9 - <% end %>  
10 -  
11 - <%= submit_button 'save', _('Save') %>  
12 - <%= cancel_edit_product_link(@product, 'image') %>  
13 -<% end %>  
14 -  
15 -<script type="text/javascript">  
16 - jQuery("#uploadForm").ajaxForm({  
17 - beforeSubmit: function(a,f,o) {  
18 - o.loading = small_loading("uploadForm");  
19 - },  
20 - target: '#product-image'  
21 - });  
22 -</script>  
23 -  
24 -<% if errors %>  
25 - <%= render_dialog_error_messages 'product' %>  
26 -<% end %>  
app/views/manage_products/_edit_info.html.erb
@@ -1,63 +0,0 @@ @@ -1,63 +0,0 @@
1 -<% if errors %>  
2 - <%= render_dialog_error_messages 'product' %>  
3 -<% end %>  
4 -  
5 -<%= remote_form_for(@product,  
6 - :loading => "small_loading('product-info-form')",  
7 - :update => 'product-info',  
8 - :url => {:controller => 'manage_products', :action => 'edit', :id => @product, :field => 'info'},  
9 - :html => {:id => 'product-info-form', :method => 'post'}) do |f| %>  
10 -  
11 - <table>  
12 - <tr>  
13 - <td><%= f.label :price, _('Price (%s)') % environment.currency_unit, :class => 'formlabel' %></td>  
14 - <td class='formfield'><%= f.text_field(:price, :value => @product.formatted_value(:price), :class => 'numbers-only') %></td>  
15 - </tr>  
16 - <tr>  
17 - <td><%= f.label :discount, _('Discount (%s)') % environment.currency_unit, :class => 'formlabel' %></td>  
18 - <td class='formfield'><%= f.text_field(:discount, :value => @product.formatted_value(:discount), :class => 'numbers-only', :title => _('If your product is on sale, fill this field with the discount value')) %></td>  
19 - </tr>  
20 - <tr>  
21 - <td class='formlabel'><%= _('Available') %></td>  
22 - <td class='formfield'><%= labelled_radio_button( _('Yes'), 'product[available]', true, @product.available, :id => 'product_available') + labelled_radio_button( _('No'), 'product[available]', false, !@product.available) %></td>  
23 - </tr>  
24 - <tr>  
25 - <td><%= f.label :highlighted, _('Highlight this product?'), :class => 'formlabel' %></td>  
26 - <td class='formfield'><%= f.check_box(:highlighted) %></td>  
27 - </tr>  
28 - </table>  
29 -  
30 - <% if !environment.qualifiers.empty? %>  
31 - <table id='product-qualifiers-list'>  
32 - <tr>  
33 - <th><%= _('Qualifier') %></th>  
34 - <th><%= _('Certifier') %></th>  
35 - </tr>  
36 - <% @product.qualifiers.each_with_index do |qualifier, index| %>  
37 - <tr>  
38 - <td>  
39 - <%= select_qualifiers(@product, qualifier.id) %>  
40 - </td>  
41 - <td id='certifier-area-<%= index %>'>  
42 - <%= select_certifiers(qualifier, @product) + remove_qualifier_button %>  
43 - </td>  
44 - </tr>  
45 - <% end %>  
46 - </table>  
47 - <%= button_to_function(  
48 - :add,  
49 - _('Add new qualifier'),  
50 - "new_qualifier_row('#product-qualifiers-list', '#{escape_javascript(CGI::escape_html(select_qualifiers(@product)))}', '#{escape_javascript(CGI::escape_html(remove_qualifier_button))}')"  
51 - ) %>  
52 - <%= hidden_field_tag "product[qualifiers_list][nil]" %>  
53 - <% end %>  
54 -  
55 - <%= hidden_field_tag 'info-bar-update-url', @product.price_composition_bar_display_url, :class => 'bar-update-url' %>  
56 -  
57 - <% button_bar do %>  
58 - <%= submit_button :save, _('Save') %>  
59 - <%= cancel_edit_product_link(@product, 'info') %>  
60 - <% end %>  
61 -<% end %>  
62 -  
63 -<%= render :partial => 'shared/numbers_only_javascript' %>  
app/views/manage_products/_edit_input.html.erb
@@ -1,43 +0,0 @@ @@ -1,43 +0,0 @@
1 -<%= form_for(:input, :url => {:controller => 'manage_products', :action => 'edit_input', :id => @input},  
2 - :html => {:method => 'post', :id => "edit-input-#{ @input.id }-form"}) do |f| %>  
3 -  
4 - <%= hidden_field_tag 'input-bar-update-url', @input.product.price_composition_bar_display_url, :class => 'bar-update-url' %>  
5 - <%= hidden_field_tag 'inputs-cost-update-url', @input.product.inputs_cost_update_url %>  
6 -  
7 - <table>  
8 - <tr>  
9 - <td><%= f.label :amount_used, label_amount_used(@input), :class => 'formlabel' %></td>  
10 - <td class='formfield'><%= f.text_field(:amount_used, :value => @input.formatted_amount, :class => 'numbers-only amount-used') + select_unit(@input) %></td>  
11 - </tr>  
12 - <tr>  
13 - <td><%= f.label :price_per_unit, _('Price %s (%s)') % [display_price_by(@input.unit), environment.currency_unit], :class => 'formlabel' %></td>  
14 - <td class='formfield'><%= f.text_field(:price_per_unit, :value => @input.formatted_value(:price_per_unit), :class => 'numbers-only price-per-unit') %></td>  
15 - </tr>  
16 - <tr>  
17 - <td class='formlabel'><%= _("This input or raw material inpact on the final price of the product?") %></td>  
18 - <td>  
19 - <%= radio_button :input, 'relevant_to_price', true %>  
20 - <label for="input_relevant_to_price"><%= _('Yes') %></label>  
21 - <%= radio_button :input, 'relevant_to_price', false %>  
22 - <label for="input_relevant_to_price"><%= _('No') %></label>  
23 - </td>  
24 - </tr>  
25 - <tr>  
26 - <td class='formlabel'><%= _('Is it from solidarity economy?') %></td>  
27 - <td>  
28 - <%= radio_button :input, 'is_from_solidarity_economy', true %>  
29 - <label for="input_is_from_solidarity_economy"><%= _('Yes') %></label>  
30 - <%= radio_button :input, 'is_from_solidarity_economy', false %>  
31 - <label for="input_is_from_solidarity_economy"><%= _('No') %></label>  
32 - </td>  
33 - </tr>  
34 - <tr>  
35 - <td colspan='2'>  
36 - <%= submit_button :save, _('Save'), :title => _('Save changes of this input or raw material') %>  
37 - <%= button :cancel, _('Cancel'), '#', :class => 'cancel-edit-input', :id => "cancel-edit-input-#{@input.id}", :title => _('Cancel changes of this input or raw material') %>  
38 - <td>  
39 - <tr>  
40 - </table>  
41 -<% end %>  
42 -  
43 -<%= javascript_tag "edit_input_stuff(#{@input.id}, '#{environment.currency_separator}')" %>  
app/views/manage_products/_edit_name.html.erb
@@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
1 -<%= remote_form_for(@product,  
2 - :loading => "small_loading('product-name-form')",  
3 - :update => 'product-name',  
4 - :url => {:controller => 'manage_products', :action => 'edit', :id => @product, :field => 'name'},  
5 - :html => {:method => 'post', :id => 'product-name-form'}) do |f| %>  
6 - <%= f.text_field(:name, :value => @product.name, :class => 'name_edition') %>  
7 - <%= select_unit(@product) %>  
8 -  
9 - <% button_bar do %>  
10 - <%= submit_button :save, _('Save') %>  
11 - <%= cancel_edit_product_link(@product, 'name') %>  
12 - <% end %>  
13 -<% end %>  
14 -  
15 -<script type="text/javascript">  
16 - jQuery('#product_name').focus().select();  
17 -</script>  
18 -  
19 -<% if errors %>  
20 - <%= render_dialog_error_messages 'product' %>  
21 -<% end %>  
app/views/manage_products/_edit_price_details.html.erb
@@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
1 -<% price_details.each do |price_detail| %>  
2 - <tr id='<%= "price-detail-#{price_detail.id}" %>'>  
3 - <td><%= select_production_cost(@product, price_detail.production_cost_id) %></td>  
4 - <td><%= labelled_form_field(environment.currency_unit, text_field_tag('price_details[][price]', price_detail.formatted_value(:price), :class => 'numbers-only price-details-price', :size => 6)) %></td>  
5 - <td>  
6 - <%= link_to_remote(_('Remove'),  
7 - :update => "price-detail-#{price_detail.id}",  
8 - :complete => "calculateValuesForBar();",  
9 - data: {confirm: _('Are you sure that you want to remove this cost?')},  
10 - :url => { :action => 'remove_price_detail', :id => price_detail, :product => @product }) %>  
11 - </tr>  
12 -<% end %>  
13 -  
14 -<%= render :partial => 'shared/numbers_only_javascript' %>  
app/views/manage_products/_form.html.erb
@@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
1 -<%= error_messages_for :product %> <br/>  
2 -  
3 -<%= form_for :product, :html => {:multipart => true }, :url => {:action => mode} do |f| %>  
4 - <%= required_fields_message %>  
5 -  
6 - <%= display_form_field( _('Name:'), f.text_field(:name) ) %>  
7 - <%= display_form_field( _('Price:'), f.text_field(:price) ) %>  
8 - <%= display_form_field( _('Description:'), f.text_area(:description, :rows => 10, :class => 'mceEditor') ) %>  
9 - <%= labelled_form_field(f.check_box(:highlighted) + _('Highlight this product'),'') %>  
10 - <%= f.fields_for :image_builder, @product.image do |i| %>  
11 - <%= file_field_or_thumbnail(_('Image:'), @product.image, i) %>  
12 - <% end %>  
13 -  
14 - <% button_bar do %>  
15 - <%= submit_button('save', (mode == 'new' ? _('Create product') : _('Save changes')), :cancel => {:action => 'index'} ) %>  
16 - <% end %>  
17 -<% end %>  
app/views/manage_products/_input.html.erb
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -<li class='input-item' id="input-<%= input.id %>">  
2 -<%= render :partial => 'manage_products/display_input', :locals =>{:input => input} %>  
3 -</li>  
app/views/manage_products/_manage_product_details.html.erb
@@ -1,43 +0,0 @@ @@ -1,43 +0,0 @@
1 -<div id='price-composition-bar'>  
2 - <%= render :partial => 'manage_products/price_composition_bar' %>  
3 -</div>  
4 -  
5 -<%= form_tag({:action => 'manage_product_details'}, :method => 'post', :id => 'manage-product-details-form') do %>  
6 - <div>  
7 - <table id='display-product-price-details'>  
8 - <tr>  
9 - <td><%= _('Inputs') %></td>  
10 - <td class='inputs-cost'>  
11 - <span><%= float_to_currency(@product.inputs_cost) %></span>  
12 - </td>  
13 - <td>  
14 - <small><%= _('This value is composed by the total value of registered inputs') %></small>  
15 - </td>  
16 - </tr>  
17 - <%= render :partial => 'manage_products/edit_price_details', :locals => {:price_details => @product.price_details} %>  
18 - </table>  
19 - </div>  
20 -  
21 - <%= hidden_field(:product, :inputs_cost) %>  
22 - <%= hidden_field(:product, :price) %>  
23 -  
24 - <% button_bar do %>  
25 - <%= submit_button :save, _('Save'), :disabled => '', :class => 'disabled' %>  
26 - <%= button :cancel, _('Cancel'), '#', class: 'cancel-price-details', data: {confirm: _('If you leave, you will lose all unsaved information. Are you sure you want to quit?')} %>  
27 - <%= button(:add, _('New cost'), '#', :id => 'add-new-cost') %>  
28 - <span class='loading-area'></span>  
29 - <% end %>  
30 -  
31 -<% end %>  
32 -  
33 -<div style='display:none'>  
34 - <table id='new-cost-fields'>  
35 - <tr>  
36 - <td><%= select_production_cost(@product) %></td>  
37 - <td><%= labelled_form_field(environment.currency_unit, text_field_tag('price_details[][price]', nil, :class => 'numbers-only price-details-price', :size => 6)) %></td>  
38 - <td><%= link_to(_('Cancel'), '#', {:class => 'cancel-new-cost'}) %></td>  
39 - </tr>  
40 - </table>  
41 -</div>  
42 -  
43 -<%= render :partial => 'shared/numbers_only_javascript' %>  
app/views/manage_products/_price_composition_bar.html.erb
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -<%= javascript_tag do %>  
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;  
6 - var currency_format = { separator : '<%= environment.currency_separator %>', delimiter : '<%= environment.currency_delimiter %>', unit : '<%= environment.currency_unit %>' };  
7 - if (<%= @product.price_described? %>) {  
8 - var described = true;  
9 - }  
10 - priceCompositionBar(value,described,total_cost,price);  
11 -<% end %>  
12 -  
13 -<div id="price-details-info">  
14 - <div id="details-progressbar">  
15 - <div id='progressbar'></div>  
16 - <div id='progressbar-text'>  
17 - <%= price_composition_progressbar_text(@product) %>  
18 - </div>  
19 - </div>  
20 - <div id='progressbar-icon' class='ui-icon ui-icon-info' data-price-not-described-message='<%= _("The production cost of your product is not described yet. If you want to display the price composition, please add all the costs") %>' data-price-described-message='<%= _("The production cost of your product is fully described and will be displayed on your product's page") %>' data-price-described-notice='<%= _("Congratulations! Now the price is open to the public") %>'>  
21 -</div>  
22 -</div>  
app/views/manage_products/_price_details_button.html.erb
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
1 -<%= edit_ui_button(  
2 - _('Describe here the cost of production'),  
3 - {:action => 'manage_product_details', :id => @product.id},  
4 - :id => 'manage-product-details-button',  
5 - 'data-primary-icon' => 'ui-icon-pencil',  
6 - 'data-secondary-icon' => 'ui-icon-triangle-1-s',  
7 - :title => _('Describe details about how the price was defined')  
8 -) %>  
9 -<%= javascript_tag("render_jquery_ui_buttons('manage-product-details-button')") %>  
10 -<span class='loading-area'></span>  
app/views/manage_products/_selected_category_tree.html.erb
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -<%= categories_container selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true) %>  
2 -  
app/views/manage_products/edit.html.erb
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -<h2> <%= _('Editing') %> <%= @product.name %> </h2>  
2 -  
3 -<%= render :partial => 'manage_products/form', :locals => {:mode => 'edit'} %>  
app/views/manage_products/edit_category.html.erb
@@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
1 -<div class=product-category-hierarchy>  
2 - <%= hierarchy_category_navigation(@category, :make_links => false)%>  
3 -</div>  
4 -  
5 -<div id="category-product-edition">  
6 -  
7 - <h2><%= @product.name %></h2>  
8 -  
9 - <div id='request_result_message' style='display: none'></div>  
10 -  
11 - <%= remote_form_for(@product,  
12 - :loading => "open_loading('#{ _('loading...') }')",  
13 - :update => "request_result_message",  
14 - :url => {:action => 'edit_category', :id => @product},  
15 - :html => {:method => 'post', :id => 'category_form'}) do |f| %>  
16 -  
17 - <h3><%= _('Edit category of this product:') %></h3>  
18 -  
19 - <%= render 'manage_products/selected_category_tree' %>  
20 -  
21 - <div id='categories_selection_actionbar'>  
22 - <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %>  
23 - <span id='save_and_continue_wrapper'>  
24 - <%= submit_button(:save, _('Save and continue'), :id => 'save_and_continue') %>  
25 - <span class='tooltip' id='save_and_continue_disabled_tooltip'>  
26 - <%= ui_icon('ui-icon-alert') %>  
27 - <%= _('This category does not allow registration of products, select a more specific category') %>  
28 - </span>  
29 - </span>  
30 - </div>  
31 -  
32 - <% end %>  
33 -</div>  
app/views/manage_products/index.html.erb
@@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
1 -<h2> <%=_('Listing products and services') %> </h2>  
2 -  
3 -<table>  
4 - <tr>  
5 - <th><%= _('Product') %></th>  
6 - <th><%= _('Price') %></th>  
7 - <th><%= _('Actions') %></th>  
8 - </tr>  
9 - <% if @products.empty? %>  
10 - <tr>  
11 - <td colspan='3' style='text-align: center; padding: 10px'><em><%= _('(no product registered yet)') %></em></td>  
12 - </tr>  
13 - <% end %>  
14 - <% @products.each do |product| %>  
15 - <tr>  
16 - <td><strong><%= link_to product.name, :action => 'show', :id => product %></strong></td>  
17 - <td><%= product.price %></td>  
18 - <td>  
19 - <%= button :delete, _('Remove'), {action: 'destroy', id: product}, data: {confirm: _('Are you sure you want to remove this product?')} %>  
20 - </td>  
21 - </tr>  
22 - <% end %>  
23 -</table>  
24 -  
25 -<%= pagination_links @products %>  
26 -  
27 -<% button_bar do %>  
28 - <%= button :add, _('New product or service'), :action => 'new' if @profile.create_product? %>  
29 - <%= button :back, _('Back'), { :controller => 'profile_editor', :profile => @profile.identifier, :action => 'index' } %>  
30 -<% end %>  
app/views/manage_products/new.html.erb
@@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
1 -<h2 id='new_product_title'><%= _('New product or service') %></h2>  
2 -  
3 -<div id='request_result_message' style='display: none'></div>  
4 -  
5 -<%= remote_form_for @product,  
6 - :loading => "open_loading('#{ _('loading...') }')",  
7 - :update => "request_result_message",  
8 - :url => {:action => 'new'},  
9 - :html => {:method => 'post', :id => 'category_form'} do |f| %>  
10 -  
11 - <h3><%= _('Select the category of the new product or service') %></h3>  
12 -  
13 - <%= categories_container(select_for_new_category(@categories, @level)) %>  
14 -  
15 - <div id='categories_selection_actionbar'>  
16 - <%= button :back, _('Back to the product listing'), :action => 'index' %>  
17 - <span id='save_and_continue_wrapper'>  
18 - <%= submit_button(:save, _('Save and continue'), :id => 'save_and_continue') %>  
19 - <span class='tooltip' id='save_and_continue_disabled_tooltip'>  
20 - <%= ui_icon('ui-icon-alert') %>  
21 - <%= _('This category does not allow registration of products, select a more specific category') %>  
22 - </span>  
23 - </span>  
24 - </div>  
25 -  
26 -<% end %>  
27 -  
28 -<%= javascript_tag do %>  
29 - toggleDisabled(<%= @category && @category.accept_products? ? 'true' : 'false' %>, jQuery('#save_and_continue')[0])  
30 -<% end %>  
app/views/manage_products/show.html.erb
@@ -1,74 +0,0 @@ @@ -1,74 +0,0 @@
1 -<div id="product-category">  
2 - <%= render :partial => 'manage_products/display_category' %>  
3 -</div>  
4 -  
5 -<div id="show_product">  
6 -  
7 - <div id='product-name'>  
8 - <%= render :partial => 'manage_products/display_name' %>  
9 - </div>  
10 -  
11 - <div id='product-details'>  
12 - <div id='product-image' class="zoomable-image">  
13 - <%= render :partial => 'manage_products/display_image' %>  
14 - </div>  
15 - <div id='product-extra-content'>  
16 - <% extra_content = @plugins.dispatch(:product_info_extras, @product).collect { |content| instance_exec(&content) } %>  
17 - <%= safe_join(extra_content, "\n") %>  
18 - </div>  
19 - <div id='product-info'>  
20 - <%= render :partial => 'manage_products/display_info' %>  
21 - </div>  
22 - </div>  
23 -  
24 - <br style='clear: both'/>  
25 -  
26 - <% unless !@allowed_user && (@product.description.blank? && @product.inputs.empty? && !@product.price_described? ) %>  
27 - <% plugins_tabs = plugins_product_tabs %>  
28 -  
29 - <div class='ui-tabs' id='product-<%= @product.id %>-tabs'>  
30 - <ul>  
31 - <% if !@product.description.blank? || @allowed_user %>  
32 - <li class='tab'><a href='#product-description'><%= _('Description') %></a></li>  
33 - <% end %>  
34 - <% if !@product.inputs.empty? || @allowed_user %>  
35 - <li class='tab'><a href='#product-inputs'><%= _('Inputs and raw material') %></a></li>  
36 - <% end %>  
37 - <% if @product.price_described? || @allowed_user %>  
38 - <li class='tab'><a href='#product-price-details'><%= _('Price composition') %></a></li>  
39 - <% end %>  
40 -  
41 - <% plugins_tabs.each do |tab| %>  
42 - <li class='tab'><a href='#<%=tab[:id]%>'><%= tab[:title] %></a></li>  
43 - <% end %>  
44 -  
45 - </ul>  
46 -  
47 - <div id='product-description'>  
48 - <%= render :partial => 'manage_products/display_description' %>  
49 - </div>  
50 -  
51 - <div id='product-inputs'>  
52 - <%= render :partial => 'manage_products/display_inputs' %>  
53 - </div>  
54 -  
55 - <% if @product.price_described? || @allowed_user %>  
56 - <div id='product-price-details'>  
57 - <%= render :partial => 'manage_products/display_price_details' %>  
58 - <%= render :partial => 'manage_products/price_details_button' %>  
59 - </div>  
60 - <% end %>  
61 -  
62 - <% plugins_tabs.each do |tab| %>  
63 - <div id='<%=tab[:id]%>'><%= raw tab[:content] %></div>  
64 - <% end %>  
65 -  
66 - </div>  
67 - <% end %>  
68 -  
69 -</div>  
70 -  
71 -<% button_bar do %>  
72 - <%= button :back, _('Back to the product listing'), :controller => 'catalog', :action => 'index' %>  
73 - <%= button :delete, _('Remove product or service'), {:action => 'destroy', :id => @product}, :class => 'requires-permission-manage_products', :style => 'display:none;' %>  
74 -<% end %>  
app/views/map_balloon/profile.html.erb
@@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
17 <strong><%= _('Address: ') + @profile.address %></strong><br/> 17 <strong><%= _('Address: ') + @profile.address %></strong><br/>
18 <% end %> 18 <% end %>
19 <% if @profile.respond_to?(:products) and !@profile.products.blank? %> 19 <% if @profile.respond_to?(:products) and !@profile.products.blank? %>
20 - <strong><%= _('Products/Services: ') + @profile.products.map{|i| link_to(i.name, :controller => 'manage_products', :profile => @profile.identifier, :action => 'show', :id => i.id)}.join(', ') %></strong><br/> 20 + <strong><%= _('Products/Services: ') + @profile.products.map{|i| link_to(i.name, controller: 'products_plugin/page', profile: @profile.identifier, action: 'show', id: i.id)}.join(', ') %></strong><br/>
21 <% end %> 21 <% end %>
22 <% if @profile.respond_to?(:distance) and !@profile.distance.nil? %> 22 <% if @profile.respond_to?(:distance) and !@profile.distance.nil? %>
23 <strong><%= _('Distance: ') + "%.2f%" % @profile.distance %></strong><br/> 23 <strong><%= _('Distance: ') + "%.2f%" % @profile.distance %></strong><br/>
app/views/person_notifier/mailer/_create_product.html.erb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -../../profile/_create_product.html.erb  
2 \ No newline at end of file 0 \ No newline at end of file
app/views/person_notifier/mailer/_remove_product.html.erb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -../../profile/_remove_product.html.erb  
2 \ No newline at end of file 0 \ No newline at end of file
app/views/person_notifier/mailer/_update_product.html.erb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -../../profile/_update_product.html.erb  
2 \ No newline at end of file 0 \ No newline at end of file
app/views/profile/_create_product.html.erb
@@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
1 -<div class='profile-activity-image'>  
2 - <%= link_to image_tag(activity.target.default_image :minor), activity.target.url, class: 'product-pic' if activity.target.present? %>  
3 -</div>  
4 -<div class='profile-activity-description'>  
5 - <p class='profile-activity-text'><%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %></p>  
6 - <p class='profile-activity-time'><%= time_ago_in_words activity.created_at %></p>  
7 -  
8 - <div class='profile-wall-actions'>  
9 - <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>  
10 - </div>  
11 -</div>  
12 -  
13 -<div style="clear: both"></div>  
app/views/profile/_remove_product.html.erb
@@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
1 -<div class='profile-activity-image'>  
2 -</div>  
3 -<div class='profile-activity-description'>  
4 - <p class='profile-activity-text'><%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %></p>  
5 - <p class='profile-activity-time'><%= time_ago_in_words activity.created_at %></p>  
6 -  
7 - <div class='profile-wall-actions'>  
8 - <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>  
9 - </div>  
10 -</div>  
11 -  
12 -<div style="clear: both"></div>  
app/views/profile/_update_product.html.erb
@@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
1 -<div class='profile-activity-image'>  
2 - <%= link_to image_tag(activity.target.default_image :minor), activity.target.url, class: 'product-pic' if activity.target.present? %>  
3 -</div>  
4 -<div class='profile-activity-description'>  
5 - <p class='profile-activity-text'><%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %></p>  
6 - <p class='profile-activity-time'><%= time_ago_in_words activity.created_at %></p>  
7 -  
8 - <div class='profile-wall-actions'>  
9 - <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>  
10 - </div>  
11 -</div>  
12 -  
13 -<div style="clear: both"></div>  
app/views/profile_editor/_organization.html.erb
@@ -66,8 +66,3 @@ @@ -66,8 +66,3 @@
66 <%= labelled_check_box(_('Enable "contact us"'), 'profile_data[enable_contact_us]', "1", @profile.enable_contact_us) if @profile.enterprise? %> 66 <%= labelled_check_box(_('Enable "contact us"'), 'profile_data[enable_contact_us]', "1", @profile.enable_contact_us) if @profile.enterprise? %>
67 67
68 <%= render :partial => 'moderation', :locals => { :profile => @profile } %> 68 <%= render :partial => 'moderation', :locals => { :profile => @profile } %>
69 -  
70 -<% if profile.enterprise? && profile.environment.enabled?('products_for_enterprises') %>  
71 - <h2><%=_('Products/Services catalog')%></h2>  
72 - <%= labelled_form_field(_('Number of products/services displayed per page on catalog'), text_field(:profile_data, :products_per_catalog_page, :size => 3)) %>  
73 -<% end %>  
app/views/profile_editor/index.html.erb
@@ -47,8 +47,6 @@ @@ -47,8 +47,6 @@
47 47
48 <%= control_panel_button(_('Manage Members'), 'members', :controller => 'profile_members') if profile.organization? && user.has_permission?(:manage_memberships, profile) %> 48 <%= control_panel_button(_('Manage Members'), 'members', :controller => 'profile_members') if profile.organization? && user.has_permission?(:manage_memberships, profile) %>
49 49
50 - <%= control_panel_button(_('Manage Products/Services'), 'products', :controller => 'manage_products') if profile.enterprise? && environment.enabled?('products_for_enterprises') %>  
51 -  
52 <% if !environment.enabled?('disable_asset_enterprises') %> 50 <% if !environment.enabled?('disable_asset_enterprises') %>
53 <% if profile.is_validation_entity? %> 51 <% if profile.is_validation_entity? %>
54 <%= control_panel_button(_('Enterprise Validation'), 'validation', :controller => 'enterprise_validation') %> 52 <%= control_panel_button(_('Enterprise Validation'), 'validation', :controller => 'enterprise_validation') %>
app/views/search/_display_results.html.erb
@@ -17,9 +17,10 @@ @@ -17,9 +17,10 @@
17 <div class="search-results-innerbox search-results-type-<%= name.to_s.singularize %> <%= 'common-profile-list-block' if SearchHelper::COMMON_PROFILE_LIST_BLOCK.include?(name) %>"> 17 <div class="search-results-innerbox search-results-type-<%= name.to_s.singularize %> <%= 'common-profile-list-block' if SearchHelper::COMMON_PROFILE_LIST_BLOCK.include?(name) %>">
18 <ul> 18 <ul>
19 <% search[:results].each do |hit| %> 19 <% search[:results].each do |hit| %>
20 - <% partial = partial_for_class(hit.class, display) %>  
21 - <% variable_name = partial.gsub("#{display}_", '').to_sym %>  
22 - <%= render :partial => partial, :locals => {variable_name => hit} %> 20 + <%= render_for_class hit.class do |klass| %>
  21 + <% name = klass.name.underscore %>
  22 + <%= render partial_name_for(name, display), name.split('/').last.to_sym => hit %>
  23 + <% end %>
23 <% end %> 24 <% end %>
24 </ul> 25 </ul>
25 </div> 26 </div>
app/views/search/_full_product.html.erb
@@ -1,85 +0,0 @@ @@ -1,85 +0,0 @@
1 -<% extra_content = @plugins.dispatch(:asset_product_extras, product).collect { |content| instance_exec(&content) } %>  
2 -<% extra_properties = @plugins.dispatch(:asset_product_properties, product) %>  
3 -  
4 -<li class="search-product-item <%= 'highlighted' if product.highlighted? %>">  
5 -  
6 - <div class="search-product-item-first-column">  
7 - <%= render :partial => 'search/image', :object => product %>  
8 -  
9 - <% if product.available %>  
10 - <% if product.price && product.price > 0 %>  
11 - <% has_discount = product.discount && product.discount > 0 %>  
12 - <% if product.price %>  
13 - <span class="search-product-price-textid"><%=_("from") if has_discount %></span><%= price_span(product.price, :class => "search-product-price " + (has_discount ? 'with-discount' : '')) %>  
14 - <% if has_discount %>  
15 - <span class="search-product-price-textid"><%=_("by")%></span><%= price_span(product.price_with_discount, :class => "search-product-price") %>  
16 - <% end %>  
17 - <% if product.unit %>  
18 - <span class="search-product-unit">&nbsp;<%= _('/') %>&nbsp;<%= product.unit.name %></span>  
19 - <% end %>  
20 - <% end %>  
21 - <div class="search-product-inputs-info">  
22 - <% if p = product.percentage_from_solidarity_economy %>  
23 - <div class="search-product-percentage-from-solidarity-economy search-product-ecosol-percentage-icon-<%= p[0].to_s %>"  
24 - title="<%=_('Percentage of inputs from solidarity economy')%>">  
25 - <%= p[1] %>  
26 - </div>  
27 - <% end %>  
28 -  
29 - <% if product.price_described? %>  
30 - <% title = (product.inputs.relevant_to_price + product.price_details).map{ |i|  
31 - '<div class="search-product-input-dots-to-price">' +  
32 - '<div class="search-product-input-name">' + i.name + '</div>' +  
33 - price_span(i.price, :class => 'search-product-input-price') +  
34 - '</div>' }.join('') %>  
35 - <%= link_to_function _("Open Price"), '', :title => title, :class => "search-product-price-details" %>  
36 - <% end %>  
37 - </div>  
38 - <% end %>  
39 - <% else %>  
40 - <span class="product-not-available"><%= _('Not available') %></div>  
41 - <% end %>  
42 -  
43 - </div>  
44 - <div class="search-product-item-second-column">  
45 - <%= link_to_product product, :class => 'search-result-title' %>  
46 - <div class="search-product-supplier">  
47 - <span class="search-field-label"><%= _('Supplier') %> </span><%= link_to_homepage product.enterprise.name, product.enterprise %>  
48 - </div>  
49 - <div class="search-product-description">  
50 - <% if product.description %>  
51 - <% desc_stripped = strip_tags(product.description) %>  
52 - <span class="search-field-label"><%= _('Description') %> </span><%= excerpt desc_stripped, desc_stripped.first(3), radius: 300 %>  
53 - <% end %>  
54 - </div>  
55 - </div>  
56 - <div class="search-product-item-third-column">  
57 - <div class="search-product-region">  
58 - <% if product.enterprise.region %>  
59 - <span class="search-field-label"><%= _('City') %></span>  
60 - <br /><%= city_with_state(product.enterprise.region) %>  
61 - <% end %>  
62 - </div>  
63 - <div class="search-product-qualifiers">  
64 - <% if product.product_qualifiers.count > 0 %>  
65 - <span class="search-field-label"><%= _('Qualifiers') %></span>  
66 - <% product.product_qualifiers.each do |pq| %>  
67 - <% if pq.qualifier %>  
68 - <span class="search-product-qualifier"><%= pq.qualifier.name + (pq.certifier.nil? ? _(";") : '') %></span>  
69 - <% end %>  
70 - <% if pq.certifier %>  
71 - <span class="search-product-certifier">&nbsp;<%= _('cert. ') + pq.certifier.name + _(";") %></span>  
72 - <% end %>  
73 - <% end %>  
74 - <% end %>  
75 - </div>  
76 - </div>  
77 -  
78 - <div style="clear: both"></div>  
79 -  
80 - <%= safe_join(extra_content, '\n') %>  
81 - <% extra_properties.each do |property| %>  
82 - <div><%= ''.html_safe + property[:name] + ': ' + instance_exec(&property[:content]) %></div>  
83 - <% end %>  
84 -  
85 -</li>  
app/views/search/_image.html.erb
@@ -36,17 +36,6 @@ @@ -36,17 +36,6 @@
36 <div class="search-no-image"><span><%= _('No image') %></span></div> 36 <div class="search-no-image"><span><%= _('No image') %></span></div>
37 <% end %> 37 <% end %>
38 </div> 38 </div>
39 - <% elsif image.is_a? Product %>  
40 - <% if image.image %>  
41 - <div class="zoomable-image">  
42 - <%= link_to '', product_path(image), :class => "search-image-pic",  
43 - :style => 'background-image: url(%s)'% image.default_image(:thumb) %>  
44 - <%= link_to content_tag(:span, _('Zoom in')), image.image.public_filename,  
45 - :class => 'zoomify-image' %>  
46 - </div>  
47 - <% else %>  
48 - <div class="search-no-image"><span><%= _('No image') %></span></div>  
49 - <% end %>  
50 <% else %> 39 <% else %>
51 <div class="search-content-type-icon icon-content-<%=image.class.to_s.underscore.dasherize%>"></div> 40 <div class="search-content-type-icon icon-content-<%=image.class.to_s.underscore.dasherize%>"></div>
52 <% end %> 41 <% end %>
app/views/search/products.html.erb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -search_page.html.erb  
2 \ No newline at end of file 0 \ No newline at end of file
app/views/search/products.js.erb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -search.js.erb  
2 \ No newline at end of file 0 \ No newline at end of file
config/initializers/action_tracker.rb
@@ -32,15 +32,6 @@ ActionTrackerConfig.verbs = { @@ -32,15 +32,6 @@ ActionTrackerConfig.verbs = {
32 reply_scrap_on_self: { 32 reply_scrap_on_self: {
33 }, 33 },
34 34
35 - create_product: {  
36 - },  
37 -  
38 - update_product: {  
39 - },  
40 -  
41 - remove_product: {  
42 - },  
43 -  
44 favorite_enterprise: { 35 favorite_enterprise: {
45 }, 36 },
46 37
config/routes.rb
@@ -56,6 +56,13 @@ Noosfero::Application.routes.draw do @@ -56,6 +56,13 @@ Noosfero::Application.routes.draw do
56 # search 56 # search
57 match 'search(/:action(/*category_path))', controller: 'search', via: :all 57 match 'search(/:action(/*category_path))', controller: 'search', via: :all
58 58
  59 + ##
  60 + # Keep products URL compatibility
  61 + get 'catalog/:profile', to: redirect{ |params, request| "/profile/#{request.params[:profile]}/plugin/products/catalog" }
  62 + get 'myprofile/:profile/manage_products(/:action(/:id))', to: (redirect do |params, request|
  63 + "/profile/#{request.params[:profile]}/plugin/products/page/#{request.params[:action]}/#{request.params[:id]}"
  64 + end)
  65 +
59 # events 66 # events
60 match 'profile/:profile/events_by_day', controller: 'events', action: 'events_by_day', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all 67 match 'profile/:profile/events_by_day', controller: 'events', action: 'events_by_day', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all
61 match 'profile/:profile/events_by_month', controller: 'events', action: 'events_by_month', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all 68 match 'profile/:profile/events_by_month', controller: 'events', action: 'events_by_month', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all
@@ -63,9 +70,6 @@ Noosfero::Application.routes.draw do @@ -63,9 +70,6 @@ Noosfero::Application.routes.draw do
63 match 'profile/:profile/events/:year/:month', controller: 'events', action: 'events', year: /\d*/, month: /\d*/, profile: /#{Noosfero.identifier_format_in_url}/i, via: :all 70 match 'profile/:profile/events/:year/:month', controller: 'events', action: 'events', year: /\d*/, month: /\d*/, profile: /#{Noosfero.identifier_format_in_url}/i, via: :all
64 match 'profile/:profile/events', controller: 'events', action: 'events', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all 71 match 'profile/:profile/events', controller: 'events', action: 'events', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all
65 72
66 - # catalog  
67 - match 'catalog/:profile', controller: 'catalog', action: 'index', profile: /#{Noosfero.identifier_format_in_url}/i, as: :catalog, via: :all  
68 -  
69 # invite 73 # invite
70 match 'profile/:profile/invite/friends', controller: 'invite', action: 'invite_friends', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all 74 match 'profile/:profile/invite/friends', controller: 'invite', action: 'invite_friends', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all
71 match 'profile/:profile/invite/:action', controller: 'invite', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all 75 match 'profile/:profile/invite/:action', controller: 'invite', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all
@@ -95,6 +99,7 @@ Noosfero::Application.routes.draw do @@ -95,6 +99,7 @@ Noosfero::Application.routes.draw do
95 # chat 99 # chat
96 match 'chat(/:action(/:id))', controller: 'chat', via: :all 100 match 'chat(/:action(/:id))', controller: 'chat', via: :all
97 101
  102 +
98 ###################################################### 103 ######################################################
99 ## Controllers that are profile-specific (for profile admins ) 104 ## Controllers that are profile-specific (for profile admins )
100 ###################################################### 105 ######################################################
db/migrate/20160422163123_enable_products_plugin_on_environments.rb 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +class Product < ApplicationRecord
  2 +end
  3 +class Profile < ApplicationRecord
  4 + has_many :products
  5 +end
  6 +class Environment < ApplicationRecord
  7 + has_many :profiles
  8 + has_many :products, through: :profiles
  9 +
  10 + acts_as_having_settings field: :settings
  11 + settings_items :enabled_plugins, type: Array
  12 +end
  13 +
  14 +class EnableProductsPluginOnEnvironments < ActiveRecord::Migration
  15 +
  16 + def up
  17 + environments = Environment.all
  18 + products_used = environments.any?{ |e| e.products.count > 0 }
  19 + return unless products_used
  20 +
  21 + Bundler.clean_system 'script/noosfero-plugins enable products'
  22 + environments.each do |e|
  23 + next unless e.products.count > 0
  24 + e.enabled_plugins << 'ProductsPlugin'
  25 + e.save!
  26 + end
  27 + end
  28 +
  29 + def down
  30 + say "this migration can't be reverted"
  31 + end
  32 +
  33 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended that you check this file into your version control system. 12 # It's strongly recommended that you check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(version: 20160408011720) do 14 +ActiveRecord::Schema.define(version: 20160422163123) do
15 15
16 # These are extensions that must be enabled in order to support this database 16 # These are extensions that must be enabled in order to support this database
17 enable_extension "plpgsql" 17 enable_extension "plpgsql"
features/browse_catalogs.feature
@@ -1,317 +0,0 @@ @@ -1,317 +0,0 @@
1 -Feature: browse catalogs  
2 - As a noosfero visitor  
3 - I want to browse catalogs of products  
4 -  
5 - Background:  
6 - Given the following users  
7 - | login | name |  
8 - | joaosilva | Joao Silva |  
9 - And the following enterprises  
10 - | identifier | owner | name | enabled |  
11 - | artebonito | joaosilva | Associação de Artesanato de Bonito | true |  
12 - And feature "products_for_enterprises" is enabled on environment  
13 - And the following product_categories  
14 - | name |  
15 - | categ1 |  
16 - | food |  
17 - And I am on /catalog/artebonito  
18 -  
19 - Scenario: display titles  
20 - Then the page title should be "Associação de Artesanato de Bonito"  
21 - And I should see "Products/Services"  
22 -  
23 - Scenario: display the simplest possible product  
24 - Given the following products  
25 - | owner | category |  
26 - | artebonito | categ1 |  
27 - And I am on /catalog/artebonito  
28 - Then I should see "categ1" within "li.product-link"  
29 - And I should see "No image" within ".no-image"  
30 - And I should not see "unit" within "#product-list"  
31 - And I should not see "product unavailable"  
32 - And I should not see "description"  
33 - And I should not see "qualifiers"  
34 - And I should not see "price composition"  
35 -  
36 - Scenario: display a simple product without price  
37 - Given the following products  
38 - | owner | category | name |  
39 - | artebonito | categ1 | Produto1 |  
40 - And I am on /catalog/artebonito  
41 - Then I should see "Produto1" within "li.product-link"  
42 - And I should see "No image" within ".no-image"  
43 - And I should not see "unit" within "#product-list"  
44 - And I should not see "product unavailable"  
45 - And I should not see "description"  
46 - And I should not see "qualifiers"  
47 - And I should not see "price composition"  
48 -  
49 - Scenario: display a simple product without details  
50 - Given the following products  
51 - | owner | category | name | price |  
52 - | artebonito | categ1 | Produto1 | 50.00 |  
53 - And I am on /catalog/artebonito  
54 - Then I should see "Produto1" within "li.product-link"  
55 - And I should see "50.00" within "span.product-price"  
56 - And I should see "unit" within "span.product-unit"  
57 - And I should see "No image" within ".no-image"  
58 - And I should not see "product unavailable"  
59 - And I should not see "description"  
60 - And I should not see "qualifiers"  
61 - And I should not see "price composition"  
62 -  
63 - Scenario: don't display the price when it's $0.00  
64 - Given the following products  
65 - | owner | category | name | price |  
66 - | artebonito | categ1 | Produto1 | 0.00 |  
67 - And I am on /catalog/artebonito  
68 - Then I should see "Produto1" within "li.product-link"  
69 - And I should not see "0.00"  
70 -  
71 - Scenario: don't display the price when it's not defined  
72 - Given the following products  
73 - | owner | category | name |  
74 - | artebonito | categ1 | Produto1 |  
75 - And I am on /catalog/artebonito  
76 - Then I should see "Produto1" within "li.product-link"  
77 - And I should not see "0.00"  
78 - And I should see "No image" within ".no-image"  
79 - And I should not see "product unavailable"  
80 - And I should not see "description"  
81 - And I should not see "qualifiers"  
82 - And I should not see "price composition"  
83 -  
84 - Scenario: product name links to product page  
85 - Given the following products  
86 - | owner | category | name | price |  
87 - | artebonito | categ1 | Produto1 | 50.00 |  
88 - And I am on /catalog/artebonito  
89 - When I follow "Produto1" within "li.product-link"  
90 - Then I should be taken to "Produto1" product page  
91 -  
92 - Scenario: display product with custom image  
93 - Given the following products  
94 - | owner | category | name | price | img |  
95 - | artebonito | categ1 | Agrotox | 12.34 | agrotox |  
96 - And I am on /catalog/artebonito  
97 - Then I should see "Agrotox" within "li.product-link"  
98 - And I should see "12.34" within "span.product-price"  
99 - And I should see "unit" within "span.product-unit"  
100 - And I should not see "No image"  
101 - And I should not see "product unavailable"  
102 - And I should not see "description"  
103 - And I should not see "qualifiers"  
104 - And I should not see "price composition"  
105 -  
106 - Scenario: display "zoom in" button  
107 - Given the following products  
108 - | owner | category | name | price | img |  
109 - | artebonito | categ1 | Agrotox | 12.34 | agrotox |  
110 - And I am on /catalog/artebonito  
111 - And I should not see "No image"  
112 - And I should see "Zoom in" within ".zoomify-image"  
113 -  
114 - Scenario: image links to product page  
115 - Given the following products  
116 - | owner | category | name | price | img |  
117 - | artebonito | categ1 | Agrotox | 12.34 | agrotox |  
118 - And I am on /catalog/artebonito  
119 - When I follow "Agrotox" within ".product-image-link"  
120 - Then I should be taken to "Agrotox" product page  
121 -  
122 - Scenario: display product with discount  
123 - Given the following products  
124 - | owner | category | name | price | discount | img |  
125 - | artebonito | categ1 | Semterrinha | 99.99 | 12.34 | semterrinha |  
126 - And I am on /catalog/artebonito  
127 - Then I should see "Semterrinha" within "li.product-link"  
128 - And I should see "99.99" within "span.product-discount"  
129 - And I should see "87.65" within "span.product-price"  
130 - And I should not see "No image"  
131 - And I should not see "description"  
132 - And I should not see "qualifiers"  
133 - And I should not see "price composition"  
134 -  
135 - @selenium-fixme  
136 - Scenario: display description button when needed (but not the description)  
137 - Given the following products  
138 - | owner | category | name | price | description |  
139 - | artebonito | categ1 | Produto2 | 12.34 | A small description for a product that doesn't exist. |  
140 - And I am on /catalog/artebonito  
141 - And I reload and wait for the page  
142 - Then I should see "Produto2" within "li.product-link"  
143 - And I should see "12.34" within "span.product-price"  
144 - And I should see "description" within "#product-description-button"  
145 - And "description" should not be visible within "product-description-button"  
146 - And I should see "A small description" within "#product-description"  
147 - And "A small description for a product that doesn't exist" should not be visible within "product-description"  
148 -  
149 - @selenium-fixme  
150 - Scenario: display description when button is clicked  
151 - Given the following products  
152 - | owner | category | name | price | description |  
153 - | artebonito | categ1 | Produto3 | 12.34 | A small description for a product that doesn't exist. |  
154 - And I am on /catalog/artebonito  
155 - And I reload and wait for the page  
156 - When I follow "product-description-button"  
157 - Then I should see "A small description" within "#product-description"  
158 - And "A small description for a product that doesn't exist" should not be visible within "product-description"  
159 -  
160 - @selenium-fixme  
161 - Scenario: hide description  
162 - Given the following products  
163 - | owner | category | name | price | description |  
164 - | artebonito | categ1 | Produto3 | 12.34 | A small description for a product that doesn't exist. |  
165 - And I am on /catalog/artebonito  
166 - And I reload and wait for the page  
167 - When I click "product-description-button"  
168 - Then I should see "A small description" within "#product-description"  
169 - And the "product-description" should be visible  
170 - When I click "product-list"  
171 - Then the "product-description" should not be visible  
172 -  
173 - Scenario: display unavailable product  
174 - Given the following products  
175 - | owner | category | name | price | available |  
176 - | artebonito | categ1 | Prod3 | 12.34 | false |  
177 - And I am on /catalog/artebonito  
178 - Then I should see "Prod3" within "li.not-available"  
179 - And I should see "12.34" within "li.not-available"  
180 - And I should see "product unavailable" within "li.product-unavailable"  
181 - And I should not see "qualifiers"  
182 - And I should not see "price composition"  
183 -  
184 - Scenario: display qualifiers  
185 - Given the following qualifiers  
186 - | name |  
187 - | Organic |  
188 - And the following certifiers  
189 - | name | qualifiers |  
190 - | Colivre | Organic |  
191 - And the following products  
192 - | owner | category | name | price | qualifier |  
193 - | artebonito | categ1 | Banana | 0.99 | Organic |  
194 - And I am on /catalog/artebonito  
195 - Then I should see "Banana" within "li.product-link"  
196 - And I should see "0.99" within "span.product-price"  
197 - And I should see "qualifiers" within "li.product-qualifiers"  
198 - And I should see "Organic" within "span.search-product-qualifier"  
199 - And I should not see "price composition"  
200 -  
201 - @selenium-fixme  
202 - Scenario: not display price composition button if price is not described  
203 - Given the following product  
204 - | owner | category | name | price |  
205 - | artebonito | food | Bananada | 10.00 |  
206 - And the following input  
207 - | product | category | price_per_unit | amount_used |  
208 - | Bananada | food | 0.99 | 5 |  
209 - And I am on /catalog/artebonito  
210 - And I reload and wait for the page  
211 - Then I should see "Bananada" within "li.product-link"  
212 - And I should see "10.00" within "span.product-price"  
213 - And the "#product-price-composition-button" should not be visible  
214 -  
215 - @selenium-fixme  
216 - Scenario: display price composition button (but not inputs)  
217 - Given the following product  
218 - | owner | category | name | price |  
219 - | artebonito | food | Bananada | 10.00 |  
220 - And the following input  
221 - | product | category | price_per_unit | amount_used |  
222 - | Bananada | food | 2.00 | 5 |  
223 - And I am on /catalog/artebonito  
224 - And I reload and wait for the page  
225 - Then I should see "Bananada" within "li.product-link"  
226 - And I should see "10.00" within "span.product-price"  
227 - And I should see "price composition" within "#product-price-composition-button"  
228 - And the "#product-price-composition-button" should be visible  
229 - And I should see "food" within "#product-price-composition"  
230 - And I should see "10.00" within "#product-price-composition"  
231 -  
232 - @selenium-fixme  
233 - Scenario: display price composition when button is clicked  
234 - Given the following product  
235 - | owner | category | name | price |  
236 - | artebonito | food | Bananada | 10.88 |  
237 - And the following input  
238 - | product | category | price_per_unit | amount_used |  
239 - | Bananada | food | 2.72 | 4 |  
240 - And I am on /catalog/artebonito  
241 - And I reload and wait for the page  
242 - When I click "#product-price-composition-button"  
243 - Then the "#product-price-composition" should be visible  
244 - And I should see "food" within "#product-price-composition"  
245 - And I should see "10.88" within "#product-price-composition"  
246 -  
247 - @selenium-fixme  
248 - Scenario: display inputs and raw materials button when not completely filled  
249 - Given the following product  
250 - | owner | category | name | price |  
251 - | artebonito | food | Vitamina | 17.99 |  
252 - And the following unit  
253 - | name | plural |  
254 - | Liter | Liters |  
255 - And the following input  
256 - | product | category |  
257 - | Vitamina | food |  
258 - And I am on /catalog/artebonito  
259 - And I reload and wait for the page  
260 - Then the "#inputs-button" should be visible  
261 - And I should see "inputs and raw materials" within "#inputs-button"  
262 -  
263 - @selenium-fixme  
264 - Scenario: display inputs and raw materials button  
265 - Given the following product  
266 - | owner | category | name | price |  
267 - | artebonito | food | Vitamina | 17.99 |  
268 - And the following unit  
269 - | name | plural |  
270 - | Liter | Liters |  
271 - And the following input  
272 - | product | category | price_per_unit | amount_used | unit |  
273 - | Vitamina | food | 1.45 | 7 | Liter |  
274 - And I am on /catalog/artebonito  
275 - And I reload and wait for the page  
276 - Then I should see "Vitamina" within "li.product-link"  
277 - And I should see "17.99" within "span.product-price"  
278 - And the "#inputs-button" should be visible  
279 - And I should see "inputs and raw materials" within "#inputs-button"  
280 - And the "#inputs-description" should not be visible  
281 - And I should see "7.0 Liter of food" within "#inputs-description"  
282 -  
283 - @selenium-fixme  
284 - Scenario: display inputs and raw materials description  
285 - Given the following product  
286 - | owner | category | name | price |  
287 - | artebonito | food | Vitamina | 17.99 |  
288 - And the following unit  
289 - | name | plural |  
290 - | Liter | Liters |  
291 - And the following input  
292 - | product | category | price_per_unit | amount_used | unit |  
293 - | Vitamina | food | 1.45 | 7 | Liter |  
294 - And I am on /catalog/artebonito  
295 - And I reload and wait for the page  
296 - When I click "#inputs-button"  
297 - Then the "#inputs-description" should be visible  
298 - And I should see "7.0 Liter of food" within "#inputs-description"  
299 -  
300 - @selenium-fixme  
301 - Scenario: hide inputs and raw materials  
302 - Given the following product  
303 - | owner | category | name | price |  
304 - | artebonito | food | Vitamina | 17.99 |  
305 - And the following unit  
306 - | name | plural |  
307 - | Liter | Liters |  
308 - And the following input  
309 - | product | category | price_per_unit | amount_used | unit |  
310 - | Vitamina | food | 1.45 | 7 | Liter |  
311 - And I am on /catalog/artebonito  
312 - And I reload and wait for the page  
313 - When I click "#inputs-button"  
314 - Then the "#inputs-description" should be visible  
315 - And I should see "7.0 Liter of food" within "#inputs-description"  
316 - When I click "#product-list"  
317 - Then the "#inputs-description" should not be visible  
features/categories_block.feature
@@ -4,16 +4,6 @@ Feature: categories_block @@ -4,16 +4,6 @@ Feature: categories_block
4 4
5 Background: 5 Background:
6 Given I am on the homepage 6 Given I am on the homepage
7 - And the following product_categories  
8 - | name | display_in_menu |  
9 - | Food | true |  
10 - | Book | true |  
11 - And the following product_categories  
12 - | parent | name | display_in_menu |  
13 - | Food | Vegetarian | true |  
14 - | Food | Steak | true |  
15 - | Book | Fiction | false |  
16 - | Book | Literature | true |  
17 And the following categories 7 And the following categories
18 | name | display_in_menu | 8 | name | display_in_menu |
19 | Wood | true | 9 | Wood | true |
@@ -27,49 +17,6 @@ Feature: categories_block @@ -27,49 +17,6 @@ Feature: categories_block
27 And I go to /admin/environment_design 17 And I go to /admin/environment_design
28 18
29 @selenium 19 @selenium
30 - Scenario: List just product categories  
31 - Given display ".button-bar"  
32 - And I follow "Edit" within ".block-outer .categories-block"  
33 - And I check "Product"  
34 - When I press "Save"  
35 - Then I should see "Food"  
36 - And I should see "Book"  
37 - And "Vegetarian" should not be visible within "span#category-name"  
38 - And "Steak" should not be visible within "span#category-name"  
39 - And "Fiction" should not be visible within "span#category-name"  
40 -  
41 - @selenium  
42 - Scenario: Show submenu if it exists  
43 - Given display ".button-bar"  
44 - And I follow "Edit" within ".block-outer .categories-block"  
45 - And I check "Product"  
46 - And I press "Save"  
47 - And I go to /  
48 - Then I should see "Food"  
49 - And I should see "Book"  
50 - And "Vegetarian" should not be visible within "span#category-name"  
51 - And "Steak" should not be visible within "span#category-name"  
52 - And "Literature" should not be visible within "span#category-name"  
53 - When I follow "block_2_category_2"  
54 - Then I should see "Literature"  
55 - When I follow "block_2_category_1"  
56 - Then I should see "Vegetarian"  
57 - And I should see "Steak"  
58 - And I should not see "Fiction"  
59 -  
60 - @selenium  
61 - Scenario: Show only one submenu per time  
62 - Given display ".button-bar"  
63 - And I follow "Edit" within ".block-outer .categories-block"  
64 - And I check "Product"  
65 - And I press "Save"  
66 - And I go to /  
67 - Then I should see "Book"  
68 - And "Literature" should not be visible within "span#category-name"  
69 - When I follow "block_2_category_2"  
70 - Then I should see "Literature"  
71 -  
72 - @selenium  
73 Scenario: List just general categories 20 Scenario: List just general categories
74 Given display ".button-bar" 21 Given display ".button-bar"
75 And I follow "Edit" within ".block-outer .categories-block" 22 And I follow "Edit" within ".block-outer .categories-block"
features/enterprise_homepage.feature
@@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
1 -# These tests were originally unit tests, but they were moved here since they are view tests. The originals have been kept just in case somebody wants to review them, but should be removed shortly.  
2 -  
3 -Feature: enterprise homepage  
4 - As a noosfero visitor  
5 - I want to browse an enterprise's homepage  
6 - In order to know more information about the enterprise  
7 -  
8 - Background:  
9 - Given the following users  
10 - | login | name |  
11 - | durdentyler | Tyler Durden |  
12 - And the following enterprises  
13 - | identifier | owner | name | contact_email | contact_phone | enabled |  
14 - | mayhem | durdentyler | Paper Street Soap Co. | queen@workerbees.org | (288) 555-0153 | true |  
15 - And the following enterprise homepage  
16 - | enterprise | name |  
17 - | mayhem | article homepage |  
18 - And the following product_category  
19 - | name |  
20 - | soap |  
21 - And the following product  
22 - | name | category | owner |  
23 - | Natural Handmade | soap | mayhem |  
24 - And feature "products_for_enterprises" is enabled on environment  
25 -  
26 -  
27 - Scenario: display profile info  
28 - When I go to /mayhem/homepage  
29 - Then I should see "queen@workerbees.org"  
30 - And I should see "(288) 555-0153"  
31 -  
32 - Scenario: display products list  
33 - When I go to /mayhem/homepage  
34 - Then I should see "Natural Handmade"  
35 -  
36 - Scenario: display link to product  
37 - When I go to /mayhem/homepage  
38 - And I follow "Natural Handmade"  
39 - Then I should be taken to "Natural Handmade" product page  
features/featured_products_block.feature
@@ -1,47 +0,0 @@ @@ -1,47 +0,0 @@
1 -Feature: featured_products_block  
2 - As a profile owner  
3 - I want to edit the featured block  
4 -  
5 - Background:  
6 - Given I am on the homepage  
7 - And the following users  
8 - | login | name |  
9 - | eddievedder | Eddie Vedder |  
10 - And the following enterprises  
11 - | identifier | owner | name | enabled |  
12 - | redemoinho | eddievedder | Rede Moinho | true |  
13 - And the following blocks  
14 - | owner | type |  
15 - | redemoinho | FeaturedProductsBlock |  
16 - And the following product_category  
17 - | name |  
18 - | automobile |  
19 - And the following products  
20 - | owner | category | name | description | highlighted |  
21 - | redemoinho | automobile | Car | Red Car | true |  
22 - | redemoinho | automobile | Truck | Blue Truck | true |  
23 - | redemoinho | automobile | Moto | Very long description of and auto-mobile moto to be truncated | true |  
24 - And I am logged in as "eddievedder"  
25 -  
26 - @selenium-fixme  
27 - Scenario: select a product to be featured  
28 - And I follow "Manage my groups"  
29 - And I follow "Control panel of this group"  
30 - And I follow "Edit sideboxes"  
31 - Given I follow "Edit" within ".featured-products-block"  
32 - And I select "Car"  
33 - When I press "Save"  
34 - Then I should see "Car"  
35 - And I should not see "float_to_currency"  
36 - And I should not see "product_path"  
37 -  
38 - @selenium-fixme  
39 - Scenario: display block with long description  
40 - Given I follow "Manage my groups"  
41 - And I follow "Control panel of this group"  
42 - And I follow "Edit sideboxes"  
43 - And I follow "Edit" within ".featured-products-block"  
44 - And I select "Moto"  
45 - And I press "Save"  
46 - When I am on redemoinho's homepage  
47 - Then I should see "Very long description of and auto-mobile moto to b..."  
features/search.feature
@@ -3,9 +3,6 @@ Feature: search @@ -3,9 +3,6 @@ Feature: search
3 I want to search 3 I want to search
4 In order to find stuff 4 In order to find stuff
5 5
6 - Background:  
7 - Given feature "disable_asset_products" is disabled on environment  
8 -  
9 Scenario: show empty results in all enabled assets 6 Scenario: show empty results in all enabled assets
10 Given I go to the search page 7 Given I go to the search page
11 And I fill in "search-input" with "Anything" 8 And I fill in "search-input" with "Anything"
@@ -18,8 +15,6 @@ Feature: search @@ -18,8 +15,6 @@ Feature: search
18 And I should see "None" within ".search-results-enterprises" 15 And I should see "None" within ".search-results-enterprises"
19 And I should see "Contents" within ".search-results-articles" 16 And I should see "Contents" within ".search-results-articles"
20 And I should see "None" within ".search-results-articles" 17 And I should see "None" within ".search-results-articles"
21 - And I should see "Products" within ".search-results-products"  
22 - And I should see "None" within ".search-results-products"  
23 And I should see "Events" within ".search-results-events" 18 And I should see "Events" within ".search-results-events"
24 And I should see "None" within ".search-results-events" 19 And I should see "None" within ".search-results-events"
25 20
@@ -92,23 +87,6 @@ Feature: search @@ -92,23 +87,6 @@ Feature: search
92 Then I should see "whales and dolphins" within "div.search-results-articles" 87 Then I should see "whales and dolphins" within "div.search-results-articles"
93 And I should not see "bees and butterflies" 88 And I should not see "bees and butterflies"
94 89
95 - Scenario: simple search for product  
96 - Given the following enterprises  
97 - | identifier | name |  
98 - | colivre-ent | Colivre |  
99 - And the following product_categories  
100 - | name |  
101 - | Development |  
102 - And the following products  
103 - | owner | category | name |  
104 - | colivre-ent | development | social networks consultancy |  
105 - | colivre-ent | development | wikis consultancy |  
106 - When I go to the search page  
107 - And I fill in "search-input" with "wikis"  
108 - And I press "Search"  
109 - Then I should see "wikis consultancy" within "div.search-results-products"  
110 - And I should not see "social networks consultancy"  
111 -  
112 Scenario: simple search for event 90 Scenario: simple search for event
113 Given the following communities 91 Given the following communities
114 | identifier | name | 92 | identifier | name |
@@ -130,15 +108,8 @@ Feature: search @@ -130,15 +108,8 @@ Feature: search
130 And the following communities 108 And the following communities
131 | identifier | name | 109 | identifier | name |
132 | noosfero-users | Noosfero users | 110 | noosfero-users | Noosfero users |
133 - And the following product_categories  
134 - | name |  
135 - | Development |  
136 - And the following products  
137 - | owner | name | category |  
138 - | colivre_dev | Noosfero platform | Development |  
139 When I go to the search page 111 When I go to the search page
140 And I fill in "search-input" with "noosfero" 112 And I fill in "search-input" with "noosfero"
141 And I press "Search" 113 And I press "Search"
142 Then I should see "Colivre - Noosfero dev." within "div.search-results-enterprises" 114 Then I should see "Colivre - Noosfero dev." within "div.search-results-enterprises"
143 And I should see "Noosfero users" within "div.search-results-communities" 115 And I should see "Noosfero users" within "div.search-results-communities"
144 - And I should see "Noosfero platform" within "div.search-results-products"  
features/search_products.feature
@@ -1,105 +0,0 @@ @@ -1,105 +0,0 @@
1 -Feature: search products  
2 - As a noosfero user  
3 - I want to search products  
4 - In order to find ones that interest me  
5 -  
6 - Background:  
7 - Given feature "disable_asset_products" is disabled on environment  
8 - And the following enterprises  
9 - | identifier | name |  
10 - | colivre-ent | Colivre |  
11 - And the following product_categories  
12 - | name |  
13 - | Development |  
14 - And the following products  
15 - | owner | category | name | price | img |  
16 - | colivre-ent | development | social networks consultancy | 1.00 | fruits |  
17 - | colivre-ent | development | wikis consultancy | 2.00 | shoes |  
18 -  
19 - Scenario: show recent products on index  
20 - When I go to the search products page  
21 - Then I should see "wikis consultancy" within "#search-results"  
22 - And I should see "social networks consultancy" within "#search-results"  
23 -  
24 - Scenario: show empty search results  
25 - When I search products for "something unrelated"  
26 - Then I should see "None" within ".search-results-type-empty"  
27 -  
28 - Scenario: simple search for product  
29 - Given there are no pending jobs  
30 - When I search products for "wikis"  
31 - Then I should see "wikis consultancy" within "#search-results"  
32 - And I should see "wikis consultancy" within ".only-one-result-box"  
33 - And I should see wikis consultancy's product image  
34 - And I should not see "social networks consultancy"  
35 - And I should not see social networks consultancy's product image  
36 -  
37 - Scenario: show percentage (100%) of solidary economy inputs in results  
38 - Given the following inputs  
39 - | product | category | solidary |  
40 - | wikis consultancy | development | true |  
41 - When I go to the search products page  
42 - And I fill in "search-input" with "wikis"  
43 - And I press "Search"  
44 - Then I should see "100%" within "div.search-product-ecosol-percentage-icon-100"  
45 -  
46 - Scenario: show percentage (50%) of solidary economy inputs in results  
47 - Given the following inputs  
48 - | product | category | solidary |  
49 - | wikis consultancy | development | true |  
50 - | wikis consultancy | development | false |  
51 - When I go to the search products page  
52 - And I fill in "search-input" with "wikis"  
53 - And I press "Search"  
54 - Then I should see "50%" within "div.search-product-ecosol-percentage-icon-50"  
55 -  
56 - Scenario: show percentage (75%) of solidary economy inputs in results  
57 - Given the following inputs  
58 - | product | category | solidary |  
59 - | wikis consultancy | development | true |  
60 - | wikis consultancy | development | true |  
61 - | wikis consultancy | development | true |  
62 - | wikis consultancy | development | false |  
63 - When I go to the search products page  
64 - And I fill in "search-input" with "wikis"  
65 - And I press "Search"  
66 - Then I should see "75%" within "div.search-product-ecosol-percentage-icon-75"  
67 -  
68 - Scenario: show percentage (25%) of solidary economy inputs in results  
69 - Given the following inputs  
70 - | product | category | solidary |  
71 - | wikis consultancy | development | true |  
72 - | wikis consultancy | development | false |  
73 - | wikis consultancy | development | false |  
74 - | wikis consultancy | development | false |  
75 - When I go to the search products page  
76 - And I fill in "search-input" with "wikis"  
77 - And I press "Search"  
78 - Then I should see "25%" within "div.search-product-ecosol-percentage-icon-25"  
79 -  
80 - Scenario: display "zoom in" button on images on results  
81 - Given the following products  
82 - | owner | category | name | price | img |  
83 - | colivre-ent | development | noosfero | 12.34 | noosfero-network |  
84 - When I go to the search products page  
85 - And I fill in "search-input" with "noosfero"  
86 - And I press "Search"  
87 - Then I should not see "No image"  
88 - And I should see "Zoom in" within "a.zoomify-image"  
89 -  
90 - Scenario: find products without exact query  
91 - Given the following product_category  
92 - | name |  
93 - | Software Livre |  
94 - And the following products  
95 - | owner | name | category |  
96 - | colivre-ent | Noosfero Social Network Platform | software-livre |  
97 - When I go to the search products page  
98 - And I fill in "search-input" with "Noosfero Social"  
99 - And I press "Search"  
100 - Then I should see "Noosfero Social Network Platform" within "#search-results"  
101 -  
102 - Scenario: don't search when products are disabled in environment  
103 - Given feature "disable_asset_products" is enabled on environment  
104 - When I go to the search products page  
105 - Then I should see "There is no such page" within "#not-found"