discounter 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +61 -0
- data/Rakefile +1 -0
- data/discounter.gemspec +25 -0
- data/lib/discounter/discount.rb +49 -0
- data/lib/discounter/version.rb +3 -0
- data/lib/discounter.rb +66 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: 5849c701150419b978cdd6fef7fd9648118c5629
|
4
|
+
data.tar.gz: 629a57c35222092975414096194ff22a52a75488
|
5
|
+
!binary "U0hBNTEy":
|
6
|
+
metadata.gz: c7015c5ae00266cbd43115aabc76f61c3ff4d19c52ba896a97e51cc9405c4771cfa6f7a0c8b297b9b8660d6da7cd5587745165bdcb3889f4c65babb95c22bf61
|
7
|
+
data.tar.gz: 37aa7da010436101c92e4dabae6bc74e1bd35ef71ef5cb7807255f5979d5356997538bf7adf64229cff492568195b03456c47f91a66df4dacc1534f3b9b17810
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Dain Miller
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Discounter
|
2
|
+
|
3
|
+
Discounter allows you to create a tree of discount tiers for your application (currently max'd at 3, dynamic max coming soon). We allow you to use this tree on the front-end via form post helpers or on the backend to help track and calculate currently applied discounts for a user. This is aiming to be an entirely end-to-end solution for discounting.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'discounter'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install discounter
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
After you have required the gem in your project, then you can initialize it and add your discounts.
|
22
|
+
Note: you will not need to initialize both modules to work with this gem, you can pick if you just want it to help you with your views or with your calculations.
|
23
|
+
|
24
|
+
First, add your discounts to the tree:
|
25
|
+
|
26
|
+
@discounts = Discounts.new(discount_percentage_1, discount_percentage_2, discount_percentage_3)
|
27
|
+
|
28
|
+
Then you have access to the following methods:
|
29
|
+
|
30
|
+
@discounts.all
|
31
|
+
@discounts.select_helper
|
32
|
+
|
33
|
+
Now, let's say you have used the select helper to post a discount to the server in a join record.
|
34
|
+
Let's also pretend the entity is called Event, the join is called EventUser, and the user is simply a User record.
|
35
|
+
|
36
|
+
In that case we might have a controller that looks like this:
|
37
|
+
|
38
|
+
@event = Event.find(params[:id])
|
39
|
+
@user = current_user
|
40
|
+
|
41
|
+
With that, we can easily calculate our new event price if the user viewing it has a discount able to be applied to them
|
42
|
+
in the system. Keep in mind we need to pass in the join model last.
|
43
|
+
|
44
|
+
@discounter = Discounter.new(@event)
|
45
|
+
@event.price = @discounter.evaluate_discount(@user, EventUser)
|
46
|
+
|
47
|
+
Then we will query the database in an optimized fashion and find the discount able to be applied to that user, and if so
|
48
|
+
we will go ahead and manipulate the current @event.price and return out the new discounted price.
|
49
|
+
|
50
|
+
Then using @event in your view will easily allow you to display each current_users customized price.
|
51
|
+
|
52
|
+
## ToDo:
|
53
|
+
- Add dynamic max, allowing users to mix in as many discount tiers as they want for their application.
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
|
57
|
+
1. Fork it
|
58
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
59
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
60
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
61
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/discounter.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'discounter/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "discounter"
|
8
|
+
spec.version = Discounter::VERSION
|
9
|
+
spec.authors = ["Dain Miller"]
|
10
|
+
spec.email = ["miller.dain@gmail.com"]
|
11
|
+
spec.description = %q{Discounter helps you to quickly set up calculation and form post helpers for discount tiers.}
|
12
|
+
spec.summary = %q{Discounter is a gem that allows you to set up a discount based tiering system, and then helps
|
13
|
+
you to use it both via posts to the server or as a method for evaluating current customer
|
14
|
+
discounts on an entity item view.}
|
15
|
+
spec.homepage = ""
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($/)
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Discounts
|
2
|
+
|
3
|
+
def initialize(percentage_1, percentage_2, percentage_3)
|
4
|
+
@tier_1 = percentage_1
|
5
|
+
@tier_2 = percentage_2
|
6
|
+
@tier_3 = percentage_3
|
7
|
+
end
|
8
|
+
|
9
|
+
# Make this dynamic, allow users to pass in as many
|
10
|
+
# discount percentages as they want. Increment by one.
|
11
|
+
DISCOUNTS = {
|
12
|
+
'pretty_discounts': {
|
13
|
+
'Tier 1': @tier_1,
|
14
|
+
'Tier 2': @tier_2,
|
15
|
+
'Tier 3': @tier_3
|
16
|
+
},
|
17
|
+
|
18
|
+
'tier_1': (@tier_1 * 0.01),
|
19
|
+
'tier_2': (@tier_2 * 0.01),
|
20
|
+
'tier_3': (@tier_3 * 0.01)
|
21
|
+
}
|
22
|
+
|
23
|
+
# Instance based query method.
|
24
|
+
def all
|
25
|
+
DISCOUNTS.values.flatten.uniq
|
26
|
+
end
|
27
|
+
|
28
|
+
# Helper for select methods in the HTML.
|
29
|
+
# Should you want a dropdown to choose discount type.
|
30
|
+
def select_helper
|
31
|
+
DISCOUNTS['pretty_discounts']
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# Interface:
|
38
|
+
# Somewhere in their application code they call:
|
39
|
+
# perhaps on the purchase model or the controller for the show view that is
|
40
|
+
# responsible for making a purchase.
|
41
|
+
#
|
42
|
+
# @discounts = Discounts.new(percentage_1, percentage_2, percentage_3)
|
43
|
+
#
|
44
|
+
# Then via our gem magically they have access to the following
|
45
|
+
# @discounts.all
|
46
|
+
# or
|
47
|
+
# <%= select_tag 'Choose a discount to apply', @discounts.select_helper' %>
|
48
|
+
#
|
49
|
+
#
|
data/lib/discounter.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'discounter/version'
|
2
|
+
require 'discounter/discount'
|
3
|
+
|
4
|
+
# We expect the entity to have a price attribute.
|
5
|
+
module Discounter
|
6
|
+
class << self
|
7
|
+
|
8
|
+
attr_accessor :price
|
9
|
+
|
10
|
+
# Entity is the entity in which the price to be set is on.
|
11
|
+
def initialize(entity)
|
12
|
+
@entity ||= entity
|
13
|
+
@price ||= entity.try(:price)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize_discount
|
17
|
+
# ?
|
18
|
+
end
|
19
|
+
|
20
|
+
# User is the user that may have a discount for this entity.
|
21
|
+
# Join is the entity in which there is a setting for yes this user has a
|
22
|
+
# discount associated to them.
|
23
|
+
# We expect the join model to have a discount_tier column that is set to either.
|
24
|
+
# So we expect it to be set up this way:
|
25
|
+
# - Model Join - Attributes: user_id, discount_tier (optional column = entity_id (for discounting on)).
|
26
|
+
# nil if there is no discount, or the discount tier if there is indeed one.
|
27
|
+
def evaluate_discount(user, join)
|
28
|
+
Join.find_all_by_user_id(user.id).each(&method(:verify_discount_applicability))
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
# This method is passed a row from the join table to verify the discount on.
|
33
|
+
def verify_discount_applicability(row)
|
34
|
+
if row.try(:discount).nil?
|
35
|
+
# There is no discount set for this user in the system
|
36
|
+
@price
|
37
|
+
else
|
38
|
+
# There is a discount tier applied. Let's do the calculation
|
39
|
+
# And return out the price for the Interface.
|
40
|
+
@price = (@price.to_f * row.discount.to_f).to_i
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end # / class
|
45
|
+
end # / module
|
46
|
+
|
47
|
+
|
48
|
+
# Interface:
|
49
|
+
#
|
50
|
+
# Entity in this case is an event that has a purchase price
|
51
|
+
# That we sometimes want admins to be able to discount.
|
52
|
+
#
|
53
|
+
# event = Event.find(params[:id])
|
54
|
+
#
|
55
|
+
# Safety check, as we expect a price on the model
|
56
|
+
# IDEA: Mixin an options hash that has price true/false flag on it.
|
57
|
+
# if event.price
|
58
|
+
# discounter = Discounter.new(event)
|
59
|
+
#
|
60
|
+
# One big use case for this gem is to proxy the price IF we have a discounted
|
61
|
+
# price available to it.
|
62
|
+
# @event.price = discounter.evaluate_discount(user, join)
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
#
|
66
|
+
#
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: discounter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dain Miller
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Discounter helps you to quickly set up calculation and form post helpers
|
42
|
+
for discount tiers.
|
43
|
+
email:
|
44
|
+
- miller.dain@gmail.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- .gitignore
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE.txt
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- discounter.gemspec
|
55
|
+
- lib/discounter.rb
|
56
|
+
- lib/discounter/discount.rb
|
57
|
+
- lib/discounter/version.rb
|
58
|
+
homepage: ''
|
59
|
+
licenses:
|
60
|
+
- MIT
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 2.0.3
|
79
|
+
signing_key:
|
80
|
+
specification_version: 4
|
81
|
+
summary: Discounter is a gem that allows you to set up a discount based tiering system,
|
82
|
+
and then helps you to use it both via posts to the server or as a method for evaluating
|
83
|
+
current customer discounts on an entity item view.
|
84
|
+
test_files: []
|