Commit 53d8ceb4d43536a7311c19bc15d4ed5911f5b88a
Exists in
master
and in
28 other branches
Merge branch 'merge-requests/248' into redemoinho
Conflicts: lib/noosfero/plugin/settings.rb test/unit/plugin_settings_test.rb
Showing
37 changed files
with
690 additions
and
117 deletions
Show diff stats
app/controllers/public/catalog_controller.rb
1 | 1 | class CatalogController < PublicController |
2 | 2 | needs_profile |
3 | + no_design_blocks | |
3 | 4 | |
4 | 5 | before_filter :check_enterprise_and_environment |
5 | 6 | |
6 | 7 | def index |
7 | - @products = @profile.products.paginate(:order => 'name asc', :per_page => 9, :page => params[:page]) | |
8 | + @category = params[:level] ? ProductCategory.find(params[:level]) : nil | |
9 | + @products = @profile.products.from_category(@category).paginate(:order => 'available desc, highlighted desc, name asc', :per_page => 9, :page => params[:page]) | |
10 | + @categories = ProductCategory.on_level(params[:level]) | |
8 | 11 | end |
9 | 12 | |
10 | 13 | protected | ... | ... |
app/helpers/catalog_helper.rb
... | ... | @@ -3,4 +3,28 @@ module CatalogHelper |
3 | 3 | include DisplayHelper |
4 | 4 | include ManageProductsHelper |
5 | 5 | |
6 | + def breadcrumb(category) | |
7 | + start = link_to(_('Start'), {:action => 'index'}) | |
8 | + ancestors = category.ancestors.map { |c| link_to(c.name, {:action => 'index', :level => c.id}) }.reverse | |
9 | + current_level = content_tag('strong', category.name) | |
10 | + all_items = [start] + ancestors + [current_level] | |
11 | + content_tag('div', all_items.join(' → '), :id => 'breadcrumb') | |
12 | + end | |
13 | + | |
14 | + def category_link(category, sub = false) | |
15 | + count = profile.products.from_category(category).count | |
16 | + name = truncate(category.name, :length => 22 - count.to_s.size) | |
17 | + link_name = sub ? name : content_tag('strong', name) | |
18 | + link = link_to(link_name, {:action => 'index', :level => category.id}, :title => category.name) | |
19 | + content_tag('li', "#{link} (#{count})") if count > 0 | |
20 | + end | |
21 | + | |
22 | + def category_sub_links(category) | |
23 | + sub_categories = [] | |
24 | + category.children.each do |sub_category| | |
25 | + sub_categories << category_link(sub_category, true) | |
26 | + end | |
27 | + content_tag('ul', sub_categories) if sub_categories.size > 1 | |
28 | + end | |
29 | + | |
6 | 30 | end | ... | ... |
app/helpers/display_helper.rb
... | ... | @@ -8,6 +8,14 @@ module DisplayHelper |
8 | 8 | opts |
9 | 9 | end |
10 | 10 | |
11 | + def themed_path(file) | |
12 | + if File.exists?(File.join(Rails.root, 'public', theme_path, file)) | |
13 | + File.join(theme_path, file) | |
14 | + else | |
15 | + file | |
16 | + end | |
17 | + end | |
18 | + | |
11 | 19 | def image_link_to_product(product, opts={}) |
12 | 20 | return _('No product') unless product |
13 | 21 | target = product_path(product) | ... | ... |
app/models/category.rb
... | ... | @@ -13,6 +13,16 @@ class Category < ActiveRecord::Base |
13 | 13 | {:conditions => ['parent_id is null and environment_id = ?', environment.id ]} |
14 | 14 | } |
15 | 15 | |
16 | + named_scope :on_level, lambda { |parent| {:conditions => {:parent_id => parent}} } | |
17 | + | |
18 | + named_scope :sub_categories, lambda { |category| | |
19 | + {:conditions => ['categories.path LIKE ? AND categories.id != ?', "%#{category.slug}%", category.id]} | |
20 | + } | |
21 | + | |
22 | + named_scope :sub_tree, lambda { |category| | |
23 | + {:conditions => ['categories.path LIKE ?', "%#{category.slug}%"]} | |
24 | + } | |
25 | + | |
16 | 26 | acts_as_filesystem |
17 | 27 | |
18 | 28 | has_many :article_categorizations, :dependent => :destroy | ... | ... |
app/models/organization.rb
... | ... | @@ -78,6 +78,8 @@ class Organization < Profile |
78 | 78 | country |
79 | 79 | tag_list |
80 | 80 | template_id |
81 | + district | |
82 | + address_reference | |
81 | 83 | ] |
82 | 84 | |
83 | 85 | def self.fields |
... | ... | @@ -96,8 +98,8 @@ class Organization < Profile |
96 | 98 | [] |
97 | 99 | end |
98 | 100 | |
99 | - N_('Display name'); N_('Description'); N_('Contact person'); N_('Contact email'); N_('Acronym'); N_('Foundation year'); N_('Legal form'); N_('Economic activity'); N_('Management information'); N_('Tag list') | |
100 | - settings_items :display_name, :description, :contact_person, :contact_email, :acronym, :foundation_year, :legal_form, :economic_activity, :management_information | |
101 | + N_('Display name'); N_('Description'); N_('Contact person'); N_('Contact email'); N_('Acronym'); N_('Foundation year'); N_('Legal form'); N_('Economic activity'); N_('Management information'); N_('Tag list'); N_('District'); N_('Address reference') | |
102 | + settings_items :display_name, :description, :contact_person, :contact_email, :acronym, :foundation_year, :legal_form, :economic_activity, :management_information, :district, :address_reference | |
101 | 103 | |
102 | 104 | validates_format_of :foundation_year, :with => Noosfero::Constants::INTEGER_FORMAT |
103 | 105 | validates_format_of :contact_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |org| !org.contact_email.blank? }) | ... | ... |
app/models/person.rb
... | ... | @@ -147,6 +147,9 @@ class Person < Profile |
147 | 147 | contact_phone |
148 | 148 | contact_information |
149 | 149 | description |
150 | + image | |
151 | + district | |
152 | + address_reference | |
150 | 153 | ] |
151 | 154 | |
152 | 155 | validates_multiparameter_assignments |
... | ... | @@ -201,8 +204,8 @@ class Person < Profile |
201 | 204 | N_('Education'); N_('Custom education'); N_('Custom area of study'); |
202 | 205 | settings_items :formation, :custom_formation, :custom_area_of_study |
203 | 206 | |
204 | - N_('Contact information'); N_('City'); N_('State'); N_('Country'); N_('Sex'); N_('Zip code') | |
205 | - settings_items :photo, :contact_information, :sex, :city, :state, :country, :zip_code | |
207 | + N_('Contact information'); N_('City'); N_('State'); N_('Country'); N_('Sex'); N_('Zip code'); N_('District'); N_('Address reference') | |
208 | + settings_items :photo, :contact_information, :sex, :city, :state, :country, :zip_code, :district, :address_reference | |
206 | 209 | |
207 | 210 | extend SetProfileRegionFromCityState::ClassMethods |
208 | 211 | set_profile_region_from_city_state | ... | ... |
app/models/product.rb
... | ... | @@ -23,6 +23,10 @@ class Product < ActiveRecord::Base |
23 | 23 | |
24 | 24 | named_scope :more_recent, :order => "created_at DESC" |
25 | 25 | |
26 | + named_scope :from_category, lambda { |category| | |
27 | + {:joins => :product_category, :conditions => ['categories.path LIKE ?', "%#{category.slug}%"]} if category | |
28 | + } | |
29 | + | |
26 | 30 | after_update :save_image |
27 | 31 | |
28 | 32 | def lat | ... | ... |
app/models/profile.rb
... | ... | @@ -141,6 +141,10 @@ class Profile < ActiveRecord::Base |
141 | 141 | |
142 | 142 | acts_as_having_settings :field => :data |
143 | 143 | |
144 | + def settings | |
145 | + data | |
146 | + end | |
147 | + | |
144 | 148 | settings_items :redirect_l10n, :type => :boolean, :default => false |
145 | 149 | settings_items :public_content, :type => :boolean, :default => true |
146 | 150 | settings_items :description |
... | ... | @@ -229,7 +233,7 @@ class Profile < ActiveRecord::Base |
229 | 233 | if myregion |
230 | 234 | myregion.hierarchy.reverse.first(2).map(&:name).join(separator) |
231 | 235 | else |
232 | - %w[address city state country_name zip_code ].map {|item| (self.respond_to?(item) && !self.send(item).blank?) ? self.send(item) : nil }.compact.join(separator) | |
236 | + %w[address district city state country_name zip_code ].map {|item| (self.respond_to?(item) && !self.send(item).blank?) ? self.send(item) : nil }.compact.join(separator) | |
233 | 237 | end |
234 | 238 | end |
235 | 239 | |
... | ... | @@ -694,7 +698,7 @@ private :generate_url, :url_options |
694 | 698 | def custom_footer_expanded |
695 | 699 | footer = custom_footer |
696 | 700 | if footer |
697 | - %w[contact_person contact_email contact_phone location address economic_activity city state country zip_code].each do |att| | |
701 | + %w[contact_person contact_email contact_phone location address district address_reference economic_activity city state country zip_code].each do |att| | |
698 | 702 | if self.respond_to?(att) && footer.match(/\{[^{]*#{att}\}/) |
699 | 703 | if !self.send(att).nil? && !self.send(att).blank? |
700 | 704 | footer = footer.gsub(/\{([^{]*)#{att}\}/, '\1' + self.send(att)) | ... | ... |
app/views/catalog/index.rhtml
1 | 1 | <% extra_content = [] %> |
2 | 2 | <% extra_content_list = [] %> |
3 | 3 | |
4 | -<ul id="product-list"> | |
5 | - <li><h1><%= _('Products/Services') %></h1></li> | |
4 | +<h1><%= _('Products/Services') %></h1> | |
6 | 5 | |
6 | +<%= breadcrumb(@category) if params[:level] %> | |
7 | + | |
8 | +<div class='l-sidebar-left-bar'> | |
9 | + <ul> | |
10 | + <% if @categories.size > 0 %> | |
11 | + <% @categories.each do |category| %> | |
12 | + <%= category_link(category) %> | |
13 | + <%= category_sub_links(category) %> | |
14 | + <% end %> | |
15 | + <% else %> | |
16 | + <%= content_tag('li', _('There are no sub-categories for %s') % @category.name, :style => 'color: #555753; padding-bottom: 0.5em;') %> | |
17 | + <% end %> | |
18 | + </ul> | |
19 | +</div> | |
20 | + | |
21 | +<ul id="product-list" class="l-sidebar-left-content"> | |
7 | 22 | <% @products.each do |product| %> |
8 | 23 | <% extra_content = @plugins.dispatch(:catalog_item_extras, product).collect { |content| instance_eval(&content) } %> |
9 | 24 | <% extra_content_list = @plugins.dispatch(:catalog_list_item_extras, product).collect { |content| instance_eval(&content) } %> |
10 | 25 | |
11 | - <li class="product <%= "not-available" unless product.available %>"> | |
26 | + <% status = [] %> | |
27 | + <% status << 'not-available' if !product.available %> | |
28 | + <% status << 'highlighted' if product.highlighted %> | |
29 | + | |
30 | + <li class="product <%= status.join(' ') %>"> | |
12 | 31 | <ul> |
13 | 32 | <li class="product-image-link"> |
33 | + <% if product.highlighted? %> | |
34 | + <%= link_to image_tag(themed_path('/images/star.png'), :class => 'star', :alt => _('Highlighted product')), product_path(product) %> | |
35 | + <% end %> | |
14 | 36 | <% if product.image %> |
15 | 37 | <div class="zoomable-image"> |
16 | 38 | <%= link_to_product product, :class => 'product-big', :style => "background-image: url(#{product.default_image(:big)})" %> | ... | ... |
app/views/profile_editor/_person_form.rhtml
... | ... | @@ -21,6 +21,8 @@ |
21 | 21 | <%= optional_field(@person, 'city', f.text_field(:city, :rel => _('City'))) %> |
22 | 22 | <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %> |
23 | 23 | <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %> |
24 | +<%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference, :rel => _('Address reference')))) %> | |
25 | +<%= optional_field(@person, 'district', labelled_form_field(_('District'), text_field(:profile_data, :district, :rel => _('District')))) %> | |
24 | 26 | |
25 | 27 | <% optional_field(@person, 'schooling') do %> |
26 | 28 | <div class="formfieldline"> | ... | ... |
app/views/search/_product.rhtml
1 | 1 | <% extra_content = @plugins.dispatch(:asset_product_extras, product, product.enterprise).collect { |content| instance_eval(&content) } %> |
2 | 2 | <% extra_properties = @plugins.dispatch(:asset_product_properties, product)%> |
3 | 3 | |
4 | -<li class="search-product-item"> | |
4 | +<li class="search-product-item <%= 'highlighted' if product.highlighted? %>"> | |
5 | 5 | |
6 | 6 | <div class="search-product-item-first-column"> |
7 | 7 | <%= render :partial => 'search/image', :object => product %> | ... | ... |
app/views/shared/_organization_custom_fields.rhtml
... | ... | @@ -10,6 +10,8 @@ |
10 | 10 | <%= optional_field(profile, 'economic_activity', f.text_field(:economic_activity)) %> |
11 | 11 | <%= optional_field(profile, 'management_information', f.text_area(:management_information, :rows => 5)) %> |
12 | 12 | <%= optional_field(profile, 'address', labelled_form_field(_('Address (street and number)'), text_field(object_name, :address))) %> |
13 | +<%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %> | |
14 | +<%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %> | |
13 | 15 | <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(object_name, :zip_code))) %> |
14 | 16 | <%= optional_field(profile, 'city', f.text_field(:city)) %> |
15 | 17 | <%= optional_field(profile, 'state', f.text_field(:state)) %> | ... | ... |
lib/noosfero/plugin/settings.rb
1 | 1 | class Noosfero::Plugin::Settings |
2 | 2 | |
3 | - def initialize(environment, plugin, attributes = nil) | |
4 | - @environment = environment | |
3 | + def initialize(base, plugin, attributes = nil) | |
4 | + @base = base | |
5 | 5 | @plugin = plugin |
6 | 6 | attributes ||= {} |
7 | 7 | attributes.each do |k,v| |
... | ... | @@ -10,7 +10,7 @@ class Noosfero::Plugin::Settings |
10 | 10 | end |
11 | 11 | |
12 | 12 | def settings |
13 | - @environment.settings["#{@plugin.public_name}_plugin".to_sym] ||= {} | |
13 | + @base.settings["#{@plugin.public_name}_plugin".to_sym] ||= {} | |
14 | 14 | end |
15 | 15 | |
16 | 16 | def method_missing(method, *args, &block) |
... | ... | @@ -38,7 +38,11 @@ class Noosfero::Plugin::Settings |
38 | 38 | end |
39 | 39 | |
40 | 40 | def save! |
41 | +<<<<<<< HEAD | |
41 | 42 | @environment.save! |
43 | +======= | |
44 | + @base.save! | |
45 | +>>>>>>> merge-requests/248 | |
42 | 46 | end |
43 | 47 | |
44 | 48 | end | ... | ... |
plugins/shopping_cart/controllers/shopping_cart_plugin_myprofile_controller.rb
... | ... | @@ -4,9 +4,12 @@ class ShoppingCartPluginMyprofileController < MyProfileController |
4 | 4 | append_view_path File.join(File.dirname(__FILE__) + '/../views') |
5 | 5 | |
6 | 6 | def edit |
7 | + params[:settings] = treat_cart_options(params[:settings]) | |
8 | + | |
9 | + @settings = Noosfero::Plugin::Settings.new(profile, ShoppingCartPlugin, params[:settings]) | |
7 | 10 | if request.post? |
8 | 11 | begin |
9 | - profile.update_attributes!(params[:profile_attr]) | |
12 | + @settings.save! | |
10 | 13 | session[:notice] = _('Option updated successfully.') |
11 | 14 | rescue Exception => exception |
12 | 15 | session[:notice] = _('Option wasn\'t updated successfully.') |
... | ... | @@ -46,4 +49,25 @@ class ShoppingCartPluginMyprofileController < MyProfileController |
46 | 49 | order.save! |
47 | 50 | redirect_to :action => 'reports', :from => params[:context_from], :to => params[:context_to], :filter_status => params[:context_status] |
48 | 51 | end |
52 | + | |
53 | + private | |
54 | + | |
55 | + def treat_cart_options(settings) | |
56 | + return if settings.blank? | |
57 | + settings[:enabled] = settings[:enabled] == '1' | |
58 | + settings[:delivery] = settings[:delivery] == '1' | |
59 | + settings[:free_delivery_price] = settings[:free_delivery_price].blank? ? nil : settings[:free_delivery_price].to_d | |
60 | + settings[:delivery_options] = treat_delivery_options(settings[:delivery_options]) | |
61 | + settings | |
62 | + end | |
63 | + | |
64 | + def treat_delivery_options(params) | |
65 | + result = {} | |
66 | + params[:options].size.times do |counter| | |
67 | + if params[:options][counter].present? && params[:prices][counter].present? | |
68 | + result[params[:options][counter]] = params[:prices][counter] | |
69 | + end | |
70 | + end | |
71 | + result | |
72 | + end | |
49 | 73 | end | ... | ... |
plugins/shopping_cart/controllers/shopping_cart_plugin_profile_controller.rb
... | ... | @@ -85,14 +85,15 @@ class ShoppingCartPluginProfileController < ProfileController |
85 | 85 | |
86 | 86 | def buy |
87 | 87 | @environment = profile.environment |
88 | + @settings = Noosfero::Plugin::Settings.new(profile, ShoppingCartPlugin) | |
88 | 89 | render :layout => false |
89 | 90 | end |
90 | 91 | |
91 | 92 | def send_request |
92 | 93 | register_order(params[:customer], session[:cart][:items]) |
93 | 94 | begin |
94 | - ShoppingCartPlugin::Mailer.deliver_customer_notification(params[:customer], profile, session[:cart][:items]) | |
95 | - ShoppingCartPlugin::Mailer.deliver_supplier_notification(params[:customer], profile, session[:cart][:items]) | |
95 | + ShoppingCartPlugin::Mailer.deliver_customer_notification(params[:customer], profile, session[:cart][:items], params[:delivery_option]) | |
96 | + ShoppingCartPlugin::Mailer.deliver_supplier_notification(params[:customer], profile, session[:cart][:items], params[:delivery_option]) | |
96 | 97 | render :text => { |
97 | 98 | :ok => true, |
98 | 99 | :message => _('Request sent successfully. Check your email.'), |
... | ... | @@ -151,6 +152,24 @@ class ShoppingCartPluginProfileController < ProfileController |
151 | 152 | end |
152 | 153 | end |
153 | 154 | |
155 | + def update_delivery_option | |
156 | + settings = Noosfero::Plugin::Settings.new(profile, ShoppingCartPlugin) | |
157 | + delivery_price = settings.delivery_options[params[:delivery_option]] | |
158 | + delivery = Product.new(:name => params[:delivery_option], :price => delivery_price) | |
159 | + delivery.save(false) | |
160 | + items = session[:cart][:items].clone | |
161 | + items[delivery.id] = 1 | |
162 | + total_price = get_total_on_currency(items, environment) | |
163 | + delivery.destroy | |
164 | + render :text => { | |
165 | + :ok => true, | |
166 | + :delivery_price => float_to_currency_cart(delivery_price, environment), | |
167 | + :total_price => total_price, | |
168 | + :message => _('Delivery option updated.'), | |
169 | + :error => {:code => 0} | |
170 | + }.to_json | |
171 | + end | |
172 | + | |
154 | 173 | private |
155 | 174 | |
156 | 175 | def validate_same_enterprise | ... | ... |
plugins/shopping_cart/db/migrate/20121022190819_move_fields_included_on_profiles_table_to_settings.rb
0 → 100644
... | ... | @@ -0,0 +1,19 @@ |
1 | +class MoveFieldsIncludedOnProfilesTableToSettings < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + Profile.find_each do |profile| | |
4 | + settings = Noosfero::Plugin::Settings.new(profile, ShoppingCartPlugin) | |
5 | + settings.enabled = profile.shopping_cart | |
6 | + settings.delivery = profile.shopping_cart_delivery | |
7 | + settings.delivery_price = profile.shopping_cart_delivery_price | |
8 | + settings.save! | |
9 | + end | |
10 | + | |
11 | + remove_column :profiles, :shopping_cart | |
12 | + remove_column :profiles, :shopping_cart_delivery | |
13 | + remove_column :profiles, :shopping_cart_delivery_price | |
14 | + end | |
15 | + | |
16 | + def self.down | |
17 | + say "This migration can not be reverted!" | |
18 | + end | |
19 | +end | ... | ... |
plugins/shopping_cart/lib/shopping_cart_plugin.rb
... | ... | @@ -3,16 +3,35 @@ require_dependency 'shopping_cart_plugin/ext/person' |
3 | 3 | |
4 | 4 | class ShoppingCartPlugin < Noosfero::Plugin |
5 | 5 | |
6 | - def self.plugin_name | |
6 | + class << self | |
7 | + def plugin_name | |
7 | 8 | "Shopping Basket" |
8 | - end | |
9 | + end | |
10 | + | |
11 | + def plugin_description | |
12 | + _("A shopping basket feature for enterprises") | |
13 | + end | |
14 | + | |
15 | + def enabled_default_setting | |
16 | + true | |
17 | + end | |
9 | 18 | |
10 | - def self.plugin_description | |
11 | - _("A shopping basket feature for enterprises") | |
19 | + def delivery_default_setting | |
20 | + false | |
21 | + end | |
22 | + | |
23 | + def delivery_price_default_setting | |
24 | + 0 | |
25 | + end | |
26 | + | |
27 | + def delivery_options_default_setting | |
28 | + {} | |
29 | + end | |
12 | 30 | end |
13 | 31 | |
14 | 32 | def add_to_cart_button(item, enterprise = context.profile) |
15 | - if enterprise.shopping_cart && item.available | |
33 | + settings = Noosfero::Plugin::Settings.new(enterprise, ShoppingCartPlugin) | |
34 | + if settings.enabled && item.available | |
16 | 35 | lambda { |
17 | 36 | link_to(_('Add to basket'), "add:#{item.name}", |
18 | 37 | :class => 'cart-add-item', |
... | ... | @@ -39,11 +58,12 @@ class ShoppingCartPlugin < Noosfero::Plugin |
39 | 58 | end |
40 | 59 | |
41 | 60 | def control_panel_buttons |
61 | + settings = Noosfero::Plugin::Settings.new(context.profile, ShoppingCartPlugin) | |
42 | 62 | buttons = [] |
43 | 63 | if context.profile.enterprise? |
44 | 64 | buttons << { :title => _('Shopping basket'), :icon => 'shopping-cart-icon', :url => {:controller => 'shopping_cart_plugin_myprofile', :action => 'edit'} } |
45 | 65 | end |
46 | - if context.profile.enterprise? && context.profile.shopping_cart | |
66 | + if context.profile.enterprise? && settings.enabled | |
47 | 67 | buttons << { :title => _('Purchase reports'), :icon => 'shopping-cart-purchase-report', :url => {:controller => 'shopping_cart_plugin_myprofile', :action => 'reports'} } |
48 | 68 | end |
49 | 69 | ... | ... |
plugins/shopping_cart/lib/shopping_cart_plugin/cart_helper.rb
... | ... | @@ -7,46 +7,69 @@ module ShoppingCartPlugin::CartHelper |
7 | 7 | product.discount ? product.price_with_discount : product.price |
8 | 8 | end |
9 | 9 | |
10 | - def get_price(product, environment) | |
11 | - float_to_currency_cart(sell_price(product), environment) | |
10 | + def get_price(product, environment, quantity=1) | |
11 | + float_to_currency_cart(price_with_quantity(product,quantity), environment) | |
12 | 12 | end |
13 | 13 | |
14 | - def get_total(items, environment) | |
15 | - float_to_currency_cart(items.map { |id, quantity| sell_price(Product.find(id)) * quantity}.sum, environment) | |
14 | + def price_with_quantity(product, quantity=1) | |
15 | + quantity = 1 if !quantity.kind_of?(Numeric) | |
16 | + sell_price(product)*quantity | |
16 | 17 | end |
17 | 18 | |
18 | - def items_table(items, profile, by_mail = false) | |
19 | + def get_total(items) | |
20 | + items.map { |id, quantity| price_with_quantity(Product.find(id),quantity)}.sum | |
21 | + end | |
22 | + | |
23 | + def get_total_on_currency(items, environment) | |
24 | + float_to_currency_cart(get_total(items), environment) | |
25 | + end | |
26 | + | |
27 | + def items_table(items, profile, delivery_option = nil, by_mail = false) | |
19 | 28 | environment = profile.environment |
29 | + settings = Noosfero::Plugin::Settings.new(profile, ShoppingCartPlugin) | |
20 | 30 | items = items.to_a |
21 | - if profile.shopping_cart_delivery | |
22 | - delivery = Product.create!(:name => _('Delivery'), :price => profile.shopping_cart_delivery_price, :product_category => ProductCategory.last) | |
23 | - items << [delivery.id, 1] | |
24 | - end | |
25 | 31 | |
26 | 32 | quantity_opts = { :class => 'cart-table-quantity' } |
27 | 33 | quantity_opts.merge!({:align => 'center'}) if by_mail |
28 | 34 | price_opts = {:class => 'cart-table-price'} |
29 | 35 | price_opts.merge!({:align => 'right'}) if by_mail |
36 | + items.sort! {|a, b| Product.find(a.first).name <=> Product.find(b.first).name} | |
37 | + | |
38 | + if settings.delivery | |
39 | + if settings.free_delivery_price && get_total(items) >= settings.free_delivery_price | |
40 | + delivery = Product.new(:name => _('Free delivery'), :price => 0) | |
41 | + else | |
42 | + delivery = Product.new(:name => delivery_option || _('Delivery'), :price => settings.delivery_options[delivery_option]) | |
43 | + end | |
44 | + delivery.save(false) | |
45 | + items << [delivery.id, ''] | |
46 | + end | |
30 | 47 | |
31 | 48 | table = '<table id="cart-items-table" cellpadding="2" cellspacing="0" |
32 | 49 | border="'+(by_mail ? '1' : '0')+'" |
33 | 50 | style="'+(by_mail ? 'border-collapse:collapse' : '')+'">' + |
34 | 51 | content_tag('tr', |
35 | - content_tag('th', _('Item name')) + | |
36 | - content_tag('th', by_mail ? ' # ' : '#') + | |
37 | - content_tag('th', _('Price')) | |
52 | + content_tag('th', _('Item name')) + | |
53 | + content_tag('th', by_mail ? ' # ' : '#') + | |
54 | + content_tag('th', _('Price')) | |
38 | 55 | ) + |
39 | 56 | items.map do |id, quantity| |
40 | 57 | product = Product.find(id) |
58 | + name_opts = {} | |
59 | + is_delivery = quantity.kind_of?(String) | |
60 | + if is_delivery | |
61 | + price_opts.merge!({:id => 'delivery-price'}) | |
62 | + name_opts.merge!({:id => 'delivery-name'}) | |
63 | + end | |
41 | 64 | content_tag('tr', |
42 | - content_tag('td', product.name) + | |
43 | - content_tag('td', quantity, quantity_opts ) + | |
44 | - content_tag('td', get_price(product, environment), price_opts ) | |
45 | - ) | |
65 | + content_tag('td', product.name, name_opts) + | |
66 | + content_tag('td', quantity, quantity_opts ) + | |
67 | + content_tag('td', get_price(product, environment, quantity), price_opts) | |
68 | + ) | |
46 | 69 | end.join("\n") |
47 | 70 | |
48 | - total = get_total(items, environment) | |
49 | - delivery.destroy if profile.shopping_cart_delivery | |
71 | + total = get_total_on_currency(items, environment) | |
72 | + delivery.destroy if settings.delivery | |
50 | 73 | |
51 | 74 | table + |
52 | 75 | content_tag('th', _('Total:'), :colspan => 2, :class => 'cart-table-total-label') + |
... | ... | @@ -55,6 +78,14 @@ module ShoppingCartPlugin::CartHelper |
55 | 78 | end |
56 | 79 | |
57 | 80 | def float_to_currency_cart(value, environment) |
58 | - number_to_currency(value, :unit => environment.currency_unit, :separator => environment.currency_separator, :delimiter => environment.currency_delimiter, :precision => 2, :format => "%u %n") | |
81 | + number_to_currency(value, :unit => environment.currency_unit, :separator => environment.currency_separator, :delimiter => environment.currency_delimiter, :precision => 2, :format => "%u%n") | |
82 | + end | |
83 | + | |
84 | + def select_delivery_options(options, environment) | |
85 | + result = options.map do |option, price| | |
86 | + ["#{option} (#{float_to_currency_cart(price, environment)})", option] | |
87 | + end | |
88 | + result << ["#{_('Delivery')} (#{float_to_currency_cart(0, environment)})", 'delivery'] if result.empty? | |
89 | + result | |
59 | 90 | end |
60 | 91 | end | ... | ... |
plugins/shopping_cart/lib/shopping_cart_plugin/mailer.rb
1 | 1 | class ShoppingCartPlugin::Mailer < Noosfero::Plugin::MailerBase |
2 | 2 | |
3 | - def customer_notification(customer, supplier, items) | |
3 | + def customer_notification(customer, supplier, items, delivery_option) | |
4 | 4 | domain = supplier.hostname || supplier.environment.default_hostname |
5 | 5 | recipients customer[:email] |
6 | 6 | from 'no-reply@' + domain |
... | ... | @@ -10,10 +10,11 @@ class ShoppingCartPlugin::Mailer < Noosfero::Plugin::MailerBase |
10 | 10 | body :customer => customer, |
11 | 11 | :supplier => supplier, |
12 | 12 | :items => items, |
13 | - :environment => supplier.environment | |
13 | + :environment => supplier.environment, | |
14 | + :delivery_option => delivery_option | |
14 | 15 | end |
15 | 16 | |
16 | - def supplier_notification(customer, supplier, items) | |
17 | + def supplier_notification(customer, supplier, items, delivery_option) | |
17 | 18 | domain = supplier.environment.default_hostname |
18 | 19 | recipients supplier.contact_email |
19 | 20 | from 'no-reply@' + domain |
... | ... | @@ -23,6 +24,7 @@ class ShoppingCartPlugin::Mailer < Noosfero::Plugin::MailerBase |
23 | 24 | body :customer => customer, |
24 | 25 | :supplier => supplier, |
25 | 26 | :items => items, |
26 | - :environment => supplier.environment | |
27 | + :environment => supplier.environment, | |
28 | + :delivery_option => delivery_option | |
27 | 29 | end |
28 | 30 | end | ... | ... |
... | ... | @@ -0,0 +1,34 @@ |
1 | +jQuery(document).ready(function(){ | |
2 | + jQuery("#cart-request-form").validate({ | |
3 | + submitHandler: function(form) { | |
4 | + jQuery(form).find('input.submit').attr('disabled', true); | |
5 | + jQuery('#cboxLoadingOverlay').show().addClass('loading'); | |
6 | + jQuery('#cboxLoadingGraphic').show().addClass('loading'); | |
7 | + } | |
8 | + }); | |
9 | +}); | |
10 | + | |
11 | +jQuery('#delivery_option').change(function(){ | |
12 | + jQuery('#cboxLoadingGraphic').show(); | |
13 | + me = this; | |
14 | + enterprise = jQuery(me).attr('data-profile-identifier'); | |
15 | + option = jQuery(me).val(); | |
16 | + jQuery.ajax({ | |
17 | + url: '/profile/'+ enterprise +'/plugin/shopping_cart/update_delivery_option', | |
18 | + dataType: "json", | |
19 | + data: 'delivery_option='+option, | |
20 | + success: function(data, st, ajax) { | |
21 | + jQuery('#delivery-price').text(data.delivery_price); | |
22 | + jQuery('.cart-table-total-value').text(data.total_price); | |
23 | + jQuery('#delivery-name').text(option); | |
24 | + jQuery('#cboxLoadingGraphic').hide(); | |
25 | + }, | |
26 | + error: function(ajax, st, errorThrown) { | |
27 | + alert('Update delivery option - HTTP '+st+': '+errorThrown); | |
28 | + }, | |
29 | + }); | |
30 | +}); | |
31 | + | |
32 | +jQuery('#customer_payment').change(function(){ | |
33 | + jQuery(this).closest('.formfieldline').next().slideToggle('fast'); | |
34 | +}); | ... | ... |
plugins/shopping_cart/public/cart.js
... | ... | @@ -14,7 +14,7 @@ function Cart(config) { |
14 | 14 | this.enterprise = config.enterprise; |
15 | 15 | me = this; |
16 | 16 | $.ajax({ |
17 | - url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/visibility', | |
17 | + url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/visibility', | |
18 | 18 | dataType: 'json', |
19 | 19 | success: function(data, status, ajax){ |
20 | 20 | me.visible = /^true$/i.test(data); |
... | ... | @@ -25,7 +25,7 @@ function Cart(config) { |
25 | 25 | alert('Visibility - HTTP '+status+': '+errorThrown); |
26 | 26 | } |
27 | 27 | }); |
28 | - $(".cart-buy", this.cartElem).colorbox({href: '/profile/' + this.enterprise + '/plugins/shopping_cart/buy'}); | |
28 | + $(".cart-buy", this.cartElem).colorbox({href: '/profile/' + this.enterprise + '/plugin/shopping_cart/buy'}); | |
29 | 29 | } |
30 | 30 | } |
31 | 31 | |
... | ... | @@ -34,7 +34,7 @@ function Cart(config) { |
34 | 34 | Cart.prototype.listProducts = function() { |
35 | 35 | var me = this; |
36 | 36 | $.ajax({ |
37 | - url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/list', | |
37 | + url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/list', | |
38 | 38 | dataType: 'json', |
39 | 39 | success: function(data, ststus, ajax){ |
40 | 40 | if ( !data.ok ) alert(data.error.message); |
... | ... | @@ -100,7 +100,7 @@ function Cart(config) { |
100 | 100 | var me = this; |
101 | 101 | if( quantity == NaN ) return input.value = input.lastValue; |
102 | 102 | $.ajax({ |
103 | - url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/update_quantity/'+ itemId +'?quantity='+ quantity, | |
103 | + url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/update_quantity/'+ itemId +'?quantity='+ quantity, | |
104 | 104 | dataType: 'json', |
105 | 105 | success: function(data, status, ajax){ |
106 | 106 | if ( !data.ok ) { |
... | ... | @@ -150,12 +150,12 @@ function Cart(config) { |
150 | 150 | Cart.prototype.addItem = function(enterprise, itemId, callback) { |
151 | 151 | if(!this.enterprise) { |
152 | 152 | this.enterprise = enterprise; |
153 | - $(".cart-buy", this.cartElem).colorbox({href: '/profile/' + this.enterprise + '/plugins/shopping_cart/buy'}); | |
153 | + $(".cart-buy", this.cartElem).colorbox({href: '/profile/' + this.enterprise + '/plugin/shopping_cart/buy'}); | |
154 | 154 | // $(this.cartElem).show(); |
155 | 155 | } |
156 | 156 | var me = this; |
157 | 157 | $.ajax({ |
158 | - url: '/profile/'+ enterprise +'/plugins/shopping_cart/add/'+ itemId, | |
158 | + url: '/profile/'+ enterprise +'/plugin/shopping_cart/add/'+ itemId, | |
159 | 159 | dataType: 'json', |
160 | 160 | success: function(data, status, ajax){ |
161 | 161 | if ( !data.ok ) alert(data.error.message); |
... | ... | @@ -178,7 +178,7 @@ function Cart(config) { |
178 | 178 | if ($("li", this.itemsBox).size() < 2) return this.clean(); |
179 | 179 | var me = this; |
180 | 180 | $.ajax({ |
181 | - url: '/profile/'+ enterprise +'/plugins/shopping_cart/remove/'+ itemId, | |
181 | + url: '/profile/'+ enterprise +'/plugin/shopping_cart/remove/'+ itemId, | |
182 | 182 | dataType: 'json', |
183 | 183 | success: function(data, status, ajax){ |
184 | 184 | if ( !data.ok ) alert(data.error.message); |
... | ... | @@ -200,7 +200,7 @@ function Cart(config) { |
200 | 200 | |
201 | 201 | Cart.prototype.show = function() { |
202 | 202 | $.ajax({ |
203 | - url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/show', | |
203 | + url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/show', | |
204 | 204 | dataType: 'json', |
205 | 205 | cache: false, |
206 | 206 | error: function(ajax, status, errorThrown) { |
... | ... | @@ -215,7 +215,7 @@ function Cart(config) { |
215 | 215 | } |
216 | 216 | Cart.prototype.hide = function() { |
217 | 217 | $.ajax({ |
218 | - url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/hide', | |
218 | + url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/hide', | |
219 | 219 | dataType: 'json', |
220 | 220 | cache: false, |
221 | 221 | error: function(ajax, status, errorThrown) { |
... | ... | @@ -252,7 +252,7 @@ function Cart(config) { |
252 | 252 | Cart.prototype.clean = function() { |
253 | 253 | var me = this; |
254 | 254 | $.ajax({ |
255 | - url: '/profile/'+ me.enterprise +'/plugins/shopping_cart/clean', | |
255 | + url: '/profile/'+ me.enterprise +'/plugin/shopping_cart/clean', | |
256 | 256 | dataType: 'json', |
257 | 257 | success: function(data, status, ajax){ |
258 | 258 | if ( !data.ok ) alert(data.error.message); |
... | ... | @@ -284,7 +284,7 @@ function Cart(config) { |
284 | 284 | var me = this; |
285 | 285 | $.ajax({ |
286 | 286 | type: 'POST', |
287 | - url: '/profile/'+ me.enterprise +'/plugins/shopping_cart/send_request', | |
287 | + url: '/profile/'+ me.enterprise +'/plugin/shopping_cart/send_request', | |
288 | 288 | data: params, |
289 | 289 | dataType: 'json', |
290 | 290 | success: function(data, status, ajax){ | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +jQuery('#settings_delivery').click(function(){ | |
2 | + jQuery('#delivery_settings').toggle('fast'); | |
3 | +}); | |
4 | + | |
5 | +jQuery('#add-new-option').click(function(){ | |
6 | + new_option = jQuery('#empty-option').clone(); | |
7 | + new_option.removeAttr('id'); | |
8 | + jQuery('#add-new-option-row').before(new_option); | |
9 | + new_option.show(); | |
10 | + return false; | |
11 | +}); | |
12 | + | |
13 | +jQuery('.remove-option').live('click', function(){ | |
14 | + jQuery(this).closest('tr').remove(); | |
15 | + return false; | |
16 | +}); | ... | ... |
plugins/shopping_cart/test/functional/shopping_cart_plugin_myprofile_controller_test.rb
... | ... | @@ -13,46 +13,42 @@ class ShoppingCartPluginMyprofileControllerTest < ActionController::TestCase |
13 | 13 | attr_reader :enterprise |
14 | 14 | |
15 | 15 | should 'be able to enable shopping cart' do |
16 | - enterprise.shopping_cart = false | |
17 | - enterprise.save | |
18 | - post :edit, :profile => enterprise.identifier, :profile_attr => {:shopping_cart => '1'} | |
19 | - enterprise.reload | |
16 | + settings.enabled = false | |
17 | + settings.save! | |
18 | + post :edit, :profile => enterprise.identifier, :settings => {:enabled => '1'} | |
20 | 19 | |
21 | - assert enterprise.shopping_cart | |
20 | + assert settings.enabled | |
22 | 21 | end |
23 | 22 | |
24 | 23 | should 'be able to disable shopping cart' do |
25 | - enterprise.shopping_cart = true | |
26 | - enterprise.save | |
27 | - post :edit, :profile => enterprise.identifier, :profile_attr => {:shopping_cart => '0'} | |
28 | - enterprise.reload | |
24 | + settings.enabled = true | |
25 | + settings.save! | |
26 | + post :edit, :profile => enterprise.identifier, :settings => {:enabled => '0'} | |
29 | 27 | |
30 | - assert !enterprise.shopping_cart | |
28 | + assert !settings.enabled | |
31 | 29 | end |
32 | 30 | |
33 | 31 | should 'be able to enable shopping cart delivery' do |
34 | - enterprise.shopping_cart_delivery = false | |
35 | - enterprise.save | |
36 | - post :edit, :profile => enterprise.identifier, :profile_attr => {:shopping_cart_delivery => '1'} | |
37 | - enterprise.reload | |
32 | + settings.delivery = false | |
33 | + settings.save! | |
34 | + post :edit, :profile => enterprise.identifier, :settings => {:delivery => '1'} | |
38 | 35 | |
39 | - assert enterprise.shopping_cart_delivery | |
36 | + assert settings.delivery | |
40 | 37 | end |
41 | 38 | |
42 | 39 | should 'be able to disable shopping cart delivery' do |
43 | - enterprise.shopping_cart_delivery = true | |
44 | - enterprise.save | |
45 | - post :edit, :profile => enterprise.identifier, :profile_attr => {:shopping_cart_delivery => '0'} | |
46 | - enterprise.reload | |
40 | + settings.delivery = true | |
41 | + settings.save! | |
42 | + post :edit, :profile => enterprise.identifier, :settings => {:delivery => '0'} | |
47 | 43 | |
48 | - assert !enterprise.shopping_cart_delivery | |
44 | + assert !settings.delivery | |
49 | 45 | end |
50 | 46 | |
51 | 47 | should 'be able to choose the delivery price' do |
52 | 48 | price = 4.35 |
53 | - post :edit, :profile => enterprise.identifier, :profile_attr => {:shopping_cart_delivery_price => price} | |
54 | - enterprise.reload | |
55 | - assert enterprise.shopping_cart_delivery_price == price | |
49 | + post :edit, :profile => enterprise.identifier, :settings => {:delivery_price => price} | |
50 | + | |
51 | + assert settings.delivery_price == price | |
56 | 52 | end |
57 | 53 | |
58 | 54 | should 'filter the reports correctly' do |
... | ... | @@ -112,4 +108,11 @@ class ShoppingCartPluginMyprofileControllerTest < ActionController::TestCase |
112 | 108 | po.reload |
113 | 109 | assert_equal ShoppingCartPlugin::PurchaseOrder::Status::CONFIRMED, po.status |
114 | 110 | end |
111 | + | |
112 | + private | |
113 | + | |
114 | + def settings | |
115 | + @enterprise.reload | |
116 | + Noosfero::Plugin::Settings.new(@enterprise, ShoppingCartPlugin) | |
117 | + end | |
115 | 118 | end | ... | ... |
plugins/shopping_cart/views/shopping_cart_plugin/mailer/customer_notification.html.erb
... | ... | @@ -17,25 +17,35 @@ |
17 | 17 | <li><b><%= _('Full name') %>: </b><%= @customer[:name] %></li> |
18 | 18 | <li><b><%= _('Email') %>: </b><%= @customer[:email] %></li> |
19 | 19 | <li><b><%= _('Phone number') %>: </b><%= @customer[:contact_phone] %></li> |
20 | - <% if !@customer[:address].blank? || !@customer[:city].blank? || !@customer[:zip_code].blank? %> | |
20 | + <li><b><%= _('Payment') %>: </b><%= @customer[:payment] == 'money' ? _('Money') : _('Check') %></li> | |
21 | + <% if @customer[:payment] == 'money' %> | |
22 | + <li><b><%= _('Change') %>: </b><%= @customer[:change] %></li> | |
23 | + <% end %> | |
24 | + <% if !@customer[:address].blank? || !@customer[:city].blank? || !@customer[:zip_code].blank? || !@customer[:district].blank? || !@customer[:address_reference].blank? %> | |
21 | 25 | <li><b><%= _('Address') %>:</b> |
22 | 26 | <% end %> |
23 | 27 | <% if !@customer[:address].blank? %> |
24 | 28 | <%= @customer[:address] %><br \> |
25 | 29 | <% end %> |
30 | + <% if !@customer[:district].blank? %> | |
31 | + <%= @customer[:district] %><br \> | |
32 | + <% end %> | |
26 | 33 | <% if !@customer[:city].blank? %> |
27 | 34 | <%= @customer[:city] %><br \> |
28 | 35 | <% end %> |
29 | 36 | <% if !@customer[:zip_code].blank? %> |
30 | 37 | <%= @customer[:zip_code] %> |
31 | 38 | <% end %> |
32 | - <% if !@customer[:address].blank? || !@customer[:city].blank? || !@customer[:zip_code].blank? %> | |
39 | + <% if !@customer[:address_reference].blank? %> | |
40 | + <%= @customer[:address_reference] %><br \> | |
41 | + <% end %> | |
42 | + <% if !@customer[:address].blank? || !@customer[:city].blank? || !@customer[:zip_code].blank? || !@customer[:district].blank? || !@customer[:address_reference].blank? %> | |
33 | 43 | </li> |
34 | 44 | <% end %> |
35 | 45 | </ul> |
36 | 46 | |
37 | 47 | <p><%=_('Here are the products you bought:')%></p> |
38 | - <%= items_table(@items, @supplier, true) %> | |
48 | + <%= items_table(@items, @supplier, @delivery_option, true) %> | |
39 | 49 | |
40 | 50 | <p> |
41 | 51 | --<br/> | ... | ... |
plugins/shopping_cart/views/shopping_cart_plugin/mailer/supplier_notification.html.erb
... | ... | @@ -15,25 +15,35 @@ |
15 | 15 | <li><b><%= _('Full name') %>: </b><%= @customer[:name] %></li> |
16 | 16 | <li><b><%= _('Email') %>: </b><%= @customer[:email] %></li> |
17 | 17 | <li><b><%= _('Phone number') %>: </b><%= @customer[:contact_phone] %></li> |
18 | - <% if !@customer[:address].blank? || !@customer[:city].blank? || !@customer[:zip_code].blank? %> | |
18 | + <li><b><%= _('Payment') %>: </b><%= @customer[:payment] == 'money' ? _('Money') : _('Check') %></li> | |
19 | + <% if @customer[:payment] == 'money' %> | |
20 | + <li><b><%= _('Change') %>: </b><%= @customer[:change] %></li> | |
21 | + <% end %> | |
22 | + <% if !@customer[:address].blank? || !@customer[:city].blank? || !@customer[:zip_code].blank? || !@customer[:district].blank? || !@customer[:address_reference].blank? %> | |
19 | 23 | <li><b><%= _('Address') %>:</b> |
20 | 24 | <% end %> |
21 | 25 | <% if !@customer[:address].blank? %> |
22 | 26 | <%= @customer[:address] %><br \> |
23 | 27 | <% end %> |
28 | + <% if !@customer[:district].blank? %> | |
29 | + <%= @customer[:district] %><br \> | |
30 | + <% end %> | |
24 | 31 | <% if !@customer[:city].blank? %> |
25 | 32 | <%= @customer[:city] %><br \> |
26 | 33 | <% end %> |
27 | 34 | <% if !@customer[:zip_code].blank? %> |
28 | 35 | <%= @customer[:zip_code] %> |
29 | 36 | <% end %> |
30 | - <% if !@customer[:address].blank? || !@customer[:city].blank? || !@customer[:zip_code].blank? %> | |
37 | + <% if !@customer[:address_reference].blank? %> | |
38 | + <%= @customer[:address_reference] %><br \> | |
39 | + <% end %> | |
40 | + <% if !@customer[:address].blank? || !@customer[:city].blank? || !@customer[:zip_code].blank? || !@customer[:district].blank? || !@customer[:address_reference].blank? %> | |
31 | 41 | </li> |
32 | 42 | <% end %> |
33 | 43 | </ul> |
34 | 44 | |
35 | 45 | <p><%=_('And here are the items bought by this customer:')%></p> |
36 | - <%= items_table(@items, @supplier, true) %> | |
46 | + <%= items_table(@items, @supplier, @delivery_option, true) %> | |
37 | 47 | |
38 | 48 | <p> |
39 | 49 | --<br/> | ... | ... |
plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb
1 | 1 | <h1> <%= _('Basket options') %> </h1> |
2 | 2 | |
3 | -<% form_for(:profile_attr, profile, :url => {:action => 'edit'}, :html => {:method => 'post'}) do |f| %> | |
4 | - <%= labelled_form_field(_('Enabled?'), f.check_box(:shopping_cart)) %> | |
5 | - <%= labelled_form_field(_('Delivery?'), f.check_box(:shopping_cart_delivery)) %> | |
6 | - <%= labelled_form_field(_('Delivery price:'), f.text_field(:shopping_cart_delivery_price)) %> | |
3 | +<% form_for(:settings, @settings, :url => {:action => 'edit'}, :html => {:method => 'post'}) do |f| %> | |
4 | + <%= labelled_form_field(_('Enabled?'), f.check_box(:enabled)) %> | |
5 | + <%= labelled_form_field(_('Delivery?'), f.check_box(:delivery)) %> | |
6 | + <% display_delivery_settings = @settings.delivery ? 'auto' : 'none' %> | |
7 | + <fieldset id='delivery_settings' style="display: <%= display_delivery_settings %>"><legend><%=_('Delivery')%></legend> | |
8 | + <table> | |
9 | + <tr> | |
10 | + <th><%= _('Option') %></th> | |
11 | + <th><%= _('Price') %></th> | |
12 | + <th> </th> | |
13 | + </tr> | |
14 | + <% @settings.delivery_options.each do |option, price| %> | |
15 | + <tr> | |
16 | + <td><%= text_field_tag('settings[delivery_options][options][]', option, :style => 'width: 100%') %></td> | |
17 | + <td><%= text_field_tag('settings[delivery_options][prices][]', price, :style => 'width: 100%') %></td> | |
18 | + <td><%= button_without_text(:close, _('Remove option'), '', :class => 'remove-option') %></td> | |
19 | + </tr> | |
20 | + <% end %> | |
21 | + <tr> | |
22 | + <td><%= text_field_tag('settings[delivery_options][options][]', nil, :style => 'width: 100%') %></td> | |
23 | + <td><%= text_field_tag('settings[delivery_options][prices][]', nil, :style => 'width: 100%') %></td> | |
24 | + <td><%= button_without_text(:close, _('Remove option'), '', :class => 'remove-option') %></td> | |
25 | + </tr> | |
26 | + <tr id='add-new-option-row'> | |
27 | + <td colspan='3' style='background-color: #EEE; text-align: center'><%= link_to(_('ADD NEW OPTION'), '', :id => 'add-new-option') %></td> | |
28 | + </tr> | |
29 | + <tr id="empty-option" style='display: none'> | |
30 | + <td><%= text_field_tag('settings[delivery_options][options][]', nil, :style => 'width: 100%') %></td> | |
31 | + <td><%= text_field_tag('settings[delivery_options][prices][]', nil, :style => 'width: 100%') %></td> | |
32 | + <td><%= button_without_text(:close, _('Remove option'), '', :class => 'remove-option') %></td> | |
33 | + </tr> | |
34 | + </table> | |
35 | + | |
36 | + <%= labelled_form_field(_('Free delivery price:'), f.text_field(:free_delivery_price)) %> | |
37 | + <%= content_tag('small', _('Empty stands for no free delivery price.')) %> | |
38 | + </fieldset> | |
7 | 39 | <br style='clear: both'/> |
8 | 40 | <br style='clear: both'/> |
9 | 41 | <div> |
... | ... | @@ -11,3 +43,5 @@ |
11 | 43 | <%= button :back, _('Back to control panel'), :controller => 'profile_editor' %> |
12 | 44 | </div> |
13 | 45 | <% end%> |
46 | + | |
47 | +<%= javascript_include_tag '../plugins/shopping_cart/edit' %> | ... | ... |
plugins/shopping_cart/views/shopping_cart_plugin_profile/buy.html.erb
... | ... | @@ -6,30 +6,26 @@ |
6 | 6 | <%= labelled_form_field('* ' + _("Name"), f.text_field(:name, :class => 'required') ) %> |
7 | 7 | <%= labelled_form_field('* ' + _("Email"), f.text_field(:email, :class => 'required email') ) %> |
8 | 8 | <%= labelled_form_field('* ' + _("Contact phone"), f.text_field(:contact_phone, :class => 'required') ) %> |
9 | + <%= labelled_form_field(_('Delivery option'), select_tag(:delivery_option, options_for_select(select_delivery_options(@settings.delivery_options, environment)), 'data-profile-identifier' => profile.identifier)) unless !@settings.delivery || (@settings.free_delivery_price && get_total(session[:cart][:items]) >= @settings.free_delivery_price) %> | |
10 | + <%= labelled_form_field(_('Payment'), select_tag('customer[payment]', options_for_select([[_("Money"), :money],[_('Check'), :check]]))) %> | |
11 | + <%= labelled_form_field(_('Change'), text_field_tag('customer[change]')) %> | |
9 | 12 | </div> |
10 | - <fieldset><legend><%=_('Delivery Address')%></legend> | |
11 | - <%= labelled_form_field(_('Address (street and number)'), f.text_field(:address)) %> | |
12 | - <%= labelled_form_field( _("City"), f.text_field(:city)) %> | |
13 | - <%= labelled_form_field(_('ZIP code'), f.text_field(:zip_code)) %> | |
14 | - </fieldset> | |
13 | + <% if @settings.delivery %> | |
14 | + <fieldset><legend><%=_('Delivery Address')%></legend> | |
15 | + <%= labelled_form_field(_('Address (street and number)'), f.text_field(:address)) %> | |
16 | + <%= labelled_form_field(_('Address reference'), f.text_field(:address_reference)) %> | |
17 | + <%= labelled_form_field(_('District'), f.text_field(:district)) %> | |
18 | + <%= labelled_form_field( _("City"), f.text_field(:city)) %> | |
19 | + <%= labelled_form_field(_('ZIP code'), f.text_field(:zip_code)) %> | |
20 | + </fieldset> | |
21 | + <% end %> | |
15 | 22 | <div id="cart-form-actions"> |
16 | 23 | <%= submit_button(:send, _('Send buy request')) %> |
17 | 24 | </div> |
18 | 25 | <% end %> |
19 | - <%= items_table(session[:cart][:items], profile) %> | |
26 | + <% delivery_option = @settings.delivery_options.first && @settings.delivery_options.first.first %> | |
27 | + <%= items_table(session[:cart][:items], profile, delivery_option) %> | |
20 | 28 | <%= link_to '', '#', :onclick => "Cart.colorbox_close(this);", :class => 'cart-box-close icon-cancel' %> |
21 | 29 | </div> |
22 | 30 | |
23 | -<script type="text/javascript"> | |
24 | -//<![CDATA[ | |
25 | - jQuery(document).ready(function(){ | |
26 | - jQuery("#cart-request-form").validate({ | |
27 | - submitHandler: function(form) { | |
28 | - jQuery(form).find('input.submit').attr('disabled', true); | |
29 | - jQuery('#cboxLoadingOverlay').show().addClass('loading'); | |
30 | - jQuery('#cboxLoadingGraphic').show().addClass('loading'); | |
31 | - } | |
32 | - }); | |
33 | - }); | |
34 | -//]]> | |
35 | -</script> | |
31 | +<%= javascript_include_tag '../plugins/shopping_cart/buy' %> | ... | ... |
1.75 KB
3.58 KB
public/stylesheets/application.css
... | ... | @@ -2677,6 +2677,40 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation |
2677 | 2677 | .msie #product-list h3 { |
2678 | 2678 | margin-top: -15px; |
2679 | 2679 | } |
2680 | + | |
2681 | +.l-sidebar-left-bar ul, | |
2682 | +.l-sidebar-right-bar ul { | |
2683 | + list-style-type: none; | |
2684 | + margin-left: 0; | |
2685 | + padding: 1em 1em 0.5em 1em; | |
2686 | +} | |
2687 | + | |
2688 | +.l-sidebar-left-bar ul ul, | |
2689 | +.l-sidebar-right-bar ul ul { | |
2690 | + padding-top: 0; | |
2691 | +} | |
2692 | + | |
2693 | +.l-sidebar-left-bar ul{ | |
2694 | + background-color: #eeeeec; | |
2695 | + border-radius: 5px; | |
2696 | +} | |
2697 | + | |
2698 | +.l-sidebar-left-bar a, | |
2699 | +.l-sidebar-right-bar a { | |
2700 | + text-decoration: none; | |
2701 | +} | |
2702 | + | |
2703 | +.l-sidebar-left-bar a:hover, | |
2704 | +.l-sidebar-right-bar a:hover { | |
2705 | + text-decoration: underline; | |
2706 | +} | |
2707 | + | |
2708 | +.l-sidebar-left-bar li, | |
2709 | +.l-sidebar-right-bar li { | |
2710 | + margin: 0; | |
2711 | + padding: 0; | |
2712 | +} | |
2713 | + | |
2680 | 2714 | /* * * Show Product * * * * * * * * * * * * */ |
2681 | 2715 | |
2682 | 2716 | .controller-catalog #show_product .product-pic { |
... | ... | @@ -6066,6 +6100,35 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { |
6066 | 6100 | line-height: 1.5; |
6067 | 6101 | } |
6068 | 6102 | |
6103 | +/* Sidebar Layout */ | |
6104 | + | |
6105 | +.l-sidebar-left-bar { | |
6106 | + float: left; | |
6107 | + width: 20%; | |
6108 | +} | |
6109 | + | |
6110 | +.l-sidebar-left-content { | |
6111 | + float: right; | |
6112 | + width: 78%; | |
6113 | +} | |
6114 | + | |
6115 | +.l-sidebar-right-bar { | |
6116 | + float: right; | |
6117 | + width: 20%; | |
6118 | +} | |
6119 | + | |
6120 | +.l-sidebar-right-content { | |
6121 | + float: left; | |
6122 | + width: 78%; | |
6123 | +} | |
6124 | + | |
6125 | +/* Breadcrumb */ | |
6126 | + | |
6127 | +#breadcrumb { | |
6128 | + font-size: 16px; | |
6129 | + margin: 15px 0; | |
6130 | +} | |
6131 | + | |
6069 | 6132 | .controller-profile_editor #profile-data { |
6070 | 6133 | display: table; |
6071 | 6134 | width: auto; |
... | ... | @@ -6114,3 +6177,10 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { |
6114 | 6177 | width: 100px; |
6115 | 6178 | text-align: center; |
6116 | 6179 | } |
6180 | + | |
6181 | +#product-list .highlighted img.star { | |
6182 | + position: absolute; | |
6183 | + top: 2px; | |
6184 | + right: 2px; | |
6185 | + z-index: 10; | |
6186 | +} | ... | ... |
test/functional/catalog_controller_test.rb
... | ... | @@ -109,4 +109,71 @@ class CatalogControllerTest < ActionController::TestCase |
109 | 109 | assert_tag :tag => 'span', :content => 'This is Plugin2 speaking!', :attributes => {:id => 'plugin2'} |
110 | 110 | end |
111 | 111 | |
112 | + should 'get categories of the right level' do | |
113 | + pc1 = ProductCategory.create!(:name => "PC1", :environment => @enterprise.environment) | |
114 | + pc2 = ProductCategory.create!(:name => "PC2", :environment => @enterprise.environment, :parent_id => pc1.id) | |
115 | + pc3 = ProductCategory.create!(:name => "PC3", :environment => @enterprise.environment, :parent_id => pc1.id) | |
116 | + pc4 = ProductCategory.create!(:name => "PC4", :environment => @enterprise.environment, :parent_id => pc2.id) | |
117 | + p1 = fast_create(Product, :product_category_id => pc1.id, :enterprise_id => @enterprise.id) | |
118 | + p2 = fast_create(Product, :product_category_id => pc2.id, :enterprise_id => @enterprise.id) | |
119 | + p3 = fast_create(Product, :product_category_id => pc3.id, :enterprise_id => @enterprise.id) | |
120 | + p4 = fast_create(Product, :product_category_id => pc4.id, :enterprise_id => @enterprise.id) | |
121 | + | |
122 | + get :index, :profile => @enterprise.identifier, :level => pc1.id | |
123 | + | |
124 | + assert_not_includes assigns(:categories), pc1 | |
125 | + assert_includes assigns(:categories), pc2 | |
126 | + assert_includes assigns(:categories), pc3 | |
127 | + assert_not_includes assigns(:categories), pc4 | |
128 | + end | |
129 | + | |
130 | + should 'filter products based on level selected' do | |
131 | + pc1 = ProductCategory.create!(:name => "PC1", :environment => @enterprise.environment) | |
132 | + pc2 = ProductCategory.create!(:name => "PC2", :environment => @enterprise.environment, :parent_id => pc1.id) | |
133 | + pc3 = ProductCategory.create!(:name => "PC3", :environment => @enterprise.environment, :parent_id => pc1.id) | |
134 | + pc4 = ProductCategory.create!(:name => "PC4", :environment => @enterprise.environment, :parent_id => pc2.id) | |
135 | + p1 = fast_create(Product, :product_category_id => pc1.id, :enterprise_id => @enterprise.id) | |
136 | + p2 = fast_create(Product, :product_category_id => pc2.id, :enterprise_id => @enterprise.id) | |
137 | + p3 = fast_create(Product, :product_category_id => pc3.id, :enterprise_id => @enterprise.id) | |
138 | + p4 = fast_create(Product, :product_category_id => pc4.id, :enterprise_id => @enterprise.id) | |
139 | + | |
140 | + get :index, :profile => @enterprise.identifier, :level => pc2.id | |
141 | + | |
142 | + assert_not_includes assigns(:products), p1 | |
143 | + assert_includes assigns(:products), p2 | |
144 | + assert_not_includes assigns(:products), p3 | |
145 | + assert_includes assigns(:products), p4 | |
146 | + end | |
147 | + | |
148 | + should 'get products ordered by availability, highlighted and then name' do | |
149 | + p1 = fast_create(Product, :enterprise_id => @enterprise.id, :name => 'Zebra', :available => true, :highlighted => true) | |
150 | + p2 = fast_create(Product, :enterprise_id => @enterprise.id, :name => 'Car', :available => true) | |
151 | + p3 = fast_create(Product, :enterprise_id => @enterprise.id, :name => 'Panda', :available => true) | |
152 | + p4 = fast_create(Product, :enterprise_id => @enterprise.id, :name => 'Pen', :available => false, :highlighted => true) | |
153 | + p5 = fast_create(Product, :enterprise_id => @enterprise.id, :name => 'Ball', :available => false) | |
154 | + p6 = fast_create(Product, :enterprise_id => @enterprise.id, :name => 'Medal', :available => false) | |
155 | + | |
156 | + get :index, :profile => @enterprise.identifier | |
157 | + | |
158 | + assert_equal [p1,p2,p3,p4,p5,p6], assigns(:products) | |
159 | + end | |
160 | + | |
161 | + should 'add highlighted CSS class around a highlighted product' do | |
162 | + prod = @enterprise.products.create!(:name => 'Highlighted Product', :product_category => @product_category, :highlighted => true) | |
163 | + get :index, :profile => @enterprise.identifier | |
164 | + assert_tag :tag => 'li', :attributes => { :class => 'product highlighted' }, :content => /Highlighted Product/ | |
165 | + end | |
166 | + | |
167 | + should 'do not add highlighted CSS class around an ordinary product' do | |
168 | + prod = @enterprise.products.create!(:name => 'Ordinary Product', :product_category => @product_category, :highlighted => false) | |
169 | + get :index, :profile => @enterprise.identifier | |
170 | + assert_no_tag :tag => 'li', :attributes => { :class => 'product highlighted' }, :content => /Ordinary Product/ | |
171 | + end | |
172 | + | |
173 | + should 'display star image in highlighted product' do | |
174 | + prod = @enterprise.products.create!(:name => 'The Eyes Are The Light', :product_category => @product_category, :highlighted => true) | |
175 | + get :index, :profile => @enterprise.identifier | |
176 | + assert_tag :tag => 'img', :attributes => { :class => 'star', :src => /star.png/ } | |
177 | + end | |
178 | + | |
112 | 179 | end | ... | ... |
test/functional/search_controller_test.rb
... | ... | @@ -926,6 +926,20 @@ class SearchControllerTest < ActionController::TestCase |
926 | 926 | end |
927 | 927 | end |
928 | 928 | |
929 | + should 'add highlighted CSS class around a highlighted product' do | |
930 | + enterprise = fast_create(Enterprise) | |
931 | + product = Product.create!(:name => 'Enter Sandman', :enterprise_id => enterprise.id, :product_category_id => @product_category.id, :highlighted => true) | |
932 | + get :products | |
933 | + assert_tag :tag => 'li', :attributes => { :class => 'search-product-item highlighted' }, :content => /Enter Sandman/ | |
934 | + end | |
935 | + | |
936 | + should 'do not add highlighted CSS class around an ordinary product' do | |
937 | + enterprise = fast_create(Enterprise) | |
938 | + product = Product.create!(:name => 'Holier Than Thou', :enterprise_id => enterprise.id, :product_category_id => @product_category.id, :highlighted => false) | |
939 | + get :products | |
940 | + assert_no_tag :tag => 'li', :attributes => { :class => 'search-product-item highlighted' }, :content => /Holier Than Thou/ | |
941 | + end | |
942 | + | |
929 | 943 | ################################################################## |
930 | 944 | ################################################################## |
931 | 945 | ... | ... |
test/unit/category_test.rb
... | ... | @@ -552,4 +552,62 @@ class CategoryTest < ActiveSupport::TestCase |
552 | 552 | cat.save! |
553 | 553 | end |
554 | 554 | |
555 | + should 'return categories of a level' do | |
556 | + c1 = fast_create(Category) | |
557 | + c2 = fast_create(Category) | |
558 | + c3 = fast_create(Category, :parent_id => c1) | |
559 | + c4 = fast_create(Category, :parent_id => c1) | |
560 | + c5 = fast_create(Category, :parent_id => c2) | |
561 | + c6 = fast_create(Category, :parent_id => c3) | |
562 | + | |
563 | + assert_includes Category.on_level(nil), c1 | |
564 | + assert_includes Category.on_level(nil), c2 | |
565 | + assert_includes Category.on_level(c1), c3 | |
566 | + assert_includes Category.on_level(c1), c4 | |
567 | + assert_includes Category.on_level(c2), c5 | |
568 | + assert_includes Category.on_level(c3), c6 | |
569 | + end | |
570 | + | |
571 | + should 'on level named_scope must be able to receive parent or parent_id' do | |
572 | + parent = fast_create(Category) | |
573 | + category = fast_create(Category, :parent_id => parent) | |
574 | + | |
575 | + assert_includes Category.on_level(parent), category | |
576 | + assert_includes Category.on_level(parent.id), category | |
577 | + end | |
578 | + | |
579 | + should 'list category sub-categories' do | |
580 | + c1 = Category.create!(:name => 'Category 1', :environment => Environment.default) | |
581 | + c2 = Category.create!(:name => 'Category 2', :environment => Environment.default) | |
582 | + c3 = Category.create!(:name => 'Category 3', :environment => Environment.default, :parent_id => c1) | |
583 | + c4 = Category.create!(:name => 'Category 4', :environment => Environment.default, :parent_id => c1) | |
584 | + c5 = Category.create!(:name => 'Category 5', :environment => Environment.default, :parent_id => c3) | |
585 | + | |
586 | + sub_categories = Category.sub_categories(c1) | |
587 | + | |
588 | + assert ActiveRecord::NamedScope::Scope, sub_categories.class | |
589 | + assert_not_includes sub_categories, c1 | |
590 | + assert_not_includes sub_categories, c2 | |
591 | + assert_includes sub_categories, c3 | |
592 | + assert_includes sub_categories, c4 | |
593 | + assert_includes sub_categories, c5 | |
594 | + end | |
595 | + | |
596 | + should 'list category sub-tree' do | |
597 | + c1 = Category.create!(:name => 'Category 1', :environment => Environment.default) | |
598 | + c2 = Category.create!(:name => 'Category 2', :environment => Environment.default) | |
599 | + c3 = Category.create!(:name => 'Category 3', :environment => Environment.default, :parent_id => c1) | |
600 | + c4 = Category.create!(:name => 'Category 4', :environment => Environment.default, :parent_id => c1) | |
601 | + c5 = Category.create!(:name => 'Category 5', :environment => Environment.default, :parent_id => c3) | |
602 | + | |
603 | + sub_tree = Category.sub_tree(c1) | |
604 | + | |
605 | + assert ActiveRecord::NamedScope::Scope, sub_tree.class | |
606 | + assert_includes sub_tree, c1 | |
607 | + assert_not_includes sub_tree, c2 | |
608 | + assert_includes sub_tree, c3 | |
609 | + assert_includes sub_tree, c4 | |
610 | + assert_includes sub_tree, c5 | |
611 | + end | |
612 | + | |
555 | 613 | end | ... | ... |
test/unit/display_helper_test.rb
... | ... | @@ -44,4 +44,14 @@ class DisplayHelperTest < ActiveSupport::TestCase |
44 | 44 | assert_equal 'go to <a href="http://www.noosfero.org" onclick="return confirm(\'Are you sure you want to visit this web site?\')" rel="nofolow" target="_blank">www.​noos​fero​.org</a> yeah!', html |
45 | 45 | end |
46 | 46 | |
47 | + should 'return path to file under theme dir if theme has that file' do | |
48 | + stubs(:theme_path).returns('/designs/themes/noosfero') | |
49 | + assert_equal '/designs/themes/noosfero/images/rails.png', themed_path('/images/rails.png') | |
50 | + end | |
51 | + | |
52 | + should 'return path to file under public dir if theme hasnt that file' do | |
53 | + stubs(:theme_path).returns('/designs/themes/noosfero') | |
54 | + assert_equal '/images/invalid-file.png', themed_path('/images/invalid-file.png') | |
55 | + end | |
56 | + | |
47 | 57 | end | ... | ... |
test/unit/person_test.rb
... | ... | @@ -64,7 +64,7 @@ class PersonTest < ActiveSupport::TestCase |
64 | 64 | |
65 | 65 | should "have person info fields" do |
66 | 66 | p = Person.new(:environment => Environment.default) |
67 | - [ :name, :photo, :contact_information, :birth_date, :sex, :address, :city, :state, :country, :zip_code, :image ].each do |i| | |
67 | + [ :name, :photo, :contact_information, :birth_date, :sex, :address, :city, :state, :country, :zip_code, :image, :district, :address_reference ].each do |i| | |
68 | 68 | assert_respond_to p, i |
69 | 69 | end |
70 | 70 | end | ... | ... |
test/unit/plugin_settings_test.rb
... | ... | @@ -10,29 +10,41 @@ class PluginSettingsTest < ActiveSupport::TestCase |
10 | 10 | |
11 | 11 | def setup |
12 | 12 | @environment = Environment.new |
13 | + @profile = Profile.new | |
13 | 14 | @plugin = SolarSystemPlugin |
14 | - @settings = Noosfero::Plugin::Settings.new(@environment, @plugin) | |
15 | 15 | end |
16 | 16 | |
17 | - attr_accessor :environment, :plugin, :settings | |
17 | + attr_accessor :environment, :profile, :plugin, :settings | |
18 | 18 | |
19 | - should 'store setttings in environment' do | |
19 | + should 'store setttings on any model that offers settings' do | |
20 | + base = environment | |
21 | + settings = Noosfero::Plugin::Settings.new(base, plugin) | |
20 | 22 | settings.star = 'sun' |
21 | 23 | settings.planets = 8 |
22 | - assert_equal 'sun', environment.settings[:solar_system_plugin][:star] | |
23 | - assert_equal 8, environment.settings[:solar_system_plugin][:planets] | |
24 | + assert_equal 'sun', base.settings[:solar_system_plugin][:star] | |
25 | + assert_equal 8, base.settings[:solar_system_plugin][:planets] | |
26 | + assert_equal 'sun', settings.star | |
27 | + assert_equal 8, settings.planets | |
28 | + | |
29 | + base = profile | |
30 | + settings = Noosfero::Plugin::Settings.new(base, plugin) | |
31 | + settings.star = 'sun' | |
32 | + settings.planets = 8 | |
33 | + assert_equal 'sun', base.settings[:solar_system_plugin][:star] | |
34 | + assert_equal 8, base.settings[:solar_system_plugin][:planets] | |
24 | 35 | assert_equal 'sun', settings.star |
25 | 36 | assert_equal 8, settings.planets |
26 | 37 | end |
27 | 38 | |
28 | - should 'save environment on save' do | |
39 | + should 'save base on save' do | |
29 | 40 | environment.expects(:save!) |
41 | + settings = Noosfero::Plugin::Settings.new(environment, plugin) | |
30 | 42 | settings.save! |
31 | 43 | end |
32 | 44 | |
33 | 45 | should 'use default value defined on the plugin class' do |
46 | + settings = Noosfero::Plugin::Settings.new(profile, plugin) | |
34 | 47 | assert_equal 42, settings.secret |
35 | 48 | end |
36 | 49 | |
37 | 50 | end |
38 | - | ... | ... |
test/unit/product_test.rb
... | ... | @@ -772,4 +772,40 @@ class ProductTest < ActiveSupport::TestCase |
772 | 772 | assert_equal [prod3, prod2, prod1], Product.more_recent |
773 | 773 | end |
774 | 774 | |
775 | + should 'return products from a category' do | |
776 | + pc1 = ProductCategory.create!(:name => 'PC1', :environment => Environment.default) | |
777 | + pc2 = ProductCategory.create!(:name => 'PC2', :environment => Environment.default) | |
778 | + pc3 = ProductCategory.create!(:name => 'PC3', :environment => Environment.default, :parent => pc1) | |
779 | + p1 = fast_create(Product, :product_category_id => pc1) | |
780 | + p2 = fast_create(Product, :product_category_id => pc1) | |
781 | + p3 = fast_create(Product, :product_category_id => pc2) | |
782 | + p4 = fast_create(Product, :product_category_id => pc3) | |
783 | + | |
784 | + products = Product.from_category(pc1) | |
785 | + | |
786 | + assert_includes products, p1 | |
787 | + assert_includes products, p2 | |
788 | + assert_not_includes products, p3 | |
789 | + assert_includes products, p4 | |
790 | + end | |
791 | + | |
792 | + should 'not crash if nil is passed to from_category' do | |
793 | + assert_nothing_raised do | |
794 | + Product.from_category(nil) | |
795 | + end | |
796 | + end | |
797 | + | |
798 | + should 'return from_category scope untouched if passed nil' do | |
799 | + enterprise = fast_create(Enterprise) | |
800 | + p1 = fast_create(Product, :enterprise_id => enterprise.id) | |
801 | + p2 = fast_create(Product, :enterprise_id => enterprise.id) | |
802 | + p3 = fast_create(Product, :enterprise_id => enterprise.id) | |
803 | + | |
804 | + products = enterprise.products.from_category(nil) | |
805 | + | |
806 | + assert_includes products, p1 | |
807 | + assert_includes products, p2 | |
808 | + assert_includes products, p3 | |
809 | + end | |
810 | + | |
775 | 811 | end | ... | ... |