workarea-gift_cards 3.4.10 → 4.0.3
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 +5 -5
- data/{.eslintrc → .eslintrc.json} +12 -1
- data/.github/workflows/ci.yml +10 -8
- data/.rubocop.yml +2 -197
- data/.stylelintrc.json +8 -0
- data/CHANGELOG.md +40 -20
- data/Gemfile +3 -5
- data/README.md +25 -1
- data/app/controllers/workarea/api/admin/gift_cards_controller.rb +309 -0
- data/app/controllers/workarea/api/storefront/checkouts_controller.decorator +6 -0
- data/app/controllers/workarea/api/storefront/gift_cards_controller.rb +2 -8
- data/app/controllers/workarea/storefront/checkout/gift_cards_controller.rb +32 -0
- data/app/controllers/workarea/storefront/gift_cards_controller.rb +15 -16
- data/app/models/workarea/checkout/steps/gift_card.rb +72 -0
- data/app/models/workarea/fulfillment/policies/create_gift_card.rb +30 -0
- data/app/models/workarea/payment.decorator +25 -7
- data/app/models/workarea/payment/authorize/gift_card.rb +7 -20
- data/app/models/workarea/payment/capture/gift_card.rb +5 -7
- data/app/models/workarea/payment/gift_card.rb +1 -1
- data/app/models/workarea/payment/gift_card_operation.rb +9 -0
- data/app/models/workarea/payment/purchase/gift_card.rb +24 -1
- data/app/models/workarea/payment/refund/gift_card.rb +9 -14
- data/app/models/workarea/payment/tender/gift_card.rb +3 -10
- data/app/models/workarea/search/admin/order.decorator +2 -4
- data/app/seeds/workarea/gift_card_seeds.rb +7 -7
- data/app/view_models/workarea/storefront/gift_card_order_pricing.rb +19 -20
- data/app/view_models/workarea/storefront/order_view_model.decorator +2 -22
- data/app/views/workarea/admin/payment_gift_cards/_menu.html.haml +2 -1
- data/app/views/workarea/storefront/checkouts/_gift_card_error.html.haml +8 -6
- data/app/views/workarea/storefront/checkouts/_gift_card_payment.html.haml +20 -12
- data/app/views/workarea/storefront/gift_card_mailer/created.html.haml +1 -1
- data/app/views/workarea/storefront/order_mailer/_gift_card_summary.html.haml +6 -5
- data/app/views/workarea/storefront/orders/_gift_card_summary.html.haml +2 -2
- data/app/views/workarea/storefront/products/templates/_gift_card.html.haml +5 -5
- data/app/workers/workarea/log_gift_card_redemption.rb +16 -9
- data/config/initializers/configuration.rb +7 -4
- data/config/initializers/fields.rb +14 -0
- data/config/locales/en.yml +14 -4
- data/config/routes.rb +9 -2
- data/lib/workarea/gift_cards.rb +9 -0
- data/lib/workarea/gift_cards/gateway.rb +128 -0
- data/lib/workarea/gift_cards/version.rb +1 -1
- data/test/documentation/workarea/api/admin/gift_cards_documentation_test.rb +24 -10
- data/test/documentation/workarea/api/storefront/gift_cards_documentation_test.rb +57 -50
- data/test/dummy/config/initializers/session_store.rb +1 -1
- data/test/integration/workarea/api/admin/gift_card_integration_test.rb +13 -5
- data/test/integration/workarea/api/storefront/checkout_gift_cards_integration_test.rb +120 -0
- data/test/integration/workarea/api/storefront/{balance_integration_test.rb → gift_cards_integration_test.rb} +1 -1
- data/test/integration/workarea/storefront/checkout_gift_cards_integration_test.rb +116 -0
- data/test/integration/workarea/storefront/gift_cards_integration_test.rb +48 -0
- data/test/integration/workarea/storefront/purchase_gift_cards_integration_test.rb +55 -0
- data/test/lib/workarea/gift_cards/gateway_test.rb +131 -0
- data/test/models/workarea/checkout/steps/gift_card_test.rb +104 -0
- data/test/models/workarea/fulfillment/policies/create_gift_card_test.rb +47 -0
- data/test/models/workarea/gift_card_payment_test.rb +15 -3
- data/test/models/workarea/payment/purchase/gift_card_test.rb +11 -8
- data/test/queries/workarea/admin_redemptions_export_test.rb +31 -35
- data/test/system/workarea/storefront/gift_cards_system_test.rb +8 -2
- data/test/view_models/workarea/storefront/gift_card_order_pricing_test.rb +113 -0
- data/test/workers/workarea/log_gift_card_redemption_test.rb +1 -1
- data/workarea-gift_cards.gemspec +4 -4
- metadata +32 -25
- data/.eslintignore +0 -2
- data/.scss-lint.yml +0 -188
- data/app/controllers/workarea/api/admin/payment_gift_cards_controller.rb +0 -49
- data/app/controllers/workarea/storefront/checkouts_controller.decorator +0 -24
- data/app/services/workarea/checkout/steps/gift_card.rb +0 -49
- data/app/view_models/workarea/storefront/checkout/payment_view_model.decorator +0 -32
- data/app/view_models/workarea/storefront/checkout/summary_view_model.decorator +0 -11
- data/app/workers/workarea/create_ordered_gift_cards.rb +0 -47
- data/config/initializers/jump_to_navigation.rb +0 -3
- data/test/integration/workarea/api/storefront/checkout_integration_test.rb +0 -161
- data/test/integration/workarea/storefront/gift_card_integration_test.rb +0 -226
- data/test/services/workarea/checkout/steps/gift_card_test.rb +0 -87
- data/test/view_models/workarea/storefront/checkout/gift_card_payment_view_model_test.rb +0 -65
- data/test/workers/workarea/create_ordered_gift_cards_test.rb +0 -39
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
module Workarea
|
|
2
2
|
decorate Search::Admin::Order, with: 'gift_cards' do
|
|
3
|
-
def
|
|
4
|
-
|
|
5
|
-
result += " #{payment.gift_card.number}" if payment.gift_card.present?
|
|
6
|
-
result
|
|
3
|
+
def keywords
|
|
4
|
+
super + payment.gift_cards.map(&:number)
|
|
7
5
|
end
|
|
8
6
|
end
|
|
9
7
|
end
|
|
@@ -12,7 +12,6 @@ module Workarea
|
|
|
12
12
|
id: 'GIFT_CARD',
|
|
13
13
|
name: 'Gift Card',
|
|
14
14
|
gift_card: true,
|
|
15
|
-
digital: true,
|
|
16
15
|
template: 'gift_card',
|
|
17
16
|
customizations: 'gift_card',
|
|
18
17
|
description: Faker::Lorem.paragraph,
|
|
@@ -25,19 +24,20 @@ module Workarea
|
|
|
25
24
|
|
|
26
25
|
product.save!
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
Workarea::Fulfillment::Sku.find_or_create_by(
|
|
29
29
|
id: 'GIFT_CARD_10',
|
|
30
|
-
|
|
30
|
+
policy: :create_gift_card
|
|
31
31
|
)
|
|
32
32
|
|
|
33
|
-
Workarea::
|
|
33
|
+
Workarea::Fulfillment::Sku.find_or_create_by(
|
|
34
34
|
id: 'GIFT_CARD_25',
|
|
35
|
-
|
|
35
|
+
policy: :create_gift_card
|
|
36
36
|
)
|
|
37
37
|
|
|
38
|
-
Workarea::
|
|
38
|
+
Workarea::Fulfillment::Sku.find_or_create_by(
|
|
39
39
|
id: 'GIFT_CARD_50',
|
|
40
|
-
|
|
40
|
+
policy: :create_gift_card
|
|
41
41
|
)
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -1,35 +1,34 @@
|
|
|
1
1
|
module Workarea
|
|
2
2
|
module Storefront
|
|
3
3
|
module GiftCardOrderPricing
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
)
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
def gift_cards
|
|
7
|
+
@gift_cards ||= payment.gift_cards.select(&:persisted?)
|
|
9
8
|
end
|
|
10
9
|
|
|
11
|
-
def
|
|
12
|
-
|
|
13
|
-
gift_card.balance
|
|
14
|
-
else
|
|
15
|
-
0.to_m
|
|
16
|
-
end
|
|
10
|
+
def gift_card?
|
|
11
|
+
gift_cards.present?
|
|
17
12
|
end
|
|
18
13
|
|
|
19
14
|
def gift_card_amount
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
gift_cards.sum(0.to_m, &:amount)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def gift_card_balance
|
|
19
|
+
gift_cards.sum(0.to_m, &:balance)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def total_before_gift_cards
|
|
23
|
+
order.total_price - advance_payment_amount + gift_card_amount
|
|
25
24
|
end
|
|
26
25
|
|
|
27
|
-
def
|
|
28
|
-
|
|
26
|
+
def advance_payment_amount
|
|
27
|
+
super + gift_card_amount
|
|
29
28
|
end
|
|
30
29
|
|
|
31
|
-
def
|
|
32
|
-
|
|
30
|
+
def failed_gift_card
|
|
31
|
+
@failed_gift_card ||= payment.gift_cards.reject(&:persisted?).first
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
34
|
end
|
|
@@ -1,27 +1,7 @@
|
|
|
1
1
|
module Workarea
|
|
2
|
-
decorate Storefront::OrderViewModel, with:
|
|
3
|
-
decorated do
|
|
4
|
-
delegate :gift_card?, to: :payment
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
def gift_card_tender
|
|
8
|
-
payment.gift_card
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def gift_card_display_number
|
|
12
|
-
gift_card_tender.try(:display_number)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def gift_card_tender_amount
|
|
16
|
-
if gift_card?
|
|
17
|
-
gift_card_tender.amount
|
|
18
|
-
else
|
|
19
|
-
0.to_m
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
2
|
+
decorate Storefront::OrderViewModel, with: :order_gift_card do
|
|
23
3
|
def paid_amount
|
|
24
|
-
super -
|
|
4
|
+
super - gift_card_amount
|
|
25
5
|
end
|
|
26
6
|
end
|
|
27
7
|
end
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
- if Workarea::GiftCards.uses_system_cards?
|
|
2
|
+
%li{ class: "primary-nav__item" }= link_to t('workarea.admin.shared.primary_nav.gift_cards'), payment_gift_cards_path, class: navigation_link_classes(payment_gift_cards_path)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
- if step.
|
|
2
|
-
- step.
|
|
3
|
-
.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
- if step.gift_card?
|
|
2
|
+
- step.gift_cards.each do |gift_card|
|
|
3
|
+
- if gift_card.errors.any?
|
|
4
|
+
- gift_card.full_messages.each do |message|
|
|
5
|
+
.message.message--error
|
|
6
|
+
%p.message__type
|
|
7
|
+
%span.message__icon= t('workarea.storefront.messages.error')
|
|
8
|
+
%p.message__text= message
|
|
@@ -1,28 +1,36 @@
|
|
|
1
|
-
.checkout-payment__secondary-method{ class: step.
|
|
1
|
+
.checkout-payment__secondary-method{ class: step.gift_card? ? 'checkout-payment__secondary-method--visible' : nil }
|
|
2
2
|
|
|
3
|
-
- if step.
|
|
3
|
+
- if step.gift_card?
|
|
4
4
|
.message.message--info
|
|
5
5
|
%p.message__type
|
|
6
6
|
%span.message__icon= t('workarea.storefront.messages.info')
|
|
7
7
|
%p.message__text
|
|
8
|
-
#{t('workarea.storefront.gift_cards.
|
|
9
|
-
#{t('workarea.storefront.gift_cards.
|
|
8
|
+
#{t('workarea.storefront.gift_cards.balance_html', amount: number_to_currency(step.gift_card_balance))}
|
|
9
|
+
#{t('workarea.storefront.gift_cards.applied_to_order_html', amount: number_to_currency(step.gift_card_amount))}
|
|
10
10
|
|
|
11
|
-
- if step.order_covered_by_gift_card?
|
|
12
|
-
#{t('workarea.storefront.gift_cards.place_order', amount: number_to_currency(step.gift_card_amount))}
|
|
13
11
|
- if step.tender_required?
|
|
14
|
-
#{t('workarea.storefront.gift_cards.
|
|
12
|
+
#{t('workarea.storefront.gift_cards.tender_required_html', amount: number_to_currency(step.order_balance))}
|
|
13
|
+
- else
|
|
14
|
+
#{t('workarea.storefront.gift_cards.place_order')}
|
|
15
15
|
|
|
16
|
-
= optional_field(t('workarea.storefront.gift_cards.enter_gift_card_prompt'), step.
|
|
16
|
+
= optional_field(t('workarea.storefront.gift_cards.enter_gift_card_prompt'), step.gift_cards, step.failed_gift_card) do
|
|
17
17
|
|
|
18
18
|
%h2= t('workarea.storefront.gift_cards.gift_card')
|
|
19
19
|
|
|
20
|
-
= form_tag
|
|
20
|
+
= form_tag checkout_gift_cards_path, method: 'patch', id: 'gift_card_form', class: 'inline-form' do
|
|
21
21
|
|
|
22
22
|
.inline-form__cell
|
|
23
23
|
.value
|
|
24
|
-
= text_field_tag 'gift_card_number', step.
|
|
25
|
-
- if step.
|
|
26
|
-
%span.value__error= step.
|
|
24
|
+
= text_field_tag 'gift_card_number', step.failed_gift_card&.number, class: 'text-box', autocomplete: 'off', title: t('workarea.storefront.gift_cards.gift_card_number'), placeholder: t('workarea.storefront.gift_cards.gift_card_number')
|
|
25
|
+
- if step.failed_gift_card && step.failed_gift_card.errors[:number].present?
|
|
26
|
+
%span.value__error= step.failed_gift_card.errors[:number].first
|
|
27
27
|
.inline-form__cell
|
|
28
28
|
%p= button_tag t('workarea.storefront.gift_cards.apply_gift_card'), value: 'apply_gift_card', class: 'button'
|
|
29
|
+
|
|
30
|
+
.applied-gift-cards
|
|
31
|
+
- step.gift_cards.each do |gift_card|
|
|
32
|
+
%p.applied-gift-card
|
|
33
|
+
%strong.applied-gift-card__number= gift_card.display_number
|
|
34
|
+
= link_to t('workarea.storefront.gift_cards.remove'), checkout_gift_cards_path(gift_card_id: gift_card.id), data: { method: :delete, confirm: t('workarea.storefront.gift_cards.remove_confirmation') }, class: 'applied-gift-card__remove-link'
|
|
35
|
+
%br
|
|
36
|
+
%span.applied-gift-card__applied= t('workarea.storefront.gift_cards.balance_applied_html', amount: number_to_currency(gift_card.amount), balance: number_to_currency(gift_card.balance))
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
%p
|
|
5
5
|
%strong= @from
|
|
6
6
|
%br
|
|
7
|
-
= t('workarea.storefront.email.gift_card_created.message_html', link: link_to(Workarea.config.host, Workarea.config.host
|
|
7
|
+
= t('workarea.storefront.email.gift_card_created.message_html', link: link_to(Workarea.config.host, Workarea.config.host), amount: number_to_currency(@card.amount))
|
|
8
8
|
|
|
9
9
|
- if @card.message.present?
|
|
10
10
|
%p
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
- if order.
|
|
2
|
-
|
|
3
|
-
%
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
- if order.gift_card_amount > 0
|
|
2
|
+
- order.gift_cards.each do |gift_card|
|
|
3
|
+
%p
|
|
4
|
+
= t('workarea.storefront.gift_cards.gift_card')
|
|
5
|
+
= gift_card.display_number
|
|
6
|
+
= number_to_currency(gift_card.amount)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
- if order.
|
|
1
|
+
- if order.gift_card_amount > 0
|
|
2
2
|
%tr
|
|
3
3
|
%th
|
|
4
4
|
%span= t('workarea.storefront.gift_cards.gift_card')
|
|
5
5
|
%td
|
|
6
|
-
%strong.table__price-discount −#{number_to_currency(order.
|
|
6
|
+
%strong.table__price-discount −#{number_to_currency(order.gift_card_amount)}
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
.grid__cell.grid__cell--60-at-medium
|
|
3
3
|
|
|
4
4
|
.product-details__name
|
|
5
|
-
%h1.product-details__heading
|
|
5
|
+
%h1.product-details__heading= product.name
|
|
6
6
|
|
|
7
7
|
%p.product-details__id
|
|
8
|
-
%span
|
|
8
|
+
%span= product.id
|
|
9
9
|
|
|
10
|
-
.product-prices.product-prices--details
|
|
10
|
+
.product-prices.product-prices--details
|
|
11
11
|
= render 'workarea/storefront/products/pricing', product: product
|
|
12
12
|
|
|
13
13
|
- if product.description.present?
|
|
@@ -60,13 +60,13 @@
|
|
|
60
60
|
|
|
61
61
|
= append_partials('storefront.product_details', product: product)
|
|
62
62
|
|
|
63
|
-
%p.product-details__full-details=link_to t('workarea.storefront.products.view_full_details'), product_path(product, color: params[:color]), class: 'text-button'
|
|
63
|
+
%p.product-details__full-details=link_to t('workarea.storefront.products.view_full_details'), product_path(product, color: params[:color]), class: 'text-button'
|
|
64
64
|
|
|
65
65
|
.grid__cell.grid__cell--40-at-medium
|
|
66
66
|
|
|
67
67
|
.product-details__primary-image
|
|
68
68
|
= link_to(product_image_url(product.primary_image, :zoom), target: '_blank', class: 'product-details__primary-image-link', data: { dialog_button: '' }) do
|
|
69
|
-
= image_tag product_image_url(product.primary_image, :detail), alt: 'View Larger Image',
|
|
69
|
+
= image_tag product_image_url(product.primary_image, :detail), alt: 'View Larger Image', class: 'product-details__primary-image-link-image'
|
|
70
70
|
|
|
71
71
|
- if product.images.length > 1
|
|
72
72
|
.product-details__alt-images
|
|
@@ -3,7 +3,12 @@ module Workarea
|
|
|
3
3
|
include Sidekiq::Worker
|
|
4
4
|
include Sidekiq::CallbacksWorker
|
|
5
5
|
|
|
6
|
-
sidekiq_options
|
|
6
|
+
sidekiq_options(
|
|
7
|
+
enqueue_on: {
|
|
8
|
+
Order => :place,
|
|
9
|
+
only_if: -> { Workarea::GiftCards.uses_system_cards? }
|
|
10
|
+
}
|
|
11
|
+
)
|
|
7
12
|
|
|
8
13
|
def perform(order_id)
|
|
9
14
|
order = Order.find(order_id)
|
|
@@ -11,16 +16,18 @@ module Workarea
|
|
|
11
16
|
payment = Payment.find_or_initialize_by(id: order.id)
|
|
12
17
|
return unless payment.gift_card?
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
payment.gift_cards.each do |tender|
|
|
20
|
+
gift_card = Payment::GiftCard.find_by_token(tender.number)
|
|
21
|
+
next if redemption_already_exists?(gift_card, order.id)
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
gift_card.redemptions.create!(
|
|
24
|
+
redeemed_at: order.placed_at,
|
|
25
|
+
amount: tender.amount,
|
|
26
|
+
order_id: order.id
|
|
27
|
+
)
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
gift_card.touch
|
|
30
|
+
end
|
|
24
31
|
end
|
|
25
32
|
|
|
26
33
|
private
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
Workarea.configure do |config|
|
|
2
|
-
config.checkout_steps << 'Workarea::Checkout::Steps::GiftCard'
|
|
3
|
-
config.customization_types << Workarea::Catalog::Customizations::GiftCard
|
|
4
2
|
config.product_templates << :gift_card
|
|
5
|
-
config.
|
|
3
|
+
config.customization_types << 'Workarea::Catalog::Customizations::GiftCard'
|
|
4
|
+
config.fulfillment_policies << 'Workarea::Fulfillment::Policies::CreateGiftCard'
|
|
5
|
+
config.checkout_steps << 'Workarea::Checkout::Steps::GiftCard'
|
|
6
|
+
config.tender_types.prepend(:gift_cards)
|
|
6
7
|
config.seeds << 'Workarea::GiftCardSeeds'
|
|
7
|
-
config.
|
|
8
|
+
config.jump_to_navigation.merge!('Gift Cards' => :payment_gift_cards_path)
|
|
9
|
+
|
|
10
|
+
config.gateways.gift_card = 'Workarea::GiftCards::Gateway'
|
|
8
11
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
Workarea::Configuration.define_fields do
|
|
3
|
+
fieldset 'Gift Cards', namespaced: false do
|
|
4
|
+
field 'Gift Card Token Length',
|
|
5
|
+
type: :integer,
|
|
6
|
+
default: 8,
|
|
7
|
+
description: 'Length of digital gift card numbers generated by Workarea.'
|
|
8
|
+
|
|
9
|
+
field 'Max Gift Cards Per Order',
|
|
10
|
+
type: :integer,
|
|
11
|
+
default: 10,
|
|
12
|
+
description: 'How many gift cards can be applied to a single order.'
|
|
13
|
+
end
|
|
14
|
+
end
|
data/config/locales/en.yml
CHANGED
|
@@ -52,6 +52,7 @@ en:
|
|
|
52
52
|
credit: "%{amount} added to gift card %{number}"
|
|
53
53
|
debit: "%{amount} deducted from gift card %{number}"
|
|
54
54
|
insufficient_funds: This gift card doesn't not enough balance.
|
|
55
|
+
max_applied: You can only apply up to %{count} gift cards to an order.
|
|
55
56
|
payment_gift_card:
|
|
56
57
|
name: Gift Card %{token}
|
|
57
58
|
storefront:
|
|
@@ -62,20 +63,29 @@ en:
|
|
|
62
63
|
message_html: has purchased a gift certificate for you to use at %{link} in the amount of %{amount}.
|
|
63
64
|
says: 'says:'
|
|
64
65
|
subject: You've Got a Gift Certificate!
|
|
66
|
+
flash_messages:
|
|
67
|
+
gift_card_added: Your gift card has been applied.
|
|
68
|
+
gift_card_error: We couldn't add this gift card number.
|
|
69
|
+
gift_card_removed: Your gift card has been removed.
|
|
70
|
+
gift_card_balance: Your balance is %{balance}.
|
|
71
|
+
gift_card_not_found: Invalid card number or email.
|
|
65
72
|
gift_cards:
|
|
66
|
-
|
|
73
|
+
applied_to_order_html: "%{amount} will be applied to your order."
|
|
67
74
|
apply_gift_card: Apply
|
|
68
|
-
|
|
75
|
+
balance_html: Your total gift card balance is %{amount}.
|
|
76
|
+
balance_applied_html: '%{amount} of %{balance} balance will be applied to this order.'
|
|
69
77
|
check_balance: Check Your Gift Card Balance
|
|
70
78
|
email_to_recipient: We will email the digital gift card to the recipient.
|
|
71
79
|
enter_gift_card_prompt: Enter a gift card number
|
|
72
|
-
gift_card: Gift
|
|
80
|
+
gift_card: Gift Cards
|
|
73
81
|
gift_card_number: Gift Card Number
|
|
74
82
|
message_to_recipient: Message to Recipient
|
|
75
83
|
place_order: Click the Place Order button below to complete your order.
|
|
76
84
|
recipients_email: Recipient's Email
|
|
85
|
+
remove: remove
|
|
86
|
+
remove_confirmation: Are you sure you want to remove this gift card?
|
|
77
87
|
senders_email: Your Name
|
|
78
|
-
|
|
88
|
+
tender_required_html: You must submit another payment method for %{amount}.
|
|
79
89
|
orders:
|
|
80
90
|
tenders:
|
|
81
91
|
gift_card:
|
data/config/routes.rb
CHANGED
|
@@ -10,19 +10,26 @@ Workarea::Storefront::Engine.routes.draw do
|
|
|
10
10
|
scope '(:locale)', constraints: Workarea::I18n.routes_constraint do
|
|
11
11
|
get 'gift_cards/balance', to: 'gift_cards#index'
|
|
12
12
|
get 'gift_cards/lookup', to: 'gift_cards#lookup'
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
namespace :checkout do
|
|
15
|
+
patch 'gift_cards', to: 'gift_cards#add'
|
|
16
|
+
delete 'gift_cards', to: 'gift_cards#remove'
|
|
17
|
+
end
|
|
14
18
|
end
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
if Workarea::Plugin.installed?(:api)
|
|
18
22
|
Workarea::Api::Admin::Engine.routes.draw do
|
|
19
|
-
resources :
|
|
23
|
+
resources :gift_cards do
|
|
24
|
+
collection { patch 'bulk' }
|
|
25
|
+
end
|
|
20
26
|
end
|
|
21
27
|
|
|
22
28
|
Workarea::Api::Storefront::Engine.routes.draw do
|
|
23
29
|
resources :checkouts, only: [] do
|
|
24
30
|
member do
|
|
25
31
|
patch 'add_gift_card'
|
|
32
|
+
delete 'remove_gift_card'
|
|
26
33
|
end
|
|
27
34
|
end
|
|
28
35
|
|
data/lib/workarea/gift_cards.rb
CHANGED
|
@@ -4,8 +4,17 @@ require 'workarea/admin'
|
|
|
4
4
|
|
|
5
5
|
module Workarea
|
|
6
6
|
module GiftCards
|
|
7
|
+
def self.gateway
|
|
8
|
+
Workarea.config.gateways.gift_card.constantize.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.uses_system_cards?
|
|
12
|
+
Workarea::GiftCards.gateway.respond_to?(:uses_system_cards?) &&
|
|
13
|
+
Workarea::GiftCards.gateway.uses_system_cards?
|
|
14
|
+
end
|
|
7
15
|
end
|
|
8
16
|
end
|
|
9
17
|
|
|
10
18
|
require 'workarea/gift_cards/version'
|
|
11
19
|
require 'workarea/gift_cards/engine'
|
|
20
|
+
require 'workarea/gift_cards/gateway'
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
module GiftCards
|
|
3
|
+
class Gateway
|
|
4
|
+
# Object returns from transaction requests.
|
|
5
|
+
#
|
|
6
|
+
# @attr [Boolean] success? whether the transaction was successful or not
|
|
7
|
+
# @attr [String] message information on the transaction result
|
|
8
|
+
#
|
|
9
|
+
class Response < Struct.new(:success?, :message); end
|
|
10
|
+
|
|
11
|
+
# Whether or not this gateway uses +Workarea::Payment::GiftCard+
|
|
12
|
+
# This controls the display of the admin menu, triggering the creation of
|
|
13
|
+
# cards from orders, and tracking redemptions.
|
|
14
|
+
#
|
|
15
|
+
def uses_system_cards?
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# See purchase. This gateway performs a purchase on authorization.
|
|
20
|
+
#
|
|
21
|
+
# @param [Integer] amount amount to authorize, in cents
|
|
22
|
+
# @param [Workarea::Payment::Tender::GiftCard] tender for transaction
|
|
23
|
+
#
|
|
24
|
+
# @return [Workarea::GiftCards::Gateway::Response]
|
|
25
|
+
#
|
|
26
|
+
def authorize(amount, tender)
|
|
27
|
+
purchase(amount, tender)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# See refund.
|
|
31
|
+
#
|
|
32
|
+
# @param [Integer] amount amount to cancel, in cents
|
|
33
|
+
# @param [Workarea::Payment::Tender::GiftCard] tender for transaction
|
|
34
|
+
#
|
|
35
|
+
# @return [Workarea::GiftCards::Gateway::Response]
|
|
36
|
+
#
|
|
37
|
+
def cancel(amount, tender)
|
|
38
|
+
refund(amount, tender)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# This gateway does a purchase on authorization so no capture is required.
|
|
42
|
+
#
|
|
43
|
+
# @param [Integer] amount amount to capture, in cents
|
|
44
|
+
# @param [Workarea::Payment::Tender::GiftCard] tender for transaction
|
|
45
|
+
#
|
|
46
|
+
# @return [Workarea::GiftCards::Gateway::Response]
|
|
47
|
+
#
|
|
48
|
+
def capture(amount, tender)
|
|
49
|
+
# no op, captures on authorization
|
|
50
|
+
Response.new(true, I18n.t('workarea.gift_cards.capture'))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Perform a purchase on a +Workarea::Payment::GiftCard+. This will
|
|
54
|
+
# increment the `used` field, and decrement the `balance` field.
|
|
55
|
+
#
|
|
56
|
+
# @param [Integer] amount amount to purchase, in cents
|
|
57
|
+
# @param [Workarea::Payment::Tender::GiftCard] tender for transaction
|
|
58
|
+
#
|
|
59
|
+
# @return [Workarea::GiftCards::Gateway::Response]
|
|
60
|
+
#
|
|
61
|
+
def purchase(amount, tender)
|
|
62
|
+
Payment::GiftCard.purchase(tender.number, amount)
|
|
63
|
+
|
|
64
|
+
Response.new(
|
|
65
|
+
true,
|
|
66
|
+
I18n.t(
|
|
67
|
+
'workarea.gift_cards.debit',
|
|
68
|
+
amount: amount,
|
|
69
|
+
number: tender.number
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
rescue Payment::InsufficientFunds
|
|
73
|
+
Response.new(false, I18n.t('workarea.gift_cards.insufficient_funds'))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Undo a purchase on a +Workarea::Payment::GiftCard+. This will
|
|
77
|
+
# increment the `balance` field, and decrement the `used` field.
|
|
78
|
+
#
|
|
79
|
+
# @param [Integer] amount amount to refund, in cents
|
|
80
|
+
# @param [Workarea::Payment::Tender::GiftCard] tender for transaction
|
|
81
|
+
#
|
|
82
|
+
# @return [Workarea::GiftCards::Gateway::Response]
|
|
83
|
+
#
|
|
84
|
+
def refund(amount, tender)
|
|
85
|
+
Payment::GiftCard.refund(tender.number, amount)
|
|
86
|
+
|
|
87
|
+
Response.new(
|
|
88
|
+
true,
|
|
89
|
+
I18n.t(
|
|
90
|
+
'workarea.gift_cards.credit',
|
|
91
|
+
amount: amount,
|
|
92
|
+
number: tender.number
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Lookup the balance of one or many +Workarea::Payment::GiftCard+ records.
|
|
98
|
+
# It will always return a single sum. If multiple numbers are provided, it
|
|
99
|
+
# returns the total of all balances. Invalid numbers return a balance of
|
|
100
|
+
# zero.
|
|
101
|
+
#
|
|
102
|
+
# @param [String] token the gift card number/token
|
|
103
|
+
#
|
|
104
|
+
# @return [Money] the balance gift cards matching the numbers provided
|
|
105
|
+
#
|
|
106
|
+
def balance(token)
|
|
107
|
+
Array.wrap(token).sum(0.to_m) { |t| Payment::GiftCard.find_balance(t) }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Lookup a gift card.
|
|
111
|
+
#
|
|
112
|
+
# @param [Hash] params
|
|
113
|
+
# @option params [String] :email address associated to the gift card
|
|
114
|
+
# @option params [String] :token gift card number/token to lookup
|
|
115
|
+
#
|
|
116
|
+
# @return [Workarea::Payment::GiftCard, nil]
|
|
117
|
+
#
|
|
118
|
+
def lookup(params)
|
|
119
|
+
email = params.fetch(:email, nil)
|
|
120
|
+
token = params.fetch(:token, nil)
|
|
121
|
+
|
|
122
|
+
if email.present? && token.present?
|
|
123
|
+
Workarea::Payment::GiftCard.find_by_token_and_email(token, email)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|