spree_core 1.0.0.rc3 → 1.0.0.rc4
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/images/admin/payment_banner.png +0 -0
- data/app/assets/javascripts/admin/admin.js.erb +16 -5
- data/app/assets/javascripts/admin/spree_core.js +0 -1
- data/app/assets/javascripts/store/spree_core.js +0 -1
- data/app/assets/stylesheets/admin/admin.css.erb +57 -3
- data/app/assets/stylesheets/store/screen.css.scss +72 -29
- data/app/assets/stylesheets/store/spree_core.css +5 -4
- data/app/controllers/spree/admin/tax_categories_controller.rb +13 -0
- data/app/controllers/spree/admin/users_controller.rb +16 -0
- data/app/controllers/spree/products_controller.rb +1 -1
- data/app/helpers/spree/admin/navigation_helper.rb +3 -1
- data/app/models/spree/payment_method.rb +2 -0
- data/app/models/spree/preferences/preferable.rb +32 -1
- data/app/models/spree/preferences/preferable_class_methods.rb +21 -4
- data/app/models/spree/product.rb +4 -3
- data/app/models/spree/tax_category.rb +7 -1
- data/app/models/spree/tax_rate.rb +4 -1
- data/app/models/spree/user.rb +2 -0
- data/app/views/spree/admin/banners/_gateway.html.erb +14 -0
- data/app/views/spree/admin/images/index.html.erb +4 -4
- data/app/views/spree/admin/option_types/index.html.erb +2 -2
- data/app/views/spree/admin/payment_methods/index.html.erb +2 -0
- data/app/views/spree/admin/variants/index.html.erb +2 -2
- data/app/views/spree/orders/_line_item.html.erb +4 -4
- data/app/views/spree/shared/_order_details.html.erb +8 -9
- data/config/locales/en.yml +4 -0
- data/config/routes.rb +6 -3
- data/db/migrate/20120203153759_add_deleted_at_to_tax_category.rb +5 -0
- data/lib/spree/core/middleware/seo_assist.rb +1 -1
- data/lib/spree/core/user_banners.rb +25 -0
- data/lib/spree/core/version.rb +1 -1
- data/vendor/assets/images/jquery.formalize/button.png +0 -0
- data/vendor/assets/images/jquery.formalize/select_arrow.gif +0 -0
- data/vendor/assets/stylesheets/html5reset.css +177 -0
- data/vendor/assets/stylesheets/{jquery.formalize.css → jquery.formalize.css.erb} +3 -3
- data/{app/assets/stylesheets/store/base.css → vendor/assets/stylesheets/skeleton.css} +14 -159
- metadata +37 -31
- data/app/assets/javascripts/store/helpers.js.erb +0 -2
Binary file
|
@@ -1,4 +1,3 @@
|
|
1
|
-
//= require store/helpers
|
2
1
|
//= require_self
|
3
2
|
|
4
3
|
/**
|
@@ -17,6 +16,20 @@ $(document).ajaxStop(function(){
|
|
17
16
|
|
18
17
|
$.fn.visible = function(cond) { this[cond ? 'show' : 'hide' ]() };
|
19
18
|
|
19
|
+
show_flash_error = function(message) {
|
20
|
+
error_div = $('.flash.error');
|
21
|
+
if (error_div.length > 0) {
|
22
|
+
error_div.html(message);
|
23
|
+
error_div.show();
|
24
|
+
} else {
|
25
|
+
if ($("#content .toolbar").length > 0) {
|
26
|
+
$("#content .toolbar").before('<div class="flash error">' + message + '</div>');
|
27
|
+
} else {
|
28
|
+
$("#content h1").before('<div class="flash error">' + message + '</div>');
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
20
33
|
// Apply to individual radio button that makes another element visible when checked
|
21
34
|
$.fn.radioControlsVisibilityOfElement = function(dependentElementSelector){
|
22
35
|
if(!this.get(0)){ return }
|
@@ -227,19 +240,17 @@ $(document).ready(function(){
|
|
227
240
|
update: function(event, ui) {
|
228
241
|
$("#progress").show();
|
229
242
|
positions = {};
|
230
|
-
type = '';
|
231
243
|
$.each($('table.sortable tbody tr'), function(position, obj){
|
232
244
|
reg = /spree_(\w+_?)+_(\d+)/;
|
233
245
|
parts = reg.exec($(obj).attr('id'));
|
234
246
|
if (parts) {
|
235
247
|
positions['positions['+parts[2]+']'] = position;
|
236
|
-
type = parts[1];
|
237
248
|
}
|
238
249
|
});
|
239
250
|
$.ajax({
|
240
251
|
type: 'POST',
|
241
252
|
dataType: 'script',
|
242
|
-
url:
|
253
|
+
url: $(ui.item).closest("table.sortable").data("sortable-link"),
|
243
254
|
data: positions,
|
244
255
|
success: function(data){ $("#progress").hide(); }
|
245
256
|
});
|
@@ -250,7 +261,7 @@ $(document).ready(function(){
|
|
250
261
|
});
|
251
262
|
|
252
263
|
jQuery(document).ready(function() {
|
253
|
-
$('
|
264
|
+
$('a.dismiss').click(function() {
|
254
265
|
$(this).parent().fadeOut();
|
255
266
|
});
|
256
267
|
});
|
@@ -616,17 +616,71 @@ span.handle{
|
|
616
616
|
font-size: 0.8em;
|
617
617
|
}
|
618
618
|
.alert.release {
|
619
|
-
background: #ccddff
|
619
|
+
background-color: #ccddff;
|
620
620
|
color: #556699;
|
621
621
|
border: 1px solid #99aacc;
|
622
622
|
}
|
623
623
|
.alert.security {
|
624
|
-
background: #f4b4b4
|
624
|
+
background-color: #f4b4b4;
|
625
625
|
color: #000000;
|
626
626
|
border: 1px solid #e75b5b;
|
627
627
|
}
|
628
628
|
.alert.news {
|
629
|
-
background: #ccffd4
|
629
|
+
background-color: #ccffd4;
|
630
630
|
color: #000000;
|
631
631
|
border: 1px solid #66ff7e;
|
632
632
|
}
|
633
|
+
|
634
|
+
/* Spree analytics preview buttons */
|
635
|
+
.analytics_splash{
|
636
|
+
text-align: center;
|
637
|
+
}
|
638
|
+
.preview-buttons {
|
639
|
+
position: absolute;
|
640
|
+
left: 860px;
|
641
|
+
top: 820px;
|
642
|
+
}
|
643
|
+
.preview-buttons a.button {
|
644
|
+
display: inline-block;
|
645
|
+
float: none;
|
646
|
+
font-size: 14px;
|
647
|
+
}
|
648
|
+
|
649
|
+
/* Spree admin banners*/
|
650
|
+
.banner {
|
651
|
+
overflow: auto;
|
652
|
+
}
|
653
|
+
.banner p {
|
654
|
+
text-transform: uppercase;
|
655
|
+
font-weight: bold;
|
656
|
+
}
|
657
|
+
.banner .button {
|
658
|
+
float: none !important;
|
659
|
+
display: inline-block;
|
660
|
+
}
|
661
|
+
|
662
|
+
.banner.payment_banner {
|
663
|
+
width: 739px;
|
664
|
+
height: 135px;
|
665
|
+
background: transparent url(<%= asset_path 'admin/payment_banner.png' %>) no-repeat left top;
|
666
|
+
position: absolute;
|
667
|
+
left: -17px;
|
668
|
+
}
|
669
|
+
.banner.payment_banner .message {
|
670
|
+
padding-left: 40px;
|
671
|
+
padding-top: 35px;
|
672
|
+
font-size: 16px;
|
673
|
+
width: 500px;
|
674
|
+
color: #5A81B3;
|
675
|
+
line-height: 25px;
|
676
|
+
}
|
677
|
+
.banner.payment_banner .message a {
|
678
|
+
color: #82a653 !important;
|
679
|
+
}
|
680
|
+
|
681
|
+
.banner.payment_banner .dismiss {
|
682
|
+
color: #B25B59 !important;
|
683
|
+
font-weight: bold;
|
684
|
+
float: right;
|
685
|
+
margin-right: 25px;
|
686
|
+
}
|
@@ -2,13 +2,18 @@
|
|
2
2
|
/* Colors
|
3
3
|
/*--------------------------------------*/
|
4
4
|
$c_base: #404042; /* Dark gray */
|
5
|
-
$
|
5
|
+
$c_gray: #bbbbbb; /* Mid light gray */
|
6
6
|
$c_colored: #00ADEE; /* Light blue */
|
7
7
|
$c_colored_alt: #f0f8ff; /* Lighter blue */
|
8
8
|
$c_border: #dedede; /* Light gray */
|
9
9
|
$c_green: #8dba53; /* Spree green */
|
10
10
|
$c_red: #e45353; /* Error red */
|
11
11
|
|
12
|
+
/*--------------------------------------*/
|
13
|
+
/* Fonts
|
14
|
+
/*--------------------------------------*/
|
15
|
+
@import url(http://fonts.googleapis.com/css?family=Ubuntu:400,700,400italic,700italic|&subset=latin,cyrillic,greek,greek-ext,latin-ext,cyrillic-ext);
|
16
|
+
|
12
17
|
/*--------------------------------------*/
|
13
18
|
/* Basic styles
|
14
19
|
/*--------------------------------------*/
|
@@ -19,6 +24,11 @@ body {
|
|
19
24
|
font-size: 12px;
|
20
25
|
}
|
21
26
|
|
27
|
+
/* Line style */
|
28
|
+
hr {
|
29
|
+
border-color: $c_border;
|
30
|
+
}
|
31
|
+
|
22
32
|
/* Custom text-selection colors (remove any text shadows: twitter.com/miketaylr/status/12228805301) */
|
23
33
|
::-moz-selection{background: $c_colored; color: white; text-shadow: none;}
|
24
34
|
::selection {background: $c_colored; color: white; text-shadow: none;}
|
@@ -55,27 +65,25 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
55
65
|
}
|
56
66
|
}
|
57
67
|
}
|
58
|
-
|
59
68
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
69
|
+
dl {
|
70
|
+
dt, dd {
|
71
|
+
display: inline-block;
|
72
|
+
width: 50%;
|
73
|
+
padding: 5px;
|
65
74
|
|
66
|
-
|
67
|
-
|
68
|
-
}
|
69
|
-
}
|
70
|
-
dt {
|
71
|
-
font-weight: bold;
|
72
|
-
text-transform: uppercase;
|
73
|
-
}
|
74
|
-
dd {
|
75
|
-
margin-left: -23px;
|
75
|
+
&.odd {
|
76
|
+
background-color: $c_border;
|
76
77
|
}
|
77
78
|
}
|
78
|
-
|
79
|
+
dt {
|
80
|
+
font-weight: bold;
|
81
|
+
text-transform: uppercase;
|
82
|
+
}
|
83
|
+
dd {
|
84
|
+
margin-left: -23px;
|
85
|
+
}
|
86
|
+
}
|
79
87
|
|
80
88
|
/*--------------------------------------*/
|
81
89
|
/* Headers
|
@@ -90,7 +98,6 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
90
98
|
h5 { font-size: 16px; line-height: 26px; }
|
91
99
|
h6 { font-size: 14px; line-height: 24px; }
|
92
100
|
|
93
|
-
|
94
101
|
/*--------------------------------------*/
|
95
102
|
/* Forms
|
96
103
|
/*--------------------------------------*/
|
@@ -121,6 +128,13 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
121
128
|
select {
|
122
129
|
border: 1px solid $c_border;
|
123
130
|
font-family: "Ubuntu", sans-serif;
|
131
|
+
background-image: url('select_arrow.gif');
|
132
|
+
background-repeat: no-repeat;
|
133
|
+
background-position: right center;
|
134
|
+
|
135
|
+
&:active, &:focus {
|
136
|
+
@extend input[type="text"]:focus
|
137
|
+
}
|
124
138
|
}
|
125
139
|
|
126
140
|
label.error {
|
@@ -142,7 +156,6 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
142
156
|
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
|
143
157
|
-khtml-box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
|
144
158
|
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
|
145
|
-
-ms-box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
|
146
159
|
-o-box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
|
147
160
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
|
148
161
|
-webkit-border-radius: 0px;
|
@@ -290,7 +303,7 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
290
303
|
font-weight: bold;
|
291
304
|
border-left: 1px solid $c_border;
|
292
305
|
padding-left: 5px;
|
293
|
-
padding-bottom:
|
306
|
+
padding-bottom: 5px;
|
294
307
|
}
|
295
308
|
}
|
296
309
|
}
|
@@ -386,7 +399,10 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
386
399
|
margin-top: 15px;
|
387
400
|
|
388
401
|
input[type="number"] {
|
389
|
-
width:
|
402
|
+
width: 60px;
|
403
|
+
vertical-align: middle;
|
404
|
+
padding: 5px;
|
405
|
+
height: 35px;
|
390
406
|
}
|
391
407
|
}
|
392
408
|
|
@@ -417,7 +433,7 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
417
433
|
&.info {
|
418
434
|
height: 35px;
|
419
435
|
margin-top: 5px;
|
420
|
-
color: $
|
436
|
+
color: $c_gray;
|
421
437
|
border-bottom: 1px solid $c_border;
|
422
438
|
}
|
423
439
|
}
|
@@ -534,7 +550,7 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
534
550
|
font-weight: bold;
|
535
551
|
text-transform: uppercase;
|
536
552
|
padding: 5px 20px;
|
537
|
-
color: $
|
553
|
+
color: $c_gray;
|
538
554
|
|
539
555
|
&.current-first, &.current {
|
540
556
|
background-color: $c_colored;
|
@@ -638,7 +654,7 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
638
654
|
|
639
655
|
table tfoot {
|
640
656
|
text-align: right;
|
641
|
-
color: $
|
657
|
+
color: $c_gray;
|
642
658
|
|
643
659
|
tr {
|
644
660
|
border: none;
|
@@ -723,7 +739,7 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
723
739
|
#subtotal {
|
724
740
|
text-align: right;
|
725
741
|
text-transform: uppercase;
|
726
|
-
margin-top:
|
742
|
+
margin-top: 15px;
|
727
743
|
|
728
744
|
span.order-total {
|
729
745
|
@extend span.price;
|
@@ -878,6 +894,33 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
878
894
|
}
|
879
895
|
}
|
880
896
|
|
897
|
+
table#cart-detail, table[data-hook="order_details"] {
|
898
|
+
tbody {
|
899
|
+
tr {
|
900
|
+
td[data-hook="cart_item_description"], td[data-hook="order_item_description"] {
|
901
|
+
font-size: 11px;
|
902
|
+
line-height: 15px;
|
903
|
+
width: 100px;
|
904
|
+
|
905
|
+
h4 {
|
906
|
+
font-size: 14px;
|
907
|
+
line-height: 17px;
|
908
|
+
margin-bottom: 10px;
|
909
|
+
}
|
910
|
+
}
|
911
|
+
td[data-hook="cart_item_price"], td[data-hook="cart_item_total"],
|
912
|
+
td[data-hook="order_item_price"], td[data-hook="order_item_total"] {
|
913
|
+
font-size: 12px !important;
|
914
|
+
}
|
915
|
+
td[data-hook="cart_item_image"], td[data-hook="order_item_image"] {
|
916
|
+
img {
|
917
|
+
width: 70px;
|
918
|
+
}
|
919
|
+
}
|
920
|
+
}
|
921
|
+
}
|
922
|
+
}
|
923
|
+
|
881
924
|
}
|
882
925
|
|
883
926
|
|
@@ -907,10 +950,10 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
907
950
|
margin-top: 0;
|
908
951
|
}
|
909
952
|
|
910
|
-
table#cart-detail {
|
953
|
+
table#cart-detail, table[data-hook="order_details"] {
|
911
954
|
tbody {
|
912
955
|
tr {
|
913
|
-
td[data-hook="cart_item_description"] {
|
956
|
+
td[data-hook="cart_item_description"], td[data-hook="order_item_description"] {
|
914
957
|
padding: 0 !important;
|
915
958
|
text-indent: -9999px;
|
916
959
|
|
@@ -918,7 +961,7 @@ mark {background-color: $c_colored; color: white; font-style: italic; font-weigh
|
|
918
961
|
display: none;
|
919
962
|
}
|
920
963
|
}
|
921
|
-
td[data-hook="cart_item_image"] {
|
964
|
+
td[data-hook="cart_item_image"], td[data-hook="order_item_image"] {
|
922
965
|
img {
|
923
966
|
width: 70px;
|
924
967
|
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/*
|
2
|
-
* This is a manifest file that includes stylesheets for spree_core
|
3
|
-
*= require
|
4
|
-
*= require
|
2
|
+
* This is a manifest file that includes stylesheets for spree_core
|
3
|
+
*= require html5reset
|
4
|
+
*= require skeleton
|
5
|
+
*= require jquery.formalize
|
5
6
|
*= require store/screen
|
6
|
-
*/
|
7
|
+
*/
|
@@ -1,6 +1,19 @@
|
|
1
1
|
module Spree
|
2
2
|
module Admin
|
3
3
|
class TaxCategoriesController < ResourceController
|
4
|
+
def destroy
|
5
|
+
if @object.mark_deleted!
|
6
|
+
flash.notice = flash_message_for(@object, :successfully_removed)
|
7
|
+
respond_with(@object) do |format|
|
8
|
+
format.html { redirect_to collection_url }
|
9
|
+
format.js { render :partial => "spree/admin/shared/destroy" }
|
10
|
+
end
|
11
|
+
else
|
12
|
+
respond_with(@object) do |format|
|
13
|
+
format.html { redirect_to collection_url }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
4
17
|
end
|
5
18
|
end
|
6
19
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Spree
|
2
2
|
module Admin
|
3
3
|
class UsersController < ResourceController
|
4
|
+
rescue_from User::DestroyWithOrdersError, :with => :user_destroy_with_orders_error
|
5
|
+
|
4
6
|
# http://spreecommerce.com/blog/2010/11/02/json-hijacking-vulnerability/
|
5
7
|
before_filter :check_json_authenticity, :only => :index
|
6
8
|
before_filter :load_roles, :only => [:edit, :new, :update, :create]
|
@@ -16,6 +18,13 @@ module Spree
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
21
|
+
def dismiss_banner
|
22
|
+
if request.xhr? and params[:banner_id]
|
23
|
+
current_user.dismiss_banner(params[:banner_id])
|
24
|
+
render :nothing => true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
19
28
|
protected
|
20
29
|
def collection
|
21
30
|
return @collection if @collection.present?
|
@@ -48,6 +57,13 @@ module Spree
|
|
48
57
|
end
|
49
58
|
|
50
59
|
private
|
60
|
+
|
61
|
+
# handling raise from Admin::ResourceController#destroy
|
62
|
+
def user_destroy_with_orders_error
|
63
|
+
invoke_callbacks(:destroy, :fails)
|
64
|
+
render :status => :forbidden, :text => t(:error_user_destroy_with_orders)
|
65
|
+
end
|
66
|
+
|
51
67
|
# Allow different formats of json data to suit different ajax calls
|
52
68
|
def json_data
|
53
69
|
json_format = params[:json_format] or 'default'
|
@@ -64,6 +64,7 @@ module Spree
|
|
64
64
|
options.reverse_merge! :title => t(:confirm_delete)
|
65
65
|
options.reverse_merge! :dataType => 'script'
|
66
66
|
options.reverse_merge! :success => "function(r){ $('##{dom_id resource}').fadeOut('hide'); }"
|
67
|
+
options.reverse_merge! :error => "function(jqXHR, textStatus, errorThrown){ show_flash_error(jqXHR.responseText); }"
|
67
68
|
options.reverse_merge! :name => icon('delete') + ' ' + t(:delete)
|
68
69
|
|
69
70
|
link_to_function_delete(options, html_options)
|
@@ -92,7 +93,8 @@ module Spree
|
|
92
93
|
url: '#{options[:url]}',
|
93
94
|
data: ({_method: 'delete', authenticity_token: AUTH_TOKEN}),
|
94
95
|
dataType:'#{options[:dataType]}',
|
95
|
-
success: #{options[:success]}
|
96
|
+
success: #{options[:success]},
|
97
|
+
error: #{options[:error]}
|
96
98
|
});
|
97
99
|
}
|
98
100
|
end
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# The preference_cache_key is used to determine if the preference
|
2
|
+
# can be set. The default behavior is to return nil if there is no
|
3
|
+
# id value. On ActiveRecords, new objects will have their preferences
|
4
|
+
# saved to a pending hash until it is persisted.
|
5
|
+
#
|
1
6
|
# class_attributes are inheritied unless you reassign them in
|
2
7
|
# the subclass, so when you inherit a Preferable class, the
|
3
8
|
# inherited hook will assign a new hash for the subclass definitions
|
@@ -8,11 +13,19 @@ module Spree::Preferences::Preferable
|
|
8
13
|
def self.included(base)
|
9
14
|
base.class_eval do
|
10
15
|
extend Spree::Preferences::PreferableClassMethods
|
16
|
+
|
17
|
+
if respond_to?(:after_create)
|
18
|
+
after_create do |obj|
|
19
|
+
obj.save_pending_preferences
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
11
23
|
if respond_to?(:after_destroy)
|
12
24
|
after_destroy do |obj|
|
13
25
|
obj.clear_preferences
|
14
26
|
end
|
15
27
|
end
|
28
|
+
|
16
29
|
end
|
17
30
|
end
|
18
31
|
|
@@ -64,7 +77,15 @@ module Spree::Preferences::Preferable
|
|
64
77
|
end
|
65
78
|
|
66
79
|
def preference_cache_key(name)
|
67
|
-
|
80
|
+
return unless id
|
81
|
+
[self.class.name, name, id].join('::').underscore
|
82
|
+
end
|
83
|
+
|
84
|
+
def save_pending_preferences
|
85
|
+
return unless @pending_preferences
|
86
|
+
@pending_preferences.each do |name, value|
|
87
|
+
set_preference(name, value)
|
88
|
+
end
|
68
89
|
end
|
69
90
|
|
70
91
|
def clear_preferences
|
@@ -73,6 +94,16 @@ module Spree::Preferences::Preferable
|
|
73
94
|
|
74
95
|
private
|
75
96
|
|
97
|
+
def add_pending_preference(name, value)
|
98
|
+
@pending_preferences ||= {}
|
99
|
+
@pending_preferences[name] = value
|
100
|
+
end
|
101
|
+
|
102
|
+
def get_pending_preference(name)
|
103
|
+
return unless @pending_preferences
|
104
|
+
@pending_preferences[name]
|
105
|
+
end
|
106
|
+
|
76
107
|
def preference_store
|
77
108
|
Spree::Preferences::Store.instance
|
78
109
|
end
|
@@ -7,11 +7,17 @@ module Spree::Preferences
|
|
7
7
|
default = options[:default]
|
8
8
|
description = options[:description] || name
|
9
9
|
|
10
|
+
# cache_key will be nil for new objects, then if we check if there
|
11
|
+
# is a pending preference before going to default
|
10
12
|
define_method preference_getter_method(name) do
|
11
|
-
if preference_store.exist?
|
13
|
+
if preference_cache_key(name) && preference_store.exist?(preference_cache_key(name))
|
12
14
|
preference_store.get preference_cache_key(name)
|
13
15
|
else
|
14
|
-
|
16
|
+
if get_pending_preference(name)
|
17
|
+
get_pending_preference(name)
|
18
|
+
else
|
19
|
+
send self.class.preference_default_getter_method(name)
|
20
|
+
end
|
15
21
|
end
|
16
22
|
end
|
17
23
|
alias_method prefers_getter_method(name), preference_getter_method(name)
|
@@ -20,9 +26,20 @@ module Spree::Preferences
|
|
20
26
|
# Boolean attributes can come back from forms as '0' or '1'
|
21
27
|
# Convert them to their correct values here
|
22
28
|
if type == :boolean && !value.is_a?(TrueClass) && !value.is_a?(FalseClass)
|
23
|
-
value = value.
|
29
|
+
value = value.downcase if value.respond_to? :downcase
|
30
|
+
case value
|
31
|
+
when 0, '0', 'false', 'f', "", []
|
32
|
+
value = false
|
33
|
+
else
|
34
|
+
value = true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
if preference_cache_key(name)
|
39
|
+
preference_store.set preference_cache_key(name), value
|
40
|
+
else
|
41
|
+
add_pending_preference(name, value)
|
24
42
|
end
|
25
|
-
preference_store.set preference_cache_key(name), value
|
26
43
|
end
|
27
44
|
alias_method prefers_setter_method(name), preference_setter_method(name)
|
28
45
|
|
data/app/models/spree/product.rb
CHANGED
@@ -140,10 +140,11 @@ module Spree
|
|
140
140
|
image_dup = lambda { |i| j = i.dup; j.attachment = i.attachment.clone; j }
|
141
141
|
p.images = self.images.map { |i| image_dup.call i }
|
142
142
|
|
143
|
-
|
144
|
-
variant
|
143
|
+
master = Spree::Variant.find_by_product_id_and_is_master(self.id, true)
|
144
|
+
variant = master.dup
|
145
|
+
variant.sku = 'COPY OF ' + master.sku
|
145
146
|
variant.deleted_at = nil
|
146
|
-
variant.images =
|
147
|
+
variant.images = master.images.map { |i| image_dup.call i }
|
147
148
|
p.master = variant
|
148
149
|
|
149
150
|
if self.has_variants?
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module Spree
|
2
2
|
class TaxCategory < ActiveRecord::Base
|
3
|
-
validates :name, :presence => true, :uniqueness =>
|
3
|
+
validates :name, :presence => true, :uniqueness => { :scope => :deleted_at }
|
4
4
|
|
5
5
|
has_many :tax_rates, :dependent => :destroy
|
6
6
|
|
7
7
|
before_save :set_default_category
|
8
8
|
|
9
|
+
default_scope where(:deleted_at => nil)
|
10
|
+
|
9
11
|
def set_default_category
|
10
12
|
#set existing default tax category to false if this one has been marked as default
|
11
13
|
|
@@ -14,5 +16,9 @@ module Spree
|
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
19
|
+
def mark_deleted!
|
20
|
+
self.deleted_at = Time.now
|
21
|
+
self.save
|
22
|
+
end
|
17
23
|
end
|
18
24
|
end
|
@@ -35,7 +35,10 @@ module Spree
|
|
35
35
|
category = TaxCategory.includes(:tax_rates).where(:is_default => true).first
|
36
36
|
return 0 unless category
|
37
37
|
|
38
|
-
|
38
|
+
address ||= Address.new(:country_id => Spree::Config[:default_country_id])
|
39
|
+
rate = category.tax_rates.detect { |rate| rate.zone.include? address }.try(:amount)
|
40
|
+
|
41
|
+
rate || 0
|
39
42
|
end
|
40
43
|
|
41
44
|
# Creates necessary tax adjustments for the order.
|
data/app/models/spree/user.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Default implementation of User. This class is intended to be modified by extensions (ex. spree_auth)
|
2
2
|
module Spree
|
3
3
|
class User < ActiveRecord::Base
|
4
|
+
include Core::UserBanners
|
5
|
+
|
4
6
|
has_many :orders
|
5
7
|
|
6
8
|
belongs_to :ship_address, :foreign_key => 'ship_address_id', :class_name => 'Spree::Address'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<% if !current_user.dismissed_banner?(:gateway) &&
|
2
|
+
Spree::PaymentMethod.production.where("type != 'Spree::Gateway::Bogus'").empty? %>
|
3
|
+
|
4
|
+
<div class="banner payment_banner">
|
5
|
+
<p class="message">
|
6
|
+
<%= t(:payment_processor_choose_banner_text)%>
|
7
|
+
<%= link_to t(:payment_processor_choose_link), "http://spreecommerce.com/products/gateway", :target => '_blank' %>
|
8
|
+
</p>
|
9
|
+
|
10
|
+
<%= link_to t(:dismiss_banner), dismiss_banner_admin_user_path(current_user, :banner_id => :gateway),
|
11
|
+
:remote => true, :method => :post, :class => 'dismiss' %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<% end %>
|