spree_active_sale 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +15 -5
- data/app/controllers/spree/admin/active_sale_events_controller.rb +26 -11
- data/app/controllers/spree/admin/active_sales_controller.rb +30 -0
- data/app/controllers/spree/admin/resource_controller_decorator.rb +19 -0
- data/app/controllers/spree/home_controller_decorator.rb +2 -1
- data/app/helpers/spree/active_sale_events_helper.rb +6 -1
- data/app/helpers/spree/active_sales_helper.rb +42 -0
- data/app/helpers/spree/base_helper_decorator.rb +3 -0
- data/app/models/spree/active_sale.rb +35 -7
- data/app/models/spree/active_sale_configuration.rb +1 -0
- data/app/models/spree/active_sale_event.rb +14 -7
- data/app/models/spree/product_decorator.rb +9 -2
- data/app/models/spree/sale_event.rb +17 -10
- data/app/models/spree/sale_image.rb +4 -0
- data/app/models/spree/taxon_decorator.rb +8 -1
- data/app/models/spree/variant_decorator.rb +15 -1
- data/app/views/spree/admin/active_sale_events/_form.html.erb +40 -41
- data/app/views/spree/admin/active_sale_events/edit.html.erb +4 -4
- data/app/views/spree/admin/active_sale_events/index.html.erb +1 -12
- data/app/views/spree/admin/active_sale_events/new.html.erb +3 -1
- data/app/views/spree/admin/active_sales/edit.html.erb +1 -17
- data/app/views/spree/admin/active_sales/get_children.json.erb +9 -0
- data/app/views/spree/admin/active_sales/index.html.erb +12 -11
- data/app/views/spree/admin/active_sales/new.html.erb +10 -1
- data/app/views/spree/admin/sale_images/_form.html.erb +1 -1
- data/app/views/spree/admin/shared/_js_head.html.erb +8 -0
- data/app/views/spree/admin/shared/_list_events.html.erb +50 -29
- data/config/locales/active_sales_en.yml +5 -0
- data/config/locales/active_sales_es.yml +2 -2
- data/config/routes.rb +10 -1
- data/lib/spree_active_sale/engine.rb +1 -1
- metadata +13 -10
- data/app/views/spree/admin/active_sales/_form.html.erb +0 -35
data/README.md
CHANGED
@@ -9,8 +9,8 @@ Spree Active Sale makes it easy to handle flash sale/ daily deals behavior withi
|
|
9
9
|
## FEATURES
|
10
10
|
|
11
11
|
* Provides a quick implementation of flash sales/ daily deals behavior by a easy scheduler a.k.a *ActiveSale*.
|
12
|
-
* Provides an admin interface for creating/ scheduling, managing, or re-scheduling sale events.
|
13
|
-
* Provides a view helper for countdown timer to show sale's ending time, which will be shown to your customers. This eventually makes a sense of urgency
|
12
|
+
* Provides an admin interface for creating/ scheduling, managing, sorting, bundeling, or re-scheduling sale events.
|
13
|
+
* Provides a view helper for countdown timer to show sale's ending time, which will be shown to your customers. This eventually makes a sense of urgency on your customers' mind.
|
14
14
|
* Supplies methods for class <tt>Spree::ActiveSaleEvent</tt> like: <tt>live</tt>, <tt>active</tt>, <tt>live_active</tt>, <tt>hidden</tt>, <tt>live_active_and_hidden</tt>, <tt>upcoming_events</tt>, <tt>starting_today</tt>, <tt>ending_today</tt>.
|
15
15
|
|
16
16
|
## LINKS
|
@@ -18,7 +18,7 @@ Spree Active Sale makes it easy to handle flash sale/ daily deals behavior withi
|
|
18
18
|
* Demo application: [Spree Active Sale Demo](https://github.com/suryart/spree_active_sale_demo)
|
19
19
|
* Dependency status: [![Dependency Status](https://gemnasium.com/suryart/spree_active_sale.png)](https://gemnasium.com/suryart/spree_active_sale)
|
20
20
|
* Code climate: [![Code Climate](https://codeclimate.com/github/suryart/spree_active_sale.png)](https://codeclimate.com/github/suryart/spree_active_sale)
|
21
|
-
* Build Status: [![Build Status](https://travis-ci.org/suryart/spree_active_sale.png?branch=
|
21
|
+
* Build Status: [![Build Status](https://travis-ci.org/suryart/spree_active_sale.png?branch=master)](https://travis-ci.org/suryart/spree_active_sale)
|
22
22
|
* Issues: [Project issues](https://github.com/suryart/spree_active_sale/issues)
|
23
23
|
* Fork: [Fork this Project](https://github.com/suryart/spree_active_sale/fork_select)
|
24
24
|
|
@@ -40,7 +40,7 @@ Spree Active Sale makes it easy to handle flash sale/ daily deals behavior withi
|
|
40
40
|
* Or get it from rubygems.org by mentioning the following line in your Gemfile:
|
41
41
|
|
42
42
|
```ruby
|
43
|
-
gem 'spree_active_sale', '1.0
|
43
|
+
gem 'spree_active_sale', '1.3.0'
|
44
44
|
```
|
45
45
|
|
46
46
|
### Then run the following commands:
|
@@ -176,6 +176,15 @@ You will have to add javascript in the bottom of your **store/all.js** file as f
|
|
176
176
|
# "Spree::ActiveSaleEvent", "Spree::Variant", "Spree::Product", or "Spree::Taxon" class.
|
177
177
|
# Which simply says if sale event for that instance is accessible for users or not.
|
178
178
|
Spree::ActiveSaleEvent.is_live?(instance)
|
179
|
+
|
180
|
+
# You can list the rows where a column, for example- :start_date, is not blank,
|
181
|
+
# and get it sorted using not_blank_and_sorted_by(:column_name) like this:
|
182
|
+
Spree::SaleEvent.not_blank_and_sorted_by(:start_date)
|
183
|
+
Spree::ActiveSale.not_blank_and_sorted_by(:start_date)
|
184
|
+
Spree::ActiveSaleEvent.not_blank_and_sorted_by(:start_date)
|
185
|
+
|
186
|
+
# Also, you can chain this method with other scopes, like this:
|
187
|
+
Spree::ActiveSaleEvent.live_active.not_blank_and_sorted_by(:start_date)
|
179
188
|
```
|
180
189
|
|
181
190
|
## Overriding countdown timer's layout differently for different events
|
@@ -194,7 +203,7 @@ Please visit [jQuery Countdown](http://keith-wood.name/countdown.html) for more
|
|
194
203
|
|
195
204
|
## Overriding configuration and preferences
|
196
205
|
|
197
|
-
You can use
|
206
|
+
You can use this at the bottom of your **application's app/config/initializers/spree.rb** for configuration:
|
198
207
|
|
199
208
|
```ruby
|
200
209
|
Spree::ActiveSale.config do |config|
|
@@ -211,6 +220,7 @@ Since you can not set boolean values from the block config shown above for assig
|
|
211
220
|
Spree::ActiveSaleConfig[:paginate_sales_for_admin?] = true
|
212
221
|
Spree::ActiveSaleConfig[:paginate_sale_events_for_user?] = true
|
213
222
|
Spree::ActiveSaleConfig[:paginate_sales_for_user?] = false
|
223
|
+
Spree::ActiveSaleConfig[:name_with_event_position?] = true
|
214
224
|
```
|
215
225
|
|
216
226
|
## TODOs
|
@@ -3,15 +3,23 @@ module Spree
|
|
3
3
|
class ActiveSaleEventsController < ResourceController
|
4
4
|
belongs_to 'spree/active_sale', :find_by => :id
|
5
5
|
before_filter :load_active_sale, :only => [:index]
|
6
|
+
before_filter :parent_id_for_event, :only => [:new, :edit, :create, :update]
|
6
7
|
update.before :get_eventable
|
8
|
+
respond_to :json, :only => [:update_events]
|
7
9
|
|
8
10
|
def show
|
9
11
|
redirect_to( :action => :edit )
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
14
|
+
def destroy
|
15
|
+
@active_sale_event = Spree::ActiveSaleEvent.find(params[:id])
|
16
|
+
@active_sale_event.destroy
|
17
|
+
respond_with(@active_sale_event) { |format| format.json { render :json => '' } }
|
18
|
+
end
|
19
|
+
|
20
|
+
def update_events
|
21
|
+
@active_sale_event.update_attributes(params[:active_sale_event])
|
22
|
+
respond_with(@active_sale_event)
|
15
23
|
end
|
16
24
|
|
17
25
|
protected
|
@@ -37,16 +45,23 @@ module Spree
|
|
37
45
|
|
38
46
|
def get_eventable
|
39
47
|
object_name = params[:active_sale_event]
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
get_eventable_object(object_name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def parent_id_for_event
|
52
|
+
params[:parent_id] ||= check_active_sale_event_params
|
53
|
+
@parent_id = params[:parent_id]
|
54
|
+
if @parent_id.blank?
|
55
|
+
redirect_to edit_admin_active_sale_path(params[:active_sale_id]), :notice => I18n.t('spree.active_sale.event.parent_id_cant_be_nil')
|
48
56
|
end
|
49
57
|
end
|
58
|
+
|
59
|
+
def check_active_sale_event_params(event = params[:active_sale_event])
|
60
|
+
return nil if event.nil?
|
61
|
+
parent_id = event[:parent_id]
|
62
|
+
event.delete(:parent_id) if event[:parent_id].nil? || event[:parent_id] == "nil"
|
63
|
+
parent_id
|
64
|
+
end
|
50
65
|
end
|
51
66
|
end
|
52
67
|
end
|
@@ -1,6 +1,14 @@
|
|
1
1
|
module Spree
|
2
2
|
module Admin
|
3
3
|
class ActiveSalesController < ResourceController
|
4
|
+
before_filter :load_active_sale_events, :only => [:new, :edit]
|
5
|
+
before_filter :set_active_sale, :only => [:create, :update]
|
6
|
+
respond_to :json, :only => [:get_children]
|
7
|
+
|
8
|
+
def get_children
|
9
|
+
@active_sale_events = Spree::ActiveSaleEvent.find(params[:parent_id]).children_sorted_by_position
|
10
|
+
respond_with(@active_sale_events)
|
11
|
+
end
|
4
12
|
|
5
13
|
def index
|
6
14
|
respond_with(@collection) do |format|
|
@@ -13,6 +21,11 @@ module Spree
|
|
13
21
|
redirect_to edit_object_url(@active_sale)
|
14
22
|
end
|
15
23
|
|
24
|
+
def eventables
|
25
|
+
search = params[:eventable_type].constantize.search(:name_cont => params[:name])
|
26
|
+
render :json => search.result.map(&:name)
|
27
|
+
end
|
28
|
+
|
16
29
|
protected
|
17
30
|
|
18
31
|
def collection
|
@@ -20,6 +33,23 @@ module Spree
|
|
20
33
|
@search = Spree::ActiveSale.includes(:active_sale_events).ransack(params[:q])
|
21
34
|
@collection = @search.result.page(params[:page]).per(Spree::ActiveSaleConfig[:admin_active_sales_per_page])
|
22
35
|
end
|
36
|
+
|
37
|
+
def load_active_sale_events
|
38
|
+
if @active_sale.new_record?
|
39
|
+
@active_sale_event = @active_sale.active_sale_events.build
|
40
|
+
else
|
41
|
+
@active_sale_event = @active_sale.root
|
42
|
+
@active_sale_events = @active_sale.active_sale_events
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def set_active_sale
|
47
|
+
return false if params[:active_sale_event].blank?
|
48
|
+
params[:active_sale] = params[:active_sale_event]
|
49
|
+
params[:active_sale].delete(:discount)
|
50
|
+
object_name = params[:active_sale]
|
51
|
+
get_eventable_object(object_name)
|
52
|
+
end
|
23
53
|
end
|
24
54
|
end
|
25
55
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spree
|
2
|
+
module Admin
|
3
|
+
ResourceController.class_eval do
|
4
|
+
|
5
|
+
private
|
6
|
+
def get_eventable_object(object_name = {})
|
7
|
+
unless object_name[:eventable_type].nil?
|
8
|
+
eventable = "#{object_name[:eventable_type]}".constantize.find_by_name(object_name[:eventable_name])
|
9
|
+
object_name.delete(:eventable_name)
|
10
|
+
unless eventable.nil?
|
11
|
+
object_name.merge!(:eventable_id => eventable.id, :permalink => eventable.permalink)
|
12
|
+
else
|
13
|
+
object_name.merge!(:eventable_id => nil)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Spree
|
2
2
|
HomeController.class_eval do
|
3
|
+
include Spree::ActiveSalesHelper
|
3
4
|
|
4
5
|
# List live and active sales on home page
|
5
6
|
def index
|
6
|
-
@sale_events =
|
7
|
+
@sale_events = all_active_sale_events
|
7
8
|
respond_with(@sale_events)
|
8
9
|
end
|
9
10
|
end
|
@@ -4,7 +4,7 @@ module Spree
|
|
4
4
|
def sale_event_timer(event = nil, layout = nil)
|
5
5
|
return I18n.t('spree.active_sale.event.can_not_be_nil') if (event == nil) || (event.class.name != "Spree::ActiveSaleEvent")
|
6
6
|
layout ||= '{dn} DAYS {hnn}{sep}{mnn}{sep}{snn}'
|
7
|
-
content_tag(:span, I18n.t('spree.active_sale.event.ending_message'), :class => 'sale_event_message') + " " + content_tag(:span, event.end_date.strftime('%Y-%m-%dT%H:%M:%S'), "data-timer" => event.end_date.strftime('%Y-%m-%dT%H:%M:%S'), "data-layout" => layout, :class => '
|
7
|
+
content_tag(:span, I18n.t('spree.active_sale.event.ending_message'), :class => 'sale_event_message') + " " + content_tag(:span, event.end_date.strftime('%Y-%m-%dT%H:%M:%S'), "data-timer" => event.end_date.strftime('%Y-%m-%dT%H:%M:%S'), "data-layout" => layout, :class => 'sale_event_message_timer')
|
8
8
|
end
|
9
9
|
|
10
10
|
def method_missing(method_name, *args, &block)
|
@@ -42,5 +42,10 @@ module Spree
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
|
+
|
46
|
+
def event_js_data(event)
|
47
|
+
return nil if event.blank?
|
48
|
+
Spree::ActiveSaleConfig[:name_with_event_position?] ? "#{event.name.gsub('"','\"')} - #{I18n.t('spree.active_sale.event.active_record.position')}: #{event.position}" : event.name.gsub('"','\"')
|
49
|
+
end
|
45
50
|
end
|
46
51
|
end
|
@@ -1,4 +1,46 @@
|
|
1
1
|
module Spree
|
2
2
|
module ActiveSalesHelper
|
3
|
+
# Getter to load all_sale_events
|
4
|
+
# Get the helper and load from cache when possible
|
5
|
+
def all_sale_events
|
6
|
+
@all_sale_events ||= Spree::SaleEvent.live_active
|
7
|
+
end
|
8
|
+
|
9
|
+
# Setter to set all_sale_events.
|
10
|
+
# Set the helper and load from parameter when possible
|
11
|
+
def all_sale_events=(sale_events)
|
12
|
+
return Array.new unless sale_events.class == Array
|
13
|
+
@all_sale_events = sale_events
|
14
|
+
end
|
15
|
+
|
16
|
+
# Get the helper and load from cache when possible
|
17
|
+
def all_active_sale_events
|
18
|
+
all_sale_events.select{ |e| e.type == "Spree::ActiveSaleEvent" && e.parent != nil }
|
19
|
+
end
|
20
|
+
|
21
|
+
# find sale event for the product or a taxon
|
22
|
+
# pass taxon or product object in the argument
|
23
|
+
def get_sale_event(object)
|
24
|
+
if ["Spree::Product", "Spree::Taxon"].include? object.class.name
|
25
|
+
active_sale_event = all_sale_events.detect{ |sale_event| (sale_event.eventable_type == object.class.name) && (sale_event.eventable_id == object.id) }
|
26
|
+
end
|
27
|
+
active_sale_event
|
28
|
+
end
|
29
|
+
|
30
|
+
# helper to load current_active_sale_event
|
31
|
+
def current_active_sale_event
|
32
|
+
all_sale_events.detect{ |sale_event| current_permalink?(sale_event.permalink) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def current_active_sale_event=(active_sale_event)
|
36
|
+
active_sale_event.nil? ? current_active_sale_event : active_sale_event
|
37
|
+
end
|
38
|
+
|
39
|
+
# check for current permalink using request
|
40
|
+
# split with "?" as there can be parameters
|
41
|
+
def current_permalink?(permalink = nil)
|
42
|
+
return false if permalink.blank?
|
43
|
+
request.path.split('/').reject(&:blank?).join('/') == permalink
|
44
|
+
end
|
3
45
|
end
|
4
46
|
end
|
@@ -1,22 +1,50 @@
|
|
1
1
|
# ActiveSales
|
2
|
-
# Active sales represent an entity for one sale at a time.
|
2
|
+
# Active sales represent an entity for one sale at a time, just like a taxonomy in spree.
|
3
3
|
# For example: 'January 2013' sale, which can have many sale events in it.
|
4
4
|
#
|
5
5
|
module Spree
|
6
6
|
class ActiveSale < Spree::SaleEvent
|
7
|
-
|
7
|
+
validates :name, :presence => true
|
8
|
+
validate :start_and_end_date_presence, :start_and_end_date_range
|
9
|
+
|
8
10
|
has_many :active_sale_events
|
11
|
+
has_one :root, :conditions => { :parent_id => nil }, :class_name => "Spree::ActiveSaleEvent",
|
12
|
+
:dependent => :destroy
|
9
13
|
|
10
|
-
|
14
|
+
after_save :set_root
|
11
15
|
|
12
|
-
|
16
|
+
default_scope :order => "#{self.table_name}.position"
|
13
17
|
|
14
18
|
def self.config(&block)
|
15
19
|
yield(Spree::ActiveSaleConfig)
|
16
20
|
end
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
private
|
23
|
+
def set_root
|
24
|
+
root_hash = self.serializable_hash
|
25
|
+
root_hash["active_sale_id"] = self.id
|
26
|
+
root_hash["type"] = "Spree::ActiveSaleEvent"
|
27
|
+
%w(id created_at updated_at lft rgt parent_id).each{ |column| root_hash.delete(column) }
|
28
|
+
if root
|
29
|
+
root.update_attributes(root_hash)
|
30
|
+
else
|
31
|
+
self.root = Spree::ActiveSaleEvent.create!(root_hash, :without_protection => true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def start_and_end_date_presence
|
36
|
+
errors.add(:start_date, I18n.t('spree.active_sale.event.validation.errors.date_empty')) if self.start_date.nil?
|
37
|
+
errors.add(:end_date, I18n.t('spree.active_sale.event.validation.errors.date_empty')) if self.end_date.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
# This should validate the start and end date range between
|
41
|
+
# its active_sale_events. To make sure that, root lives longer.
|
42
|
+
def start_and_end_date_range
|
43
|
+
unless self.start_date.nil? || self.end_date.nil?
|
44
|
+
oldest_start_date = self.active_sale_events.not_blank_and_sorted_by(:start_date).first
|
45
|
+
latest_end_date = self.active_sale_events.not_blank_and_sorted_by(:end_date).last
|
46
|
+
errors.add(:start_date, I18n.t('spree.active_sale.event.validation.errors.invalid_root_dates')) if (oldest_start_date.nil? && latest_end_date.nil?) ? false : (self.start_date > oldest_start_date || self.end_date < latest_end_date)
|
47
|
+
end
|
48
|
+
end
|
21
49
|
end
|
22
50
|
end
|
@@ -5,6 +5,7 @@ module Spree
|
|
5
5
|
preference :paginate_sales_for_admin?, :boolean, :default => false
|
6
6
|
preference :paginate_sale_events_for_user?, :boolean, :default => false
|
7
7
|
preference :paginate_sales_for_user?, :boolean, :default => false
|
8
|
+
preference :name_with_event_position?, :boolean, :default => false
|
8
9
|
preference :admin_active_sales_per_page, :integer, :default => 25
|
9
10
|
preference :active_sales_per_page, :integer, :default => 25
|
10
11
|
preference :admin_active_sale_events_per_page, :integer, :default => 25
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# EVENTS
|
2
2
|
# Events represent an entity for active sale in a flash sale/ daily deal.
|
3
|
-
# There can be many events for one sale.
|
3
|
+
# There can be many events for one sale, just like taxonomies in spree.
|
4
4
|
#
|
5
5
|
module Spree
|
6
6
|
class ActiveSaleEvent < Spree::SaleEvent
|
7
|
+
acts_as_nested_set :dependent => :destroy, :polymorphic => true
|
8
|
+
|
7
9
|
before_validation :update_permalink
|
8
10
|
after_save :update_parent_active_sales
|
9
11
|
|
@@ -11,11 +13,12 @@ module Spree
|
|
11
13
|
belongs_to :eventable, :polymorphic => true
|
12
14
|
belongs_to :active_sale
|
13
15
|
|
14
|
-
attr_accessible :description, :end_date, :eventable_id, :eventable_type, :is_active, :is_hidden, :is_permanent, :name, :permalink, :active_sale_id, :start_date, :eventable_name, :discount
|
16
|
+
attr_accessible :description, :end_date, :eventable_id, :eventable_type, :is_active, :is_hidden, :is_permanent, :name, :permalink, :active_sale_id, :start_date, :eventable_name, :discount, :parent_id
|
15
17
|
|
16
18
|
validates :name, :permalink, :eventable_id, :start_date, :end_date, :active_sale_id, :presence => true
|
17
19
|
validates :eventable_type, :presence => true, :uniqueness => { :scope => :eventable_id, :message => I18n.t('spree.active_sale.event.validation.errors.live_event') }, :if => :live?
|
18
|
-
|
20
|
+
|
21
|
+
scope :non_parents, lambda { where('parent_id IS NOT NULL') }
|
19
22
|
|
20
23
|
# Spree::ActiveSaleEvent.is_live? method
|
21
24
|
# should only/ always represents live and active events and not just live events.
|
@@ -33,10 +36,10 @@ module Spree
|
|
33
36
|
# This callback basically makes sure that parents for an event lives longer.
|
34
37
|
# Or at least parents live for the time when event is live.
|
35
38
|
def update_parent_active_sales
|
36
|
-
active_sale_events = self.
|
37
|
-
parents = self.
|
38
|
-
oldest_start_date = active_sale_events.
|
39
|
-
latest_end_date = active_sale_events.
|
39
|
+
active_sale_events = self.self_and_ancestors
|
40
|
+
parents = self.ancestors
|
41
|
+
oldest_start_date = active_sale_events.not_blank_and_sorted_by(:start_date).first
|
42
|
+
latest_end_date = active_sale_events.not_blank_and_sorted_by(:end_date).last
|
40
43
|
parents.each{ |parent|
|
41
44
|
parent.update_attributes(:start_date => oldest_start_date) if parent.start_date.nil? ? true : (parent.start_date > oldest_start_date)
|
42
45
|
parent.update_attributes(:end_date => latest_end_date) if parent.end_date.nil? ? true : (parent.end_date < latest_end_date)
|
@@ -54,5 +57,9 @@ module Spree
|
|
54
57
|
def eventable_image_available?
|
55
58
|
!!eventable.try(:image_available?)
|
56
59
|
end
|
60
|
+
|
61
|
+
def children_sorted_by_position
|
62
|
+
self.children.sort_by{ |child| child.position.nil? ? 0 : child.position }
|
63
|
+
end
|
57
64
|
end
|
58
65
|
end
|
@@ -1,14 +1,21 @@
|
|
1
1
|
Spree::Product.class_eval do
|
2
|
+
include Spree::ActiveSalesHelper
|
3
|
+
|
2
4
|
has_many :active_sale_events, :as => :eventable
|
3
5
|
|
4
6
|
# Find live and active taxons for a product.
|
5
7
|
def find_live_taxons
|
6
|
-
|
8
|
+
all_sale_events.select{ |sale_event| (sale_event.eventable_type == "Spree::Taxon") && (self.taxons.map(&:id).include?(sale_event.eventable_id)) }
|
9
|
+
end
|
10
|
+
|
11
|
+
# product.live_active_sale_event gets first active sale event which is live and active
|
12
|
+
def live_active_sale_event
|
13
|
+
get_sale_event(self)
|
7
14
|
end
|
8
15
|
|
9
16
|
# if there is at least one active sale event which is live and active.
|
10
17
|
def live?
|
11
|
-
!self.
|
18
|
+
!self.live_active_sale_event.nil? || !self.find_live_taxons.blank?
|
12
19
|
end
|
13
20
|
|
14
21
|
# Check if image is available for this.
|
@@ -20,45 +20,48 @@ module Spree
|
|
20
20
|
scope :starting_today, lambda { where(:start_date => zone_time..zone_time.end_of_day) }
|
21
21
|
scope :ending_today, lambda { where(:end_date => zone_time..zone_time.end_of_day) }
|
22
22
|
|
23
|
-
|
24
|
-
def validate_start_and_end_date
|
25
|
-
errors.add(:start_date, I18n.t('spree.active_sale.event.validation.errors.invalid_dates')) if invalid_dates?
|
26
|
-
end
|
23
|
+
validate :validate_start_and_end_date
|
27
24
|
|
28
25
|
def live?(moment=nil)
|
29
26
|
moment ||= object_zone_time
|
30
|
-
(self.start_date <= moment and self.end_date >= moment) or self.is_permanent? if
|
27
|
+
(self.start_date <= moment and self.end_date >= moment) or self.is_permanent? if start_and_end_dates_available?
|
31
28
|
end
|
32
29
|
|
33
30
|
def upcoming?
|
34
31
|
current_time = object_zone_time
|
35
|
-
(self.start_date >= current_time and self.end_date > self.start_date) if
|
32
|
+
(self.start_date >= current_time and self.end_date > self.start_date) if start_and_end_dates_available?
|
36
33
|
end
|
37
34
|
|
38
35
|
def past?
|
39
36
|
current_time = object_zone_time
|
40
|
-
(self.start_date < current_time and self.end_date > self.start_date and self.end_date < current_time) if
|
37
|
+
(self.start_date < current_time and self.end_date > self.start_date and self.end_date < current_time) if start_and_end_dates_available?
|
41
38
|
end
|
42
39
|
|
43
40
|
def live_and_active?(moment=nil)
|
44
41
|
self.live?(moment) and self.is_active?
|
45
42
|
end
|
46
43
|
|
47
|
-
def
|
44
|
+
def start_and_end_dates_available?
|
48
45
|
self.start_date and self.end_date
|
49
46
|
end
|
50
47
|
|
51
48
|
def invalid_dates?
|
52
|
-
self.
|
49
|
+
self.start_and_end_dates_available? and (self.start_date >= self.end_date)
|
53
50
|
end
|
54
51
|
|
52
|
+
# Class methods
|
55
53
|
class << self
|
56
|
-
# Class methods
|
57
54
|
def paginate(objects_per_page, options = {})
|
58
55
|
options = prepare_pagination(objects_per_page, options)
|
59
56
|
self.page(options[:page]).per(options[:per_page])
|
60
57
|
end
|
61
58
|
|
59
|
+
def not_blank_and_sorted_by(column)
|
60
|
+
return nil if column.blank?
|
61
|
+
column = column.to_sym
|
62
|
+
self.select(&column).map(&column).reject(&:blank?).sort
|
63
|
+
end
|
64
|
+
|
62
65
|
private
|
63
66
|
def valid_argument args
|
64
67
|
(args.first == nil || args.first == true)
|
@@ -82,5 +85,9 @@ module Spree
|
|
82
85
|
def object_zone_time
|
83
86
|
Time.zone.now
|
84
87
|
end
|
88
|
+
|
89
|
+
def validate_start_and_end_date
|
90
|
+
errors.add(:start_date, I18n.t('spree.active_sale.event.validation.errors.invalid_dates')) if invalid_dates?
|
91
|
+
end
|
85
92
|
end
|
86
93
|
end
|
@@ -1,9 +1,16 @@
|
|
1
1
|
Spree::Taxon.class_eval do
|
2
|
+
include Spree::ActiveSalesHelper
|
3
|
+
|
2
4
|
has_many :active_sale_events, :as => :eventable
|
3
5
|
|
6
|
+
# taxon.live_active_sale_event gets first active sale event which is live and active
|
7
|
+
def live_active_sale_event
|
8
|
+
get_sale_event(self)
|
9
|
+
end
|
10
|
+
|
4
11
|
# if there is at least one active sale event which is live and active.
|
5
12
|
def live?
|
6
|
-
!self.
|
13
|
+
!self.live_active_sale_event.nil?
|
7
14
|
end
|
8
15
|
|
9
16
|
def image_available?
|
@@ -1,7 +1,21 @@
|
|
1
|
+
# This decorator is created by keeping that in mind
|
2
|
+
# what is when a user may need or want a sale event on
|
3
|
+
# an SKU or a Variant level. Variant needs to reflect the
|
4
|
+
# same on admin dashboard for selection from dropdrown in
|
5
|
+
# edit and new view pages.
|
6
|
+
#
|
7
|
+
|
1
8
|
Spree::Variant.class_eval do
|
9
|
+
include Spree::ActiveSalesHelper
|
10
|
+
|
2
11
|
has_many :active_sale_events, :as => :eventable
|
3
12
|
|
13
|
+
# variant.live_active_sale_event gets first active sale event which is live and active
|
14
|
+
def live_active_sale_event
|
15
|
+
get_sale_event(self)
|
16
|
+
end
|
17
|
+
|
4
18
|
def live?
|
5
|
-
!self.
|
19
|
+
!self.live_active_sale_event.nil? || self.product.live?
|
6
20
|
end
|
7
21
|
end
|
@@ -2,96 +2,96 @@
|
|
2
2
|
<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @active_sale_event } %>
|
3
3
|
<% end %>
|
4
4
|
|
5
|
-
<%= form_for [:admin, @active_sale, @active_sale_event], :html => { :id => 'admin_active_sale_event', :multipart => true } do |f| %>
|
6
5
|
<fieldset data-hook="admin_active_sale_event_form_fields">
|
7
6
|
|
7
|
+
<%= form.hidden_field :parent_id, :value => @parent_id %>
|
8
|
+
|
8
9
|
<div class="clearfix">
|
9
10
|
<div class="left eight columns alpha" data-hook="admin_active_sale_event_form_left">
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
<%= form.field_container :name do %>
|
12
|
+
<%= form.label :name, raw(t('spree.active_sale.event.active_record.name') + content_tag(:span, ' *', :class => 'required')) %>
|
13
|
+
<%= form.text_field :name, :class => 'fullwidth' %>
|
14
|
+
<%= form.error_message_on :name %>
|
15
|
+
<% end %>
|
16
|
+
<%= form.field_container :description do %>
|
17
|
+
<%= form.label :description, t('spree.active_sale.event.active_record.description') %>
|
18
|
+
<%= form.text_area :description, {:cols => 60, :rows => 10, :class => 'fullwidth'} %>
|
19
|
+
<%= form.error_message_on :description %>
|
20
|
+
<% end %>
|
20
21
|
</div>
|
21
22
|
|
22
23
|
<div class="right eight columns omega" data-hook="admin_active_sale_event_form_right">
|
23
24
|
<div class="row">
|
24
25
|
<div class="alpha four columns">
|
25
|
-
|
26
|
-
|
27
|
-
<%=
|
28
|
-
<%= f.error_message_on :start_date %>
|
26
|
+
<%= form.field_container :start_date do %>
|
27
|
+
<%= form.label :start_date, t('spree.active_sale.event.active_record.start_date') %>
|
28
|
+
<%= form.error_message_on :start_date %>
|
29
29
|
<% if @active_sale_event.start_date? %>
|
30
30
|
<% start_date = l(@active_sale_event.start_date, :format => t('spree.active_sale.event.datetimepicker.format')) %>
|
31
31
|
<% else %>
|
32
32
|
<% start_date = l(Time.zone.now, :format => t('spree.active_sale.event.datetimepicker.format')) %>
|
33
33
|
<% end %>
|
34
|
-
<%=
|
34
|
+
<%= form.text_field :start_date, :value => start_date, :class => 'timepicker' %>
|
35
35
|
<% end %>
|
36
36
|
</div>
|
37
37
|
|
38
38
|
<div class="omega four columns">
|
39
|
-
<%=
|
40
|
-
<%=
|
41
|
-
<%=
|
39
|
+
<%= form.field_container :end_date do %>
|
40
|
+
<%= form.label :end_date, t('spree.active_sale.event.active_record.end_date') %>
|
41
|
+
<%= form.error_message_on :end_date %>
|
42
42
|
<% end_date = l((@active_sale_event.end_date? ? @active_sale_event.end_date : Time.zone.now+1.day), :format => t('spree.active_sale.event.datetimepicker.format')) %>
|
43
|
-
<%=
|
43
|
+
<%= form.text_field :end_date, :value => end_date, :class => 'timepicker' %>
|
44
44
|
<% end %>
|
45
45
|
</div>
|
46
46
|
</div>
|
47
47
|
<div class="row">
|
48
48
|
<div class="alpha four columns">
|
49
|
-
<%=
|
49
|
+
<%= form.label :eventable, t('spree.active_sale.event.active_record.eventable_type', :default => :evenetable) %>
|
50
50
|
<p class='hint'><%= t('spree.active_sale.event.eventable_hint') %></p>
|
51
|
-
<%=
|
52
|
-
<%=
|
51
|
+
<%= form.select :eventable_type, [["Product","Spree::Product"], ["Taxon","Spree::Taxon"]], { :include_blank => false }, { :class => 'select2' } %>
|
52
|
+
<%= form.error_message_on :eventable %>
|
53
53
|
</div>
|
54
54
|
|
55
55
|
<div class="omega four columns">
|
56
|
-
<%=
|
56
|
+
<%= form.label :eventable_name, t('spree.active_sale.event.active_record.eventable_name', :default => :eventable_name) %>
|
57
57
|
<p class='hint'><%= t('spree.active_sale.event.eventable_name_hint') %></p>
|
58
|
-
<%=
|
59
|
-
<%=
|
58
|
+
<%= form.error_message_on :eventable_name %>
|
59
|
+
<%= form.text_field :eventable_name, :class => 'autocomplete', :data => { :auto_complete_url => eventables_admin_active_sales_url } %>
|
60
60
|
</div>
|
61
61
|
</div>
|
62
62
|
<div class="row">
|
63
63
|
<div class="alpha four columns clearfix">
|
64
|
-
<%=
|
64
|
+
<%= form.field_container :is_active, :class => ['checkbox'] do %>
|
65
65
|
<label>
|
66
|
-
<%=
|
66
|
+
<%= form.check_box :is_active %>
|
67
67
|
<%= t('spree.active_sale.event.active_record.is_active') %>
|
68
|
-
<%=
|
68
|
+
<%= form.error_message_on :is_active %>
|
69
69
|
</label>
|
70
70
|
<% end %>
|
71
71
|
|
72
|
-
<%=
|
72
|
+
<%= form.field_container :is_hidden, :class => ['checkbox'] do %>
|
73
73
|
<label>
|
74
|
-
<%=
|
74
|
+
<%= form.check_box :is_hidden %>
|
75
75
|
<%= t('spree.active_sale.event.active_record.is_hidden') %>
|
76
|
-
<%=
|
76
|
+
<%= form.error_message_on :is_hidden %>
|
77
77
|
</label>
|
78
78
|
<% end %>
|
79
79
|
|
80
|
-
<%=
|
80
|
+
<%= form.field_container :is_permanent, :class => ['checkbox'] do %>
|
81
81
|
<label>
|
82
|
-
<%=
|
82
|
+
<%= form.check_box :is_permanent %>
|
83
83
|
<%= t('spree.active_sale.event.active_record.is_permanent') %>
|
84
|
-
<%=
|
84
|
+
<%= form.error_message_on :is_permanent %>
|
85
85
|
</label>
|
86
86
|
<% end %>
|
87
87
|
</div>
|
88
88
|
|
89
89
|
<div class="omega four columns">
|
90
|
-
<%=
|
91
|
-
<%=
|
90
|
+
<%= form.field_container :discount do %>
|
91
|
+
<%= form.label :discount, t('spree.active_sale.event.active_record.discount', :default => :discount) %>
|
92
92
|
<p class='hint'><%= t('spree.active_sale.event.discount_hint') %></p>
|
93
|
-
<%=
|
94
|
-
<%=
|
93
|
+
<%= form.error_message_on :discount %>
|
94
|
+
<%= form.text_field :discount, :size => 2, :maxlength => 2 %>
|
95
95
|
<% end %>
|
96
96
|
</div>
|
97
97
|
</div>
|
@@ -116,12 +116,11 @@
|
|
116
116
|
<% end %>
|
117
117
|
</p>
|
118
118
|
</fieldset>
|
119
|
-
<% end %>
|
120
119
|
|
121
120
|
<%= javascript_tag do -%>
|
122
121
|
var properties = "<%= raw(@properties.to_json) %>";
|
123
122
|
|
124
|
-
$("#admin_active_sale_event input.autocomplete").
|
123
|
+
$("#admin_active_sale_event input.autocomplete").on("keydown", function(){
|
125
124
|
var eventable_type = $('#active_sale_event_eventable_type :selected').val();
|
126
125
|
var eventable_name = $('#active_sale_event_eventable_name').val();
|
127
126
|
var url = $(this).data('auto-complete-url')
|
@@ -4,14 +4,14 @@
|
|
4
4
|
|
5
5
|
<% content_for :page_actions do %>
|
6
6
|
<li>
|
7
|
-
<%= button_link_to t('spree.active_sale.
|
8
|
-
<%= button_link_to t('spree.active_sale.event.link.new'), new_object_url, :icon => 'icon-plus', :id => 'new_admin_active_sale_event_link' %>
|
9
|
-
<%= button_link_to t('spree.active_sale.link.edit'), [:edit, :admin, @active_sale], :icon => 'icon-edit', :id => 'admin_active_sale_events_link' %>
|
7
|
+
<%= button_link_to t('spree.active_sale.link.edit'), [:edit, :admin, @active_sale], :icon => 'icon-arrow-left', :id => 'admin_active_sales_link' %>
|
10
8
|
</li>
|
11
9
|
<% end %>
|
12
10
|
|
13
11
|
<div data-hook="admin_active_sale_event_edit_form">
|
14
12
|
<div id="active-sale-event-form-wrapper">
|
15
|
-
<%=
|
13
|
+
<%= form_for [:admin, @active_sale, @active_sale_event], :html => { :id => 'admin_active_sale_event', :multipart => true } do |form| %>
|
14
|
+
<%= render :partial => 'form', :locals => { :form => form } %>
|
15
|
+
<% end %>
|
16
16
|
</div>
|
17
17
|
</div>
|
@@ -1,12 +1 @@
|
|
1
|
-
|
2
|
-
<%= @active_sale.name %> > <%= t('spree.active_sale.event.title.list') %>
|
3
|
-
<% end %>
|
4
|
-
|
5
|
-
<% content_for :page_actions do %>
|
6
|
-
<li>
|
7
|
-
<%= button_link_to t('spree.active_sale.link.edit'), [:admin, @active_sale], :icon => 'icon-arrow-left', :id => 'admin_active_sale_events_link' %>
|
8
|
-
<%= button_link_to t('spree.active_sale.event.link.new'), new_object_url, :icon => 'icon-plus', :id => 'admin_new_active_sale_event_link' %>
|
9
|
-
</li>
|
10
|
-
<% end %>
|
11
|
-
|
12
|
-
<%= render :partial => "spree/admin/shared/list_events", :locals => { :active_sale_events => @active_sale_events } %>
|
1
|
+
<%= render :partial => 'spree/admin/shared/list_events', :locals => { :active_sale => @active_sale, :active_sale_events => @active_sale_events } %>
|
@@ -10,6 +10,8 @@
|
|
10
10
|
|
11
11
|
<div data-hook="admin_active_sale_event_edit_form">
|
12
12
|
<div id="active-sale-event-form-wrapper">
|
13
|
-
<%=
|
13
|
+
<%= form_for [:admin, @active_sale, @active_sale_event], :html => { :id => 'admin_active_sale_event', :multipart => true } do |form| %>
|
14
|
+
<%= render :partial => 'form', :locals => { :form => form } %>
|
15
|
+
<% end %>
|
14
16
|
</div>
|
15
17
|
</div>
|
@@ -1,17 +1 @@
|
|
1
|
-
|
2
|
-
<%= t('spree.active_sale.title.edit') %>
|
3
|
-
<% end %>
|
4
|
-
|
5
|
-
<% content_for :page_actions do %>
|
6
|
-
<li>
|
7
|
-
<% @event = Spree::ActiveSaleEvent.new %>
|
8
|
-
<%= button_link_to t('spree.active_sale.link.back'), collection_url, :icon => 'icon-arrow-left', :id => 'admin_new_active_sale_link' %>
|
9
|
-
<%= button_link_to t('spree.active_sale.event.link.new'), [:new, :admin, @active_sale, :active_sale_event], :icon => 'icon-plus', :id => 'admin_new_active_sale_link' %>
|
10
|
-
</li>
|
11
|
-
<% end %>
|
12
|
-
|
13
|
-
<div data-hook="admin_active_sale_edit_form">
|
14
|
-
<div id="active-sale-form-wrapper">
|
15
|
-
<%= render :partial => 'form' %>
|
16
|
-
</div>
|
17
|
-
</div>
|
1
|
+
<%= render :partial => 'spree/admin/shared/list_events', :locals => { :active_sale => @active_sale, :active_sale_events => @active_sale_events } %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
[<% @active_sale_events.each_with_index do |t,i| %>
|
2
|
+
{ "attr" :
|
3
|
+
{ "id" : "<%= t.id %>", "parent_id" : "<%= t.parent_id %>" },
|
4
|
+
"data" : "<%= raw(event_js_data(t)) %>"
|
5
|
+
<% unless t.children.empty? %>
|
6
|
+
,"state" : "closed"
|
7
|
+
<% end %>
|
8
|
+
}<%= "," if i < (@active_sale_events.size - 1) %>
|
9
|
+
<% end %>]
|
@@ -10,26 +10,27 @@
|
|
10
10
|
|
11
11
|
<div id="new_active_sale" data-hook></div>
|
12
12
|
|
13
|
-
<table class="index" id=
|
13
|
+
<table class="index sortable" id='listing_active_sales' data-hook data-sortable-link="<%= update_positions_admin_active_sales_url %>">
|
14
14
|
<colgroup>
|
15
15
|
<col style="width: 85%">
|
16
16
|
<col style="width: 15%">
|
17
17
|
</colgroup>
|
18
18
|
<thead>
|
19
|
-
<tr data-hook="
|
20
|
-
<th><%=
|
21
|
-
<th
|
19
|
+
<tr data-hook="active_sales_header">
|
20
|
+
<th><%= t(:name) %></th>
|
21
|
+
<th class="actions"></th>
|
22
22
|
</tr>
|
23
23
|
</thead>
|
24
24
|
<tbody>
|
25
25
|
<% @active_sales.each do |active_sale| %>
|
26
|
-
<tr id="<%= spree_dom_id active_sale %>" data-hook="
|
27
|
-
<td
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
<tr id="<%= spree_dom_id active_sale %>" data-hook="active_sales_row" class="<%= cycle('odd', 'even')%>">
|
27
|
+
<td>
|
28
|
+
<span class="handle"></span>
|
29
|
+
<%= active_sale.name %>
|
30
|
+
</td>
|
31
|
+
<td class="actions">
|
32
|
+
<%= link_to_edit active_sale.id, :no_text => true %>
|
33
|
+
<%= link_to_delete active_sale, :no_text => true %>
|
33
34
|
</td>
|
34
35
|
</tr>
|
35
36
|
<% end %>
|
@@ -10,6 +10,15 @@
|
|
10
10
|
|
11
11
|
<div data-hook="admin_active_sale_new_form">
|
12
12
|
<div id="active-sale-form-wrapper">
|
13
|
-
|
13
|
+
|
14
|
+
<% if @active_sale.try(:errors).present? %>
|
15
|
+
<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @active_sale } %>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<%= form_for [:admin, @active_sale], :html => { :id => 'admin_active_sale_event' } do |form| %>
|
19
|
+
<%= fields_for @active_sale_event do |event_form| %>
|
20
|
+
<%= render :partial => 'spree/admin/active_sale_events/form', :locals => { :form => event_form } %>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
14
23
|
</div>
|
15
24
|
</div>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<% content_for :head do %>
|
2
|
+
<%= javascript_tag "var active_sale_id = #{@active_sale.id};
|
3
|
+
var loading = '#{escape_javascript t(:loading)}';
|
4
|
+
var new_active_sale_event = '#{escape_javascript t(:new_active_sale_event)}';
|
5
|
+
var server_error = '#{escape_javascript t(:server_error)}';
|
6
|
+
var active_sale_tree_error = '#{escape_javascript t(:active_sale_tree_error)}';"
|
7
|
+
%>
|
8
|
+
<% end %>
|
@@ -1,32 +1,53 @@
|
|
1
|
+
<%= render :partial => 'spree/admin/shared/js_head' %>
|
1
2
|
|
2
|
-
|
3
|
+
<% content_for :page_title do %>
|
4
|
+
<%= t('spree.active_sale.title.edit') %> > <%= @active_sale.name %>
|
5
|
+
<% end %>
|
3
6
|
|
4
|
-
|
5
|
-
<
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
<th><%= t('spree.active_sale.event.active_record.end_date') %></th>
|
10
|
-
<th><%= t('spree.active_sale.event.active_record.is_live') %></th>
|
11
|
-
<th data-hook="admin_active_sale_events_index_header_actions" class="actions"></th>
|
12
|
-
</tr>
|
13
|
-
</thead>
|
14
|
-
<tbody>
|
15
|
-
<% @active_sale_events.each do |event| %>
|
16
|
-
<tr id="<%= spree_dom_id event %>" data-hook="admin_active_sales_index_rows" class="<%= cycle('odd', 'even')%>">
|
17
|
-
<td class='active_sale_name'><%= link_to event.name, [:admin, @active_sale, event] %></td>
|
18
|
-
<td class='active_sale_start_date'><%= event.start_date %></td>
|
19
|
-
<td class='active_sale_end_date'><%= event.end_date %></td>
|
20
|
-
<td class='active_sale_is_live'><%= event.live? ? t('spree.active_sale.event.boolean.yes') : t('spree.active_sale.event.boolean.no') %></td>
|
7
|
+
<% content_for :page_actions do %>
|
8
|
+
<li>
|
9
|
+
<%= button_link_to t('spree.active_sale.link.back'), collection_url, :icon => 'icon-arrow-left', :id => 'admin_new_active_sale_link' %>
|
10
|
+
</li>
|
11
|
+
<% end %>
|
21
12
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
</
|
32
|
-
|
13
|
+
<div id="ajax_error" class="errorExplanation" style="display:none;"></div>
|
14
|
+
|
15
|
+
<fieldset class="no-border-top">
|
16
|
+
<div>
|
17
|
+
<%= label_tag nil, t(:tree) %><br />
|
18
|
+
<div id="active_sale_tree" class="tree" data-url="<%= admin_active_sale_active_sale_events_path @active_sale %>"></div>
|
19
|
+
</div>
|
20
|
+
<div id="progress" style="display:none;">
|
21
|
+
<%= image_tag 'spinner.gif', :title => 'Spinner', :style => "vertical-align:bottom;" %> <%= t(:updating) %>..
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<p class='hint info'>
|
25
|
+
<%= t('spree.active_sale.event.active_sale_tree_hint') %>
|
26
|
+
</p>
|
27
|
+
|
28
|
+
<br>
|
29
|
+
</fieldset>
|
30
|
+
|
31
|
+
<% content_for :head do %>
|
32
|
+
<%= javascript_tag do -%>
|
33
|
+
var initial = [
|
34
|
+
{ "attr" :
|
35
|
+
{ "id" : "<%= @active_sale.root.id %>", "rel" : "root", "parent_id" : "nil" },
|
36
|
+
"data" : "<%= escape_javascript(raw(@active_sale.root.name)) %>",
|
37
|
+
"state" : "open",
|
38
|
+
"children" : [
|
39
|
+
<% @active_sale.root.children_sorted_by_position.each_with_index do |event,i| %>
|
40
|
+
{
|
41
|
+
"attr" :
|
42
|
+
{ "id" : "<%= event.id %>", "parent_id" : "<%= event.parent_id %>" },
|
43
|
+
"data" : "<%= escape_javascript(raw(event_js_data(event))) %>"
|
44
|
+
<% unless event.children.empty? %>
|
45
|
+
,"state" : "closed"
|
46
|
+
<% end %>
|
47
|
+
}<%= ',' if i < (@active_sale.root.children.size - 1) %>
|
48
|
+
<% end %>
|
49
|
+
]
|
50
|
+
}
|
51
|
+
];
|
52
|
+
<% end -%>
|
53
|
+
<% end %>
|
@@ -7,6 +7,7 @@ en:
|
|
7
7
|
active_record:
|
8
8
|
name: "Sale name"
|
9
9
|
event:
|
10
|
+
active_sale_tree_hint: "Right click on any row in the tree to access the menu for adding, deleting or sorting products in a sale. Drag and drop to change their positions."
|
10
11
|
active_record:
|
11
12
|
description: "Event Description"
|
12
13
|
is_active: "Active?"
|
@@ -20,6 +21,7 @@ en:
|
|
20
21
|
eventable_name: "Add the name to add type in event"
|
21
22
|
eventable_type: "Add a type for event"
|
22
23
|
permalink: "Type the name or permalink"
|
24
|
+
position: "Position"
|
23
25
|
boolean:
|
24
26
|
yes: "Yes"
|
25
27
|
no: "No"
|
@@ -57,8 +59,11 @@ en:
|
|
57
59
|
list: "Listing events"
|
58
60
|
validation:
|
59
61
|
errors:
|
62
|
+
date_empty: "can't be left empty."
|
60
63
|
invalid_dates: "can not be greater than or equal to the end date."
|
64
|
+
invalid_root_dates: "and end date should be in between it's sub sales' start and end dates range."
|
61
65
|
live_event: "already running and live."
|
66
|
+
parent_id_cant_be_nil: "Parent can not be null"
|
62
67
|
events_not_found: "There are no sales available at this moment. Try later?"
|
63
68
|
link:
|
64
69
|
new: "New active sale"
|
@@ -23,8 +23,8 @@ es:
|
|
23
23
|
boolean:
|
24
24
|
yes: "Sí"
|
25
25
|
no: "No"
|
26
|
-
can_not_be_nil: "
|
27
|
-
create_if_no_record: "
|
26
|
+
can_not_be_nil: "El argumento no puede ser nulo y debe ser una instancia de la clase Spree::ActiveSaleEvent"
|
27
|
+
create_if_no_record: "Todavía no tienes creada ningún evento, ¿lo creamos ya?"
|
28
28
|
datetimepicker:
|
29
29
|
format: ! '%d/%m/%Y %H:%M:%S %z'
|
30
30
|
js_format: 'HH:mm:ss z'
|
data/config/routes.rb
CHANGED
@@ -2,8 +2,17 @@ Spree::Core::Engine.routes.draw do
|
|
2
2
|
# Add this extension's routes here
|
3
3
|
namespace :admin do
|
4
4
|
resources :active_sales do
|
5
|
+
collection do
|
6
|
+
get :eventables
|
7
|
+
post :update_positions
|
8
|
+
end
|
9
|
+
member do
|
10
|
+
get :get_children
|
11
|
+
end
|
5
12
|
resources :active_sale_events do
|
6
|
-
|
13
|
+
member do
|
14
|
+
put :update_events
|
15
|
+
end
|
7
16
|
resources :sale_images do
|
8
17
|
collection do
|
9
18
|
post :update_positions
|
@@ -6,7 +6,7 @@ module SpreeActiveSale
|
|
6
6
|
|
7
7
|
config.autoload_paths += %W(#{config.root}/lib)
|
8
8
|
|
9
|
-
initializer "spree_active_sale.environment", :
|
9
|
+
initializer "spree_active_sale.environment", :before => "spree.environment" do |app|
|
10
10
|
Spree::ActiveSaleConfig = Spree::ActiveSaleConfiguration.new
|
11
11
|
%w(ActionController::Base Spree::BaseController).each { |controller| controller.constantize.send(:helper, Spree::ActiveSaleEventsHelper) }
|
12
12
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spree_active_sale
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: spree_core
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.3.
|
21
|
+
version: 1.3.2
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.3.
|
29
|
+
version: 1.3.2
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: capybara
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,17 +112,17 @@ dependencies:
|
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
113
113
|
none: false
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - '='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: 3.0.2
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
none: false
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - '='
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
125
|
+
version: 3.0.2
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: sass-rails
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -181,14 +181,15 @@ files:
|
|
181
181
|
- app/models/spree/active_sale_event.rb
|
182
182
|
- app/models/spree/sale_event.rb
|
183
183
|
- app/views/spree/home/index.html.erb
|
184
|
-
- app/views/spree/admin/active_sales/_form.html.erb
|
185
184
|
- app/views/spree/admin/active_sales/new.html.erb
|
185
|
+
- app/views/spree/admin/active_sales/get_children.json.erb
|
186
186
|
- app/views/spree/admin/active_sales/index.html.erb
|
187
187
|
- app/views/spree/admin/active_sales/edit.html.erb
|
188
188
|
- app/views/spree/admin/active_sale_events/_form.html.erb
|
189
189
|
- app/views/spree/admin/active_sale_events/new.html.erb
|
190
190
|
- app/views/spree/admin/active_sale_events/index.html.erb
|
191
191
|
- app/views/spree/admin/active_sale_events/edit.html.erb
|
192
|
+
- app/views/spree/admin/shared/_js_head.html.erb
|
192
193
|
- app/views/spree/admin/shared/_translations.html.erb
|
193
194
|
- app/views/spree/admin/shared/_list_events.html.erb
|
194
195
|
- app/views/spree/admin/shared/_sale_images.html.erb
|
@@ -197,6 +198,7 @@ files:
|
|
197
198
|
- app/views/spree/admin/sale_images/edit.html.erb
|
198
199
|
- app/views/spree/shared/_sale_events.html.erb
|
199
200
|
- app/controllers/spree/admin/sale_images_controller.rb
|
201
|
+
- app/controllers/spree/admin/resource_controller_decorator.rb
|
200
202
|
- app/controllers/spree/admin/active_sales_controller.rb
|
201
203
|
- app/controllers/spree/admin/active_sale_events_controller.rb
|
202
204
|
- app/controllers/spree/home_controller_decorator.rb
|
@@ -205,6 +207,7 @@ files:
|
|
205
207
|
- app/controllers/spree/products_controller_decorator.rb
|
206
208
|
- app/controllers/spree/store_controller_decorator.rb
|
207
209
|
- app/controllers/spree/taxons_controller_decorator.rb
|
210
|
+
- app/helpers/spree/base_helper_decorator.rb
|
208
211
|
- app/helpers/spree/active_sale_events_helper.rb
|
209
212
|
- app/helpers/spree/active_sales_helper.rb
|
210
213
|
- app/overrides/admin_active_sales_tab.rb
|
@@ -241,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
241
244
|
version: '0'
|
242
245
|
segments:
|
243
246
|
- 0
|
244
|
-
hash: -
|
247
|
+
hash: -430475808815195775
|
245
248
|
requirements:
|
246
249
|
- none
|
247
250
|
rubyforge_project:
|
@@ -1,35 +0,0 @@
|
|
1
|
-
<% if @active_sale.try(:errors).present? %>
|
2
|
-
<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @active_sale } %>
|
3
|
-
<% end %>
|
4
|
-
|
5
|
-
<%= form_for [:admin, @active_sale] do |f| %>
|
6
|
-
|
7
|
-
<fieldset data-hook="new_active_sale">
|
8
|
-
|
9
|
-
<%= f.field_container :name do %>
|
10
|
-
<%= f.label :name, t(:name) %> <span class="required">*</span><br />
|
11
|
-
<%= f.text_field :name, :class => 'fullwidth title' %>
|
12
|
-
<%= f.error_message_on :name %>
|
13
|
-
<% end %>
|
14
|
-
|
15
|
-
<p class="form-buttons" data-hook="admin_active_sale_form_buttons">
|
16
|
-
<% if @active_sale.new_record? %>
|
17
|
-
<%= render :partial => 'spree/admin/shared/new_resource_links' %>
|
18
|
-
<% else %>
|
19
|
-
<%= render :partial => 'spree/admin/shared/edit_resource_links' %>
|
20
|
-
<% end %>
|
21
|
-
</p>
|
22
|
-
|
23
|
-
</fieldset>
|
24
|
-
<% end %>
|
25
|
-
|
26
|
-
<% unless @active_sale.new_record? %>
|
27
|
-
<% if @active_sale.active_sale_events.blank? %>
|
28
|
-
<% @active_sale_event = @active_sale.active_sale_events.build %>
|
29
|
-
<h4><%= t('spree.active_sale.event.create_if_no_record') %></h4>
|
30
|
-
<%= render :partial => "spree/admin/active_sale_events/form", :locals => { :events => @active_sale_event } %>
|
31
|
-
<% else %>
|
32
|
-
<% @active_sale_events = @active_sale.active_sale_events %>
|
33
|
-
<%= render :partial => "spree/admin/shared/list_events", :locals => { :events => @active_sale_events } %>
|
34
|
-
<% end %>
|
35
|
-
<% end %>
|