caboose-cms 0.5.15 → 0.5.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +9 -9
- data/app/assets/javascripts/caboose/cart2.js +98 -0
- data/app/assets/javascripts/caboose/model/index_table.js +82 -30
- data/app/assets/javascripts/caboose/model/model_binder.js +4 -4
- data/app/assets/stylesheets/caboose/admin.css +1 -0
- data/app/assets/stylesheets/caboose/admin_main.css +0 -42
- data/app/assets/stylesheets/caboose/cart.scss +41 -0
- data/app/assets/stylesheets/caboose/checkout.css.scss +2 -3
- data/app/assets/stylesheets/caboose/message_boxes.scss +49 -0
- data/app/assets/templates/caboose/cart/add_to_cart.jst.ejs +1 -1
- data/app/controllers/caboose/block_types_controller.rb +3 -1
- data/app/controllers/caboose/cart_controller.rb +30 -23
- data/app/controllers/caboose/checkout_controller.rb +11 -1
- data/app/controllers/caboose/products_controller.rb +28 -14
- data/app/controllers/caboose/stackable_groups_controller.rb +107 -0
- data/app/models/caboose/line_item.rb +20 -6
- data/app/models/caboose/order.rb +2 -1
- data/app/models/caboose/order_package.rb +103 -0
- data/app/models/caboose/product.rb +2 -1
- data/app/models/caboose/schema.rb +45 -3
- data/app/models/caboose/shipping_calculator.rb +101 -60
- data/app/models/caboose/shipping_package.rb +80 -0
- data/app/models/caboose/site.rb +3 -1
- data/app/models/caboose/stackable_group.rb +17 -0
- data/app/models/caboose/tax_calculator.rb +1 -2
- data/app/models/caboose/variant.rb +2 -5
- data/app/views/caboose/cart/index.html.erb +19 -6
- data/app/views/caboose/checkout/_cart.html.erb +49 -52
- data/app/views/caboose/checkout/empty.html.erb +9 -2
- data/app/views/caboose/checkout/step_one.html.erb +2 -3
- data/app/views/caboose/checkout/step_three.html.erb +28 -10
- data/app/views/caboose/checkout/step_two.html.erb +2 -4
- data/app/views/caboose/pages/admin_edit_content.html.erb +1 -1
- data/app/views/caboose/products/admin_index.html.erb +12 -11
- data/app/views/caboose/sites/admin_edit.html.erb +33 -6
- data/app/views/caboose/stackable_groups/admin_index.html.erb +43 -0
- data/config/routes.rb +15 -6
- data/lib/caboose/version.rb +1 -1
- data/lib/tasks/caboose.rake +7 -1
- metadata +36 -14
@@ -2,13 +2,13 @@
|
|
2
2
|
// Checkout
|
3
3
|
//
|
4
4
|
|
5
|
-
#checkout {
|
5
|
+
#checkout { }
|
6
6
|
#checkout * { box-sizing: border-box }
|
7
7
|
|
8
8
|
#checkout input[type=text],
|
9
9
|
#checkout input[type=password],
|
10
10
|
#checkout input[type=email] {
|
11
|
-
|
11
|
+
border-width: 1px;
|
12
12
|
height: 36px;
|
13
13
|
}
|
14
14
|
|
@@ -199,7 +199,6 @@
|
|
199
199
|
}
|
200
200
|
|
201
201
|
#checkout #checkout-address {
|
202
|
-
margin: 42px 0;
|
203
202
|
.wrapper { overflow: hidden }
|
204
203
|
h1, h2, h3, h4, h5, h6 {
|
205
204
|
text-align: left;
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
/*******************************************************************************
|
3
|
+
Message boxes
|
4
|
+
*******************************************************************************/
|
5
|
+
|
6
|
+
.loading {
|
7
|
+
background-image: url('/assets/caboose/loading_black_on_white.gif');
|
8
|
+
background-position: 0 center;
|
9
|
+
background-repeat: no-repeat;
|
10
|
+
color: #000;
|
11
|
+
font-weight: normal;
|
12
|
+
font-size: 16pt;
|
13
|
+
padding: 10px 10px 10px 40px;
|
14
|
+
}
|
15
|
+
|
16
|
+
.note {
|
17
|
+
padding: 20px;
|
18
|
+
margin-bottom: 10px;
|
19
|
+
background: #fef49c;
|
20
|
+
color: #000000;
|
21
|
+
font-weight: bold;
|
22
|
+
font-size: 1.4em;
|
23
|
+
border-radius: 3px;
|
24
|
+
|
25
|
+
h2 { margin: 0 0 10px 0; padding: 0; }
|
26
|
+
}
|
27
|
+
|
28
|
+
.note_small {
|
29
|
+
display: block;
|
30
|
+
padding: 4px 10px;
|
31
|
+
background: #fef49c;
|
32
|
+
color: #000000;
|
33
|
+
font-size: 1em;
|
34
|
+
border-radius: 3px;
|
35
|
+
}
|
36
|
+
|
37
|
+
.error {
|
38
|
+
background: #9c171b;
|
39
|
+
color: #ffffff;
|
40
|
+
a { color: #fff; }
|
41
|
+
a:hover { color: #000; }
|
42
|
+
}
|
43
|
+
|
44
|
+
.success {
|
45
|
+
background: #009900;
|
46
|
+
color: #ffffff;
|
47
|
+
a { color: #ffffff; }
|
48
|
+
}
|
49
|
+
|
@@ -23,13 +23,15 @@ module Caboose
|
|
23
23
|
h['parent_id'] = ''
|
24
24
|
else
|
25
25
|
h['parent_id_null'] = true
|
26
|
+
params[:parent_id_null] = nil if params[:parent_id_null]
|
26
27
|
end
|
27
28
|
pager = Caboose::Pager.new(params, h, {
|
28
29
|
'model' => 'Caboose::BlockType',
|
29
30
|
'sort' => 'description',
|
30
31
|
'desc' => 'false',
|
31
32
|
'base_url' => "/admin/block-types",
|
32
|
-
'items_per_page' => 10
|
33
|
+
'items_per_page' => 10,
|
34
|
+
'skip' => ['parent_id_null']
|
33
35
|
})
|
34
36
|
render :json => {
|
35
37
|
:pager => pager,
|
@@ -1,13 +1,8 @@
|
|
1
1
|
module Caboose
|
2
2
|
class CartController < Caboose::ApplicationController
|
3
|
-
before_filter :get_line_item, :only => [:update, :remove]
|
4
|
-
|
5
|
-
def get_line_item
|
6
|
-
@line_item = @order.line_items.find(params[:id])
|
7
|
-
end
|
8
3
|
|
9
4
|
# GET /cart
|
10
|
-
def index
|
5
|
+
def index
|
11
6
|
end
|
12
7
|
|
13
8
|
# GET /cart/items
|
@@ -20,31 +15,43 @@ module Caboose
|
|
20
15
|
render :json => { :item_count => @order.line_items.count }
|
21
16
|
end
|
22
17
|
|
23
|
-
# POST /cart
|
18
|
+
# POST /cart
|
24
19
|
def add
|
25
|
-
|
26
|
-
|
27
|
-
@line_item.quantity += params[:quantity] ? params[:quantity].to_i : 1
|
28
|
-
else
|
29
|
-
@line_item = LineItem.new
|
30
|
-
@line_item.variant_id = params[:variant_id]
|
31
|
-
@line_item.order_id = @order.id
|
32
|
-
@line_item.status = 'pending'
|
33
|
-
@line_item.quantity = params[:quantity] ? params[:quantity].to_i : 1
|
34
|
-
end
|
20
|
+
variant_id = params[:variant_id]
|
21
|
+
qty = params[:quantity] ? params[:quantity].to_i : 1
|
35
22
|
|
36
|
-
|
23
|
+
if @order.line_items.exists?(:variant_id => variant_id)
|
24
|
+
li = @order.line_items.find_by_variant_id(variant_id)
|
25
|
+
li.quantity += qty
|
26
|
+
else
|
27
|
+
li = LineItem.new(
|
28
|
+
:order_id => @order.id,
|
29
|
+
:variant_id => variant_id,
|
30
|
+
:quantity => qty,
|
31
|
+
:status => 'pending'
|
32
|
+
)
|
33
|
+
end
|
34
|
+
render :json => {
|
35
|
+
:success => li.save,
|
36
|
+
:errors => li.errors.full_messages,
|
37
|
+
:item_count => @order.line_items.count
|
38
|
+
}
|
37
39
|
end
|
38
40
|
|
39
|
-
# PUT cart
|
41
|
+
# PUT /cart/:line_item_id
|
40
42
|
def update
|
41
|
-
|
42
|
-
|
43
|
+
li = LineItem.find(params[:line_item_id])
|
44
|
+
li.quantity = params[:quantity].to_i
|
45
|
+
li.save
|
46
|
+
li.destroy if li.quantity == 0
|
47
|
+
@order.calculate_subtotal
|
48
|
+
render :json => { :success => true }
|
43
49
|
end
|
44
50
|
|
45
|
-
# DELETE cart
|
51
|
+
# DELETE /cart/:line_item_id
|
46
52
|
def remove
|
47
|
-
|
53
|
+
li = LineItem.find(params[:line_item_id]).destroy
|
54
|
+
render :json => { :success => true, :item_count => @order.line_items.count }
|
48
55
|
end
|
49
56
|
end
|
50
57
|
end
|
@@ -36,8 +36,18 @@ module Caboose
|
|
36
36
|
def step_three
|
37
37
|
redirect_to '/checkout/step-one' and return if !logged_in?
|
38
38
|
redirect_to '/checkout/step-two' and return if @order.shipping_address.nil? || @order.billing_address.nil?
|
39
|
+
|
40
|
+
# Remove any order packages
|
41
|
+
LineItem.where(:order_id => @order.id).update_all(:order_package_id => nil)
|
42
|
+
OrderPackage.where(:order_id => @order.id).destroy_all
|
43
|
+
|
44
|
+
# Calculate what shipping packages we'll need
|
45
|
+
OrderPackage.create_for_order(@order)
|
46
|
+
|
47
|
+
# Now get the rates for those packages
|
48
|
+
Caboose.log("Getting rates...")
|
39
49
|
@rates = ShippingCalculator.rates(@order)
|
40
|
-
|
50
|
+
Caboose.log(@rates.inspect)
|
41
51
|
end
|
42
52
|
|
43
53
|
# GET /checkout/step-four
|
@@ -577,20 +577,21 @@ module Caboose
|
|
577
577
|
save = true
|
578
578
|
params.each do |name,value|
|
579
579
|
case name
|
580
|
-
when 'alternate_id'
|
581
|
-
when 'title'
|
582
|
-
when 'caption'
|
583
|
-
when 'featured'
|
584
|
-
when 'description'
|
585
|
-
when 'vendor_id'
|
586
|
-
when 'handle'
|
587
|
-
when 'seo_title'
|
588
|
-
when 'seo_description'
|
589
|
-
when 'status'
|
590
|
-
when 'category_id'
|
591
|
-
when '
|
592
|
-
when '
|
593
|
-
when '
|
580
|
+
when 'alternate_id' then product.alternate_id = value
|
581
|
+
when 'title' then product.title = value
|
582
|
+
when 'caption' then product.caption = value
|
583
|
+
when 'featured' then product.featured = value
|
584
|
+
when 'description' then product.description = value
|
585
|
+
when 'vendor_id' then product.vendor_id = value
|
586
|
+
when 'handle' then product.handle = value
|
587
|
+
when 'seo_title' then product.seo_title = value
|
588
|
+
when 'seo_description' then product.seo_description = value
|
589
|
+
when 'status' then product.status = value
|
590
|
+
when 'category_id' then product.toggle_category(value[0], value[1])
|
591
|
+
when 'stackable_group_id' then product.stackable_group_id = value
|
592
|
+
when 'option1' then product.option1 = value
|
593
|
+
when 'option2' then product.option2 = value
|
594
|
+
when 'option3' then product.option3 = value
|
594
595
|
when 'default1'
|
595
596
|
product.default1 = value
|
596
597
|
Variant.where(:product_id => product.id, :option1 => nil).each do |p|
|
@@ -677,6 +678,19 @@ module Caboose
|
|
677
678
|
render :json => options
|
678
679
|
end
|
679
680
|
|
681
|
+
# GET /products/stackable-group-options
|
682
|
+
def admin_stackable_group_options
|
683
|
+
arr = ['Active', 'Inactive', 'Deleted']
|
684
|
+
options = []
|
685
|
+
arr.each do |status|
|
686
|
+
options << {
|
687
|
+
:value => status,
|
688
|
+
:text => status
|
689
|
+
}
|
690
|
+
end
|
691
|
+
render :json => options
|
692
|
+
end
|
693
|
+
|
680
694
|
# GET /admin/products/combine
|
681
695
|
def admin_combine_select_products
|
682
696
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Caboose
|
2
|
+
class StackableGroupsController < Caboose::ApplicationController
|
3
|
+
|
4
|
+
# GET /admin/stackable-groups
|
5
|
+
def admin_index
|
6
|
+
return if !user_is_allowed('products', 'view')
|
7
|
+
render :layout => 'caboose/admin'
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /admin/stackable-groups/json
|
11
|
+
def admin_json
|
12
|
+
return if !user_is_allowed('products', 'view')
|
13
|
+
|
14
|
+
pager = Caboose::PageBarGenerator.new(params, {
|
15
|
+
'name' => ''
|
16
|
+
}, {
|
17
|
+
'model' => 'Caboose::StackableGroup',
|
18
|
+
'sort' => 'name',
|
19
|
+
'desc' => false,
|
20
|
+
'base_url' => '/admin/stackable-groups',
|
21
|
+
'items_per_page' => 25,
|
22
|
+
'use_url_params' => false
|
23
|
+
})
|
24
|
+
render :json => {
|
25
|
+
:pager => pager,
|
26
|
+
:models => pager.items
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
# GET /admin/stackable-groups/:id/json
|
31
|
+
def admin_json_single
|
32
|
+
sg = StackableGroup.find(params[:id])
|
33
|
+
render :json => sg
|
34
|
+
end
|
35
|
+
|
36
|
+
# PUT /admin/stackable-groups/:id
|
37
|
+
def admin_update
|
38
|
+
return if !user_is_allowed('products', 'edit')
|
39
|
+
|
40
|
+
resp = Caboose::StdClass.new
|
41
|
+
sg = StackableGroup.find(params[:id])
|
42
|
+
|
43
|
+
save = true
|
44
|
+
params.each do |name,value|
|
45
|
+
case name
|
46
|
+
when 'name' then sg.name = value
|
47
|
+
when 'extra_length' then sg.extra_length = value.to_f
|
48
|
+
when 'extra_width' then sg.extra_width = value.to_f
|
49
|
+
when 'extra_height' then sg.extra_height = value.to_f
|
50
|
+
when 'max_length' then sg.max_length = value.to_f
|
51
|
+
when 'max_width' then sg.max_width = value.to_f
|
52
|
+
when 'max_height' then sg.max_height = value.to_f
|
53
|
+
end
|
54
|
+
end
|
55
|
+
resp.success = save && sg.save
|
56
|
+
render :json => resp
|
57
|
+
end
|
58
|
+
|
59
|
+
# POST /admin/stackable-groups
|
60
|
+
def admin_add
|
61
|
+
return if !user_is_allowed('products', 'add')
|
62
|
+
|
63
|
+
resp = Caboose::StdClass.new
|
64
|
+
name = params[:name]
|
65
|
+
|
66
|
+
if name.length == 0
|
67
|
+
resp.error = "The title cannot be empty."
|
68
|
+
elsif StackableGroup.where(:name => name).exists?
|
69
|
+
resp.error = "A stackable group with that name already exists."
|
70
|
+
else
|
71
|
+
sg = StackableGroup.new(:name => name)
|
72
|
+
sg.save
|
73
|
+
resp.refresh = true
|
74
|
+
end
|
75
|
+
render :json => resp
|
76
|
+
end
|
77
|
+
|
78
|
+
# DELETE /admin/stackable-groups/:id
|
79
|
+
def admin_delete
|
80
|
+
return if !user_is_allowed('products', 'delete')
|
81
|
+
StackableGroup.find(params[:id]).destroy
|
82
|
+
render :json => true
|
83
|
+
end
|
84
|
+
|
85
|
+
# DELETE /admin/stackable-groups/bulk
|
86
|
+
def admin_bulk_delete
|
87
|
+
return if !user_is_allowed('products', 'delete')
|
88
|
+
params[:model_ids].each do |sg_id|
|
89
|
+
sg = StackableGroup.where(:id => sg_id).first
|
90
|
+
sg.destroy if sg
|
91
|
+
end
|
92
|
+
render :json => { :success => true }
|
93
|
+
end
|
94
|
+
|
95
|
+
# GET /admin/stackable-groups/options
|
96
|
+
def admin_options
|
97
|
+
options = StackableGroup.reorder(:name).all.collect do |sg|
|
98
|
+
{
|
99
|
+
:value => sg.id,
|
100
|
+
:text => sg.name
|
101
|
+
}
|
102
|
+
end
|
103
|
+
render :json => options
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
@@ -3,18 +3,19 @@ module Caboose
|
|
3
3
|
self.table_name = 'store_line_items'
|
4
4
|
|
5
5
|
belongs_to :variant
|
6
|
-
belongs_to :order
|
6
|
+
belongs_to :order
|
7
|
+
belongs_to :order_package, :class_name => 'OrderPackage'
|
7
8
|
belongs_to :parent, :class_name => 'LineItem', :foreign_key => 'parent_id'
|
8
9
|
has_many :children, :class_name => 'LineItem', :foreign_key => 'parent_id'
|
9
10
|
|
10
11
|
attr_accessible :id,
|
12
|
+
:order_package_id,
|
11
13
|
:variant_id,
|
12
14
|
:quantity,
|
13
15
|
:price,
|
14
16
|
:notes,
|
15
17
|
:order_id,
|
16
|
-
:status,
|
17
|
-
:tracking_number,
|
18
|
+
:status,
|
18
19
|
:custom1,
|
19
20
|
:custom2,
|
20
21
|
:custom3
|
@@ -66,16 +67,29 @@ module Caboose
|
|
66
67
|
end
|
67
68
|
|
68
69
|
def as_json(options={})
|
69
|
-
self.attributes.merge({
|
70
|
+
self.attributes.merge({
|
70
71
|
:variant => self.variant,
|
71
|
-
:title
|
72
|
-
:product => { :images => self.variant.product.product_images }
|
72
|
+
:title => self.title
|
73
73
|
})
|
74
74
|
end
|
75
75
|
|
76
76
|
def subtotal
|
77
77
|
return self.quantity * self.price
|
78
78
|
end
|
79
|
+
|
80
|
+
def copy
|
81
|
+
LineItem.new(
|
82
|
+
:variant_id => self.variant_id ,
|
83
|
+
:quantity => self.quantity ,
|
84
|
+
:price => self.price ,
|
85
|
+
:notes => self.notes ,
|
86
|
+
:order_id => self.order_id ,
|
87
|
+
:status => self.status ,
|
88
|
+
:custom1 => self.custom1 ,
|
89
|
+
:custom2 => self.custom2 ,
|
90
|
+
:custom3 => self.custom3
|
91
|
+
)
|
92
|
+
end
|
79
93
|
end
|
80
94
|
end
|
81
95
|
|
data/app/models/caboose/order.rb
CHANGED
@@ -12,7 +12,8 @@ module Caboose
|
|
12
12
|
belongs_to :billing_address, :class_name => 'Address'
|
13
13
|
has_many :discounts, :through => :order_discounts
|
14
14
|
has_many :order_discounts
|
15
|
-
has_many :line_items, :after_add => :line_item_added, :after_remove => :line_item_removed
|
15
|
+
has_many :line_items, :after_add => :line_item_added, :after_remove => :line_item_removed, :order => :id
|
16
|
+
has_many :packages, :class_name => 'Caboose::OrderPackage'
|
16
17
|
|
17
18
|
attr_accessible :id,
|
18
19
|
:order_number,
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Caboose
|
2
|
+
class OrderPackage < ActiveRecord::Base
|
3
|
+
self.table_name = 'store_order_packages'
|
4
|
+
|
5
|
+
belongs_to :order
|
6
|
+
belongs_to :shipping_package
|
7
|
+
has_many :line_items
|
8
|
+
attr_accessible :id,
|
9
|
+
:order_id,
|
10
|
+
:shipping_package_id,
|
11
|
+
:status,
|
12
|
+
:tracking_number
|
13
|
+
|
14
|
+
STATUS_PENDING = 'Pending'
|
15
|
+
STATUS_SHIPPED = 'Shipped'
|
16
|
+
|
17
|
+
# Calculates the shipping packages required for all the items in the order
|
18
|
+
def self.create_for_order(order)
|
19
|
+
|
20
|
+
# Make sure all the line items in the order have a quantity of 1
|
21
|
+
extra_line_items = []
|
22
|
+
order.line_items.each do |li|
|
23
|
+
if li.quantity > 1
|
24
|
+
(1..li.quantity).each{ |i|
|
25
|
+
extra_line_items << li.copy
|
26
|
+
}
|
27
|
+
li.quantity = 1
|
28
|
+
li.save
|
29
|
+
end
|
30
|
+
end
|
31
|
+
extra_line_items.each do |li|
|
32
|
+
li.quantity = 1
|
33
|
+
li.save
|
34
|
+
end
|
35
|
+
|
36
|
+
# Make sure all the items in the order have attributes set
|
37
|
+
order.line_items.each do |li|
|
38
|
+
v = li.variant
|
39
|
+
Caboose.log("Error: variant #{v.id} has a zero weight") and return false if v.weight.nil? || v.weight == 0
|
40
|
+
next if v.volume && v.volume > 0
|
41
|
+
Caboose.log("Error: variant #{v.id} has a zero length") and return false if v.length.nil? || v.length == 0
|
42
|
+
Caboose.log("Error: variant #{v.id} has a zero width" ) and return false if v.width.nil? || v.width == 0
|
43
|
+
Caboose.log("Error: variant #{v.id} has a zero height") and return false if v.height.nil? || v.height == 0
|
44
|
+
v.volume = v.length * v.width * v.height
|
45
|
+
v.save
|
46
|
+
end
|
47
|
+
|
48
|
+
# Reorder the items in the order by volume
|
49
|
+
h = {}
|
50
|
+
order.line_items.each do |li|
|
51
|
+
(1..li.quantity).each do |i|
|
52
|
+
v = li.variant
|
53
|
+
h[v.volume] = li
|
54
|
+
end
|
55
|
+
end
|
56
|
+
line_items = h.sort_by{ |k,v| k }.collect{ |x| x[1] }
|
57
|
+
all_packages = ShippingPackage.reorder(:price).all
|
58
|
+
|
59
|
+
# Now go through each variant and fit it in a new or existing package
|
60
|
+
line_items.each do |li|
|
61
|
+
|
62
|
+
# See if the item will fit in any of the existing packages
|
63
|
+
it_fits = false
|
64
|
+
order.packages.each do |op|
|
65
|
+
it_fits = op.fits(li)
|
66
|
+
if it_fits
|
67
|
+
li.order_package_id = op.id
|
68
|
+
li.save
|
69
|
+
break
|
70
|
+
end
|
71
|
+
end
|
72
|
+
next if it_fits
|
73
|
+
|
74
|
+
# Otherwise find the cheapest package the item will fit into
|
75
|
+
all_packages.each do |sp|
|
76
|
+
if sp.fits(li.variant)
|
77
|
+
op = OrderPackage.create(:order_id => order.id, :shipping_package_id => sp.id)
|
78
|
+
li.order_package_id = op.id
|
79
|
+
li.save
|
80
|
+
break
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def fits(line_item = nil)
|
88
|
+
variants = self.line_items.collect{ |li| li.variant }
|
89
|
+
variants << line_item.variant if line_item
|
90
|
+
return self.shipping_package.fits(variants)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Gets the activemerchant package based on the shipping package
|
94
|
+
def activemerchant_package
|
95
|
+
weight = 0.0
|
96
|
+
self.line_items.each{ |li| weight = weight + li.variant.weight }
|
97
|
+
weight = weight * 0.035274 # Convert from grams to ounces
|
98
|
+
sp = self.shipping_package
|
99
|
+
return Package.new(weight, [sp.length, sp.width, sp.height], :units => :imperial)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|