diff --git a/app/controllers/admin/environment_design_controller.rb b/app/controllers/admin/environment_design_controller.rb index 6544329..efefac0 100644 --- a/app/controllers/admin/environment_design_controller.rb +++ b/app/controllers/admin/environment_design_controller.rb @@ -3,7 +3,7 @@ class EnvironmentDesignController < BoxOrganizerController protect 'edit_environment_design', :environment def available_blocks - @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock ] + @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock ] end end diff --git a/app/controllers/my_profile/profile_design_controller.rb b/app/controllers/my_profile/profile_design_controller.rb index dda3257..cd4fc38 100644 --- a/app/controllers/my_profile/profile_design_controller.rb +++ b/app/controllers/my_profile/profile_design_controller.rb @@ -24,6 +24,7 @@ class ProfileDesignController < BoxOrganizerController if profile.enterprise? blocks << DisabledEnterpriseMessageBlock blocks << HighlightsBlock + blocks << FeaturedProductsBlock end # product block exclusive for enterprises in environments that permits it diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 90794a1..768f8c9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -960,4 +960,9 @@ module ApplicationHelper text_field_tag(name, value, options.merge(:class => 'colorpicker_field')) end + # for now force currency to Brazillian format, like: "12.345,20" + def float_to_currency(price) + number_to_currency(price, :unit => 'R$', :separator => ',', :delimiter => '.') + end + end diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 2383e61..1d01020 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -51,6 +51,10 @@ class Enterprise < Organization environment ? environment.active_enterprise_fields : [] end + def highlighted_products_with_image(options = {}) + Product.find(:all, {:conditions => {:highlighted => true}, :joins => :image}.merge(options)) + end + def required_fields environment ? environment.required_enterprise_fields : [] end diff --git a/app/models/environment.rb b/app/models/environment.rb index 0588375..5558434 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -628,4 +628,9 @@ class Environment < ActiveRecord::Base end end + def highlighted_products_with_image(options = {}) + Product.find(:all, {:conditions => {:highlighted => true, :enterprise_id => self.enterprises.find(:all, :select => :id) }, :joins => :image}.merge(options)) + end + end + diff --git a/app/models/featured_products_block.rb b/app/models/featured_products_block.rb new file mode 100644 index 0000000..e8dbfd3 --- /dev/null +++ b/app/models/featured_products_block.rb @@ -0,0 +1,35 @@ +class FeaturedProductsBlock < Block + + settings_items :product_ids, :type => Array, :default => [] + settings_items :groups_of, :type => :integer, :default => 3 + settings_items :speed, :type => :integer, :default => 1000 + settings_items :reflect, :type => :boolean, :default => true + + before_save do |block| + if block.owner.kind_of?(Environment) && block.product_ids.blank? + seed = block.owner.products.count + block.product_ids = block.owner.highlighted_products_with_image(:offset => (rand(seed) % (seed - block.groups_of * 3)), :limit => block.groups_of * 3).map(&:id) + end + block.groups_of = block.groups_of.to_i + end + + def self.description + _('Featured Products') + end + + def products + Product.find(self.product_ids) || [] + end + + def products_for_selection + self.owner.highlighted_products_with_image + end + + def content + block = self + lambda do + render :file => 'blocks/featured_products', :locals => { :block => block } + end + end + +end diff --git a/app/views/blocks/featured_products.rhtml b/app/views/blocks/featured_products.rhtml new file mode 100644 index 0000000..67cffec --- /dev/null +++ b/app/views/blocks/featured_products.rhtml @@ -0,0 +1,55 @@ +<%= block_title(block.title) %> +<% unless block.products.blank? %> + <%= link_to content_tag(:span, _('Previous')), '#', :class => 'featured-product-prev featured-product-arrow' %> + + <%= link_to content_tag(:span, _('Next')), '#', :class => 'featured-product-next featured-product-arrow' %> + + +<% else %> + <%= _('Please, edit this block and choose some products') %> +<% end %> diff --git a/app/views/box_organizer/_featured_products_block.rhtml b/app/views/box_organizer/_featured_products_block.rhtml new file mode 100644 index 0000000..123c1e1 --- /dev/null +++ b/app/views/box_organizer/_featured_products_block.rhtml @@ -0,0 +1,8 @@ +<%= _('Featured Products') %> + diff --git a/app/views/layouts/_javascript.rhtml b/app/views/layouts/_javascript.rhtml index c244260..9294422 100644 --- a/app/views/layouts/_javascript.rhtml +++ b/app/views/layouts/_javascript.rhtml @@ -1 +1 @@ -<%= javascript_include_tag :defaults, 'jquery-latest.js', 'jquery.noconflict.js', 'jquery.cycle.all.min.js', 'thickbox.js', 'lightbox', 'colorpicker', 'colorpicker-noosfero', :cache => 'cache-general' %> +<%= javascript_include_tag :defaults, 'jquery-latest.js', 'jquery.noconflict.js', 'jquery.cycle.all.min.js', 'thickbox.js', 'lightbox', 'colorpicker', 'colorpicker-noosfero', 'reflection', :cache => 'cache-general' %> diff --git a/app/views/manage_products/_form.rhtml b/app/views/manage_products/_form.rhtml index 6754630..235e718 100644 --- a/app/views/manage_products/_form.rhtml +++ b/app/views/manage_products/_form.rhtml @@ -6,6 +6,7 @@ <%= required display_form_field( _('Name:'), f.text_field(:name) ) %> <%= display_form_field( _('Price:'), f.text_field(:price) ) %> <%= display_form_field( _('Description:'), f.text_area(:description, :rows => 10) ) %> + <%= labelled_form_field(f.check_box(:highlighted) + _('Highlight this product'),'') %> <% f.fields_for :image_builder, @product.image do |i| %> <%= file_field_or_thumbnail(_('Image:'), @product.image, i) %> <% end %> diff --git a/db/migrate/20100619031945_add_highlighted_to_product.rb b/db/migrate/20100619031945_add_highlighted_to_product.rb new file mode 100644 index 0000000..269d00b --- /dev/null +++ b/db/migrate/20100619031945_add_highlighted_to_product.rb @@ -0,0 +1,9 @@ +class AddHighlightedToProduct < ActiveRecord::Migration + def self.up + add_column :products, :highlighted, :boolean + end + + def self.down + remove_column :products, :highlighted + end +end diff --git a/db/schema.rb b/db/schema.rb index 658d58f..39aa2f2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,8 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20100514133346) do + +ActiveRecord::Schema.define(:version => 20100619031945) do create_table "article_versions", :force => true do |t| t.integer "article_id" @@ -240,6 +241,7 @@ ActiveRecord::Schema.define(:version => 20100514133346) do t.datetime "updated_at" t.float "lat" t.float "lng" + t.boolean "highlighted" end add_index "products", ["enterprise_id"], :name => "index_products_on_enterprise_id" diff --git a/public/javascripts/reflection.js b/public/javascripts/reflection.js new file mode 100644 index 0000000..1cab119 --- /dev/null +++ b/public/javascripts/reflection.js @@ -0,0 +1,177 @@ +/** + * reflection.js v2.0 + * http://cow.neondragon.net/stuff/reflection/ + * Freely distributable under MIT-style license. + */ + +/* From prototype.js */ +if (!document.myGetElementsByClassName) { + document.myGetElementsByClassName = function(className) { + var children = document.getElementsByTagName('*') || document.all; + var elements = new Array(); + + for (var i = 0; i < children.length; i++) { + var child = children[i]; + var classNames = child.className.split(' '); + for (var j = 0; j < classNames.length; j++) { + if (classNames[j] == className) { + elements.push(child); + break; + } + } + } + return elements; + } +} + +var Reflection = { + defaultHeight : 0.5, + defaultOpacity: 0.5, + + add: function(image, options) { + Reflection.remove(image); + + doptions = { "height" : Reflection.defaultHeight, "opacity" : Reflection.defaultOpacity } + if (options) { + for (var i in doptions) { + if (!options[i]) { + options[i] = doptions[i]; + } + } + } else { + options = doptions; + } + + try { + var d = document.createElement('div'); + var p = image; + + var classes = p.className.split(' '); + var newClasses = ''; + for (j=0;j 'test enteprise', :identifier => 'test_ent') assert_equal 3, ent.boxes.size end + + should 'collect the highlighted products with image' do + env = Environment.default + e1 = fast_create(Enterprise) + p1 = e1.products.create!(:name => 'test_prod1') + products = [] + 3.times {|n| + products.push(Product.create!(:name => "product #{n}", :enterprise_id => e1.id, :highlighted => true, :image_builder => { + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') + })) + } + Product.create!(:name => "product 4", :enterprise_id => e1.id, :highlighted => true) + Product.create!(:name => "product 5", :enterprise_id => e1.id, :image_builder => { + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') + }) + assert_equal products, e1.highlighted_products_with_image + end + end diff --git a/test/unit/environment_test.rb b/test/unit/environment_test.rb index 46f37c4..bec3af6 100644 --- a/test/unit/environment_test.rb +++ b/test/unit/environment_test.rb @@ -374,6 +374,23 @@ class EnvironmentTest < Test::Unit::TestCase assert_includes env.products, p1 end + should 'collect the highlighted products with image through enterprises' do + env = Environment.default + e1 = fast_create(Enterprise) + p1 = e1.products.create!(:name => 'test_prod1') + products = [] + 3.times {|n| + products.push(Product.create!(:name => "product #{n}", :enterprise_id => e1.id, :highlighted => true, :image_builder => { + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') + })) + } + Product.create!(:name => "product 4", :enterprise_id => e1.id, :highlighted => true) + Product.create!(:name => "product 5", :enterprise_id => e1.id, :image_builder => { + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') + }) + assert_equal products, env.highlighted_products_with_image + end + should 'not have person through communities' do env = Environment.default com = fast_create(Community) diff --git a/test/unit/featured_products_block_test.rb b/test/unit/featured_products_block_test.rb new file mode 100644 index 0000000..c48101b --- /dev/null +++ b/test/unit/featured_products_block_test.rb @@ -0,0 +1,127 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class FeaturedProductsBlockTest < ActiveSupport::TestCase + + def setup + @profile = fast_create(Profile) + @environment = Environment.default + @environment.boxes << Box.new + end + attr_reader :profile + + should 'refer to products' do + products = [] + 3.times {|n| products.push(Product.create!(:name => "product #{n}", :enterprise_id => profile.id)) } + featured_products_block = FeaturedProductsBlock.create!(:product_ids => products.map(&:id)) + assert_equal products, featured_products_block.products + end + + should "have method products_for_selection" do + block = FeaturedProductsBlock.new + assert_respond_to block, 'products_for_selection' + end + + should " the defaul product_ids be an empty array" do + block = FeaturedProductsBlock.new + assert_equal [], block.product_ids + end + + should " the defaul groups_of be 3" do + block = FeaturedProductsBlock.new + assert_equal 3, block.groups_of + end + + should 'default interval between transitions is 1000 miliseconds' do + block = FeaturedProductsBlock.new + assert_equal 1000, block.speed + end + + should "reflect by default" do + block = FeaturedProductsBlock.new + assert_equal true, block.reflect + end + + should 'describe itself' do + assert_not_equal Block.description, FeaturedProductsBlock.description + end + + should "the groups_of variabe be a integer" do + block = FeaturedProductsBlock.new + assert_kind_of Integer, block.groups_of + block.groups_of = 2 + block.save + block.reload + assert_kind_of Integer, block.groups_of + block.groups_of = '2' + block.save + block.reload + assert_kind_of Integer, block.groups_of + end + + should "an environment block collect product automatically" do + block = FeaturedProductsBlock.new() + block.product_ids = [] + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) + 3.times {|n| + Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :highlighted => true, :image_builder => { + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') + }) + } + @environment.boxes.first.blocks<< block + + assert_not_equal [], block.product_ids + end + + should "an environment block collect just product with image automatically" do + block = FeaturedProductsBlock.new() + block.product_ids = [] + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) + 3.times {|n| + Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :highlighted => true) + } + @environment.boxes.first.blocks<< block + + assert_equal [], block.product_ids + end + + should "an environment block collect just highlighted product automatically" do + block = FeaturedProductsBlock.new() + block.product_ids = [] + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) + 3.times {|n| + Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :image_builder => { + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') + }) + } + @environment.boxes.first.blocks<< block + + assert_equal [], block.product_ids + end + + should 'display feature products block' do + block = FeaturedProductsBlock.new + + self.expects(:render).with(:file => 'blocks/featured_products', :locals => { :block => block}) + instance_eval(& block.content) + end + + should "return just highlighted products with image for selection" do + block = FeaturedProductsBlock.new() + block.product_ids = [] + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) + products = [] + 3.times {|n| + products.push(Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :highlighted => true, :image_builder => { + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') + })) + } + Product.create!(:name => "product 4", :enterprise_id => enterprise.id, :highlighted => true) + Product.create!(:name => "product 5", :enterprise_id => enterprise.id, :image_builder => { + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') + }) + @environment.boxes.first.blocks<< block + + assert_equal products, block.products_for_selection + end + +end diff --git a/test/unit/highlights_block_test.rb b/test/unit/highlights_block_test.rb index c403b18..31fc29c 100644 --- a/test/unit/highlights_block_test.rb +++ b/test/unit/highlights_block_test.rb @@ -119,12 +119,14 @@ class HighlightsBlockTest < ActiveSupport::TestCase i1 = {:image_id => 1, :address => '/address', :position => 3, :title => 'address'} i2 = {:image_id => 2, :address => '/address', :position => 1, :title => 'address'} i3 = {:image_id => 3, :address => '/address', :position => 2, :title => 'address'} - block.images = [i1,i2,i3] + i4 = {:image_id => 4, :address => '/address', :position => 5, :title => 'address'} + i5 = {:image_id => 5, :address => '/address', :position => 4, :title => 'address'} + block.images = [i1,i2,i3,i4,i5] block.shuffle = true block.save! block.reload - assert_equal [i1,i2,i3], block.images - assert_not_equal [i2,i3,i1], block.featured_images + assert_equal [i1,i2,i3,i4,i5], block.images + assert_not_equal [i2,i3,i1,i4,i5], block.featured_images end end -- libgit2 0.21.2