effective_orders 1.8.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +150 -60
- data/Rakefile +0 -3
- data/active_admin/effective_orders.rb +14 -9
- data/app/assets/javascripts/effective_orders.js +2 -0
- data/app/assets/javascripts/effective_orders/{stripe_charges.js.coffee → providers/stripe_charges.js.coffee} +1 -1
- data/app/assets/javascripts/effective_orders/{stripe_subscriptions.js.coffee → providers/stripe_subscriptions.js.coffee} +1 -1
- data/app/assets/stylesheets/effective_orders/_order.scss +9 -3
- data/app/controllers/admin/orders_controller.rb +87 -3
- data/app/controllers/concerns/acts_as_active_admin_controller.rb +2 -1
- data/app/controllers/effective/carts_controller.rb +4 -2
- data/app/controllers/effective/orders_controller.rb +101 -60
- data/app/controllers/effective/providers/app_checkout.rb +10 -2
- data/app/controllers/effective/providers/ccbill.rb +34 -0
- data/app/controllers/effective/providers/cheque.rb +30 -0
- data/app/controllers/effective/providers/moneris.rb +7 -7
- data/app/controllers/effective/providers/paypal.rb +7 -5
- data/app/controllers/effective/providers/pretend.rb +22 -0
- data/app/controllers/effective/providers/stripe.rb +26 -24
- data/app/controllers/effective/webhooks_controller.rb +1 -1
- data/app/helpers/effective_carts_helper.rb +59 -29
- data/app/helpers/effective_ccbill_helper.rb +25 -0
- data/app/helpers/effective_orders_helper.rb +50 -41
- data/app/helpers/effective_paypal_helper.rb +11 -11
- data/app/mailers/effective/orders_mailer.rb +95 -20
- data/app/models/concerns/acts_as_purchasable.rb +14 -22
- data/app/models/effective/cart.rb +9 -15
- data/app/models/effective/cart_item.rb +15 -13
- data/app/models/effective/customer.rb +9 -9
- data/app/models/effective/datatables/order_items.rb +14 -8
- data/app/models/effective/datatables/orders.rb +56 -69
- data/app/models/effective/order.rb +250 -139
- data/app/models/effective/order_item.rb +23 -16
- data/app/models/effective/product.rb +23 -0
- data/app/models/effective/providers/ccbill_postback.rb +85 -0
- data/app/models/effective/{stripe_charge.rb → providers/stripe_charge.rb} +1 -1
- data/app/models/effective/subscription.rb +16 -12
- data/app/models/effective/tax_rate_calculator.rb +45 -0
- data/app/views/admin/customers/index.html.haml +2 -5
- data/app/views/admin/order_items/index.html.haml +2 -5
- data/app/views/admin/orders/_actions.html.haml +2 -0
- data/app/views/admin/orders/_form.html.haml +28 -0
- data/app/views/admin/orders/_order_item_fields.html.haml +9 -0
- data/app/views/admin/orders/index.html.haml +9 -5
- data/app/views/admin/orders/new.html.haml +3 -0
- data/app/views/effective/carts/_cart.html.haml +3 -12
- data/app/views/effective/carts/_cart_actions.html.haml +4 -0
- data/app/views/effective/carts/show.html.haml +10 -12
- data/app/views/effective/orders/_checkout_step1.html.haml +46 -0
- data/app/views/effective/orders/_checkout_step2.html.haml +33 -0
- data/app/views/effective/orders/_order.html.haml +2 -0
- data/app/views/effective/orders/_order_actions.html.haml +10 -5
- data/app/views/effective/orders/_order_footer.html.haml +1 -0
- data/app/views/effective/orders/_order_items.html.haml +11 -9
- data/app/views/effective/orders/_order_note.html.haml +8 -0
- data/app/views/effective/orders/_order_note_fields.html.haml +5 -0
- data/app/views/effective/orders/_order_shipping.html.haml +4 -4
- data/app/views/effective/orders/_order_user_fields.html.haml +1 -0
- data/app/views/effective/orders/_orders_table.html.haml +27 -0
- data/app/views/effective/orders/ccbill/_form.html.haml +24 -0
- data/app/views/effective/orders/checkout_step1.html.haml +3 -0
- data/app/views/effective/orders/checkout_step2.html.haml +3 -0
- data/app/views/effective/orders/cheque/_form.html.haml +2 -0
- data/app/views/effective/orders/cheque/pay_by_cheque.html.haml +9 -0
- data/app/views/effective/orders/declined.html.haml +4 -2
- data/app/views/effective/orders/my_purchases.html.haml +1 -1
- data/app/views/effective/orders/my_sales.html.haml +1 -1
- data/app/views/effective/orders/purchased.html.haml +3 -2
- data/app/views/effective/orders/show.html.haml +1 -1
- data/app/views/effective/orders/stripe/_form.html.haml +5 -5
- data/app/views/effective/orders_mailer/order_error.html.haml +11 -0
- data/app/views/effective/orders_mailer/payment_request_to_buyer.html.haml +13 -0
- data/app/views/effective/orders_mailer/pending_order_invoice_to_buyer.html.haml +13 -0
- data/app/views/layouts/effective_orders_mailer_layout.html.haml +7 -7
- data/config/routes.rb +39 -24
- data/db/migrate/01_create_effective_orders.rb.erb +20 -1
- data/db/upgrade/03_upgrade_effective_orders_from1x.rb.erb +95 -0
- data/lib/effective_orders.rb +67 -9
- data/lib/effective_orders/app_checkout_service.rb +1 -2
- data/lib/effective_orders/engine.rb +46 -14
- data/lib/effective_orders/version.rb +1 -1
- data/lib/generators/effective_orders/install_generator.rb +1 -0
- data/lib/generators/effective_orders/upgrade_from03x_generator.rb +1 -0
- data/lib/generators/effective_orders/upgrade_from1x_generator.rb +31 -0
- data/lib/generators/templates/effective_orders.rb +131 -66
- data/lib/generators/templates/effective_orders_mailer_preview.rb +28 -13
- data/spec/controllers/admin/orders_controller_spec.rb +242 -0
- data/spec/controllers/ccbill_orders_controller_spec.rb +103 -0
- data/spec/controllers/moneris_orders_controller_spec.rb +23 -23
- data/spec/controllers/orders_controller_spec.rb +167 -79
- data/spec/controllers/stripe_orders_controller_spec.rb +7 -7
- data/spec/dummy/app/models/product.rb +0 -8
- data/spec/dummy/app/models/product_with_float_price.rb +0 -8
- data/spec/dummy/app/models/user.rb +2 -19
- data/spec/dummy/config/application.rb +2 -1
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/dummy/config/initializers/effective_orders.rb +109 -64
- data/spec/dummy/db/schema.rb +15 -2
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +0 -258
- data/spec/models/acts_as_purchasable_spec.rb +8 -6
- data/spec/models/factories_spec.rb +7 -1
- data/spec/models/order_item_spec.rb +1 -1
- data/spec/models/order_spec.rb +165 -46
- data/spec/models/stripe_charge_spec.rb +5 -5
- data/spec/spec_helper.rb +2 -0
- data/spec/support/factories.rb +49 -33
- metadata +47 -64
- data/app/views/effective/orders/_checkout_step_1.html.haml +0 -43
- data/app/views/effective/orders/_checkout_step_2.html.haml +0 -25
- data/app/views/effective/orders/_my_purchases.html.haml +0 -17
- data/app/views/effective/orders/checkout.html.haml +0 -3
- data/app/views/effective/orders/new.html.haml +0 -4
- data/spec/dummy/log/development.log +0 -82
@@ -6,24 +6,27 @@ module Effective
|
|
6
6
|
belongs_to :purchasable, :polymorphic => true
|
7
7
|
belongs_to :seller, :class_name => 'User'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
quantity :integer, :validates => [:presence, :numericality]
|
12
|
-
price :integer, :default => 0, :validates => [:numericality]
|
13
|
-
tax_exempt :boolean, :validates => [:inclusion => {:in => [true, false]}]
|
14
|
-
tax_rate :decimal, :precision => 5, :scale => 3, :default => 0.000, :validates => [:presence]
|
9
|
+
delegate :purchased_download_url, :to => :purchasable
|
10
|
+
delegate :purchased?, :declined?, :to => :order
|
15
11
|
|
16
|
-
|
17
|
-
|
12
|
+
# structure do
|
13
|
+
# title :string
|
14
|
+
# quantity :integer
|
15
|
+
# price :integer, default: 0
|
16
|
+
# tax_exempt :boolean
|
17
|
+
#
|
18
|
+
# timestamps
|
19
|
+
# end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
accepts_nested_attributes_for :purchasable, :allow_destroy => false, :reject_if => :all_blank, :update_only => true
|
21
|
+
validates :purchasable, associated: true, presence: true
|
22
|
+
accepts_nested_attributes_for :purchasable, allow_destroy: false, reject_if: :all_blank, update_only: true
|
22
23
|
|
23
|
-
|
24
|
+
validates :title, presence: true
|
25
|
+
validates :quantity, presence: true, numericality: { greater_than: 0 }
|
26
|
+
validates :price, numericality: true
|
27
|
+
validates :tax_exempt, inclusion: { in: [true, false] }
|
24
28
|
|
25
|
-
|
26
|
-
delegate :purchased?, :declined?, :to => :order
|
29
|
+
validates :seller_id, presence: true, if: Proc.new { |order_item| EffectiveOrders.stripe_connect_enabled }
|
27
30
|
|
28
31
|
scope :sold, -> { joins(:order).where(:orders => {:purchase_state => EffectiveOrders::PURCHASED}) }
|
29
32
|
scope :sold_by, lambda { |user| sold().where(:seller_id => user.try(:id)) }
|
@@ -36,11 +39,15 @@ module Effective
|
|
36
39
|
price * quantity
|
37
40
|
end
|
38
41
|
|
39
|
-
def tax
|
40
|
-
|
42
|
+
def tax
|
43
|
+
return 0 if tax_exempt?
|
44
|
+
raise 'parent Effective::Order must have a tax_rate to compute order item tax' unless order.try(:tax_rate).present?
|
45
|
+
(subtotal * order.tax_rate / 100.0).round(0).to_i
|
41
46
|
end
|
42
47
|
|
43
48
|
def total
|
49
|
+
return subtotal if tax_exempt?
|
50
|
+
raise 'parent Effective::Order must have a tax_rate to compute order item total' unless order.try(:tax_rate).present?
|
44
51
|
subtotal + tax
|
45
52
|
end
|
46
53
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Effective
|
2
|
+
class Product < ActiveRecord::Base
|
3
|
+
self.table_name = EffectiveOrders.products_table_name.to_s
|
4
|
+
|
5
|
+
acts_as_purchasable
|
6
|
+
|
7
|
+
# structure do
|
8
|
+
# title :string
|
9
|
+
# price :integer, default: 0
|
10
|
+
# tax_exempt :boolean, default: false
|
11
|
+
#
|
12
|
+
# timestamps
|
13
|
+
# end
|
14
|
+
|
15
|
+
validates :title, presence: true
|
16
|
+
validates :price, numericality: { greater_than: 0 }
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
self[:title] || 'New Product'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# https://www.ccbill.com/cs/wiki/tiki-index.php?page=Background+Post
|
2
|
+
class Effective::Providers::CcbillPostback
|
3
|
+
attr_reader :params
|
4
|
+
|
5
|
+
def initialize(params)
|
6
|
+
@params = params
|
7
|
+
end
|
8
|
+
|
9
|
+
def verified?
|
10
|
+
params[:responseDigest] == digest(digest_value)
|
11
|
+
end
|
12
|
+
|
13
|
+
def matches?(order)
|
14
|
+
price == order.total && order_id == order.to_param
|
15
|
+
end
|
16
|
+
|
17
|
+
def approval?
|
18
|
+
!denial?
|
19
|
+
end
|
20
|
+
|
21
|
+
def denial?
|
22
|
+
# denialId is for subscriptions only
|
23
|
+
[:reasonForDeclineCode, :reasonForDecline, :denialId].any? {|key| params[key].present?}
|
24
|
+
end
|
25
|
+
|
26
|
+
def order_details
|
27
|
+
@order_details ||= get_order_details
|
28
|
+
end
|
29
|
+
|
30
|
+
def order_id
|
31
|
+
params[:order_id]
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# https://www.ccbill.com/cs/wiki/tiki-index.php?page=Dynamic+Pricing+User+Guide#Postback
|
37
|
+
def digest_value
|
38
|
+
if approval?
|
39
|
+
"#{params[:subscription_id]}1#{salt}" # the `subscriptionId` param in the linked docs is a typo
|
40
|
+
else
|
41
|
+
"#{params[:denialId]}0#{salt}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def digest(value)
|
46
|
+
Digest::MD5.hexdigest(value)
|
47
|
+
end
|
48
|
+
|
49
|
+
def salt
|
50
|
+
EffectiveOrders.ccbill[:dynamic_pricing_salt]
|
51
|
+
end
|
52
|
+
|
53
|
+
# in cents
|
54
|
+
def price
|
55
|
+
return @price if @price.present?
|
56
|
+
formatted_price = params[:initialFormattedPrice] # example: "$10.00"
|
57
|
+
formatted_price = Nokogiri::HTML::DocumentFragment.parse(formatted_price).to_s # => "$10.00"
|
58
|
+
match = formatted_price.match(/^\D(\d*.\d\d)$/) # {a currency symbol}(digits.two digits)
|
59
|
+
return false unless match.present?
|
60
|
+
formatted_price = match[1] # => "10.00"
|
61
|
+
@price = formatted_price.sub('.', '').to_i # => 1000
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_order_details
|
65
|
+
# ignore some params
|
66
|
+
keepable = params.except(*ignorable_params)
|
67
|
+
# remove blanks
|
68
|
+
keepable.inject({}) do |details, kv_pair|
|
69
|
+
details[kv_pair[0]] = kv_pair[1] if kv_pair[1].present?
|
70
|
+
details
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def ignorable_params
|
75
|
+
[
|
76
|
+
# we have these already
|
77
|
+
:clientAccnum,
|
78
|
+
:clientSubacc,
|
79
|
+
:productDesc,
|
80
|
+
# a hash of billing information which CCBill doesn't share the format of (afaik)
|
81
|
+
:paymentAccount
|
82
|
+
]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
@@ -8,21 +8,25 @@ module Effective
|
|
8
8
|
|
9
9
|
belongs_to :customer
|
10
10
|
|
11
|
-
structure do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
11
|
+
# structure do
|
12
|
+
# stripe_plan_id :string # This will be 'Weekly' or something like that
|
13
|
+
# stripe_subscription_id :string
|
14
|
+
# stripe_coupon_id :string
|
15
|
+
#
|
16
|
+
# title :string
|
17
|
+
# price :integer, default: 0
|
18
|
+
#
|
19
|
+
# timestamps
|
20
|
+
# end
|
21
21
|
|
22
22
|
delegate :user, :user_id, :to => :customer
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
validates :stripe_plan_id, presence: true
|
25
|
+
validates :title, presence: true
|
26
|
+
validates :price, numericality: { greater_than: 0 }
|
27
|
+
|
28
|
+
validates :customer, presence: true
|
29
|
+
validates :customer_id, uniqueness: { scope: [:stripe_plan_id] } # Can only be on each plan once.
|
26
30
|
|
27
31
|
before_validation do
|
28
32
|
self.errors.add(:stripe_plan_id, "is an invalid Plan") if stripe_plan_id.present? && stripe_plan.blank?
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Effective
|
2
|
+
class TaxRateCalculator
|
3
|
+
attr_reader :order
|
4
|
+
|
5
|
+
RATES = {
|
6
|
+
'CA' => { # Canada
|
7
|
+
'AB' => 5.00, # Alberta
|
8
|
+
'BC' => 5.00, # British Columbia
|
9
|
+
'MB' => 5.00, # Manitoba
|
10
|
+
'NB' => 13.0, # New Brunswick
|
11
|
+
'NL' => 13.0, # Newfoundland and Labrador
|
12
|
+
'NT' => 5.00, # Northwest Territories
|
13
|
+
'NS' => 15.0, # Nova Scotia
|
14
|
+
'ON' => 13.0, # Ontario
|
15
|
+
'PE' => 14.0, # Prince Edward Island
|
16
|
+
'QC' => 5.00, # Quebec
|
17
|
+
'SK' => 5.00, # Saskatchewan
|
18
|
+
'YT' => 5.00, # Yukon Territory
|
19
|
+
'NU' => 5.00 # Nunavut
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
def initialize(order:)
|
24
|
+
@order = order
|
25
|
+
end
|
26
|
+
|
27
|
+
def tax_rate
|
28
|
+
return nil unless order.billing_address.try(:country_code).present?
|
29
|
+
|
30
|
+
country = order.billing_address.country_code
|
31
|
+
state = order.billing_address.state_code
|
32
|
+
|
33
|
+
rate = RATES[country]
|
34
|
+
return rate if rate.kind_of?(Numeric)
|
35
|
+
return unknown_tax_rate() if rate.nil?
|
36
|
+
|
37
|
+
rate[state].presence || unknown_tax_rate()
|
38
|
+
end
|
39
|
+
|
40
|
+
def unknown_tax_rate
|
41
|
+
order.skip_buyer_validations? ? nil : 0
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -1,12 +1,9 @@
|
|
1
|
-
%h2.effective-orders-page-title Customers
|
1
|
+
%h2.effective-orders-page-title= (@page_title || 'Customers')
|
2
2
|
|
3
3
|
%p.text-right= link_to 'Stripe Dashboard: Customers', 'https://manage.stripe.com/customers', :class => 'btn btn-primary'
|
4
4
|
|
5
5
|
- if @datatable.nil?
|
6
|
-
%p
|
7
|
-
Please install
|
8
|
-
= link_to 'effective_datatables', 'https://github.com/code-and-effect/effective_datatables'
|
9
|
-
to see this page.
|
6
|
+
%p Please install #{link_to 'effective_datatables', 'https://github.com/code-and-effect/effective_datatables'} to see this page.
|
10
7
|
- elsif @datatable.present?
|
11
8
|
= render_datatable @datatable
|
12
9
|
- else
|
@@ -1,10 +1,7 @@
|
|
1
|
-
%h2.effective-orders-page-title Order Items
|
1
|
+
%h2.effective-orders-page-title= (@page_title || 'Order Items')
|
2
2
|
|
3
3
|
- if @datatable.nil?
|
4
|
-
%p
|
5
|
-
Please install
|
6
|
-
= link_to 'effective_datatables', 'https://github.com/code-and-effect/effective_datatables'
|
7
|
-
to see this page.
|
4
|
+
%p Please install #{link_to 'effective_datatables', 'https://github.com/code-and-effect/effective_datatables'} to see this page.
|
8
5
|
- elsif @datatable.present?
|
9
6
|
= render_datatable @datatable
|
10
7
|
- else
|
@@ -0,0 +1,28 @@
|
|
1
|
+
- unless defined?(Cocoon)
|
2
|
+
Please install #{link_to 'cocoon', 'https://github.com/nathanvda/cocoon'} to see this page.
|
3
|
+
- else
|
4
|
+
= simple_form_for [:admin, order], (EffectiveOrders.admin_simple_form_options || {}).merge(url: effective_orders.admin_orders_path) do |f|
|
5
|
+
= f.association :user,
|
6
|
+
label: 'Buyer',
|
7
|
+
required: true,
|
8
|
+
as: (defined?(EffectiveFormInputs) ? :effective_select : :select),
|
9
|
+
collection: @users || User.all.to_a.sort { |user1, user2| user1.to_s <=> user2.to_s }
|
10
|
+
|
11
|
+
%h3 Order Items
|
12
|
+
.order_items
|
13
|
+
- f.object.order_items.build unless f.object.order_items.present?
|
14
|
+
= f.simple_fields_for :order_items do |order_item|
|
15
|
+
= render 'order_item_fields', f: order_item
|
16
|
+
|
17
|
+
.links
|
18
|
+
= link_to_add_association '+ Add line item', f, :order_items, partial: 'order_item_fields'
|
19
|
+
|
20
|
+
= f.input :send_payment_request_to_buyer,
|
21
|
+
as: :boolean,
|
22
|
+
label: 'Yes, send a payment request email to the buyer.',
|
23
|
+
value: (f.object.send_payment_request_to_buyer.nil? ? EffectiveOrders.mailer[:send_payment_request_to_buyer] : f.object.send_payment_request_to_buyer?)
|
24
|
+
|
25
|
+
.form-group.pull-right
|
26
|
+
= f.button :submit, 'Save', data: { disable_with: 'Saving...' }
|
27
|
+
= f.button :submit, 'Save and Add New', data: { disable_with: 'Saving...' }
|
28
|
+
= link_to 'Cancel', effective_orders.admin_orders_path
|
@@ -0,0 +1,9 @@
|
|
1
|
+
.nested-fields.order-item
|
2
|
+
.row
|
3
|
+
- f.object.purchasable ||= Effective::Product.new
|
4
|
+
= f.simple_fields_for :purchasable do |purchasable|
|
5
|
+
.col-sm-2= f.input :quantity, input_html: { value: f.object.quantity || 1, min: 1 }
|
6
|
+
.col-sm-4= purchasable.input :title, input_html: { maxlength: 255 }
|
7
|
+
.col-sm-2= purchasable.input :price, as: (defined?(EffectiveFormInputs) ? :effective_price : :price)
|
8
|
+
.col-sm-2= purchasable.input :tax_exempt, label: 'Tax Exempt', input_html: { title: 'When checked, tax will not be applied to this item' }
|
9
|
+
.col-sm-2.remove-nested-fields= link_to_remove_association('Remove line item', f)
|
@@ -1,11 +1,15 @@
|
|
1
|
-
%h2.effective-orders-page-title Orders
|
1
|
+
%h2.effective-orders-page-title= (@page_title || 'Orders')
|
2
|
+
|
3
|
+
%p.text-right.effective-orders-page-action= link_to 'New Order', effective_orders.new_admin_order_path, :class => 'btn btn-primary'
|
2
4
|
|
3
5
|
- if @datatable.nil?
|
4
|
-
%p
|
5
|
-
Please install
|
6
|
-
= link_to 'effective_datatables', 'https://github.com/code-and-effect/effective_datatables'
|
7
|
-
to see this page.
|
6
|
+
%p Please install #{link_to 'effective_datatables', 'https://github.com/code-and-effect/effective_datatables'} to see this page.
|
8
7
|
- elsif @datatable.present?
|
9
8
|
= render_datatable @datatable
|
10
9
|
- else
|
11
10
|
%p There are no orders present
|
11
|
+
|
12
|
+
- if @datatable.present?
|
13
|
+
%p.text-right= link_to 'New Order', effective_orders.new_admin_order_path, :class => 'btn btn-primary'
|
14
|
+
|
15
|
+
|
@@ -19,19 +19,10 @@
|
|
19
19
|
- if cart.empty?
|
20
20
|
%tr
|
21
21
|
%td.quantity
|
22
|
-
%td.item
|
22
|
+
%td.item Your cart is empty.
|
23
23
|
%td.price
|
24
24
|
%tfoot
|
25
|
-
- if cart.tax > 0
|
26
|
-
%tr
|
27
|
-
%th.quantity
|
28
|
-
%th.subtotal Subtotal
|
29
|
-
%td.price.subtotal-price= price_to_currency(cart.subtotal)
|
30
|
-
%tr
|
31
|
-
%th.quantity
|
32
|
-
%th.tax Tax
|
33
|
-
%td.price.tax-price= price_to_currency(cart.tax)
|
34
25
|
%tr
|
35
26
|
%th.quantity
|
36
|
-
%th.
|
37
|
-
%td.price.
|
27
|
+
%th.subtotal Subtotal
|
28
|
+
%td.price.subtotal-price= price_to_currency(cart.subtotal)
|
@@ -1,20 +1,18 @@
|
|
1
|
-
%h2.effective-orders-page-title
|
1
|
+
%h2.effective-orders-page-title= (@page_title || 'My Cart')
|
2
2
|
|
3
3
|
- if @cart.empty?
|
4
4
|
%p Your cart is empty.
|
5
|
-
|
6
|
-
%hr
|
7
|
-
= link_to 'Home', root_url, :class => 'btn btn-primary'
|
8
|
-
- if EffectiveOrders.show_order_history_button
|
9
|
-
= link_to 'Order History', effective_orders.my_purchases_path, class: 'btn btn-default'
|
10
|
-
|
11
5
|
- else
|
12
6
|
%p Your cart has #{@cart.cart_items.length} items.
|
13
7
|
|
14
8
|
= render_cart(@cart)
|
15
|
-
|
16
9
|
%hr
|
17
|
-
=
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
= render partial: '/effective/carts/cart_actions', locals: { cart: @cart }
|
11
|
+
|
12
|
+
- if @pending_orders.present?
|
13
|
+
%h3 Pending Orders
|
14
|
+
%p The following orders are ready for you to purchase:
|
15
|
+
= render_orders_table(@pending_orders)
|
16
|
+
|
17
|
+
- if EffectiveOrders.show_order_history_button
|
18
|
+
= link_to_my_purchases(label: 'Order History')
|
@@ -0,0 +1,46 @@
|
|
1
|
+
.effective-order
|
2
|
+
= simple_form_for(order, (EffectiveOrders.simple_form_options || {}).merge(url: (order.new_record? ? effective_orders.orders_path : effective_orders.order_path(order)))) do |f|
|
3
|
+
= render partial: 'effective/orders/order_items', locals: {order: order, form: f}
|
4
|
+
|
5
|
+
- if order.errors[:order_items].present?
|
6
|
+
%p.inline-errors= order.errors[:order_items].first
|
7
|
+
|
8
|
+
- if order.errors[:total].present?
|
9
|
+
%p.inline-errors= order.errors[:total].first.gsub(EffectiveOrders.minimum_charge.to_i.to_s, price_to_currency(EffectiveOrders.minimum_charge.to_i))
|
10
|
+
|
11
|
+
- if EffectiveOrders.collect_user_fields.present? && (f.object.user rescue nil).present?
|
12
|
+
= render partial: 'effective/orders/order_user_fields', locals: {form: f, user: f.object.user }
|
13
|
+
|
14
|
+
- num_addresses = [EffectiveOrders.require_billing_address, EffectiveOrders.require_shipping_address].count(true)
|
15
|
+
|
16
|
+
- if num_addresses > 0
|
17
|
+
.row
|
18
|
+
- if EffectiveOrders.require_billing_address
|
19
|
+
%div{class: "col-sm-#{12 / num_addresses}"}
|
20
|
+
%h3 Billing Address
|
21
|
+
= effective_address_fields(f, :billing_address)
|
22
|
+
- if f.object.user.respond_to?(:billing_address=)
|
23
|
+
= f.input :save_billing_address, as: :boolean, label: 'Save as my default billing address', required: false
|
24
|
+
|
25
|
+
- if EffectiveOrders.require_shipping_address
|
26
|
+
%div{class: "col-sm-#{12 / num_addresses}"}
|
27
|
+
%h3 Shipping Address
|
28
|
+
- if EffectiveOrders.require_billing_address && EffectiveOrders.require_shipping_address
|
29
|
+
.shipping_address_fields{style: (f.object.shipping_address_same_as_billing? && (f.object.errors[:shipping_address] || []).blank?) ? 'display: none;' : 'display: block;'}
|
30
|
+
= effective_address_fields(f, :shipping_address)
|
31
|
+
- if f.object.user.respond_to?(:shipping_address=)
|
32
|
+
= f.input :save_shipping_address, as: :boolean, label: 'Save as my default shipping address', required: false
|
33
|
+
|
34
|
+
= f.input :shipping_address_same_as_billing, as: :boolean, label: 'My shipping address is the same as my billing address', required: false
|
35
|
+
|
36
|
+
- if EffectiveOrders.collect_note
|
37
|
+
= render partial: 'effective/orders/order_note_fields', locals: {form: f}
|
38
|
+
|
39
|
+
- unless f.object.pending? || current_cart.try(:empty?)
|
40
|
+
= link_to_current_cart(label: 'Change Items')
|
41
|
+
|
42
|
+
.pull-right
|
43
|
+
- if order.total == 0 && EffectiveOrders.allow_free_orders
|
44
|
+
= f.submit order_checkout_label(:free), class: 'btn btn-primary', rel: :nofollow, data: {'disable_with' => 'Processing...' }
|
45
|
+
- else
|
46
|
+
= f.submit 'Save and Continue', class: 'btn btn-primary', rel: :nofollow, data: {'disable_with' => 'Saving...' }
|