Permalink
Browse files

Allowing different discount types.

  • Loading branch information...
1 parent 882342e commit 6abce9c34f8134744e44b36b757e142012e60563 @JDutil JDutil committed Nov 15, 2012
View
@@ -4,3 +4,4 @@ pkg
Gemfile.lock
spec/dummy
Guardfile
+coverage
View
@@ -1,4 +1,3 @@
source 'http://rubygems.org'
-gemspec
-gem 'spree', '~> 1.2'
+gemspec
View
@@ -8,10 +8,11 @@ Volume Pricing is an extension to Spree (a complete open source commerce solutio
Each VolumePrice contains the following values:
1. **Variant:** Each VolumePrice is associated with a _Variant_, which is used to link products to particular prices.
-2. **Name:** The human readable reprentation of the quantity range (Ex. 10-100). (Optional)
-3. **Range:** The quantity range for which the price is valid (See Below for Examples of Valid Ranges.)
-4. **Amount:** The price of the product if the line item quantity falls within the specified range.
-5. **Position:** Integer value for `acts_as_list` (Helps keep the volume prices in a defined order.)
+1. **Name:** The human readable reprentation of the quantity range (Ex. 10-100). (Optional)
+1. **Discount Type** The type of discount to apply. Price: sets price to the amount specified. Dollar: subtracts specified amount from the Variant price. Percent: subtracts the specific amounts percentage from the Variant price.
+1. **Range:** The quantity range for which the price is valid (See Below for Examples of Valid Ranges.)
+1. **Amount:** The price of the product if the line item quantity falls within the specified range.
+1. **Position:** Integer value for `acts_as_list` (Helps keep the volume prices in a defined order.)
Install
=======
@@ -6,10 +6,24 @@
# calculates the price based on quantity
def volume_price(quantity)
- volume_prices.each do |price|
- return price.amount if price.include?(quantity)
+ if self.volume_prices.count == 0
+ return self.price
+ else
+ self.volume_prices.each do |volume_price|
+ if volume_price.include?(quantity)
+ case volume_price.discount_type
+ when 'price'
+ return volume_price.amount
+ when 'dollar'
+ return self.price - volume_price.amount
+ when 'percent'
+ return self.price * (1 - volume_price.amount)
+ end
+ end
+ end
+ # No price ranges matched.
+ return self.price
end
- self.price
end
end
@@ -2,11 +2,12 @@ class Spree::VolumePrice < ActiveRecord::Base
belongs_to :variant, :touch => true
acts_as_list :scope => :variant
+ validates :amount, :presence => true
+ validates :discount_type, :presence => true, :inclusion => {:in => %w(price dollar percent), :message => "%{value} is not a valid Volume Price Type"}
validates :range, :format => {:with => /\(?[0-9]+(?:\.{2,3}[0-9]+|\+\)?)/, :message => "must be in one of the following formats: (a..b), (a...b), (a+)"}
- validates_presence_of :variant
- validates_presence_of :amount
+ validates :variant, :presence => true
- attr_accessible :amount, :name, :position, :range, :variant
+ attr_accessible :amount, :discount_type, :name, :position, :range, :variant
OPEN_ENDED = /\(?[0-9]+\+\)?/
@@ -3,6 +3,7 @@
<thead>
<tr>
<th><%= t("name") %></th>
+ <th><%= t("discount_type") %></th>
<th><%= t("range") %></th>
<th><%= t("amount") %></th>
<th><%= t("position") %></th>
@@ -4,6 +4,10 @@
<%= f.text_field :name, :size => 10 %>
</td>
<td>
+ <%= error_message_on(f.object, :discount_type) %>
+ <%= f.select :discount_type, [['Dollar Price','price'],['Percent Discount','percent'],['Dollar Discount','dollar']] %>
+ </td>
+ <td>
<%= error_message_on(f.object, :range) %>
<%= f.text_field :range, :size => 10 %>
</td>
@@ -8,6 +8,7 @@
<thead>
<tr>
<th><%= t("name") %></th>
+ <th><%= t("discount_type") %></th>
<th><%= t("range") %></th>
<th><%= t("amount") %></th>
<th><%= t("position") %></th>
@@ -2,6 +2,7 @@
en:
add_volume_price: Add Volume Price
position: Position
+ discount_type: Discount Type
range: Range
volume_prices: Volume Prices
volume_pricing: Volume Pricing
@@ -0,0 +1,5 @@
+class AddDiscountTypeColumn < ActiveRecord::Migration
+ def change
+ add_column :spree_volume_prices, :discount_type, :string
+ end
+end
View
@@ -1,5 +1,7 @@
-#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
-ENGINE_PATH = File.expand_path('../..', __FILE__)
-load File.expand_path('../../spec/dummy/script/rails', __FILE__)
+ENGINE_ROOT = File.expand_path('../..', __FILE__)
+ENGINE_PATH = File.expand_path('../../lib/spree_volume_pricing/engine', __FILE__)
+
+require 'rails/all'
+require 'rails/engine/commands'
@@ -15,6 +15,7 @@
"volume_prices_attributes" => {
"1335830259720" => {
"name"=>"5-10",
+ "discount_type" => 'price',
"range"=>"5..10",
"amount"=>"90",
"position"=>"1",
@@ -1,6 +1,7 @@
FactoryGirl.define do
factory :volume_price, :class => Spree::VolumePrice do
amount 10
+ discount_type 'price'
range '(1..5)'
association :variant
end
@@ -4,7 +4,7 @@
before :each do
@order = FactoryGirl.create(:order)
@variant = FactoryGirl.create(:variant, :price => 10)
- @variant.volume_prices.create! :amount => 9, :range => '(2+)'
+ @variant.volume_prices.create! :amount => 9, :discount_type => 'price', :range => '(2+)'
@order.add_variant(@variant, 1)
@line_item = @order.line_items.first
end
@@ -15,4 +15,3 @@
@order.line_items.first.price.to_f.should == 9.00
end
end
-
@@ -4,18 +4,51 @@
it { should have_many(:volume_prices) }
describe '#volume_price' do
- before :each do
- @variant = Factory :variant, :price => 10
- @variant.volume_prices.create! :amount => 9, :range => '(10+)'
+
+ context 'discount_type = price' do
+ before :each do
+ @variant = Factory :variant, :price => 10
+ @variant.volume_prices.create! :amount => 9, :discount_type => 'price', :range => '(10+)'
+ end
+
+ it 'should use the variants price when it does not match a range' do
+ @variant.volume_price(1).to_f.should == 10.00
+ end
+
+ it 'should use the volume price when it does match a range' do
+ @variant.volume_price(10).to_f.should == 9.00
+ end
end
- it 'should use the variants price when it doesnt match a range' do
- @variant.volume_price(1).to_f.should == 10.00
+ context 'discount_type = dollar' do
+ before :each do
+ @variant = Factory :variant, :price => 10
+ @variant.volume_prices.create! :amount => 1, :discount_type => 'dollar', :range => '(10+)'
+ end
+
+ it 'should use the variants price when it does not match a range' do
+ @variant.volume_price(1).to_f.should == 10.00
+ end
+
+ it 'should use the volume price when it does match a range' do
+ @variant.volume_price(10).to_f.should == 9.00
+ end
end
- it 'should use the volume price when it does match a range' do
- @variant.volume_price(10).to_f.should == 9.00
+ context 'discount_type = percent' do
+ before :each do
+ @variant = Factory :variant, :price => 10
+ @variant.volume_prices.create! :amount => 0.1, :discount_type => 'percent', :range => '(10+)'
+ end
+
+ it 'should use the variants price when it does not match a range' do
+ @variant.volume_price(1).to_f.should == 10.00
+ end
+
+ it 'should use the volume price when it does match a range' do
+ @variant.volume_price(10).to_f.should == 9.00
+ end
end
+
end
end
-
@@ -6,7 +6,7 @@
it { should validate_presence_of(:amount) }
before(:each) do
- @volume_price = Spree::VolumePrice.new(:variant => Spree::Variant.new, :amount => 10)
+ @volume_price = Spree::VolumePrice.new(:variant => Spree::Variant.new, :amount => 10, :discount_type => 'price')
end
it "should not interepret a Ruby range as being opend ended" do
View
@@ -1,3 +1,16 @@
+# Configure simeplecov for test coverage report
+require 'simplecov'
+SimpleCov.start do
+ add_filter '/config/'
+ add_group 'Controllers', 'app/controllers'
+ add_group 'Helpers', 'app/helpers'
+ add_group 'Mailers', 'app/mailers'
+ add_group 'Models', 'app/models'
+ add_group 'Overrides', 'app/overrides'
+ add_group 'Libraries', 'lib'
+ add_group 'Specs', 'spec'
+end
+
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../dummy/config/environment", __FILE__)
require 'rspec/rails'
@@ -6,9 +19,10 @@
#include spree's factories
require 'spree/core/testing_support/factories'
+# Uncomment when 1.2.1 is released
+# require 'spree/core/testing_support/authorization_helpers'
require 'spree/core/testing_support/controller_requests'
require 'spree/core/url_helpers'
-# require 'spree/core/testing_support/authorization_helpers'
# include local factories
Dir["#{File.dirname(__FILE__)}/factories/**/*.rb"].each do |f|
@@ -30,4 +30,4 @@ def stub_authorization!
RSpec.configure do |config|
config.extend AuthorizationHelpers::Controller, :type => :controller
config.extend AuthorizationHelpers::Request, :type => :request
-end
+end
@@ -22,5 +22,6 @@ Gem::Specification.new do |s|
s.add_development_dependency('ffaker')
s.add_development_dependency('shoulda-matchers')
s.add_development_dependency('rspec-rails', '~> 2.11')
+ s.add_development_dependency 'simplecov'
s.add_development_dependency('factory_girl_rails', '~> 1.7.0')
end

0 comments on commit 6abce9c

Please sign in to comment.